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.KotlinType;
027 import org.jetbrains.kotlin.types.TypeSubstitutor;
028 import org.jetbrains.kotlin.types.Variance;
029 import org.jetbrains.kotlin.utils.CollectionsKt;
030 import org.jetbrains.kotlin.utils.SmartSet;
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 KotlinType unsubstitutedReturnType;
041 private ReceiverParameterDescriptor extensionReceiverParameter;
042 private ReceiverParameterDescriptor dispatchReceiverParameter;
043 private Modality modality;
044 private Visibility visibility = Visibilities.UNKNOWN;
045 private boolean isOperator = false;
046 private boolean isInfix = false;
047 private boolean isExternal = false;
048 private boolean isInline = false;
049 private boolean isTailrec = false;
050 private boolean isHidden = false;
051 private boolean hasStableParameterNames = true;
052 private boolean hasSynthesizedParameterNames = false;
053 private final Set<FunctionDescriptor> overriddenFunctions = SmartSet.create();
054 private final FunctionDescriptor original;
055 private final Kind kind;
056 @Nullable
057 private FunctionDescriptor initialSignatureDescriptor = null;
058
059 protected FunctionDescriptorImpl(
060 @NotNull DeclarationDescriptor containingDeclaration,
061 @Nullable FunctionDescriptor original,
062 @NotNull Annotations annotations,
063 @NotNull Name name,
064 @NotNull Kind kind,
065 @NotNull SourceElement source
066 ) {
067 super(containingDeclaration, annotations, name, source);
068 this.original = original == null ? this : original;
069 this.kind = kind;
070 }
071
072 @NotNull
073 public FunctionDescriptorImpl initialize(
074 @Nullable KotlinType receiverParameterType,
075 @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
076 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
077 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
078 @Nullable KotlinType unsubstitutedReturnType,
079 @Nullable Modality modality,
080 @NotNull Visibility visibility
081 ) {
082 this.typeParameters = CollectionsKt.toReadOnlyList(typeParameters);
083 this.unsubstitutedValueParameters = unsubstitutedValueParameters;
084 this.unsubstitutedReturnType = unsubstitutedReturnType;
085 this.modality = modality;
086 this.visibility = visibility;
087 this.extensionReceiverParameter = DescriptorFactory.createExtensionReceiverParameterForCallable(this, receiverParameterType);
088 this.dispatchReceiverParameter = dispatchReceiverParameter;
089
090 for (int i = 0; i < typeParameters.size(); ++i) {
091 TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
092 if (typeParameterDescriptor.getIndex() != i) {
093 throw new IllegalStateException(typeParameterDescriptor + " index is " + typeParameterDescriptor.getIndex() + " but position is " + i);
094 }
095 }
096
097 for (int i = 0; i < unsubstitutedValueParameters.size(); ++i) {
098 // TODO fill me
099 int firstValueParameterOffset = 0; // receiverParameter.exists() ? 1 : 0;
100 ValueParameterDescriptor valueParameterDescriptor = unsubstitutedValueParameters.get(i);
101 if (valueParameterDescriptor.getIndex() != i + firstValueParameterOffset) {
102 throw new IllegalStateException(valueParameterDescriptor + "index is " + valueParameterDescriptor.getIndex() + " but position is " + i);
103 }
104 }
105
106 return this;
107 }
108
109 public void setVisibility(@NotNull Visibility visibility) {
110 this.visibility = visibility;
111 }
112
113 public void setOperator(boolean isOperator) {
114 this.isOperator = isOperator;
115 }
116
117 public void setInfix(boolean isInfix) {
118 this.isInfix = isInfix;
119 }
120
121 public void setExternal(boolean isExternal) {
122 this.isExternal = isExternal;
123 }
124
125 public void setInline(boolean isInline) {
126 this.isInline = isInline;
127 }
128
129 public void setTailrec(boolean isTailrec) {
130 this.isTailrec = isTailrec;
131 }
132
133 public void setHidden(boolean hidden) {
134 isHidden = hidden;
135 }
136
137 public void setReturnType(@NotNull KotlinType unsubstitutedReturnType) {
138 if (this.unsubstitutedReturnType != null) {
139 // TODO: uncomment and fix tests
140 //throw new IllegalStateException("returnType already set");
141 }
142 this.unsubstitutedReturnType = unsubstitutedReturnType;
143 }
144
145 public void setHasStableParameterNames(boolean hasStableParameterNames) {
146 this.hasStableParameterNames = hasStableParameterNames;
147 }
148
149 public void setHasSynthesizedParameterNames(boolean hasSynthesizedParameterNames) {
150 this.hasSynthesizedParameterNames = hasSynthesizedParameterNames;
151 }
152
153 @Nullable
154 @Override
155 public ReceiverParameterDescriptor getExtensionReceiverParameter() {
156 return extensionReceiverParameter;
157 }
158
159 @Nullable
160 @Override
161 public ReceiverParameterDescriptor getDispatchReceiverParameter() {
162 return dispatchReceiverParameter;
163 }
164
165 @NotNull
166 @Override
167 public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
168 return overriddenFunctions;
169 }
170
171 @NotNull
172 @Override
173 public Modality getModality() {
174 return modality;
175 }
176
177 @NotNull
178 @Override
179 public Visibility getVisibility() {
180 return visibility;
181 }
182
183 @Override
184 public boolean isOperator() {
185 if (isOperator) return true;
186
187 for (FunctionDescriptor descriptor : overriddenFunctions) {
188 if (descriptor.isOperator()) return true;
189 }
190
191 return false;
192 }
193
194 @Override
195 public boolean isInfix() {
196 if (isInfix) return true;
197
198 for (FunctionDescriptor descriptor : overriddenFunctions) {
199 if (descriptor.isInfix()) return true;
200 }
201
202 return false;
203 }
204
205 @Override
206 public boolean isExternal() {
207 return isExternal;
208 }
209
210 @Override
211 public boolean isInline() {
212 return isInline;
213 }
214
215 @Override
216 public boolean isTailrec() {
217 return isTailrec;
218 }
219
220 @Override
221 public boolean isHiddenToOvercomeSignatureClash() {
222 return isHidden;
223 }
224
225 @Override
226 public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
227 overriddenFunctions.add((FunctionDescriptor) overriddenFunction);
228 }
229
230 @Override
231 @NotNull
232 public List<TypeParameterDescriptor> getTypeParameters() {
233 return typeParameters;
234 }
235
236 @Override
237 @NotNull
238 public List<ValueParameterDescriptor> getValueParameters() {
239 return unsubstitutedValueParameters;
240 }
241
242 @Override
243 public boolean hasStableParameterNames() {
244 return hasStableParameterNames;
245 }
246
247 @Override
248 public boolean hasSynthesizedParameterNames() {
249 return hasSynthesizedParameterNames;
250 }
251
252 @Override
253 public KotlinType getReturnType() {
254 return unsubstitutedReturnType;
255 }
256
257 @NotNull
258 @Override
259 public FunctionDescriptor getOriginal() {
260 return original == this ? this : original.getOriginal();
261 }
262
263 @NotNull
264 @Override
265 public Kind getKind() {
266 return kind;
267 }
268
269 @Override
270 public FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
271 if (originalSubstitutor.isEmpty()) {
272 return this;
273 }
274 return doSubstitute(newCopyBuilder(originalSubstitutor).setOriginal(getOriginal()));
275 }
276
277 @Nullable
278 protected KotlinType getExtensionReceiverParameterType() {
279 if (extensionReceiverParameter == null) return null;
280 return extensionReceiverParameter.getType();
281 }
282
283 public class CopyConfiguration {
284 protected @NotNull TypeSubstitutor originalSubstitutor;
285 protected @NotNull DeclarationDescriptor newOwner;
286 protected @NotNull Modality newModality;
287 protected @NotNull Visibility newVisibility;
288 protected @Nullable FunctionDescriptor original = null;
289 protected @NotNull Kind kind;
290 protected @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors;
291 protected @Nullable KotlinType newExtensionReceiverParameterType;
292 protected @NotNull KotlinType newReturnType;
293 protected @Nullable Name name;
294 protected boolean copyOverrides;
295 protected boolean signatureChange;
296 private boolean isHiddenToOvercomeSignatureClash;
297 private List<TypeParameterDescriptor> newTypeParameters = null;
298
299 public CopyConfiguration(
300 @NotNull TypeSubstitutor originalSubstitutor,
301 @NotNull DeclarationDescriptor newOwner,
302 @NotNull Modality newModality,
303 @NotNull Visibility newVisibility,
304 @NotNull Kind kind,
305 @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
306 @Nullable KotlinType newExtensionReceiverParameterType,
307 @NotNull KotlinType newReturnType,
308 @Nullable Name name
309 ) {
310 this.originalSubstitutor = originalSubstitutor;
311 this.newOwner = newOwner;
312 this.newModality = newModality;
313 this.newVisibility = newVisibility;
314 this.kind = kind;
315 this.newValueParameterDescriptors = newValueParameterDescriptors;
316 this.newExtensionReceiverParameterType = newExtensionReceiverParameterType;
317 this.newReturnType = newReturnType;
318 this.name = name;
319 this.copyOverrides = true;
320 this.signatureChange = false;
321 this.isHiddenToOvercomeSignatureClash = isHiddenToOvercomeSignatureClash();
322 }
323
324 @NotNull
325 protected CopyConfiguration setOwner(@NotNull DeclarationDescriptor owner) {
326 this.newOwner = owner;
327 return this;
328 }
329
330 @NotNull
331 public CopyConfiguration setModality(@NotNull Modality modality) {
332 this.newModality = modality;
333 return this;
334 }
335
336 @NotNull
337 public CopyConfiguration setVisibility(@NotNull Visibility visibility) {
338 this.newVisibility = visibility;
339 return this;
340 }
341
342 @NotNull
343 public CopyConfiguration setKind(@NotNull Kind kind) {
344 this.kind = kind;
345 return this;
346 }
347
348 @NotNull
349 public CopyConfiguration setCopyOverrides(boolean copyOverrides) {
350 this.copyOverrides = copyOverrides;
351 return this;
352 }
353
354 @NotNull
355 public CopyConfiguration setName(@NotNull Name name) {
356 this.name = name;
357 return this;
358 }
359
360 @NotNull
361 public CopyConfiguration setValueParameters(@NotNull List<ValueParameterDescriptor> parameters) {
362 this.newValueParameterDescriptors = parameters;
363 return this;
364 }
365
366 @NotNull
367 public CopyConfiguration setTypeParameters(@NotNull List<TypeParameterDescriptor> parameters) {
368 this.newTypeParameters = parameters;
369 return this;
370 }
371
372 public CopyConfiguration setReturnType(@NotNull KotlinType type) {
373 this.newReturnType = type;
374 return this;
375 }
376
377 public CopyConfiguration setExtensionReceiverType(@Nullable KotlinType type) {
378 this.newExtensionReceiverParameterType = type;
379 return this;
380 }
381
382 @NotNull
383 public CopyConfiguration setOriginal(@NotNull FunctionDescriptor original) {
384 this.original = original;
385 return this;
386 }
387
388 @NotNull
389 public CopyConfiguration setSignatureChange() {
390 this.signatureChange = true;
391 return this;
392 }
393
394 @NotNull
395 public CopyConfiguration setHidden() {
396 isHiddenToOvercomeSignatureClash = true;
397 return this;
398 }
399
400 public FunctionDescriptor build() {
401 return doSubstitute(this);
402 }
403
404 @Nullable
405 public FunctionDescriptor getOriginal() {
406 return original;
407 }
408
409 @NotNull
410 public TypeSubstitutor getOriginalSubstitutor() {
411 return originalSubstitutor;
412 }
413 }
414
415 @NotNull
416 public CopyConfiguration newCopyBuilder() {
417 return newCopyBuilder(TypeSubstitutor.EMPTY);
418 }
419
420 @NotNull
421 private CopyConfiguration newCopyBuilder(@NotNull TypeSubstitutor substitutor) {
422 return new CopyConfiguration(
423 substitutor,
424 getContainingDeclaration(), getModality(), getVisibility(), getKind(), getValueParameters(),
425 getExtensionReceiverParameterType(), getReturnType(), null);
426 }
427
428 @Nullable
429 protected FunctionDescriptor doSubstitute(@NotNull CopyConfiguration configuration) {
430 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(
431 configuration.newOwner, configuration.original, configuration.kind, configuration.name,
432 /* preserveSource = */ configuration.signatureChange);
433
434 List<TypeParameterDescriptor> substitutedTypeParameters;
435 TypeSubstitutor substitutor;
436
437 if (configuration.newTypeParameters == null) {
438 List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
439 substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
440 substitutor = DescriptorSubstitutor.substituteTypeParameters(
441 originalTypeParameters, configuration.originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
442 );
443 }
444 else {
445 // They should be already substituted
446 substitutedTypeParameters = configuration.newTypeParameters;
447 substitutor = configuration.originalSubstitutor;
448 }
449
450 KotlinType substitutedReceiverParameterType = null;
451 if (configuration.newExtensionReceiverParameterType != null) {
452 substitutedReceiverParameterType = substitutor.substitute(configuration.newExtensionReceiverParameterType, Variance.IN_VARIANCE);
453 if (substitutedReceiverParameterType == null) {
454 return null;
455 }
456 }
457
458 ReceiverParameterDescriptor substitutedExpectedThis = null;
459 if (dispatchReceiverParameter != null) {
460 // When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
461 // E.g.
462 // class Base { fun foo() }
463 // class Derived : Base
464 // val x: Base
465 // if (x is Derived) {
466 // // `x` shouldn't be marked as smart-cast
467 // // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
468 // x.foo()
469 // }
470 substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
471 if (substitutedExpectedThis == null) {
472 return null;
473 }
474 }
475
476 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
477 substitutedDescriptor, configuration.newValueParameterDescriptors, substitutor
478 );
479 if (substitutedValueParameters == null) {
480 return null;
481 }
482
483 KotlinType substitutedReturnType = substitutor.substitute(configuration.newReturnType, Variance.OUT_VARIANCE);
484 if (substitutedReturnType == null) {
485 return null;
486 }
487
488 substitutedDescriptor.initialize(
489 substitutedReceiverParameterType,
490 substitutedExpectedThis,
491 substitutedTypeParameters,
492 substitutedValueParameters,
493 substitutedReturnType,
494 configuration.newModality,
495 configuration.newVisibility
496 );
497 substitutedDescriptor.setOperator(isOperator);
498 substitutedDescriptor.setInfix(isInfix);
499 substitutedDescriptor.setExternal(isExternal);
500 substitutedDescriptor.setInline(isInline);
501 substitutedDescriptor.setTailrec(isTailrec);
502 substitutedDescriptor.setHasStableParameterNames(hasStableParameterNames);
503 substitutedDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames);
504 substitutedDescriptor.setHidden(configuration.isHiddenToOvercomeSignatureClash);
505
506 if (configuration.signatureChange || getInitialSignatureDescriptor() != null) {
507 FunctionDescriptor initialSignature = (getInitialSignatureDescriptor() != null ? getInitialSignatureDescriptor() : this);
508 FunctionDescriptor initialSignatureSubstituted = initialSignature.substitute(substitutor);
509 substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted);
510 }
511
512 if (configuration.copyOverrides) {
513 for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
514 substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor));
515 }
516 }
517
518 return substitutedDescriptor;
519 }
520
521 @NotNull
522 protected abstract FunctionDescriptorImpl createSubstitutedCopy(
523 @NotNull DeclarationDescriptor newOwner,
524 @Nullable FunctionDescriptor original,
525 @NotNull Kind kind,
526 @Nullable Name newName,
527 boolean preserveSource
528 );
529
530 @NotNull
531 protected SourceElement getSourceToUseForCopy(boolean preserveSource, @Nullable FunctionDescriptor original) {
532 return preserveSource
533 ? (original != null ? original.getSource() : getOriginal().getSource())
534 : SourceElement.NO_SOURCE;
535 }
536
537 @Override
538 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
539 return visitor.visitFunctionDescriptor(this, data);
540 }
541
542 @Nullable
543 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
544 FunctionDescriptor substitutedDescriptor,
545 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
546 @NotNull TypeSubstitutor substitutor
547 ) {
548 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
549 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
550 // TODO : Lazy?
551 KotlinType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
552 KotlinType varargElementType = unsubstitutedValueParameter.getVarargElementType();
553 KotlinType substituteVarargElementType =
554 varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
555 if (substitutedType == null) return null;
556 result.add(
557 new ValueParameterDescriptorImpl(
558 substitutedDescriptor,
559 unsubstitutedValueParameter,
560 unsubstitutedValueParameter.getIndex(),
561 unsubstitutedValueParameter.getAnnotations(),
562 unsubstitutedValueParameter.getName(),
563 substitutedType,
564 unsubstitutedValueParameter.declaresDefaultValue(),
565 unsubstitutedValueParameter.isCrossinline(),
566 unsubstitutedValueParameter.isNoinline(),
567 substituteVarargElementType,
568 SourceElement.NO_SOURCE
569 )
570 );
571 }
572 return result;
573 }
574
575 @Override
576 @Nullable
577 public FunctionDescriptor getInitialSignatureDescriptor() {
578 return initialSignatureDescriptor;
579 }
580
581 public void setInitialSignatureDescriptor(@Nullable FunctionDescriptor initialSignatureDescriptor) {
582 this.initialSignatureDescriptor = initialSignatureDescriptor;
583 }
584 }