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