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