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 org.jetbrains.annotations.NotNull;
020import org.jetbrains.annotations.Nullable;
021import org.jetbrains.jet.lang.descriptors.*;
022import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
023import org.jetbrains.jet.lang.resolve.DescriptorResolver;
024import org.jetbrains.jet.lang.resolve.name.Name;
025import org.jetbrains.jet.lang.resolve.scopes.JetScope;
026import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
027import org.jetbrains.jet.lang.types.*;
028
029import java.util.Collection;
030import java.util.List;
031import java.util.Map;
032import java.util.Set;
033
034public class ClassDescriptorImpl extends DeclarationDescriptorNonRootImpl implements ClassDescriptor {
035    private TypeConstructor typeConstructor;
036
037    private JetScope memberDeclarations;
038    private Set<ConstructorDescriptor> constructors;
039    private ConstructorDescriptor primaryConstructor;
040    private ReceiverParameterDescriptor thisAsReceiverParameter;
041    private final Modality modality;
042    private ClassDescriptor classObjectDescriptor;
043    private final ClassKind kind;
044    private boolean isInner;
045
046    public ClassDescriptorImpl(
047        @NotNull DeclarationDescriptor containingDeclaration,
048        @NotNull List<AnnotationDescriptor> annotations,
049        @NotNull Modality modality,
050        @NotNull Name name
051    ) {
052        this(containingDeclaration, ClassKind.CLASS, annotations, modality, name);
053    }
054
055    public ClassDescriptorImpl(
056            @NotNull DeclarationDescriptor containingDeclaration,
057            @NotNull ClassKind kind,
058            @NotNull List<AnnotationDescriptor> annotations,
059            @NotNull Modality modality,
060            @NotNull Name name) {
061        super(containingDeclaration, annotations, name);
062        this.kind = kind;
063        this.modality = modality;
064    }
065
066
067    public final ClassDescriptorImpl initialize(
068            boolean sealed,
069            @NotNull List<? extends TypeParameterDescriptor> typeParameters,
070            @NotNull Collection<JetType> supertypes,
071            @NotNull JetScope memberDeclarations,
072            @NotNull Set<ConstructorDescriptor> constructors,
073            @Nullable ConstructorDescriptor primaryConstructor,
074            boolean isInner
075    ) {
076        this.typeConstructor = new TypeConstructorImpl(this, getAnnotations(), sealed, getName().asString(), typeParameters, supertypes);
077        this.memberDeclarations = memberDeclarations;
078        this.constructors = constructors;
079        this.primaryConstructor = primaryConstructor;
080        this.isInner = isInner;
081        return this;
082    }
083
084    public void setPrimaryConstructor(@NotNull ConstructorDescriptor primaryConstructor) {
085        this.primaryConstructor = primaryConstructor;
086    }
087
088    public void setClassObjectDescriptor(@NotNull ClassDescriptor classObjectDescriptor) {
089        this.classObjectDescriptor = classObjectDescriptor;
090    }
091
092    @Override
093    @NotNull
094    public TypeConstructor getTypeConstructor() {
095        return typeConstructor;
096    }
097
098    @Override
099    @NotNull
100    public JetScope getMemberScope(List<TypeProjection> typeArguments) {
101        assert typeArguments.size() == typeConstructor.getParameters().size() : typeArguments;
102        if (typeConstructor.getParameters().isEmpty()) {
103            return  memberDeclarations;
104        }
105        Map<TypeConstructor, TypeProjection> substitutionContext = SubstitutionUtils
106                .buildSubstitutionContext(typeConstructor.getParameters(), typeArguments);
107        return new SubstitutingScope(memberDeclarations, TypeSubstitutor.create(substitutionContext));
108    }
109
110    @NotNull
111    @Override
112    public JetType getDefaultType() {
113        return TypeUtils.makeUnsubstitutedType(this, memberDeclarations);
114    }
115
116    @NotNull
117    @Override
118    public Collection<ConstructorDescriptor> getConstructors() {
119        return constructors;
120    }
121
122    @NotNull
123    @Override
124    public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
125        throw new UnsupportedOperationException(); // TODO
126    }
127
128    @Override
129    public JetType getClassObjectType() {
130        return getClassObjectDescriptor().getDefaultType();
131    }
132
133    @Override
134    public ClassDescriptor getClassObjectDescriptor() {
135        return classObjectDescriptor;
136    }
137
138    @NotNull
139    @Override
140    public ClassKind getKind() {
141        return kind;
142    }
143
144    @Override
145    public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
146        return visitor.visitClassDescriptor(this, data);
147    }
148
149    @Override
150    public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
151        return primaryConstructor;
152    }
153
154    @Override
155    @NotNull
156    public Modality getModality() {
157        return modality;
158    }
159
160    @NotNull
161    @Override
162    public Visibility getVisibility() {
163        return Visibilities.PUBLIC;
164    }
165
166    @Override
167    public boolean isInner() {
168        return isInner;
169    }
170
171    @NotNull
172    @Override
173    public ReceiverParameterDescriptor getThisAsReceiverParameter() {
174        if (thisAsReceiverParameter == null) {
175            thisAsReceiverParameter = DescriptorResolver.createLazyReceiverParameterDescriptor(this);
176        }
177        return thisAsReceiverParameter;
178    }
179
180    @NotNull
181    @Override
182    public JetScope getUnsubstitutedInnerClassesScope() {
183        return JetScope.EMPTY;
184    }
185}