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

org.jetbrains.jet.lang.resolve.calls.tasks.CallableDescriptorCollectors Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * Copyright 2010-2013 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.calls.tasks;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;

import java.util.*;

import static org.jetbrains.jet.lang.resolve.LibrarySourceHacks.filterOutMembersFromLibrarySource;

@SuppressWarnings("unchecked")
public class CallableDescriptorCollectors implements Iterable> {
    private static final CallableDescriptorCollector FUNCTIONS_COLLECTOR =
            new FilteredCollector(new FunctionCollector());
    private static final CallableDescriptorCollector VARIABLES_COLLECTOR =
            new FilteredCollector(new VariableCollector());
    private static final CallableDescriptorCollector PROPERTIES_COLLECTOR =
            new FilteredCollector(new PropertyCollector());

    public static final CallableDescriptorCollectors FUNCTIONS_AND_VARIABLES =
            new CallableDescriptorCollectors(FUNCTIONS_COLLECTOR, VARIABLES_COLLECTOR);
    public static final CallableDescriptorCollectors FUNCTIONS =
            new CallableDescriptorCollectors(FUNCTIONS_COLLECTOR);
    public static final CallableDescriptorCollectors VARIABLES =
            new CallableDescriptorCollectors(VARIABLES_COLLECTOR);
    public static final CallableDescriptorCollectors PROPERTIES =
            new CallableDescriptorCollectors(PROPERTIES_COLLECTOR);

    private static class FunctionCollector implements CallableDescriptorCollector {

        @NotNull
        @Override
        public Collection getNonExtensionsByName(JetScope scope, Name name, @NotNull BindingTrace bindingTrace) {
            Set functions = Sets.newLinkedHashSet();
            for (FunctionDescriptor function : scope.getFunctions(name)) {
                if (function.getReceiverParameter() == null) {
                    functions.add(function);
                }
            }
            addConstructors(scope, name, functions);
            return functions;
        }

        @NotNull
        @Override
        public Collection getMembersByName(@NotNull JetType receiverType, Name name, @NotNull BindingTrace bindingTrace) {
            JetScope receiverScope = receiverType.getMemberScope();
            Set members = Sets.newHashSet(receiverScope.getFunctions(name));
            addConstructors(receiverScope, name, members);
            return members;
        }

        @NotNull
        @Override
        public Collection getNonMembersByName(JetScope scope, Name name, @NotNull BindingTrace bindingTrace) {
            return scope.getFunctions(name);
        }

        private static void addConstructors(JetScope scope, Name name, Collection functions) {
            ClassifierDescriptor classifier = scope.getClassifier(name);
            if (!(classifier instanceof ClassDescriptor) || ErrorUtils.isError(classifier)) return;
            ClassDescriptor classDescriptor = (ClassDescriptor) classifier;
            if (classDescriptor.getKind().isSingleton()) {
                // Constructors of singletons shouldn't be callable from the code
                return;
            }
            functions.addAll(classDescriptor.getConstructors());
        }

        @Override
        public String toString() {
            return "FUNCTIONS";
        }
    }

    private static class VariableCollector implements CallableDescriptorCollector {

        @NotNull
        @Override
        public Collection getNonExtensionsByName(JetScope scope, Name name, @NotNull BindingTrace bindingTrace) {
            VariableDescriptor localVariable = scope.getLocalVariable(name);
            if (localVariable != null) {
                return Collections.singleton(localVariable);
            }

            LinkedHashSet variables = Sets.newLinkedHashSet();
            for (VariableDescriptor variable : scope.getProperties(name)) {
                if (variable.getReceiverParameter() == null) {
                    variables.add(variable);
                }
            }
            return variables;
        }

        @NotNull
        @Override
        public Collection getMembersByName(@NotNull JetType receiverType, Name name, @NotNull BindingTrace bindingTrace) {
            return receiverType.getMemberScope().getProperties(name);
        }

        @NotNull
        @Override
        public Collection getNonMembersByName(JetScope scope, Name name, @NotNull BindingTrace bindingTrace) {
            Collection result = Sets.newLinkedHashSet();

            VariableDescriptor localVariable = scope.getLocalVariable(name);
            if (localVariable != null) {
                result.add(localVariable);
            }
            result.addAll(scope.getProperties(name));
            return result;
        }

        @Override
        public String toString() {
            return "VARIABLES";
        }
    }

    private static class PropertyCollector implements CallableDescriptorCollector {
        private static Collection filterProperties(Collection variableDescriptors) {
            ArrayList properties = Lists.newArrayList();
            for (VariableDescriptor descriptor : variableDescriptors) {
                if (descriptor instanceof PropertyDescriptor) {
                    properties.add(descriptor);
                }
            }
            return properties;
        }

        @NotNull
        @Override
        public Collection getNonExtensionsByName(JetScope scope, Name name, @NotNull BindingTrace bindingTrace) {
            return filterProperties(VARIABLES_COLLECTOR.getNonExtensionsByName(scope, name, bindingTrace));
        }

        @NotNull
        @Override
        public Collection getMembersByName(@NotNull JetType receiver, Name name, @NotNull BindingTrace bindingTrace) {
            return filterProperties(VARIABLES_COLLECTOR.getMembersByName(receiver, name, bindingTrace));
        }

        @NotNull
        @Override
        public Collection getNonMembersByName(JetScope scope, Name name, @NotNull BindingTrace bindingTrace) {
            return filterProperties(VARIABLES_COLLECTOR.getNonMembersByName(scope, name, bindingTrace));
        }

        @Override
        public String toString() {
            return "PROPERTIES";
        }
    }
    
    private static class FilteredCollector implements CallableDescriptorCollector {
        private final CallableDescriptorCollector delegate;

        private FilteredCollector(CallableDescriptorCollector delegate) {
            this.delegate = delegate;
        }

        @NotNull
        @Override
        public Collection getNonExtensionsByName(JetScope scope, Name name, @NotNull BindingTrace bindingTrace) {
            return filterOutMembersFromLibrarySource(delegate.getNonExtensionsByName(scope, name, bindingTrace));
        }

        @NotNull
        @Override
        public Collection getMembersByName(@NotNull JetType receiver, Name name, @NotNull BindingTrace bindingTrace) {
            return filterOutMembersFromLibrarySource(delegate.getMembersByName(receiver, name, bindingTrace));
        }

        @NotNull
        @Override
        public Collection getNonMembersByName(JetScope scope, Name name, @NotNull BindingTrace bindingTrace) {
            return filterOutMembersFromLibrarySource(delegate.getNonMembersByName(scope, name, bindingTrace));
        }

        @Override
        public String toString() {
            return delegate.toString();
        }
    }

    private final Collection> collectors;

    private CallableDescriptorCollectors(CallableDescriptorCollector... collectors) {
        this.collectors = Lists.newArrayList(collectors);
    }

    @NotNull
    @Override
    public Iterator> iterator() {
        return collectors.iterator();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy