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