001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.resolve.scopes;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.kotlin.descriptors.*;
022    import org.jetbrains.kotlin.name.Name;
023    
024    import java.util.*;
025    
026    public class JetScopeSelectorUtil {
027        private JetScopeSelectorUtil() {
028        }
029    
030        public interface ScopeByNameSelector<D extends DeclarationDescriptor> {
031            @Nullable
032            D get(@NotNull JetScope scope, @NotNull Name name);
033        }
034    
035        public interface ScopeByNameMultiSelector<D extends DeclarationDescriptor> {
036            @NotNull
037            Collection<D> get(JetScope scope, Name name);
038        }
039    
040        @NotNull
041        public static <D extends DeclarationDescriptor> Collection<D> collect(Collection<JetScope> scopes, ScopeByNameMultiSelector<D> selector, Name name) {
042            Set<D> descriptors = new HashSet<D>();
043    
044            for (JetScope scope : scopes) {
045                descriptors.addAll(selector.get(scope, name));
046            }
047    
048            return descriptors;
049        }
050    
051        public static final ScopeByNameSelector<ClassifierDescriptor> CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR =
052                new ScopeByNameSelector<ClassifierDescriptor>() {
053                    @Nullable
054                    @Override
055                    public ClassifierDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
056                        return scope.getClassifier(name);
057                    }
058                };
059    
060        public static final ScopeByNameSelector<PackageViewDescriptor> PACKAGE_SCOPE_SELECTOR =
061                new ScopeByNameSelector<PackageViewDescriptor>() {
062                    @Nullable
063                    @Override
064                    public PackageViewDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
065                        return scope.getPackage(name);
066                    }
067                };
068    
069        public static final ScopeByNameSelector<VariableDescriptor> VARIABLE_DESCRIPTOR_SCOPE_SELECTOR =
070                new ScopeByNameSelector<VariableDescriptor>() {
071                    @Nullable
072                    @Override
073                    public VariableDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
074                        return scope.getLocalVariable(name);
075                    }
076                };
077    
078        public static final ScopeByNameMultiSelector<FunctionDescriptor> NAMED_FUNCTION_SCOPE_SELECTOR =
079                new ScopeByNameMultiSelector<FunctionDescriptor>() {
080                    @NotNull
081                    @Override
082                    public Collection<FunctionDescriptor> get(@NotNull JetScope scope, @NotNull Name name) {
083                        return scope.getFunctions(name);
084                    }
085                };
086    
087        public static final ScopeByNameMultiSelector<VariableDescriptor> NAMED_PROPERTIES_SCOPE_SELECTOR =
088                new ScopeByNameMultiSelector<VariableDescriptor>() {
089                    @NotNull
090                    @Override
091                    public Collection<VariableDescriptor> get(@NotNull JetScope scope, @NotNull Name name) {
092                        return scope.getProperties(name);
093                    }
094                };
095    
096        @Nullable
097        public static <D extends DeclarationDescriptor> D getFirstMatch(
098                @NotNull JetScope[] scopes,
099                @NotNull Name name,
100                @NotNull ScopeByNameSelector<D> descriptorSelector
101        ) {
102            for (JetScope scope : scopes) {
103                D descriptor = descriptorSelector.get(scope, name);
104    
105                if (descriptor != null) {
106                    return descriptor;
107                }
108            }
109    
110            return null;
111        }
112    
113        @NotNull
114        public static <D extends DeclarationDescriptor> Set<D> getFromAllScopes(
115                @NotNull JetScope[] scopes,
116                @NotNull Name name,
117                @NotNull ScopeByNameMultiSelector<D> descriptorsSelector
118        ) {
119            if (scopes.length == 0) return Collections.emptySet();
120    
121            Set<D> descriptors = new LinkedHashSet<D>();
122            for (JetScope jetScope : scopes) {
123                descriptors.addAll(descriptorsSelector.get(jetScope, name));
124            }
125    
126            return descriptors;
127        }
128    }