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.Multimap;
021 import com.google.common.collect.Sets;
022 import org.jetbrains.annotations.NotNull;
023 import org.jetbrains.annotations.Nullable;
024 import org.jetbrains.annotations.TestOnly;
025 import org.jetbrains.jet.lang.descriptors.*;
026 import org.jetbrains.jet.lang.resolve.name.LabelName;
027 import org.jetbrains.jet.lang.resolve.name.Name;
028 import org.jetbrains.jet.utils.Printer;
029
030 import java.util.Collection;
031 import java.util.Set;
032
033 public class WriteThroughScope extends WritableScopeWithImports {
034 private final WritableScope writableWorker;
035 private Collection<DeclarationDescriptor> allDescriptors;
036
037 public WriteThroughScope(@NotNull JetScope outerScope, @NotNull WritableScope scope,
038 @NotNull RedeclarationHandler redeclarationHandler, @NotNull String debugName) {
039 super(outerScope, redeclarationHandler, debugName);
040 this.writableWorker = scope;
041 }
042
043 @Override
044 @NotNull
045 public Collection<DeclarationDescriptor> getDeclarationsByLabel(LabelName labelName) {
046 checkMayRead();
047
048 return writableWorker.getDeclarationsByLabel(labelName);
049 }
050
051 @Override
052 @NotNull
053 public DeclarationDescriptor getContainingDeclaration() {
054 checkMayRead();
055
056 return writableWorker.getContainingDeclaration();
057 }
058
059 @Override
060 @NotNull
061 public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
062 checkMayRead();
063
064 Set<FunctionDescriptor> result = Sets.newLinkedHashSet();
065
066 result.addAll(writableWorker.getFunctions(name));
067
068 result.addAll(getWorkerScope().getFunctions(name));
069
070 result.addAll(super.getFunctions(name)); // Imports
071
072 return result;
073 }
074
075 @Override
076 @NotNull
077 public Set<VariableDescriptor> getProperties(@NotNull Name name) {
078 checkMayRead();
079
080 Set<VariableDescriptor> properties = Sets.newLinkedHashSet();
081 properties.addAll(writableWorker.getProperties(name));
082 properties.addAll(getWorkerScope().getProperties(name));
083 properties.addAll(super.getProperties(name)); //imports
084 return properties;
085 }
086
087 @Override
088 @Nullable
089 public VariableDescriptor getLocalVariable(@NotNull Name name) {
090 checkMayRead();
091
092 VariableDescriptor variable = writableWorker.getLocalVariable(name);
093 if (variable != null) return variable;
094
095 variable = getWorkerScope().getLocalVariable(name);
096 if (variable != null) return variable;
097
098 return super.getLocalVariable(name); // Imports
099 }
100
101 @Override
102 @Nullable
103 public NamespaceDescriptor getNamespace(@NotNull Name name) {
104 checkMayRead();
105
106 NamespaceDescriptor namespace = writableWorker.getNamespace(name);
107 if (namespace != null) return namespace;
108
109 namespace = getWorkerScope().getNamespace(name);
110 if (namespace != null) return namespace;
111
112 return super.getNamespace(name); // Imports
113 }
114
115 @Override
116 @Nullable
117 public ClassifierDescriptor getClassifier(@NotNull Name name) {
118 checkMayRead();
119
120 ClassifierDescriptor classifier = writableWorker.getClassifier(name);
121 if (classifier != null) return classifier;
122
123 classifier = getWorkerScope().getClassifier(name);
124 if (classifier != null) return classifier;
125
126 return super.getClassifier(name); // Imports
127 }
128
129 @Override
130 public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
131 checkMayRead();
132
133 ClassDescriptor objectDescriptor = writableWorker.getObjectDescriptor(name);
134 if (objectDescriptor != null) return objectDescriptor;
135
136 objectDescriptor = getWorkerScope().getObjectDescriptor(name);
137 if (objectDescriptor != null) return objectDescriptor;
138
139 return super.getObjectDescriptor(name); // Imports
140 }
141
142 @NotNull
143 @Override
144 public Set<ClassDescriptor> getObjectDescriptors() {
145 checkMayRead();
146 Set<ClassDescriptor> objectDescriptors = Sets.newHashSet();
147
148 objectDescriptors.addAll(super.getObjectDescriptors());
149 objectDescriptors.addAll(getWorkerScope().getObjectDescriptors());
150 objectDescriptors.addAll(writableWorker.getObjectDescriptors());
151 return objectDescriptors;
152 }
153
154 @Override
155 public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) {
156 checkMayWrite();
157
158 writableWorker.addLabeledDeclaration(descriptor); // TODO : review
159 }
160
161 @Override
162 public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) {
163 checkMayWrite();
164
165 writableWorker.addVariableDescriptor(variableDescriptor);
166 }
167
168 @Override
169 public void addPropertyDescriptor(@NotNull VariableDescriptor propertyDescriptor) {
170 checkMayWrite();
171
172 writableWorker.addPropertyDescriptor(propertyDescriptor);
173 }
174
175 @Override
176 public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
177 checkMayWrite();
178
179 writableWorker.addFunctionDescriptor(functionDescriptor);
180 }
181
182 @Override
183 public void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
184 checkMayWrite();
185
186 writableWorker.addTypeParameterDescriptor(typeParameterDescriptor);
187 }
188
189 @Override
190 public void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor) {
191 checkMayWrite();
192
193 writableWorker.addClassifierDescriptor(classDescriptor);
194 }
195
196 @Override
197 public void addObjectDescriptor(@NotNull ClassDescriptor objectDescriptor) {
198 checkMayWrite();
199
200 writableWorker.addObjectDescriptor(objectDescriptor);
201 }
202
203 @Override
204 public void addClassifierAlias(@NotNull Name name, @NotNull ClassifierDescriptor classifierDescriptor) {
205 checkMayWrite();
206
207 writableWorker.addClassifierAlias(name, classifierDescriptor);
208 }
209
210 @Override
211 public void addNamespaceAlias(@NotNull Name name, @NotNull NamespaceDescriptor namespaceDescriptor) {
212 checkMayWrite();
213
214 writableWorker.addNamespaceAlias(name, namespaceDescriptor);
215 }
216
217 @Override
218 public void addVariableAlias(@NotNull Name name, @NotNull VariableDescriptor variableDescriptor) {
219 checkMayWrite();
220
221 writableWorker.addVariableAlias(name, variableDescriptor);
222 }
223
224 @Override
225 public void addFunctionAlias(@NotNull Name name, @NotNull FunctionDescriptor functionDescriptor) {
226 checkMayWrite();
227
228 writableWorker.addFunctionAlias(name, functionDescriptor);
229 }
230
231 @Override
232 public void addNamespace(@NotNull NamespaceDescriptor namespaceDescriptor) {
233 checkMayWrite();
234
235 writableWorker.addNamespace(namespaceDescriptor);
236 }
237
238 @Override
239 @Nullable
240 public NamespaceDescriptor getDeclaredNamespace(@NotNull Name name) {
241 checkMayRead();
242
243 return writableWorker.getDeclaredNamespace(name);
244 }
245
246 @NotNull
247 @Override
248 public Multimap<Name, DeclarationDescriptor> getDeclaredDescriptorsAccessibleBySimpleName() {
249 return writableWorker.getDeclaredDescriptorsAccessibleBySimpleName();
250 }
251
252 @Override
253 public void importScope(@NotNull JetScope imported) {
254 checkMayWrite();
255
256 super.importScope(imported); //
257 }
258
259 @Override
260 public void setImplicitReceiver(@NotNull ReceiverParameterDescriptor implicitReceiver) {
261 checkMayWrite();
262
263 writableWorker.setImplicitReceiver(implicitReceiver);
264 }
265
266 @NotNull
267 @Override
268 public Collection<DeclarationDescriptor> getAllDescriptors() {
269 checkMayRead();
270
271 if (allDescriptors == null) {
272 allDescriptors = Lists.newArrayList();
273 allDescriptors.addAll(writableWorker.getAllDescriptors());
274 allDescriptors.addAll(getWorkerScope().getAllDescriptors());
275
276 for (JetScope imported : getImports()) {
277 allDescriptors.addAll(imported.getAllDescriptors());
278 }
279 }
280 return allDescriptors;
281 }
282
283 @NotNull
284 public JetScope getOuterScope() {
285 checkMayRead();
286
287 return getWorkerScope();
288 }
289
290 @TestOnly
291 @Override
292 protected void printAdditionalScopeStructure(@NotNull Printer p) {
293 p.print("writableWorker = ");
294 writableWorker.printScopeStructure(p.withholdIndentOnce());
295 }
296 }