org.apache.flex.compiler.definitions.references.ReferenceFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.flex.compiler.definitions.references.ReferenceFactory.java

Source

/*
 *
 *  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.definitions.references;

import java.util.Set;

import org.apache.flex.compiler.constants.IASLanguageConstants;
import org.apache.flex.compiler.definitions.IDefinition;
import org.apache.flex.compiler.definitions.INamespaceDefinition;
import org.apache.flex.compiler.internal.definitions.references.BuiltinReference;
import org.apache.flex.compiler.internal.definitions.references.LexicalReference;
import org.apache.flex.compiler.internal.definitions.references.NotATypeReference;
import org.apache.flex.compiler.internal.definitions.references.ParameterizedReference;
import org.apache.flex.compiler.internal.definitions.references.ResolvedQualifiersReference;
import org.apache.flex.compiler.internal.definitions.references.ResolvedReference;
import org.apache.flex.compiler.internal.workspaces.Workspace;
import org.apache.flex.compiler.workspaces.IWorkspace;
import com.google.common.collect.ImmutableSet;

/**
 * A factory class to create instances of type {@link IReference}.
 */
public class ReferenceFactory {
    // Constant IReferences returned by builtinReference().
    private static final IReference REFERENCE_ANY_TYPE = new BuiltinReference(
            IASLanguageConstants.BuiltinType.ANY_TYPE);
    private static final IReference REFERENCE_Array = new BuiltinReference(IASLanguageConstants.BuiltinType.ARRAY);
    private static final IReference REFERENCE_Boolean = new BuiltinReference(
            IASLanguageConstants.BuiltinType.BOOLEAN);
    private static final IReference REFERENCE_Class = new BuiltinReference(IASLanguageConstants.BuiltinType.CLASS);
    private static final IReference REFERENCE_Function = new BuiltinReference(
            IASLanguageConstants.BuiltinType.FUNCTION);
    private static final IReference REFERENCE_int = new BuiltinReference(IASLanguageConstants.BuiltinType.INT);
    private static final IReference REFERENCE_null = new BuiltinReference(IASLanguageConstants.BuiltinType.NULL);
    private static final IReference REFERENCE_Number = new BuiltinReference(
            IASLanguageConstants.BuiltinType.NUMBER);
    private static final IReference REFERENCE_Object = new BuiltinReference(
            IASLanguageConstants.BuiltinType.OBJECT);
    private static final IReference REFERENCE_QName = new BuiltinReference(IASLanguageConstants.BuiltinType.QNAME);
    private static final IReference REFERENCE_RegExp = new BuiltinReference(
            IASLanguageConstants.BuiltinType.REGEXP);
    private static final IReference REFERENCE_String = new BuiltinReference(
            IASLanguageConstants.BuiltinType.STRING);
    private static final IReference REFERENCE_undefined = new BuiltinReference(
            IASLanguageConstants.BuiltinType.Undefined);
    private static final IReference REFERENCE_uint = new BuiltinReference(IASLanguageConstants.BuiltinType.UINT);
    private static final IReference REFERENCE_Vector = new BuiltinReference(
            IASLanguageConstants.BuiltinType.VECTOR);
    private static final IReference REFERENCE_void = new BuiltinReference(IASLanguageConstants.BuiltinType.VOID);
    private static final IReference REFERENCE_XML = new BuiltinReference(IASLanguageConstants.BuiltinType.XML);
    private static final IReference REFERENCE_XMLList = new BuiltinReference(
            IASLanguageConstants.BuiltinType.XMLLIST);

    /**
     * Gets an {@link IReference} for one of the builtin types such as
     * <code>Object</code>, <code>String</code>, or <code>Array</code>.
     * 
     * @param type The {@code IASLanguageConstants.BuiltinType} you want the
     * reference for.
     * @return A {@link BuiltinReference}.
     */
    public static IReference builtinReference(IASLanguageConstants.BuiltinType type) {
        switch (type) {
        case ANY_TYPE:
            return REFERENCE_ANY_TYPE;
        case ARRAY:
            return REFERENCE_Array;
        case BOOLEAN:
            return REFERENCE_Boolean;
        case CLASS:
            return REFERENCE_Class;
        case FUNCTION:
            return REFERENCE_Function;
        case INT:
            return REFERENCE_int;
        case NULL:
            return REFERENCE_null;
        case NUMBER:
            return REFERENCE_Number;
        case OBJECT:
            return REFERENCE_Object;
        case QNAME:
            return REFERENCE_QName;
        case REGEXP:
            return REFERENCE_RegExp;
        case STRING:
            return REFERENCE_String;
        case Undefined:
            return REFERENCE_undefined;
        case UINT:
            return REFERENCE_uint;
        case VECTOR:
            return REFERENCE_Vector;
        case VOID:
            return REFERENCE_void;
        case XML:
            return REFERENCE_XML;
        case XMLLIST:
            return REFERENCE_XMLList;
        default:
            assert false : "Unknown builtin type " + type;
            return new BuiltinReference(type);
        }
    }

    /**
     * Generates an {@link IReference} for an unqualified base name.
     * 
     * @param workspace The workspace.
     * @param baseName The base name you want a reference to.
     * @return A {@link LexicalReference}.
     */
    public static IReference lexicalReference(IWorkspace workspace, String baseName) {
        if (workspace instanceof Workspace)
            return ((Workspace) workspace).getReferenceCache().getLexicalReference(baseName);

        return new LexicalReference(baseName);
    }

    /**
     * Generates an {@link IReference} for a base name qualified by an
     * {@link INamespaceDefinition}.
     * 
     * @param workspace The workspace.
     * @param namespace The {@link INamespaceDefinition} to use as the qualifier.
     * @param baseName The base name you want to reference to.
     * @return A {@link ResolvedQualifiersReference}.
     */
    public static IResolvedQualifiersReference resolvedQualifierQualifiedReference(IWorkspace workspace,
            INamespaceDefinition namespace, String baseName) {
        ImmutableSet<INamespaceDefinition> qualifiers = new ImmutableSet.Builder<INamespaceDefinition>()
                .add(namespace).build();
        return new ResolvedQualifiersReference(qualifiers, baseName);
    }

    /**
     * Generates an {@link IReference} for a base name qualified by a package
     * name.
     * 
     * @param workspace The workspace.
     * @param packageName The package name to use as the qualifier.
     * @param baseName The base name you want a reference to.
     * @param includeInternal Indicates whether or not the reference should
     * resolve to package internal definitions.
     * @return A {@link ResolvedQualifiersReference}.
     */
    public static IResolvedQualifiersReference packageQualifiedReference(IWorkspace workspace, String packageName,
            String baseName, boolean includeInternal) {
        INamespaceDefinition packagePublicNS = ((Workspace) workspace).getPackageNamespaceDefinitionCache()
                .get(packageName, false);
        ImmutableSet.Builder<INamespaceDefinition> namespaceSetBuilder = new ImmutableSet.Builder<INamespaceDefinition>()
                .add(packagePublicNS);
        if (includeInternal) {
            INamespaceDefinition packageInternalNS = ((Workspace) workspace).getPackageNamespaceDefinitionCache()
                    .get(packageName, true);
            namespaceSetBuilder.add(packageInternalNS);
        }
        ImmutableSet<INamespaceDefinition> namespaceSet = namespaceSetBuilder.build();
        return new ResolvedQualifiersReference(namespaceSet, baseName);
    }

    /**
     * Generates an {@link IReference} for a fully qualified name.
     * <p>
     * It is expected that the string will be of the form
     * <code>my.package.name.Foo</code>. This will be used to generate a
     * reference to <code>Foo</code> in the package <code>my.package.name</code>.
     * 
     * @param workspace The workspace.
     * @param qname A <code>String</code> representing a fully qualified name.
     * @return A {@link ResolvedQualifiersReference}.
     */
    public static IResolvedQualifiersReference packageQualifiedReference(IWorkspace workspace, String qname) {
        return packageQualifiedReference(workspace, qname, false);
    }

    /**
     * Generates an {@link IReference} for a fully qualified name.
     * <p>
     * It is expected that the string will be of the form
     * <code>my.package.name.Foo</code>. This will be used to generate a
     * reference to <code>Foo</code> in the package <code>my.package.name</code>.
     * 
     * @param workspace The workspace.
     * @param qname A <code>String</code> representing a fully qualified name.
     * @param includeInternal Indicates whether or not the reference should
     * resolve to package internal definitions.
     * @return A {@link ResolvedQualifiersReference}.
     */
    public static IResolvedQualifiersReference packageQualifiedReference(IWorkspace workspace, String qname,
            boolean includeInternal) {
        int lastIndexOfDot = qname.lastIndexOf('.');
        if (lastIndexOfDot != -1) {
            String unqualifiedName = qname.substring(lastIndexOfDot + 1);
            String packageName = qname.substring(0, lastIndexOfDot);
            return ReferenceFactory.packageQualifiedReference(workspace, packageName, unqualifiedName,
                    includeInternal);
        } else {
            return ReferenceFactory.packageQualifiedReference(workspace, "", qname, includeInternal);
        }
    }

    /**
     * Generates an {@link IReference} for a multiname coming from an ABC.
     * 
     * @param workspace The workspace.
     * @param namespaces The set of {@link INamespaceDefinition}s to use as the
     * namespace set.
     * @param baseName The base name you want a reference to.
     * @return A {@link ResolvedQualifiersReference}.n
     */
    public static IResolvedQualifiersReference multinameReference(IWorkspace workspace,
            Set<INamespaceDefinition> namespaces, String baseName) {
        return new ResolvedQualifiersReference(ImmutableSet.copyOf(namespaces), baseName);
    }

    /**
     * Generates an {@link IReference} for a parameterized type, such as
     * {@code Vector.<Foo>}.
     * <p>
     * This currently only supports one type parameter, as Vector is the only
     * parameterized type, and it only takes 1 type parameter.
     * 
     * @param workspace The workspace.
     * @param base The base reference, such as <code>Vector</code> in
     * {@code Vector.<Foo>}.
     * @param param The type parameter reference, such as <code>Foo</code> in
     * {@code Vector.<Foo>}.
     * @return A {@link ParameterizedReference}.
     */
    public static IReference parameterizedReference(IWorkspace workspace, IReference base, IReference param) {
        return new ParameterizedReference(base, param);
    }

    /**
     * Generates an {@link IReference} that always resolves to the
     * {@link IDefinition} passed in.
     * <p>
     * This is useful for <code>Vector</code> methods, where the return type is
     * the type parameter for the <code>Vector</code> (i.e., <code>T</code> in
     * {@code Vector.<T>}).
     * 
     * @param definition The {@link IDefinition} to generate a reference to.
     * @return A {@link ResolvedReference} that resolves to <code>d</code>.
     */
    public static IReference resolvedReference(IDefinition definition) {
        return new ResolvedReference(definition);
    }

    /**
     * Generates an {@link IReference} for a type reference that will always be
     * an error. An example would be: class C extends a.b.c.d.Foo{} If a.b.c.d
     * was not a package name then this class would be used to represent the
     * reference. This is because a property access will be an error, but we
     * have to remember that something was specified for the base class so we
     * can report the correct error when we try and resolve it.
     * 
     * @param workspace The workspace.
     * @param baseName The base name you want a reference to.
     * @return A {@link NotATypeReference}.
     */
    public static IReference notATypeReference(IWorkspace workspace, String baseName) {
        return new NotATypeReference(baseName);
    }

    // This is an all-static class and no instances of it can be created.
    private ReferenceFactory() {
    }
}