org.apache.flex.compiler.internal.definitions.references.ResolvedQualifiersReference.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.flex.compiler.internal.definitions.references.ResolvedQualifiersReference.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.internal.definitions.references;

import static org.apache.flex.abc.ABCConstants.CONSTANT_Multiname;
import static org.apache.flex.abc.ABCConstants.CONSTANT_Qname;

import java.util.ArrayList;
import java.util.List;

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.common.DependencyType;
import org.apache.flex.compiler.definitions.IDefinition;
import org.apache.flex.compiler.definitions.INamespaceDefinition;
import org.apache.flex.compiler.definitions.references.IReference;
import org.apache.flex.compiler.definitions.references.IResolvedQualifiersReference;
import org.apache.flex.compiler.internal.definitions.AmbiguousDefinition;
import org.apache.flex.compiler.internal.definitions.NamespaceDefinition;
import org.apache.flex.compiler.internal.projects.CompilerProject;
import org.apache.flex.compiler.internal.scopes.ASScope;
import org.apache.flex.compiler.projects.ICompilerProject;
import org.apache.flex.compiler.units.ICompilationUnit;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;

/**
 * Implementation of {@link IReference} representing a reference where all the
 * qualifiers have been resolved to namespace definitions.
 */
public class ResolvedQualifiersReference implements IResolvedQualifiersReference {
    /**
     * Constructor.
     */
    public ResolvedQualifiersReference(ImmutableSet<INamespaceDefinition> qualifiers, String baseName) {
        assert baseName != null;
        this.qualifiers = qualifiers;
        this.baseName = baseName;
    }

    private final ImmutableSet<INamespaceDefinition> qualifiers;

    private final String baseName;

    @Override
    public String getName() {
        return baseName;
    }

    @Override
    public IDefinition resolve(ICompilerProject project, ASScope scope, DependencyType dependencyType,
            boolean canEscapeWith) {
        if (qualifiers.size() == 1) {
            INamespaceDefinition qualifier = Iterables.getOnlyElement(qualifiers);
            return scope.findPropertyQualified(project, qualifier, getName(), dependencyType, canEscapeWith);
        }

        return ((CompilerProject) project).getCacheForScope(scope).findPropertyMultiname(this, dependencyType);
    }

    @Override
    public String getDisplayString() {
        // Look through the multiname set for a package name.
        // Although most names in SWCs seem to have only
        // one namespace in their namespace set, interfaces seem
        // to have true multinames with multiple namespaces.
        // For code mode purposes, just look for the package namespace.
        String packageName = null;
        for (INamespaceDefinition namespace : qualifiers) {
            if (namespace.isPublicOrInternalNamespace()) {
                packageName = namespace.getURI();
                if (packageName.length() > 0)
                    break;
            }
        }

        return packageName != null && packageName.length() > 0 ? packageName + '.' + baseName : baseName;
    }

    @Override
    public Name getMName(ICompilerProject project, ASScope scope) {
        return getMName();
    }

    private IDefinition resolveAmbiguities(ICompilerProject project, List<IDefinition> defs) {
        switch (defs.size()) {
        case 0: {
            return null;
        }
        case 1: {
            assert Iterables.getOnlyElement(defs).isInProject(project);
            return Iterables.getOnlyElement(defs);
        }
        default: {
            IDefinition d = AmbiguousDefinition.resolveAmbiguities(project, defs);
            if (d == null)
                return AmbiguousDefinition.get();
            return d;
        }
        }
    }

    @Override
    public IDefinition resolve(ICompilerProject project, ICompilationUnit referencingCompilationUnit,
            DependencyType dt) {
        CompilerProject compilerProject = (CompilerProject) project;
        ArrayList<IDefinition> defs = new ArrayList<IDefinition>(2);
        compilerProject.getScope().findDefinitionByName(referencingCompilationUnit, defs, baseName, qualifiers, dt);
        return resolveAmbiguities(project, defs);
    }

    @Override
    public IDefinition resolve(ICompilerProject project) {
        CompilerProject compilerProject = (CompilerProject) project;
        ArrayList<IDefinition> defs = new ArrayList<IDefinition>(2);
        compilerProject.getScope().findDefinitionByName(defs, baseName, qualifiers);
        return resolveAmbiguities(project, defs);
    }

    @Override
    public Name getMName() {
        ArrayList<Namespace> ns_set = new ArrayList<Namespace>(qualifiers.size());
        for (INamespaceDefinition namespace : qualifiers)
            ns_set.add(((NamespaceDefinition) namespace).getAETNamespace());
        int nameType = ns_set.size() == 1 ? CONSTANT_Qname : CONSTANT_Multiname;
        return new Name(nameType, new Nsset(ns_set), baseName);
    }

    @Override
    public ImmutableSet<INamespaceDefinition> getQualifiers() {
        return qualifiers;
    }

    @Override
    public boolean matches(IResolvedQualifiersReference toMatch) {
        if (!baseName.equals(toMatch.getName()))
            return false;
        for (INamespaceDefinition qualifierToMatch : toMatch.getQualifiers()) {
            if (qualifiers.contains(qualifierToMatch))
                return true;
        }
        return false;
    }
}