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 com.google.common.collect.Lists;
020    import com.google.common.collect.Sets;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.annotations.Nullable;
023    import org.jetbrains.jet.lang.descriptors.*;
024    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
025    import org.jetbrains.jet.lang.resolve.DescriptorResolver;
026    import org.jetbrains.jet.lang.resolve.OverridingUtil;
027    import org.jetbrains.jet.lang.resolve.name.Name;
028    import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
029    import org.jetbrains.jet.lang.types.JetType;
030    import org.jetbrains.jet.lang.types.TypeSubstitutor;
031    import org.jetbrains.jet.lang.types.Variance;
032    
033    import java.util.List;
034    import java.util.Set;
035    
036    public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRootImpl implements FunctionDescriptor {
037    
038        protected List<TypeParameterDescriptor> typeParameters;
039        protected List<ValueParameterDescriptor> unsubstitutedValueParameters;
040        protected JetType unsubstitutedReturnType;
041        private ReceiverParameterDescriptor receiverParameter;
042        protected ReceiverParameterDescriptor expectedThisObject;
043    
044        protected Modality modality;
045        protected Visibility visibility;
046        protected final Set<FunctionDescriptor> overriddenFunctions = Sets.newLinkedHashSet(); // LinkedHashSet is essential here
047        private final FunctionDescriptor original;
048        private final Kind kind;
049    
050        protected FunctionDescriptorImpl(
051                @NotNull DeclarationDescriptor containingDeclaration,
052                @NotNull List<AnnotationDescriptor> annotations,
053                @NotNull Name name,
054                @NotNull Kind kind) {
055            super(containingDeclaration, annotations, name);
056            this.original = this;
057            this.kind = kind;
058        }
059    
060        protected FunctionDescriptorImpl(
061                @NotNull DeclarationDescriptor containingDeclaration,
062                @NotNull FunctionDescriptor original,
063                @NotNull List<AnnotationDescriptor> annotations,
064                @NotNull Name name,
065                @NotNull Kind kind) {
066            super(containingDeclaration, annotations, name);
067            this.original = original;
068            this.kind = kind;
069        }
070    
071        protected FunctionDescriptorImpl initialize(
072                @Nullable JetType receiverParameterType,
073                @Nullable ReceiverParameterDescriptor expectedThisObject,
074                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
075                @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
076                @Nullable JetType unsubstitutedReturnType,
077                @Nullable Modality modality,
078                @NotNull Visibility visibility) {
079            this.typeParameters = Lists.newArrayList(typeParameters);
080            this.unsubstitutedValueParameters = unsubstitutedValueParameters;
081            this.unsubstitutedReturnType = unsubstitutedReturnType;
082            this.modality = modality;
083            this.visibility = visibility;
084            this.receiverParameter = DescriptorResolver.resolveReceiverParameterFor(this, receiverParameterType);
085            this.expectedThisObject = expectedThisObject;
086            
087            for (int i = 0; i < typeParameters.size(); ++i) {
088                TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
089                if (typeParameterDescriptor.getIndex() != i) {
090                    throw new IllegalStateException(typeParameterDescriptor + " index is " + typeParameterDescriptor.getIndex() + " but position is " + i);
091                }
092            }
093    
094            for (int i = 0; i < unsubstitutedValueParameters.size(); ++i) {
095                // TODO fill me
096                int firstValueParameterOffset = 0; // receiverParameter.exists() ? 1 : 0;
097                ValueParameterDescriptor valueParameterDescriptor = unsubstitutedValueParameters.get(i);
098                if (valueParameterDescriptor.getIndex() != i + firstValueParameterOffset) {
099                    throw new IllegalStateException(valueParameterDescriptor + "index is " + valueParameterDescriptor.getIndex() + " but position is " + i);
100                }
101            }
102    
103            return this;
104        }
105    
106        public void setVisibility(@NotNull Visibility visibility) {
107            this.visibility = visibility;
108        }
109    
110        public void setReturnType(@NotNull JetType unsubstitutedReturnType) {
111            if (this.unsubstitutedReturnType != null) {
112                // TODO: uncomment and fix tests
113                //throw new IllegalStateException("returnType already set");
114            }
115            this.unsubstitutedReturnType = unsubstitutedReturnType;
116        }
117    
118        @Nullable
119        @Override
120        public ReceiverParameterDescriptor getReceiverParameter() {
121            return receiverParameter;
122        }
123    
124        @Nullable
125        @Override
126        public ReceiverParameterDescriptor getExpectedThisObject() {
127            return expectedThisObject;
128        }
129    
130        @NotNull
131        @Override
132        public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
133            return overriddenFunctions;
134        }
135    
136        @NotNull
137        @Override
138        public Modality getModality() {
139            return modality;
140        }
141    
142        @NotNull
143        @Override
144        public Visibility getVisibility() {
145            return visibility;
146        }
147    
148        @Override
149        public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
150            overriddenFunctions.add((FunctionDescriptor) overriddenFunction);
151        }
152    
153        @Override
154        @NotNull
155        public List<TypeParameterDescriptor> getTypeParameters() {
156            return typeParameters;
157        }
158    
159        @Override
160        @NotNull
161        public List<ValueParameterDescriptor> getValueParameters() {
162            return unsubstitutedValueParameters;
163        }
164    
165        @Override
166        public JetType getReturnType() {
167            return unsubstitutedReturnType;
168        }
169    
170        @NotNull
171        @Override
172        public FunctionDescriptor getOriginal() {
173            return original == this ? this : original.getOriginal();
174        }
175    
176        @Override
177        public Kind getKind() {
178            return kind;
179        }
180    
181        @Override
182        public final FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
183            if (originalSubstitutor.isEmpty()) {
184                return this;
185            }
186            return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility, true, true, getKind());
187        }
188    
189        protected FunctionDescriptor doSubstitute(TypeSubstitutor originalSubstitutor,
190                DeclarationDescriptor newOwner, Modality newModality, Visibility newVisibility, boolean preserveOriginal, boolean copyOverrides, Kind kind) {
191            FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, preserveOriginal, kind);
192    
193            List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
194            TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
195    
196            JetType substitutedReceiverParameterType = null;
197            if (receiverParameter != null) {
198                substitutedReceiverParameterType = substitutor.substitute(getReceiverParameter().getType(), Variance.IN_VARIANCE);
199                if (substitutedReceiverParameterType == null) {
200                    return null;
201                }
202            }
203    
204            ReceiverParameterDescriptor substitutedExpectedThis = null;
205            if (expectedThisObject != null) {
206                substitutedExpectedThis = expectedThisObject.substitute(substitutor);
207                if (substitutedExpectedThis == null) {
208                    return null;
209                }
210            }
211    
212            List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(substitutedDescriptor, this, substitutor);
213            if (substitutedValueParameters == null) {
214                return null;
215            }
216    
217            JetType substitutedReturnType = FunctionDescriptorUtil.getSubstitutedReturnType(this, substitutor);
218            if (substitutedReturnType == null) {
219                return null;
220            }
221    
222            substitutedDescriptor.initialize(
223                    substitutedReceiverParameterType,
224                    substitutedExpectedThis,
225                    substitutedTypeParameters,
226                    substitutedValueParameters,
227                    substitutedReturnType,
228                    newModality,
229                    newVisibility
230            );
231            if (copyOverrides) {
232                for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
233                    OverridingUtil.bindOverride(substitutedDescriptor, overriddenFunction.substitute(substitutor));
234                }
235            }
236            return substitutedDescriptor;
237        }
238    
239        protected abstract FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind);
240    
241        @Override
242        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
243            return visitor.visitFunctionDescriptor(this, data);
244        }
245    }