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.Lists;
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.descriptors.annotations.AnnotationDescriptor;
024 import org.jetbrains.jet.lang.resolve.DescriptorResolver;
025 import org.jetbrains.jet.lang.resolve.name.Name;
026 import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper;
027 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
028 import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
029 import org.jetbrains.jet.lang.types.*;
030 import org.jetbrains.jet.renderer.DescriptorRenderer;
031
032 import java.util.ArrayList;
033 import java.util.Collection;
034 import java.util.Collections;
035 import java.util.List;
036
037 public abstract class MutableClassDescriptorLite extends ClassDescriptorBase {
038
039 private List<AnnotationDescriptor> annotations = Lists.newArrayList();
040
041 private List<TypeParameterDescriptor> typeParameters;
042 private Collection<JetType> supertypes = Lists.newArrayList();
043
044 private TypeConstructor typeConstructor;
045
046 private Modality modality;
047 private Visibility visibility;
048
049 private final boolean isInner;
050
051 private MutableClassDescriptorLite classObjectDescriptor;
052 private JetType classObjectType;
053 private final ClassKind kind;
054
055 private JetScope scopeForMemberLookup;
056 private JetScope innerClassesScope;
057
058 private ReceiverParameterDescriptor implicitReceiver;
059
060 private Name name;
061 private final DeclarationDescriptor containingDeclaration;
062
063 public MutableClassDescriptorLite(@NotNull DeclarationDescriptor containingDeclaration,
064 @NotNull ClassKind kind,
065 boolean isInner
066 ) {
067 this.containingDeclaration = containingDeclaration;
068 this.kind = kind;
069 this.isInner = isInner;
070 }
071
072 @NotNull
073 @Override
074 public DeclarationDescriptor getContainingDeclaration() {
075 return containingDeclaration;
076 }
077
078 @NotNull
079 @Override
080 public Name getName() {
081 return name;
082 }
083
084 public void setName(@NotNull Name name) {
085 assert this.name == null : this.name;
086 this.name = name;
087 }
088
089 @NotNull
090 @Override
091 public DeclarationDescriptor getOriginal() {
092 return this;
093 }
094
095 @NotNull
096 @Override
097 public TypeConstructor getTypeConstructor() {
098 return typeConstructor;
099 }
100
101 public void setScopeForMemberLookup(JetScope scopeForMemberLookup) {
102 this.scopeForMemberLookup = scopeForMemberLookup;
103 this.innerClassesScope = new InnerClassesScopeWrapper(scopeForMemberLookup);
104 }
105
106 public void createTypeConstructor() {
107 assert typeConstructor == null : typeConstructor;
108 this.typeConstructor = new TypeConstructorImpl(
109 this,
110 Collections.<AnnotationDescriptor>emptyList(), // TODO : pass annotations from the class?
111 !getModality().isOverridable(),
112 getName().asString(),
113 typeParameters,
114 supertypes);
115 }
116
117 private WritableScope getScopeForMemberLookupAsWritableScope() {
118 // hack
119 return (WritableScope) scopeForMemberLookup;
120 }
121
122
123 @NotNull
124 public JetScope getScopeForMemberLookup() {
125 return scopeForMemberLookup;
126 }
127
128 @Override
129 public JetType getClassObjectType() {
130 if (classObjectType == null && classObjectDescriptor != null) {
131 classObjectType = classObjectDescriptor.getDefaultType();
132 }
133 return classObjectType;
134 }
135
136 @NotNull
137 @Override
138 public ClassKind getKind() {
139 return kind;
140 }
141
142 public void setModality(Modality modality) {
143 this.modality = modality;
144 }
145
146 public void setVisibility(Visibility visibility) {
147 this.visibility = visibility;
148 }
149
150 @Override
151 @NotNull
152 public Modality getModality() {
153 return modality;
154 }
155
156 @NotNull
157 @Override
158 public Visibility getVisibility() {
159 return visibility;
160 }
161
162 @Override
163 public boolean isInner() {
164 return isInner;
165 }
166
167 public Collection<JetType> getSupertypes() {
168 return supertypes;
169 }
170
171 public void setSupertypes(@NotNull Collection<JetType> supertypes) {
172 this.supertypes = supertypes;
173 }
174
175
176 @Override
177 @Nullable
178 public MutableClassDescriptorLite getClassObjectDescriptor() {
179 return classObjectDescriptor;
180 }
181
182
183
184 @NotNull
185 @Override
186 public JetScope getUnsubstitutedInnerClassesScope() {
187 return innerClassesScope;
188 }
189
190
191 public void addSupertype(@NotNull JetType supertype) {
192 assert !ErrorUtils.isErrorType(supertype) : "Error types must be filtered out in DescriptorResolver";
193 if (TypeUtils.getClassDescriptor(supertype) != null) {
194 // See the Errors.SUPERTYPE_NOT_A_CLASS_OR_TRAIT
195 supertypes.add(supertype);
196 }
197 }
198
199 public void setTypeParameterDescriptors(List<TypeParameterDescriptor> typeParameters) {
200 if (this.typeParameters != null) {
201 throw new IllegalStateException();
202 }
203 this.typeParameters = new ArrayList<TypeParameterDescriptor>();
204 for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
205 this.typeParameters.add(typeParameterDescriptor);
206 }
207 }
208
209 public void lockScopes() {
210 getScopeForMemberLookupAsWritableScope().changeLockLevel(WritableScope.LockLevel.READING);
211 if (classObjectDescriptor != null) {
212 classObjectDescriptor.lockScopes();
213 }
214 }
215
216 @NotNull
217 @Override
218 public ReceiverParameterDescriptor getThisAsReceiverParameter() {
219 if (implicitReceiver == null) {
220 implicitReceiver = DescriptorResolver.createLazyReceiverParameterDescriptor(this);
221 }
222 return implicitReceiver;
223 }
224
225 @Override
226 public String toString() {
227 try {
228 return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]";
229 } catch (Throwable e) {
230 return super.toString();
231 }
232 }
233
234 @Override
235 public List<AnnotationDescriptor> getAnnotations() {
236 return annotations;
237 }
238
239 public void setAnnotations(List<AnnotationDescriptor> annotations) {
240 this.annotations = annotations;
241 }
242
243 private NamespaceLikeBuilder builder = null;
244 public NamespaceLikeBuilder getBuilder() {
245 if (builder == null) {
246 builder = new NamespaceLikeBuilderDummy() {
247 @NotNull
248 @Override
249 public DeclarationDescriptor getOwnerForChildren() {
250 return MutableClassDescriptorLite.this;
251 }
252
253 @Override
254 public void addClassifierDescriptor(@NotNull MutableClassDescriptorLite classDescriptor) {
255 getScopeForMemberLookupAsWritableScope().addClassifierDescriptor(classDescriptor);
256 }
257
258 @Override
259 public void addObjectDescriptor(@NotNull MutableClassDescriptorLite objectDescriptor) {
260 getScopeForMemberLookupAsWritableScope().addObjectDescriptor(objectDescriptor);
261 }
262
263 @Override
264 public void addFunctionDescriptor(@NotNull SimpleFunctionDescriptor functionDescriptor) {
265 getScopeForMemberLookupAsWritableScope().addFunctionDescriptor(functionDescriptor);
266 }
267
268 @Override
269 public void addPropertyDescriptor(@NotNull PropertyDescriptor propertyDescriptor) {
270 getScopeForMemberLookupAsWritableScope().addPropertyDescriptor(propertyDescriptor);
271 }
272
273 @Override
274 public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) {
275 if (getKind().isObject() || isInner()) {
276 return ClassObjectStatus.NOT_ALLOWED;
277 }
278
279 if (MutableClassDescriptorLite.this.classObjectDescriptor != null) {
280 return ClassObjectStatus.DUPLICATE;
281 }
282
283 assert classObjectDescriptor.getKind() == ClassKind.CLASS_OBJECT;
284 MutableClassDescriptorLite.this.classObjectDescriptor = classObjectDescriptor;
285
286 return ClassObjectStatus.OK;
287 }
288 };
289 }
290
291 return builder;
292 }
293 }