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 implements ClassDescriptorWithResolutionScopes {
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.isComputed()) {
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 @Override
111 @NotNull
112 public Set<CallableMemberDescriptor> getDeclaredCallableMembers() {
113 return declaredCallableMembers;
114 }
115
116 @NotNull
117 public Set<CallableMemberDescriptor> getAllCallableMembers() {
118 return allCallableMembers;
119 }
120
121 @Override
122 public void setTypeParameterDescriptors(List<TypeParameterDescriptor> typeParameters) {
123 super.setTypeParameterDescriptors(typeParameters);
124 for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
125 scopeForSupertypeResolution.addTypeParameterDescriptor(typeParameterDescriptor);
126 }
127 scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
128 }
129
130 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
131
132 @Override
133 public void createTypeConstructor() {
134 super.createTypeConstructor();
135 for (FunctionDescriptor functionDescriptor : getConstructors()) {
136 ((ConstructorDescriptorImpl) functionDescriptor).setReturnType(getDefaultType());
137 }
138 scopeForMemberResolution.setImplicitReceiver(getThisAsReceiverParameter());
139 }
140
141 @Override
142 @NotNull
143 public JetScope getScopeForClassHeaderResolution() {
144 return scopeForSupertypeResolution;
145 }
146
147 @Override
148 @NotNull
149 public JetScope getScopeForMemberDeclarationResolution() {
150 return scopeForMemberResolution;
151 }
152
153 private WritableScope getWritableScopeForInitializers() {
154 if (scopeForInitializers == null) {
155 throw new IllegalStateException("Scope for initializers queried before the primary constructor is set");
156 }
157 return scopeForInitializers;
158 }
159
160 @Override
161 @NotNull
162 public JetScope getScopeForInitializerResolution() {
163 return getWritableScopeForInitializers();
164 }
165
166 private void setUpScopeForInitializers(@NotNull DeclarationDescriptor containingDeclaration) {
167 this.scopeForInitializers = new WritableScopeImpl(
168 scopeForMemberResolution, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Initializers")
169 .changeLockLevel(WritableScope.LockLevel.BOTH);
170 }
171
172 @Override
173 public void lockScopes() {
174 super.lockScopes();
175 scopeForSupertypeResolution.changeLockLevel(WritableScope.LockLevel.READING);
176 scopeForMemberResolution.changeLockLevel(WritableScope.LockLevel.READING);
177 getWritableScopeForInitializers().changeLockLevel(WritableScope.LockLevel.READING);
178 }
179
180 private PackageLikeBuilder builder = null;
181
182 @Override
183 public PackageLikeBuilder getBuilder() {
184 if (builder == null) {
185 final PackageLikeBuilder superBuilder = super.getBuilder();
186 builder = new PackageLikeBuilder() {
187 @NotNull
188 @Override
189 public DeclarationDescriptor getOwnerForChildren() {
190 return superBuilder.getOwnerForChildren();
191 }
192
193 @Override
194 public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
195 superBuilder.addClassifierDescriptor(classDescriptor);
196 scopeForMemberResolution.addClassifierDescriptor(classDescriptor);
197 }
198
199 @Override
200 public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
201 superBuilder.addFunctionDescriptor(functionDescriptor);
202 functions.add(functionDescriptor);
203 if (functionDescriptor.getKind().isReal()) {
204 declaredCallableMembers.add(functionDescriptor);
205 }
206 allCallableMembers.add(functionDescriptor);
207 scopeForMemberResolution.addFunctionDescriptor(functionDescriptor);
208 }
209
210 @Override
211 public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
212 ClassObjectStatus r = superBuilder.setClassObjectDescriptor(classObjectDescriptor);
213 if (r != ClassObjectStatus.OK) {
214 return r;
215 }
216
217 // Members of the class object are accessible from the class
218 // The scope must be lazy, because classObjectDescriptor may not by fully built yet
219 scopeForMemberResolution.importScope(new ClassObjectMixinScope(classObjectDescriptor));
220
221 return ClassObjectStatus.OK;
222 }
223
224 @Override
225 public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
226 superBuilder.addPropertyDescriptor(propertyDescriptor);
227 properties.add(propertyDescriptor);
228 if (propertyDescriptor.getKind().isReal()) {
229 declaredCallableMembers.add(propertyDescriptor);
230 }
231 allCallableMembers.add(propertyDescriptor);
232 scopeForMemberResolution.addPropertyDescriptor(propertyDescriptor);
233 }
234 };
235 }
236
237 return builder;
238 }
239 }