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.context.CodegenContext;
032 import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
033 import org.jetbrains.kotlin.descriptors.*;
034 import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
035 import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
036 import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
037 import org.jetbrains.kotlin.load.java.JvmAbi;
038 import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
039 import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
040 import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
041 import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
042 import org.jetbrains.kotlin.name.*;
043 import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
044 import org.jetbrains.kotlin.psi.JetExpression;
045 import org.jetbrains.kotlin.psi.JetFile;
046 import org.jetbrains.kotlin.psi.JetFunctionLiteral;
047 import org.jetbrains.kotlin.psi.JetFunctionLiteralExpression;
048 import org.jetbrains.kotlin.resolve.BindingContext;
049 import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
050 import org.jetbrains.kotlin.resolve.DescriptorUtils;
051 import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
052 import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument;
053 import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
054 import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
055 import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
056 import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
057 import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
058 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
059 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
060 import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
061 import org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter;
062 import org.jetbrains.kotlin.resolve.scopes.ChainedScope;
063 import org.jetbrains.kotlin.resolve.scopes.JetScope;
064 import org.jetbrains.kotlin.serialization.deserialization.DeserializedType;
065 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
066 import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope;
067 import org.jetbrains.kotlin.types.*;
068 import org.jetbrains.kotlin.types.expressions.OperatorConventions;
069 import org.jetbrains.org.objectweb.asm.Type;
070 import org.jetbrains.org.objectweb.asm.commons.Method;
071
072 import java.io.File;
073 import java.util.ArrayList;
074 import java.util.List;
075
076 import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isUnit;
077 import static org.jetbrains.kotlin.codegen.AsmUtil.*;
078 import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
079 import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
080 import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
081 import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
082 import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
083 import static org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage.getBuiltIns;
084 import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER;
085 import static org.jetbrains.org.objectweb.asm.Opcodes.*;
086
087 public class JetTypeMapper {
088 private final BindingContext bindingContext;
089 private final ClassBuilderMode classBuilderMode;
090 private final JvmFileClassesProvider fileClassesProvider;
091
092 public JetTypeMapper(
093 @NotNull BindingContext bindingContext,
094 @NotNull ClassBuilderMode classBuilderMode,
095 @NotNull JvmFileClassesProvider fileClassesProvider
096 ) {
097 this.bindingContext = bindingContext;
098 this.classBuilderMode = classBuilderMode;
099 this.fileClassesProvider = fileClassesProvider;
100 }
101
102 @NotNull
103 public BindingContext getBindingContext() {
104 return bindingContext;
105 }
106
107 private enum JetTypeMapperMode {
108 /**
109 * foo.Bar is mapped to Lfoo/Bar;
110 */
111 IMPL,
112 /**
113 * kotlin.Int is mapped to I
114 */
115 VALUE,
116 /**
117 * kotlin.Int is mapped to Ljava/lang/Integer;
118 */
119 TYPE_PARAMETER,
120 /**
121 * kotlin.Int is mapped to Ljava/lang/Integer;
122 * No projections allowed in immediate arguments
123 */
124 SUPER_TYPE,
125 /**
126 * kotlin.reflect.KClass mapped to java.lang.Class
127 * Other types mapped as VALUE
128 */
129 VALUE_FOR_ANNOTATION,
130 /**
131 * kotlin.reflect.KClass mapped to java.lang.Class
132 * Other types mapped as TYPE_PARAMETER
133 */
134 TYPE_PARAMETER_FOR_ANNOTATION;
135
136 boolean isForAnnotation() {
137 return this == VALUE_FOR_ANNOTATION || this == TYPE_PARAMETER_FOR_ANNOTATION;
138 }
139 }
140
141 @NotNull
142 public Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean isInsideModule) {
143 if (isLocalFunction(descriptor)) {
144 return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
145 }
146
147 DeclarationDescriptor container = descriptor.getContainingDeclaration();
148 if (container instanceof PackageFragmentDescriptor) {
149 return Type.getObjectType(internalNameForPackage((CallableMemberDescriptor) descriptor));
150 }
151 else if (container instanceof ClassDescriptor) {
152 return mapClass((ClassDescriptor) container);
153 }
154 else if (container instanceof ScriptDescriptor) {
155 return asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) container);
156 }
157 else {
158 throw new UnsupportedOperationException("Don't know how to map owner for " + descriptor);
159 }
160 }
161
162 @NotNull
163 private String internalNameForPackage(@NotNull CallableMemberDescriptor descriptor) {
164 JetFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
165 if (file != null) {
166 Visibility visibility = descriptor.getVisibility();
167 if (descriptor instanceof PropertyDescriptor || Visibilities.isPrivate(visibility)) {
168 return FileClassesPackage.getFileClassInternalName(fileClassesProvider, file);
169 }
170 else {
171 return FileClassesPackage.getFacadeClassInternalName(fileClassesProvider, file);
172 }
173 }
174
175 CallableMemberDescriptor directMember = getDirectMember(descriptor);
176
177 if (directMember instanceof DeserializedCallableMemberDescriptor) {
178 String facadeFqName = getPackageMemberOwnerInternalName((DeserializedCallableMemberDescriptor) directMember);
179 if (facadeFqName != null) return facadeFqName;
180 }
181
182 throw new RuntimeException("Unreachable state");
183 //return PackageClassUtils.getPackageClassInternalName(packageFragment.getFqName());
184 }
185
186 @Nullable
187 private static String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
188 // XXX This method (and getPackageMemberOwnerShortName) is a dirty hack
189 // introduced to make stdlib work with package facades built as multifile facades for M13.
190 // We need some safe, concise way to identify multifile facade and multifile part
191 // from a deserialized package member descriptor.
192 // Possible approaches:
193 // - create a special instance of DeserializedPackageFragmentDescriptor for each facade class (multifile or single-file),
194 // keep related mapping information there;
195 // - provide a proper SourceElement for such descriptors (similar to KotlinJvmBinarySourceElement).
196 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
197 assert containingDeclaration instanceof PackageFragmentDescriptor : "Not a top-level member: " + descriptor;
198 PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
199
200 String facadeShortName = getPackageMemberOwnerShortName(descriptor);
201 if (facadeShortName == null) {
202 return null;
203 }
204
205 FqName facadeFqName = packageFragmentDescriptor.getFqName().child(Name.identifier(facadeShortName));
206 return internalNameByFqNameWithoutInnerClasses(facadeFqName);
207 }
208
209 @Nullable
210 private static String getPackageMemberOwnerShortName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
211 // XXX Dirty hack; see getPackageMemberOwnerInternalName above for more details.
212 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
213 if (containingDeclaration instanceof PackageFragmentDescriptor) {
214 PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
215 JetScope scope = packageFragmentDescriptor.getMemberScope();
216 if (scope instanceof AbstractScopeAdapter) {
217 scope = ((AbstractScopeAdapter) scope).getActualScope();
218 }
219 if (scope instanceof LazyJavaPackageScope) {
220 Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
221 return ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString());
222 }
223 else if (packageFragmentDescriptor instanceof BuiltinsPackageFragment) {
224 return PackageClassUtils.getPackageClassFqName(packageFragmentDescriptor.getFqName()).shortName().asString();
225 }
226 else {
227 // Incremental compilation ends up here. We do not have multifile classes support in incremental so far,
228 // so "use implementation class name" looks like a safe assumption for this case.
229 // However, this should be fixed; see getPackageMemberOwnerInternalName above for more details.
230 Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
231 return implClassName.asString();
232 }
233 }
234 return null;
235 }
236
237 @NotNull
238 public Type mapReturnType(@NotNull CallableDescriptor descriptor) {
239 return mapReturnType(descriptor, null);
240 }
241
242 @NotNull
243 private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable BothSignatureWriter sw) {
244 JetType returnType = descriptor.getReturnType();
245 assert returnType != null : "Function has no return type: " + descriptor;
246
247 if (descriptor instanceof ConstructorDescriptor) {
248 return Type.VOID_TYPE;
249 }
250
251 if (isUnit(returnType) && !TypeUtils.isNullableType(returnType) && !(descriptor instanceof PropertyGetterDescriptor)) {
252 if (sw != null) {
253 sw.writeAsmType(Type.VOID_TYPE);
254 }
255 return Type.VOID_TYPE;
256 }
257 else if (descriptor instanceof FunctionDescriptor && forceBoxedReturnType((FunctionDescriptor) descriptor)) {
258 // TYPE_PARAMETER is a hack to automatically box the return type
259 //noinspection ConstantConditions
260 return mapType(descriptor.getReturnType(), sw, JetTypeMapperMode.TYPE_PARAMETER);
261 }
262 else if (DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration())) {
263 //noinspection ConstantConditions
264 return mapType(descriptor.getReturnType(), sw, JetTypeMapperMode.VALUE_FOR_ANNOTATION);
265 }
266 else {
267 return mapType(returnType, sw, JetTypeMapperMode.VALUE, Variance.OUT_VARIANCE);
268 }
269 }
270
271 @NotNull
272 private Type mapType(@NotNull JetType jetType, @NotNull JetTypeMapperMode mode) {
273 return mapType(jetType, null, mode);
274 }
275
276 @NotNull
277 public Type mapSupertype(@NotNull JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
278 return mapType(jetType, signatureVisitor, JetTypeMapperMode.SUPER_TYPE);
279 }
280
281 @NotNull
282 public Type mapTypeParameter(@NotNull JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
283 return mapType(jetType, signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER);
284 }
285
286 @NotNull
287 public Type mapClass(@NotNull ClassifierDescriptor classifier) {
288 return mapType(classifier.getDefaultType(), null, JetTypeMapperMode.IMPL);
289 }
290
291 @NotNull
292 public Type mapType(@NotNull JetType jetType) {
293 return mapType(jetType, null, JetTypeMapperMode.VALUE);
294 }
295
296 @NotNull
297 public Type mapType(@NotNull CallableDescriptor descriptor) {
298 //noinspection ConstantConditions
299 return mapType(descriptor.getReturnType());
300 }
301
302 @NotNull
303 public JvmMethodSignature mapAnnotationParameterSignature(@NotNull PropertyDescriptor descriptor) {
304 BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
305 sw.writeReturnType();
306 mapType(descriptor.getType(), sw, JetTypeMapperMode.VALUE_FOR_ANNOTATION);
307 sw.writeReturnTypeEnd();
308 return sw.makeJvmMethodSignature(descriptor.getName().asString());
309 }
310
311 @NotNull
312 public Type mapType(@NotNull ClassifierDescriptor descriptor) {
313 return mapType(descriptor.getDefaultType());
314 }
315
316 @NotNull
317 private Type mapType(@NotNull JetType jetType, @Nullable BothSignatureWriter signatureVisitor, @NotNull JetTypeMapperMode mode) {
318 return mapType(jetType, signatureVisitor, mode, Variance.INVARIANT);
319 }
320
321 @NotNull
322 private Type mapType(
323 @NotNull JetType jetType,
324 @Nullable BothSignatureWriter signatureVisitor,
325 @NotNull JetTypeMapperMode kind,
326 @NotNull Variance howThisTypeIsUsed
327 ) {
328 Type known = mapBuiltinType(jetType);
329
330 boolean projectionsAllowed = kind != JetTypeMapperMode.SUPER_TYPE;
331 if (known != null) {
332 if (kind == JetTypeMapperMode.VALUE || kind == JetTypeMapperMode.VALUE_FOR_ANNOTATION) {
333 return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed);
334 }
335 else if (kind == JetTypeMapperMode.TYPE_PARAMETER || kind == JetTypeMapperMode.SUPER_TYPE ||
336 kind == JetTypeMapperMode.TYPE_PARAMETER_FOR_ANNOTATION) {
337 return mapKnownAsmType(jetType, boxType(known), signatureVisitor, howThisTypeIsUsed, projectionsAllowed);
338 }
339 else if (kind == JetTypeMapperMode.IMPL) {
340 // TODO: enable and fix tests
341 //throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType);
342 return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed);
343 }
344 else {
345 throw new IllegalStateException("unknown kind: " + kind);
346 }
347 }
348
349 TypeConstructor constructor = jetType.getConstructor();
350 DeclarationDescriptor descriptor = constructor.getDeclarationDescriptor();
351 if (constructor instanceof IntersectionTypeConstructor) {
352 jetType = CommonSupertypes.commonSupertype(new ArrayList<JetType>(constructor.getSupertypes()));
353 }
354
355 if (descriptor == null) {
356 throw new UnsupportedOperationException("no descriptor for type constructor of " + jetType);
357 }
358
359 if (ErrorUtils.isError(descriptor)) {
360 if (classBuilderMode != ClassBuilderMode.LIGHT_CLASSES) {
361 throw new IllegalStateException(generateErrorMessageForErrorType(jetType, descriptor));
362 }
363 Type asmType = Type.getObjectType("error/NonExistentClass");
364 if (signatureVisitor != null) {
365 signatureVisitor.writeAsmType(asmType);
366 }
367 return asmType;
368 }
369
370 if (descriptor instanceof ClassDescriptor && KotlinBuiltIns.isArray(jetType)) {
371 if (jetType.getArguments().size() != 1) {
372 throw new UnsupportedOperationException("arrays must have one type argument");
373 }
374 TypeProjection memberProjection = jetType.getArguments().get(0);
375 JetType memberType = memberProjection.getType();
376
377 Type arrayElementType;
378 if (memberProjection.getProjectionKind() == Variance.IN_VARIANCE) {
379 arrayElementType = AsmTypes.OBJECT_TYPE;
380 if (signatureVisitor != null) {
381 signatureVisitor.writeArrayType();
382 signatureVisitor.writeAsmType(arrayElementType);
383 signatureVisitor.writeArrayEnd();
384 }
385 }
386 else {
387 arrayElementType = boxType(mapType(memberType, kind));
388 if (signatureVisitor != null) {
389 signatureVisitor.writeArrayType();
390 JetTypeMapperMode newMode = kind.isForAnnotation() ?
391 JetTypeMapperMode.TYPE_PARAMETER_FOR_ANNOTATION :
392 JetTypeMapperMode.TYPE_PARAMETER;
393 mapType(memberType, signatureVisitor, newMode, memberProjection.getProjectionKind());
394 signatureVisitor.writeArrayEnd();
395 }
396 }
397
398 return Type.getType("[" + arrayElementType.getDescriptor());
399 }
400
401 if (descriptor instanceof ClassDescriptor) {
402 Type asmType = kind.isForAnnotation() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
403 AsmTypes.JAVA_CLASS_TYPE :
404 computeAsmType((ClassDescriptor) descriptor.getOriginal());
405 writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, projectionsAllowed);
406 return asmType;
407 }
408
409 if (descriptor instanceof TypeParameterDescriptor) {
410 TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
411 Type type = mapType(typeParameterDescriptor.getUpperBounds().iterator().next(), kind);
412 if (signatureVisitor != null) {
413 signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), type);
414 }
415 return type;
416 }
417
418 throw new UnsupportedOperationException("Unknown type " + jetType);
419 }
420
421 @Nullable
422 private static Type mapBuiltinType(@NotNull JetType type) {
423 DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
424 if (!(descriptor instanceof ClassDescriptor)) return null;
425
426 FqNameUnsafe fqName = DescriptorUtils.getFqName(descriptor);
427
428 PrimitiveType primitiveType = KotlinBuiltIns.getPrimitiveTypeByFqName(fqName);
429 if (primitiveType != null) {
430 Type asmType = Type.getType(JvmPrimitiveType.get(primitiveType).getDesc());
431 return TypeUtils.isNullableType(type) ? boxType(asmType) : asmType;
432 }
433
434 PrimitiveType arrayElementType = KotlinBuiltIns.getPrimitiveTypeByArrayClassFqName(fqName);
435 if (arrayElementType != null) {
436 return Type.getType("[" + JvmPrimitiveType.get(arrayElementType).getDesc());
437 }
438
439 ClassId classId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(fqName);
440 if (classId != null) {
441 return Type.getObjectType(JvmClassName.byClassId(classId).getInternalName());
442 }
443
444 return null;
445 }
446
447 @NotNull
448 private Type computeAsmType(@NotNull ClassDescriptor klass) {
449 Type alreadyComputedType = bindingContext.get(ASM_TYPE, klass);
450 if (alreadyComputedType != null) {
451 return alreadyComputedType;
452 }
453
454 Type asmType = Type.getObjectType(computeAsmTypeImpl(klass));
455 assert PsiCodegenPredictor.checkPredictedNameFromPsi(klass, asmType, fileClassesProvider);
456 return asmType;
457 }
458
459 @NotNull
460 private String computeAsmTypeImpl(@NotNull ClassDescriptor klass) {
461 DeclarationDescriptor container = klass.getContainingDeclaration();
462
463 String name = SpecialNames.safeIdentifier(klass.getName()).getIdentifier();
464 if (container instanceof PackageFragmentDescriptor) {
465 FqName fqName = ((PackageFragmentDescriptor) container).getFqName();
466 return fqName.isRoot() ? name : fqName.asString().replace('.', '/') + '/' + name;
467 }
468
469 if (container instanceof ScriptDescriptor) {
470 return asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) container).getInternalName() + "$" + name;
471 }
472
473 assert container instanceof ClassDescriptor : "Unexpected container: " + container + " for " + klass;
474
475 String containerInternalName = computeAsmTypeImpl((ClassDescriptor) container);
476 return klass.getKind() == ClassKind.ENUM_ENTRY ? containerInternalName : containerInternalName + "$" + name;
477 }
478
479 @NotNull
480 public Type mapTraitImpl(@NotNull ClassDescriptor descriptor) {
481 return Type.getObjectType(mapType(descriptor).getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
482 }
483
484 @NotNull
485 private static String generateErrorMessageForErrorType(@NotNull JetType type, @NotNull DeclarationDescriptor descriptor) {
486 PsiElement declarationElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
487
488 if (declarationElement == null) {
489 String message = "Error type encountered: %s (%s).";
490 if (TypesPackage.upperIfFlexible(type) instanceof DeserializedType) {
491 message +=
492 " One of the possible reasons may be that this type is not directly accessible from this module. " +
493 "To workaround this error, try adding an explicit dependency on the module or library which contains this type " +
494 "to the classpath";
495 }
496 return String.format(message, type, type.getClass().getSimpleName());
497 }
498
499 DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
500 PsiElement parentDeclarationElement =
501 containingDeclaration != null ? DescriptorToSourceUtils.descriptorToDeclaration(containingDeclaration) : null;
502
503 return String.format(
504 "Error type encountered: %s (%s). Descriptor: %s. For declaration %s:%s in %s:%s",
505 type,
506 type.getClass().getSimpleName(),
507 descriptor,
508 declarationElement,
509 declarationElement.getText(),
510 parentDeclarationElement,
511 parentDeclarationElement != null ? parentDeclarationElement.getText() : "null"
512 );
513 }
514
515 private void writeGenericType(
516 BothSignatureWriter signatureVisitor,
517 Type asmType,
518 JetType jetType,
519 Variance howThisTypeIsUsed,
520 boolean projectionsAllowed
521 ) {
522 if (signatureVisitor != null) {
523 signatureVisitor.writeClassBegin(asmType);
524
525 List<TypeProjection> arguments = jetType.getArguments();
526 for (TypeParameterDescriptor parameter : jetType.getConstructor().getParameters()) {
527 TypeProjection argument = arguments.get(parameter.getIndex());
528
529 if (projectionsAllowed && argument.isStarProjection()) {
530 signatureVisitor.writeUnboundedWildcard();
531 }
532 else {
533 Variance projectionKind = projectionsAllowed
534 ? getEffectiveVariance(
535 parameter.getVariance(),
536 argument.getProjectionKind(),
537 howThisTypeIsUsed
538 )
539 : Variance.INVARIANT;
540 signatureVisitor.writeTypeArgument(projectionKind);
541
542 mapType(argument.getType(), signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER);
543 signatureVisitor.writeTypeArgumentEnd();
544 }
545 }
546 signatureVisitor.writeClassEnd();
547 }
548 }
549
550 private static Variance getEffectiveVariance(Variance parameterVariance, Variance projectionKind, Variance howThisTypeIsUsed) {
551 // Return type must not contain wildcards
552 if (howThisTypeIsUsed == Variance.OUT_VARIANCE) return projectionKind;
553
554 if (parameterVariance == Variance.INVARIANT) {
555 return projectionKind;
556 }
557 if (projectionKind == Variance.INVARIANT) {
558 return parameterVariance;
559 }
560 if (parameterVariance == projectionKind) {
561 return parameterVariance;
562 }
563
564 // In<out X> = In<*>
565 // Out<in X> = Out<*>
566 return Variance.OUT_VARIANCE;
567 }
568
569 private Type mapKnownAsmType(
570 JetType jetType,
571 Type asmType,
572 @Nullable BothSignatureWriter signatureVisitor,
573 @NotNull Variance howThisTypeIsUsed
574 ) {
575 return mapKnownAsmType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, true);
576 }
577
578 private Type mapKnownAsmType(
579 JetType jetType,
580 Type asmType,
581 @Nullable BothSignatureWriter signatureVisitor,
582 @NotNull Variance howThisTypeIsUsed,
583 boolean allowProjections
584 ) {
585 if (signatureVisitor != null) {
586 if (jetType.getArguments().isEmpty()) {
587 signatureVisitor.writeAsmType(asmType);
588 }
589 else {
590 writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, allowProjections);
591 }
592 }
593 return asmType;
594 }
595
596 @NotNull
597 public CallableMethod mapToCallableMethod(
598 @NotNull FunctionDescriptor descriptor,
599 boolean superCall,
600 @NotNull CodegenContext<?> context
601 ) {
602 DeclarationDescriptor functionParent = descriptor.getOriginal().getContainingDeclaration();
603
604 FunctionDescriptor functionDescriptor = unwrapFakeOverride(descriptor.getOriginal());
605
606 JvmMethodSignature signature;
607 Type owner;
608 Type ownerForDefaultImpl;
609 Type ownerForDefaultParam;
610 int invokeOpcode;
611 Type thisClass;
612
613 if (functionParent instanceof ClassDescriptor) {
614 FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor);
615
616 ClassDescriptor currentOwner = (ClassDescriptor) functionParent;
617 ClassDescriptor declarationOwner = (ClassDescriptor) declarationFunctionDescriptor.getContainingDeclaration();
618
619 boolean originalIsInterface = isInterface(declarationOwner);
620 boolean currentIsInterface = isInterface(currentOwner);
621
622 boolean isInterface = currentIsInterface && originalIsInterface;
623
624 ClassDescriptor ownerForDefault = (ClassDescriptor) findBaseDeclaration(functionDescriptor).getContainingDeclaration();
625 ownerForDefaultParam = mapClass(ownerForDefault);
626 ownerForDefaultImpl = isInterface(ownerForDefault) ? mapTraitImpl(ownerForDefault) : ownerForDefaultParam;
627
628 if (isInterface && superCall) {
629 thisClass = mapClass(currentOwner);
630 if (declarationOwner instanceof JavaClassDescriptor) {
631 invokeOpcode = INVOKESPECIAL;
632 signature = mapSignature(functionDescriptor);
633 owner = thisClass;
634 }
635 else {
636 invokeOpcode = INVOKESTATIC;
637 signature = mapSignature(descriptor.getOriginal(), OwnerKind.TRAIT_IMPL);
638 owner = mapTraitImpl(currentOwner);
639 }
640 }
641 else {
642 if (isStaticDeclaration(functionDescriptor) ||
643 isStaticAccessor(functionDescriptor) ||
644 AnnotationsPackage.isPlatformStaticInObjectOrClass(functionDescriptor)) {
645 invokeOpcode = INVOKESTATIC;
646 }
647 else if (isInterface) {
648 invokeOpcode = INVOKEINTERFACE;
649 }
650 else {
651 boolean isPrivateFunInvocation = Visibilities.isPrivate(functionDescriptor.getVisibility());
652 invokeOpcode = superCall || isPrivateFunInvocation ? INVOKESPECIAL : INVOKEVIRTUAL;
653 }
654
655 signature = mapSignature(functionDescriptor.getOriginal());
656
657 ClassDescriptor receiver = (currentIsInterface && !originalIsInterface) || currentOwner instanceof FunctionClassDescriptor
658 ? declarationOwner
659 : currentOwner;
660 owner = mapClass(receiver);
661 thisClass = owner;
662 }
663 }
664 else {
665 signature = mapSignature(functionDescriptor.getOriginal());
666 owner = mapOwner(functionDescriptor, isCallInsideSameModuleAsDeclared(functionDescriptor, context, getOutDirectory()));
667 ownerForDefaultParam = owner;
668 ownerForDefaultImpl = owner;
669 if (functionParent instanceof PackageFragmentDescriptor) {
670 invokeOpcode = INVOKESTATIC;
671 thisClass = null;
672 }
673 else if (functionDescriptor instanceof ConstructorDescriptor) {
674 invokeOpcode = INVOKESPECIAL;
675 thisClass = null;
676 }
677 else {
678 invokeOpcode = INVOKEVIRTUAL;
679 thisClass = owner;
680 }
681 }
682
683 Type calleeType = isLocalFunction(functionDescriptor) ? owner : null;
684
685 Type receiverParameterType;
686 ReceiverParameterDescriptor receiverParameter = functionDescriptor.getOriginal().getExtensionReceiverParameter();
687 if (receiverParameter != null) {
688 receiverParameterType = mapType(receiverParameter.getType());
689 }
690 else {
691 receiverParameterType = null;
692 }
693 return new CallableMethod(
694 owner, ownerForDefaultImpl, ownerForDefaultParam, signature, invokeOpcode,
695 thisClass, receiverParameterType, calleeType);
696 }
697
698 public static boolean isAccessor(@NotNull CallableMemberDescriptor descriptor) {
699 return descriptor instanceof AccessorForCallableDescriptor<?>;
700 }
701
702 public static boolean isStaticAccessor(@NotNull CallableMemberDescriptor descriptor) {
703 if (descriptor instanceof AccessorForConstructorDescriptor) return false;
704 return isAccessor(descriptor);
705 }
706
707 @NotNull
708 private static FunctionDescriptor findAnyDeclaration(@NotNull FunctionDescriptor function) {
709 if (function.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
710 return function;
711 }
712 return findBaseDeclaration(function);
713 }
714
715 @NotNull
716 private static FunctionDescriptor findBaseDeclaration(@NotNull FunctionDescriptor function) {
717 if (function.getOverriddenDescriptors().isEmpty()) {
718 return function;
719 }
720 else {
721 // TODO: prefer class to interface
722 return findBaseDeclaration(function.getOverriddenDescriptors().iterator().next());
723 }
724 }
725
726 @NotNull
727 private String mapFunctionName(@NotNull FunctionDescriptor descriptor) {
728 if (!(descriptor instanceof JavaCallableMemberDescriptor)) {
729 String platformName = getJvmName(descriptor);
730 if (platformName != null) return platformName;
731 }
732
733 if (descriptor instanceof PropertyAccessorDescriptor) {
734 PropertyDescriptor property = ((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty();
735 if (isAnnotationClass(property.getContainingDeclaration())) {
736 return property.getName().asString();
737 }
738
739 boolean isAccessor = property instanceof AccessorForPropertyDescriptor;
740 String propertyName = isAccessor
741 ? ((AccessorForPropertyDescriptor) property).getIndexedAccessorSuffix()
742 : property.getName().asString();
743
744 String accessorName = descriptor instanceof PropertyGetterDescriptor
745 ? JvmAbi.getterName(propertyName)
746 : JvmAbi.setterName(propertyName);
747
748 return isAccessor ? "access$" + accessorName : accessorName;
749 }
750 else if (isFunctionLiteral(descriptor)) {
751 PsiElement element = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor);
752 if (element instanceof JetFunctionLiteral) {
753 PsiElement expression = element.getParent();
754 if (expression instanceof JetFunctionLiteralExpression) {
755 SamType samType = bindingContext.get(SAM_VALUE, (JetExpression) expression);
756 if (samType != null) {
757 return samType.getAbstractMethod().getName().asString();
758 }
759 }
760 }
761
762 return OperatorConventions.INVOKE.asString();
763 }
764 else if (isLocalFunction(descriptor) || isFunctionExpression(descriptor)) {
765 return OperatorConventions.INVOKE.asString();
766 }
767 else {
768 return descriptor.getName().asString();
769 }
770 }
771
772 @NotNull
773 public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor descriptor) {
774 return mapSignature(descriptor, OwnerKind.IMPLEMENTATION);
775 }
776
777 @NotNull
778 public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind) {
779 if (f instanceof ConstructorDescriptor) {
780 return mapSignature(f, kind, f.getOriginal().getValueParameters());
781 }
782 return mapSignature(f, kind, f.getValueParameters());
783 }
784
785 @NotNull
786 public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, @NotNull OwnerKind kind,
787 List<ValueParameterDescriptor> valueParameters) {
788 BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
789
790 if (f instanceof ConstructorDescriptor) {
791 sw.writeParametersStart();
792 writeAdditionalConstructorParameters((ConstructorDescriptor) f, sw);
793
794 for (ValueParameterDescriptor parameter : valueParameters) {
795 writeParameter(sw, parameter.getType());
796 }
797
798 if (f instanceof AccessorForConstructorDescriptor) {
799 writeParameter(sw, JvmMethodParameterKind.CONSTRUCTOR_MARKER, DEFAULT_CONSTRUCTOR_MARKER);
800 }
801
802 writeVoidReturn(sw);
803 }
804 else {
805 writeFormalTypeParameters(getDirectMember(f).getTypeParameters(), sw);
806
807 sw.writeParametersStart();
808 writeThisIfNeeded(f, kind, sw);
809
810 ReceiverParameterDescriptor receiverParameter = f.getExtensionReceiverParameter();
811 if (receiverParameter != null) {
812 writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.getType());
813 }
814
815 for (ValueParameterDescriptor parameter : valueParameters) {
816 writeParameter(sw, parameter.getType());
817 }
818
819 sw.writeReturnType();
820 mapReturnType(f, sw);
821 sw.writeReturnTypeEnd();
822 }
823
824 return sw.makeJvmMethodSignature(mapFunctionName(f));
825 }
826
827 @NotNull
828 public static String getDefaultDescriptor(@NotNull Method method, @Nullable String dispatchReceiverDescriptor, boolean isExtension) {
829 String descriptor = method.getDescriptor();
830 int argumentsCount = Type.getArgumentTypes(descriptor).length;
831 if (isExtension) {
832 argumentsCount--;
833 }
834 int maskArgumentsCount = (argumentsCount + Integer.SIZE - 1) / Integer.SIZE;
835 String additionalArgs = StringUtil.repeat(Type.INT_TYPE.getDescriptor(), maskArgumentsCount);
836 if (isConstructor(method)) {
837 additionalArgs += DEFAULT_CONSTRUCTOR_MARKER.getDescriptor();
838 }
839 String result = descriptor.replace(")", additionalArgs + ")");
840 if (dispatchReceiverDescriptor != null && !isConstructor(method)) {
841 return result.replace("(", "(" + dispatchReceiverDescriptor);
842 }
843 return result;
844 }
845
846 public ClassBuilderMode getClassBuilderMode() {
847 return classBuilderMode;
848 }
849
850 private static boolean isConstructor(@NotNull Method method) {
851 return "<init>".equals(method.getName());
852 }
853
854 @NotNull
855 public Method mapDefaultMethod(@NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind kind, @NotNull CodegenContext<?> context) {
856 Method jvmSignature = mapSignature(functionDescriptor, kind).getAsmMethod();
857 Type ownerType = mapOwner(functionDescriptor, isCallInsideSameModuleAsDeclared(functionDescriptor, context, getOutDirectory()));
858 boolean isConstructor = isConstructor(jvmSignature);
859 String descriptor = getDefaultDescriptor(jvmSignature,
860 isStaticMethod(kind, functionDescriptor) || isConstructor ? null : ownerType.getDescriptor(),
861 functionDescriptor.getExtensionReceiverParameter() != null);
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 @NotNull
1121 public CallableMethod mapToCallableMethod(@NotNull ConstructorDescriptor descriptor) {
1122 JvmMethodSignature method = mapSignature(descriptor);
1123 ClassDescriptor container = descriptor.getContainingDeclaration();
1124 Type owner = mapClass(container);
1125 if (owner.getSort() != Type.OBJECT) {
1126 throw new IllegalStateException("type must have been mapped to object: " + container.getDefaultType() + ", actual: " + owner);
1127 }
1128 return new CallableMethod(owner, owner, owner, method, INVOKESPECIAL, null, null, null);
1129 }
1130
1131 public Type getSharedVarType(DeclarationDescriptor descriptor) {
1132 if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
1133 return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
1134 }
1135 else if (descriptor instanceof PropertyDescriptor || descriptor instanceof FunctionDescriptor) {
1136 ReceiverParameterDescriptor receiverParameter = ((CallableDescriptor) descriptor).getExtensionReceiverParameter();
1137 assert receiverParameter != null : "Callable should have a receiver parameter: " + descriptor;
1138 return StackValue.sharedTypeForType(mapType(receiverParameter.getType()));
1139 }
1140 else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(bindingContext, descriptor)) {
1141 return StackValue.sharedTypeForType(mapType(((VariableDescriptor) descriptor).getType()));
1142 }
1143 return null;
1144 }
1145
1146 // TODO Temporary hack until modules infrastructure is implemented. See JetTypeMapperWithOutDirectory for details
1147 @Nullable
1148 protected File getOutDirectory() {
1149 return null;
1150 }
1151 }