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 017package org.jetbrains.jet.lang.resolve.scopes; 018 019import com.google.common.collect.Lists; 020import com.google.common.collect.Multimap; 021import com.google.common.collect.Sets; 022import org.jetbrains.annotations.NotNull; 023import org.jetbrains.annotations.Nullable; 024import org.jetbrains.jet.lang.descriptors.*; 025import org.jetbrains.jet.lang.resolve.name.LabelName; 026import org.jetbrains.jet.lang.resolve.name.Name; 027 028import java.util.Collection; 029import java.util.Set; 030 031public 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}