001 /*
002 * Copyright 2010-2013 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.jet.lang.resolve.scopes;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.jet.lang.descriptors.*;
022 import org.jetbrains.jet.lang.resolve.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 public interface ScopeDescriptorSelector<D extends DeclarationDescriptor> {
041 @NotNull
042 Collection<D> get(JetScope scope);
043 }
044
045 @NotNull
046 public static <D extends DeclarationDescriptor> Collection<D> collect(Collection<JetScope> scopes, ScopeByNameMultiSelector<D> selector, Name name) {
047 Set<D> descriptors = new HashSet<D>();
048
049 for (JetScope scope : scopes) {
050 descriptors.addAll(selector.get(scope, name));
051 }
052
053 return descriptors;
054 }
055
056 @NotNull
057 public static <D extends DeclarationDescriptor> Collection<D> collect(Collection<JetScope> scopes, ScopeDescriptorSelector<D> selector) {
058 Set<D> descriptors = new HashSet<D>();
059
060 for (JetScope scope : scopes) {
061 descriptors.addAll(selector.get(scope));
062 }
063
064 return descriptors;
065 }
066
067 public static final ScopeByNameSelector<ClassifierDescriptor> CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR =
068 new ScopeByNameSelector<ClassifierDescriptor>() {
069 @Nullable
070 @Override
071 public ClassifierDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
072 return scope.getClassifier(name);
073 }
074 };
075
076 public static final ScopeByNameSelector<PackageViewDescriptor> PACKAGE_SCOPE_SELECTOR =
077 new ScopeByNameSelector<PackageViewDescriptor>() {
078 @Nullable
079 @Override
080 public PackageViewDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
081 return scope.getPackage(name);
082 }
083 };
084
085 public static final ScopeByNameSelector<VariableDescriptor> VARIABLE_DESCRIPTOR_SCOPE_SELECTOR =
086 new ScopeByNameSelector<VariableDescriptor>() {
087 @Nullable
088 @Override
089 public VariableDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
090 return scope.getLocalVariable(name);
091 }
092 };
093
094 public static final ScopeByNameMultiSelector<FunctionDescriptor> NAMED_FUNCTION_SCOPE_SELECTOR =
095 new ScopeByNameMultiSelector<FunctionDescriptor>() {
096 @NotNull
097 @Override
098 public Collection<FunctionDescriptor> get(@NotNull JetScope scope, @NotNull Name name) {
099 return scope.getFunctions(name);
100 }
101 };
102
103 public static final ScopeByNameMultiSelector<VariableDescriptor> NAMED_PROPERTIES_SCOPE_SELECTOR =
104 new ScopeByNameMultiSelector<VariableDescriptor>() {
105 @NotNull
106 @Override
107 public Collection<VariableDescriptor> get(@NotNull JetScope scope, @NotNull Name name) {
108 return scope.getProperties(name);
109 }
110 };
111
112 public static final ScopeDescriptorSelector<DeclarationDescriptor> ALL_DESCRIPTORS_SCOPE_SELECTOR =
113 new ScopeDescriptorSelector<DeclarationDescriptor>() {
114 @NotNull
115 @Override
116 public Collection<DeclarationDescriptor> get(@NotNull JetScope scope) {
117 return scope.getAllDescriptors();
118 }
119 };
120
121 @Nullable
122 public static <D extends DeclarationDescriptor> D getFirstMatch(
123 @NotNull JetScope[] scopes,
124 @NotNull Name name,
125 @NotNull ScopeByNameSelector<D> descriptorSelector
126 ) {
127 for (JetScope scope : scopes) {
128 D descriptor = descriptorSelector.get(scope, name);
129
130 if (descriptor != null) {
131 return descriptor;
132 }
133 }
134
135 return null;
136 }
137
138 @NotNull
139 public static <D extends DeclarationDescriptor> Set<D> getFromAllScopes(
140 @NotNull JetScope[] scopes,
141 @NotNull Name name,
142 @NotNull ScopeByNameMultiSelector<D> descriptorsSelector
143 ) {
144 if (scopes.length == 0) return Collections.emptySet();
145
146 Set<D> descriptors = new LinkedHashSet<D>();
147 for (JetScope jetScope : scopes) {
148 descriptors.addAll(descriptorsSelector.get(jetScope, name));
149 }
150
151 return descriptors;
152 }
153 }