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