001 /*
002 * Copyright 2010-2015 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.kotlin.descriptors.impl;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.kotlin.descriptors.*;
022 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
023 import org.jetbrains.kotlin.name.Name;
024 import org.jetbrains.kotlin.resolve.DescriptorFactory;
025 import org.jetbrains.kotlin.types.DescriptorSubstitutor;
026 import org.jetbrains.kotlin.types.JetType;
027 import org.jetbrains.kotlin.types.TypeSubstitutor;
028 import org.jetbrains.kotlin.types.Variance;
029 import org.jetbrains.kotlin.utils.SmartSet;
030 import org.jetbrains.kotlin.utils.UtilsPackage;
031
032 import java.util.ArrayList;
033 import java.util.Collection;
034 import java.util.List;
035 import java.util.Set;
036
037 public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRootImpl implements FunctionDescriptor {
038 private List<TypeParameterDescriptor> typeParameters;
039 private List<ValueParameterDescriptor> unsubstitutedValueParameters;
040 private JetType unsubstitutedReturnType;
041 private ReceiverParameterDescriptor extensionReceiverParameter;
042 private ReceiverParameterDescriptor dispatchReceiverParameter;
043 private Modality modality;
044 private Visibility visibility = Visibilities.UNKNOWN;
045 private boolean isOperator;
046 private final Set<FunctionDescriptor> overriddenFunctions = SmartSet.create();
047 private final FunctionDescriptor original;
048 private final Kind kind;
049
050 protected FunctionDescriptorImpl(
051 @NotNull DeclarationDescriptor containingDeclaration,
052 @Nullable FunctionDescriptor original,
053 @NotNull Annotations annotations,
054 @NotNull Name name,
055 @NotNull Kind kind,
056 @NotNull SourceElement source
057 ) {
058 super(containingDeclaration, annotations, name, source);
059 this.original = original == null ? this : original;
060 this.kind = kind;
061 }
062
063 @NotNull
064 public FunctionDescriptorImpl initialize(
065 @Nullable JetType receiverParameterType,
066 @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
067 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
068 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
069 @Nullable JetType unsubstitutedReturnType,
070 @Nullable Modality modality,
071 @NotNull Visibility visibility,
072 boolean isOperator
073 ) {
074 this.typeParameters = UtilsPackage.toReadOnlyList(typeParameters);
075 this.unsubstitutedValueParameters = unsubstitutedValueParameters;
076 this.unsubstitutedReturnType = unsubstitutedReturnType;
077 this.modality = modality;
078 this.visibility = visibility;
079 this.isOperator = isOperator;
080 this.extensionReceiverParameter = DescriptorFactory.createExtensionReceiverParameterForCallable(this, receiverParameterType);
081 this.dispatchReceiverParameter = dispatchReceiverParameter;
082
083 for (int i = 0; i < typeParameters.size(); ++i) {
084 TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
085 if (typeParameterDescriptor.getIndex() != i) {
086 throw new IllegalStateException(typeParameterDescriptor + " index is " + typeParameterDescriptor.getIndex() + " but position is " + i);
087 }
088 }
089
090 for (int i = 0; i < unsubstitutedValueParameters.size(); ++i) {
091 // TODO fill me
092 int firstValueParameterOffset = 0; // receiverParameter.exists() ? 1 : 0;
093 ValueParameterDescriptor valueParameterDescriptor = unsubstitutedValueParameters.get(i);
094 if (valueParameterDescriptor.getIndex() != i + firstValueParameterOffset) {
095 throw new IllegalStateException(valueParameterDescriptor + "index is " + valueParameterDescriptor.getIndex() + " but position is " + i);
096 }
097 }
098
099 return this;
100 }
101
102 public void setVisibility(@NotNull Visibility visibility) {
103 this.visibility = visibility;
104 }
105
106 public void setReturnType(@NotNull JetType unsubstitutedReturnType) {
107 if (this.unsubstitutedReturnType != null) {
108 // TODO: uncomment and fix tests
109 //throw new IllegalStateException("returnType already set");
110 }
111 this.unsubstitutedReturnType = unsubstitutedReturnType;
112 }
113
114 @Nullable
115 @Override
116 public ReceiverParameterDescriptor getExtensionReceiverParameter() {
117 return extensionReceiverParameter;
118 }
119
120 @Nullable
121 @Override
122 public ReceiverParameterDescriptor getDispatchReceiverParameter() {
123 return dispatchReceiverParameter;
124 }
125
126 @NotNull
127 @Override
128 public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
129 return overriddenFunctions;
130 }
131
132 @NotNull
133 @Override
134 public Modality getModality() {
135 return modality;
136 }
137
138 @NotNull
139 @Override
140 public Visibility getVisibility() {
141 return visibility;
142 }
143
144 @Override
145 public boolean isOperator() {
146 if (isOperator) return true;
147
148 for (FunctionDescriptor descriptor : overriddenFunctions) {
149 if (descriptor.isOperator()) return true;
150 }
151
152 return false;
153 }
154
155 @Override
156 public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
157 overriddenFunctions.add((FunctionDescriptor) overriddenFunction);
158 }
159
160 @Override
161 @NotNull
162 public List<TypeParameterDescriptor> getTypeParameters() {
163 return typeParameters;
164 }
165
166 @Override
167 @NotNull
168 public List<ValueParameterDescriptor> getValueParameters() {
169 return unsubstitutedValueParameters;
170 }
171
172 @Override
173 public boolean hasStableParameterNames() {
174 return true;
175 }
176
177 @Override
178 public boolean hasSynthesizedParameterNames() {
179 return false;
180 }
181
182 @Override
183 public JetType getReturnType() {
184 return unsubstitutedReturnType;
185 }
186
187 @NotNull
188 @Override
189 public FunctionDescriptor getOriginal() {
190 return original == this ? this : original.getOriginal();
191 }
192
193 @NotNull
194 @Override
195 public Kind getKind() {
196 return kind;
197 }
198
199 @Override
200 public final FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
201 if (originalSubstitutor.isEmpty()) {
202 return this;
203 }
204 return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility, isOperator, getOriginal(), true, getKind());
205 }
206
207 @Nullable
208 protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
209 @NotNull DeclarationDescriptor newOwner,
210 @NotNull Modality newModality,
211 @NotNull Visibility newVisibility,
212 boolean isOperator,
213 @Nullable FunctionDescriptor original,
214 boolean copyOverrides,
215 @NotNull Kind kind
216 ) {
217 return doSubstitute(originalSubstitutor,
218 newOwner, newModality, newVisibility, isOperator, original, copyOverrides, kind,
219 getValueParameters(), getExtensionReceiverParameterType(), getReturnType()
220 );
221 }
222
223 @Nullable
224 protected JetType getExtensionReceiverParameterType() {
225 if (extensionReceiverParameter == null) return null;
226 return extensionReceiverParameter.getType();
227 }
228
229
230 @Nullable
231 protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
232 @NotNull DeclarationDescriptor newOwner,
233 @NotNull Modality newModality,
234 @NotNull Visibility newVisibility,
235 boolean isOperator,
236 @Nullable FunctionDescriptor original,
237 boolean copyOverrides,
238 @NotNull Kind kind,
239 @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
240 @Nullable JetType newExtensionReceiverParameterType,
241 @NotNull JetType newReturnType
242 ) {
243 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, original, kind);
244
245 List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
246 List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
247 TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
248 originalTypeParameters, originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
249 );
250
251 JetType substitutedReceiverParameterType = null;
252 if (newExtensionReceiverParameterType != null) {
253 substitutedReceiverParameterType = substitutor.substitute(newExtensionReceiverParameterType, Variance.IN_VARIANCE);
254 if (substitutedReceiverParameterType == null) {
255 return null;
256 }
257 }
258
259 ReceiverParameterDescriptor substitutedExpectedThis = null;
260 if (dispatchReceiverParameter != null) {
261 // When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
262 // E.g.
263 // class Base { fun foo() }
264 // class Derived : Base
265 // val x: Base
266 // if (x is Derived) {
267 // // `x` shouldn't be marked as smart-cast
268 // // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
269 // x.foo()
270 // }
271 substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
272 if (substitutedExpectedThis == null) {
273 return null;
274 }
275 }
276
277 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
278 substitutedDescriptor, newValueParameterDescriptors, substitutor
279 );
280 if (substitutedValueParameters == null) {
281 return null;
282 }
283
284 JetType substitutedReturnType = substitutor.substitute(newReturnType, Variance.OUT_VARIANCE);
285 if (substitutedReturnType == null) {
286 return null;
287 }
288
289 substitutedDescriptor.initialize(
290 substitutedReceiverParameterType,
291 substitutedExpectedThis,
292 substitutedTypeParameters,
293 substitutedValueParameters,
294 substitutedReturnType,
295 newModality,
296 newVisibility,
297 isOperator
298 );
299
300 if (copyOverrides) {
301 for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
302 substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor));
303 }
304 }
305
306 return substitutedDescriptor;
307 }
308
309 @NotNull
310 protected abstract FunctionDescriptorImpl createSubstitutedCopy(
311 @NotNull DeclarationDescriptor newOwner,
312 @Nullable FunctionDescriptor original,
313 @NotNull Kind kind
314 );
315
316 @Override
317 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
318 return visitor.visitFunctionDescriptor(this, data);
319 }
320
321 @Nullable
322 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
323 FunctionDescriptor substitutedDescriptor,
324 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
325 @NotNull TypeSubstitutor substitutor
326 ) {
327 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
328 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
329 // TODO : Lazy?
330 JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
331 JetType varargElementType = unsubstitutedValueParameter.getVarargElementType();
332 JetType substituteVarargElementType =
333 varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
334 if (substitutedType == null) return null;
335 result.add(
336 new ValueParameterDescriptorImpl(
337 substitutedDescriptor,
338 unsubstitutedValueParameter,
339 unsubstitutedValueParameter.getIndex(),
340 unsubstitutedValueParameter.getAnnotations(),
341 unsubstitutedValueParameter.getName(),
342 substitutedType,
343 unsubstitutedValueParameter.declaresDefaultValue(),
344 substituteVarargElementType,
345 SourceElement.NO_SOURCE
346 )
347 );
348 }
349 return result;
350 }
351 }