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