001    /*
002     * Copyright 2010-2014 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.Annotations;
023    import org.jetbrains.jet.lang.resolve.name.Name;
024    
025    import java.util.Collections;
026    import java.util.List;
027    import java.util.Set;
028    
029    import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER;
030    
031    public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements ConstructorDescriptor {
032    
033        protected final boolean isPrimary;
034    
035        private static final Name NAME = Name.special("<init>");
036    
037        protected ConstructorDescriptorImpl(
038                @NotNull ClassDescriptor containingDeclaration,
039                @Nullable ConstructorDescriptor original,
040                @NotNull Annotations annotations,
041                boolean isPrimary,
042                @NotNull Kind kind,
043                @NotNull SourceElement source
044        ) {
045            super(containingDeclaration, original, annotations, NAME, kind, source);
046            this.isPrimary = isPrimary;
047        }
048    
049        @NotNull
050        public static ConstructorDescriptorImpl create(
051                @NotNull ClassDescriptor containingDeclaration,
052                @NotNull Annotations annotations,
053                boolean isPrimary,
054                @NotNull SourceElement source
055        ) {
056            return new ConstructorDescriptorImpl(containingDeclaration, null, annotations, isPrimary, Kind.DECLARATION, source);
057        }
058    
059        public ConstructorDescriptorImpl initialize(
060                @NotNull List<TypeParameterDescriptor> typeParameters,
061                @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
062                @NotNull Visibility visibility
063        ) {
064            super.initialize(null, calculateDispatchReceiverParameter(), typeParameters, unsubstitutedValueParameters, null, Modality.FINAL, visibility);
065            return this;
066        }
067    
068        @Nullable
069        private ReceiverParameterDescriptor calculateDispatchReceiverParameter() {
070            ClassDescriptor classDescriptor = getContainingDeclaration();
071            if (classDescriptor.isInner()) {
072                DeclarationDescriptor classContainer = classDescriptor.getContainingDeclaration();
073                if (classContainer instanceof ClassDescriptor) {
074                    return ((ClassDescriptor) classContainer).getThisAsReceiverParameter();
075                }
076            }
077            return NO_RECEIVER_PARAMETER;
078        }
079    
080        @NotNull
081        @Override
082        public ClassDescriptor getContainingDeclaration() {
083            return (ClassDescriptor) super.getContainingDeclaration();
084        }
085    
086        @NotNull
087        @Override
088        public ConstructorDescriptor getOriginal() {
089            return (ConstructorDescriptor) super.getOriginal();
090        }
091    
092        @Override
093        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
094            return visitor.visitConstructorDescriptor(this, data);
095        }
096    
097        @Override
098        public boolean isPrimary() {
099            return isPrimary;
100        }
101    
102        @NotNull
103        @Override
104        public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
105            return Collections.emptySet();
106        }
107    
108        @Override
109        public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
110            throw new UnsupportedOperationException("Constructors cannot override anything");
111        }
112    
113        @NotNull
114        @Override
115        protected FunctionDescriptorImpl createSubstitutedCopy(
116                @NotNull DeclarationDescriptor newOwner,
117                @Nullable FunctionDescriptor original,
118                @NotNull Kind kind
119        ) {
120            if (kind != Kind.DECLARATION && kind != Kind.SYNTHESIZED) {
121                throw new IllegalStateException("Attempt at creating a constructor that is not a declaration: \n" +
122                                                "copy from: " + this + "\n" +
123                                                "newOwner: " + newOwner + "\n" +
124                                                "kind: " + kind);
125            }
126            assert original != null : "Attempt to create copy of constructor without preserving original: " + this;
127            return new ConstructorDescriptorImpl(
128                    (ClassDescriptor) newOwner,
129                    this,
130                    Annotations.EMPTY, // TODO
131                    isPrimary,
132                    Kind.DECLARATION,
133                    SourceElement.NO_SOURCE
134            );
135        }
136    
137        @NotNull
138        @Override
139        public ConstructorDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides) {
140            throw new UnsupportedOperationException("Constructors should not be copied for overriding");
141        }
142    }