All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2014 JetBrains s.r.o.
 *
 * Licensed 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.jetbrains.jet.lang.resolve.lazy;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor;
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
import org.jetbrains.jet.lang.psi.JetNamedDeclarationUtil;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.name.NamePackage;
import org.jetbrains.jet.lang.resolve.name.SpecialNames;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;

import java.util.Collection;
import java.util.Collections;

public class ResolveSessionUtils {

    public static final Predicate NON_SINGLETON_FILTER = new Predicate() {
        @Override
        public boolean apply(@Nullable ClassDescriptor descriptor) {
            assert descriptor != null;
            return !descriptor.getKind().isSingleton();
        }
    };

    public static final Predicate SINGLETON_FILTER = new Predicate() {
        @Override
        public boolean apply(@Nullable ClassDescriptor descriptor) {
            assert descriptor != null;
            return descriptor.getKind().isSingleton();
        }
    };

    private ResolveSessionUtils() {
    }

    @NotNull
    public static Collection getClassDescriptorsByFqName(@NotNull KotlinCodeAnalyzer analyzer, @NotNull FqName fqName) {
        return getClassOrObjectDescriptorsByFqName(analyzer, fqName, NON_SINGLETON_FILTER);
    }

    @NotNull
    public static Collection getClassOrObjectDescriptorsByFqName(
            @NotNull KotlinCodeAnalyzer analyzer,
            @NotNull FqName fqName,
            @NotNull Predicate filter
    ) {
        if (fqName.isRoot()) return Collections.emptyList();

        Collection classDescriptors = Lists.newArrayList();

        FqName packageFqName = fqName.parent();
        while (true) {
            PackageViewDescriptor packageDescriptor = analyzer.getModuleDescriptor().getPackage(packageFqName);
            if (packageDescriptor != null) {
                FqName classInPackagePath = NamePackage.tail(fqName, packageFqName);
                ClassDescriptor classDescriptor = findByQualifiedName(packageDescriptor.getMemberScope(), classInPackagePath, filter);
                if (classDescriptor != null) {
                    classDescriptors.add(classDescriptor);
                }
            }

            if (packageFqName.isRoot()) {
                break;
            }
            else {
                packageFqName = packageFqName.parent();
            }
        }

        return classDescriptors;
    }

    @Nullable
    public static ClassDescriptor findByQualifiedName(@NotNull JetScope packageScope, @NotNull FqName path) {
        return findByQualifiedName(packageScope, path, Predicates.alwaysTrue());
    }

    @Nullable
    private static ClassDescriptor findByQualifiedName(
            @NotNull JetScope jetScope,
            @NotNull FqName path,
            @NotNull Predicate filter
    ) {
        if (path.isRoot()) return null;

        if (NamePackage.isOneSegmentFQN(path)) {
            Name shortName = path.shortName();
            ClassifierDescriptor classifier = jetScope.getClassifier(shortName);
            if (classifier instanceof ClassDescriptor) {
                ClassDescriptor resultDescriptor = (ClassDescriptor) classifier;

                if (filter.apply(resultDescriptor)) {
                    return resultDescriptor;
                }
            }

            return null;
        }

        Name firstName = NamePackage.getFirstSegment(path);

        // Search in internal class
        ClassifierDescriptor classifier = jetScope.getClassifier(firstName);
        if (classifier instanceof ClassDescriptor) {
            return findByQualifiedName(
                    ((ClassDescriptor) classifier).getUnsubstitutedInnerClassesScope(),
                    NamePackage.withoutFirstSegment(path),
                    filter);
        }

        // TODO: search in class object

        return null;
    }

    @NotNull
    public static Name safeNameForLazyResolve(@NotNull JetNamedDeclaration declaration) {
        return safeNameForLazyResolve(declaration.getNameAsName());
    }

    @NotNull
    public static Name safeNameForLazyResolve(@Nullable Name name) {
        return SpecialNames.safeIdentifier(name);
    }

    @Nullable
    public static FqName safeFqNameForLazyResolve(@NotNull JetNamedDeclaration declaration) {
        //NOTE: should only create special names for package level declarations, so we can safely rely on real fq name for parent
        FqName parentFqName = JetNamedDeclarationUtil.getParentFqName(declaration);
        return parentFqName != null ? parentFqName.child(safeNameForLazyResolve(declaration)) : null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy