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
017package org.jetbrains.jet.lang.resolve.scopes;
018
019import com.google.common.collect.Sets;
020import org.jetbrains.annotations.NotNull;
021import org.jetbrains.annotations.Nullable;
022import org.jetbrains.jet.lang.descriptors.*;
023import org.jetbrains.jet.lang.resolve.name.Name;
024
025import java.util.Collection;
026import java.util.Set;
027
028public class JetScopeSelectorUtil {
029    private JetScopeSelectorUtil() {
030    }
031
032    public interface ScopeByNameSelector<D extends DeclarationDescriptor> {
033        @Nullable
034        D get(@NotNull JetScope scope, @NotNull Name name);
035    }
036
037    public interface ScopeByNameMultiSelector<D extends DeclarationDescriptor> {
038        @NotNull
039        Collection<D> get(JetScope scope, Name name);
040    }
041
042    public interface ScopeDescriptorSelector<D extends DeclarationDescriptor> {
043        @NotNull
044        Collection<D> get(JetScope scope);
045    }
046
047    @NotNull
048    public static <D extends DeclarationDescriptor> Collection<D> collect(Collection<JetScope> scopes, ScopeByNameMultiSelector<D> selector, Name name) {
049        Set<D> descriptors = Sets.newHashSet();
050
051        for (JetScope scope : scopes) {
052            descriptors.addAll(selector.get(scope, name));
053        }
054
055        return descriptors;
056    }
057
058    @NotNull
059    public static <D extends DeclarationDescriptor> Collection<D> collect(Collection<JetScope> scopes, ScopeDescriptorSelector<D> selector) {
060        Set<D> descriptors = Sets.newHashSet();
061
062        for (JetScope scope : scopes) {
063            descriptors.addAll(selector.get(scope));
064        }
065
066        return descriptors;
067    }
068
069    public static final ScopeByNameSelector<ClassifierDescriptor> CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR =
070            new ScopeByNameSelector<ClassifierDescriptor>() {
071                @Nullable
072                @Override
073                public ClassifierDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
074                    return scope.getClassifier(name);
075                }
076            };
077
078    public static final ScopeByNameSelector<ClassDescriptor> NAMED_OBJECT_SCOPE_SELECTOR =
079            new ScopeByNameSelector<ClassDescriptor>() {
080                @Nullable
081                @Override
082                public ClassDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
083                    return scope.getObjectDescriptor(name);
084                }
085            };
086
087    public static final ScopeByNameSelector<NamespaceDescriptor> NAMESPACE_SCOPE_SELECTOR =
088            new ScopeByNameSelector<NamespaceDescriptor>() {
089                @Nullable
090                @Override
091                public NamespaceDescriptor get(@NotNull JetScope scope, @NotNull Name name) {
092                    return scope.getNamespace(name);
093                }
094            };
095
096    public static final ScopeByNameMultiSelector<FunctionDescriptor> NAMED_FUNCTION_SCOPE_SELECTOR =
097            new ScopeByNameMultiSelector<FunctionDescriptor>() {
098                @NotNull
099                @Override
100                public Collection<FunctionDescriptor> get(@NotNull JetScope scope, @NotNull Name name) {
101                    return scope.getFunctions(name);
102                }
103            };
104
105    public static final ScopeByNameMultiSelector<VariableDescriptor> NAMED_PROPERTIES_SCOPE_SELECTOR =
106            new ScopeByNameMultiSelector<VariableDescriptor>() {
107                @NotNull
108                @Override
109                public Collection<VariableDescriptor> get(@NotNull JetScope scope, @NotNull Name name) {
110                    return scope.getProperties(name);
111                }
112            };
113
114    public static final ScopeDescriptorSelector<ClassDescriptor> OBJECTS_SCOPE_SELECTOR =
115            new ScopeDescriptorSelector<ClassDescriptor>() {
116                @NotNull
117                @Override
118                public Collection<ClassDescriptor> get(@NotNull JetScope scope) {
119                    return scope.getObjectDescriptors();
120                }
121            };
122
123    public static final ScopeDescriptorSelector<DeclarationDescriptor> ALL_DESCRIPTORS_SCOPE_SELECTOR =
124            new ScopeDescriptorSelector<DeclarationDescriptor>() {
125                @NotNull
126                @Override
127                public Collection<DeclarationDescriptor> get(@NotNull JetScope scope) {
128                    return scope.getAllDescriptors();
129                }
130            };
131}