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.codegen.state;
018
019 import com.intellij.openapi.util.text.StringUtil;
020 import com.intellij.psi.PsiElement;
021 import kotlin.Pair;
022 import kotlin.Unit;
023 import kotlin.collections.CollectionsKt;
024 import kotlin.jvm.functions.Function2;
025 import kotlin.jvm.functions.Function3;
026 import org.jetbrains.annotations.NotNull;
027 import org.jetbrains.annotations.Nullable;
028 import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment;
029 import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
030 import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
031 import org.jetbrains.kotlin.codegen.*;
032 import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
033 import org.jetbrains.kotlin.codegen.binding.MutableClosure;
034 import org.jetbrains.kotlin.codegen.signature.AsmTypeFactory;
035 import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
036 import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
037 import org.jetbrains.kotlin.descriptors.*;
038 import org.jetbrains.kotlin.fileClasses.FileClasses;
039 import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
040 import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
041 import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
042 import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature;
043 import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo;
044 import org.jetbrains.kotlin.load.java.JvmAbi;
045 import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
046 import org.jetbrains.kotlin.load.java.SpecialBuiltinMembers;
047 import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
048 import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
049 import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment;
050 import org.jetbrains.kotlin.load.kotlin.*;
051 import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider.IncrementalMultifileClassPackageFragment;
052 import org.jetbrains.kotlin.name.ClassId;
053 import org.jetbrains.kotlin.name.FqName;
054 import org.jetbrains.kotlin.name.Name;
055 import org.jetbrains.kotlin.name.SpecialNames;
056 import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
057 import org.jetbrains.kotlin.psi.KtExpression;
058 import org.jetbrains.kotlin.psi.KtFile;
059 import org.jetbrains.kotlin.psi.KtFunctionLiteral;
060 import org.jetbrains.kotlin.psi.KtLambdaExpression;
061 import org.jetbrains.kotlin.resolve.*;
062 import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
063 import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
064 import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
065 import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
066 import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
067 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature;
068 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
069 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
070 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
071 import org.jetbrains.kotlin.serialization.deserialization.DeserializedType;
072 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
073 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor;
074 import org.jetbrains.kotlin.types.*;
075 import org.jetbrains.kotlin.util.OperatorNameConventions;
076 import org.jetbrains.org.objectweb.asm.Type;
077 import org.jetbrains.org.objectweb.asm.commons.Method;
078
079 import java.util.Collection;
080 import java.util.List;
081
082 import static org.jetbrains.kotlin.codegen.AsmUtil.isStaticMethod;
083 import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
084 import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
085 import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
086 import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
087 import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
088 import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER;
089 import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
090 import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*;
091 import static org.jetbrains.org.objectweb.asm.Opcodes.*;
092
093 public class KotlinTypeMapper {
094 private final BindingContext bindingContext;
095 private final ClassBuilderMode classBuilderMode;
096 private final JvmFileClassesProvider fileClassesProvider;
097 private final IncompatibleClassTracker incompatibleClassTracker;
098 private final String moduleName;
099
100 private final TypeMappingConfiguration<Type> typeMappingConfiguration = new TypeMappingConfiguration<Type>() {
101 private final Function2<String, String, String> defaultClassNameFactory
102 = TypeMappingConfiguration.Companion.getDEFAULT_INNER_CLASS_NAME_FACTORY();
103
104 private final Function2<String, String, String> innerClassNameFactory = new Function2<String, String, String>() {
105 @Override
106 public String invoke(String outer, String inner) {
107 if (classBuilderMode == ClassBuilderMode.KAPT3) {
108 return outer + '/' + inner;
109 }
110
111 return defaultClassNameFactory.invoke(outer, inner);
112 }
113 };
114
115 @NotNull
116 @Override
117 public KotlinType commonSupertype(@NotNull Collection<KotlinType> types) {
118 return CommonSupertypes.commonSupertype(types);
119 }
120
121 @NotNull
122 @Override
123 public Function2<String, String, String> getInnerClassNameFactory() {
124 return innerClassNameFactory;
125 }
126
127 @Nullable
128 @Override
129 public Type getPredefinedTypeForClass(@NotNull ClassDescriptor classDescriptor) {
130 return bindingContext.get(ASM_TYPE, classDescriptor);
131 }
132
133 @Override
134 public void processErrorType(@NotNull KotlinType kotlinType, @NotNull ClassDescriptor descriptor) {
135 if (classBuilderMode.generateBodies) {
136 throw new IllegalStateException(generateErrorMessageForErrorType(kotlinType, descriptor));
137 }
138 }
139 };
140
141 public KotlinTypeMapper(
142 @NotNull BindingContext bindingContext,
143 @NotNull ClassBuilderMode classBuilderMode,
144 @NotNull JvmFileClassesProvider fileClassesProvider,
145 @NotNull IncompatibleClassTracker incompatibleClassTracker,
146 @NotNull String moduleName
147 ) {
148 this.bindingContext = bindingContext;
149 this.classBuilderMode = classBuilderMode;
150 this.fileClassesProvider = fileClassesProvider;
151 this.incompatibleClassTracker = incompatibleClassTracker;
152 this.moduleName = moduleName;
153 }
154
155 @NotNull
156 public TypeMappingConfiguration<Type> getTypeMappingConfiguration() {
157 return typeMappingConfiguration;
158 }
159
160 @NotNull
161 public BindingContext getBindingContext() {
162 return bindingContext;
163 }
164
165 @NotNull
166 public Type mapOwner(@NotNull DeclarationDescriptor descriptor) {
167 return mapOwner(descriptor, true);
168 }
169
170 public Type mapImplementationOwner(@NotNull DeclarationDescriptor descriptor) {
171 return mapOwner(descriptor, false);
172 }
173
174 @NotNull
175 private Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean publicFacade) {
176 if (isLocalFunction(descriptor)) {
177 return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
178 }
179
180 DeclarationDescriptor container = descriptor.getContainingDeclaration();
181 if (container instanceof PackageFragmentDescriptor) {
182 String packageMemberOwner = internalNameForPackageMemberOwner((CallableMemberDescriptor) descriptor, publicFacade);
183 return Type.getObjectType(packageMemberOwner);
184 }
185 else if (container instanceof ClassDescriptor) {
186 return mapClass((ClassDescriptor) container);
187 }
188 else {
189 throw new UnsupportedOperationException("Don't know how to map owner for " + descriptor);
190 }
191 }
192
193 @NotNull
194 private String internalNameForPackageMemberOwner(@NotNull CallableMemberDescriptor descriptor, boolean publicFacade) {
195 boolean isAccessor = descriptor instanceof AccessorForCallableDescriptor;
196 if (isAccessor) {
197 descriptor = ((AccessorForCallableDescriptor) descriptor).getCalleeDescriptor();
198 }
199 KtFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
200 if (file != null) {
201 Visibility visibility = descriptor.getVisibility();
202 if (!publicFacade ||
203 isNonConstProperty(descriptor) ||
204 Visibilities.isPrivate(visibility) ||
205 isAccessor/*Cause of KT-9603*/
206 ) {
207 return FileClasses.getFileClassInternalName(fileClassesProvider, file);
208 }
209 else {
210 return FileClasses.getFacadeClassInternalName(fileClassesProvider, file);
211 }
212 }
213
214 CallableMemberDescriptor directMember = getDirectMember(descriptor);
215
216 if (directMember instanceof DeserializedCallableMemberDescriptor) {
217 String facadeFqName = getPackageMemberOwnerInternalName((DeserializedCallableMemberDescriptor) directMember, publicFacade);
218 if (facadeFqName != null) return facadeFqName;
219 }
220
221 throw new RuntimeException("Could not find package member for " + descriptor +
222 " in package fragment " + descriptor.getContainingDeclaration());
223 }
224
225 private static boolean isNonConstProperty(@NotNull CallableMemberDescriptor descriptor) {
226 if (!(descriptor instanceof PropertyDescriptor)) return false;
227 PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
228 return !propertyDescriptor.isConst();
229 }
230
231 public static class ContainingClassesInfo {
232 private final ClassId facadeClassId;
233 private final ClassId implClassId;
234
235 public ContainingClassesInfo(@NotNull ClassId facadeClassId, @NotNull ClassId implClassId) {
236 this.facadeClassId = facadeClassId;
237 this.implClassId = implClassId;
238 }
239
240 @NotNull
241 public ClassId getFacadeClassId() {
242 return facadeClassId;
243 }
244
245 @NotNull
246 public ClassId getImplClassId() {
247 return implClassId;
248 }
249
250 @Nullable
251 private static ContainingClassesInfo forPackageMember(
252 @NotNull FqName packageFqName,
253 @NotNull String facadeClassName,
254 @NotNull String implClassName
255 ) {
256 return new ContainingClassesInfo(ClassId.topLevel(packageFqName.child(Name.identifier(facadeClassName))),
257 ClassId.topLevel(packageFqName.child(Name.identifier(implClassName))));
258 }
259
260 @NotNull
261 private static ContainingClassesInfo forClassMemberOrNull(@NotNull ClassId classId) {
262 return new ContainingClassesInfo(classId, classId);
263 }
264 }
265
266 @NotNull
267 public ContainingClassesInfo getContainingClassesForDeserializedCallable(
268 @NotNull DeserializedCallableMemberDescriptor deserializedDescriptor
269 ) {
270 DeclarationDescriptor parentDeclaration = deserializedDescriptor.getContainingDeclaration();
271 ContainingClassesInfo containingClassesInfo;
272 if (parentDeclaration instanceof PackageFragmentDescriptor) {
273 containingClassesInfo = getPackageMemberContainingClassesInfo(deserializedDescriptor);
274 }
275 else {
276 ClassId classId = getContainerClassIdForClassDescriptor((ClassDescriptor) parentDeclaration);
277 containingClassesInfo = ContainingClassesInfo.forClassMemberOrNull(classId);
278 }
279 if (containingClassesInfo == null) {
280 throw new IllegalStateException("Couldn't find container for " + deserializedDescriptor.getName());
281 }
282 return containingClassesInfo;
283 }
284
285 @NotNull
286 private ClassId getContainerClassIdForClassDescriptor(@NotNull ClassDescriptor classDescriptor) {
287 ClassId classId = DescriptorUtilsKt.getClassId(classDescriptor);
288 if (isInterface(classDescriptor)) {
289 FqName relativeClassName = classId.getRelativeClassName();
290 //TODO test nested trait fun inlining
291 String defaultImplsClassName = typeMappingConfiguration.getInnerClassNameFactory()
292 .invoke(relativeClassName.shortName().asString(), JvmAbi.DEFAULT_IMPLS_CLASS_NAME);
293 classId = new ClassId(classId.getPackageFqName(), Name.identifier(defaultImplsClassName));
294 }
295 return classId;
296 }
297
298 @Nullable
299 private String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor, boolean publicFacade) {
300 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
301 assert containingDeclaration instanceof PackageFragmentDescriptor : "Not a top-level member: " + descriptor;
302
303 ContainingClassesInfo containingClasses = getPackageMemberContainingClassesInfo(descriptor);
304 if (containingClasses == null) {
305 return null;
306 }
307
308 ClassId ownerClassId = publicFacade ? containingClasses.getFacadeClassId()
309 : containingClasses.getImplClassId();
310 return JvmClassName.byClassId(ownerClassId, typeMappingConfiguration).getInternalName();
311 }
312
313 private static final ClassId FAKE_CLASS_ID_FOR_BUILTINS = ClassId.topLevel(new FqName("kotlin.KotlinPackage"));
314
315 @Nullable
316 private static ContainingClassesInfo getPackageMemberContainingClassesInfo(@NotNull DeserializedCallableMemberDescriptor descriptor) {
317 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
318 if (containingDeclaration instanceof BuiltInsPackageFragment) {
319 return new ContainingClassesInfo(FAKE_CLASS_ID_FOR_BUILTINS, FAKE_CLASS_ID_FOR_BUILTINS);
320 }
321
322 Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
323 assert implClassName != null : "No implClassName for " + descriptor;
324 String implSimpleName = implClassName.asString();
325
326 String facadeSimpleName;
327
328 if (containingDeclaration instanceof LazyJavaPackageFragment) {
329 facadeSimpleName = ((LazyJavaPackageFragment) containingDeclaration).getFacadeSimpleNameForPartSimpleName(implSimpleName);
330 if (facadeSimpleName == null) return null;
331 }
332 else if (containingDeclaration instanceof IncrementalMultifileClassPackageFragment) {
333 facadeSimpleName = ((IncrementalMultifileClassPackageFragment) containingDeclaration).getMultifileClassName().asString();
334 }
335 else {
336 throw new AssertionError("Unexpected package fragment for " + descriptor + ": " +
337 containingDeclaration + " (" + containingDeclaration.getClass().getSimpleName() + ")");
338 }
339
340 return ContainingClassesInfo.forPackageMember(
341 ((PackageFragmentDescriptor) containingDeclaration).getFqName(), facadeSimpleName, implSimpleName
342 );
343 }
344
345 @NotNull
346 public Type mapReturnType(@NotNull CallableDescriptor descriptor) {
347 return mapReturnType(descriptor, null);
348 }
349
350 @NotNull
351 private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable JvmSignatureWriter sw) {
352 KotlinType returnType = descriptor.getReturnType();
353 assert returnType != null : "Function has no return type: " + descriptor;
354
355 if (descriptor instanceof ConstructorDescriptor) {
356 return Type.VOID_TYPE;
357 }
358
359 if (TypeSignatureMappingKt.hasVoidReturnType(descriptor)) {
360 if (sw != null) {
361 sw.writeAsmType(Type.VOID_TYPE);
362 }
363 return Type.VOID_TYPE;
364 }
365 else if (descriptor instanceof FunctionDescriptor && forceBoxedReturnType((FunctionDescriptor) descriptor)) {
366 // GENERIC_TYPE is a hack to automatically box the return type
367 //noinspection ConstantConditions
368 return mapType(descriptor.getReturnType(), sw, TypeMappingMode.GENERIC_ARGUMENT);
369 }
370
371 return mapReturnType(descriptor, sw, returnType);
372 }
373
374 @NotNull
375 private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable JvmSignatureWriter sw, @NotNull KotlinType returnType) {
376 boolean isAnnotationMethod = DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration());
377 if (sw == null || sw.skipGenericSignature()) {
378 return mapType(returnType, sw, TypeMappingMode.getModeForReturnTypeNoGeneric(isAnnotationMethod));
379 }
380
381 TypeMappingMode typeMappingModeFromAnnotation =
382 TypeMappingUtil.extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod);
383 if (typeMappingModeFromAnnotation != null) {
384 return mapType(returnType, sw, typeMappingModeFromAnnotation);
385 }
386
387 TypeMappingMode mappingMode = TypeMappingMode.getOptimalModeForReturnType(
388 returnType,
389 /* isAnnotationMethod = */ isAnnotationMethod);
390
391 return mapType(returnType, sw, mappingMode);
392 }
393
394 @NotNull
395 public Type mapSupertype(@NotNull KotlinType jetType, @Nullable JvmSignatureWriter signatureVisitor) {
396 return mapType(jetType, signatureVisitor, TypeMappingMode.SUPER_TYPE);
397 }
398
399 @NotNull
400 public Type mapTypeParameter(@NotNull KotlinType jetType, @Nullable JvmSignatureWriter signatureVisitor) {
401 return mapType(jetType, signatureVisitor, TypeMappingMode.GENERIC_ARGUMENT);
402 }
403
404 @NotNull
405 public Type mapClass(@NotNull ClassifierDescriptor classifier) {
406 return mapType(classifier.getDefaultType(), null, TypeMappingMode.DEFAULT);
407 }
408
409 @NotNull
410 public Type mapType(@NotNull KotlinType jetType) {
411 return mapType(jetType, null, TypeMappingMode.DEFAULT);
412 }
413
414 @NotNull
415 public Type mapType(@NotNull CallableDescriptor descriptor) {
416 //noinspection ConstantConditions
417 return mapType(descriptor.getReturnType());
418 }
419
420 @NotNull
421 public JvmMethodGenericSignature mapAnnotationParameterSignature(@NotNull PropertyDescriptor descriptor) {
422 JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
423 sw.writeReturnType();
424 mapType(descriptor.getType(), sw, TypeMappingMode.VALUE_FOR_ANNOTATION);
425 sw.writeReturnTypeEnd();
426 return sw.makeJvmMethodSignature(descriptor.getName().asString());
427 }
428
429 @NotNull
430 public Type mapType(@NotNull ClassifierDescriptor descriptor) {
431 return mapType(descriptor.getDefaultType());
432 }
433
434 @NotNull
435 public Type mapType(
436 @NotNull KotlinType kotlinType,
437 @Nullable final JvmSignatureWriter signatureVisitor,
438 @NotNull TypeMappingMode mode
439 ) {
440 return TypeSignatureMappingKt.mapType(
441 kotlinType, AsmTypeFactory.INSTANCE, mode, typeMappingConfiguration, signatureVisitor,
442 new Function3<KotlinType, Type, TypeMappingMode, Unit>() {
443 @Override
444 public Unit invoke(KotlinType kotlinType, Type type, TypeMappingMode mode) {
445 writeGenericType(kotlinType, type, signatureVisitor, mode);
446 return Unit.INSTANCE;
447 }
448 });
449 }
450
451 @NotNull
452 public Type mapDefaultImpls(@NotNull ClassDescriptor descriptor) {
453 String defaultImplsClassName = typeMappingConfiguration.getInnerClassNameFactory().invoke(
454 mapType(descriptor).getInternalName(), JvmAbi.DEFAULT_IMPLS_CLASS_NAME);
455 return Type.getObjectType(defaultImplsClassName);
456 }
457
458 @NotNull
459 private static String generateErrorMessageForErrorType(@NotNull KotlinType type, @NotNull DeclarationDescriptor descriptor) {
460 PsiElement declarationElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
461
462 if (declarationElement == null) {
463 String message = "Error type encountered: %s (%s).";
464 if (FlexibleTypesKt.upperIfFlexible(type) instanceof DeserializedType) {
465 message +=
466 " One of the possible reasons may be that this type is not directly accessible from this module. " +
467 "To workaround this error, try adding an explicit dependency on the module or library which contains this type " +
468 "to the classpath";
469 }
470 return String.format(message, type, type.getClass().getSimpleName());
471 }
472
473 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
474 PsiElement parentDeclarationElement =
475 containingDeclaration != null ? DescriptorToSourceUtils.descriptorToDeclaration(containingDeclaration) : null;
476
477 return String.format(
478 "Error type encountered: %s (%s). Descriptor: %s. For declaration %s:%s in %s:%s",
479 type,
480 type.getClass().getSimpleName(),
481 descriptor,
482 declarationElement,
483 declarationElement.getText(),
484 parentDeclarationElement,
485 parentDeclarationElement != null ? parentDeclarationElement.getText() : "null"
486 );
487 }
488
489 private void writeGenericType(
490 @NotNull KotlinType type,
491 @NotNull Type asmType,
492 @Nullable JvmSignatureWriter signatureVisitor,
493 @NotNull TypeMappingMode mode
494 ) {
495 if (signatureVisitor != null) {
496
497 // Nothing mapping rules:
498 // Map<Nothing, Foo> -> Map
499 // Map<Foo, List<Nothing>> -> Map<Foo, List>
500 // In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
501 // In<Nothing, Nothing> -> In
502 // Inv<in Nothing, Foo> -> Inv
503 if (signatureVisitor.skipGenericSignature() || hasNothingInNonContravariantPosition(type) || type.getArguments().isEmpty()) {
504 signatureVisitor.writeAsmType(asmType);
505 return;
506 }
507
508 PossiblyInnerType possiblyInnerType = TypeParameterUtilsKt.buildPossiblyInnerType(type);
509 assert possiblyInnerType != null : "possiblyInnerType with arguments should not be null";
510
511 List<PossiblyInnerType> innerTypesAsList = possiblyInnerType.segments();
512 PossiblyInnerType outermostInnerType = innerTypesAsList.get(0);
513 ClassDescriptor outermostClass = outermostInnerType.getClassDescriptor();
514
515 if (innerTypesAsList.size() == 1) {
516 signatureVisitor.writeClassBegin(asmType);
517 }
518 else {
519 signatureVisitor.writeOuterClassBegin(
520 asmType,
521 mapType(outermostClass.getDefaultType()).getInternalName());
522 }
523
524 writeGenericArguments(
525 signatureVisitor,
526 outermostInnerType.getArguments(), outermostClass.getDeclaredTypeParameters(), mode);
527
528 for (PossiblyInnerType innerPart : innerTypesAsList.subList(1, innerTypesAsList.size())) {
529 ClassDescriptor classDescriptor = innerPart.getClassDescriptor();
530 signatureVisitor.writeInnerClass(getJvmShortName(classDescriptor));
531 writeGenericArguments(
532 signatureVisitor, innerPart.getArguments(),
533 classDescriptor.getDeclaredTypeParameters(), mode);
534 }
535
536 signatureVisitor.writeClassEnd();
537 }
538 }
539
540 @Nullable
541 private static String getJvmShortName(@NotNull ClassDescriptor klass) {
542 ClassId classId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(DescriptorUtils.getFqName(klass));
543 if (classId != null) {
544 return classId.getShortClassName().asString();
545 }
546
547 return SpecialNames.safeIdentifier(klass.getName()).getIdentifier();
548 }
549
550 private void writeGenericArguments(
551 @NotNull JvmSignatureWriter signatureVisitor,
552 @NotNull List<? extends TypeProjection> arguments,
553 @NotNull List<? extends TypeParameterDescriptor> parameters,
554 @NotNull TypeMappingMode mode
555 ) {
556 for (Pair<? extends TypeParameterDescriptor, ? extends TypeProjection> item : CollectionsKt.zip(parameters, arguments)) {
557 TypeParameterDescriptor parameter = item.getFirst();
558 TypeProjection argument = item.getSecond();
559
560 if (
561 argument.isStarProjection() ||
562 // In<Nothing, Foo> == In<*, Foo> -> In<?, Foo>
563 KotlinBuiltIns.isNothing(argument.getType()) && parameter.getVariance() == Variance.IN_VARIANCE
564 ) {
565 signatureVisitor.writeUnboundedWildcard();
566 }
567 else {
568 TypeMappingMode argumentMode = TypeMappingUtil.updateArgumentModeFromAnnotations(mode, argument.getType());
569 Variance projectionKind = getVarianceForWildcard(parameter, argument, argumentMode);
570
571 signatureVisitor.writeTypeArgument(projectionKind);
572
573 mapType(argument.getType(), signatureVisitor,
574 argumentMode.toGenericArgumentMode(
575 TypeMappingUtil.getEffectiveVariance(parameter.getVariance(), argument.getProjectionKind())));
576
577 signatureVisitor.writeTypeArgumentEnd();
578 }
579 }
580 }
581
582 private static boolean hasNothingInNonContravariantPosition(KotlinType kotlinType) {
583 List<TypeParameterDescriptor> parameters = kotlinType.getConstructor().getParameters();
584 List<TypeProjection> arguments = kotlinType.getArguments();
585
586 for (int i = 0; i < arguments.size(); i++) {
587 TypeProjection projection = arguments.get(i);
588
589 if (projection.isStarProjection()) continue;
590
591 KotlinType type = projection.getType();
592
593 if (KotlinBuiltIns.isNullableNothing(type) ||
594 KotlinBuiltIns.isNothing(type) && parameters.get(i).getVariance() != Variance.IN_VARIANCE) return true;
595 }
596
597 return false;
598 }
599
600 @NotNull
601 private static Variance getVarianceForWildcard(
602 @NotNull TypeParameterDescriptor parameter,
603 @NotNull TypeProjection projection,
604 @NotNull TypeMappingMode mode
605 ) {
606 Variance projectionKind = projection.getProjectionKind();
607 Variance parameterVariance = parameter.getVariance();
608
609 if (parameterVariance == Variance.INVARIANT) {
610 return projectionKind;
611 }
612
613 if (mode.getSkipDeclarationSiteWildcards()) {
614 return Variance.INVARIANT;
615 }
616
617 if (projectionKind == Variance.INVARIANT || projectionKind == parameterVariance) {
618 if (mode.getSkipDeclarationSiteWildcardsIfPossible() && !projection.isStarProjection()) {
619 if (parameterVariance == Variance.OUT_VARIANCE && TypeMappingUtil.isMostPreciseCovariantArgument(projection.getType())){
620 return Variance.INVARIANT;
621 }
622
623 if (parameterVariance == Variance.IN_VARIANCE
624 && TypeMappingUtil.isMostPreciseContravariantArgument(projection.getType(), parameter)) {
625 return Variance.INVARIANT;
626 }
627 }
628 return parameterVariance;
629 }
630
631 // In<out X> = In<*>
632 // Out<in X> = Out<*>
633 return Variance.OUT_VARIANCE;
634 }
635
636 //NB: similar platform agnostic code in DescriptorUtils.unwrapFakeOverride
637 private FunctionDescriptor findSuperDeclaration(@NotNull FunctionDescriptor descriptor, boolean isSuperCall) {
638 while (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
639 Collection<? extends FunctionDescriptor> overridden = descriptor.getOverriddenDescriptors();
640 if (overridden.isEmpty()) {
641 throw new IllegalStateException("Fake override should have at least one overridden descriptor: " + descriptor);
642 }
643
644 FunctionDescriptor classCallable = null;
645 for (FunctionDescriptor overriddenFunction : overridden) {
646 if (!isInterface(overriddenFunction.getContainingDeclaration())) {
647 classCallable = overriddenFunction;
648 break;
649 }
650 }
651
652 if (classCallable != null) {
653 //prefer class callable cause of else branch
654 descriptor = classCallable;
655 continue;
656 }
657 else if (isSuperCall && !isInterface(descriptor.getContainingDeclaration())) {
658 //Don't unwrap fake overrides from class to interface cause substituted override would be implicitly generated for target 1.6
659 return descriptor;
660 }
661
662 descriptor = overridden.iterator().next();
663 }
664 return descriptor;
665 }
666
667 @NotNull
668 public CallableMethod mapToCallableMethod(@NotNull FunctionDescriptor descriptor, boolean superCall) {
669 if (descriptor instanceof ConstructorDescriptor) {
670 JvmMethodSignature method = mapSignatureSkipGeneric(descriptor);
671 Type owner = mapClass(((ConstructorDescriptor) descriptor).getContainingDeclaration());
672 String defaultImplDesc = mapDefaultMethod(descriptor, OwnerKind.IMPLEMENTATION).getDescriptor();
673 return new CallableMethod(owner, owner, defaultImplDesc, method, INVOKESPECIAL, null, null, null);
674 }
675
676 DeclarationDescriptor functionParent = descriptor.getOriginal().getContainingDeclaration();
677
678 FunctionDescriptor functionDescriptor = findSuperDeclaration(descriptor.getOriginal(), superCall);
679
680 JvmMethodSignature signature;
681 Type owner;
682 Type ownerForDefaultImpl;
683 FunctionDescriptor baseMethodDescriptor;
684 int invokeOpcode;
685 Type thisClass;
686
687 if (functionParent instanceof ClassDescriptor) {
688 FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor);
689
690 ClassDescriptor currentOwner = (ClassDescriptor) functionParent;
691 ClassDescriptor declarationOwner = (ClassDescriptor) declarationFunctionDescriptor.getContainingDeclaration();
692
693 boolean originalIsInterface = isJvmInterface(declarationOwner);
694 boolean currentIsInterface = isJvmInterface(currentOwner);
695
696 boolean isInterface = currentIsInterface && originalIsInterface;
697
698 baseMethodDescriptor = findBaseDeclaration(functionDescriptor).getOriginal();
699 ClassDescriptor ownerForDefault = (ClassDescriptor) baseMethodDescriptor.getContainingDeclaration();
700 ownerForDefaultImpl = isJvmInterface(ownerForDefault) ? mapDefaultImpls(ownerForDefault) : mapClass(ownerForDefault);
701
702 if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE || isAccessor(descriptor))) {
703 thisClass = mapClass(currentOwner);
704 if (declarationOwner instanceof JavaClassDescriptor) {
705 invokeOpcode = INVOKESPECIAL;
706 signature = mapSignatureSkipGeneric(functionDescriptor);
707 owner = thisClass;
708 }
709 else {
710 invokeOpcode = INVOKESTATIC;
711 signature = mapSignatureSkipGeneric(descriptor.getOriginal(), OwnerKind.DEFAULT_IMPLS);
712 owner = mapDefaultImpls(currentOwner);
713 }
714 }
715 else {
716 boolean isStaticInvocation = (isStaticDeclaration(functionDescriptor) &&
717 !(functionDescriptor instanceof ImportedFromObjectCallableDescriptor)) ||
718 isStaticAccessor(functionDescriptor) ||
719 CodegenUtilKt.isJvmStaticInObjectOrClass(functionDescriptor);
720 if (isStaticInvocation) {
721 invokeOpcode = INVOKESTATIC;
722 }
723 else if (isInterface) {
724 invokeOpcode = INVOKEINTERFACE;
725 }
726 else {
727 boolean isPrivateFunInvocation = Visibilities.isPrivate(functionDescriptor.getVisibility());
728 invokeOpcode = superCall || isPrivateFunInvocation ? INVOKESPECIAL : INVOKEVIRTUAL;
729 }
730
731 FunctionDescriptor overriddenSpecialBuiltinFunction =
732 SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(functionDescriptor.getOriginal());
733 FunctionDescriptor functionToCall = overriddenSpecialBuiltinFunction != null && !superCall
734 ? overriddenSpecialBuiltinFunction.getOriginal()
735 : functionDescriptor.getOriginal();
736
737 signature = mapSignatureSkipGeneric(functionToCall);
738
739 ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor
740 ? declarationOwner
741 : currentOwner;
742 owner = mapClass(receiver);
743 thisClass = owner;
744 }
745 }
746 else {
747 signature = mapSignatureSkipGeneric(functionDescriptor.getOriginal());
748 owner = mapOwner(functionDescriptor);
749 ownerForDefaultImpl = owner;
750 baseMethodDescriptor = functionDescriptor;
751 if (functionParent instanceof PackageFragmentDescriptor) {
752 invokeOpcode = INVOKESTATIC;
753 thisClass = null;
754 }
755 else if (functionDescriptor instanceof ConstructorDescriptor) {
756 invokeOpcode = INVOKESPECIAL;
757 thisClass = null;
758 }
759 else {
760 invokeOpcode = INVOKEVIRTUAL;
761 thisClass = owner;
762 }
763 }
764
765 Type calleeType = isLocalFunction(functionDescriptor) ? owner : null;
766
767 Type receiverParameterType;
768 ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter();
769 if (receiverParameter != null) {
770 receiverParameterType = mapType(receiverParameter.getType());
771 }
772 else {
773 receiverParameterType = null;
774 }
775
776 String defaultImplDesc = mapDefaultMethod(baseMethodDescriptor, getKindForDefaultImplCall(baseMethodDescriptor)).getDescriptor();
777
778 return new CallableMethod(
779 owner, ownerForDefaultImpl, defaultImplDesc, signature, invokeOpcode,
780 thisClass, receiverParameterType, calleeType);
781 }
782
783 public static boolean isAccessor(@NotNull CallableMemberDescriptor descriptor) {
784 return descriptor instanceof AccessorForCallableDescriptor<?>;
785 }
786
787 public static boolean isStaticAccessor(@NotNull CallableMemberDescriptor descriptor) {
788 if (descriptor instanceof AccessorForConstructorDescriptor) return false;
789 return isAccessor(descriptor);
790 }
791
792 @NotNull
793 private static FunctionDescriptor findAnyDeclaration(@NotNull FunctionDescriptor function) {
794 if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
795 return function;
796 }
797 return findBaseDeclaration(function);
798 }
799
800 @NotNull
801 private static FunctionDescriptor findBaseDeclaration(@NotNull FunctionDescriptor function) {
802 if (function.getOverriddenDescriptors().isEmpty()) {
803 return function;
804 }
805 else {
806 // TODO: prefer class to interface
807 return findBaseDeclaration(function.getOverriddenDescriptors().iterator().next());
808 }
809 }
810
811 @NotNull
812 private String mapFunctionName(@NotNull FunctionDescriptor descriptor) {
813 if (!(descriptor instanceof JavaCallableMemberDescriptor)) {
814 String platformName = getJvmName(descriptor);
815 if (platformName != null) return platformName;
816 }
817
818 String nameForSpecialFunction = SpecialBuiltinMembers.getJvmMethodNameIfSpecial(descriptor);
819 if (nameForSpecialFunction != null) return nameForSpecialFunction;
820
821 if (descriptor instanceof PropertyAccessorDescriptor) {
822 PropertyDescriptor property = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
823 if (isAnnotationClass(property.getContainingDeclaration())) {
824 return property.getName().asString();
825 }
826
827 boolean isAccessor = property instanceof AccessorForPropertyDescriptor;
828 String propertyName = isAccessor
829 ? ((AccessorForPropertyDescriptor) property).getAccessorSuffix()
830 : property.getName().asString();
831
832 String accessorName = descriptor instanceof PropertyGetterDescriptor
833 ? JvmAbi.getterName(propertyName)
834 : JvmAbi.setterName(propertyName);
835
836 return mangleMemberNameIfRequired(isAccessor ? "access$" + accessorName : accessorName, descriptor);
837 }
838 else if (isFunctionLiteral(descriptor)) {
839 PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor);
840 if (element instanceof KtFunctionLiteral) {
841 PsiElement expression = element.getParent();
842 if (expression instanceof KtLambdaExpression) {
843 SamType samType = bindingContext.get(SAM_VALUE, (KtExpression) expression);
844 if (samType != null) {
845 return samType.getAbstractMethod().getName().asString();
846 }
847 }
848 }
849
850 return OperatorNameConventions.INVOKE.asString();
851 }
852 else if (isLocalFunction(descriptor) || isFunctionExpression(descriptor)) {
853 return OperatorNameConventions.INVOKE.asString();
854 }
855 else {
856 return mangleMemberNameIfRequired(descriptor.getName().asString(), descriptor);
857 }
858 }
859
860 @NotNull
861 private static OwnerKind getKindForDefaultImplCall(@NotNull FunctionDescriptor baseMethodDescriptor) {
862 DeclarationDescriptor containingDeclaration = baseMethodDescriptor.getContainingDeclaration();
863 if (containingDeclaration instanceof PackageFragmentDescriptor) {
864 return OwnerKind.PACKAGE;
865 }
866 else if (isInterface(containingDeclaration)) {
867 return OwnerKind.DEFAULT_IMPLS;
868 }
869 return OwnerKind.IMPLEMENTATION;
870 }
871
872 @NotNull
873 public static String mapDefaultFieldName(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegated) {
874 String name;
875 if (propertyDescriptor instanceof AccessorForPropertyDescriptor) {
876 name = ((AccessorForPropertyDescriptor) propertyDescriptor).getCalleeDescriptor().getName().asString();
877 }
878 else {
879 name = propertyDescriptor.getName().asString();
880 }
881 return isDelegated ? name + JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX : name;
882 }
883
884 @NotNull
885 private String mangleMemberNameIfRequired(@NotNull String name, @NotNull CallableMemberDescriptor descriptor) {
886 if (descriptor.getContainingDeclaration() instanceof ScriptDescriptor) {
887 //script properties should be public
888 return name;
889 }
890
891 if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
892 if (Visibilities.isPrivate(descriptor.getVisibility()) && !(descriptor instanceof ConstructorDescriptor) && !"<clinit>".equals(name)) {
893 String partName = getPartSimpleNameForMangling(descriptor);
894 if (partName != null) return name + "$" + partName;
895 }
896 return name;
897 }
898
899 if (!(descriptor instanceof ConstructorDescriptor) && descriptor.getVisibility() == Visibilities.INTERNAL) {
900 return name + "$" + JvmAbi.sanitizeAsJavaIdentifier(moduleName);
901 }
902
903 return name;
904 }
905
906 @Nullable
907 private String getPartSimpleNameForMangling(@NotNull CallableMemberDescriptor descriptor) {
908 KtFile containingFile = DescriptorToSourceUtils.getContainingFile(descriptor);
909 if (containingFile != null) {
910 JvmFileClassInfo fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile);
911 if (fileClassInfo.getWithJvmMultifileClass()) {
912 return fileClassInfo.getFileClassFqName().shortName().asString();
913 }
914 return null;
915 }
916
917 descriptor = getDirectMember(descriptor);
918 assert descriptor instanceof DeserializedCallableMemberDescriptor :
919 "Descriptor without sources should be instance of DeserializedCallableMemberDescriptor, but: " +
920 descriptor;
921 ContainingClassesInfo containingClassesInfo =
922 getContainingClassesForDeserializedCallable((DeserializedCallableMemberDescriptor) descriptor);
923 String facadeShortName = containingClassesInfo.getFacadeClassId().getShortClassName().asString();
924 String implShortName = containingClassesInfo.getImplClassId().getShortClassName().asString();
925 return !facadeShortName.equals(implShortName) ? implShortName : null;
926 }
927
928 @NotNull
929 public Method mapAsmMethod(@NotNull FunctionDescriptor descriptor) {
930 return mapSignature(descriptor, true).getAsmMethod();
931 }
932
933 @NotNull
934 public Method mapAsmMethod(@NotNull FunctionDescriptor descriptor, @NotNull OwnerKind kind) {
935 return mapSignature(descriptor, kind, true).getAsmMethod();
936 }
937
938 @NotNull
939 private JvmMethodGenericSignature mapSignature(@NotNull FunctionDescriptor f, boolean skipGenericSignature) {
940 return mapSignature(f, OwnerKind.IMPLEMENTATION, skipGenericSignature);
941 }
942
943 @NotNull
944 public JvmMethodSignature mapSignatureSkipGeneric(@NotNull FunctionDescriptor f) {
945 return mapSignatureSkipGeneric(f, OwnerKind.IMPLEMENTATION);
946 }
947
948 @NotNull
949 public JvmMethodSignature mapSignatureSkipGeneric(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
950 return mapSignature(f, kind, true);
951 }
952
953 @NotNull
954 public JvmMethodGenericSignature mapSignatureWithGeneric(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
955 return mapSignature(f, kind, false);
956 }
957
958 @NotNull
959 private JvmMethodGenericSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind, boolean skipGenericSignature) {
960 if (f.getInitialSignatureDescriptor() != null && f != f.getInitialSignatureDescriptor()) {
961 // Overrides of special builtin in Kotlin classes always have special signature
962 if (SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(f) == null ||
963 f.getContainingDeclaration().getOriginal() instanceof JavaClassDescriptor) {
964 return mapSignature(f.getInitialSignatureDescriptor(), kind, skipGenericSignature);
965 }
966 }
967
968 if (f instanceof ConstructorDescriptor) {
969 return mapSignature(f, kind, f.getOriginal().getValueParameters(), skipGenericSignature);
970 }
971
972 return mapSignature(f, kind, f.getValueParameters(), skipGenericSignature);
973 }
974
975 @NotNull
976 public JvmMethodGenericSignature mapSignature(
977 @NotNull FunctionDescriptor f,
978 @NotNull OwnerKind kind,
979 @NotNull List<ValueParameterDescriptor> valueParameters,
980 boolean skipGenericSignature
981 ) {
982 if (f instanceof FunctionImportedFromObject) {
983 return mapSignature(((FunctionImportedFromObject) f).getCallableFromObject(), kind, skipGenericSignature);
984 }
985
986 checkOwnerCompatibility(f);
987
988 JvmSignatureWriter sw = skipGenericSignature || f instanceof AccessorForCallableDescriptor
989 ? new JvmSignatureWriter()
990 : new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
991
992 if (f instanceof ConstructorDescriptor) {
993 sw.writeParametersStart();
994 writeAdditionalConstructorParameters((ConstructorDescriptor) f, sw);
995
996 for (ValueParameterDescriptor parameter : valueParameters) {
997 writeParameter(sw, parameter.getType(), f);
998 }
999
1000 if (f instanceof AccessorForConstructorDescriptor) {
1001 writeParameter(sw, JvmMethodParameterKind.CONSTRUCTOR_MARKER, DEFAULT_CONSTRUCTOR_MARKER);
1002 }
1003
1004 writeVoidReturn(sw);
1005 }
1006 else {
1007 CallableMemberDescriptor directMember = getDirectMember(f);
1008 KotlinType thisIfNeeded = null;
1009 if (OwnerKind.DEFAULT_IMPLS == kind) {
1010 ReceiverTypeAndTypeParameters receiverTypeAndTypeParameters = TypeMapperUtilsKt.patchTypeParametersForDefaultImplMethod(directMember);
1011 writeFormalTypeParameters(CollectionsKt.plus(receiverTypeAndTypeParameters.getTypeParameters(), directMember.getTypeParameters()), sw);
1012 thisIfNeeded = receiverTypeAndTypeParameters.getReceiverType();
1013 }
1014 else {
1015 writeFormalTypeParameters(directMember.getTypeParameters(), sw);
1016 if (isAccessor(f) && f.getDispatchReceiverParameter() != null) {
1017 thisIfNeeded = ((ClassDescriptor) f.getContainingDeclaration()).getDefaultType();
1018 }
1019 }
1020
1021 sw.writeParametersStart();
1022 if (thisIfNeeded != null) {
1023 writeParameter(sw, JvmMethodParameterKind.THIS, thisIfNeeded, f);
1024 }
1025
1026 ReceiverParameterDescriptor receiverParameter = f.getExtensionReceiverParameter();
1027 if (receiverParameter != null) {
1028 writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.getType(), f);
1029 }
1030
1031 for (ValueParameterDescriptor parameter : valueParameters) {
1032 boolean forceBoxing = MethodSignatureMappingKt.forceSingleValueParameterBoxing(f);
1033 writeParameter(
1034 sw,
1035 forceBoxing ? TypeUtils.makeNullable(parameter.getType()) : parameter.getType(),
1036 f
1037 );
1038 }
1039
1040 sw.writeReturnType();
1041 mapReturnType(f, sw);
1042 sw.writeReturnTypeEnd();
1043 }
1044
1045 JvmMethodGenericSignature signature = sw.makeJvmMethodSignature(mapFunctionName(f));
1046
1047 if (kind != OwnerKind.DEFAULT_IMPLS) {
1048 SpecialSignatureInfo specialSignatureInfo = BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo(f);
1049
1050 if (specialSignatureInfo != null) {
1051 String newGenericSignature = CodegenUtilKt.replaceValueParametersIn(
1052 specialSignatureInfo, signature.getGenericsSignature());
1053 return new JvmMethodGenericSignature(signature.getAsmMethod(), signature.getValueParameters(), newGenericSignature);
1054 }
1055 }
1056
1057 return signature;
1058 }
1059
1060 private void checkOwnerCompatibility(@NotNull FunctionDescriptor descriptor) {
1061 if (!(descriptor instanceof DeserializedCallableMemberDescriptor)) return;
1062
1063 KotlinJvmBinaryClass ownerClass = null;
1064
1065 DeclarationDescriptor container = descriptor.getContainingDeclaration();
1066 if (container instanceof DeserializedClassDescriptor) {
1067 SourceElement source = ((DeserializedClassDescriptor) container).getSource();
1068 if (source instanceof KotlinJvmBinarySourceElement) {
1069 ownerClass = ((KotlinJvmBinarySourceElement) source).getBinaryClass();
1070 }
1071 }
1072 else if (container instanceof LazyJavaPackageFragment) {
1073 SourceElement source = ((LazyJavaPackageFragment) container).getSource();
1074 if (source instanceof KotlinJvmBinaryPackageSourceElement) {
1075 ownerClass = ((KotlinJvmBinaryPackageSourceElement) source).getRepresentativeBinaryClass();
1076 }
1077 }
1078
1079 if (ownerClass != null) {
1080 JvmBytecodeBinaryVersion version = ownerClass.getClassHeader().getBytecodeVersion();
1081 if (!version.isCompatible()) {
1082 incompatibleClassTracker.record(ownerClass);
1083 }
1084 }
1085 }
1086
1087 @NotNull
1088 private static String getDefaultDescriptor(@NotNull Method method, @Nullable String dispatchReceiverDescriptor, boolean isExtension) {
1089 String descriptor = method.getDescriptor();
1090 int argumentsCount = Type.getArgumentTypes(descriptor).length;
1091 if (isExtension) {
1092 argumentsCount--;
1093 }
1094 int maskArgumentsCount = (argumentsCount + Integer.SIZE - 1) / Integer.SIZE;
1095 String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount);
1096 additionalArgs += (isConstructor(method) ? DEFAULT_CONSTRUCTOR_MARKER : OBJECT_TYPE).getDescriptor();
1097 String result = descriptor.replace(")", additionalArgs + ")");
1098 if (dispatchReceiverDescriptor != null && !isConstructor(method)) {
1099 return result.replace("(", "(" + dispatchReceiverDescriptor);
1100 }
1101 return result;
1102 }
1103
1104 public ClassBuilderMode getClassBuilderMode() {
1105 return classBuilderMode;
1106 }
1107
1108 private static boolean isConstructor(@NotNull Method method) {
1109 return "<init>".equals(method.getName());
1110 }
1111
1112 @NotNull
1113 public Method mapDefaultMethod(@NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind kind) {
1114 Method jvmSignature = mapAsmMethod(functionDescriptor, kind);
1115 Type ownerType = mapOwner(functionDescriptor);
1116 boolean isConstructor = isConstructor(jvmSignature);
1117 String descriptor = getDefaultDescriptor(
1118 jvmSignature,
1119 isStaticMethod(kind, functionDescriptor) || isConstructor ? null : ownerType.getDescriptor(),
1120 functionDescriptor.getExtensionReceiverParameter() != null
1121 );
1122
1123 return new Method(isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor);
1124 }
1125
1126 /**
1127 * @return true iff a given function descriptor should be compiled to a method with boxed return type regardless of whether return type
1128 * of that descriptor is nullable or not. This happens when a function returning a value of a primitive type overrides another function
1129 * with a non-primitive return type. In that case the generated method's return type should be boxed: otherwise it's not possible to use
1130 * this class from Java since javac issues errors when loading the class (incompatible return types)
1131 */
1132 private static boolean forceBoxedReturnType(@NotNull FunctionDescriptor descriptor) {
1133 //noinspection ConstantConditions
1134 if (!KotlinBuiltIns.isPrimitiveType(descriptor.getReturnType())) return false;
1135
1136 for (FunctionDescriptor overridden : getAllOverriddenDescriptors(descriptor)) {
1137 //noinspection ConstantConditions
1138 if (!KotlinBuiltIns.isPrimitiveType(overridden.getReturnType())) return true;
1139 }
1140
1141 return false;
1142 }
1143
1144 private static void writeVoidReturn(@NotNull JvmSignatureWriter sw) {
1145 sw.writeReturnType();
1146 sw.writeAsmType(Type.VOID_TYPE);
1147 sw.writeReturnTypeEnd();
1148 }
1149
1150 @Nullable
1151 public String mapFieldSignature(@NotNull KotlinType backingFieldType, @NotNull PropertyDescriptor propertyDescriptor) {
1152 JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
1153
1154 if (!propertyDescriptor.isVar()) {
1155 mapReturnType(propertyDescriptor, sw, backingFieldType);
1156 }
1157 else {
1158 writeParameterType(sw, backingFieldType, propertyDescriptor);
1159 }
1160
1161 return sw.makeJavaGenericSignature();
1162 }
1163
1164 public void writeFormalTypeParameters(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull JvmSignatureWriter sw) {
1165 if (sw.skipGenericSignature()) return;
1166 for (TypeParameterDescriptor typeParameter : typeParameters) {
1167 writeFormalTypeParameter(typeParameter, sw);
1168 }
1169 }
1170
1171 private void writeFormalTypeParameter(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull JvmSignatureWriter sw) {
1172 if (!classBuilderMode.generateBodies && typeParameterDescriptor.getName().isSpecial()) {
1173 // If a type parameter has no name, the code below fails, but it should recover in case of light classes
1174 return;
1175 }
1176
1177 sw.writeFormalTypeParameter(typeParameterDescriptor.getName().asString());
1178
1179 classBound:
1180 {
1181 sw.writeClassBound();
1182
1183 for (KotlinType jetType : typeParameterDescriptor.getUpperBounds()) {
1184 if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
1185 if (!isJvmInterface(jetType)) {
1186 mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
1187 break classBound;
1188 }
1189 }
1190 }
1191
1192 // "extends Object" is optional according to ClassFileFormat-Java5.pdf
1193 // but javac complaints to signature:
1194 // <P:>Ljava/lang/Object;
1195 // TODO: avoid writing java/lang/Object if interface list is not empty
1196 }
1197 sw.writeClassBoundEnd();
1198
1199 for (KotlinType jetType : typeParameterDescriptor.getUpperBounds()) {
1200 ClassifierDescriptor classifier = jetType.getConstructor().getDeclarationDescriptor();
1201 if (classifier instanceof ClassDescriptor) {
1202 if (isJvmInterface(jetType)) {
1203 sw.writeInterfaceBound();
1204 mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
1205 sw.writeInterfaceBoundEnd();
1206 }
1207 }
1208 else if (classifier instanceof TypeParameterDescriptor) {
1209 sw.writeInterfaceBound();
1210 mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
1211 sw.writeInterfaceBoundEnd();
1212 }
1213 else {
1214 throw new UnsupportedOperationException("Unknown classifier: " + classifier);
1215 }
1216 }
1217 }
1218
1219 private void writeParameter(
1220 @NotNull JvmSignatureWriter sw,
1221 @NotNull KotlinType type,
1222 @Nullable CallableDescriptor callableDescriptor
1223 ) {
1224 writeParameter(sw, JvmMethodParameterKind.VALUE, type, callableDescriptor);
1225 }
1226
1227 private void writeParameter(
1228 @NotNull JvmSignatureWriter sw,
1229 @NotNull JvmMethodParameterKind kind,
1230 @NotNull KotlinType type,
1231 @Nullable CallableDescriptor callableDescriptor
1232 ) {
1233 sw.writeParameterType(kind);
1234
1235 writeParameterType(sw, type, callableDescriptor);
1236
1237 sw.writeParameterTypeEnd();
1238 }
1239
1240 private void writeParameterType(
1241 @NotNull JvmSignatureWriter sw,
1242 @NotNull KotlinType type,
1243 @Nullable CallableDescriptor callableDescriptor
1244 ) {
1245 if (sw.skipGenericSignature()) {
1246 mapType(type, sw, TypeMappingMode.DEFAULT);
1247 return;
1248 }
1249
1250 TypeMappingMode typeMappingMode;
1251
1252 TypeMappingMode typeMappingModeFromAnnotation =
1253 TypeMappingUtil.extractTypeMappingModeFromAnnotation(callableDescriptor, type, /* isForAnnotationParameter = */ false);
1254
1255 if (typeMappingModeFromAnnotation != null) {
1256 typeMappingMode = typeMappingModeFromAnnotation;
1257 }
1258 else if (TypeMappingUtil.isMethodWithDeclarationSiteWildcards(callableDescriptor) && !type.getArguments().isEmpty()) {
1259 typeMappingMode = TypeMappingMode.GENERIC_ARGUMENT; // Render all wildcards
1260 }
1261 else {
1262 typeMappingMode = TypeMappingMode.getOptimalModeForValueParameter(type);
1263 }
1264
1265 mapType(type, sw, typeMappingMode);
1266 }
1267
1268 private static void writeParameter(@NotNull JvmSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull Type type) {
1269 sw.writeParameterType(kind);
1270 sw.writeAsmType(type);
1271 sw.writeParameterTypeEnd();
1272 }
1273
1274 private void writeAdditionalConstructorParameters(@NotNull ConstructorDescriptor descriptor, @NotNull JvmSignatureWriter sw) {
1275 MutableClosure closure = bindingContext.get(CodegenBinding.CLOSURE, descriptor.getContainingDeclaration());
1276
1277 ClassDescriptor captureThis = getDispatchReceiverParameterForConstructorCall(descriptor, closure);
1278 if (captureThis != null) {
1279 writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType(), descriptor);
1280 }
1281
1282 KotlinType captureReceiverType = closure != null ? closure.getCaptureReceiverType() : null;
1283 if (captureReceiverType != null) {
1284 writeParameter(sw, JvmMethodParameterKind.RECEIVER, captureReceiverType, descriptor);
1285 }
1286
1287 ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
1288 if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) {
1289 writeParameter(
1290 sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType(), descriptor);
1291 writeParameter(
1292 sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getIntType(), descriptor);
1293 }
1294
1295 if (closure == null) return;
1296
1297 for (DeclarationDescriptor variableDescriptor : closure.getCaptureVariables().keySet()) {
1298 Type type;
1299 if (variableDescriptor instanceof VariableDescriptor && !(variableDescriptor instanceof PropertyDescriptor)) {
1300 Type sharedVarType = getSharedVarType(variableDescriptor);
1301 if (sharedVarType == null) {
1302 sharedVarType = mapType(((VariableDescriptor) variableDescriptor).getType());
1303 }
1304 type = sharedVarType;
1305 }
1306 else if (isLocalFunction(variableDescriptor)) {
1307 //noinspection CastConflictsWithInstanceof
1308 type = asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) variableDescriptor);
1309 }
1310 else {
1311 type = null;
1312 }
1313
1314 if (type != null) {
1315 closure.setCapturedParameterOffsetInConstructor(variableDescriptor, sw.getCurrentSignatureSize() + 1);
1316 writeParameter(sw, JvmMethodParameterKind.CAPTURED_LOCAL_VARIABLE, type);
1317 }
1318 }
1319
1320 // We may generate a slightly wrong signature for a local class / anonymous object in light classes mode but we don't care,
1321 // because such classes are not accessible from the outside world
1322 if (classBuilderMode.generateBodies) {
1323 ResolvedCall<ConstructorDescriptor> superCall = findFirstDelegatingSuperCall(descriptor);
1324 if (superCall == null) return;
1325 writeSuperConstructorCallParameters(sw, descriptor, superCall, captureThis != null);
1326 }
1327 }
1328
1329 private void writeSuperConstructorCallParameters(
1330 @NotNull JvmSignatureWriter sw,
1331 @NotNull ConstructorDescriptor descriptor,
1332 @NotNull ResolvedCall<ConstructorDescriptor> superCall,
1333 boolean hasOuter
1334 ) {
1335 ConstructorDescriptor superDescriptor = SamCodegenUtil.resolveSamAdapter(superCall.getResultingDescriptor());
1336 List<ResolvedValueArgument> valueArguments = superCall.getValueArgumentsByIndex();
1337 assert valueArguments != null : "Failed to arrange value arguments by index: " + superDescriptor;
1338
1339 List<JvmMethodParameterSignature> parameters = mapSignatureSkipGeneric(superDescriptor).getValueParameters();
1340
1341 int params = parameters.size();
1342 int args = valueArguments.size();
1343
1344 // Mapped parameters should consist of captured values plus all of valueArguments
1345 assert params >= args :
1346 String.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s", params, args, descriptor);
1347
1348 // Include all captured values, i.e. those parameters for which there are no resolved value arguments
1349 for (int i = 0; i < params - args; i++) {
1350 JvmMethodParameterSignature parameter = parameters.get(i);
1351 JvmMethodParameterKind kind = parameter.getKind();
1352 if (kind == JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL) continue;
1353 if (hasOuter && kind == JvmMethodParameterKind.OUTER) continue;
1354
1355 writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
1356 }
1357
1358 if (isAnonymousObject(descriptor.getContainingDeclaration())) {
1359 // For anonymous objects, also add all real non-default value arguments passed to the super constructor
1360 for (int i = 0; i < args; i++) {
1361 ResolvedValueArgument valueArgument = valueArguments.get(i);
1362 JvmMethodParameterSignature parameter = parameters.get(params - args + i);
1363 if (!(valueArgument instanceof DefaultValueArgument)) {
1364 writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
1365 }
1366 }
1367 }
1368 }
1369
1370 @Nullable
1371 private ResolvedCall<ConstructorDescriptor> findFirstDelegatingSuperCall(@NotNull ConstructorDescriptor descriptor) {
1372 ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
1373 while (true) {
1374 ResolvedCall<ConstructorDescriptor> next = getDelegationConstructorCall(bindingContext, descriptor);
1375 if (next == null) return null;
1376 descriptor = next.getResultingDescriptor();
1377 if (descriptor.getContainingDeclaration() != classDescriptor) return next;
1378 }
1379 }
1380
1381 @NotNull
1382 public JvmMethodSignature mapScriptSignature(@NotNull ScriptDescriptor script, @NotNull List<ScriptDescriptor> importedScripts) {
1383 JvmSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
1384
1385 sw.writeParametersStart();
1386
1387 for (ScriptDescriptor importedScript : importedScripts) {
1388 writeParameter(sw, importedScript.getDefaultType(), /* callableDescriptor = */ null);
1389 }
1390
1391 for (ValueParameterDescriptor valueParameter : script.getUnsubstitutedPrimaryConstructor().getValueParameters()) {
1392 writeParameter(sw, valueParameter.getType(), /* callableDescriptor = */ null);
1393 }
1394
1395 writeVoidReturn(sw);
1396
1397 return sw.makeJvmMethodSignature("<init>");
1398 }
1399
1400 public Type getSharedVarType(DeclarationDescriptor descriptor) {
1401 if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
1402 return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
1403 }
1404 else if (descriptor instanceof PropertyDescriptor || descriptor instanceof FunctionDescriptor) {
1405 ReceiverParameterDescriptor receiverParameter = ((CallableDescriptor) descriptor).getExtensionReceiverParameter();
1406 assert receiverParameter != null : "Callable should have a receiver parameter: " + descriptor;
1407 return StackValue.sharedTypeForType(mapType(receiverParameter.getType()));
1408 }
1409 else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(bindingContext, descriptor)) {
1410 return StackValue.sharedTypeForType(mapType(((VariableDescriptor) descriptor).getType()));
1411 }
1412 return null;
1413 }
1414 }