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 com.google.common.collect.Lists;
020 import com.google.common.collect.Sets;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.TestOnly;
023 import org.jetbrains.jet.lang.descriptors.*;
024 import org.jetbrains.jet.lang.resolve.name.LabelName;
025 import org.jetbrains.jet.lang.resolve.name.Name;
026 import org.jetbrains.jet.utils.Printer;
027
028 import java.util.Collection;
029 import java.util.Collections;
030 import java.util.List;
031 import java.util.Set;
032
033 import static org.jetbrains.jet.lang.resolve.scopes.JetScopeSelectorUtil.*;
034
035 public class ChainedScope implements JetScope {
036 private final DeclarationDescriptor containingDeclaration;
037 private final String debugName;
038 private final JetScope[] scopeChain;
039 private Collection<DeclarationDescriptor> allDescriptors;
040 private List<ReceiverParameterDescriptor> implicitReceiverHierarchy;
041
042 public ChainedScope(DeclarationDescriptor containingDeclaration, String debugName, JetScope... scopes) {
043 this.containingDeclaration = containingDeclaration;
044 scopeChain = scopes.clone();
045
046 this.debugName = debugName;
047 }
048
049 @Override
050 public ClassifierDescriptor getClassifier(@NotNull Name name) {
051 return getFirstMatch(scopeChain, name, CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR);
052 }
053
054 @Override
055 public PackageViewDescriptor getPackage(@NotNull Name name) {
056 return getFirstMatch(scopeChain, name, PACKAGE_SCOPE_SELECTOR);
057 }
058
059 @NotNull
060 @Override
061 public Set<VariableDescriptor> getProperties(@NotNull Name name) {
062 return getFromAllScopes(scopeChain, name, NAMED_PROPERTIES_SCOPE_SELECTOR);
063 }
064
065 @Override
066 public VariableDescriptor getLocalVariable(@NotNull Name name) {
067 return getFirstMatch(scopeChain, name, VARIABLE_DESCRIPTOR_SCOPE_SELECTOR);
068 }
069
070 @NotNull
071 @Override
072 public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
073 return getFromAllScopes(scopeChain, name, NAMED_FUNCTION_SCOPE_SELECTOR);
074 }
075
076 @NotNull
077 @Override
078 public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
079 if (implicitReceiverHierarchy == null) {
080 implicitReceiverHierarchy = Lists.newArrayList();
081 for (JetScope jetScope : scopeChain) {
082 implicitReceiverHierarchy.addAll(jetScope.getImplicitReceiversHierarchy());
083 }
084 }
085 return implicitReceiverHierarchy;
086 }
087
088 @NotNull
089 @Override
090 public DeclarationDescriptor getContainingDeclaration() {
091 return containingDeclaration;
092 }
093
094 @NotNull
095 @Override
096 public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
097 for (JetScope jetScope : scopeChain) {
098 Collection<DeclarationDescriptor> declarationsByLabel = jetScope.getDeclarationsByLabel(labelName);
099 if (!declarationsByLabel.isEmpty()) return declarationsByLabel; // TODO : merge?
100 }
101 return Collections.emptyList();
102 }
103
104 @NotNull
105 @Override
106 public Collection<DeclarationDescriptor> getAllDescriptors() {
107 if (allDescriptors == null) {
108 allDescriptors = Sets.newHashSet();
109 for (JetScope scope : scopeChain) {
110 allDescriptors.addAll(scope.getAllDescriptors());
111 }
112 }
113 return allDescriptors;
114 }
115
116 @NotNull
117 @Override
118 public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
119 throw new UnsupportedOperationException();
120 }
121
122 @Override
123 public String toString() {
124 return debugName;
125 }
126
127 @TestOnly
128 @Override
129 public void printScopeStructure(@NotNull Printer p) {
130 p.println(getClass().getSimpleName(), ": ", debugName, " {");
131 p.pushIndent();
132
133 for (JetScope scope : scopeChain) {
134 scope.printScopeStructure(p);
135 }
136
137 p.popIndent();
138 p.println("}");
139 }
140 }