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 org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment;
024 import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
025 import org.jetbrains.kotlin.builtins.PrimitiveType;
026 import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
027 import org.jetbrains.kotlin.codegen.*;
028 import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
029 import org.jetbrains.kotlin.codegen.binding.MutableClosure;
030 import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor;
031 import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
032 import org.jetbrains.kotlin.descriptors.*;
033 import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
034 import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
035 import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
036 import org.jetbrains.kotlin.load.java.JvmAbi;
037 import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
038 import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
039 import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
040 import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
041 import org.jetbrains.kotlin.name.*;
042 import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
043 import org.jetbrains.kotlin.psi.JetExpression;
044 import org.jetbrains.kotlin.psi.JetFile;
045 import org.jetbrains.kotlin.psi.JetFunctionLiteral;
046 import org.jetbrains.kotlin.psi.JetFunctionLiteralExpression;
047 import org.jetbrains.kotlin.resolve.BindingContext;
048 import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
049 import org.jetbrains.kotlin.resolve.DescriptorUtils;
050 import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
051 import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
052 import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
053 import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
054 import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
055 import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
056 import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
057 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
058 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
059 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
060 import org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter;
061 import org.jetbrains.kotlin.resolve.scopes.JetScope;
062 import org.jetbrains.kotlin.serialization.deserialization.DeserializedType;
063 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
064 import org.jetbrains.kotlin.types.*;
065 import org.jetbrains.kotlin.types.expressions.OperatorConventions;
066 import org.jetbrains.org.objectweb.asm.Type;
067 import org.jetbrains.org.objectweb.asm.commons.Method;
068
069 import java.util.ArrayList;
070 import java.util.List;
071
072 import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isUnit;
073 import static org.jetbrains.kotlin.codegen.AsmUtil.*;
074 import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
075 import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
076 import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
077 import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
078 import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
079 import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
080 import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER;
081 import static org.jetbrains.org.objectweb.asm.Opcodes.*;
082
083 public class JetTypeMapper {
084 private final BindingContext bindingContext;
085 private final ClassBuilderMode classBuilderMode;
086 private final JvmFileClassesProvider fileClassesProvider;
087
088 public JetTypeMapper(
089 @NotNull BindingContext bindingContext,
090 @NotNull ClassBuilderMode classBuilderMode,
091 @NotNull JvmFileClassesProvider fileClassesProvider
092 ) {
093 this.bindingContext = bindingContext;
094 this.classBuilderMode = classBuilderMode;
095 this.fileClassesProvider = fileClassesProvider;
096 }
097
098 @NotNull
099 public BindingContext getBindingContext() {
100 return bindingContext;
101 }
102
103 private enum JetTypeMapperMode {
104 /**
105 * foo.Bar is mapped to Lfoo/Bar;
106 */
107 IMPL,
108 /**
109 * kotlin.Int is mapped to I
110 */
111 VALUE,
112 /**
113 * kotlin.Int is mapped to Ljava/lang/Integer;
114 */
115 TYPE_PARAMETER,
116 /**
117 * kotlin.Int is mapped to Ljava/lang/Integer;
118 * No projections allowed in immediate arguments
119 */
120 SUPER_TYPE,
121 /**
122 * kotlin.reflect.KClass mapped to java.lang.Class
123 * Other types mapped as VALUE
124 */
125 VALUE_FOR_ANNOTATION,
126 /**
127 * kotlin.reflect.KClass mapped to java.lang.Class
128 * Other types mapped as TYPE_PARAMETER
129 */
130 TYPE_PARAMETER_FOR_ANNOTATION;
131
132 boolean isForAnnotation() {
133 return this == VALUE_FOR_ANNOTATION || this == TYPE_PARAMETER_FOR_ANNOTATION;
134 }
135 }
136
137 @NotNull
138 public Type mapOwner(@NotNull DeclarationDescriptor descriptor) {
139 if (isLocalFunction(descriptor)) {
140 return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
141 }
142
143 DeclarationDescriptor container = descriptor.getContainingDeclaration();
144 if (container instanceof PackageFragmentDescriptor) {
145 return Type.getObjectType(internalNameForPackage((CallableMemberDescriptor) descriptor));
146 }
147 else if (container instanceof ClassDescriptor) {
148 return mapClass((ClassDescriptor) container);
149 }
150 else if (container instanceof ScriptDescriptor) {
151 return asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) container);
152 }
153 else {
154 throw new UnsupportedOperationException("Don't know how to map owner for " + descriptor);
155 }
156 }
157
158 @NotNull
159 private String internalNameForPackage(@NotNull CallableMemberDescriptor descriptor) {
160 JetFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
161 if (file != null) {
162 Visibility visibility = descriptor.getVisibility();
163 if (descriptor instanceof PropertyDescriptor || Visibilities.isPrivate(visibility)) {
164 return FileClassesPackage.getFileClassInternalName(fileClassesProvider, file);
165 }
166 else {
167 return FileClassesPackage.getFacadeClassInternalName(fileClassesProvider, file);
168 }
169 }
170
171 CallableMemberDescriptor directMember = getDirectMember(descriptor);
172
173 if (directMember instanceof DeserializedCallableMemberDescriptor) {
174 String facadeFqName = getPackageMemberOwnerInternalName((DeserializedCallableMemberDescriptor) directMember);
175 if (facadeFqName != null) return facadeFqName;
176 }
177
178 throw new RuntimeException("Unreachable state");
179 //return PackageClassUtils.getPackageClassInternalName(packageFragment.getFqName());
180 }
181
182 @Nullable
183 private static String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
184 // XXX This method (and getPackageMemberOwnerShortName) is a dirty hack
185 // introduced to make stdlib work with package facades built as multifile facades for M13.
186 // We need some safe, concise way to identify multifile facade and multifile part
187 // from a deserialized package member descriptor.
188 // Possible approaches:
189 // - create a special instance of DeserializedPackageFragmentDescriptor for each facade class (multifile or single-file),
190 // keep related mapping information there;
191 // - provide a proper SourceElement for such descriptors (similar to KotlinJvmBinarySourceElement).
192 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
193 assert containingDeclaration instanceof PackageFragmentDescriptor : "Not a top-level member: " + descriptor;
194 PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
195
196 String facadeShortName = getPackageMemberOwnerShortName(descriptor);
197 if (facadeShortName == null) {
198 return null;
199 }
200
201 FqName facadeFqName = packageFragmentDescriptor.getFqName().child(Name.identifier(facadeShortName));
202 return internalNameByFqNameWithoutInnerClasses(facadeFqName);
203 }
204
205 @Nullable
206 private static String getPackageMemberOwnerShortName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
207 // XXX Dirty hack; see getPackageMemberOwnerInternalName above for more details.
208 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
209 if (containingDeclaration instanceof PackageFragmentDescriptor) {
210 PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
211 JetScope scope = packageFragmentDescriptor.getMemberScope();
212 if (scope instanceof AbstractScopeAdapter) {
213 scope = ((AbstractScopeAdapter) scope).getActualScope();
214 }
215 if (scope instanceof LazyJavaPackageScope) {
216 Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
217 return ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString());
218 }
219 else if (packageFragmentDescriptor instanceof BuiltinsPackageFragment) {
220 return PackageClassUtils.getPackageClassFqName(packageFragmentDescriptor.getFqName()).shortName().asString();
221 }
222 else {
223 // Incremental compilation ends up here. We do not have multifile classes support in incremental so far,
224 // so "use implementation class name" looks like a safe assumption for this case.
225 // However, this should be fixed; see getPackageMemberOwnerInternalName above for more details.
226 Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
227 return implClassName.asString();
228 }
229 }
230 return null;
231 }
232
233 @NotNull
234 public Type mapReturnType(@NotNull CallableDescriptor descriptor) {
235 return mapReturnType(descriptor, null);
236 }
237
238 @NotNull
239 private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable BothSignatureWriter sw) {
240 JetType returnType = descriptor.getReturnType();
241 assert returnType != null : "Function has no return type: " + descriptor;
242
243 if (descriptor instanceof ConstructorDescriptor) {
244 return Type.VOID_TYPE;
245 }
246
247 if (isUnit(returnType) && !TypeUtils.isNullableType(returnType) && !(descriptor instanceof PropertyGetterDescriptor)) {
248 if (sw != null) {
249 sw.writeAsmType(Type.VOID_TYPE);
250 }
251 return Type.VOID_TYPE;
252 }
253 else if (descriptor instanceof FunctionDescriptor && forceBoxedReturnType((FunctionDescriptor) descriptor)) {
254 // TYPE_PARAMETER is a hack to automatically box the return type
255 //noinspection ConstantConditions
256 return mapType(descriptor.getReturnType(), sw, JetTypeMapperMode.TYPE_PARAMETER);
257 }
258 else if (DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration())) {
259 //noinspection ConstantConditions
260 return mapType(descriptor.getReturnType(), sw, JetTypeMapperMode.VALUE_FOR_ANNOTATION);
261 }
262 else {
263 return mapType(returnType, sw, JetTypeMapperMode.VALUE, Variance.OUT_VARIANCE);
264 }
265 }
266
267 @NotNull
268 private Type mapType(@NotNull JetType jetType, @NotNull JetTypeMapperMode mode) {
269 return mapType(jetType, null, mode);
270 }
271
272 @NotNull
273 public Type mapSupertype(@NotNull JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
274 return mapType(jetType, signatureVisitor, JetTypeMapperMode.SUPER_TYPE);
275 }
276
277 @NotNull
278 public Type mapTypeParameter(@NotNull JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
279 return mapType(jetType, signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER);
280 }
281
282 @NotNull
283 public Type mapClass(@NotNull ClassifierDescriptor classifier) {
284 return mapType(classifier.getDefaultType(), null, JetTypeMapperMode.IMPL);
285 }
286
287 @NotNull
288 public Type mapType(@NotNull JetType jetType) {
289 return mapType(jetType, null, JetTypeMapperMode.VALUE);
290 }
291
292 @NotNull
293 public Type mapType(@NotNull CallableDescriptor descriptor) {
294 //noinspection ConstantConditions
295 return mapType(descriptor.getReturnType());
296 }
297
298 @NotNull
299 public JvmMethodSignature mapAnnotationParameterSignature(@NotNull PropertyDescriptor descriptor) {
300 BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
301 sw.writeReturnType();
302 mapType(descriptor.getType(), sw, JetTypeMapperMode.VALUE_FOR_ANNOTATION);
303 sw.writeReturnTypeEnd();
304 return sw.makeJvmMethodSignature(descriptor.getName().asString());
305 }
306
307 @NotNull
308 public Type mapType(@NotNull ClassifierDescriptor descriptor) {
309 return mapType(descriptor.getDefaultType());
310 }
311
312 @NotNull
313 private Type mapType(@NotNull JetType jetType, @Nullable BothSignatureWriter signatureVisitor, @NotNull JetTypeMapperMode mode) {
314 return mapType(jetType, signatureVisitor, mode, Variance.INVARIANT);
315 }
316
317 @NotNull
318 private Type mapType(
319 @NotNull JetType jetType,
320 @Nullable BothSignatureWriter signatureVisitor,
321 @NotNull JetTypeMapperMode kind,
322 @NotNull Variance howThisTypeIsUsed
323 ) {
324 Type known = mapBuiltinType(jetType);
325
326 boolean projectionsAllowed = kind != JetTypeMapperMode.SUPER_TYPE;
327 if (known != null) {
328 if (kind == JetTypeMapperMode.VALUE || kind == JetTypeMapperMode.VALUE_FOR_ANNOTATION) {
329 return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed);
330 }
331 else if (kind == JetTypeMapperMode.TYPE_PARAMETER || kind == JetTypeMapperMode.SUPER_TYPE ||
332 kind == JetTypeMapperMode.TYPE_PARAMETER_FOR_ANNOTATION) {
333 return mapKnownAsmType(jetType, boxType(known), signatureVisitor, howThisTypeIsUsed, projectionsAllowed);
334 }
335 else if (kind == JetTypeMapperMode.IMPL) {
336 // TODO: enable and fix tests
337 //throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType);
338 return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed);
339 }
340 else {
341 throw new IllegalStateException("unknown kind: " + kind);
342 }
343 }
344
345 TypeConstructor constructor = jetType.getConstructor();
346 DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
347 if (constructor instanceof IntersectionTypeConstructor) {
348 jetType = CommonSupertypes.commonSupertype(new ArrayList<JetType>(constructor.getSupertypes()));
349 }
350
351 if (descriptor == null) {
352 throw new UnsupportedOperationException("no descriptor for type constructor of " + jetType);
353 }
354
355 if (ErrorUtils.isError(descriptor)) {
356 if (classBuilderMode != ClassBuilderMode.LIGHT_CLASSES) {
357 throw new IllegalStateException(generateErrorMessageForErrorType(jetType, descriptor));
358 }
359 Type asmType = Type.getObjectType("error/NonExistentClass");
360 if (signatureVisitor != null) {
361 signatureVisitor.writeAsmType(asmType);
362 }
363 return asmType;
364 }
365
366 if (descriptor instanceof ClassDescriptor && KotlinBuiltIns.isArray(jetType)) {
367 if (jetType.getArguments().size() != 1) {
368 throw new UnsupportedOperationException("arrays must have one type argument");
369 }
370 TypeProjection memberProjection = jetType.getArguments().get(0);
371 JetType memberType = memberProjection.getType();
372
373 Type arrayElementType;
374 if (memberProjection.getProjectionKind() == Variance.IN_VARIANCE) {
375 arrayElementType = AsmTypes.OBJECT_TYPE;
376 if (signatureVisitor != null) {
377 signatureVisitor.writeArrayType();
378 signatureVisitor.writeAsmType(arrayElementType);
379 signatureVisitor.writeArrayEnd();
380 }
381 }
382 else {
383 arrayElementType = boxType(mapType(memberType, kind));
384 if (signatureVisitor != null) {
385 signatureVisitor.writeArrayType();
386 JetTypeMapperMode newMode = kind.isForAnnotation() ?
387 JetTypeMapperMode.TYPE_PARAMETER_FOR_ANNOTATION :
388 JetTypeMapperMode.TYPE_PARAMETER;
389 mapType(memberType, signatureVisitor, newMode, memberProjection.getProjectionKind());
390 signatureVisitor.writeArrayEnd();
391 }
392 }
393
394 return Type.getType("[" + arrayElementType.getDescriptor());
395 }
396
397 if (descriptor instanceof ClassDescriptor) {
398 Type asmType = kind.isForAnnotation() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
399 AsmTypes.JAVA_CLASS_TYPE :
400 computeAsmType((ClassDescriptor) descriptor.getOriginal());
401 writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, projectionsAllowed);
402 return asmType;
403 }
404
405 if (descriptor instanceof TypeParameterDescriptor) {
406 TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
407 Type type = mapType(typeParameterDescriptor.getUpperBounds().iterator().next(), kind);
408 if (signatureVisitor != null) {
409 signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), type);
410 }
411 return type;
412 }
413
414 throw new UnsupportedOperationException("Unknown type " + jetType);
415 }
416
417 @Nullable
418 private static Type mapBuiltinType(@NotNull JetType type) {
419 DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
420 if (!(descriptor instanceof ClassDescriptor)) return null;
421
422 FqNameUnsafe fqName = DescriptorUtils.getFqName(descriptor);
423
424 PrimitiveType primitiveType = KotlinBuiltIns.getPrimitiveTypeByFqName(fqName);
425 if (primitiveType != null) {
426 Type asmType = Type.getType(JvmPrimitiveType.get(primitiveType).getDesc());
427 return TypeUtils.isNullableType(type) ? boxType(asmType) : asmType;
428 }
429
430 PrimitiveType arrayElementType = KotlinBuiltIns.getPrimitiveTypeByArrayClassFqName(fqName);
431 if (arrayElementType != null) {
432 return Type.getType("[" + JvmPrimitiveType.get(arrayElementType).getDesc());
433 }
434
435 ClassId classId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqName);
436 if (classId != null) {
437 return Type.getObjectType(JvmClassName.byClassId(classId).getInternalName());
438 }
439
440 return null;
441 }
442
443 @NotNull
444 private Type computeAsmType(@NotNull ClassDescriptor klass) {
445 Type alreadyComputedType = bindingContext.get(ASM_TYPE, klass);
446 if (alreadyComputedType != null) {
447 return alreadyComputedType;
448 }
449
450 Type asmType = Type.getObjectType(computeAsmTypeImpl(klass));
451 assert PsiCodegenPredictor.checkPredictedNameFromPsi(klass, asmType, fileClassesProvider);
452 return asmType;
453 }
454
455 @NotNull
456 private String computeAsmTypeImpl(@NotNull ClassDescriptor klass) {
457 DeclarationDescriptor container = klass.getContainingDeclaration();
458
459 String name = SpecialNames.safeIdentifier(klass.getName()).getIdentifier();
460 if (container instanceof PackageFragmentDescriptor) {
461 FqName fqName = ((PackageFragmentDescriptor) container).getFqName();
462 return fqName.isRoot() ? name : fqName.asString().replace('.', '/') + '/' + name;
463 }
464
465 if (container instanceof ScriptDescriptor) {
466 return asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) container).getInternalName() + "$" + name;
467 }
468
469 assert container instanceof ClassDescriptor : "Unexpected container: " + container + " for " + klass;
470
471 String containerInternalName = computeAsmTypeImpl((ClassDescriptor) container);
472 return klass.getKind() == ClassKind.ENUM_ENTRY ? containerInternalName : containerInternalName + "$" + name;
473 }
474
475 @NotNull
476 public Type mapTraitImpl(@NotNull ClassDescriptor descriptor) {
477 return Type.getObjectType(mapType(descriptor).getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
478 }
479
480 @NotNull
481 private static String generateErrorMessageForErrorType(@NotNull JetType type, @NotNull DeclarationDescriptor descriptor) {
482 PsiElement declarationElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
483
484 if (declarationElement == null) {
485 String message = "Error type encountered: %s (%s).";
486 if (TypesPackage.upperIfFlexible(type) instanceof DeserializedType) {
487 message +=
488 " One of the possible reasons may be that this type is not directly accessible from this module. " +
489 "To workaround this error, try adding an explicit dependency on the module or library which contains this type " +
490 "to the classpath";
491 }
492 return String.format(message, type, type.getClass().getSimpleName());
493 }
494
495 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
496 PsiElement parentDeclarationElement =
497 containingDeclaration != null ? DescriptorToSourceUtils.descriptorToDeclaration(containingDeclaration) : null;
498
499 return String.format(
500 "Error type encountered: %s (%s). Descriptor: %s. For declaration %s:%s in %s:%s",
501 type,
502 type.getClass().getSimpleName(),
503 descriptor,
504 declarationElement,
505 declarationElement.getText(),
506 parentDeclarationElement,
507 parentDeclarationElement != null ? parentDeclarationElement.getText() : "null"
508 );
509 }
510
511 private void writeGenericType(
512 BothSignatureWriter signatureVisitor,
513 Type asmType,
514 JetType jetType,
515 Variance howThisTypeIsUsed,
516 boolean projectionsAllowed
517 ) {
518 if (signatureVisitor != null) {
519 signatureVisitor.writeClassBegin(asmType);
520
521 List<TypeProjection> arguments = jetType.getArguments();
522 for (TypeParameterDescriptor parameter : jetType.getConstructor().getParameters()) {
523 TypeProjection argument = arguments.get(parameter.getIndex());
524
525 if (projectionsAllowed && argument.isStarProjection()) {
526 signatureVisitor.writeUnboundedWildcard();
527 }
528 else {
529 Variance projectionKind = projectionsAllowed
530 ? getEffectiveVariance(
531 parameter.getVariance(),
532 argument.getProjectionKind(),
533 howThisTypeIsUsed
534 )
535 : Variance.INVARIANT;
536 signatureVisitor.writeTypeArgument(projectionKind);
537
538 mapType(argument.getType(), signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER);
539 signatureVisitor.writeTypeArgumentEnd();
540 }
541 }
542 signatureVisitor.writeClassEnd();
543 }
544 }
545
546 private static Variance getEffectiveVariance(Variance parameterVariance, Variance projectionKind, Variance howThisTypeIsUsed) {
547 // Return type must not contain wildcards
548 if (howThisTypeIsUsed == Variance.OUT_VARIANCE) return projectionKind;
549
550 if (parameterVariance == Variance.INVARIANT) {
551 return projectionKind;
552 }
553 if (projectionKind == Variance.INVARIANT) {
554 return parameterVariance;
555 }
556 if (parameterVariance == projectionKind) {
557 return parameterVariance;
558 }
559
560 // In<out X> = In<*>
561 // Out<in X> = Out<*>
562 return Variance.OUT_VARIANCE;
563 }
564
565 private Type mapKnownAsmType(
566 JetType jetType,
567 Type asmType,
568 @Nullable BothSignatureWriter signatureVisitor,
569 @NotNull Variance howThisTypeIsUsed
570 ) {
571 return mapKnownAsmType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, true);
572 }
573
574 private Type mapKnownAsmType(
575 JetType jetType,
576 Type asmType,
577 @Nullable BothSignatureWriter signatureVisitor,
578 @NotNull Variance howThisTypeIsUsed,
579 boolean allowProjections
580 ) {
581 if (signatureVisitor != null) {
582 if (jetType.getArguments().isEmpty()) {
583 signatureVisitor.writeAsmType(asmType);
584 }
585 else {
586 writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, allowProjections);
587 }
588 }
589 return asmType;
590 }
591
592 @NotNull
593 public CallableMethod mapToCallableMethod(@NotNull FunctionDescriptor descriptor, boolean superCall) {
594 if (descriptor instanceof ConstructorDescriptor) {
595 JvmMethodSignature method = mapSignature(descriptor);
596 Type owner = mapClass(((ConstructorDescriptor) descriptor).getContainingDeclaration());
597 return new CallableMethod(owner, owner, owner, method, INVOKESPECIAL, null, null, null);
598 }
599
600 DeclarationDescriptor functionParent = descriptor.getOriginal().getContainingDeclaration();
601
602 FunctionDescriptor functionDescriptor = unwrapFakeOverride(descriptor.getOriginal());
603
604 JvmMethodSignature signature;
605 Type owner;
606 Type ownerForDefaultImpl;
607 Type ownerForDefaultParam;
608 int invokeOpcode;
609 Type thisClass;
610
611 if (functionParent instanceof ClassDescriptor) {
612 FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor);
613
614 ClassDescriptor currentOwner = (ClassDescriptor) functionParent;
615 ClassDescriptor declarationOwner = (ClassDescriptor) declarationFunctionDescriptor.getContainingDeclaration();
616
617 boolean originalIsInterface = isInterface(declarationOwner);
618 boolean currentIsInterface = isInterface(currentOwner);
619
620 boolean isInterface = currentIsInterface && originalIsInterface;
621
622 ClassDescriptor ownerForDefault = (ClassDescriptor) findBaseDeclaration(functionDescriptor).getContainingDeclaration();
623 ownerForDefaultParam = mapClass(ownerForDefault);
624 ownerForDefaultImpl = isInterface(ownerForDefault) ? mapTraitImpl(ownerForDefault) : ownerForDefaultParam;
625
626 if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE)) {
627 thisClass = mapClass(currentOwner);
628 if (declarationOwner instanceof JavaClassDescriptor) {
629 invokeOpcode = INVOKESPECIAL;
630 signature = mapSignature(functionDescriptor);
631 owner = thisClass;
632 }
633 else {
634 invokeOpcode = INVOKESTATIC;
635 signature = mapSignature(descriptor.getOriginal(), OwnerKind.TRAIT_IMPL);
636 owner = mapTraitImpl(currentOwner);
637 }
638 }
639 else {
640 if (isStaticDeclaration(functionDescriptor) ||
641 isStaticAccessor(functionDescriptor) ||
642 AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor)) {
643 invokeOpcode = INVOKESTATIC;
644 }
645 else if (isInterface) {
646 invokeOpcode = INVOKEINTERFACE;
647 }
648 else {
649 boolean isPrivateFunInvocation = Visibilities.isPrivate(functionDescriptor.getVisibility());
650 invokeOpcode = superCall || isPrivateFunInvocation ? INVOKESPECIAL : INVOKEVIRTUAL;
651 }
652
653 signature = mapSignature(functionDescriptor.getOriginal());
654
655 ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor
656 ? declarationOwner
657 : currentOwner;
658 owner = mapClass(receiver);
659 thisClass = owner;
660 }
661 }
662 else {
663 signature = mapSignature(functionDescriptor.getOriginal());
664 owner = mapOwner(functionDescriptor);
665 ownerForDefaultParam = owner;
666 ownerForDefaultImpl = owner;
667 if (functionParent instanceof PackageFragmentDescriptor) {
668 invokeOpcode = INVOKESTATIC;
669 thisClass = null;
670 }
671 else if (functionDescriptor instanceof ConstructorDescriptor) {
672 invokeOpcode = INVOKESPECIAL;
673 thisClass = null;
674 }
675 else {
676 invokeOpcode = INVOKEVIRTUAL;
677 thisClass = owner;
678 }
679 }
680
681 Type calleeType = isLocalFunction(functionDescriptor) ? owner : null;
682
683 Type receiverParameterType;
684 ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter();
685 if (receiverParameter != null) {
686 receiverParameterType = mapType(receiverParameter.getType());
687 }
688 else {
689 receiverParameterType = null;
690 }
691 return new CallableMethod(
692 owner, ownerForDefaultImpl, ownerForDefaultParam, signature, invokeOpcode,
693 thisClass, receiverParameterType, calleeType);
694 }
695
696 public static boolean isAccessor(@NotNull CallableMemberDescriptor descriptor) {
697 return descriptor instanceof AccessorForCallableDescriptor<?>;
698 }
699
700 public static boolean isStaticAccessor(@NotNull CallableMemberDescriptor descriptor) {
701 if (descriptor instanceof AccessorForConstructorDescriptor) return false;
702 return isAccessor(descriptor);
703 }
704
705 @NotNull
706 private static FunctionDescriptor findAnyDeclaration(@NotNull FunctionDescriptor function) {
707 if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
708 return function;
709 }
710 return findBaseDeclaration(function);
711 }
712
713 @NotNull
714 private static FunctionDescriptor findBaseDeclaration(@NotNull FunctionDescriptor function) {
715 if (function.getOverriddenDescriptors().isEmpty()) {
716 return function;
717 }
718 else {
719 // TODO: prefer class to interface
720 return findBaseDeclaration(function.getOverriddenDescriptors().iterator().next());
721 }
722 }
723
724 @NotNull
725 private String mapFunctionName(@NotNull FunctionDescriptor descriptor) {
726 if (!(descriptor instanceof JavaCallableMemberDescriptor)) {
727 String platformName = getJvmName(descriptor);
728 if (platformName != null) return platformName;
729 }
730
731 if (descriptor instanceof PropertyAccessorDescriptor) {
732 PropertyDescriptor property = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
733 if (isAnnotationClass(property.getContainingDeclaration())) {
734 return property.getName().asString();
735 }
736
737 boolean isAccessor = property instanceof AccessorForPropertyDescriptor;
738 String propertyName = isAccessor
739 ? ((AccessorForPropertyDescriptor) property).getIndexedAccessorSuffix()
740 : property.getName().asString();
741
742 String accessorName = descriptor instanceof PropertyGetterDescriptor
743 ? JvmAbi.getterName(propertyName)
744 : JvmAbi.setterName(propertyName);
745
746 return isAccessor ? "access$" + accessorName : accessorName;
747 }
748 else if (isFunctionLiteral(descriptor)) {
749 PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor);
750 if (element instanceof JetFunctionLiteral) {
751 PsiElement expression = element.getParent();
752 if (expression instanceof JetFunctionLiteralExpression) {
753 SamType samType = bindingContext.get(SAM_VALUE, (JetExpression) expression);
754 if (samType != null) {
755 return samType.getAbstractMethod().getName().asString();
756 }
757 }
758 }
759
760 return OperatorConventions.INVOKE.asString();
761 }
762 else if (isLocalFunction(descriptor) || isFunctionExpression(descriptor)) {
763 return OperatorConventions.INVOKE.asString();
764 }
765 else {
766 return descriptor.getName().asString();
767 }
768 }
769
770 @NotNull
771 public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor descriptor) {
772 return mapSignature(descriptor, OwnerKind.IMPLEMENTATION);
773 }
774
775 @NotNull
776 public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
777 if (f instanceof ConstructorDescriptor) {
778 return mapSignature(f, kind, f.getOriginal().getValueParameters());
779 }
780 return mapSignature(f, kind, f.getValueParameters());
781 }
782
783 @NotNull
784 public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind,
785 List<ValueParameterDescriptor> valueParameters) {
786 BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
787
788 if (f instanceof ConstructorDescriptor) {
789 sw.writeParametersStart();
790 writeAdditionalConstructorParameters((ConstructorDescriptor) f, sw);
791
792 for (ValueParameterDescriptor parameter : valueParameters) {
793 writeParameter(sw, parameter.getType());
794 }
795
796 if (f instanceof AccessorForConstructorDescriptor) {
797 writeParameter(sw, JvmMethodParameterKind.CONSTRUCTOR_MARKER, DEFAULT_CONSTRUCTOR_MARKER);
798 }
799
800 writeVoidReturn(sw);
801 }
802 else {
803 writeFormalTypeParameters(getDirectMember(f).getTypeParameters(), sw);
804
805 sw.writeParametersStart();
806 writeThisIfNeeded(f, kind, sw);
807
808 ReceiverParameterDescriptor receiverParameter = f.getExtensionReceiverParameter();
809 if (receiverParameter != null) {
810 writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.getType());
811 }
812
813 for (ValueParameterDescriptor parameter : valueParameters) {
814 writeParameter(sw, parameter.getType());
815 }
816
817 sw.writeReturnType();
818 mapReturnType(f, sw);
819 sw.writeReturnTypeEnd();
820 }
821
822 return sw.makeJvmMethodSignature(mapFunctionName(f));
823 }
824
825 @NotNull
826 public static String getDefaultDescriptor(@NotNull Method method, @Nullable String dispatchReceiverDescriptor, boolean isExtension) {
827 String descriptor = method.getDescriptor();
828 int argumentsCount = Type.getArgumentTypes(descriptor).length;
829 if (isExtension) {
830 argumentsCount--;
831 }
832 int maskArgumentsCount = (argumentsCount + Integer.SIZE - 1) / Integer.SIZE;
833 String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount);
834 if (isConstructor(method)) {
835 additionalArgs += DEFAULT_CONSTRUCTOR_MARKER.getDescriptor();
836 }
837 String result = descriptor.replace(")", additionalArgs + ")");
838 if (dispatchReceiverDescriptor != null && !isConstructor(method)) {
839 return result.replace("(", "(" + dispatchReceiverDescriptor);
840 }
841 return result;
842 }
843
844 public ClassBuilderMode getClassBuilderMode() {
845 return classBuilderMode;
846 }
847
848 private static boolean isConstructor(@NotNull Method method) {
849 return "<init>".equals(method.getName());
850 }
851
852 @NotNull
853 public Method mapDefaultMethod(@NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind kind) {
854 Method jvmSignature = mapSignature(functionDescriptor, kind).getAsmMethod();
855 Type ownerType = mapOwner(functionDescriptor);
856 boolean isConstructor = isConstructor(jvmSignature);
857 String descriptor = getDefaultDescriptor(
858 jvmSignature,
859 isStaticMethod(kind, functionDescriptor) || isConstructor ? null : ownerType.getDescriptor(),
860 functionDescriptor.getExtensionReceiverParameter() != null
861 );
862
863 return new Method(isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor);
864 }
865
866 /**
867 * @return true iff a given function descriptor should be compiled to a method with boxed return type regardless of whether return type
868 * of that descriptor is nullable or not. This happens when a function returning a value of a primitive type overrides another function
869 * 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
870 * this class from Java since javac issues errors when loading the class (incompatible return types)
871 */
872 private static boolean forceBoxedReturnType(@NotNull FunctionDescriptor descriptor) {
873 //noinspection ConstantConditions
874 if (!KotlinBuiltIns.isPrimitiveType(descriptor.getReturnType())) return false;
875
876 for (FunctionDescriptor overridden : getAllOverriddenDescriptors(descriptor)) {
877 //noinspection ConstantConditions
878 if (!KotlinBuiltIns.isPrimitiveType(overridden.getOriginal().getReturnType())) return true;
879 }
880
881 return false;
882 }
883
884 private static void writeVoidReturn(@NotNull BothSignatureWriter sw) {
885 sw.writeReturnType();
886 sw.writeAsmType(Type.VOID_TYPE);
887 sw.writeReturnTypeEnd();
888 }
889
890 @Nullable
891 public String mapFieldSignature(@NotNull JetType backingFieldType) {
892 BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
893 mapType(backingFieldType, sw, JetTypeMapperMode.VALUE);
894 return sw.makeJavaGenericSignature();
895 }
896
897 private void writeThisIfNeeded(
898 @NotNull CallableMemberDescriptor descriptor,
899 @NotNull OwnerKind kind,
900 @NotNull BothSignatureWriter sw
901 ) {
902 ClassDescriptor thisType;
903 if (kind == OwnerKind.TRAIT_IMPL) {
904 thisType = getTraitImplThisParameterClass((ClassDescriptor) descriptor.getContainingDeclaration());
905 }
906 else if (isAccessor(descriptor) && descriptor.getDispatchReceiverParameter() != null) {
907 thisType = (ClassDescriptor) descriptor.getContainingDeclaration();
908 }
909 else return;
910
911 writeParameter(sw, JvmMethodParameterKind.THIS, thisType.getDefaultType());
912 }
913
914 @NotNull
915 private static ClassDescriptor getTraitImplThisParameterClass(@NotNull ClassDescriptor traitDescriptor) {
916 for (ClassDescriptor descriptor : DescriptorUtils.getSuperclassDescriptors(traitDescriptor)) {
917 if (descriptor.getKind() != ClassKind.INTERFACE) {
918 return descriptor;
919 }
920 }
921 return traitDescriptor;
922 }
923
924 public void writeFormalTypeParameters(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull BothSignatureWriter sw) {
925 for (TypeParameterDescriptor typeParameter : typeParameters) {
926 writeFormalTypeParameter(typeParameter, sw);
927 }
928 }
929
930 private void writeFormalTypeParameter(@NotNull TypeParameterDescriptor typeParameterDescriptor, @NotNull BothSignatureWriter sw) {
931 if (classBuilderMode == ClassBuilderMode.LIGHT_CLASSES && typeParameterDescriptor.getName().isSpecial()) {
932 // If a type parameter has no name, the code below fails, but it should recover in case of light classes
933 return;
934 }
935
936 sw.writeFormalTypeParameter(typeParameterDescriptor.getName().asString());
937
938 classBound:
939 {
940 sw.writeClassBound();
941
942 for (JetType jetType : typeParameterDescriptor.getUpperBounds()) {
943 if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
944 if (!isInterface(jetType)) {
945 mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
946 break classBound;
947 }
948 }
949 }
950
951 // "extends Object" is optional according to ClassFileFormat-Java5.pdf
952 // but javac complaints to signature:
953 // <P:>Ljava/lang/Object;
954 // TODO: avoid writing java/lang/Object if interface list is not empty
955 }
956 sw.writeClassBoundEnd();
957
958 for (JetType jetType : typeParameterDescriptor.getUpperBounds()) {
959 ClassifierDescriptor classifier = jetType.getConstructor().getDeclarationDescriptor();
960 if (classifier instanceof ClassDescriptor) {
961 if (isInterface(jetType)) {
962 sw.writeInterfaceBound();
963 mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
964 sw.writeInterfaceBoundEnd();
965 }
966 }
967 else if (classifier instanceof TypeParameterDescriptor) {
968 sw.writeInterfaceBound();
969 mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
970 sw.writeInterfaceBoundEnd();
971 }
972 else {
973 throw new UnsupportedOperationException("Unknown classifier: " + classifier);
974 }
975 }
976 }
977
978 private void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JetType type) {
979 writeParameter(sw, JvmMethodParameterKind.VALUE, type);
980 }
981
982 private void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull JetType type) {
983 sw.writeParameterType(kind);
984 mapType(type, sw, JetTypeMapperMode.VALUE);
985 sw.writeParameterTypeEnd();
986 }
987
988 private static void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull Type type) {
989 sw.writeParameterType(kind);
990 sw.writeAsmType(type);
991 sw.writeParameterTypeEnd();
992 }
993
994 private void writeAdditionalConstructorParameters(@NotNull ConstructorDescriptor descriptor, @NotNull BothSignatureWriter sw) {
995 MutableClosure closure = bindingContext.get(CodegenBinding.CLOSURE, descriptor.getContainingDeclaration());
996
997 ClassDescriptor captureThis = getDispatchReceiverParameterForConstructorCall(descriptor, closure);
998 if (captureThis != null) {
999 writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType());
1000 }
1001
1002 JetType captureReceiverType = closure != null ? closure.getCaptureReceiverType() : null;
1003 if (captureReceiverType != null) {
1004 writeParameter(sw, JvmMethodParameterKind.RECEIVER, captureReceiverType);
1005 }
1006
1007 ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
1008 if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) {
1009 writeParameter(sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, getBuiltIns(descriptor).getStringType());
1010 writeParameter(sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, getBuiltIns(descriptor).getIntType());
1011 }
1012
1013 if (closure == null) return;
1014
1015 for (DeclarationDescriptor variableDescriptor : closure.getCaptureVariables().keySet()) {
1016 Type type;
1017 if (variableDescriptor instanceof VariableDescriptor && !(variableDescriptor instanceof PropertyDescriptor)) {
1018 Type sharedVarType = getSharedVarType(variableDescriptor);
1019 if (sharedVarType == null) {
1020 sharedVarType = mapType(((VariableDescriptor) variableDescriptor).getType());
1021 }
1022 type = sharedVarType;
1023 }
1024 else if (isLocalFunction(variableDescriptor)) {
1025 //noinspection CastConflictsWithInstanceof
1026 type = asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) variableDescriptor);
1027 }
1028 else {
1029 type = null;
1030 }
1031
1032 if (type != null) {
1033 closure.setCapturedParameterOffsetInConstructor(variableDescriptor, sw.getCurrentSignatureSize() + 1);
1034 writeParameter(sw, JvmMethodParameterKind.CAPTURED_LOCAL_VARIABLE, type);
1035 }
1036 }
1037
1038 // We may generate a slightly wrong signature for a local class / anonymous object in light classes mode but we don't care,
1039 // because such classes are not accessible from the outside world
1040 if (classBuilderMode == ClassBuilderMode.FULL) {
1041 ResolvedCall<ConstructorDescriptor> superCall = findFirstDelegatingSuperCall(descriptor);
1042 if (superCall == null) return;
1043 writeSuperConstructorCallParameters(sw, descriptor, superCall, captureThis != null);
1044 }
1045 }
1046
1047 private void writeSuperConstructorCallParameters(
1048 @NotNull BothSignatureWriter sw,
1049 @NotNull ConstructorDescriptor descriptor,
1050 @NotNull ResolvedCall<ConstructorDescriptor> superCall,
1051 boolean hasOuter
1052 ) {
1053 ConstructorDescriptor superDescriptor = SamCodegenUtil.resolveSamAdapter(superCall.getResultingDescriptor());
1054 List<ResolvedValueArgument> valueArguments = superCall.getValueArgumentsByIndex();
1055 assert valueArguments != null : "Failed to arrange value arguments by index: " + superDescriptor;
1056
1057 List<JvmMethodParameterSignature> parameters = mapSignature(superDescriptor).getValueParameters();
1058
1059 int params = parameters.size();
1060 int args = valueArguments.size();
1061
1062 // Mapped parameters should consist of captured values plus all of valueArguments
1063 assert params >= args :
1064 String.format("Incorrect number of mapped parameters vs arguments: %d < %d for %s", params, args, descriptor);
1065
1066 // Include all captured values, i.e. those parameters for which there are no resolved value arguments
1067 for (int i = 0; i < params - args; i++) {
1068 JvmMethodParameterSignature parameter = parameters.get(i);
1069 JvmMethodParameterKind kind = parameter.getKind();
1070 if (kind == JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL) continue;
1071 if (hasOuter && kind == JvmMethodParameterKind.OUTER) continue;
1072
1073 writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
1074 }
1075
1076 if (isAnonymousObject(descriptor.getContainingDeclaration())) {
1077 // For anonymous objects, also add all real non-default value arguments passed to the super constructor
1078 for (int i = 0; i < args; i++) {
1079 ResolvedValueArgument valueArgument = valueArguments.get(i);
1080 JvmMethodParameterSignature parameter = parameters.get(params - args + i);
1081 if (!(valueArgument instanceof DefaultValueArgument)) {
1082 writeParameter(sw, JvmMethodParameterKind.SUPER_CALL_PARAM, parameter.getAsmType());
1083 }
1084 }
1085 }
1086 }
1087
1088 @Nullable
1089 private ResolvedCall<ConstructorDescriptor> findFirstDelegatingSuperCall(@NotNull ConstructorDescriptor descriptor) {
1090 ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
1091 while (true) {
1092 ResolvedCall<ConstructorDescriptor> next = getDelegationConstructorCall(bindingContext, descriptor);
1093 if (next == null) return null;
1094 descriptor = next.getResultingDescriptor();
1095 if (descriptor.getContainingDeclaration() != classDescriptor) return next;
1096 }
1097 }
1098
1099 @NotNull
1100 public JvmMethodSignature mapScriptSignature(@NotNull ScriptDescriptor script, @NotNull List<ScriptDescriptor> importedScripts) {
1101 BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
1102
1103 sw.writeParametersStart();
1104
1105 for (ScriptDescriptor importedScript : importedScripts) {
1106 ClassDescriptor descriptor = bindingContext.get(CLASS_FOR_SCRIPT, importedScript);
1107 assert descriptor != null : "Script not found: " + importedScript;
1108 writeParameter(sw, descriptor.getDefaultType());
1109 }
1110
1111 for (ValueParameterDescriptor valueParameter : script.getScriptCodeDescriptor().getValueParameters()) {
1112 writeParameter(sw, valueParameter.getType());
1113 }
1114
1115 writeVoidReturn(sw);
1116
1117 return sw.makeJvmMethodSignature("<init>");
1118 }
1119
1120 public Type getSharedVarType(DeclarationDescriptor descriptor) {
1121 if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
1122 return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
1123 }
1124 else if (descriptor instanceof PropertyDescriptor || descriptor instanceof FunctionDescriptor) {
1125 ReceiverParameterDescriptor receiverParameter = ((CallableDescriptor) descriptor).getExtensionReceiverParameter();
1126 assert receiverParameter != null : "Callable should have a receiver parameter: " + descriptor;
1127 return StackValue.sharedTypeForType(mapType(receiverParameter.getType()));
1128 }
1129 else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(bindingContext, descriptor)) {
1130 return StackValue.sharedTypeForType(mapType(((VariableDescriptor) descriptor).getType()));
1131 }
1132 return null;
1133 }
1134 }