changes required to allow [Bindable] on getters and setters. Getters and setters may be overrides, and only one or the other has [Bindable] metadata. The basic premise is to search the metadata for [Bindable] (isBindable) looks up the inheritance chain which is what we don't want). We find and search the metadata for the other accessor if it exists. Then if there is [Bindable] we move the method into the bindable namespace and generate the wrapper method.
Project: http://git-wip-us.apache.org/repos/asf/flex-falcon/repo Commit: http://git-wip-us.apache.org/repos/asf/flex-falcon/commit/89968c43 Tree: http://git-wip-us.apache.org/repos/asf/flex-falcon/tree/89968c43 Diff: http://git-wip-us.apache.org/repos/asf/flex-falcon/diff/89968c43 Branch: refs/heads/develop Commit: 89968c43a14d1e0ec3b45c1f2d4004cd65ded99d Parents: 4201746 Author: Alex Harui <[email protected]> Authored: Tue Oct 8 07:47:40 2013 -0700 Committer: Alex Harui <[email protected]> Committed: Tue Oct 8 13:50:58 2013 -0700 ---------------------------------------------------------------------- .../internal/as/codegen/BindableHelper.java | 8 ++ .../as/codegen/ClassDirectiveProcessor.java | 102 ++++++++++++++++++- .../internal/as/codegen/LexicalScope.java | 38 ++++++- .../definitions/AccessorDefinition.java | 16 ++- .../internal/definitions/DefinitionBase.java | 6 ++ .../compiler/internal/projects/FlexProject.java | 10 +- .../flex/compiler/internal/scopes/ASScope.java | 4 +- .../internal/tree/as/BaseDefinitionNode.java | 6 +- .../tree/as/BaseTypedDefinitionNode.java | 87 ++++++++++++++++ .../internal/tree/as/BaseVariableNode.java | 56 ---------- .../compiler/internal/tree/as/FunctionNode.java | 5 +- 11 files changed, 264 insertions(+), 74 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java b/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java index 21f5bda..ea1e0a3 100644 --- a/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java +++ b/compiler/src/org/apache/flex/compiler/internal/as/codegen/BindableHelper.java @@ -526,6 +526,13 @@ public class BindableHelper private static final Namespace bindablePrivateNamespace = new Namespace(CONSTANT_PrivateNs, ".BindableNamespace"); /** + * The namespace to put compiler generated members into so that they do not conflict with any user defined + * members. + */ + public static final NamespaceDefinition bindableNamespaceDefinition = NamespaceDefinition.createNamespaceDefinition(bindablePrivateNamespace); + + + /** * The mx.events package namespace */ public static Namespace NAMESPACE_MX_EVENTS = new Namespace(CONSTANT_PackageNs, "mx.events"); @@ -556,5 +563,6 @@ public class BindableHelper private static final Name NAME_STATIC_EVENT_DISPATCHER = new Name("staticEventDispatcher"); public static String PROPERTY_CHANGE = "propertyChange"; + public static String BINDABLE = "Bindable"; } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/as/codegen/ClassDirectiveProcessor.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/as/codegen/ClassDirectiveProcessor.java b/compiler/src/org/apache/flex/compiler/internal/as/codegen/ClassDirectiveProcessor.java index 29d2a7b..2354faa 100644 --- a/compiler/src/org/apache/flex/compiler/internal/as/codegen/ClassDirectiveProcessor.java +++ b/compiler/src/org/apache/flex/compiler/internal/as/codegen/ClassDirectiveProcessor.java @@ -52,7 +52,10 @@ import org.apache.flex.compiler.definitions.IClassDefinition; import org.apache.flex.compiler.definitions.IConstantDefinition; import org.apache.flex.compiler.definitions.IDefinition; import org.apache.flex.compiler.definitions.IInterfaceDefinition; +import org.apache.flex.compiler.definitions.ITypeDefinition; import org.apache.flex.compiler.definitions.metadata.IMetaTag; +import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute; +import org.apache.flex.compiler.definitions.references.INamespaceReference; import org.apache.flex.compiler.exceptions.CodegenInterruptedException; import org.apache.flex.compiler.problems.CircularTypeReferenceProblem; import org.apache.flex.compiler.problems.ConstructorCannotHaveReturnTypeProblem; @@ -83,9 +86,11 @@ import org.apache.flex.compiler.tree.as.IExpressionNode; import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode; import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode.LanguageIdentifierKind; import org.apache.flex.compiler.internal.as.codegen.ICodeGenerator.IConstantValue; +import org.apache.flex.compiler.internal.definitions.AccessorDefinition; import org.apache.flex.compiler.internal.definitions.ClassDefinition; import org.apache.flex.compiler.internal.definitions.DefinitionBase; import org.apache.flex.compiler.internal.definitions.FunctionDefinition; +import org.apache.flex.compiler.internal.definitions.GetterDefinition; import org.apache.flex.compiler.internal.definitions.InterfaceDefinition; import org.apache.flex.compiler.internal.definitions.NamespaceDefinition; import org.apache.flex.compiler.internal.definitions.TypeDefinitionBase; @@ -94,6 +99,7 @@ import org.apache.flex.compiler.internal.definitions.metadata.MetaTag; import org.apache.flex.compiler.internal.definitions.metadata.ResourceBundleMetaTag; import org.apache.flex.compiler.internal.embedding.EmbedData; import org.apache.flex.compiler.internal.projects.CompilerProject; +import org.apache.flex.compiler.internal.scopes.ASScope; import org.apache.flex.compiler.internal.semantics.MethodBodySemanticChecker; import org.apache.flex.compiler.internal.semantics.SemanticUtils; import org.apache.flex.compiler.internal.tree.as.BaseDefinitionNode; @@ -532,6 +538,23 @@ class ClassDirectiveProcessor extends DirectiveProcessor cinit_insns.addAll(this.cinitInsns); cinit_insns.addInstruction(OP_returnvoid); + + if (this.cinfo.cInit == null) + { + // Speculatively initialize the class' cinit + // (static class initializer routine)'s data + // structures; the code generator may need to + // store information in them. + this.cinfo.cInit = new MethodInfo(); + MethodBodyInfo cinit_info = new MethodBodyInfo(); + cinit_info.setMethodInfo(this.cinfo.cInit); + + this.classStaticScope.setMethodInfo(this.cinfo.cInit); + this.classStaticScope.methodVisitor = emitter.visitMethod(this.cinfo.cInit); + this.classStaticScope.methodVisitor.visit(); + this.classStaticScope.methodBodyVisitor = this.classStaticScope.methodVisitor.visitBody(cinit_info); + this.classStaticScope.methodBodyVisitor.visit(); + } /* * FIXME: NPE while compiling 'spark.swc' @@ -650,6 +673,52 @@ class ClassDirectiveProcessor extends DirectiveProcessor final FunctionDefinition funcDef = func.getDefinition(); final boolean is_constructor = func.isConstructor(); + + ICompilerProject project = classScope.getProject(); + + boolean isBindable = false; + if (funcDef instanceof AccessorDefinition) + { + IMetaTag[] metaTags = funcDef.getAllMetaTags(); + for (IMetaTag metaTag : metaTags) + { + if (metaTag.getTagName().equals(BindableHelper.BINDABLE)) + { + IMetaTagAttribute[] attrs = metaTag.getAllAttributes(); + isBindable = attrs.length == 0; + } + } + if (!isBindable) + { + AccessorDefinition otherDef = + ((AccessorDefinition)funcDef).resolveCorrespondingAccessor(classScope.getProject()); + // ignore if not in your class def + if (otherDef != null && otherDef.getContainingScope().equals(funcDef.getContainingScope())) + { + metaTags = otherDef.getAllMetaTags(); + for (IMetaTag metaTag : metaTags) + { + if (metaTag.getTagName().equals(BindableHelper.BINDABLE)) + { + IMetaTagAttribute[] attrs = metaTag.getAllAttributes(); + isBindable = attrs.length == 0; + } + } + } + } + } + Name funcName = funcDef.getMName(classScope.getProject()); + Name bindableName = null; + boolean wasOverride = false; + if (isBindable) + { + // move function into bindable namespace + bindableName = BindableHelper.getBackingPropertyName(funcName); + INamespaceReference ns = BindableHelper.bindableNamespaceDefinition; + wasOverride = funcDef.isOverride(); + funcDef.setNamespaceReference(ns); + funcDef.unsetOverride(); + } functionSemanticChecks(func); @@ -675,8 +744,8 @@ class ClassDirectiveProcessor extends DirectiveProcessor if ( mi != null ) { - Name funcName = funcDef.getMName(classScope.getProject()); - ITraitVisitor tv = ls.traitsVisitor.visitMethodTrait(functionTraitKind(func, TRAIT_Method), funcName, 0, mi); + ITraitVisitor tv = ls.traitsVisitor.visitMethodTrait(functionTraitKind(func, TRAIT_Method), + bindableName != null ? bindableName : funcName, 0, mi); if (funcName != null) classScope.getMethodBodySemanticChecker().checkFunctionForConflictingDefinitions(func, funcDef); @@ -689,11 +758,38 @@ class ClassDirectiveProcessor extends DirectiveProcessor if ( func.hasModifier(ASModifier.FINAL)) tv.visitAttribute(Trait.TRAIT_FINAL, Boolean.TRUE); - if ( func.hasModifier(ASModifier.OVERRIDE) || funcDef.isOverride()) + // don't set override if we've moved it to the bindable namespace + if (!wasOverride && (func.hasModifier(ASModifier.OVERRIDE) || funcDef.isOverride())) tv.visitAttribute(Trait.TRAIT_OVERRIDE, Boolean.TRUE); tv.visitEnd(); } } + if (isBindable) + { + if (wasOverride) + funcDef.setOverride(); + if (funcDef instanceof GetterDefinition) + { + DefinitionBase bindableGetter = func.buildBindableGetter(func.getName()); + ASScope funcScope = (ASScope)funcDef.getContainingScope(); + funcScope.addDefinition(bindableGetter); + LexicalScope ls = funcDef.isStatic()? classStaticScope: classScope; + ls.generateBindableGetter(bindableGetter, funcName, bindableName, + funcDef.resolveType(project).getMName(project), getAllMetaTags(funcDef)); + } + else + { + TypeDefinitionBase typeDef = funcDef.resolveType(project); + ASScope funcScope = (ASScope)funcDef.getContainingScope(); + DefinitionBase bindableSetter = func.buildBindableSetter(func.getName(), + funcScope, + funcDef.getTypeReference()); + funcScope.addDefinition(bindableSetter); + LexicalScope ls = funcDef.isStatic()? classStaticScope: classScope; + ls.generateBindableSetter(bindableSetter, funcName, bindableName, + typeDef.getMName(project), getAllMetaTags(funcDef)); + } + } } /** http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/as/codegen/LexicalScope.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/as/codegen/LexicalScope.java b/compiler/src/org/apache/flex/compiler/internal/as/codegen/LexicalScope.java index d8128a2..92a2973 100644 --- a/compiler/src/org/apache/flex/compiler/internal/as/codegen/LexicalScope.java +++ b/compiler/src/org/apache/flex/compiler/internal/as/codegen/LexicalScope.java @@ -44,6 +44,7 @@ import org.apache.flex.abc.semantics.Name; import org.apache.flex.abc.semantics.Namespace; import org.apache.flex.abc.semantics.Nsset; import org.apache.flex.abc.semantics.PooledValue; +import org.apache.flex.abc.semantics.Trait; import org.apache.flex.abc.visitors.IABCVisitor; import org.apache.flex.abc.visitors.IMetadataVisitor; import org.apache.flex.abc.visitors.IMethodBodyVisitor; @@ -59,6 +60,7 @@ import org.apache.flex.compiler.definitions.metadata.IMetaTag; import org.apache.flex.compiler.definitions.metadata.IMetaTagAttribute; import org.apache.flex.compiler.internal.definitions.DefinitionBase; import org.apache.flex.compiler.internal.definitions.metadata.MetaTag; +import org.apache.flex.compiler.internal.definitions.metadata.MetaTagAttribute; import org.apache.flex.compiler.internal.semantics.MethodBodySemanticChecker; import org.apache.flex.compiler.internal.semantics.SemanticUtils; import org.apache.flex.compiler.internal.tree.as.BaseVariableNode; @@ -627,10 +629,16 @@ public class LexicalScope var_type, noInitializer ); - ITraitVisitor getterTv = BindableHelper.generateBindableGetter(this, var_name, backingPropertyName, var_type); - IDefinition bindableVarDef = var.getDefinition(); + generateBindableGetter(bindableVarDef, var_name, backingPropertyName, var_type, metaTags); + generateBindableSetter(bindableVarDef, var_name, backingPropertyName, var_type, metaTags); + } + + public void generateBindableGetter(IDefinition bindableVarDef, Name var_name, Name backingPropertyName, Name var_type, IMetaInfo[] metaTags) + { + ITraitVisitor getterTv = BindableHelper.generateBindableGetter(this, var_name, backingPropertyName, var_type); + IMetaTag gotoDefinitionMetaTag = MetaTag.createGotoDefinitionHelp(bindableVarDef, bindableVarDef.getContainingFilePath(), Integer.toString(bindableVarDef.getNameStart()), false); @@ -639,6 +647,9 @@ public class LexicalScope // If we have an IMetaTagsNode use that, otherwise get the metadata from the definition processMetadata(getterTv, metaTags); + if (bindableVarDef.isOverride()) + getterTv.visitAttribute(Trait.TRAIT_OVERRIDE, Boolean.TRUE); + // We don't codegen classes in parallel right now, // so we know that we are on the main code generation thread // because bindable variables are always members of a class. @@ -646,9 +657,23 @@ public class LexicalScope // call visitEnd here and the vistEnd calls in generateBindableSetter // are ok too. getterTv.visitEnd(); - ITraitVisitor setterTv = BindableHelper.generateBindableSetter(this, var_name, backingPropertyName, var_type, var.getDefinition()); + } + + public void generateBindableSetter(IDefinition bindableVarDef, Name var_name, Name backingPropertyName, Name var_type, IMetaInfo[] metaTags) + { + + ITraitVisitor setterTv = BindableHelper.generateBindableSetter(this, var_name, backingPropertyName, var_type, bindableVarDef); + + IMetaTag gotoDefinitionMetaTag = MetaTag.createGotoDefinitionHelp(bindableVarDef, + bindableVarDef.getContainingFilePath(), + Integer.toString(bindableVarDef.getNameStart()), false); + metaTags = MetaTag.addMetaTag(metaTags, gotoDefinitionMetaTag); + + processMetadata(setterTv, metaTags); - processMetadata(setterTv, new IMetaInfo[] { gotoDefinitionMetaTag }); + if (bindableVarDef.isOverride()) + setterTv.visitAttribute(Trait.TRAIT_OVERRIDE, Boolean.TRUE); + setterTv.visitEnd(); } @@ -1766,6 +1791,11 @@ public class LexicalScope String name = meta_info.getTagName(); IMetaTagAttribute[] attrs = meta_info.getAllAttributes(); + if (name.equals(BindableHelper.BINDABLE) && attrs.length == 0) + { + attrs = new MetaTagAttribute[1]; + attrs[0] = new MetaTagAttribute("event", BindableHelper.PROPERTY_CHANGE); + } String[] keys = new String[attrs.length]; String[] values = new String[attrs.length]; http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/definitions/AccessorDefinition.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/definitions/AccessorDefinition.java b/compiler/src/org/apache/flex/compiler/internal/definitions/AccessorDefinition.java index 75e9d5e..aadd143 100644 --- a/compiler/src/org/apache/flex/compiler/internal/definitions/AccessorDefinition.java +++ b/compiler/src/org/apache/flex/compiler/internal/definitions/AccessorDefinition.java @@ -36,6 +36,7 @@ import org.apache.flex.compiler.scopes.IDefinitionSet; import org.apache.flex.compiler.tree.as.IVariableNode; import org.apache.flex.compiler.definitions.IScopedDefinition; import org.apache.flex.compiler.definitions.references.INamespaceReference; +import org.apache.flex.compiler.internal.as.codegen.BindableHelper; import org.apache.flex.compiler.internal.scopes.ASScope; /** @@ -136,6 +137,8 @@ public abstract class AccessorDefinition extends FunctionDefinition implements I final INamespaceDefinition thisNamespaceDef = namespaceReference.resolveNamespaceReference(project); if (thisNamespaceDef == null) return null; + final boolean isBindable = ((NamespaceDefinition)thisNamespaceDef).getAETNamespace().getName().equals( + BindableHelper.bindableNamespaceDefinition.getAETNamespace().getName()); final IDefinitionSet definitionSet = scope.getLocalDefinitionSetByName(name); @@ -158,13 +161,16 @@ public abstract class AccessorDefinition extends FunctionDefinition implements I if (this instanceof IGetterDefinition && definition instanceof ISetterDefinition || this instanceof ISetterDefinition && definition instanceof IGetterDefinition) { - /* aharui: namespaces shouldn't have to match. A subclass may only override - * one of the protected methods, and it was legal to have a public getter with - * a protected setter and other combinations like that - // The namespace must match or it isn't considering to correspond. INamespaceReference testDefRef = definition.getNamespaceReference(); INamespaceDefinition testNamespaceDef = testDefRef.resolveNamespaceReference(project); - if (thisNamespaceDef.equals(testNamespaceDef)) */ + final boolean testBindable = ((NamespaceDefinition)testNamespaceDef).getAETNamespace().getName().equals( + BindableHelper.bindableNamespaceDefinition.getAETNamespace().getName()); + /* aharui: namespaces shouldn't have to match. A subclass may only override + * one of the protected methods, and it was legal to have a public getter with + * a protected setter and other combinations like that. Either both + * have to be in the bindable namespace, or both are not. */ + if ((isBindable && testBindable) || + (!isBindable && !testBindable)) return (AccessorDefinition)definition; } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/definitions/DefinitionBase.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/definitions/DefinitionBase.java b/compiler/src/org/apache/flex/compiler/internal/definitions/DefinitionBase.java index c3ae2dd..3bf6df9 100644 --- a/compiler/src/org/apache/flex/compiler/internal/definitions/DefinitionBase.java +++ b/compiler/src/org/apache/flex/compiler/internal/definitions/DefinitionBase.java @@ -662,6 +662,12 @@ public abstract class DefinitionBase implements IDocumentableDefinition, IDefini flags |= FLAG_OVERRIDE; } + public void unsetOverride() + { + if (isOverride()) + flags -= FLAG_OVERRIDE; + } + @Override public boolean isStatic() { http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java index f12f47a..2b525b9 100644 --- a/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java +++ b/compiler/src/org/apache/flex/compiler/internal/projects/FlexProject.java @@ -45,15 +45,19 @@ import org.apache.flex.compiler.definitions.IDefinition; import org.apache.flex.compiler.definitions.IEffectDefinition; import org.apache.flex.compiler.definitions.IEventDefinition; import org.apache.flex.compiler.definitions.IGetterDefinition; +import org.apache.flex.compiler.definitions.INamespaceDefinition; import org.apache.flex.compiler.definitions.ISetterDefinition; import org.apache.flex.compiler.definitions.IStyleDefinition; import org.apache.flex.compiler.definitions.IVariableDefinition; +import org.apache.flex.compiler.definitions.references.INamespaceReference; import org.apache.flex.compiler.definitions.references.IResolvedQualifiersReference; import org.apache.flex.compiler.definitions.references.ReferenceFactory; import org.apache.flex.compiler.exceptions.LibraryCircularDependencyException; import org.apache.flex.compiler.filespecs.IFileSpecification; +import org.apache.flex.compiler.internal.as.codegen.BindableHelper; import org.apache.flex.compiler.internal.css.CSSManager; import org.apache.flex.compiler.internal.definitions.ClassDefinition; +import org.apache.flex.compiler.internal.definitions.NamespaceDefinition; import org.apache.flex.compiler.internal.definitions.PackageDefinition; import org.apache.flex.compiler.internal.mxml.MXMLDialect; import org.apache.flex.compiler.internal.mxml.MXMLManifestManager; @@ -1295,9 +1299,13 @@ public class FlexProject extends ASProject implements IFlexProject // Can MXML set mx_internal properties if you've done // 'use namesapce mx_internal' in a <Script>? winner = definition; + final INamespaceReference namespaceReference = definition.getNamespaceReference(); + final INamespaceDefinition thisNamespaceDef = namespaceReference.resolveNamespaceReference(this); + final boolean isBindable = ((NamespaceDefinition)thisNamespaceDef).getAETNamespace().getName().equals( + BindableHelper.bindableNamespaceDefinition.getAETNamespace().getName()); // if we find a setter always take it, otherwise // keep looking for a setter - if (winner instanceof ISetterDefinition) + if (winner instanceof ISetterDefinition && !isBindable) break; } } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/scopes/ASScope.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/scopes/ASScope.java b/compiler/src/org/apache/flex/compiler/internal/scopes/ASScope.java index ff7aff7..84b6aa1 100644 --- a/compiler/src/org/apache/flex/compiler/internal/scopes/ASScope.java +++ b/compiler/src/org/apache/flex/compiler/internal/scopes/ASScope.java @@ -1682,7 +1682,9 @@ public abstract class ASScope extends ASScopeBase { IDefinition definition = project.getBuiltinType(builtinType); - if( definition != null && builtinType != IASLanguageConstants.BuiltinType.ANY_TYPE ) + if( definition != null && + builtinType != IASLanguageConstants.BuiltinType.ANY_TYPE && + builtinType != IASLanguageConstants.BuiltinType.VOID) { ASProjectScope projectScope = project.getScope(); http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseDefinitionNode.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseDefinitionNode.java b/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseDefinitionNode.java index 86c53d4..2563416 100644 --- a/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseDefinitionNode.java +++ b/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseDefinitionNode.java @@ -377,7 +377,7 @@ public abstract class BaseDefinitionNode extends TreeNode implements IDocumentab * * @param db */ - void fillInNamespaceAndModifiers(DefinitionBase db) + protected void fillInNamespaceAndModifiers(DefinitionBase db) { INamespaceReference namespaceReference = NamespaceDefinition.createNamespaceReference( getASScope(), getNamespaceNode(), this.hasModifier(ASModifier.STATIC)); @@ -387,7 +387,7 @@ public abstract class BaseDefinitionNode extends TreeNode implements IDocumentab fillInModifiers(db); } - void fillInModifiers(DefinitionBase db) + protected void fillInModifiers(DefinitionBase db) { this.setDefinition(db); @@ -403,7 +403,7 @@ public abstract class BaseDefinitionNode extends TreeNode implements IDocumentab db.setStatic(); } - void fillInMetadata(DefinitionBase definition) + protected void fillInMetadata(DefinitionBase definition) { IMetaTagsNode metaTagsNode = getMetaTagsNode(); if (metaTagsNode == null) http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseTypedDefinitionNode.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseTypedDefinitionNode.java b/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseTypedDefinitionNode.java index 3304f05..8bfc6f6 100644 --- a/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseTypedDefinitionNode.java +++ b/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseTypedDefinitionNode.java @@ -19,11 +19,28 @@ package org.apache.flex.compiler.internal.tree.as; +import org.apache.flex.compiler.common.ASModifier; +import org.apache.flex.compiler.constants.IASLanguageConstants; +import org.apache.flex.compiler.definitions.metadata.IMetaTag; +import org.apache.flex.compiler.definitions.references.INamespaceReference; +import org.apache.flex.compiler.definitions.references.IReference; +import org.apache.flex.compiler.definitions.references.ReferenceFactory; +import org.apache.flex.compiler.internal.definitions.DefinitionBase; +import org.apache.flex.compiler.internal.definitions.GetterDefinition; +import org.apache.flex.compiler.internal.definitions.NamespaceDefinition; +import org.apache.flex.compiler.internal.definitions.ParameterDefinition; +import org.apache.flex.compiler.internal.definitions.SetterDefinition; +import org.apache.flex.compiler.internal.definitions.SyntheticBindableGetterDefinition; +import org.apache.flex.compiler.internal.definitions.SyntheticBindableSetterDefinition; +import org.apache.flex.compiler.internal.scopes.ASScope; +import org.apache.flex.compiler.internal.scopes.FunctionScope; +import org.apache.flex.compiler.internal.tree.as.metadata.MetaTagsNode; import org.apache.flex.compiler.parsing.IASToken; import org.apache.flex.compiler.tree.as.IIdentifierNode; import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode; import org.apache.flex.compiler.tree.as.ITypedNode; import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode.LanguageIdentifierKind; +import org.apache.flex.compiler.tree.metadata.IMetaTagsNode; /** * Base class for definitions that have a type associated with them @@ -139,4 +156,74 @@ public abstract class BaseTypedDefinitionNode extends BaseDefinitionNode impleme typeNode = variableType; } + + /** + * Helper method to fill in a definition with appropriate metadata & + * namespace stuff. Used by both buildDefinition and + * buildBindableDefinitions + * + * @param definition the definition to "fill in" + */ + protected void fillinDefinition(DefinitionBase definition) + { + definition.setNode(this); + + fillInNamespaceAndModifiers(definition); + fillInMetadata(definition); + + // Set the variable's type. If a type annotation doesn't appear in the source, + // the variable type in the definition will be null. + IReference typeRef = hasExplicitType() ? typeNode.computeTypeReference() : null; + definition.setTypeReference(typeRef); + } + + public DefinitionBase buildBindableGetter(String definitionName) + { + GetterDefinition getter = new SyntheticBindableGetterDefinition(definitionName); + fillinDefinition(getter); + + // set up the return type for the getter + IReference typeRef = getter.getTypeReference(); + getter.setReturnTypeReference(typeRef); + + return getter; + } + + public DefinitionBase buildBindableSetter(String definitionName, ASScope containingScope, IReference typeRef) + { + SetterDefinition setter = new SyntheticBindableSetterDefinition(definitionName); + + fillinDefinition(setter); + + // Set up the params for the setter + ParameterDefinition param = new ParameterDefinition(""); + param.setTypeReference(typeRef); + setter.setParameters(new ParameterDefinition[] {param}); + setter.setTypeReference(typeRef); + ASScope setterContainedScope = new FunctionScope(containingScope); + setter.setContainedScope(setterContainedScope); + setterContainedScope.addDefinition(param); + setter.setReturnTypeReference(ReferenceFactory.builtinReference(IASLanguageConstants.BuiltinType.VOID)); + + return setter; + } + + /** + * Build the definitions for a bindable variable that needs a generated + * getter/setter. + * + * @return An Array with all of the definitions built for this Node. + */ + DefinitionBase[] buildBindableDefinitions(ASScope containingScope) + { + String definitionName = nameNode.computeSimpleReference(); + + DefinitionBase[] definitions = new DefinitionBase[2]; + definitions[0] = buildBindableGetter(definitionName); + definitions[1] = buildBindableSetter(definitionName, containingScope, definitions[0].getTypeReference()); + + return definitions; + } + + } http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseVariableNode.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseVariableNode.java b/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseVariableNode.java index a6ccb2a..3ce33b6 100644 --- a/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseVariableNode.java +++ b/compiler/src/org/apache/flex/compiler/internal/tree/as/BaseVariableNode.java @@ -316,62 +316,6 @@ public abstract class BaseVariableNode extends BaseTypedDefinitionNode implement } /** - * Helper method to fill in a definition with appropriate metadata & - * namespace stuff. Used by both buildDefinition and - * buildBindableDefinitions - * - * @param definition the definition to "fill in" - */ - private void fillinDefinition(DefinitionBase definition) - { - definition.setNode(this); - - fillInNamespaceAndModifiers(definition); - fillInMetadata(definition); - - // Set the variable's type. If a type annotation doesn't appear in the source, - // the variable type in the definition will be null. - IReference typeRef = hasExplicitType() ? typeNode.computeTypeReference() : null; - definition.setTypeReference(typeRef); - } - - /** - * Build the definitions for a bindable variable that needs a generated - * getter/setter. - * - * @return An Array with all of the definitions built for this Node. - */ - DefinitionBase[] buildBindableDefinitions(ASScope containingScope) - { - String definitionName = nameNode.computeSimpleReference(); - - GetterDefinition getter = new SyntheticBindableGetterDefinition(definitionName); - SetterDefinition setter = new SyntheticBindableSetterDefinition(definitionName); - - fillinDefinition(getter); - fillinDefinition(setter); - - // set up the return type for the getter - IReference typeRef = getter.getTypeReference(); - getter.setReturnTypeReference(typeRef); - - // Set up the params for the setter - ParameterDefinition param = new ParameterDefinition(""); - param.setTypeReference(typeRef); - setter.setParameters(new ParameterDefinition[] {param}); - setter.setTypeReference(typeRef); - ASScope setterContainedScope = new FunctionScope(containingScope); - setter.setContainedScope(setterContainedScope); - setterContainedScope.addDefinition(param); - - DefinitionBase[] definitions = new DefinitionBase[2]; - definitions[0] = getter; - definitions[1] = setter; - - return definitions; - } - - /** * Does this variable node need to construct a special definition this is * true for variables that have bindable metadata and no attributes, or are * "public" and inside of a ClassNode with bindable metadata with no http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/89968c43/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java ---------------------------------------------------------------------- diff --git a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java b/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java index 07b630f..77a79ba 100644 --- a/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java +++ b/compiler/src/org/apache/flex/compiler/internal/tree/as/FunctionNode.java @@ -205,6 +205,7 @@ public class FunctionNode extends BaseTypedDefinitionNode implements IFunctionNo if (set.contains(PostProcessStep.POPULATE_SCOPE)) { FunctionDefinition definition = buildDefinition(); + boolean isBindable = definition.isBindable(); setDefinition(definition); // if the parent is an anonymous function, then don't add the function definition to the scope @@ -246,7 +247,9 @@ public class FunctionNode extends BaseTypedDefinitionNode implements IFunctionNo { scope = functionDef.getContainedScope(); ScopedBlockNode contents = contentsPart.getContents(); - if (contents != null) + // scope can be null for generated binding wrappers of + // getters and setters + if (contents != null && scope != null) { contents.reconnectScope(scope); }
