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