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.psi.JetParameter;
024 import org.jetbrains.jet.lang.resolve.BindingContextUtils;
025 import org.jetbrains.jet.lang.resolve.BindingTrace;
026 import org.jetbrains.jet.lang.resolve.name.Name;
027 import org.jetbrains.jet.lang.resolve.scopes.*;
028
029 import java.util.List;
030 import java.util.Set;
031
032 public 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 }