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.descriptors.impl; 018 019import com.google.common.collect.Sets; 020import org.jetbrains.annotations.NotNull; 021import org.jetbrains.annotations.Nullable; 022import org.jetbrains.jet.lang.descriptors.*; 023import org.jetbrains.jet.lang.psi.JetParameter; 024import org.jetbrains.jet.lang.resolve.BindingContextUtils; 025import org.jetbrains.jet.lang.resolve.BindingTrace; 026import org.jetbrains.jet.lang.resolve.name.Name; 027import org.jetbrains.jet.lang.resolve.scopes.*; 028 029import java.util.List; 030import java.util.Set; 031 032public class MutableClassDescriptor extends MutableClassDescriptorLite { 033 private final Set<ConstructorDescriptor> constructors = Sets.newLinkedHashSet(); 034 private ConstructorDescriptor primaryConstructor; 035 036 private final Set<CallableMemberDescriptor> declaredCallableMembers = Sets.newLinkedHashSet(); 037 private final Set<CallableMemberDescriptor> allCallableMembers = Sets.newLinkedHashSet(); // includes fake overrides 038 private final Set<PropertyDescriptor> properties = Sets.newLinkedHashSet(); 039 private final Set<SimpleFunctionDescriptor> functions = Sets.newLinkedHashSet(); 040 041 private final WritableScope scopeForMemberResolution; 042 // This scope contains type parameters but does not contain inner classes 043 private final WritableScope scopeForSupertypeResolution; 044 private WritableScope scopeForInitializers = null; //contains members + primary constructor value parameters + map for backing fields 045 046 public MutableClassDescriptor(@NotNull DeclarationDescriptor containingDeclaration, 047 @NotNull JetScope outerScope, ClassKind kind, boolean isInner, Name name) { 048 super(containingDeclaration, kind, isInner); 049 050 RedeclarationHandler redeclarationHandler = RedeclarationHandler.DO_NOTHING; 051 052 setScopeForMemberLookup(new WritableScopeImpl(JetScope.EMPTY, this, redeclarationHandler, "MemberLookup") 053 .changeLockLevel(WritableScope.LockLevel.BOTH)); 054 this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, redeclarationHandler, "SupertypeResolution") 055 .changeLockLevel(WritableScope.LockLevel.BOTH); 056 this.scopeForMemberResolution = new WritableScopeImpl(scopeForSupertypeResolution, this, redeclarationHandler, "MemberResolution") 057 .changeLockLevel(WritableScope.LockLevel.BOTH); 058 if (getKind() == ClassKind.TRAIT) { 059 setUpScopeForInitializers(this); 060 } 061 062 setName(name); 063 } 064 065//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 066 067 068 public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor, @NotNull BindingTrace trace) { 069 if (constructorDescriptor.getContainingDeclaration() != this) { 070 throw new IllegalStateException("invalid containing declaration of constructor"); 071 } 072 constructors.add(constructorDescriptor); 073 if (defaultType != null) { 074 ((ConstructorDescriptorImpl) constructorDescriptor).setReturnType(getDefaultType()); 075 } 076 077 boolean primary = constructorDescriptor.isPrimary(); 078 if (primary) { 079 setUpScopeForInitializers(constructorDescriptor); 080 for (ValueParameterDescriptor valueParameterDescriptor : constructorDescriptor.getValueParameters()) { 081 JetParameter parameter = (JetParameter) BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), valueParameterDescriptor); 082 assert parameter != null; 083 if (parameter.getValOrVarNode() == null) { 084 getWritableScopeForInitializers().addVariableDescriptor(valueParameterDescriptor); 085 } 086 } 087 } 088 } 089 090 public void setPrimaryConstructor(@NotNull ConstructorDescriptor constructorDescriptor, BindingTrace trace) { 091 assert this.primaryConstructor == null : "Primary constructor assigned twice " + this; 092 this.primaryConstructor = constructorDescriptor; 093 addConstructor(constructorDescriptor, trace); 094 } 095 096 @NotNull 097 @Override 098 public Set<ConstructorDescriptor> getConstructors() { 099 return constructors; 100 } 101 102 @Override 103 @Nullable 104 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { 105 return primaryConstructor; 106 } 107 108 @NotNull 109 public Set<SimpleFunctionDescriptor> getFunctions() { 110 return functions; 111 } 112 113 @NotNull 114 public Set<PropertyDescriptor> getProperties() { 115 return properties; 116 } 117 118 @NotNull 119 public Set<CallableMemberDescriptor> getDeclaredCallableMembers() { 120 return declaredCallableMembers; 121 } 122 123 @NotNull 124 public Set<CallableMemberDescriptor> getAllCallableMembers() { 125 return allCallableMembers; 126 } 127 128 @Override 129 public void setTypeParameterDescriptors(List<TypeParameterDescriptor> typeParameters) { 130 super.setTypeParameterDescriptors(typeParameters); 131 for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) { 132 scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor); 133 } 134 scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); 135 } 136 137 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 138 139 @Override 140 public void setName(@NotNull Name name) { 141 super.setName(name); 142 scopeForMemberResolution.addLabeledDeclaration(this); 143 } 144 145 @Override 146 public void createTypeConstructor() { 147 super.createTypeConstructor(); 148 for (FunctionDescriptor functionDescriptor : getConstructors()) { 149 ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType()); 150 } 151 scopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter()); 152 } 153 154 @NotNull 155 public JetScope getScopeForSupertypeResolution() { 156 return scopeForSupertypeResolution; 157 } 158 159 @NotNull 160 public JetScope getScopeForMemberResolution() { 161 return scopeForMemberResolution; 162 } 163 164 private WritableScope getWritableScopeForInitializers() { 165 if (scopeForInitializers == null) { 166 throw new IllegalStateException("Scope for initializers queried before the primary constructor is set"); 167 } 168 return scopeForInitializers; 169 } 170 171 @NotNull 172 public JetScope getScopeForInitializers() { 173 return getWritableScopeForInitializers(); 174 } 175 176 private void setUpScopeForInitializers(@NotNull DeclarationDescriptor containingDeclaration) { 177 this.scopeForInitializers = new WritableScopeImpl( 178 scopeForMemberResolution, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Initializers") 179 .changeLockLevel(WritableScope.LockLevel.BOTH); 180 } 181 182 @Override 183 public void lockScopes() { 184 super.lockScopes(); 185 scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING); 186 scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING); 187 getWritableScopeForInitializers().changeLockLevel(WritableScope.LockLevel.READING); 188 } 189 190 private NamespaceLikeBuilder builder = null; 191 192 @Override 193 public NamespaceLikeBuilder getBuilder() { 194 if (builder == null) { 195 final NamespaceLikeBuilder superBuilder = super.getBuilder(); 196 builder = new NamespaceLikeBuilderDummy() { 197 @NotNull 198 @Override 199 public DeclarationDescriptor getOwnerForChildren() { 200 return superBuilder.getOwnerForChildren(); 201 } 202 203 @Override 204 public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) { 205 superBuilder.addObjectDescriptor(objectDescriptor); 206 } 207 208 @Override 209 public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) { 210 superBuilder.addClassifierDescriptor(classDescriptor); 211 scopeForMemberResolution.addClassifierDescriptor(classDescriptor); 212 } 213 214 @Override 215 public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) { 216 superBuilder.addFunctionDescriptor(functionDescriptor); 217 functions.add(functionDescriptor); 218 if (functionDescriptor.getKind().isReal()) { 219 declaredCallableMembers.add(functionDescriptor); 220 } 221 allCallableMembers.add(functionDescriptor); 222 scopeForMemberResolution.addFunctionDescriptor(functionDescriptor); 223 } 224 225 @Override 226 public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) { 227 ClassObjectStatus r = superBuilder.setClassObjectDescriptor(classObjectDescriptor); 228 if (r != ClassObjectStatus.OK) { 229 return r; 230 } 231 232 // Members of the class object are accessible from the class 233 // The scope must be lazy, because classObjectDescriptor may not by fully built yet 234 scopeForMemberResolution.importScope(new ClassObjectMixinScope(classObjectDescriptor)); 235 236 return ClassObjectStatus.OK; 237 } 238 239 @Override 240 public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) { 241 superBuilder.addPropertyDescriptor(propertyDescriptor); 242 properties.add(propertyDescriptor); 243 if (propertyDescriptor.getKind().isReal()) { 244 declaredCallableMembers.add(propertyDescriptor); 245 } 246 allCallableMembers.add(propertyDescriptor); 247 scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor); 248 } 249 }; 250 } 251 252 return builder; 253 } 254}