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 }