From a196a97ab164eed3f08ce1fb944c11486e99e320 Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Mon, 7 Dec 2015 01:22:20 -0800 Subject: [PATCH] Use Object.defineProperty as ES6 class visibility. --- Replace.cpp | 43 ++++++++++++++++++++++--------------------- Syntax.hpp | 12 ++++++------ 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/Replace.cpp b/Replace.cpp index 4d1a2be..ef481e6 100644 --- a/Replace.cpp +++ b/Replace.cpp @@ -34,6 +34,13 @@ CYFunctionExpression *CYSuperize(CYContext &context, CYFunctionExpression *funct return function; } +CYStatement *CYDefineProperty(CYExpression *object, CYExpression *name, bool configurable, bool enumerable, CYProperty *descriptor) { + return $E($C3($M($V("Object"), $S("defineProperty")), object, name, $ CYObject(CYList() + ->* (configurable ? $ CYPropertyValue($S("configurable"), $ CYTrue()) : NULL) + ->* (enumerable ? $ CYPropertyValue($S("enumerable"), $ CYTrue()) : NULL) + ->* descriptor))); +} + static void CYImplicitReturn(CYStatement *&code) { if (CYStatement *&last = CYGetLast(code)) last = last->Return(); @@ -178,10 +185,10 @@ CYExpression *CYClassExpression::Replace(CYContext &context) { ->* $ CYVar($L1($L(prototype, $ CYFunctionExpression(NULL, NULL, NULL)))) ->* $E($ CYAssign($M($V(prototype), $S("prototype")), $M($V(super), $S("prototype")))) ->* $E($ CYAssign($V(prototype), $N($V(prototype)))) - ->* $E($ CYAssign($M($V(prototype), $S("constructor")), $V(constructor))) + ->* CYDefineProperty($V(prototype), $S("constructor"), false, false, $ CYPropertyValue($S("value"), $V(constructor))) ->* $ CYVar(builder.declarations_) ->* builder.statements_ - ->* $E($ CYAssign($M($V(constructor), $S("prototype")), $V(prototype))) + ->* CYDefineProperty($V(constructor), $S("prototype"), false, false, $ CYPropertyValue($S("value"), $V(prototype))) ->* $ CYReturn($V(constructor)) ), tail_->extends_ ?: $V($I("Object"))); } @@ -710,60 +717,54 @@ CYExpression *CYPrefix::Replace(CYContext &context) { CYProperty *CYProperty::ReplaceAll(CYContext &context, CYBuilder &builder, CYExpression *self, bool update) { update |= name_->Computed(); if (update) - Replace(context, builder, self, true); + Replace(context, builder, self, false); if (next_ != NULL) next_ = next_->ReplaceAll(context, builder, self, update); return update ? next_ : this; } -void CYProperty::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool computed) { +void CYProperty::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool protect) { CYExpression *name(name_->PropertyName(context)); - if (computed) { + if (name_->Computed()) { CYIdentifier *unique(context.Unique()); builder.declarations_->*$L1($L(unique, name)); name = $V(unique); } - Replace(context, builder, self, name); + Replace(context, builder, self, name, protect); } -void CYPropertyGetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) { +void CYPropertyGetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) { CYIdentifier *unique(context.Unique()); builder.declarations_ ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_)))); builder.statements_ - ->* $E($C3($M($V("Object"), $S("defineProperty")), self, name, $ CYObject(CYList() - ->* $ CYPropertyValue($S("configurable"), $ CYTrue()) - ->* $ CYPropertyValue($S("enumerable"), $ CYTrue()) - ->* $ CYPropertyValue($S("get"), $V(unique)) - ))); + ->* CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("get"), $V(unique))); } CYFunctionExpression *CYPropertyMethod::Constructor() { return name_->Constructor() ? $ CYFunctionExpression(NULL, parameters_, code_) : NULL; } -void CYPropertyMethod::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) { +void CYPropertyMethod::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) { CYIdentifier *unique(context.Unique()); builder.declarations_ ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_)))); builder.statements_ - ->* $E($ CYAssign($M(self, name), $V(unique))); + ->* (!protect ? $E($ CYAssign($M(self, name), $V(unique))) : + CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("value"), $V(unique), $ CYPropertyValue($S("writable"), $ CYTrue())))); } -void CYPropertySetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) { +void CYPropertySetter::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) { CYIdentifier *unique(context.Unique()); builder.declarations_ ->* $L1($L(unique, CYSuperize(context, $ CYFunctionExpression(NULL, parameters_, code_)))); builder.statements_ - ->* $E($C3($M($V("Object"), $S("defineProperty")), self, name, $ CYObject(CYList() - ->* $ CYPropertyValue($S("configurable"), $ CYTrue()) - ->* $ CYPropertyValue($S("enumerable"), $ CYTrue()) - ->* $ CYPropertyValue($S("set"), $V(unique)) - ))); + ->* CYDefineProperty(self, name, true, !protect, $ CYPropertyValue($S("set"), $V(unique))); } -void CYPropertyValue::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) { +void CYPropertyValue::Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) { + _assert(!protect); CYIdentifier *unique(context.Unique()); builder.declarations_ ->* $L1($L(unique, value_)); diff --git a/Syntax.hpp b/Syntax.hpp index e3999e3..d278729 100644 --- a/Syntax.hpp +++ b/Syntax.hpp @@ -1231,9 +1231,9 @@ struct CYProperty : } CYProperty *ReplaceAll(CYContext &context, CYBuilder &builder, CYExpression *self, bool update); - void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool computed); + void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, bool protect); - virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name) = 0; + virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect) = 0; virtual void Replace(CYContext &context) = 0; virtual void Output(CYOutput &out) const; @@ -1250,7 +1250,7 @@ struct CYPropertyValue : { } - virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name); + virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect); virtual void Replace(CYContext &context); virtual void Output(CYOutput &out) const; }; @@ -1626,7 +1626,7 @@ struct CYPropertyGetter : { } - virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name); + virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect); virtual void Output(CYOutput &out) const; }; @@ -1638,7 +1638,7 @@ struct CYPropertySetter : { } - virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name); + virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect); virtual void Output(CYOutput &out) const; }; @@ -1652,7 +1652,7 @@ struct CYPropertyMethod : virtual CYFunctionExpression *Constructor(); - virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name); + virtual void Replace(CYContext &context, CYBuilder &builder, CYExpression *self, CYExpression *name, bool protect); virtual void Output(CYOutput &out) const; }; -- 2.47.2