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