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 org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.jet.lang.descriptors.*;
022    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
023    import org.jetbrains.jet.lang.resolve.DescriptorResolver;
024    import org.jetbrains.jet.lang.resolve.name.Name;
025    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
026    import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope;
027    import org.jetbrains.jet.lang.types.*;
028    
029    import java.util.Collection;
030    import java.util.List;
031    import java.util.Map;
032    import java.util.Set;
033    
034    public 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    }