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 // Reads from:
034 // 1. Worker (a.k.a outer)
035 // 2. Imports
036
037 // Writes to: writable worker
038 public class WriteThroughScope extends WritableScopeWithImports {
039 private final WritableScope writableWorker;
040 private Collection<DeclarationDescriptor> allDescriptors;
041
042 public WriteThroughScope(@NotNull JetScope outerScope, @NotNull WritableScope scope,
043 @NotNull RedeclarationHandler redeclarationHandler, @NotNull String debugName) {
044 super(outerScope, redeclarationHandler, debugName);
045 this.writableWorker = scope;
046 }
047
048 @Override
049 @NotNull
050 public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
051 checkMayRead();
052
053 return writableWorker.getDeclarationsByLabel(labelName);
054 }
055
056 @Override
057 @NotNull
058 public DeclarationDescriptor getContainingDeclaration() {
059 checkMayRead();
060
061 return writableWorker.getContainingDeclaration();
062 }
063
064 @Override
065 @NotNull
066 public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
067 checkMayRead();
068
069 Set<FunctionDescriptor> result = Sets.newLinkedHashSet();
070 result.addAll(getWorkerScope().getFunctions(name));
071 result.addAll(super.getFunctions(name)); // Imports
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(getWorkerScope().getProperties(name));
082 properties.addAll(super.getProperties(name)); //imports
083 return properties;
084 }
085
086 @Override
087 @Nullable
088 public VariableDescriptor getLocalVariable(@NotNull Name name) {
089 checkMayRead();
090
091 VariableDescriptor variable = getWorkerScope().getLocalVariable(name);
092 if (variable != null) return variable;
093
094 return super.getLocalVariable(name); // Imports
095 }
096
097 @Override
098 @Nullable
099 public PackageViewDescriptor getPackage(@NotNull Name name) {
100 checkMayRead();
101
102 PackageViewDescriptor aPackage = getWorkerScope().getPackage(name);
103 if (aPackage != null) return aPackage;
104
105 return super.getPackage(name); // Imports
106 }
107
108 @Override
109 @Nullable
110 public ClassifierDescriptor getClassifier(@NotNull Name name) {
111 checkMayRead();
112
113 ClassifierDescriptor classifier = getWorkerScope().getClassifier(name);
114 if (classifier != null) return classifier;
115
116 return super.getClassifier(name); // Imports
117 }
118
119 @Override
120 public void addLabeledDeclaration(@NotNull DeclarationDescriptor descriptor) {
121 checkMayWrite();
122
123 writableWorker.addLabeledDeclaration(descriptor);
124 }
125
126 @Override
127 public void addVariableDescriptor(@NotNull VariableDescriptor variableDescriptor) {
128 checkMayWrite();
129
130 writableWorker.addVariableDescriptor(variableDescriptor);
131 }
132
133 @Override
134 public void addPropertyDescriptor(@NotNull VariableDescriptor propertyDescriptor) {
135 checkMayWrite();
136
137 writableWorker.addPropertyDescriptor(propertyDescriptor);
138 }
139
140 @Override
141 public void addFunctionDescriptor(@NotNull FunctionDescriptor functionDescriptor) {
142 checkMayWrite();
143
144 writableWorker.addFunctionDescriptor(functionDescriptor);
145 }
146
147 @Override
148 public void addTypeParameterDescriptor(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
149 checkMayWrite();
150
151 writableWorker.addTypeParameterDescriptor(typeParameterDescriptor);
152 }
153
154 @Override
155 public void addClassifierDescriptor(@NotNull ClassifierDescriptor classDescriptor) {
156 checkMayWrite();
157
158 writableWorker.addClassifierDescriptor(classDescriptor);
159 }
160
161 @Override
162 public void addClassifierAlias(@NotNull Name name, @NotNull ClassifierDescriptor classifierDescriptor) {
163 checkMayWrite();
164
165 writableWorker.addClassifierAlias(name, classifierDescriptor);
166 }
167
168 @Override
169 public void addPackageAlias(@NotNull Name name, @NotNull PackageViewDescriptor packageView) {
170 checkMayWrite();
171
172 writableWorker.addPackageAlias(name, packageView);
173 }
174
175 @Override
176 public void addVariableAlias(@NotNull Name name, @NotNull VariableDescriptor variableDescriptor) {
177 checkMayWrite();
178
179 writableWorker.addVariableAlias(name, variableDescriptor);
180 }
181
182 @Override
183 public void addFunctionAlias(@NotNull Name name, @NotNull FunctionDescriptor functionDescriptor) {
184 checkMayWrite();
185
186 writableWorker.addFunctionAlias(name, functionDescriptor);
187 }
188
189 @NotNull
190 @Override
191 public Multimap<Name, DeclarationDescriptor> getDeclaredDescriptorsAccessibleBySimpleName() {
192 return writableWorker.getDeclaredDescriptorsAccessibleBySimpleName();
193 }
194
195 @Override
196 public void importScope(@NotNull JetScope imported) {
197 checkMayWrite();
198
199 super.importScope(imported);
200 }
201
202 @Override
203 public void setImplicitReceiver(@NotNull ReceiverParameterDescriptor implicitReceiver) {
204 checkMayWrite();
205
206 writableWorker.setImplicitReceiver(implicitReceiver);
207 }
208
209 @NotNull
210 @Override
211 public Collection<DeclarationDescriptor> getAllDescriptors() {
212 checkMayRead();
213
214 if (allDescriptors == null) {
215 allDescriptors = Lists.newArrayList();
216 allDescriptors.addAll(getWorkerScope().getAllDescriptors());
217
218 for (JetScope imported : getImports()) {
219 allDescriptors.addAll(imported.getAllDescriptors());
220 }
221 }
222 return allDescriptors;
223 }
224
225 @TestOnly
226 @Override
227 protected void printAdditionalScopeStructure(@NotNull Printer p) {
228 p.print("writableWorker = ");
229 writableWorker.printScopeStructure(p.withholdIndentOnce());
230 }
231 }