Package flex2.compiler.as3

Source Code of flex2.compiler.as3.AbstractSyntaxTreeUtil

/*
*
*  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 flex2.compiler.as3;

import flex2.compiler.Logger;
import flex2.compiler.Source;
import flex2.compiler.mxml.lang.StandardDefs;
import flex2.compiler.util.QName;
import flex2.compiler.util.ThreadLocalToolkit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import macromedia.asc.embedding.ConfigVar;
import macromedia.asc.parser.*;
import macromedia.asc.semantics.NamespaceValue;
import macromedia.asc.semantics.ReferenceValue;
import macromedia.asc.util.Context;
import macromedia.asc.util.ContextStatics;
import macromedia.asc.util.Namespaces;
import macromedia.asc.util.ObjectList;

/**
* This class contains a collection of utility methods used during
* direct AST generation, which allows the compiler to go from MXML
* straight to an ASC AST, skipping the .as intermediate state.
*
* @author Paul Reilly
* @see flex2.copmiler.as3.binding.BindableSecondPassEvaluator
* @see flex2.copmiler.as3.binding.DataBindingExtension
* @see flex2.compiler.mxml.ImplementationGenerator
* @see flex2.compiler.mxml.InterfaceGenerator
* @see flex2.compiler.mxml.gen/StatesGenerator
* @see flex2.compiler.mxml.rep.init.EventInitializer
* @see flex2.compiler.mxml.rep.init.VisualChildInitializer
* @see flex2.compiler.mxml.rep.init.VisualInitializer
*/

public class AbstractSyntaxTreeUtil
{
    private static final String DOT = ".";
    private static final String DOUBLE_COLON = "::";
    private static final String LESS_THAN = "<";
    private static final String GREATER_THAN = ">";

    // intern all identifier constants
    private static final String __AS3__ = "__AS3__".intern();
    private static final String CONFIG = "CONFIG".intern();
    private static final String MX_INTERNAL = "mx_internal".intern();
    private static final String OVERRIDE = "override".intern();
    private static final String PRIVATE = "private".intern();
    private static final String PROTECTED = "protected".intern();
    private static final String PRIVATE_DOC_COMMENT = "<description><![CDATA[\n ]]></description>\n<private><![CDATA[ ]]></private>";
    private static final String INHERIT_DOC_COMMENT = "<description><![CDATA[\n ]]></description>\n<inheritDoc><![CDATA[ ]]></inheritDoc>";
    private static final String PUBLIC = "public".intern();
    private static final String STATIC = "static".intern();
    private static final String VEC = "vec".intern();
    private static final String VECTOR = "Vector".intern();

    public static ApplyTypeExprNode generateApplyTypeExpr(NodeFactory nodeFactory, String type)
    {
        IdentifierNode identifier = generateIdentifier(nodeFactory, VECTOR, false);
        TypeExpressionNode typeExpression = generateTypeExpression(nodeFactory, type, true, true);
        ListNode typeArgs = nodeFactory.list(null, typeExpression);
        return (ApplyTypeExprNode) nodeFactory.applyTypeExpr(identifier, typeArgs, -1);
    }

    public static ApplyTypeExprNode generateApplyTypeExpr(NodeFactory nodeFactory, String type,
                                                          int lessThanIndex)
    {
        String vectorType = type.substring(0, lessThanIndex - 1);
        int dotIndex = vectorType.lastIndexOf(DOT);
        IdentifierNode identifier;

        if (dotIndex > 0)
        {
            identifier = generateQualifiedIdentifier(nodeFactory, vectorType.substring(0, dotIndex),
                                                     vectorType.substring(dotIndex + 1), true);
        }
        else
        {
            identifier = generateIdentifier(nodeFactory, vectorType, true);
        }

        int greaterThanIndex = type.lastIndexOf(GREATER_THAN);
        String elementType = type.substring(lessThanIndex + 1, greaterThanIndex);
        TypeExpressionNode typeExpression =
            generateTypeExpression(nodeFactory, elementType, true, true);
        ListNode typeArgs = nodeFactory.list(null, typeExpression);
        return (ApplyTypeExprNode) nodeFactory.applyTypeExpr(identifier, typeArgs, -1);
    }

    public static ExpressionStatementNode generateAssignment(NodeFactory nodeFactory, String lvalue,
                                                             String rvalue)
    {
        IdentifierNode lvalueIdentifier = nodeFactory.identifier(lvalue);
        IdentifierNode rvalueIdentifier = nodeFactory.identifier(rvalue);
        GetExpressionNode getExpression = nodeFactory.getExpression(rvalueIdentifier);
        MemberExpressionNode rvalueMemberExpression = nodeFactory.memberExpression(null, getExpression);
        ArgumentListNode argumentList = nodeFactory.argumentList(null, rvalueMemberExpression);
        // Set the position to a non-zero value, so that LintEvaluator doesn't skip reporting warnings.
        SetExpressionNode setExpression = nodeFactory.setExpression(lvalueIdentifier, argumentList, false, 1);
        MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, setExpression);
        ListNode list = nodeFactory.list(null, memberExpression);
        return nodeFactory.expressionStatement(list);
    }

    public static ExpressionStatementNode generateAssignment(NodeFactory nodeFactory, Node base,
                                                             String lvalue, Node rvalue)
    {
        IdentifierNode lvalueIdentifier = nodeFactory.identifier(lvalue);
        ArgumentListNode argumentList = nodeFactory.argumentList(null, rvalue);
        // Set the position to a non-zero value, so that LintEvaluator doesn't skip reporting warnings.
        SetExpressionNode setExpression = nodeFactory.setExpression(lvalueIdentifier, argumentList, false, 1);
        MemberExpressionNode memberExpression = nodeFactory.memberExpression(base, setExpression);
        ListNode list = nodeFactory.list(null, memberExpression);
        return nodeFactory.expressionStatement(list);
    }

    public static ClassDefinitionNode generateClassDefinition(Context context, String className,
                                                              String baseClassName, Set<String> interfaceNames,
                                                              StatementListNode statementList)
    {
        NodeFactory nodeFactory = context.getNodeFactory();
        nodeFactory.StartClassDefs();
        ListNode interfaces = null;
        Iterator<String> iterator = interfaceNames.iterator();

        while (iterator.hasNext())
        {
            String interfaceName = iterator.next();
            int index = interfaceName.lastIndexOf(DOT);

            if (index > 0)
            {
                interfaces = nodeFactory.list(interfaces,
                                              generateGetterSelector(nodeFactory,
                                                                     interfaceName.substring(0, index),
                                                                     interfaceName.substring(index + 1),
                                                                     true));
            }
            else
            {
                interfaces = nodeFactory.list(interfaces, generateGetterSelector(nodeFactory,
                                                                                 interfaceName,
                                                                                 true));
            }
        }

        InheritanceNode inheritance;
        int index = baseClassName.lastIndexOf(DOT);

        if (index > 0)
        {
            inheritance = nodeFactory.inheritance(generateGetterSelector(nodeFactory,
                                                                         baseClassName.substring(0, index),
                                                                         baseClassName.substring(index + 1),
                                                                         true),
                                                  interfaces);
        }
        else
        {
            inheritance = nodeFactory.inheritance(generateGetterSelector(nodeFactory,
                                                                         baseClassName,
                                                                         true),
                                                  interfaces);
        }

        ClassDefinitionNode classDefinition = nodeFactory.classDefinition(context,
                                                                          generatePublicAttribute(nodeFactory),
                                                                          generatePublicQualifiedIdentifier(nodeFactory,
                                                                                                            className),
                                                                          inheritance,
                                                                          statementList);

        return classDefinition;
    }

    public static FunctionDefinitionNode generateConstructor(Context context, String className,
                                 ParameterListNode parameterList,
                                                             boolean generateSuperCall,
                                                             StatementListNode statementList,
                                                             int position)
    {
        NodeFactory nodeFactory = context.getNodeFactory();
        AttributeListNode attributeList = generatePublicAttribute(nodeFactory);
        IdentifierNode identifier = nodeFactory.identifier(className);
        FunctionNameNode functionName = nodeFactory.functionName(Tokens.EMPTY_TOKEN, identifier);
        FunctionSignatureNode functionSignature = nodeFactory.functionSignature(parameterList, null);
        functionSignature.no_anno = true;

        if (generateSuperCall)
        {
            SuperExpressionNode superExpression = nodeFactory.superExpression(null, -1);
            CallExpressionNode callExpression = (CallExpressionNode) nodeFactory.callExpression(superExpression, null);
            SuperStatementNode superStatement = nodeFactory.superStatement(callExpression);

            if (statementList != null)
            {
                statementList.items.add(0, superStatement);
            }
            else
            {
                statementList = nodeFactory.statementList(null, superStatement);
            }
        }

        FunctionCommonNode functionCommon =
            nodeFactory.functionCommon(context, identifier, functionSignature,
                                       statementList, position);
        functionCommon.setUserDefinedBody(true);

        return nodeFactory.functionDefinition(context, attributeList, functionName, functionCommon);
    }

    public static Context generateContext(ContextStatics contextStatics, Source source, BytecodeEmitter emitter,
                                          ObjectList<ConfigVar> defines)
    {
        Context result = new Context(contextStatics);
        result.setOrigin(source.getBackingFile().getName());
        result.setScriptName(source.getBackingFile().getName());
        result.setPath(source.getBackingFile().getParent());
        result.setEmitter(emitter);
        result.setHandler(new As3Compiler.CompilerHandler(source));
        result.input = new CodeFragmentsInputBuffer(source.getBackingFile().getName());

        if (defines != null)
        {
            result.config_vars.addAll(defines);
        }

        return result;
    }

    /**
     * @param comment This is assumed to be interned.
     */
    public static DocCommentNode generateDocComment(NodeFactory nodeFactory, String comment)
    {
        LiteralStringNode literalString = nodeFactory.literalString(comment, false);
        ListNode list = nodeFactory.list(null, literalString);
        LiteralXMLNode literalXML = nodeFactory.literalXML(list, false, -1);
        GetExpressionNode getExpression = nodeFactory.getExpression(literalXML);
        MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, getExpression);
        ArgumentListNode argumentList = nodeFactory.argumentList(null, memberExpression);
        LiteralArrayNode literalArray = nodeFactory.literalArray(argumentList);
        return nodeFactory.docComment(literalArray, -1);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>name</code>
     *               is interned.  If <code>name</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static MemberExpressionNode generateGetterSelector(NodeFactory nodeFactory,
                                                              String name,
                                                              boolean intern)
    {
        return generateGetterSelector(nodeFactory, name, intern, -1);
    }

    public static MemberExpressionNode generateGetterSelector(NodeFactory nodeFactory,
            String name, boolean intern, int position)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, intern, position);
        GetExpressionNode getExpression = nodeFactory.getExpression(identifier);
        return nodeFactory.memberExpression(null, getExpression);
    }
   
    /**
     * @param intern Hint to ASC for controlling if <code>name</code>
     *               is interned.  If <code>name</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static MemberExpressionNode generateGetterSelector(NodeFactory nodeFactory,
                                                              String qualifier,
                                                              String name,
                                                              boolean intern)
    {
        QualifiedIdentifierNode qualifiedIdentifier =
            generateQualifiedIdentifier(nodeFactory, qualifier, name, intern);
        GetExpressionNode getExpression = nodeFactory.getExpression(qualifiedIdentifier);
        return nodeFactory.memberExpression(null, getExpression);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>name</code>
     *               is interned.  If <code>name</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static MemberExpressionNode generateGetterSelector(NodeFactory nodeFactory,
                                                              MemberExpressionNode qualifier,
                                                              String name,
                                                              boolean intern)
    {
        QualifiedIdentifierNode qualifiedIdentifier =
            generateQualifiedIdentifier(nodeFactory, qualifier, name, intern);
        GetExpressionNode getExpression = nodeFactory.getExpression(qualifiedIdentifier);
        return nodeFactory.memberExpression(null, getExpression);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>name</code>
     *               is interned.  If <code>name</code> is a constant,
     *               <code>intern</code> should be false.  If <code>name</name> is
     *               qualified, the <code>intern</code> flag is ignored and set to
     *               true.
     */
    public static IdentifierNode generateIdentifier(NodeFactory nodeFactory, String name,
                                                    boolean intern)
    {
        IdentifierNode result;
        int index = name.lastIndexOf(DOT);

        if (index > -1)
        {
            result = generateQualifiedIdentifier(nodeFactory, name.substring(0, index),
                                                 name.substring(index + 1), true);
        }
        else
        {
            index = name.indexOf(DOUBLE_COLON);

            if (index > -1)
            {
                MemberExpressionNode memberExpression =
                    generateGetterSelector(nodeFactory, name.substring(0, index), true);
                result = generateQualifiedIdentifier(nodeFactory, memberExpression,
                                                     name.substring(index + 2), true);
            }
            else
            {
                result = nodeFactory.identifier(name, intern);
            }
        }

        return result;
    }

    public static IdentifierNode generateIdentifier(NodeFactory nodeFactory, QName qName,
                                                    boolean intern)
    {
        IdentifierNode result;

        if (qName.getNamespace().length() > 0)
        {
            MemberExpressionNode memberExpression =
                generateGetterSelector(nodeFactory, qName.getNamespace(), intern);
            result = generateQualifiedIdentifier(nodeFactory, memberExpression,
                                                 qName.getLocalPart(), intern);
        }
        else
        {
            result = nodeFactory.identifier(qName.getLocalPart(), intern);
        }

        return result;
    }

    private static StatementListNode generateImplicitNamespaces(Context context, StatementListNode statementList)
    {
        StatementListNode result = statementList;
        NodeFactory nodeFactory = context.getNodeFactory();

        if (context.statics.es4_vectors)
        {
            IdentifierNode as3Identifier = nodeFactory.identifier(__AS3__, false);
            PackageIdentifiersNode packageIdentifiers = nodeFactory.packageIdentifiers(null, as3Identifier, true);
            IdentifierNode vecIdentifier = nodeFactory.identifier(VEC, false);
            packageIdentifiers = nodeFactory.packageIdentifiers(packageIdentifiers, vecIdentifier, true);
            IdentifierNode vectorIdentifier = nodeFactory.identifier(VECTOR, false);
            packageIdentifiers = nodeFactory.packageIdentifiers(packageIdentifiers, vectorIdentifier, true);
            PackageNameNode packageName = nodeFactory.packageName(packageIdentifiers);
            ImportDirectiveNode importDirective = nodeFactory.importDirective(null, packageName, null, context);
            result = nodeFactory.statementList(result, importDirective);
        }

        if (!context.statics.use_namespaces.isEmpty())
        {
            for (String useName : context.statics.use_namespaces)
            {
                IdentifierNode identifier = nodeFactory.identifier(useName);
                GetExpressionNode getExpression = nodeFactory.getExpression(identifier);
                MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, getExpression);
                result = nodeFactory.statementList(result, nodeFactory.useDirective(null, memberExpression));
            }
        }

        result = nodeFactory.statementList(result, Parser.generateAs3UseDirective(context));

        return result;
    }

    public static ImportDirectiveNode generateImport(Context context, String name)
    {
        return generateImport(context, name, -1);
    }

    public static ImportDirectiveNode generateImport(Context context, String[] splitName)
    {
      return generateImport(context, splitName, -1);
    }

    public static ImportDirectiveNode generateImport(Context context, String name, int position)
    {
        NodeFactory nodeFactory = context.getNodeFactory();
        PackageNameNode packageName = generatePackageName(nodeFactory, name, true, position);
        return nodeFactory.importDirective(null, packageName, null, context);
    }

    public static ImportDirectiveNode generateImport(Context context, String[] splitName, int position)
    {
        NodeFactory nodeFactory = context.getNodeFactory();
        PackageNameNode packageName = generatePackageName(nodeFactory, splitName, true, position);
        return nodeFactory.importDirective(null, packageName, null, context);
    }
       
    public static MemberExpressionNode generateMemberExpression(NodeFactory nodeFactory,
                                                                String expression, int position)
    {
        MemberExpressionNode result;
        int lessThanIndex = expression.indexOf(LESS_THAN);

        if (lessThanIndex != -1)
        {
            // Handle Vector.<foo.Bar>
            String vectorString = expression.substring(0, lessThanIndex - 1);
            MemberExpressionNode base = generateGetterSelector(nodeFactory, vectorString, true);
            String elementString = expression.substring(lessThanIndex + 1, expression.length() - 1);
            ApplyTypeExprNode selector = generateApplyTypeExpr(nodeFactory, elementString);
            selector.setRValue(false);
            result = nodeFactory.memberExpression(base, selector, position);
        }
        else
        {
            int lastDotIndex = expression.lastIndexOf(DOT);

            if (lastDotIndex != -1)
            {
                // Handle a.b.C
                String baseString = expression.substring(0, lastDotIndex);
                MemberExpressionNode base = generateGetterSelector(nodeFactory, baseString, true, position);
                String selectorString = expression.substring(lastDotIndex + 1);
                IdentifierNode identifier = nodeFactory.identifier(selectorString, position);
                GetExpressionNode selector = nodeFactory.getExpression(identifier, position);
                selector.setRValue(false);
                result = nodeFactory.memberExpression(base, selector, position);
                result.setPositionTerminal(position);
            }
            else
            {
                result = generateGetterSelector(nodeFactory, expression, true, position);
            }
        }

        return result;
    }

    public static MemberExpressionNode generateMemberExpression(NodeFactory nodeFactory,
            String expression)
    {
      return generateMemberExpression(nodeFactory, expression, -1);
    }
   
    /**
     * @param name This is assumed to be interned.
     */
    public static MetaDataNode generateMetaData(NodeFactory nodeFactory, String name)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        GetExpressionNode getExpression = nodeFactory.getExpression(identifier);
        MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, getExpression);
        ArgumentListNode argumentList = nodeFactory.argumentList(null, memberExpression);
        LiteralArrayNode literalArray = nodeFactory.literalArray(argumentList);
        return nodeFactory.metaData(literalArray, -1);
    }

    /**
     * @param name This is assumed to be interned.
     * @param value This is assumed to be interned.
     */
    public static MetaDataNode generateMetaData(NodeFactory nodeFactory, String name,
                                                String value)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        LiteralStringNode literalString = nodeFactory.literalString(value, false);
        ArgumentListNode callExpressionArgumentList = nodeFactory.argumentList(null, literalString);
        CallExpressionNode callExpression =
            (CallExpressionNode) nodeFactory.callExpression(identifier, callExpressionArgumentList);
        callExpression.setRValue(false);
        MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, callExpression);
        ArgumentListNode argumentList = nodeFactory.argumentList(null, memberExpression);
        LiteralArrayNode literalArray = nodeFactory.literalArray(argumentList);
        return nodeFactory.metaData(literalArray, -1);
    }

    /**
     * @param name This is assumed to be interned.
     * @param key This is assumed to be interned.
     */
    public static MetaDataNode generateMetaData(NodeFactory nodeFactory, String name,
                                                String key, String value)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);

        IdentifierNode attributeIdentifier = nodeFactory.identifier(key, false);
        LiteralStringNode literalString = nodeFactory.literalString(value);
        ArgumentListNode attributeArgumentList = nodeFactory.argumentList(null, literalString);
        SetExpressionNode setExpression = nodeFactory.setExpression(attributeIdentifier,
                                                                    attributeArgumentList, false);
        MemberExpressionNode keyValueMemberExpression = nodeFactory.memberExpression(null, setExpression);
        ArgumentListNode callExpressionArgumentList = nodeFactory.argumentList(null, keyValueMemberExpression);

        CallExpressionNode callExpression =
            (CallExpressionNode) nodeFactory.callExpression(identifier, callExpressionArgumentList);
        callExpression.setRValue(false);
        MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, callExpression);
        ArgumentListNode argumentList = nodeFactory.argumentList(null, memberExpression);
        LiteralArrayNode literalArray = nodeFactory.literalArray(argumentList);
        return nodeFactory.metaData(literalArray, -1);
    }

    /**
     * @param name This is assumed to be interned.
     */
    public static MetaDataNode generateMetaData(NodeFactory nodeFactory, String name,
                                                Map<String, Object> attributes)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        ArgumentListNode callExpressionArgumentList = null;

        Iterator<Map.Entry<String, Object>> iterator = attributes.entrySet().iterator();

        while (iterator.hasNext())
        {
            Map.Entry<String, Object> entry = iterator.next();
            IdentifierNode attributeIdentifier = nodeFactory.identifier(entry.getKey());
            LiteralStringNode literalString = nodeFactory.literalString(entry.getValue().toString());
            ArgumentListNode attributeArgumentList = nodeFactory.argumentList(null, literalString);
            SetExpressionNode setExpression = nodeFactory.setExpression(attributeIdentifier,
                                                                        attributeArgumentList, false);
            MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, setExpression);
            callExpressionArgumentList = nodeFactory.argumentList(callExpressionArgumentList,
                                                                  memberExpression);
        }

        CallExpressionNode callExpression =
            (CallExpressionNode) nodeFactory.callExpression(identifier, callExpressionArgumentList);
        callExpression.setRValue(false);
        MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, callExpression);
        ArgumentListNode argumentList = nodeFactory.argumentList(null, memberExpression);
        LiteralArrayNode literalArray = nodeFactory.literalArray(argumentList);
        return nodeFactory.metaData(literalArray, -1);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>name</code>
     *               is interned.  If <code>name</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static QualifiedIdentifierNode generateMxInternalQualifiedIdentifier(NodeFactory nodeFactory,
                                                                                String name,
                                                                                boolean intern)
    {
        if (intern)
        {
            name = name.intern();
        }

        StandardDefs standardDefs = ThreadLocalToolkit.getStandardDefs();
        MemberExpressionNode mxInternalGetterSelector =
            generateResolvedGetterSelector(nodeFactory, standardDefs.getCorePackage(), MX_INTERNAL);
        return nodeFactory.qualifiedIdentifier(mxInternalGetterSelector, name);
    }

    public static AttributeListNode generateOverridePublicAttribute(NodeFactory nodeFactory)
    {
        IdentifierNode identifier = nodeFactory.identifier(PUBLIC, false);
        AttributeListNode attributeList = nodeFactory.attributeList(identifier, null);
        MemberExpressionNode memberExpression =
            generateGetterSelector(nodeFactory, OVERRIDE, false);
        ListNode list = nodeFactory.list(null, memberExpression);
        attributeList = nodeFactory.attributeList(list, attributeList);
        return attributeList;
    }

    public static PackageNameNode generatePackageName(NodeFactory nodeFactory, String name,
                                                      boolean isDefinition, int position)
    {
        Scanner scanner = new Scanner(name).useDelimiter("\\.");
        PackageIdentifiersNode packageIdentifiers = null;

        if (scanner.hasNext())
        {
            while (scanner.hasNext())
            {
                IdentifierNode identifier = nodeFactory.identifier(scanner.next());
                packageIdentifiers = nodeFactory.packageIdentifiers(packageIdentifiers, identifier,
                                                                    isDefinition);
            }
        }
        else
        {
            IdentifierNode identifier = nodeFactory.identifier(name);
            packageIdentifiers = nodeFactory.packageIdentifiers(packageIdentifiers, identifier,
                                                                isDefinition);
        }

        return nodeFactory.packageName(packageIdentifiers, position);
    }

    /**
     * @param splitName Each element assumed to be interned.
     */
    public static PackageNameNode generatePackageName(NodeFactory nodeFactory, String[] splitName,
                                                      boolean isDefinition, int position)
    {
        PackageIdentifiersNode packageIdentifiers = null;

        for (int i = 0; i < splitName.length; i++)
        {
            assert splitName[i].intern() == splitName[i];
            IdentifierNode identifier = nodeFactory.identifier(splitName[i], false);
            packageIdentifiers = nodeFactory.packageIdentifiers(packageIdentifiers, identifier,
                                                                isDefinition);
        }

        return nodeFactory.packageName(packageIdentifiers, position);
    }

    /**
     * @param name This is assumed to be interned.
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>internType</code> should be false.
     */
    public static ParameterNode generateParameter(NodeFactory nodeFactory, String name,
                                                  String type, boolean internType)
    {
        return generateParameter(nodeFactory, name, type, internType, -1);
    }

    /**
     * @param name This is assumed to be interned.
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>internType</code> should be false.
     */
    public static ParameterNode generateParameter(NodeFactory nodeFactory, String name,
                                                  String type, boolean internType, int position)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        TypeExpressionNode typeExpression = generateTypeExpression(nodeFactory, type, internType);
        return nodeFactory.parameter(Tokens.VAR_TOKEN, identifier, typeExpression);
    }

    /**
     * @param name This is assumed to be interned.
     * @param internType Hint to ASC for controlling if <code>type</code>
     *                   is interned.  If <code>type</code> is a constant,
     *                   <code>internType</code> should be false.
     */
    public static ParameterNode generateParameter(NodeFactory nodeFactory, String name,
                                                  String type, boolean internType,
                                                  Node init)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        TypeExpressionNode typeExpression = generateTypeExpression(nodeFactory, type, internType);
        return nodeFactory.parameter(Tokens.VAR_TOKEN, identifier, typeExpression, init);
    }

    public static ParameterNode generateParameter(NodeFactory nodeFactory, String name,
                                                  String typeNamespace, String typeName,
                                                  boolean internType)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        TypeExpressionNode typeExpression =
            generateTypeExpression(nodeFactory, typeNamespace, typeName, internType);
        return nodeFactory.parameter(Tokens.VAR_TOKEN, identifier, typeExpression);
    }

    public static DocCommentNode generatePrivateDocComment(NodeFactory nodeFactory)
    {
        return generateDocComment(nodeFactory, PRIVATE_DOC_COMMENT);
    }
   
    public static DocCommentNode generateInheritDocComment(NodeFactory nodeFactory)
    {
        return generateDocComment(nodeFactory, INHERIT_DOC_COMMENT);
    }

    public static Node generatePrivateVariable(NodeFactory nodeFactory,
                                               TypeExpressionNode typeExpression,
                                               String name)
    {
        return generatePrivateVariable(nodeFactory, typeExpression, name, null);
    }

    public static Node generatePrivateVariable(NodeFactory nodeFactory,
                                               TypeExpressionNode typeExpression,
                                               String name,
                                               Node initializer)
    {
        AttributeListNode attributeList = generatePrivateAttribute(nodeFactory);
        int kind = Tokens.VAR_TOKEN;
        QualifiedIdentifierNode qualifiedIdentifier =
            generatePrivateQualifiedIdentifier(nodeFactory, name);
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(qualifiedIdentifier,
                                                                          typeExpression);
        VariableBindingNode variableBinding = nodeFactory.variableBinding(attributeList, kind,
                                                                          typedIdentifier, initializer);
        ListNode list = nodeFactory.list(null, variableBinding);
        return nodeFactory.variableDefinition(attributeList, kind, list);
    }

    public static AttributeListNode generatePrivateAttribute(NodeFactory nodeFactory)
    {
        ListNode list = nodeFactory.list(null, generateGetterSelector(nodeFactory, PRIVATE, false));
        AttributeListNode attributeList = nodeFactory.attributeList(list, null);
        return attributeList;
    }

    public static QualifiedIdentifierNode generatePrivateQualifiedIdentifier(NodeFactory nodeFactory, String name)
    {
        return nodeFactory.qualifiedIdentifier(generatePrivateAttribute(nodeFactory), name.intern());
    }

    public static AttributeListNode generatePrivateStaticAttribute(NodeFactory nodeFactory)
    {
        MemberExpressionNode memberExpression = generateGetterSelector(nodeFactory, STATIC, false);
        AttributeListNode attributeList = nodeFactory.attributeList(memberExpression, null);
        ListNode list = nodeFactory.list(null, generateGetterSelector(nodeFactory, PRIVATE, false));
        attributeList = nodeFactory.attributeList(list, attributeList);
        return attributeList;
    }

    public static ProgramNode generateProgram(Context context, StatementListNode configVars, String packageNameString)
    {
        return generateProgram(context, configVars, packageNameString, null, -1);
    }

    public static ProgramNode generateProgram(Context context, StatementListNode configVars, String packageNameString,
                                              DocCommentNode packageDocComment, int lineNumber)
    {
        NodeFactory nodeFactory = context.getNodeFactory();

        IdentifierNode configIdentifier = nodeFactory.identifier(CONFIG, false);
        NamespaceDefinitionNode configNamespaceDefinition = nodeFactory.configNamespaceDefinition(null, configIdentifier, -1);
        StatementListNode statementList = nodeFactory.statementList(null, configNamespaceDefinition);

        if ((context.config_vars != null) && (context.config_vars.size() > 0))
        {
            statementList.items.addAll(0, configVars.items);
        }

        statementList = generateImplicitNamespaces(context, statementList);

        if (packageDocComment != null)
        {
            statementList = nodeFactory.statementList(statementList, packageDocComment);
        }

        PackageNameNode packageName = generatePackageName(nodeFactory, packageNameString, false, -1);
        PackageDefinitionNode packageDefinition = nodeFactory.startPackage(context, null, packageName);
        statementList = nodeFactory.statementList(statementList, packageDefinition);
        statementList = generateImplicitNamespaces(context, statementList);
       
        int position = -1;

        if (lineNumber != -1)
            position = AbstractSyntaxTreeUtil.lineNumberToPosition(nodeFactory, lineNumber);

        return nodeFactory.program(context, statementList, position);
    }

    public static AttributeListNode generatePublicAttribute(NodeFactory nodeFactory)
    {
        ListNode list = nodeFactory.list(null, generateGetterSelector(nodeFactory, PUBLIC, false));
        AttributeListNode attributeList = nodeFactory.attributeList(list, null);
        return attributeList;
    }
   
    public static AttributeListNode generateProtectedAttribute(NodeFactory nodeFactory)
    {
        ListNode list = nodeFactory.list(null, generateGetterSelector(nodeFactory, PROTECTED, false));
        AttributeListNode attributeList = nodeFactory.attributeList(list, null);
        return attributeList;
    }

    public static QualifiedIdentifierNode generatePublicQualifiedIdentifier(NodeFactory nodeFactory,
                                                                            String name)
    {
        return nodeFactory.qualifiedIdentifier(generatePublicAttribute(nodeFactory), name.intern());
    }
   
    public static QualifiedIdentifierNode generateProtectedQualifiedIdentifier(NodeFactory nodeFactory,
            String name)
    {
      return nodeFactory.qualifiedIdentifier(generateProtectedAttribute(nodeFactory), name.intern());
  }

    public static AttributeListNode generatePublicStaticAttribute(NodeFactory nodeFactory)
    {
        MemberExpressionNode memberExpression = generateGetterSelector(nodeFactory, STATIC, false);
        AttributeListNode attributeList = nodeFactory.attributeList(memberExpression, null);
        ListNode list = nodeFactory.list(null, generateGetterSelector(nodeFactory, PUBLIC, false));
        attributeList = nodeFactory.attributeList(list, attributeList);
        return attributeList;
    }

    public static VariableDefinitionNode generatePublicVariable(Context context, TypeExpressionNode typeExpression, String name)
    {
        return generatePublicVariable(context, typeExpression, name, null);
    }

    public static VariableDefinitionNode generatePublicVariable(Context context, TypeExpressionNode typeExpression,
                                              String name, MemberExpressionNode initializer)
    {
        NodeFactory nodeFactory = context.getNodeFactory();
        AttributeListNode attributeList = generatePublicAttribute(nodeFactory);
        int kind = Tokens.VAR_TOKEN;
        QualifiedIdentifierNode qualifiedIdentifier = generatePublicQualifiedIdentifier(nodeFactory, name);
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(qualifiedIdentifier, typeExpression);
        VariableBindingNode variableBinding = nodeFactory.variableBinding(attributeList, kind, typedIdentifier, initializer);
        ListNode list = nodeFactory.list(null, variableBinding);
        return nodeFactory.variableDefinition(attributeList, kind, list);
    }
   
    public static Node generatePrivateStaticVariable(Context context, TypeExpressionNode typeExpression, String name, Node initializer)
    {
        NodeFactory nodeFactory = context.getNodeFactory();
        AttributeListNode attributeList = generatePrivateStaticAttribute(nodeFactory);
        int kind = Tokens.VAR_TOKEN;
        QualifiedIdentifierNode qualifiedIdentifier = generatePublicQualifiedIdentifier(nodeFactory, name);
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(qualifiedIdentifier, typeExpression);
        VariableBindingNode variableBinding = nodeFactory.variableBinding(attributeList, kind, typedIdentifier, initializer);
        ListNode list = nodeFactory.list(null, variableBinding);
        return nodeFactory.variableDefinition(attributeList, kind, list);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>name</code>
     *               is interned.  If <code>name</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static QualifiedIdentifierNode generateQualifiedIdentifier(NodeFactory nodeFactory,
                                                                      String qualifier,
                                                                      String name,
                                                                      boolean intern)
    {
        if (intern)
        {
            name = name.intern();
        }

        LiteralStringNode literalString = nodeFactory.literalString(qualifier, intern);
        return nodeFactory.qualifiedIdentifier(literalString, name);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>name</code>
     *               is interned.  If <code>name</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static QualifiedIdentifierNode generateQualifiedIdentifier(NodeFactory nodeFactory,
                                                                      MemberExpressionNode qualifier,
                                                                      String name,
                                                                      boolean intern)
    {
        if (intern)
        {
            name = name.intern();
        }

        return nodeFactory.qualifiedIdentifier(qualifier, name);
    }

    /**
     * Generates a MemberExpressionNode with an IdentifierNode name
     * with a prefilled ReferenceValue with a namespace of size 1.
     * This allows ReferenceValue.findUnqualified() to run much faster
     * on the IdentifierNode.
     *
     * @param name Assumed to be interned
     */
    public static MemberExpressionNode generateResolvedGetterSelector(NodeFactory nodeFactory,
                                                                      String namespace,
                                                                      String name)
    {
        assert name.intern() == name;
        IdentifierNode identifier = generateResolvedIdentifier(nodeFactory, namespace, name);
        GetExpressionNode getExpression = nodeFactory.getExpression(identifier);
        return nodeFactory.memberExpression(null, getExpression);
    }

    /**
     * Generates an IdentifierNode with prefilled ReferenceValue with
     * a namespace of size 1.  This allows
     * ReferenceValue.findUnqualified() to run much faster.
     *
     * @param name Assumed to be interned
     */
    public static IdentifierNode generateResolvedIdentifier(NodeFactory nodeFactory,
                                                            String namespace,
                                                            String name)
    {
        assert name.intern() == name;
        IdentifierNode result = nodeFactory.identifier(name, false);
        Namespaces namespaces = new Namespaces();
        NamespaceValue namespaceValue = new NamespaceValue();
        namespaceValue.name = namespace;
        namespaces.add(namespaceValue);
        ReferenceValue referenceValue = new ReferenceValue(nodeFactory.getContext(), null, name, namespaces);
        referenceValue.setIsAttributeIdentifier(false);
        result.ref = referenceValue;
        return result;
    }

    /**
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static TypeExpressionNode generateTypeExpression(NodeFactory nodeFactory,
                                                            String typeNamespace,
                                                            String typeName,
                                                            boolean intern)
    {
        MemberExpressionNode memberExpression = generateGetterSelector(nodeFactory, typeNamespace,
                                                                       typeName, intern);
        return nodeFactory.typeExpression(memberExpression, true, false, -1);
    }

    public static TypeExpressionNode generateTypeExpression(NodeFactory nodeFactory, String type,
                                                            boolean intern)
    {
        return generateTypeExpression(nodeFactory, type, intern, false, -1);
    }

    public static TypeExpressionNode generateTypeExpression(NodeFactory nodeFactory, String type,
                                                            boolean intern, int position)
    {
        return generateTypeExpression(nodeFactory, type, intern, false, position);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static TypeExpressionNode generateTypeExpression(NodeFactory nodeFactory, String type,
                                                            boolean intern, boolean includeAnyType)
    {
        return generateTypeExpression(nodeFactory, type, intern, includeAnyType, -1);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static TypeExpressionNode generateTypeExpression(NodeFactory nodeFactory, String type,
                                                            boolean intern, boolean includeAnyType,
                                                            int position)
    {
        TypeExpressionNode result = null;

        if (includeAnyType || !type.equals("*"))
        {
            MemberExpressionNode memberExpression;

            if (intern)
            {
                int lessThanIndex = type.indexOf(LESS_THAN);

                if (lessThanIndex > 0)
                {
                    ApplyTypeExprNode applyTypeExpr = generateApplyTypeExpr(nodeFactory, type, lessThanIndex);
                    memberExpression = nodeFactory.memberExpression(null, applyTypeExpr);
                }
                else
                {
                    int dotIndex = type.lastIndexOf(DOT);

                    if (dotIndex > 0)
                    {
                        memberExpression = generateGetterSelector(nodeFactory, type.substring(0, dotIndex),
                                                                  type.substring(dotIndex + 1), intern);
                    }
                    else
                    {
                        memberExpression = generateGetterSelector(nodeFactory, type, intern);
                    }
                }
            }
            else
            {
                assert type.lastIndexOf(DOT) < 0 : "It's likely that the type, " + type + ", needs to be interned.";
                memberExpression = generateGetterSelector(nodeFactory, type, intern);
            }

            result = nodeFactory.typeExpression(memberExpression, true, false, position);
        }

        return result;
    }

    private static UseDirectiveNode generateUseDirective(Context context, String name)
    {
        NodeFactory nodeFactory = context.getNodeFactory();
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        GetExpressionNode getExpression = nodeFactory.getExpression(identifier);
        MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, getExpression);
        UseDirectiveNode useDirective = nodeFactory.useDirective(null, memberExpression);
        return useDirective;
    }

    /**
     * @param name This is assumed to be interned.
     * @param intern Hint to ASC for controlling if <code>name</code>
     *               is interned.  If <code>name</code> is a constant,
     *               <code>intern</code> should be false.
     */
    public static VariableDefinitionNode generateVariable(NodeFactory nodeFactory, String name,
                                                          boolean intern)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, intern);
        int kind = Tokens.VAR_TOKEN;
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(identifier, null);
        VariableBindingNode variableBinding = nodeFactory.variableBinding(null, kind,
                                                                          typedIdentifier,
                                                                          null);
        ListNode list = nodeFactory.list(null, variableBinding);
        return (VariableDefinitionNode) nodeFactory.variableDefinition(null, kind, list);
    }

    /**
     * @param name This is assumed to be interned.
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>internType</code> should be false.
     */
    public static VariableDefinitionNode generateVariable(NodeFactory nodeFactory, String name,
                                                          String type, boolean internType,
                                                          Node rvalue)
    {
        return generateVariable(nodeFactory, name, type, internType, rvalue, -1);
    }

    /**
     * @param name This is assumed to be interned.
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>internType</code> should be false.
     */
    public static VariableDefinitionNode generateVariable(NodeFactory nodeFactory, String name,
                                                          String type, boolean internType,
                                                          Node rvalue, int position)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        int kind = Tokens.VAR_TOKEN;
        TypeExpressionNode typeExpression = generateTypeExpression(nodeFactory, type,
                                                                   internType, position);
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(identifier,
                                                                          typeExpression);

        VariableBindingNode variableBinding = nodeFactory.variableBinding(null, kind,
                                                                          typedIdentifier,
                                                                          rvalue);
        ListNode list = nodeFactory.list(null, variableBinding);
        return (VariableDefinitionNode) nodeFactory.variableDefinition(null, kind, list);
    }

    /**
     * @param name This is assumed to be interned.
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>internType</code> should be false.
     */
    public static VariableDefinitionNode generateVariable(NodeFactory nodeFactory, String name,
                                                          String typeNamespace, String typeName,
                                                          boolean internType, Node rvalue)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        int kind = Tokens.VAR_TOKEN;
        TypeExpressionNode typeExpression =
            generateTypeExpression(nodeFactory, typeNamespace, typeName, internType);
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(identifier,
                                                                          typeExpression);

        VariableBindingNode variableBinding = nodeFactory.variableBinding(null, kind,
                                                                          typedIdentifier,
                                                                          rvalue);
        ListNode list = nodeFactory.list(null, variableBinding);
        return (VariableDefinitionNode) nodeFactory.variableDefinition(null, kind, list);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>internType</code> should be false.
     */
    public static VariableDefinitionNode generateVariable(NodeFactory nodeFactory,
                                                          AttributeListNode attributeList,
                                                          IdentifierNode identifier,
                                                          String type, boolean internType, Node rvalue)
    {
        int kind = Tokens.VAR_TOKEN;
        TypeExpressionNode typeExpression = generateTypeExpression(nodeFactory, type, internType);
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(identifier,
                                                                          typeExpression);

        VariableBindingNode variableBinding = nodeFactory.variableBinding(attributeList, kind,
                                                                          typedIdentifier,
                                                                          rvalue);
        ListNode list = nodeFactory.list(null, variableBinding);
        return (VariableDefinitionNode) nodeFactory.variableDefinition(attributeList, kind, list);
    }

    /**
     * @param intern Hint to ASC for controlling if <code>type</code>
     *               is interned.  If <code>type</code> is a constant,
     *               <code>internType</code> should be false.
     */
    public static VariableDefinitionNode generateVariable(NodeFactory nodeFactory,
                                                          AttributeListNode attributeList,
                                                          IdentifierNode identifier,
                                                          String typeNamespace, String typeName,
                                                          boolean internType, Node rvalue)
    {
        int kind = Tokens.VAR_TOKEN;
        TypeExpressionNode typeExpression =
            generateTypeExpression(nodeFactory, typeNamespace, typeName, internType);
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(identifier,
                                                                          typeExpression);

        VariableBindingNode variableBinding = nodeFactory.variableBinding(attributeList, kind,
                                                                          typedIdentifier,
                                                                          rvalue);
        ListNode list = nodeFactory.list(null, variableBinding);
        return (VariableDefinitionNode) nodeFactory.variableDefinition(attributeList, kind, list);
    }

    /**
     * @param name This is assumed to be interned.
     * @param type This is assumed not to be interned.
     */
    public static VariableDefinitionNode generateVariableNew(NodeFactory nodeFactory, String name,
                                                             String type, int position)
    {
        return generateVariableNew(nodeFactory, name, type, null, position);
    }

    /**
     * @param name This is assumed to be interned.
     * @param type This is assumed not to be interned.
     */
    public static VariableDefinitionNode generateVariableNew(NodeFactory nodeFactory, String name,
                                                             String type, ArgumentListNode argumentList,
                                                             int position)
    {
        IdentifierNode identifier = nodeFactory.identifier(name, false);
        TypeExpressionNode typeExpression = generateTypeExpression(nodeFactory, type, true, position);
        TypedIdentifierNode typedIdentifier = nodeFactory.typedIdentifier(identifier,
                                                                          typeExpression);
        int lessThanIndex = type.indexOf(LESS_THAN);
        Node initializer;

        if (lessThanIndex > 0)
        {
            ApplyTypeExprNode applyTypeExpr = generateApplyTypeExpr(nodeFactory, type, lessThanIndex);
            MemberExpressionNode memberExpression = nodeFactory.memberExpression(null, applyTypeExpr);
            CallExpressionNode callExpression =
                (CallExpressionNode) nodeFactory.callExpression(memberExpression, argumentList);
            callExpression.is_new = true;
            initializer = callExpression;
        }
        else
        {
            IdentifierNode typeIdentifier = generateIdentifier(nodeFactory, type, true);
            CallExpressionNode callExpression =
                (CallExpressionNode) nodeFactory.callExpression(typeIdentifier, argumentList);
            callExpression.is_new = true;
            callExpression.setRValue(false);
            initializer = nodeFactory.memberExpression(null, callExpression);
        }

        int kind = Tokens.VAR_TOKEN;
        VariableBindingNode variableBinding = nodeFactory.variableBinding(null, kind,
                                                                          typedIdentifier,
                                                                          initializer);
        ListNode list = nodeFactory.list(null, variableBinding);
        return (VariableDefinitionNode) nodeFactory.variableDefinition(null, kind, list);
    }

    /**
     * This method should be used to parse blocks of code, like MXML
     * script blocks.  It differs from the parseExpression() methods
     * in it's handling of expressions like "[a, b]", which are parsed
     * as metadata instead of array literals.
     */
    public static List<Node> parse(Context context, HashSet<String> configNamespaces, String text,
                                   int lineNumberOffset, boolean emitDocInfo)
    {
        return parse(context, configNamespaces, text, lineNumberOffset, emitDocInfo, false);
    }

    private static List<Node> parse(Context context, HashSet<String> configNamespaces, String text,
                                   int lineNumberOffset, boolean emitDocInfo, boolean isExpression)
    {
        List<Node> result = Collections.<Node>emptyList();

        CodeFragmentsInputBuffer codeFragmentsInputBuffer =
            (CodeFragmentsInputBuffer) context.input;
        String origin = context.input.origin;
       
        // Create a new input buffer populated with our code fragment.
        InputBuffer offsetInputBuffer =
            new InputBuffer(text, origin, codeFragmentsInputBuffer.getLength(), 0);

        Parser parser = new Parser(context, offsetInputBuffer, origin, emitDocInfo);
        parser.block_kind_stack.add(Tokens.PACKAGE_TOKEN);
        parser.block_kind_stack.add(Tokens.CLASS_TOKEN);
        parser.config_namespaces.push_back(configNamespaces);

        Logger original = ThreadLocalToolkit.getLogger();

        CodeFragmentLogAdapter codeFragmentLogAdapter =
            new CodeFragmentLogAdapter(original, lineNumberOffset);
        ThreadLocalToolkit.setLogger(codeFragmentLogAdapter);

        StatementListNode statementList = parser.parseDirectives(null, null);
        parser.match(Tokens.EOS_TOKEN);

        if ((statementList != null) && (statementList.items != null))
        {
            result = new ArrayList<Node>(1);

            for (Node node : statementList.items)
            {
                // For cases like SDK-26448, we don't want "[foo]"
                // parsed as a MetaDataNode.  We want it parsed as a
                // LiteralArrayNode.  Different Parser entrypoints
                // like parseLabeledOrExpressionStatement() were
                // tried, but an entry point was not found that worked
                // for all cases, so we ended up with this hack.
                if (isExpression && (node instanceof MetaDataNode))
                {
                    result.add(new ExpressionStatementNode(new ListNode(null, ((MetaDataNode) node).data, -1)));
                }
                else
                {
                    result.add(node);
                }
            }
        }

        ThreadLocalToolkit.setLogger(original);
        codeFragmentsInputBuffer.addCodeFragment(text.length(), offsetInputBuffer, lineNumberOffset);
        context.input = codeFragmentsInputBuffer;

        return result;
    }

    /**
     * This method should be used to parse an expression, like "a =
     * b".  It differs from the parse() methods in it's handling of
     * expressions like "[a, b]", which are parsed as array literals,
     * instead of metadata.
     */
    public static List<Node> parseExpression(Context context, HashSet<String> configNamespaces,
                                             String text)
    {
        return parseExpression(context, configNamespaces, text, 0, false);
    }

    /**
     * This method should be used to parse an expression, like "a =
     * b".  It differs from the parse() methods in it's handling of
     * expressions like "[a, b]", which are parsed as array literals,
     * instead of metadata.
     */
    public static List<Node> parseExpression(Context context, HashSet<String> configNamespaces,
                                             String text, int lineNumberOffset, boolean emitDocInfo)
    {
        return parse(context, configNamespaces, text, lineNumberOffset, emitDocInfo, true);
    }

    /**
     * @param configNamespaces This HashSet is populated by
     *   parseConfigVars().  If parseConfigVars() didn't already have a
     *   return value, configNamespaces would be returned.
     */
    public static StatementListNode parseConfigVars(Context context, HashSet<String> configNamespaces)
    {
        InputBuffer originalInputBuffer = context.input;
        Parser parser = new Parser(context, "", context.input.origin);
        parser.config_namespaces.push_back(configNamespaces);
        parser.config_namespaces.last().add(CONFIG);
        StatementListNode result = parser.parseConfigValues();
        context.input = originalInputBuffer;
        return result;
    }
   
    /**
     * Helper method which adds a new line number to the nodeFactory's
     * input buffer. Returns the corresponding position to use when later
     * associating individual nodes with the specified line number.
     */
    public static int lineNumberToPosition(NodeFactory nodeFactory, int lineNumber)
    {
      CodeFragmentsInputBuffer codeFragmentsInputBuffer =
            (CodeFragmentsInputBuffer) nodeFactory.getContext().input;
        int position = codeFragmentsInputBuffer.getLength();
        codeFragmentsInputBuffer.addLineNumber(lineNumber);
        return position;
    }
}
TOP

Related Classes of flex2.compiler.as3.AbstractSyntaxTreeUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.