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 }