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.jet.lang.descriptors.*;
023 import org.jetbrains.jet.lang.resolve.name.LabelName;
024 import org.jetbrains.jet.lang.resolve.name.Name;
025
026 import java.util.Collection;
027 import java.util.Collections;
028 import java.util.List;
029 import java.util.Set;
030
031 public class ChainedScope implements JetScope {
032 private final DeclarationDescriptor containingDeclaration;
033 private final String debugName;
034 private final JetScope[] scopeChain;
035 private Collection<DeclarationDescriptor> allDescriptors;
036 private List<ReceiverParameterDescriptor> implicitReceiverHierarchy;
037
038 public ChainedScope(DeclarationDescriptor containingDeclaration, JetScope... scopes) {
039 this(containingDeclaration, "Untitled chained scope", scopes);
040 }
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 for (JetScope scope : scopeChain) {
052 ClassifierDescriptor classifier = scope.getClassifier(name);
053 if (classifier != null) return classifier;
054 }
055 return null;
056 }
057
058 @Override
059 public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
060 for (JetScope scope : scopeChain) {
061 ClassDescriptor objectDescriptor = scope.getObjectDescriptor(name);
062 if (objectDescriptor != null) return objectDescriptor;
063 }
064 return null;
065 }
066
067 @NotNull
068 @Override
069 public Set<ClassDescriptor> getObjectDescriptors() {
070 Set<ClassDescriptor> objectDescriptors = Sets.newHashSet();
071 for (JetScope scope : scopeChain) {
072 objectDescriptors.addAll(scope.getObjectDescriptors());
073 }
074 return objectDescriptors;
075 }
076
077 @Override
078 public NamespaceDescriptor getNamespace(@NotNull Name name) {
079 for (JetScope jetScope : scopeChain) {
080 NamespaceDescriptor namespace = jetScope.getNamespace(name);
081 if (namespace != null) {
082 return namespace;
083 }
084 }
085 return null;
086 }
087
088 @NotNull
089 @Override
090 public Set<VariableDescriptor> getProperties(@NotNull Name name) {
091 Set<VariableDescriptor> properties = Sets.newLinkedHashSet();
092 for (JetScope jetScope : scopeChain) {
093 properties.addAll(jetScope.getProperties(name));
094 }
095 return properties;
096 }
097
098 @Override
099 public VariableDescriptor getLocalVariable(@NotNull Name name) {
100 for (JetScope jetScope : scopeChain) {
101 VariableDescriptor variable = jetScope.getLocalVariable(name);
102 if (variable != null) {
103 return variable;
104 }
105 }
106 return null;
107 }
108
109 @NotNull
110 @Override
111 public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
112 if (scopeChain.length == 0) {
113 return Collections.emptySet();
114 }
115
116 Set<FunctionDescriptor> result = Sets.newLinkedHashSet();
117 for (JetScope jetScope : scopeChain) {
118 result.addAll(jetScope.getFunctions(name));
119 }
120 return result;
121 }
122
123 @NotNull
124 @Override
125 public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
126 if (implicitReceiverHierarchy == null) {
127 implicitReceiverHierarchy = Lists.newArrayList();
128 for (JetScope jetScope : scopeChain) {
129 implicitReceiverHierarchy.addAll(jetScope.getImplicitReceiversHierarchy());
130 }
131 }
132 return implicitReceiverHierarchy;
133 }
134
135 @NotNull
136 @Override
137 public DeclarationDescriptor getContainingDeclaration() {
138 return containingDeclaration;
139 }
140
141 @NotNull
142 @Override
143 public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
144 for (JetScope jetScope : scopeChain) {
145 Collection<DeclarationDescriptor> declarationsByLabel = jetScope.getDeclarationsByLabel(labelName);
146 if (!declarationsByLabel.isEmpty()) return declarationsByLabel; // TODO : merge?
147 }
148 return Collections.emptyList();
149 }
150
151 @Override
152 public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) {
153 for (JetScope jetScope : scopeChain) {
154 PropertyDescriptor propertyByFieldReference = jetScope.getPropertyByFieldReference(fieldName);
155 if (propertyByFieldReference != null) {
156 return propertyByFieldReference;
157 }
158 }
159 return null;
160 }
161
162 @NotNull
163 @Override
164 public Collection<DeclarationDescriptor> getAllDescriptors() {
165 if (allDescriptors == null) {
166 allDescriptors = Sets.newHashSet();
167 for (JetScope scope : scopeChain) {
168 allDescriptors.addAll(scope.getAllDescriptors());
169 }
170 }
171 return allDescriptors;
172 }
173
174 @NotNull
175 @Override
176 public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
177 throw new UnsupportedOperationException();
178 }
179
180 @Override
181 public String toString() {
182 return debugName;
183 }
184 }