flex-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cd...@apache.org
Subject [01/51] [partial] - Migrated the directory structure to a more Maven style structure. - Started migrating the Parser from Antlr2+3 and JFlex to Antlr4.
Date Tue, 22 Jul 2014 13:35:27 GMT
Repository: flex-falcon
Updated Branches:
  refs/heads/falcon-antlr4 [created] 59f6373b3


http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/internal/definitions/ClassDefinition.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/internal/definitions/ClassDefinition.java b/compiler/src/main/java/org/apache/flex/compiler/internal/definitions/ClassDefinition.java
new file mode 100644
index 0000000..8f5ba4f
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/internal/definitions/ClassDefinition.java
@@ -0,0 +1,1455 @@
+/*
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.flex.compiler.internal.definitions;
+
+import static org.apache.flex.compiler.common.DependencyType.EXPRESSION;
+import static org.apache.flex.compiler.common.DependencyType.INHERITANCE;
+import static org.apache.flex.compiler.common.DependencyType.SIGNATURE;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.flex.abc.semantics.Name;
+import org.apache.flex.compiler.common.ISourceLocation;
+import org.apache.flex.compiler.constants.IASKeywordConstants;
+import org.apache.flex.compiler.constants.IASLanguageConstants;
+import org.apache.flex.compiler.constants.IMetaAttributeConstants;
+import org.apache.flex.compiler.constants.IASLanguageConstants.BuiltinType;
+import org.apache.flex.compiler.definitions.IClassDefinition;
+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.IFunctionDefinition;
+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.ITypeDefinition;
+import org.apache.flex.compiler.definitions.IVariableDefinition;
+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.definitions.references.IReference;
+import org.apache.flex.compiler.definitions.references.IResolvedQualifiersReference;
+import org.apache.flex.compiler.definitions.references.ReferenceFactory;
+import org.apache.flex.compiler.internal.config.QNameNormalization;
+import org.apache.flex.compiler.internal.definitions.metadata.MetaTag;
+import org.apache.flex.compiler.internal.embedding.EmbedData;
+import org.apache.flex.compiler.internal.projects.CompilerProject;
+import org.apache.flex.compiler.internal.scopes.ASFileScope;
+import org.apache.flex.compiler.internal.scopes.ASScope;
+import org.apache.flex.compiler.internal.scopes.TypeScope;
+import org.apache.flex.compiler.internal.units.EmbedCompilationUnitFactory;
+import org.apache.flex.compiler.mxml.IMXMLLanguageConstants;
+import org.apache.flex.compiler.problems.DuplicateSkinStateProblem;
+import org.apache.flex.compiler.problems.EmbedMultipleMetaTagsProblem;
+import org.apache.flex.compiler.problems.HostComponentClassNotFoundProblem;
+import org.apache.flex.compiler.problems.HostComponentMustHaveTypeProblem;
+import org.apache.flex.compiler.problems.ICompilerProblem;
+import org.apache.flex.compiler.problems.MissingSkinPartProblem;
+import org.apache.flex.compiler.problems.MissingSkinStateProblem;
+import org.apache.flex.compiler.problems.OnlyOneHostComponentAllowedProblem;
+import org.apache.flex.compiler.problems.SkinPartsMustBePublicProblem;
+import org.apache.flex.compiler.problems.WrongSkinPartProblem;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.scopes.IASScope;
+import org.apache.flex.compiler.scopes.IDefinitionSet;
+import org.apache.flex.compiler.tree.metadata.IEventTagNode;
+import org.apache.flex.compiler.tree.metadata.IMetaTagNode;
+import org.apache.flex.compiler.tree.metadata.IStyleTagNode;
+import org.apache.flex.compiler.units.ICompilationUnit;
+import org.apache.flex.compiler.workspaces.IWorkspace;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+/**
+ * Each instance of this class represents the definition of an ActionScript
+ * class in the symbol table.
+ * <p>
+ * After a class definition is in the symbol table, it should always be accessed
+ * through the read-only <code>IClassDefinition</code> interface.
+ */
+public class ClassDefinition extends ClassDefinitionBase implements IClassDefinition
+{
+    // The ClassDefinitions for *, Null, Undefined, and void are implicit;
+    // unlike for, say, Object, these are not read from any SWC.
+    // They must be created by the compiler itself.
+    private static final ClassDefinition ANY_TYPE;
+    private static final ClassDefinition NULL;
+    private static final ClassDefinition UNDEFINED;
+    private static final ClassDefinition VOID;
+
+    // Sentinel value used internally by this class to indicate that
+    // the ABC class definition does not have [RemoteClass] meta-data.
+    private static final String NO_REMOTE_CLASS_ALIAS = "";
+
+    private static final String HOST_COMPONENT = "hostComponent";
+
+    private static ClassDefinition makeImplicitClassDefinition(String name)
+    {
+        ClassDefinition def = new ClassDefinition(name, NamespaceDefinition.getPublicNamespaceDefinition());
+        def.setPublic();
+        def.setFinal();
+        def.setImplicit();
+        ASScope scope = new TypeScope(null, def);
+        scope.setContainingDefinition(def);
+        def.setContainedScope(scope);
+        return def;
+    }
+
+    /**
+     * Private class that bundles up information extracted from [Frame]
+     * meta-data tags.
+     */
+    private static class FrameInformation
+    {
+        IResolvedQualifiersReference factoryClass;
+        Collection<IResolvedQualifiersReference> extraClasses;
+    }
+
+    static
+    {
+        ANY_TYPE = makeImplicitClassDefinition(IASLanguageConstants.ANY_TYPE);
+        ANY_TYPE.setDynamic();
+
+        NULL = makeImplicitClassDefinition(IASLanguageConstants.Null);
+        UNDEFINED = makeImplicitClassDefinition(IASLanguageConstants.Undefined);
+        VOID = makeImplicitClassDefinition(IASLanguageConstants.void_);
+    }
+
+    public static IClassDefinition getAnyTypeClassDefinition()
+    {
+        return ANY_TYPE;
+    }
+
+    public static IClassDefinition getNullClassDefinition()
+    {
+        return NULL;
+    }
+
+    public static IClassDefinition getUndefinedClassDefinition()
+    {
+        return UNDEFINED;
+    }
+
+    public static IClassDefinition getVoidClassDefinition()
+    {
+        return VOID;
+    }
+
+    private static String getGeneratedURIPrefix(INamespaceReference namespaceRef)
+    {
+        if (namespaceRef instanceof NamespaceDefinition.INamespaceWithPackageName)
+            return ((NamespaceDefinition.INamespaceWithPackageName)namespaceRef).getGeneratedURIPrefix();
+        return "";
+    }
+
+    /**
+     * Constructs a new class definition with an auto generated protected
+     * namespace.
+     * 
+     * @param name Base name of the class definition, eg: DisplayObject, not
+     * flash.display.DisplayObject.
+     * @param namespaceRef {@link INamespaceReference} qualifier. Usually this
+     * will be a {@code INamespaceDefinition.IPublicNamespaceDefinition} whose
+     * URI is a package name like flash.display.
+     */
+    public ClassDefinition(String name, INamespaceReference namespaceRef)
+    {
+        this(name, namespaceRef, NamespaceDefinition.createProtectedNamespaceDefinition(getGeneratedURIPrefix(namespaceRef) + name));
+    }
+
+    /**
+     * Constructs a new class definition with an explicit protected namespace.
+     * The protected namespace is used to qualify protected instance members of
+     * the ABC class.
+     * 
+     * @param name Base name of the class definition, eg: DisplayObject, not
+     * flash.display.DisplayObject.
+     * @param namespaceRef {@link INamespaceReference} qualifier. Usually this
+     * will be a {@code INamespaceDefinition.IPublicNamespaceDefinition} whose
+     * URI is a package name like flash.display.
+     * @param protectedNamespace Protected namespace that will be used to
+     * qualifier protected instance members of the ABC class.
+     */
+    public ClassDefinition(String name, INamespaceReference namespaceRef,
+                           NamespaceDefinition.IProtectedNamespaceDefinition protectedNamespace)
+    {
+        super(name);
+        assert name.indexOf('.') == -1 : "name must not be a qualified name!";
+
+        setNamespaceReference(namespaceRef);
+
+        String generatedURI = getGeneratedURIPrefix(namespaceRef) + name;
+        privateNamespaceReference =
+                NamespaceDefinition.createPrivateNamespaceDefinition(generatedURI);
+        protectedNamespaceReference = protectedNamespace;
+        staticProtectedNamespaceReference =
+                NamespaceDefinition.createStaticProtectedNamespaceDefinition(generatedURI);
+
+        contingentDefinitions = new LinkedList<IDefinition>();
+
+        eventDefinitions = new AtomicReference<Map<String, IEventDefinition>>();
+        styleDefinitions = new AtomicReference<Map<String, IStyleDefinition>>();
+        effectDefinitions = new AtomicReference<Map<String, IEffectDefinition>>();
+
+        skinStates = new AtomicReference<String[]>();
+        skinParts = new AtomicReference<IMetaTag[]>();
+
+        stateNames = new HashSet<String>();
+
+        frameInformation = new AtomicReference<FrameInformation>();
+
+        remoteClassAlias = new AtomicReference<String>();
+    }
+
+    private final NamespaceDefinition.ILanguageNamespaceDefinition privateNamespaceReference;
+    private final NamespaceDefinition.ILanguageNamespaceDefinition protectedNamespaceReference;
+    private final NamespaceDefinition.ILanguageNamespaceDefinition staticProtectedNamespaceReference;
+
+    // A reference to the class that this class extends.
+    private IReference baseClassReference;
+
+    // References to the interfaces that this class implements.
+    private IReference[] interfaceReferences;
+
+    // The definition for the constructor of this class.
+    // This can be stored as a definition rather than as a reference
+    // because the definition is within this class
+    // rather than in a different class.
+    private IFunctionDefinition constructor;
+
+    // This map has keys which are event names (such as "click")
+    // and values which are EventDefinitions.
+    // It contains event definitions created from [Event(...)] metadata
+    // on this class, but not from such metadata on superclasses.
+    // It is lazily created so that if no one asks for the events of a class,
+    // the EventDefinitions don't get created; for example, if we are simply
+    // compiling ActionScript files, their event metadata is irrelevant.
+    // We keep an atomic reference to it because multiple threads
+    // need to be able to lazily update this ClassDefinition after it
+    // is in a scope.
+    private AtomicReference<Map<String, IEventDefinition>> eventDefinitions;
+
+    // This map has keys which are style names (such as "fontSize")
+    // and values which are StyleDefinitions.
+    // It contains style definitions created from [Style(...)] metadata
+    // on this class, but not from such metadata on superclasses.
+    // It is lazily created so that if no one asks for the styles of a class,
+    // the StyleDefinitions don't get created; for example, if we are simply
+    // compiling ActionScript files, their style metadata is irrelevant.
+    // We keep an atomic reference to it because multiple threads
+    // need to be able to lazily update this ClassDefinition after it
+    // is in a scope.
+    private final AtomicReference<Map<String, IStyleDefinition>> styleDefinitions;
+
+    private final AtomicReference<Map<String, IEffectDefinition>> effectDefinitions;
+
+    private final AtomicReference<String[]> skinStates;
+
+    private final AtomicReference<IMetaTag[]> skinParts;
+
+    private Set<String> stateNames;
+
+    private final AtomicReference<FrameInformation> frameInformation;
+
+    // Remote class alias for this class.  Set from [RemoteClass] meta-data.
+    private final AtomicReference<String> remoteClassAlias;
+
+    /**
+     * If this ClassDefinition is for an MXML class, this field is a set of
+     * implicit imports determined by the MXML instance tags that are used
+     * inside the class.
+     */
+    private Set<String> implicitImports;
+
+    private List<IDefinition> contingentDefinitions;
+
+    @Override
+    public ClassClassification getClassClassification()
+    {
+        if (inPackageNamespace())
+            return ClassClassification.PACKAGE_MEMBER;
+        return ClassClassification.FILE_MEMBER;
+    }
+
+    @Override
+    public IFunctionDefinition getConstructor()
+    {
+        return constructor;
+    }
+
+    protected void setConstructor(IFunctionDefinition constructor)
+    {
+        this.constructor = constructor;
+    }
+
+    @Override
+    public String getBaseClassAsDisplayString()
+    {
+        return baseClassReference != null ? baseClassReference.getDisplayString() : "";
+    }
+
+    @Override
+    public IReference getBaseClassReference()
+    {
+        return baseClassReference;
+    }
+
+    /**
+     * Sets a reference to the base class for this class.
+     * 
+     * @param baseClassReference An {@link IReference} referring to the base
+     * class.
+     */
+    public void setBaseClassReference(IReference baseClassReference)
+    {
+        if (baseClassReference == null)
+        {
+            // The baseClassReference of Object is null.
+            // The baseClassReference of other classes is a reference to Object,
+            // until setBaseClass() gets called (which it may never be
+            // in the case of a class declaration without an extends clause).
+            boolean isObject = getBaseName().equals(IASLanguageConstants.Object) &&
+                               getNamespaceReference().isPublicOrInternalNamespace() &&
+                               ((INamespaceDefinition)getNamespaceReference()).getURI().isEmpty();
+            if (!isObject)
+                baseClassReference = ReferenceFactory.builtinReference(BuiltinType.OBJECT);
+        }
+
+        this.baseClassReference = baseClassReference;
+    }
+
+    @Override
+    public IClassDefinition resolveBaseClass(ICompilerProject project)
+    {
+        // Object has no base class.
+        if (baseClassReference == null)
+            return null;
+
+        // Resolve the base class reference within the project,
+        // and establish an inheritance dependency.
+        ITypeDefinition typeDefinition =
+                resolveType(baseClassReference, project, INHERITANCE);
+
+        if (typeDefinition == null)
+            return null;
+
+        // A class cannot extend an interface.
+        if (!(typeDefinition instanceof IClassDefinition))
+            return null;
+
+        // The base class cannot be final.
+        if (((IClassDefinition)typeDefinition).isFinal())
+            return null;
+
+        // A class cannot extend itself.
+        if (typeDefinition == this)
+            return null;
+
+        return (IClassDefinition)typeDefinition;
+    }
+
+    @Override
+    public String[] getImplementedInterfacesAsDisplayStrings()
+    {
+        if (interfaceReferences == null)
+            return new String[0];
+
+        int n = interfaceReferences.length;
+        String[] interfaces = new String[n];
+        for (int i = 0; i < n; i++)
+            interfaces[i] = interfaceReferences[i].getDisplayString();
+
+        return interfaces;
+    }
+
+    public void setImplementedInterfaceReferences(IReference[] interfaceReferences)
+    {
+        this.interfaceReferences = interfaceReferences;
+    }
+
+    @Override
+    public IReference[] getImplementedInterfaceReferences()
+    {
+        if (interfaceReferences == null)
+            return new IReference[0];
+
+        return interfaceReferences;
+    }
+
+    @Override
+    public IEventDefinition getEventDefinition(IWorkspace w, String name)
+    {
+        if (eventDefinitions.get() == null)
+            buildEventDefinitions(w);
+
+        return eventDefinitions.get().get(name);
+    }
+
+    @Override
+    public IEventDefinition[] getEventDefinitions(IWorkspace w)
+    {
+        if (eventDefinitions.get() == null)
+            buildEventDefinitions(w);
+
+        return eventDefinitions.get().values().toArray(new IEventDefinition[0]);
+    }
+
+    /*
+     * Lazily creates a map of event names to event definitions from the event
+     * metadata declared on this class.
+     */
+    private void buildEventDefinitions(IWorkspace w)
+    {
+        Map<String, IEventDefinition> map = new HashMap<String, IEventDefinition>();
+
+        Map<String, IEventTagNode> availableTagNodes = new HashMap<String, IEventTagNode>();
+
+        // required because of CMP-2168 : can't get the event definition from the metatag.
+        if (getNode() != null && getNode().getMetaTags() != null)
+        {
+            IMetaTagNode[] allNodes = this.getNode().getMetaTags().getTagsByName(IMetaAttributeConstants.ATTRIBUTE_EVENT);
+            //                        eventDefinition.setNode((IDefinitionNode)metaTag.getTagNode());
+            for (IMetaTagNode iMetaTagNode : allNodes)
+            {
+                IEventTagNode eventTagNode = (IEventTagNode)iMetaTagNode;
+                availableTagNodes.put(eventTagNode.getName(), (IEventTagNode)iMetaTagNode);
+            }
+        }
+        
+        IMetaTag[] metaTags = getAllMetaTags();
+        if (metaTags != null)
+        {
+            for (IMetaTag metaTag : metaTags)
+            {
+                if (metaTag.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_EVENT))
+                {
+                    // Most event metadata looks like this:
+                    // [Event(name="click", type="flash.events.MouseEvent")]
+                    String name = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_EVENT_NAME);
+                    String type = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_EVENT_TYPE);
+
+                    // However,
+                    // [Event(name="click")]
+                    // and
+                    // [Event("click")]
+                    // are also allowed.
+                    if (name == null)
+                    {
+                        IMetaTagAttribute[] attrs = metaTag.getAllAttributes();
+                        if (attrs != null && attrs.length > 0)
+                        {
+                            name = attrs[0].getValue();
+                        }
+                    }
+                    if (type == null)
+                        type = IASLanguageConstants.Event;
+
+                    if (name != null)
+                    {
+                        EventDefinition eventDefinition = new EventDefinition(name, this);
+
+                        // This scope is necessary for resolving the event's type.
+                        eventDefinition.setContainingScope(getContainingScope());
+
+                        eventDefinition.setTypeReference(ReferenceFactory.packageQualifiedReference(w, type));
+
+                        if (availableTagNodes.containsKey(name))
+                        {
+                            eventDefinition.setNode(availableTagNodes.get(name));
+                        }
+                        map.put(name, eventDefinition);
+                    }
+                }
+            }
+        }
+
+        // Let the first thread that builds the map atomically set it.
+        eventDefinitions.compareAndSet(null, map);
+    }
+
+    @Override
+    public IEventDefinition[] findEventDefinitions(ICompilerProject project)
+    {
+        IWorkspace workspace = project.getWorkspace();
+
+        Map<String, IEventDefinition> map = new HashMap<String, IEventDefinition>();
+
+        // Iterate over this class and its superclasses.
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            for (IEventDefinition eventTag : c.getEventDefinitions(workspace))
+            {
+                String eventName = eventTag.getBaseName();
+
+                // By checking whether the event is already in the map,
+                // we can make sure that an event definition with a particular name
+                // on a subclass overrides ones with the same name on superclasses.
+                if (!map.containsKey(eventName))
+                    map.put(eventName, eventTag);
+            }
+        }
+
+        return map.values().toArray(new IEventDefinition[0]);
+    }
+
+    @Override
+    public IStyleDefinition getStyleDefinition(IWorkspace workspace, String name)
+    {
+        if (styleDefinitions.get() == null)
+            buildStyleDefinitions(workspace);
+
+        return styleDefinitions.get().get(name);
+    }
+
+    @Override
+    public IStyleDefinition[] getStyleDefinitions(IWorkspace w)
+    {
+        if (styleDefinitions.get() == null)
+            buildStyleDefinitions(w);
+
+        return styleDefinitions.get().values().toArray(new IStyleDefinition[0]);
+    }
+
+    /*
+     * Lazily creates a map of style names to style definitions from the style
+     * metadata declared on this class.
+     */
+    private void buildStyleDefinitions(IWorkspace workspace)
+    {
+        Map<String, IStyleDefinition> styleMap = new HashMap<String, IStyleDefinition>();
+
+        for (IMetaTag metaTag : getAllMetaTags())
+        {
+            if (metaTag.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_STYLE))
+            {
+                String name = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_NAME);
+                String type = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_TYPE);
+                String format = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_FORMAT);
+                String inherit = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_INHERIT);
+                String themes = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_THEME);
+                String minValue = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_MIN_VALUE);
+                String minValueExclusive = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_MIN_VALUE_EXCLUSIVE);
+                String maxValue = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_MAX_VALUE);
+                String maxValueExclusive = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_MAX_VALUE_EXCLUSIVE);
+                String enumeration = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_ENUMERATION);
+                String states = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_STATES);
+                String arrayTypeName = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_STYLE_ARRAYTYPE);
+
+                if (name == null) // If there is no Name, we can't create a definition, nor should we try
+                    continue;
+                if (type == null) // missing type is perfectly legal. so let's patch
+                                  // it up to something that will resolve correctly for us.
+                    type = "*";
+
+                StyleDefinition styleDefinition = new StyleDefinition(name, this);
+
+                // This scope is necessary for resolving the style's type.
+                styleDefinition.setContainingScope(getContainingScope());
+
+                styleDefinition.setTypeReference(ReferenceFactory.packageQualifiedReference(workspace, type));
+                styleDefinition.setFormat(format);
+                styleDefinition.setInherit(inherit);
+                styleDefinition.setThemes(themes);
+                styleDefinition.setMinValue(minValue);
+                styleDefinition.setMinValueExclusive(minValueExclusive);
+                styleDefinition.setMaxValue(maxValue);
+                styleDefinition.setMaxValueExclusive(maxValueExclusive);
+                styleDefinition.setArrayType(arrayTypeName);
+                if (states != null)
+                {
+                    final Iterable<String> statesIterable = Splitter.on(",")
+                                    .omitEmptyStrings()
+                                    .trimResults()
+                                    .split(states);
+                    final String[] statesArray = Iterables.toArray(statesIterable, String.class);
+                    styleDefinition.setStates(statesArray);
+                }
+                if (enumeration != null)
+                {
+                    // enumerations are comma seprated, with no spaces
+                    String[] split = enumeration.split(",");
+                    styleDefinition.setEnumeration(split);
+                }
+                IMetaTagNode styleTagNode = metaTag.getTagNode();
+                if (styleTagNode != null && styleTagNode instanceof IStyleTagNode)
+                {
+                    styleDefinition.setNode((IStyleTagNode)styleTagNode);
+                }
+                styleMap.put(name, styleDefinition);
+            }
+        }
+
+        // Let the first thread that builds the map atomically set it.
+        styleDefinitions.compareAndSet(null, styleMap);
+    }
+
+    @Override
+    public IStyleDefinition[] findStyleDefinitions(ICompilerProject project)
+    {
+        IWorkspace workspace = project.getWorkspace();
+
+        Map<String, IStyleDefinition> map = new HashMap<String, IStyleDefinition>();
+
+        // Iterate over this class and its superclasses.
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            for (IStyleDefinition styleTag : c.getStyleDefinitions(workspace))
+            {
+                String styleName = styleTag.getBaseName();
+
+                // By checking whether the style is already in the map,
+                // we can make sure that a style definition with a particular name
+                // on a subclass overrides ones with the same name on superclasses.
+                if (!map.containsKey(styleName))
+                    map.put(styleName, styleTag);
+            }
+        }
+
+        return map.values().toArray(new IStyleDefinition[0]);
+    }
+
+    @Override
+    public IEffectDefinition getEffectDefinition(IWorkspace w, String name)
+    {
+        if (effectDefinitions.get() == null)
+            buildEffectDefinitions(w);
+
+        return effectDefinitions.get().get(name);
+    }
+
+    @Override
+    public IEffectDefinition[] getEffectDefinitions(IWorkspace w)
+    {
+        if (effectDefinitions.get() == null)
+            buildEffectDefinitions(w);
+
+        return effectDefinitions.get().values().toArray(new IEffectDefinition[0]);
+    }
+
+    /*
+     * Lazily creates a map of effect names to effect definitions from the
+     * effect metadata declared on this class.
+     */
+    private void buildEffectDefinitions(IWorkspace workspace)
+    {
+        Map<String, IEffectDefinition> effectMap = new HashMap<String, IEffectDefinition>();
+
+        for (IMetaTag metaTag : getAllMetaTags())
+        {
+            if (metaTag.getTagName().equals(IMetaAttributeConstants.ATTRIBUTE_EFFECT))
+            {
+                String name = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_EFFECT_NAME);
+                String eventName = metaTag.getAttributeValue(IMetaAttributeConstants.NAME_EFFECT_EVENT);
+
+                EffectDefinition effectDefinition = new EffectDefinition(name, this);
+                effectDefinition.setEvent(eventName);
+                // Set the effect definition containing scope, so that clients
+                // can find which file scope contains the effect definition.
+                effectDefinition.setContainingScope(getContainingScope());
+
+                effectMap.put(name, effectDefinition);
+            }
+        }
+
+        // Let the first thread that builds the map atomically set it.
+        effectDefinitions.compareAndSet(null, effectMap);
+    }
+
+    @Override
+    public IEffectDefinition[] findEffectDefinitions(ICompilerProject project)
+    {
+        IWorkspace workspace = project.getWorkspace();
+
+        Map<String, IEffectDefinition> map = new HashMap<String, IEffectDefinition>();
+
+        // Iterate over this class and its superclasses.
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            for (IEffectDefinition effectTag : c.getEffectDefinitions(workspace))
+            {
+                String effectName = effectTag.getBaseName();
+
+                // By checking whether the effect is already in the map,
+                // we can make sure that an effect definition with a particular name
+                // on a subclass overrides ones with the same name on superclasses.
+                if (!map.containsKey(effectName))
+                    map.put(effectName, effectTag);
+            }
+        }
+
+        return map.values().toArray(new IEffectDefinition[0]);
+    }
+
+    /*
+     * Lazily creates a array of skin state names from the skin state metadata
+     * declared on this class.
+     */
+    private void buildSkinStates(Collection<ICompilerProblem> problems)
+    {
+        IMetaTag[] tags = getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_SKIN_STATE);
+
+        Set<String> states = new HashSet<String>();
+
+        for (IMetaTag tag : tags)
+        {
+            IMetaTagAttribute[] attributes = tag.getAllAttributes();
+            // old compiler only ever looked at first value, and ignored
+            // anything else, so match that behavior here.
+            if (attributes.length >= 1)
+            {
+                String state = attributes[0].getValue();
+                if (states.contains(state))
+                {
+                    ICompilerProblem problem = new DuplicateSkinStateProblem(tag, state);
+                    problems.add(problem);
+                }
+                states.add(state);
+            }
+        }
+
+        // Let the first thread that builds the array atomically set it.
+        skinStates.compareAndSet(null, states.toArray(new String[states.size()]));
+    }
+
+    @Override
+    public String[] getSkinStates(Collection<ICompilerProblem> problems)
+    {
+        if (skinStates.get() == null)
+            buildSkinStates(problems);
+
+        return skinStates.get();
+    }
+
+    @Override
+    public String[] findSkinStates(ICompilerProject project, Collection<ICompilerProblem> problems)
+    {
+        Set<String> states = new HashSet<String>();
+
+        // Iterate over this class and its superclasses.
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            for (String state : c.getSkinStates(problems))
+            {
+                if (states.contains(state))
+                {
+                    ICompilerProblem problem = new DuplicateSkinStateProblem(c, state);
+                    problems.add(problem);
+                }
+
+                states.add(state);
+            }
+        }
+
+        return states.toArray(new String[states.size()]);
+    }
+
+    /**
+     * Get any embedded data decorating the class definition
+     * 
+     * @param project Project to resolve against
+     * @param problems Any problems resolving the embedded data
+     * @return EmbedData or null if no embedded data, or a problem resolving
+     * embedded data
+     */
+    public EmbedData getEmbeddedAsset(CompilerProject project, Collection<ICompilerProblem> problems)
+    {
+        IMetaTag[] embedMetaTags = getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_EMBED);
+        if (embedMetaTags == null || embedMetaTags.length == 0)
+            return null;
+
+        if (embedMetaTags.length > 1)
+        {
+            problems.add(new EmbedMultipleMetaTagsProblem(getNode()));
+            return null;
+        }
+
+        String containingSourceFilename = getFileSpecification().getPath();
+        ISourceLocation location = embedMetaTags[0];
+        IMetaTagAttribute[] attributes = embedMetaTags[0].getAllAttributes();
+
+        return EmbedCompilationUnitFactory.getEmbedData(project, getQualifiedName(), containingSourceFilename, location, attributes, problems);
+    }
+
+    private Collection<VariableDefinition> getAllLocalVariables()
+    {
+        Collection<IDefinitionSet> allDefinitions = getContainedScope().getAllLocalDefinitionSets();
+        List<VariableDefinition> variables = new LinkedList<VariableDefinition>();
+
+        for (IDefinitionSet defSet : allDefinitions)
+        {
+            for (int i = 0; i < defSet.getSize(); ++i)
+            {
+                IDefinition definition = defSet.getDefinition(i);
+                if (definition instanceof VariableDefinition)
+                    variables.add((VariableDefinition)definition);
+            }
+        }
+
+        return variables;
+    }
+
+    private Collection<GetterDefinition> getAllLocalGetters()
+    {
+        Collection<IDefinitionSet> allDefinitions = getContainedScope().getAllLocalDefinitionSets();
+        List<GetterDefinition> getters = new LinkedList<GetterDefinition>();
+
+        for (IDefinitionSet defSet : allDefinitions)
+        {
+            for (int i = 0; i < defSet.getSize(); ++i)
+            {
+                IDefinition definition = defSet.getDefinition(i);
+                if (definition instanceof GetterDefinition)
+                    getters.add((GetterDefinition)definition);
+            }
+        }
+
+        return getters;
+    }
+
+    /*
+     * Lazily creates a array of skin parts from the skin part metadata declared
+     * on this class.
+     */
+    private void buildSkinParts(Collection<ICompilerProblem> problems)
+    {
+        Collection<VariableDefinition> variables = getAllLocalVariables();
+
+        List<IMetaTag> parts = new LinkedList<IMetaTag>();
+        for (VariableDefinition variable : variables)
+        {
+            IMetaTag skinPart = variable.getSkinPart();
+            if (skinPart != null)
+                parts.add(skinPart);
+        }
+
+        Collection<GetterDefinition> getters = getAllLocalGetters();
+        for (GetterDefinition getter : getters)
+        {
+            IMetaTag skinPart = getter.getSkinPart();
+            if (skinPart != null)
+                parts.add(skinPart);
+        }
+
+        for (IMetaTag part : parts)
+        {
+            IDefinition definition = part.getDecoratedDefinition();
+            if (!definition.getNamespaceReference().equals(NamespaceDefinition.getPublicNamespaceDefinition()))
+            {
+                ICompilerProblem problem = new SkinPartsMustBePublicProblem(definition);
+                problems.add(problem);
+            }
+        }
+
+        // Let the first thread that builds the array atomically set it.
+        skinParts.compareAndSet(null, parts.toArray(new IMetaTag[parts.size()]));
+    }
+
+    @Override
+    public IMetaTag[] getSkinParts(Collection<ICompilerProblem> problems)
+    {
+        if (skinParts.get() == null)
+            buildSkinParts(problems);
+
+        return skinParts.get();
+    }
+
+    @Override
+    public IMetaTag[] findSkinParts(ICompilerProject project, Collection<ICompilerProblem> problems)
+    {
+        Map<String, IMetaTag> map = new HashMap<String, IMetaTag>();
+
+        // Iterate over this class and its superclasses.
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            for (IMetaTag skinPart : c.getSkinParts(problems))
+            {
+                String variableName = skinPart.getDecoratedDefinition().getBaseName();
+
+                // By checking whether the variable is already in the map,
+                // we can make sure that a variable definition with a particular name
+                // on a subclass overrides ones with the same name on superclasses.
+                if (!map.containsKey(variableName))
+                    map.put(variableName, skinPart);
+            }
+        }
+
+        return map.values().toArray(new IMetaTag[map.size()]);
+    }
+
+    /**
+     * Add a state name to the class
+     * 
+     * @param stateName The name to add
+     */
+    public void addStateName(String stateName)
+    {
+        stateNames.add(stateName);
+    }
+
+    @Override
+    public Set<String> getStateNames()
+    {
+        return stateNames;
+    }
+
+    @Override
+    public Set<String> findStateNames(ICompilerProject project)
+    {
+        Set<String> set = new HashSet<String>();
+
+        // Iterate over this class and its superclasses.
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            set.addAll(c.getStateNames());
+        }
+
+        return set;
+    }
+
+    public List<IDefinition> getContingentDefinitions()
+    {
+        return contingentDefinitions;
+    }
+
+    /**
+     * Build any contingent definitions that may be required for the class such
+     * as hostComponent. These definitions will only be resolved against or
+     * codegend if a superclass does not implement the definition already. Note
+     * that this should only be called when constructring classes derived from
+     * AS or MXML. It is not needed when creating ABC sourced classes.
+     */
+    public void buildContingentDefinitions()
+    {
+        // for now, only host components need to be created
+        IDefinition definition = buildHostComponentMember();
+        if (definition != null)
+            contingentDefinitions.add(definition);
+    }
+
+    /**
+     * If there is host component meta data on the class, run semantic checks on
+     * it.
+     * 
+     * @param project The compiler project.
+     * @param problems The collection of compiler problems to which this method should add problems.
+     */
+    public void verifyHostComponent(CompilerProject project, Collection<ICompilerProblem> problems)
+    {
+        IMetaTag[] metaTags = getHostComponentMetaData();
+        if (metaTags.length == 0)
+            return;
+
+        if (metaTags.length > 1)
+        {
+            ICompilerProblem problem = new OnlyOneHostComponentAllowedProblem(metaTags[1]);
+            problems.add(problem);
+        }
+
+        String hostComponentClassName = getHostComponentClassName(metaTags[0]);
+        if (hostComponentClassName == null)
+        {
+            ICompilerProblem problem = new HostComponentMustHaveTypeProblem(metaTags[0]);
+            problems.add(problem);
+            // without a host component name, there aren't any more checks we
+            // can do, so just bail out.
+            return;
+        }
+
+        IResolvedQualifiersReference hostComponentRef = ReferenceFactory.packageQualifiedReference(project.getWorkspace(), hostComponentClassName);
+        ICompilationUnit referencingCU = project.getScope().getCompilationUnitForDefinition(this);
+        IDefinition hostComponentDef = hostComponentRef.resolve(project, referencingCU, SIGNATURE);
+        if (!(hostComponentDef instanceof IClassDefinition))
+        {
+            ICompilerProblem problem = new HostComponentClassNotFoundProblem(metaTags[0], hostComponentClassName);
+            problems.add(problem);
+            // without a host component class definition, there aren't any more checks we
+            // can do, so just bail out.
+            return;
+        }
+
+        IClassDefinition hostComponentClassDef = (IClassDefinition)hostComponentDef;
+        verifySkinParts(hostComponentClassDef, project, problems);
+        verifySkinStates(hostComponentClassDef, project, problems);
+    }
+
+    private void verifySkinParts(IClassDefinition hostComponentDef, ICompilerProject project, Collection<ICompilerProblem> problems)
+    {
+        IMetaTag[] skinParts = hostComponentDef.findSkinParts(project, problems);
+
+        for (IMetaTag skinPart : skinParts)
+        {
+            IVariableDefinition hostSkinPartDef = (IVariableDefinition)skinPart.getDecoratedDefinition();
+
+            String hostStringPartName = hostSkinPartDef.getBaseName();
+            IDefinition skinPartDef = getContainedScope().getPropertyFromDef(project, this, hostStringPartName, false);
+            if (skinPartDef instanceof ISetterDefinition)
+                skinPartDef = ((ISetterDefinition)skinPartDef).resolveGetter(project);
+
+            // the skinPart definition needs to be either a variable or getter
+            if (!((skinPartDef instanceof IVariableDefinition) || (skinPartDef instanceof IGetterDefinition)))
+                skinPartDef = null;
+
+            ITypeDefinition skinPartTypeDef = null;
+            if (skinPartDef != null)
+                skinPartTypeDef = skinPartDef.resolveType(project);
+
+            if (skinPartTypeDef == null && hostSkinPartDef.isRequiredSkinPart())
+            {
+                ICompilerProblem problem = new MissingSkinPartProblem(skinPart, hostComponentDef.getBaseName());
+                problems.add(problem);
+            }
+            else if (skinPartTypeDef != null && !skinPartTypeDef.isInstanceOf(hostSkinPartDef.resolveType(project), project))
+            {
+                ICompilerProblem problem = new WrongSkinPartProblem(skinPart, skinPartTypeDef, hostSkinPartDef.resolveType(project));
+                problems.add(problem);
+
+            }
+        }
+    }
+
+    private void verifySkinStates(IClassDefinition hostComponentDef, ICompilerProject project, Collection<ICompilerProblem> problems)
+    {
+        Set<String> stateNames = findStateNames(project);
+
+        String[] skinStates = hostComponentDef.findSkinStates(project, problems);
+        for (String skinStateName : skinStates)
+        {
+            if (!stateNames.contains(skinStateName))
+                problems.add(new MissingSkinStateProblem(getFileSpecification().getPath(), skinStateName));
+        }
+    }
+
+    private VariableDefinition buildHostComponentMember()
+    {
+        // if there's no host component meta data, no need to create any contingent member
+        IMetaTag[] metaTags = getHostComponentMetaData();
+        if (metaTags.length == 0)
+            return null;
+
+        String hostComponentClassName = getHostComponentClassName(metaTags[0]);
+        if (hostComponentClassName == null)
+            return null;
+
+        ASScope containedScope = getContainedScope();
+        VariableDefinition hostComponentDef = new VariableDefinition(HOST_COMPONENT);
+        hostComponentDef.setPublic();
+        hostComponentDef.setBindable();
+        hostComponentDef.setImplicit();
+        hostComponentDef.setContingent();
+
+        IReference typeRef = ReferenceFactory.packageQualifiedReference(containedScope.getWorkspace(), hostComponentClassName);
+        hostComponentDef.setTypeReference(typeRef);
+
+        containedScope.addDefinition(hostComponentDef);
+
+        return hostComponentDef;
+    }
+
+    public VariableDefinition buildOuterDocumentMember(IReference outerClass)
+    {
+        ASScope containedScope = getContainedScope();
+        VariableDefinition outerDocumentDef = new VariableDefinition(IMXMLLanguageConstants.PROPERTY_OUTER_DOCUMENT);
+        outerDocumentDef.setPublic();
+        outerDocumentDef.setBindable();
+        outerDocumentDef.setImplicit();
+        outerDocumentDef.setTypeReference(outerClass);
+
+        containedScope.addDefinition(outerDocumentDef);
+
+        // the outer document isn't really a contingent definition, as the user
+        // should never define it, and we should always create one, but making
+        // use of the contingent variable is useful as we can create it here
+        // and then resolve it during codegen and create a problem if
+        // we resolved to anything but the contingent definition outerDocument.
+        outerDocumentDef.setContingent();
+        contingentDefinitions.add(outerDocumentDef);
+
+        return outerDocumentDef;
+    }
+
+    private IMetaTag[] getHostComponentMetaData()
+    {
+        return getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_HOST_COMPONENT);
+    }
+
+    private static String getHostComponentClassName(IMetaTag metaTag)
+    {
+        assert IMetaAttributeConstants.ATTRIBUTE_HOST_COMPONENT.equals(metaTag.getTagName());
+        String hostComponentClassName = metaTag.getValue();
+        // no component name, so don't create a contingent member
+        if (hostComponentClassName == null || hostComponentClassName.isEmpty())
+            return null;
+
+        return hostComponentClassName;
+    }
+
+    private void buildFrameInformation(IWorkspace w)
+    {
+        FrameInformation result = new FrameInformation();
+        IMetaTag[] frameTags = getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_FRAME);
+
+        result.extraClasses = Collections.emptySet();
+        for (IMetaTag frameTag : frameTags)
+        {
+            String frameTagFactoryClass = frameTag.getAttributeValue(IMetaAttributeConstants.NAME_FRAME_FACTORY_CLASS);
+            if (frameTagFactoryClass != null)
+                result.factoryClass = ReferenceFactory.packageQualifiedReference(w, QNameNormalization.normalize(frameTagFactoryClass));
+            String frameTagExtraClass = frameTag.getAttributeValue(IMetaAttributeConstants.NAME_FRAME_EXTRA_CLASS);
+            if (frameTagExtraClass != null)
+            {
+                if (result.extraClasses.size() == 0)
+                    result.extraClasses = new LinkedList<IResolvedQualifiersReference>();
+                result.extraClasses.add(ReferenceFactory.packageQualifiedReference(w, QNameNormalization.normalize(frameTagExtraClass)));
+            }
+        }
+        frameInformation.compareAndSet(null, result);
+    }
+
+    private IResolvedQualifiersReference getFactoryClass(IWorkspace w)
+    {
+        if (frameInformation.get() == null)
+            buildFrameInformation(w);
+        return frameInformation.get().factoryClass;
+    }
+
+    public boolean hasOwnFactoryClass(IWorkspace w)
+    {
+        return getFactoryClass(w) != null;
+    }
+
+    private void buildRemoteClassAlias()
+    {
+        IMetaTag[] remoteClassTags = getMetaTagsByName(IMetaAttributeConstants.ATTRIBUTE_REMOTECLASS);
+        String remoteClassAlias = NO_REMOTE_CLASS_ALIAS;
+        if (remoteClassTags.length != 0)
+        {
+            // Reading the source for the Flex 4.5.X compiler, it seems that
+            // you can only have one alias for each class and that the last alias
+            // wins.
+            IMetaTag lastRemoteClassTag = remoteClassTags[remoteClassTags.length - 1];
+            remoteClassAlias = lastRemoteClassTag.getAttributeValue(IMetaAttributeConstants.NAME_REMOTECLASS_ALIAS);
+            // Goofy logic copied from flex2.compiler.as3.SyntaxTreeEvaluator.
+            // Original code references a bug number 159983 in an unknown bug base.
+            if (remoteClassAlias == null)
+                remoteClassAlias = "<" + getQualifiedName();
+        }
+
+        this.remoteClassAlias.compareAndSet(null, remoteClassAlias);
+    }
+
+    /**
+     * Get's the remote class alias for this class.
+     * 
+     * @return The remote class alias for this class.
+     */
+    public String getRemoteClassAlias()
+    {
+        if (remoteClassAlias.get() == null)
+            buildRemoteClassAlias();
+        String result = remoteClassAlias.get();
+        if (result == NO_REMOTE_CLASS_ALIAS)
+            return null;
+        return result;
+    }
+
+    public ClassDefinition resolveInheritedFactoryClass(ICompilerProject project)
+    {
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            assert c instanceof ClassDefinition : "IClassDefinition " + c.getBaseName() + "is not a ClassDefinition!";
+            ClassDefinition classDef = (ClassDefinition)c;
+            IResolvedQualifiersReference factoryRef = classDef.getFactoryClass(project.getWorkspace());
+            if (factoryRef != null)
+            {
+                IDefinition factoryDef = factoryRef.resolve(project, (ASScope)this.getContainingScope(), EXPRESSION, true);
+                if (factoryDef instanceof ClassDefinition)
+                    return (ClassDefinition)factoryDef;
+            }
+        }
+        return null;
+    }
+
+    public Collection<IDefinition> resolveExtraClasses(ICompilerProject project)
+    {
+        if (frameInformation.get() == null)
+            buildFrameInformation(project.getWorkspace());
+        LinkedList<IDefinition> result = new LinkedList<IDefinition>();
+        for (IResolvedQualifiersReference extraClassRef : frameInformation.get().extraClasses)
+        {
+            IDefinition extraClassDef =
+                    extraClassRef.resolve(project, (ASScope)this.getContainingScope(), EXPRESSION, true);
+            if (extraClassDef != null)
+                result.add(extraClassDef);
+        }
+        return ImmutableList.<IDefinition> copyOf(result);
+    }
+
+    @Override
+    public String getDefaultPropertyName(ICompilerProject project)
+    {
+        // Look for [DefaultProperty("foo")] on this class its superclasses.
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            IMetaTag defaultPropertyMetaData = c.getMetaTagByName(IMetaAttributeConstants.ATTRIBUTE_DEFAULTPROPERTY);
+            if (defaultPropertyMetaData != null)
+            {
+                IMetaTagAttribute attrs[] = defaultPropertyMetaData.getAllAttributes();
+                if ((attrs.length == 1) && (!attrs[0].hasKey()))
+                    return attrs[0].getValue();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void setContainedScope(IASScope value)
+    {
+        super.setContainedScope(value);
+        ((DefinitionBase)privateNamespaceReference).setContainingScope(value);
+    }
+
+    /**
+     * Gets the {@link INamespaceReference} that resolves to the private
+     * namespace for this {@link IClassDefinition}.
+     * 
+     * @return The {@link INamespaceReference} that resolves to the private
+     * namespace for this {@link IClassDefinition}.
+     */
+    public NamespaceDefinition.ILanguageNamespaceDefinition getPrivateNamespaceReference()
+    {
+        return privateNamespaceReference;
+    }
+
+    /**
+     * Gets the {@link INamespaceReference} that resolves to the protected
+     * namespace for this {@link IClassDefinition}.
+     * 
+     * @return The {@link INamespaceReference} that resolves to the protected
+     * namespace for this {@link IClassDefinition}.
+     */
+    @Override
+    public NamespaceDefinition.ILanguageNamespaceDefinition getProtectedNamespaceReference()
+    {
+        return protectedNamespaceReference;
+    }
+
+    /**
+     * Gets the {@link INamespaceReference} that resolves to the static
+     * protected namespace for this {@link IClassDefinition}.
+     * 
+     * @return The {@link INamespaceReference} that resolves to the static
+     * protected namespace for this {@link IClassDefinition}.
+     */
+    @Override
+    public NamespaceDefinition.ILanguageNamespaceDefinition getStaticProtectedNamespaceReference()
+    {
+        return staticProtectedNamespaceReference;
+    }
+
+    @Override
+    public Name getMName(ICompilerProject project)
+    {
+        // "*" isn't referenced by name in ABC - it's usually
+        // just index 0, which is what AET does for a null name.
+        if (getBaseName() == IASLanguageConstants.ANY_TYPE)
+            return null;
+
+        return super.getMName(project);
+    }
+
+    @Override
+    public ASFileScope getFileScope()
+    {
+        if (isImplicit())
+            return null;
+        else
+            return super.getFileScope();
+    }
+
+    /**
+     * Adds a new node to the list of nodes representing the implicit imports
+     * created by MXML tags.
+     */
+    public void addImplicitImport(String qname)
+    {
+        if (implicitImports == null)
+            implicitImports = new HashSet<String>();
+
+        implicitImports.add(qname);
+    }
+
+    /**
+     * Gets the implicit imports created by MXML tags, for use by CodeModel.
+     * 
+     * @return A list of {@code MXMLImplicitImportNode} objects.
+     */
+    public String[] getImplicitImports()
+    {
+        return implicitImports != null ?
+                implicitImports.toArray(new String[0]) :
+                new String[0];
+    }
+
+    /**
+     * Adds implicit variable definitions for "this" and "super" to this class
+     * definition's contained scope. These variable definitions are for code
+     * model compatibility and are not codegen'd.
+     */
+    public void setupThisAndSuper()
+    {
+        // Create an implicit VariableDefinition for "this".
+        VariableDefinition thisDef = new VariableDefinition(IASKeywordConstants.THIS);
+
+        ASScope containedScope = getContainedScope();
+        IWorkspace workspace = containedScope.getWorkspace();
+
+        // this is a lexical ref for codemodel backwards compat
+        thisDef.setTypeReference(ReferenceFactory.lexicalReference(workspace, getBaseName()));
+        thisDef.setImplicit();
+        thisDef.setNamespaceReference(NamespaceDefinition.getCodeModelImplicitDefinitionNamespace());
+
+        // Create an implicit VariableDefinition for "super". 
+        VariableDefinition superDef = new VariableDefinition(IASKeywordConstants.SUPER);
+        IReference baseClassRef = getBaseClassReference();
+        if (baseClassRef == null)
+        {
+            baseClassRef = ReferenceFactory.builtinReference(BuiltinType.OBJECT);
+        }
+        superDef.setTypeReference(baseClassRef);
+        superDef.setImplicit();
+        superDef.setNamespaceReference(NamespaceDefinition.getCodeModelImplicitDefinitionNamespace());
+
+        // Add these definitions to the class scope.
+        containedScope.addDefinition(thisDef);
+        containedScope.addDefinition(superDef);
+    }
+
+    /**
+     * Mark this class as an excluded class by adding [ExcludeClass] meta data.
+     */
+    public void setExcludedClass()
+    {
+        MetaTag excludeClassMetaTag = new MetaTag(this, IMetaAttributeConstants.ATTRIBUTE_EXCLUDECLASS, new IMetaTagAttribute[0]);
+        addMetaTag(excludeClassMetaTag);
+    }
+
+    /**
+     * For debugging only. Produces a string such as
+     * <code>public class B extends A implements I1, I2</code>.
+     */
+    @Override
+    protected void buildInnerString(StringBuilder sb)
+    {
+        sb.append(getNamespaceReferenceAsString());
+        sb.append(' ');
+
+        sb.append(IASKeywordConstants.CLASS);
+        sb.append(' ');
+
+        sb.append(getBaseName());
+        sb.append(' ');
+
+        if (baseClassReference != null)
+        {
+            sb.append(IASKeywordConstants.EXTENDS);
+            sb.append(' ');
+
+            String baseClassName = getBaseClassAsDisplayString();
+            sb.append(baseClassName.isEmpty() ? IASLanguageConstants.Object : baseClassName);
+        }
+
+        String[] implementedInterfaces = getImplementedInterfacesAsDisplayStrings();
+        int n = implementedInterfaces.length;
+        if (n > 0)
+        {
+            sb.append(' ');
+            sb.append(IASKeywordConstants.IMPLEMENTS);
+            sb.append(' ');
+
+            for (int i = 0; i < n; i++)
+            {
+                sb.append(implementedInterfaces[i]);
+                if (i < n - 1)
+                {
+                    sb.append(',');
+                    sb.append(' ');
+                }
+            }
+        }
+    }
+
+    public boolean getOwnNeedsProtected()
+    {
+        return ((TypeScope)getContainedScope()).getNeedsProtected();
+    }
+
+    @Override
+    public IClassDefinition resolveHostComponent(ICompilerProject project)
+    {
+        for (IClassDefinition c : classIterable(project, true))
+        {
+            if (!(c instanceof ClassDefinition))
+                continue;
+            
+            ClassDefinition classDef = (ClassDefinition)c;
+            IMetaTag[] hostComponentMetaData = classDef.getHostComponentMetaData();
+            if (hostComponentMetaData.length < 1)
+                continue;
+            String hostComponentName = getHostComponentClassName(hostComponentMetaData[0]);
+            if (hostComponentName == null)
+                return null;
+            IResolvedQualifiersReference hostComponentRef = ReferenceFactory.packageQualifiedReference(project.getWorkspace(), hostComponentName);
+            IDefinition hostComponentDef = hostComponentRef.resolve(project);
+            if (!(hostComponentDef instanceof IClassDefinition))
+                return null;
+            return (IClassDefinition)hostComponentDef;
+        }
+        return null;
+    }
+
+    @Override
+    public boolean isInProject(ICompilerProject project)
+    {
+        if (!isImplicit())
+            return super.isInProject(project);
+        // The implicit definitions are shared amoungst all projects.
+        if (this == NULL)
+            return true;
+        if (this == VOID)
+            return true;
+        if (this == ANY_TYPE)
+            return true;
+        if (this == UNDEFINED)
+            return true;
+        // Some implicit class definition we have never seen before.
+        return false;
+    }
+}


Mime
View raw message