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 017package org.jetbrains.jet.lang.descriptors.impl; 018 019import com.google.common.collect.Lists; 020import org.jetbrains.annotations.NotNull; 021import org.jetbrains.annotations.Nullable; 022import org.jetbrains.jet.lang.descriptors.*; 023import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 024import org.jetbrains.jet.lang.resolve.DescriptorResolver; 025import org.jetbrains.jet.lang.resolve.name.Name; 026import org.jetbrains.jet.lang.resolve.scopes.InnerClassesScopeWrapper; 027import org.jetbrains.jet.lang.resolve.scopes.JetScope; 028import org.jetbrains.jet.lang.resolve.scopes.WritableScope; 029import org.jetbrains.jet.lang.types.*; 030import org.jetbrains.jet.renderer.DescriptorRenderer; 031 032import java.util.ArrayList; 033import java.util.Collection; 034import java.util.Collections; 035import java.util.List; 036 037public 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}