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