You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cd...@apache.org on 2014/07/22 15:35:56 UTC

[30/51] [partial] - Migrated the directory structure to a more Maven style structure. - Started migrating the Parser from Antlr2+3 and JFlex to Antlr4.

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/ModifiersSet.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/ModifiersSet.java b/compiler/src/main/java/org/apache/flex/compiler/common/ModifiersSet.java
new file mode 100644
index 0000000..679b46e
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/ModifiersSet.java
@@ -0,0 +1,126 @@
+/*
+ *
+ *  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.common;
+
+import java.util.ArrayList;
+
+import org.apache.flex.compiler.internal.tree.as.ModifierNode;
+
+/**
+ * Map for holding a set of modifiers
+ */
+public class ModifiersSet
+{
+    public ModifiersSet()
+    {
+    }
+
+    private short bits = 0;
+
+    private int start = -1;
+
+    /**
+     * Add another modifier keyword to the collection (and adjust the span
+     * accordingly)
+     * 
+     * @param modifier token holding modifier keyword
+     */
+    public void addModifier(ASModifier modifier)
+    {
+        bits |= modifier.getMaskValue();
+    }
+
+    /**
+     * Add another modifier keyword to the collection (and adjust the span
+     * accordingly)
+     * 
+     * @param modifier token holding modifier keyword
+     */
+    public void addModifier(ModifierNode modifier)
+    {
+        if (modifier.getModifier() != null)
+        {
+            bits |= modifier.getModifier().getMaskValue();
+            if ((start == -1 || modifier.getAbsoluteStart() < start) && modifier.getAbsoluteStart() > 0)
+                start = modifier.getAbsoluteStart();
+        }
+
+    }
+
+    public int getStart()
+    {
+        return start;
+    }
+
+    public boolean hasModifiers()
+    {
+        return Integer.bitCount(bits) > 0;
+    }
+
+    public ASModifier[] getAllModifiers()
+    {
+        ArrayList<ASModifier> retVal = new ArrayList<ASModifier>(ASModifier.MODIFIERS.length);
+        if (hasModifiers())
+        {
+            for (int i = 0; i < ASModifier.MODIFIERS.length; i++)
+            {
+                if ((bits & ASModifier.MODIFIERS[i].getMaskValue()) == ASModifier.MODIFIERS[i].getMaskValue())
+                {
+                    retVal.add(ASModifier.MODIFIERS[i]);
+                }
+            }
+        }
+        return retVal.toArray(new ASModifier[0]);
+    }
+
+    /**
+     * Is the given modifier in the set?
+     * 
+     * @return true if the modifier is included in the set
+     */
+    public boolean hasModifier(ASModifier modifier)
+    {
+        return (bits & modifier.getMaskValue()) == modifier.getMaskValue();
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (!(obj instanceof ModifiersSet))
+            return false;
+
+        return bits == ((ModifiersSet)obj).bits && start == ((ModifiersSet)obj).start;
+    }
+
+    /**
+     * For debugging only.
+     */
+    @Override
+    public String toString()
+    {
+        StringBuffer sb = new StringBuffer();
+        for (ASModifier modifier : getAllModifiers())
+        {
+            sb.append(modifier.toString());
+            sb.append(' ');
+        }
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/Multiname.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/Multiname.java b/compiler/src/main/java/org/apache/flex/compiler/common/Multiname.java
new file mode 100644
index 0000000..2f296f4
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/Multiname.java
@@ -0,0 +1,192 @@
+/*
+ *
+ *  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.common;
+
+import java.util.HashSet;
+import java.util.Set;
+
+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.compiler.definitions.INamespaceDefinition;
+import org.apache.flex.compiler.internal.definitions.NamespaceDefinition;
+import org.apache.flex.compiler.internal.workspaces.Workspace;
+import org.apache.flex.compiler.projects.ICompilerProject;
+import org.apache.flex.compiler.workspaces.IWorkspace;
+
+public final class Multiname
+{
+    /**
+     * Constructs a {@link Multiname} by parsing the specified name string.
+     * 
+     * @param project {@link ICompilerProject} whose {@link IWorkspace} is used
+     * to create package namespace definitions.
+     * @param name Either a simple definition name or a dotted qname.
+     * @return A new {@link Multiname} created from information in the specified
+     * name
+     */
+    public static Multiname crackDottedQName(ICompilerProject project, String name)
+    {
+        return crackDottedQName(project, name, false);
+    }
+    
+    /**
+     * Constructs a {@link Multiname} by parsing the specified name string.
+     * 
+     * @param project {@link ICompilerProject} whose {@link IWorkspace} is used
+     * to create package namespace definitions.
+     * @param name Either a simple definition name or a dotted qname.
+     * @param includeInternal true if package internal namespaces should be in
+     * the namespace set in the multiname.
+     * @return A new {@link Multiname} created from information in the specified
+     * name
+     */
+    public static Multiname crackDottedQName(ICompilerProject project, String name, boolean includeInternal)
+    {
+        Workspace workspace = (Workspace)project.getWorkspace();
+        final Set<INamespaceDefinition> namespaceSet = new HashSet<INamespaceDefinition>(includeInternal ? 2 : 1);
+        if (name != null)
+        {
+            int lastIndexOfDot = name != null ? name.lastIndexOf('.') : -1;
+            if (lastIndexOfDot != -1)
+            {
+                final String definitionName = name.substring(lastIndexOfDot + 1);
+                final String packageName = name.substring(0, lastIndexOfDot);
+                INamespaceDefinition publicPackageNS =
+                    workspace.getPackageNamespaceDefinitionCache().get(packageName, false);
+                namespaceSet.add(publicPackageNS);
+                if (includeInternal)
+                {
+                    INamespaceDefinition internalPackageNS =
+                        workspace.getPackageNamespaceDefinitionCache().get(packageName, true);
+                    namespaceSet.add(internalPackageNS);            
+                }
+                return new Multiname(namespaceSet, definitionName);
+            }
+        }
+
+        final INamespaceDefinition publicPackageNS = NamespaceDefinition.getPublicNamespaceDefinition();
+        namespaceSet.add(publicPackageNS);
+        if (includeInternal)
+        {
+            INamespaceDefinition internalPackageNS =
+                workspace.getPackageNamespaceDefinitionCache().get("", true);
+            namespaceSet.add(internalPackageNS);            
+        }
+        return new Multiname(namespaceSet, name);
+    }
+
+    /**
+     * Returns the package name part of a dotted fully qualified AS3 name. One
+     * thing this method is used for is to compute package names of mxml
+     * classes.
+     * 
+     * @param name A dotted fully qualified AS3 name
+     * @return The package name in the specified name.
+     */
+    public static String getPackageNameForQName(String name)
+    {
+        if (name == null)
+            return "";
+        int lastIndexOfDot = name.lastIndexOf('.');
+        if (lastIndexOfDot != -1)
+            return name.substring(0, lastIndexOfDot);
+        return "";
+    }
+    
+    /**
+     * Returns the base name part of a dotted fully qualified AS3 name. 
+     * 
+     * @param name A dotted fully qualified AS3 name
+     * @return The base name in the specified name.
+     */
+    public static String getBaseNameForQName(String name)
+    {
+        int lastIndexOfDot = name.lastIndexOf('.');
+        if (lastIndexOfDot != -1)
+            return name.substring(lastIndexOfDot + 1);
+        return name;
+    }
+    
+    public static Multiname create(Set<INamespaceDefinition> nsset, String baseName)
+    {
+        return new Multiname(nsset, baseName);
+    }
+    
+    public Multiname(Set<INamespaceDefinition> namespaceSet, String baseName)
+    {
+        this.namespaceSet = namespaceSet;
+        this.baseName = baseName;
+    }
+    
+    private final Set<INamespaceDefinition> namespaceSet;
+    private final String baseName;
+    
+    /**
+     * Gets the namespace set for this {@link Multiname}.
+     * @return The namespace set for this {@link Multiname}.
+     */
+    public Set<INamespaceDefinition> getNamespaceSet()
+    {
+        return namespaceSet;
+    }
+    
+    /**
+     * Gets the base name for this {@link Multiname}.
+     * @return The base name set for this {@link Multiname}.
+     */
+    public String getBaseName()
+    {
+        return baseName;
+    }
+    
+    /**
+     * Gets the AET name for this {@link Multiname}.
+     * @return A {@link Name} object.
+     */
+    public Name getMName()
+    {
+        Set<Namespace> namespaces = new HashSet<Namespace>(namespaceSet.size());
+        for ( INamespaceDefinition ns: namespaceSet )
+            namespaces.add( ((NamespaceDefinition)ns).getAETNamespace() );
+
+        return new Name(new Nsset(namespaces), getBaseName());
+    }
+    
+    /**
+     * For debugging only.
+     * <p>
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString()
+    {
+        StringBuilder builder = new StringBuilder();
+        builder.append('[');
+        for (INamespaceDefinition namespace : namespaceSet)
+        {
+            builder.append(namespace.toString());
+            builder.append(", ");
+        }
+        builder.append("]::");
+        builder.append(baseName);
+        return builder.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/MutablePrefixMap.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/MutablePrefixMap.java b/compiler/src/main/java/org/apache/flex/compiler/common/MutablePrefixMap.java
new file mode 100644
index 0000000..53c224b
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/MutablePrefixMap.java
@@ -0,0 +1,162 @@
+/*
+ *
+ *  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.common;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * This is a mutable version of a {@link PrefixMap} that allows additions and
+ * removals of namespaces
+ */
+public class MutablePrefixMap extends PrefixMap
+{
+    public MutablePrefixMap()
+    {
+        super();
+    }
+
+    public MutablePrefixMap(PrefixMap map)
+    {
+        PrefixMap clone = map.clone();
+        namespaceToPrefixMap = new HashMap<String, Set<String>>(clone.namespaceToPrefixMap);
+        prefixes = new HashSet<String>(clone.prefixes);
+    }
+
+    public MutablePrefixMap(String ns, String prefix)
+    {
+        add(ns, prefix);
+    }
+
+    /**
+     * Creates an immutable version of this prefix map
+     * 
+     * @return an immutable prefix map
+     */
+    public PrefixMap toImmutable()
+    {
+        PrefixMap map = new PrefixMap();
+        map.namespaceToPrefixMap = new HashMap<String, Set<String>>(namespaceToPrefixMap);
+        map.prefixes = new HashSet<String>(prefixes);
+        return map;
+    }
+
+    /**
+     * Add a prefix and its uri to the map.
+     * 
+     * @param prefix A namespace prefix string, such as <code>"fx"</code>.
+     * @param uri The corresponding namespace URI, such as <code>http://ns.adobe.com/mxml/2009</code>.
+     */
+    public void add(String prefix, String uri)
+    {
+        add(prefix, uri, false);
+    }
+
+    /**
+     * Adds a prefix and uri to this namespace map.
+     * 
+     * @param prefix the prefix to add
+     * @param uri the namespace to add for the given prefix
+     * @param onlyIfUnique If the mapping is not unique, it will be added only
+     * if this flag is set to false. A mapping is considering unique if a prefix
+     * has not already been defined
+     */
+    public void add(String prefix, String uri, boolean onlyIfUnique)
+    {
+        Set<String> list = namespaceToPrefixMap.get(uri);
+        if (list == null)
+        {
+            list = new LinkedHashSet<String>(1);
+            namespaceToPrefixMap.put(uri, list);
+        }
+        if (onlyIfUnique)
+        {
+            if (!list.contains(prefix))
+            {
+                list.add(prefix);
+                prefixes.add(prefix);
+            }
+        }
+        else
+        {
+            list.add(prefix);
+            prefixes.add(prefix);
+        }
+    }
+
+    /**
+     * Adds all information from one {@link PrefixMap} to another
+     * 
+     * @param map the {@link PrefixMap} where our data is coming from
+     * @param onlyIfUnique If the mapping is not unique, it will be added only
+     * if this flag is set to false. A mapping is considering unique if a prefix
+     * has not already been defined
+     */
+    public void addAll(PrefixMap map, boolean onlyIfUnique)
+    {
+        Iterator<String> it = map.namespaceToPrefixMap.keySet().iterator();
+        while (it.hasNext())
+        {
+            String ns = it.next();
+            Iterator<String> sItr = map.namespaceToPrefixMap.get(ns).iterator();
+            while (sItr.hasNext())
+            {
+                add(sItr.next(), ns, onlyIfUnique);
+            }
+        }
+    }
+
+    /**
+     * Adds all information from one {@link PrefixMap} to another
+     * 
+     * @param map the {@link PrefixMap} where our data is coming from
+     */
+    public void addAll(PrefixMap map)
+    {
+        Iterator<String> it = map.namespaceToPrefixMap.keySet().iterator();
+        while (it.hasNext())
+        {
+            String ns = it.next();
+            Iterator<String> sItr = map.namespaceToPrefixMap.get(ns).iterator();
+            while (sItr.hasNext())
+            {
+                add(sItr.next(), ns);
+            }
+        }
+    }
+
+    public void remove(String prefix)
+    {
+        Iterator<String> it = namespaceToPrefixMap.keySet().iterator();
+        while (it.hasNext())
+        {
+            String next = it.next();
+            Set<String> set = namespaceToPrefixMap.get(next);
+            if (set != null)
+            {
+                set.remove(prefix);
+            }
+        }
+        prefixes.remove(prefix);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/NodeReference.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/NodeReference.java b/compiler/src/main/java/org/apache/flex/compiler/common/NodeReference.java
new file mode 100644
index 0000000..b1c7da9
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/NodeReference.java
@@ -0,0 +1,242 @@
+/*
+ *
+ *  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.common;
+
+import org.apache.flex.compiler.filespecs.IFileSpecification;
+import org.apache.flex.compiler.internal.scopes.ASFileScope;
+import org.apache.flex.compiler.internal.scopes.ASScope;
+import org.apache.flex.compiler.tree.as.IASNode;
+import org.apache.flex.compiler.workspaces.IWorkspace;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Helper class to abstract the details of how we get back to Nodes from Definitions and NamespaceReferences.
+ *
+ * This class holds a WeakRef to the IASNode, and is able to regenerate the IASNode if needed after it has been collected.
+ */
+public class NodeReference
+{
+    /**
+     * Construct a NodeReference to the given node
+     * @param node  the node to references
+     */
+    public NodeReference(IASNode node)
+    {
+        absoluteStart = node.getAbsoluteStart();
+        nodeRef = new WeakReference<IASNode>(node);
+        fileSpec = node.getFileSpecification();
+    }
+    
+    /**
+     * Construct a NodeReference to a node in the specified file at the
+     * specified offset. This constructor is used from the MXMLScopeBuilder,
+     * where we only have temporary tree nodes.
+     * 
+     * @param containingFileSpec File that contains the node this reference
+     * refers to.
+     * @param absoluteStart The offset at which the node this reference refers to
+     * starts.
+     */
+    public NodeReference(IFileSpecification containingFileSpec, int absoluteStart)
+    {
+        this.absoluteStart = absoluteStart;
+        nodeRef = new WeakReference<IASNode>(null);
+        fileSpec = containingFileSpec;
+    }
+
+    // The node that produced this definition, if this definition came from source.
+    // This is stored as a weak reference so that symbol tables don't prevent ASTs
+    // from being garbage-collected.
+    // If the reference is lost, getNode() restores it by using
+    // 'fileSpec' to reparse the AST and 'start' to find the correct node in that AST.
+    private WeakReference<IASNode> nodeRef;
+
+    // The {@link IFileSpecification} from which this definition came.
+    private IFileSpecification fileSpec;
+
+    // The absolute starting offset of this definition.
+    private int absoluteStart = ISourceLocation.UNKNOWN;
+
+    /**
+     * Get the file spec for this Node
+     */
+    public IFileSpecification getFileSpecification()
+    {
+        return fileSpec;
+    }
+
+    /**
+     * Get the start offset for the node
+     */
+    public int getAbsoluteStart()
+    {
+        return absoluteStart;
+    }
+    
+    /**
+     * Finds the node closest to the root whose start offset is exactly the
+     * specified offset.
+     * <p>
+     * This method differs from
+     * {@link IASNode#getContainingNode(int)}
+     * in that it considers the start of a node to be contained by the node.
+     * 
+     * @param root Node to start the search at.
+     * @param absoluteOffset Start offset of the node to find.
+     * @return The node closest to the specified root node whose start offset is
+     * the specified offset, or null if no such node exists.
+     */
+    private static IASNode findNode(IASNode root, int absoluteOffset)
+    {
+        IASNode current = root;
+        assert root.getAbsoluteEnd() >= absoluteOffset;
+        
+        // These two nested while loops rely on the fact that
+        // the start and end offset of a node enclose the start
+        // offset of the nodes first child and the end offset of the
+        // nodes last child.
+        while ((current != null) && (current.getAbsoluteStart() != absoluteOffset))
+        {
+            assert current.getAbsoluteStart() < absoluteOffset;
+            assert current.getAbsoluteEnd() >= absoluteOffset;
+            int childCount = current.getChildCount();
+            int i = 0;
+            IASNode next = null;
+            // This inner loop computes which child node to descend to.
+            // We want to descend to the child contains the
+            // start offset.  The child nodes are always in file order,
+            // and their source ranges do not overlap.
+            while ((i < childCount) && (next == null))
+            {
+                IASNode currChild = current.getChild(i);
+                // Once we find a child that ends after the offset
+                // we are looking for, descend to that child.
+                if (currChild != null && currChild.getAbsoluteEnd() >= absoluteOffset)
+                    next = currChild; 
+                ++i;
+            }
+            current = next;
+        }
+        return current;
+    }
+
+    /**
+     * Get a strong reference to the Node.  If necessary this will reparse the file to find the correct Node.
+     * This method may return null, such as when document is so malformed
+     * that we can't produce a file node for it.
+     * (Note that MXMLScopeBuilder can produce definitions with NodeReferences into a malformed document.)
+     * @param workspace     the Workspace to use to parse the file
+     * @param scope         the containing scope of the definition we want the node for - this is used
+     *                      to find the ASFileScope it's contained in to reconnect the definitions and Nodes
+     *                      if the file needs to be reparsed
+     */
+    public IASNode getNode(IWorkspace workspace, ASScope scope)
+    {
+        // If this definition didn't come from source, return null.
+        if (fileSpec == null || absoluteStart == ISourceLocation.UNKNOWN)
+            return null;
+
+        // If the definition node is still weakly attached, return it.
+        IASNode node = nodeRef.get();
+        if (node != null)
+            return node;
+
+
+        // Reparse the file from which this definition came
+        // to create a new AST.
+        // TODO Detect whether the file has changed since the definition was created.
+        if( workspace != null )
+        {
+            ASScope s = scope;
+            ASFileScope fileScope = null;
+            // Get the file scope, and reconnect the AST to the definitions/scopes that
+            // already exist
+            while( s != null )
+            {
+                if( s instanceof ASFileScope )
+                {
+                    fileScope = (ASFileScope)s;
+                }
+                s = s.getContainingScope();
+            }
+            if( fileScope != null) {
+
+                // Grab the lock
+                synchronized (this)
+                {
+                    // Check again in case another thread already updated the node reference
+                    node = nodeRef.get();
+                    if(node != null )
+                        return node;
+
+                    // Get the file node from the file scope
+                    IASNode fileNode = fileScope.getNode();
+
+                    if (fileNode != null)
+                    {
+                        // Find the node that produced this definition,
+                        // using the starting offset stored in this definition.
+                        node = findNode(fileNode, absoluteStart);
+
+                        // Reattach a weak reference to the node.
+                        nodeRef = new WeakReference<IASNode>(node);
+                    }
+                }
+            }
+        }
+        return node;
+    }
+
+    /**
+     * Get the node from the underlying weak reference.  This will not do any parsing
+     * or any other work to recover the Node if it has been collected
+     * @return  the IASNode this reference refers to, or null if the Node no longer exists
+     */
+    public IASNode getNodeIfExists()
+    {
+        return nodeRef != null ? nodeRef.get() : null;
+    }
+    
+    /**
+     * Explicitly re-connect this node reference to the specified node.
+     * @param node The {@link IASNode} to re-connect this node reference to.
+     */
+    public void reconnectNode(IASNode node)
+    {
+        assert node.contains(absoluteStart);
+        nodeRef = new WeakReference<IASNode>(node);
+    }
+
+    /**
+     * static that represents no NodeReference (e.g. for defs that came from an ABC)
+     */
+    public static NodeReference noReference = new NodeReference();
+
+    /**
+     * Private ctor only used by the noReference instance.
+     */
+    private NodeReference()
+    {
+        this.nodeRef = null;
+        this.fileSpec = null;
+        this.absoluteStart = ISourceLocation.UNKNOWN;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/PrefixMap.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/PrefixMap.java b/compiler/src/main/java/org/apache/flex/compiler/common/PrefixMap.java
new file mode 100644
index 0000000..85c70a4
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/PrefixMap.java
@@ -0,0 +1,212 @@
+/*
+ *
+ *  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.common;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * A PrefixMap contains a collection of prefix to namespace mappings found in
+ * MXML documents. This object is <b>immutable</b>. For a mutable version, look
+ * at {@link MutablePrefixMap}
+ */
+public class PrefixMap implements Cloneable
+{
+    public PrefixMap()
+    {
+        super();
+    }
+
+    public PrefixMap(PrefixMap map)
+    {
+        namespaceToPrefixMap = new HashMap<String, Set<String>>(map.namespaceToPrefixMap);
+        prefixes = new HashSet<String>(map.prefixes);
+    }
+
+    protected HashMap<String, Set<String>> namespaceToPrefixMap = new HashMap<String, Set<String>>();
+
+    protected HashSet<String> prefixes = new HashSet<String>();
+
+    @Override
+    public PrefixMap clone()
+    {
+        PrefixMap result = new PrefixMap();
+
+        result.namespaceToPrefixMap = new HashMap<String, Set<String>>();
+
+        // copy values here as there is an internal set involved here
+        Iterator<String> it = namespaceToPrefixMap.keySet().iterator();
+        while (it.hasNext())
+        {
+            String next = it.next();
+            Set<String> set = namespaceToPrefixMap.get(next);
+            if (set != null)
+            {
+                Set<String> prefixSet = new LinkedHashSet<String>();
+                Iterator<String> setIt = set.iterator();
+                while (setIt.hasNext())
+                {
+                    String prefix = setIt.next();
+                    prefixSet.add(prefix);
+                }
+                result.namespaceToPrefixMap.put(next, prefixSet);
+            }
+        }
+
+        result.prefixes = new HashSet<String>(prefixes);
+        return result;
+    }
+
+    /**
+     * Creates a mutable copy of this PrefixMap, based on its values
+     * 
+     * @return a mutable version of this prefix map
+     */
+    public MutablePrefixMap toMutable()
+    {
+        return new MutablePrefixMap(this.clone());
+    }
+
+    /**
+     * Returns the namespace for the given prefix. The first prefix found in the
+     * map will win
+     * 
+     * @param prefix the prefix to find out namespace for
+     * @return a namespace URI or null
+     */
+    public String getNamespaceForPrefix(String prefix)
+    {
+        Iterator<String> it = namespaceToPrefixMap.keySet().iterator();
+        while (it.hasNext())
+        {
+            String next = it.next();
+            Set<String> set = namespaceToPrefixMap.get(next);
+            if (set != null)
+            {
+                if (set.contains(prefix))
+                {
+                    return next;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns true if the given prefix exists somewhere in this map
+     * 
+     * @param prefix A namespace prefix string such as <code>"fx"</code>.
+     */
+    public boolean containsPrefix(String prefix)
+    {
+        return prefixes.contains(prefix);
+    }
+
+    /**
+     * Checks whether the map contains a reference to the given namespace.
+     * 
+     * @param namespace URI of a namespace.
+     */
+    public boolean containsNamespace(String namespace)
+    {
+        return namespaceToPrefixMap.containsKey(namespace);
+    }
+
+    /**
+     * Returns all the prefixes known to this map.
+     */
+    public String[] getAllPrefixes()
+    {
+        return prefixes.toArray(new String[0]);
+    }
+
+    /**
+     * Returns all the namespace URIs known to this map
+     */
+    public String[] getAllNamespaces()
+    {
+        return namespaceToPrefixMap.keySet().toArray(new String[0]);
+    }
+
+    /**
+     * Returns the prefix that is used to reference the given namespace URI.
+     * 
+     * @param uri A namespace URI such as <code>"http://ns.adobe.com/mxml/2009"</code>.
+     */
+    public String[] getPrefixesForNamespace(String uri)
+    {
+        Set<String> set = namespaceToPrefixMap.get(uri);
+        if (set != null)
+            return set.toArray(new String[0]);
+        return new String[0];
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (obj instanceof PrefixMap)
+        {
+            PrefixMap right = (PrefixMap)obj;
+            if (right.namespaceToPrefixMap.size() != namespaceToPrefixMap.size())
+            {
+                return false;
+            }
+            if (right.prefixes.size() != prefixes.size())
+            {
+                return false;
+            }
+
+            Iterator<String> prefixItr = right.prefixes.iterator();
+            while (prefixItr.hasNext())
+            {
+                if (!prefixes.contains(prefixItr.next()))
+                {
+                    return false;
+                }
+            }
+
+            Iterator<String> nsItr = right.namespaceToPrefixMap.keySet().iterator();
+            while (nsItr.hasNext())
+            {
+                String next = nsItr.next();
+                Set<String> set = namespaceToPrefixMap.get(next);
+                Set<String> rSet = right.namespaceToPrefixMap.get(next);
+                if (set == null)
+                {
+                    return false;
+                }
+                Iterator<String> pItr = rSet.iterator();
+                while (pItr.hasNext())
+                {
+                    if (!set.contains(pItr.next()))
+                    {
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+
+        return super.equals(obj);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/PrefixedXMLName.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/PrefixedXMLName.java b/compiler/src/main/java/org/apache/flex/compiler/common/PrefixedXMLName.java
new file mode 100644
index 0000000..afcd6f9
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/PrefixedXMLName.java
@@ -0,0 +1,185 @@
+/*
+ *
+ *  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.common;
+
+import org.apache.flex.compiler.constants.IMXMLCoreConstants;
+import org.apache.flex.compiler.internal.mxml.MXMLData;
+
+/**
+ * A subclass of XMLName used by clients that need to manipulate the actual
+ * syntactic form of the element name (including its prefix). Most clients of
+ * codemodel/mxmlmodel should use XMLName instead, and rely on the full
+ * namespace URI; the specific namespace prefix that's on a given element in a
+ * given document has no meaning outside that document. In particular, no one
+ * should ever assume that "mx:" is the prefix being used for the Flex
+ * namespace.
+ */
+public class PrefixedXMLName extends XMLName
+{
+    /**
+     * Constructor This version will parse the containingDocument on the fly (or
+     * use an existing parse, if there is already one in the MXMLDataProvider).
+     * 
+     * @param rawName full element name (e.g. mx:Button)
+     * @param mxmlData MXMLData containing the element
+     */
+    public PrefixedXMLName(String rawName, MXMLData mxmlData)
+    {
+        name = splitName(rawName);
+        assert name != null;
+        xmlNamespace = resolvePrefix(prefix, mxmlData);
+        if (xmlNamespace == null)
+            xmlNamespace = IMXMLCoreConstants.emptyString;
+    }
+
+    /**
+     * Constructor
+     * 
+     * @param rawName full element name (e.g. mx:Button)
+     * @param prefixMap map of element prefixes to XML namespaces
+     */
+    public PrefixedXMLName(String rawName, PrefixMap prefixMap)
+    {
+        name = splitName(rawName);
+        assert name != null;
+        xmlNamespace = prefixMap.getNamespaceForPrefix(prefix);
+        if (xmlNamespace == null)
+            xmlNamespace = IMXMLCoreConstants.emptyString;
+    }
+
+    public PrefixedXMLName(String rawName, String uri)
+    {
+        name = splitName(rawName);
+        xmlNamespace = uri;
+    }
+
+    /**
+     * Constructor used when we already know the specific namespace and prefix
+     * being used by a particular instance of an XML element.
+     * 
+     * @param xmlNamespace the namespace URI
+     * @param name the unprefixed element name
+     * @param rawName the prefixed element name (e.g. mx:Button)
+     */
+    public PrefixedXMLName(String xmlNamespace, String name, String rawName)
+    {
+        splitName(rawName);
+        this.name = name;
+        assert name != null;
+        this.xmlNamespace = (xmlNamespace == null) ? IMXMLCoreConstants.emptyString : xmlNamespace;
+    }
+
+    /**
+     * Prefix from the intial lookup. Only accurate when in the context of a
+     * document.
+     */
+    private String prefix;
+
+    /**
+     * Cached value of the full name. It's ok to cache this because we can't
+     * ever change the name, namespace, or prefix after this object is
+     * constructed.
+     */
+    private String prefixedName;
+
+    /**
+     * Split a raw tag name (e.g. mx:Button) into a prefix (mx) and short name
+     * (Button). The prefix is stored in fPrefix, and the short name is
+     * returned. For use in constructors.
+     * 
+     * @param rawName full element name (e.g. mx:Button)
+     * @return short name (e.g. Button)
+     */
+    private String splitName(String rawName)
+    {
+        String name;
+
+        if (rawName == null)
+        {
+            prefix = IMXMLCoreConstants.emptyString;
+            return IMXMLCoreConstants.emptyString;
+        }
+
+        int colonIndex = rawName.indexOf(IMXMLCoreConstants.colon);
+        if (colonIndex > -1)
+        {
+            prefix = rawName.substring(0, colonIndex);
+            name = rawName.substring(colonIndex + 1);
+        }
+        else
+        {
+            prefix = IMXMLCoreConstants.emptyString;
+            name = rawName;
+        }
+
+        return name;
+    }
+
+    /**
+     * Determine which XML namespace is appropriate for the given prefix in the
+     * given document
+     * 
+     * @param prefix element prefix
+     * @param mxmlData containing MXMLData
+     * @return XML namespaces
+     */
+    protected String resolvePrefix(String prefix, MXMLData mxmlData)
+    {
+        return resolvePrefix(prefix, mxmlData.getRootTagPrefixMap());
+    }
+
+    /**
+     * Determine which XML namespace is appropriate for the given prefix in the
+     * given prefix map
+     */
+    protected String resolvePrefix(String prefix, PrefixMap prefixMap)
+    {
+        if (prefixMap.containsPrefix(prefix))
+            return prefixMap.getNamespaceForPrefix(prefix);
+
+        return IMXMLCoreConstants.emptyString;
+    }
+
+    /**
+     * Get the prefix for the element
+     * 
+     * @return the prefix
+     */
+    public String getPrefix()
+    {
+        return prefix;
+    }
+
+    /**
+     * Return the prefixed version of the name.
+     */
+    public String getPrefixedName()
+    {
+        if (prefixedName != null)
+            return prefixedName;
+        
+        if (prefix != null && !prefix.equals(IMXMLCoreConstants.emptyString))
+            prefixedName = (prefix + IMXMLCoreConstants.colon + getName()).intern();
+        else
+            prefixedName = getName();
+        
+        return prefixedName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/RecursionGuard.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/RecursionGuard.java b/compiler/src/main/java/org/apache/flex/compiler/common/RecursionGuard.java
new file mode 100644
index 0000000..dc82334
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/RecursionGuard.java
@@ -0,0 +1,66 @@
+/*
+ *
+ *  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.common;
+
+import java.util.HashSet;
+
+import org.apache.flex.compiler.definitions.IDefinition;
+
+/**
+ * Recursion guard that can be used throughout code model to make sure we don't infinitely recurse when
+ * performing type lookups, etc.  Since user code is not guaranteed to follow language rules, these are very important to avoid loops.
+ */
+public class RecursionGuard {
+	
+	public HashSet<IDefinition> visitedDefinitions;
+	public boolean foundLoop = false;
+	
+	public RecursionGuard()
+	{
+		visitedDefinitions = null;
+	}
+	
+	public RecursionGuard( RecursionGuard other)
+	{
+	    this.foundLoop = other.foundLoop;
+	    if (other.visitedDefinitions != null)
+	        this.visitedDefinitions = new HashSet<IDefinition>(other.visitedDefinitions);
+	}
+	
+	/**
+	 * Create a guard that is pre-populated with the passed in definition.  the definition will be considered visited
+	 * @param initialDefinition the {@link IDefinition} to mark as visited
+	 */
+	public RecursionGuard(IDefinition initialDefinition)
+	{
+		visitedDefinitions = new HashSet<IDefinition>();
+		visitedDefinitions.add(initialDefinition);
+	}
+	
+	public boolean isLoop(IDefinition target) {
+        if(visitedDefinitions == null)
+        	visitedDefinitions = new HashSet<IDefinition>();
+        if (visitedDefinitions.add(target))
+        	return false;
+        
+        foundLoop = true;
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/SourceLocation.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/SourceLocation.java b/compiler/src/main/java/org/apache/flex/compiler/common/SourceLocation.java
new file mode 100644
index 0000000..88998b7
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/SourceLocation.java
@@ -0,0 +1,361 @@
+/*
+ *
+ *  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.common;
+
+import org.apache.flex.utils.FilenameNormalization;
+
+/**
+ * Common class to store file/location information across all source types
+ * such as AS, CSS etc
+ */
+public class SourceLocation implements ISourceLocation
+{
+    /**
+     * Constructor for a known source location.
+     */
+    public SourceLocation(String sourcePath, int start, int end, int line, int column)
+    {
+        this.sourcePath = sourcePath;
+        this.start = start;
+        this.end = end;
+        this.line = line;
+        this.column = column;
+    }
+    
+    /**
+     * Copy Constructor for a known source location.
+     */
+    public SourceLocation(ISourceLocation location)
+    {
+        this(location.getSourcePath(),
+             location.getStart(),
+             location.getEnd(),
+             location.getLine(),
+             location.getColumn());
+    }
+
+    /**
+     * Constructor for an unknown source location.
+     */
+    public SourceLocation()
+    {
+        this(null, UNKNOWN, UNKNOWN, UNKNOWN, UNKNOWN);
+    }
+
+    /**
+     * Source path.
+     */
+    private String sourcePath;
+
+    /**
+     * Zero-based starting offset.
+     * <p>
+     * This class does not distinguish between local and absolute offsets,
+     * but subclasses may. If so, they should store the absolute starting
+     * offset in this field and use it to compute the local starting offset.
+     */
+    private int start;
+    
+    /**
+     * Zero-based ending offset.
+     * <p>
+     * This class does not distinguish between local and absolute offsets,
+     * but subclasses may. If so, they should store the absolute ending
+     * offset in this field and use it to compute the local ending offset.
+     */
+    private int end;
+    
+    /**
+     * Zero-based line number.
+     * Corresponds to start, not end.
+     */
+    private int line;
+    
+    /**
+     * Zero-based column number.
+     * Corresponds to start, not end.
+     */
+    private int column;
+    
+    /**
+     * Copies source location information from another instance
+     * into this instance.
+     */
+    public final void setSourceLocation(ISourceLocation src)
+    {
+        assert src != null : "source location can't be null";
+        
+        this.start = src.getStart();
+        this.end = src.getEnd();
+        this.line = src.getLine();
+        this.column = src.getColumn();
+        this.sourcePath = src.getSourcePath();
+    }
+
+    /**
+     * @return The local start offset
+     */
+    @Override
+    public int getStart()
+    {
+        assert start >= 0 || start == UNKNOWN : "Invalid value for start: " + start;
+        return start;
+    }
+
+    /**
+     * @return The absolute start offset.
+     */
+    @Override
+    public int getAbsoluteStart()
+    {
+        assert start >= 0 || start == UNKNOWN : "Invalid value for start: " + start;
+        return start;
+    }
+    
+    /**
+     * @return The absolute end offset.
+     */
+    @Override
+    public int getAbsoluteEnd()
+    {
+        assert end >= 0 || end == UNKNOWN : "Invalid value for end: " + end;
+        return end;
+    }
+    
+    /**
+     * Set the absolute offset where this node starts.
+     */
+    public void setStart(int start)
+    {
+        if (start != UNKNOWN)
+            this.start = start;
+    }
+
+    /**
+     * @return The local end offset.
+     */
+    @Override
+    public int getEnd()
+    {
+        assert end >= 0 || end == UNKNOWN : "Invalid value for end: " + end;
+        return end;
+    }
+
+    /**
+     * Set the absolute offset where this node ends.
+     */
+    public void setEnd(int end)
+    {
+        if (end != UNKNOWN)
+            this.end = end;
+    }
+
+    /**
+     * Get the line number where this node starts.
+     * Line numbers start at 0, not 1.
+     * @return The line number
+     */
+    @Override
+    public int getLine()
+    {
+        assert line >= 0 || line == UNKNOWN : "Invalid value for line: " + line;
+        return line;
+    }
+
+    /**
+     * Set the line number where this node starts.
+     * Column numbers start at 0, not 1.
+     * @param line The line number
+     */
+    public void setLine(int line)
+    {
+        if (line != UNKNOWN)
+            this.line = line;
+    }
+
+    /**
+     * Get the column number where this node starts.
+     * @return The column number
+     */
+    @Override
+    public int getColumn()
+    {
+        assert column >= 0 || column == UNKNOWN : "Invalid value for column: " + column;
+        return column;
+    }
+
+    /**
+     * Set the column number where this node starts.
+     * @param column The column number
+     */
+    public void setColumn(int column)
+    {
+        if (column != UNKNOWN)
+            this.column = column;
+    }
+
+    /**
+     * Get the source path for this node.
+     * @return The source path for this node
+     */
+    @Override
+    public final String getSourcePath()
+    {
+        // null means the source is unknown.
+        // "" means the source is a buffer that hasn't yet been saved to a file.
+        // Something like "framework.swc:defaults.css" means the source is a file inside a SWC.
+        // TODO Shouldn't the part before the colon be normalized?
+        // Anything else should be a normalized path to a source file.
+        assert sourcePath == null ||
+               sourcePath.isEmpty() ||
+               sourcePath.contains(".swc:") ||
+               FilenameNormalization.isNormalized(sourcePath)  :
+               "Invalid value for sourcePath: " + sourcePath;
+        return sourcePath;
+    }
+
+    /**
+     * Set the source path of the node.
+     * @param sourcePath The source path
+     */
+    public final void setSourcePath(String sourcePath)
+    {
+        this.sourcePath = sourcePath;
+    }
+    
+    /**
+     * Displays line, column, start, end, and sourcepath in a format such as 
+     * <pre>
+     * "17:5 160-188 C:\test.as"
+     * </pre>
+     */
+    @Override
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getLineColumnString());
+        sb.append(getOffsetsString());
+        sb.append(getSourcePathString());
+        return sb.toString();
+    }
+
+    /**
+     * Displays Line and Column numbers
+     */
+    protected String getLineColumnString()
+    {
+        StringBuilder sb = new StringBuilder();
+        int line = getLine();
+        if (line != UNKNOWN)
+            sb.append(line);
+        else
+            sb.append('?');
+        sb.append(':');
+        int column = getColumn();
+        if (column != UNKNOWN)
+            sb.append(column);
+        else
+            sb.append('?');
+        
+        sb.append(' ');
+        return sb.toString();
+    }
+
+    /**
+     * Displays sourcepath
+     * 
+     */
+    protected String getSourcePathString()
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append(' ');
+        
+        String sourcePath = getSourcePath();
+        if (sourcePath != null)
+            sb.append(sourcePath);
+        else
+            sb.append('?');
+        return sb.toString();
+    }
+
+    /**
+     * Displays line, column, start, end
+     * 
+     */
+    protected String getOffsetsString()
+    {
+        StringBuilder sb = new StringBuilder();
+        sb.append("loc: ");
+        int start = getStart();
+        if (start != UNKNOWN)
+            sb.append(start);
+        else
+            sb.append('?');
+        sb.append('-');
+        int end = getEnd();
+        if (end != UNKNOWN)
+            sb.append(end);
+        else
+            sb.append('?');
+        
+        sb.append(' ');
+
+        sb.append("abs: ");
+        int absoluteStart = getAbsoluteStart();
+        if (absoluteStart != UNKNOWN)
+            sb.append(absoluteStart);
+        else
+            sb.append('?');
+        sb.append('-');
+        int absoluteEnd = getAbsoluteEnd();
+        if (absoluteEnd != UNKNOWN)
+            sb.append(absoluteEnd);
+        else
+            sb.append('?');
+        return sb.toString();
+    }
+   
+    
+    /**
+     * Span the location range from {@code start} to {@code end}.
+     * 
+     * @param start Start location.
+     * @param end End location.
+     */
+    public final void span(ISourceLocation start, ISourceLocation end)
+    {
+        setSourcePath(start.getSourcePath());
+        setStart(start.getStart());
+        setEnd(end.getEnd());
+        setLine(start.getLine());
+        setColumn(start.getColumn());
+    }
+    
+    /**
+     * Span the location range from {@code start} to {@code end}.
+     * 
+     * @param location The location
+     */
+    public final void span(ISourceLocation location)
+    {
+        if (location != null)
+            setSourceLocation(location);
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/VersionInfo.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/VersionInfo.java b/compiler/src/main/java/org/apache/flex/compiler/common/VersionInfo.java
new file mode 100644
index 0000000..3c1c2af
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/VersionInfo.java
@@ -0,0 +1,379 @@
+/*
+ *
+ *  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.common;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.apache.flex.utils.Trace;
+
+/**
+ * A helper class for querying build number, Flex version, and library
+ * version information.
+ */
+public class VersionInfo
+{
+    public static final String FLEX_MAJOR_VERSION = "4";
+    public static final String FLEX_MINOR_VERSION = "7";
+    public static final String FLEX_NANO_VERSION  = "0";
+    
+	/**
+	 * Lib version is the "version" of the SWC format. Major number changes represent big (although not
+	 * by definition incompatble) changes, such as bytecode format revs. Minor number changes are intended
+	 * to represent easy-to-support modifications. The only universal rule is that the compiler will warn
+	 * when a "future" major version is found in a SWC that's being read in.
+	 *
+	 * It's expected that incompatible changes will arise. Ad-hoc guard code will be added to implement those
+	 * dividing lines. The way the code is currently laid out, these would probably be implemented in SWC.read(),
+	 * but in any case they should be finable by looking at the callers of VersionInfo.getLibVersion().
+	 *
+     * <li>
+     * Version 1.2: Add &lt;keep-as3-metadata&gt; container to catalog.xml to perserve metadata
+     * </li>
+	 * <li>
+	 * Version 1.1: Add &lt;digest&gt; container to catalog xml for cross-domain rsls support.
+	 * 		        Add "signatureChecksum" attribute to "script" element.
+     * 
+	 * </li>
+	 * <li>
+	 * Version 1.0: Initial version.
+	 * </li>
+	 * 
+	 */
+    public static final String LIB_VERSION_1_0 = "1.0";
+    public static final String LIB_VERSION_1_1 = "1.1";
+    public static final String LIB_VERSION_1_2 = "1.2";
+    
+	public static final String LIB_MAJOR_VERSION = "1";
+	public static final String LIB_MINOR_VERSION = "2";
+
+    //
+    // Strings used for the rdf/xml tag written into a SWF via the Metadata
+    // tag.
+	//
+    /**
+     * Element containing version information.  
+     */
+    public static final String COMPILER_ELEMENT = "compiler";
+    
+    /**
+     * Product name of the compiler that compiled the SWF.
+     */
+    public static final String COMPILER_NAME_ATTRIBUTE = "name";
+
+    /**
+     * Version of the compiler that compiled the SWF.
+     */
+    public static final String COMPILER_VERSION_ATTRIBUTE = "version";
+
+    /**
+     * Build number of the compiler that compiled the SWF.
+     */
+    public static final String COMPILER_BUILD_ATTRIBUTE = "build";
+    
+    /**
+     * Namespace of the "compiler" element.
+     */
+	public static final String COMPILER_NAMESPACE_URI = "http://ns.adobe.com/asc/2012";
+
+	/**
+     * Prefix of the the compiler's namespace URI.
+     */
+    public static final String COMPILER_NAMESPACE_PREFIX = "asc";
+	
+	//Cache this info as it should not change during the time class is loaded
+    static String BUILD_MESSAGE;
+    static String BUILD_NUMBER_STRING;
+	static String FLEX_VERSION_NUMBER;
+	static String LIB_VERSION_NUMBER;
+	static boolean useFlexMessageFormat;
+	
+	public static String buildMessage()
+    {
+        if (BUILD_MESSAGE == null)
+        {
+            try
+            {
+                //Ensure we've parsed build info
+                getBuild();
+
+                // If there is a version.properties file then build the message
+                // the way flex used to. Otherwise use the information from
+                // the compiler's jar file.
+                if (useFlexMessageFormat)
+                {
+                    String buildNum = BUILD_NUMBER_STRING;
+                    BUILD_MESSAGE = "Version " + FLEX_MAJOR_VERSION + "." + FLEX_MINOR_VERSION +
+                             "." + FLEX_NANO_VERSION + " build " + buildNum;                    
+                }
+                else
+                {
+                    BUILD_MESSAGE = "Version " + getCompilerVersion() + " build " +
+                    getCompilerBuild();                    
+                }
+
+            }
+            catch (Throwable t)
+            {
+                if (Trace.error)
+                {
+                    t.printStackTrace();
+                }
+                BUILD_MESSAGE = "build information unavailable";
+            }
+        }
+
+        return BUILD_MESSAGE;
+    }
+
+    public static String getBuild()
+    {
+        if (BUILD_NUMBER_STRING == null)
+        {
+            BUILD_NUMBER_STRING = "";
+
+            InputStream in = null;
+            try
+            {
+                Properties p = new Properties();
+                in = VersionInfo.class.getResourceAsStream("version.properties");
+
+                String build = "";
+                if (in != null)
+                {
+                    p.load(in);                
+                    build = p.getProperty("build");
+                    useFlexMessageFormat = true;
+                }
+                else
+                {
+                    build =  VersionInfo.class.getPackage().getImplementationVersion();
+                }
+
+                if ((build != null) && (! build.equals("")))
+                {
+                    // In open source builds the build number has changed from an
+                    // integer to a string of dot separated integers.
+                    // for example: 191195 -> 3.0.0.97
+                    int dot_index = build.lastIndexOf(".");
+                    if (dot_index != -1) 
+                    {
+                        build = build.substring(dot_index + 1);
+                    }
+                    BUILD_NUMBER_STRING = build;
+                }
+            }
+            catch (Throwable t)
+            {
+                if (Trace.error)
+                {
+                    t.printStackTrace();
+                }
+            }
+            finally
+            {
+                if (in != null)
+                {
+                    try
+                    {
+                        in.close();
+                    }
+                    catch (IOException ex)
+                    {
+                    }
+                }
+            }
+        }
+
+        return BUILD_NUMBER_STRING;
+    }
+
+    /**
+     * Get the build number as a long.
+     * 
+     * @return build number as a long, 0 if the build number was not available.
+     */
+    public static long getBuildLong()
+    {
+        long buildNum = 0;
+        try
+        {
+            buildNum = Long.parseLong(getBuild());
+        }
+        catch (NumberFormatException e)
+        {
+            // ignore, return value will be 0.
+        }
+            
+        return buildNum;
+    }
+    
+	public static String getFlexVersion()
+	{
+	    if (FLEX_VERSION_NUMBER == null)
+	    {
+	    	FLEX_VERSION_NUMBER = FLEX_MAJOR_VERSION + "." + FLEX_MINOR_VERSION +
+                                  "." + FLEX_NANO_VERSION;
+	    }
+	    return FLEX_VERSION_NUMBER;
+	}
+
+	public static String getLibVersion()
+	{
+	    if (LIB_VERSION_NUMBER == null)
+	    {
+	    	LIB_VERSION_NUMBER = LIB_MAJOR_VERSION + "." + LIB_MINOR_VERSION;
+	    }
+	    return LIB_VERSION_NUMBER;
+	}
+	
+	/**
+	 * The name of the compiler.
+	 * 
+	 * @return name of the compiler.
+	 */
+	public static String getCompilerName()
+	{
+	    String title = VersionInfo.class.getPackage().getImplementationTitle();
+	    return title != null ? title : "";
+	}
+
+    /**
+     * The version of the compiler. Includes the major, minor, and nano versions
+     * separates by dots. For example, 4.7.0. The compiler version number comes
+     * from information from the manifest.mf file where as the Flex version
+     * number is hard-coded in this file.
+     * 
+     * @return version of the compiler.
+     */
+	public static String getCompilerVersion()
+	{
+        String version = VersionInfo.class.getPackage().getImplementationVersion();
+        
+        if ((version != null) && (!version.equals("")))
+        {
+            // remove the build number from the version.
+            // major.minor.nano.build -> major.minor.nano
+            int dot_index = version.lastIndexOf(".");
+            if (dot_index != -1) 
+                version = version.substring(0, dot_index);
+        }
+        
+        return version != null ? version : "";
+	}
+
+    /**
+     * The build number of the compiler. Can be converted to a long. The
+     * compiler build number comes from information from the manifest.mf file
+     * where as the Flex build number comes from a properties file.
+     * 
+     * @return the build number of the compiler.
+     */
+    public static String getCompilerBuild()
+    {
+        String build =  VersionInfo.class.getPackage().getImplementationVersion();
+    
+        if ((build != null) && (! build.equals("")))
+        {
+            // Change major.minor.nano.build -> build
+            int dot_index = build.lastIndexOf(".");
+            if (dot_index != -1) 
+                build = build.substring(dot_index + 1);
+        }
+     
+        return build != null ? build : "";
+    }  
+    
+	/**
+	 * 
+	 * @param swcLibVersion - library version to compare with the current library version.
+	 * @param compareMajorVersion - if true, compare only the major versions. Otherwise compare 
+	 * 								both major and minor versions.
+	 * @return true if the given library version is greater than the compiled in library version. 
+	 */
+	public static boolean IsNewerLibVersion(String swcLibVersion, boolean compareMajorVersion)
+	{
+        return compareVersions(swcLibVersion, getLibVersion(), compareMajorVersion) > 0;
+	}
+    
+
+    /**
+     * Compare two version strings that are in at "Major.minor" format.
+     * 
+     * Examples) "1.0", "1.1"
+     * 
+     * @param version1 first version
+     * @param version2 second version
+     * @param compareMajorVersion compare only the major versions, disregarding the minor version.
+     * 
+     * @return zero if the versions are equal 
+     *         less than zero if version1 is less than version2 
+     *         greater than zero if version1 is greater than version2
+     */
+    public static int compareVersions(String version1, String version2,  boolean compareMajorVersion)
+    {
+        // C: change this implementation if the lib version changes from the a.b format to the a.b.c. format.
+        //    Obviously, a.b.c is not a number!
+        
+        double v1 = 0, v2 = 0;
+
+        try
+        {
+            v1 = Double.parseDouble(version1);
+        }
+        catch (NumberFormatException ex)
+        {
+            if (Trace.error)
+            {
+                ex.printStackTrace();
+            }
+        }
+
+        try
+        {
+            v2 = Double.parseDouble(version2);
+        }
+        catch (NumberFormatException ex)
+        {
+            if (Trace.error)
+            {
+                ex.printStackTrace();
+            }
+        }
+        
+        if (compareMajorVersion) 
+        {
+            v1 = Math.floor(v1);
+            v2 = Math.floor(v2);
+        }
+        
+        if (v1 == v2) 
+        {
+            return 0;
+        }
+        else if (v1 < v2)
+        {
+            return -1;
+        }
+            
+        return 1;
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/XMLName.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/XMLName.java b/compiler/src/main/java/org/apache/flex/compiler/common/XMLName.java
new file mode 100644
index 0000000..5ab2eb5
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/XMLName.java
@@ -0,0 +1,147 @@
+/*
+ *
+ *  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.common;
+
+/**
+ * Qualified element name (XML namespace and local name). This does not contain
+ * information about the namespace prefix that may be used on the element in a
+ * given document-- that's a transient syntactic detail; clients should rely on
+ * the namespace URI to disambiguate elements.
+ */
+public class XMLName implements Comparable<XMLName>
+{
+    public static final XMLName NULL_NAME = new XMLName("");
+
+    /**
+     * Constructor
+     * 
+     * @param xmlNamespace XML namespace for element (e.g.
+     * http://foo.adobe.com/2006/mxml or shared.*)
+     * @param name element name without prefix (e.g. Button)
+     */
+    public XMLName(String xmlNamespace, String name)
+    {
+        this.name = (name == null) ? "" : name;
+        this.xmlNamespace = (xmlNamespace == null) ? "" : xmlNamespace;
+    }
+
+    /**
+     * Constructor that assumes an empty namespace.
+     * 
+     * @param name element name without prefix (e.g. Button)
+     */
+    public XMLName(String name)
+    {
+        this.name = (name == null) ? "" : name;
+        this.xmlNamespace = "";
+    }
+
+    /**
+     * Constructor for use by our subclasses
+     */
+    protected XMLName()
+    {
+        // This stub function is the default constructor, only used by our subclasses.
+    }
+
+    /**
+     * XML namespace
+     */
+    protected String xmlNamespace;
+
+    /**
+     * Local element name (unqualified)
+     */
+    protected String name;
+
+    /**
+     * Get the element's unqualified local name
+     * 
+     * @return local name
+     */
+    public String getName()
+    {
+        return name;
+    }
+
+    /**
+     * Get the XML namespace for the element (e.g.
+     * http://foo.adobe.com/2006/mxml or shared.*)
+     * 
+     * @return XML namespace
+     */
+    public String getXMLNamespace()
+    {
+        return xmlNamespace;
+    }
+
+    /**
+     * Dump the XMLName as a string (for debugging)
+     * 
+     * @return string representation of the name
+     */
+    @Override
+    public String toString()
+    {
+        String retVal = null;
+        if (!xmlNamespace.equals(""))
+            retVal = xmlNamespace + ":" + name;
+        else
+            retVal = name;
+
+        return retVal;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        // use better hashcode impl to avoid all the unneeded recomputation and storage of additional field
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((xmlNamespace == null) ? 0 : xmlNamespace.hashCode());
+        return result;
+    }
+
+    /**
+     * Does this element name equal the one that's passed in?
+     * 
+     * @return true if the element names are equal
+     */
+    @Override
+    public boolean equals(Object other)
+    {
+        if (!(other instanceof XMLName))
+            return false;
+        XMLName xmlOther = (XMLName)other;
+
+        // All the code in XMLName and PrefixedXMLName makes sure that fName and fXMLNamespace
+        // are both non-null, so we don't have to check for null here.
+        if (!name.equals(xmlOther.name))
+            return false;
+        return xmlNamespace.equals(xmlOther.xmlNamespace);
+    }
+
+    @Override
+    public int compareTo(XMLName o)
+    {
+        return toString().compareTo(o.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/common/package.html
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/common/package.html b/compiler/src/main/java/org/apache/flex/compiler/common/package.html
new file mode 100644
index 0000000..fefcf66
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/common/package.html
@@ -0,0 +1,27 @@
+<!--
+
+  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.
+
+-->
+
+<html>
+<body>
+
+This package contains miscellaneous classes and interfaces
+used by other compiler packages.
+
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/59f6373b/compiler/src/main/java/org/apache/flex/compiler/config/ApplicationDomainTarget.java
----------------------------------------------------------------------
diff --git a/compiler/src/main/java/org/apache/flex/compiler/config/ApplicationDomainTarget.java b/compiler/src/main/java/org/apache/flex/compiler/config/ApplicationDomainTarget.java
new file mode 100644
index 0000000..de0555d
--- /dev/null
+++ b/compiler/src/main/java/org/apache/flex/compiler/config/ApplicationDomainTarget.java
@@ -0,0 +1,79 @@
+/*
+ *
+ *  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.config;
+
+/**
+ *  The ApplicationDomainTarget enum defines the possible values of the 
+ *  application domain an RSL can be loaded into at runtime.
+ *  The application domain target specifies a relative application 
+ *  domain that is resolved at runtime.
+ */
+public enum ApplicationDomainTarget
+{
+    /**
+     *  The default behavior for RSL loading is to load an RSL as high in 
+     *  the parent module factory chain as possible. In order to load an RSL
+     *  into a parent module factory, that module factory must have been 
+     *  compiled with that RSL specified in the compiler options. If no parent module 
+     *  factories were compiled with that RSL , then the RSL will be loaded in
+     *  the application domain of the module factory loading the RSL.
+     */
+    DEFAULT("default"),
+    
+    /**
+     *  The application domain of the current module factory.
+     */
+    CURRENT("current"),
+    
+    /**
+     *  The application domain of the parent module factory.
+     */
+    PARENT("parent"),
+    
+    /**
+     *  The application domain of the top-level module factory.
+     */
+    TOP_LEVEL("top-level");
+    
+    
+    private String applicationDomainValue;
+
+    /**
+     * Not for public consumption.
+     * 
+     * @param applicationDomainValue
+     */
+    private ApplicationDomainTarget( String applicationDomainValue )
+    {
+        this.applicationDomainValue = applicationDomainValue;
+    }
+
+    /**
+     * The value the Flex runtime understands.
+     * 
+     * @return The {@link String} value of the enum.
+     */
+    public String getApplicationDomainValue()
+    {
+        return applicationDomainValue;
+    }
+    
+
+}