Compare commits

...

38 Commits

Author SHA1 Message Date
Ilya Gorbunov
5200048d60 Introduce T.addTo(MutableCollection<T>)
#KT-5166 Fixed
2015-12-01 15:30:54 +03:00
Pavel V. Talanov
aa1a08fe7a Minor, getModuleInfo: improve on failure messages 2015-12-01 14:53:16 +03:00
Pavel V. Talanov
bc816851f1 getModuleInfo: Provide utility to default to null instead of logging an error
Use it to workaround cases when java resolve references some unexpected classes/files, referencing non-physical Dummy.java in particular
2015-12-01 14:53:15 +03:00
Pavel V. Talanov
5e35be347c getModuleInfo: Correct module info for members of light classes for decompiled Kotlin classes 2015-12-01 14:53:12 +03:00
Natalia Ukhorskaya
dc60c025c3 Support Evaluate Expression for renamed local variables in inline function
#KT-10179 Fixed
2015-12-01 11:48:43 +03:00
Natalia Ukhorskaya
cd5e406876 Minor: fix warnings 2015-12-01 11:48:41 +03:00
Natalia Ukhorskaya
a1f3c5381e Rename local variable for this in inline function 2015-12-01 11:48:41 +03:00
Michael Bogdanov
a932315bf9 Rename local vars from inlined function
#KT-9798 Fixed
2015-12-01 11:48:40 +03:00
Natalia Ukhorskaya
5073b1d372 Don't skip inlined this 2015-12-01 11:48:39 +03:00
Natalia Ukhorskaya
29778311e8 Drop unnecesary logic about additional context for lambda in debugger 2015-12-01 11:48:38 +03:00
Dmitry Petrov
f34f7556bc KT-10192 got fixed due to new if/when check
(which doesn't depend on the expected type for expression)
 #KT-10192 Fixed
2015-12-01 10:36:40 +03:00
Dmitry Petrov
76931affc6 KT-10139:
Non-exhaustive 'when' without 'else' used in expression is an error
regardless of expected type: it can't be an expression, even of type Unit.
2015-12-01 10:36:40 +03:00
Dmitry Petrov
1a3a296827 KT-10139: any if without else used in expression is an error
regardless of expected type: it can't be an expression, even of type Unit.

 #KT-10139 Fixed
2015-12-01 10:36:40 +03:00
Denis Zharkov
b0dab4c67a Add minor changes after review
- Rename GENERIC_TYPE -> GENERIC_ARGUMENT
- Make 'callableDescriptor' nullable
2015-12-01 08:21:03 +03:00
Denis Zharkov
0fd2484bc9 Fix project source to overcome bootstrap problem 2015-12-01 08:21:02 +03:00
Denis Zharkov
c4bc2c9ba6 J2K Renderer: convert and make contravariant 2015-12-01 08:21:02 +03:00
Denis Zharkov
5a5889e3f3 J2K Renderer: .java -> .kt 2015-12-01 08:21:01 +03:00
Denis Zharkov
303c756302 Refine generic signature for fields
- For vals use the same semantics as for return types
- For vars use the same semantics as for value parameters
2015-12-01 08:21:01 +03:00
Denis Zharkov
64e0af48ed Minor. Change default for needPrimitiveBoxing 2015-12-01 08:21:01 +03:00
Denis Zharkov
ddb67d6c9c Support JvmSuppressWildcards and JvmWildcard annotations
#KT-9898 Fixed
2015-12-01 08:21:00 +03:00
Denis Zharkov
6292833a69 Refine generic signature for Map.get/remove
Before this change generic signature wasn't written because of wrong
assumption about it absence in all cases where we replace generic parameter
with Object
2015-12-01 08:21:00 +03:00
Denis Zharkov
20cbceb56d Add temporary hack for wildcards in Collections
By default we would render 'MutableCollection<String>.addAll(Collection<String>)' as
'(LCollection<String>;)' (without wildcard) because String is final and
effectively it's the same as '(LCollection<? extends String>;)'.

But that's wrong signature in a sense that java.util.Collection has different
signature: '(LCollection<? extends E>)'.

Actually the problem is much wider than collections,
it concerns any Java code that uses Kotlin classes with covariant
parameters without '? extends E' wildcards.

Temporary solution is just to hardcode/enumerate builtin methods
with special signature.
2015-12-01 08:20:59 +03:00
Denis Zharkov
0255be7deb Minor. Pass callableDescriptor into writeParameter 2015-12-01 08:20:59 +03:00
Denis Zharkov
406e31f54a Change default rules for declaration-site wildcards
Mostly this commit is about skipping wildcards that are redundant in some sense.
The motivation is that they looks `long` in Java code.

There are basically two important parts: return types and value parameters.

1. For return types default behaviour is skipping all declaration-site wildcards.
The intuition behind this rule is simple: return types are basically used in subtype position
(as an argument for another call), and here everything works well in case of 'out'-variance.
For example we have 'Out<Out<T>>>' as subtype both for 'Out<Out<T>>>' and 'Out<? extends Out<? extends T>>>',
so values of such type is more flexible in contrast to `Out<? extends Out<? extends T>>>` that could be used only
for the second case.

But we have choosen to treat `in`-variance in a different way: argument itself
should be rendered without wildcard while nested arguments are rendered by the rules
described further (see second part).

For example: 'In<Out<OpenClass>>' will have generic signature 'In<Out<? extends OpenClass>>'.
If we omit all wildcards here, then value of type 'In<Out<OpenClass>>'
will be impossible to use as argument for function expecting 'In<? super Out<? extends Derived>>'
where Derived <: OpenClass (you can check it manually :]).

And this exception should not be very inconvinient because in-variance is rather rare.

2. For value parameters we decided to skip wildcards if it doesn't make obtained signature weaker
in a sense of set of acceptable arguments.

More precisely:
    a. We write wildcard for 'Out<T>' iff T ``can have subtypes ignoring nullability''
    b. We write wildcard for 'In<T>' iff T is not equal to it's class upper bound (ignoring nullability again)

Definition of ``can have subtypes ignoring nullability'' is straightforward and you can see it in commit.

 #KT-9801 Fixed
 #KT-9890 Fixed
2015-12-01 08:20:59 +03:00
Denis Zharkov
1731cb8b40 Make jvmSignature optional in WriteSignatureTest 2015-12-01 08:20:58 +03:00
Denis Zharkov
917420f332 Convert TypeMappingMode from enum to plain class with constant instances 2015-12-01 08:20:58 +03:00
Denis Zharkov
faf1e17888 Introduce TypeMappingMode.toGenericArgumentMode 2015-12-01 08:20:57 +03:00
Denis Zharkov
ef2bc28463 Minor. Rename TypeMappingMode entries 2015-12-01 08:20:57 +03:00
Denis Zharkov
d22aaf9d52 Introduce writeDeclarationSiteProjections option into TypeMappingMode 2015-12-01 08:20:57 +03:00
Denis Zharkov
d8297cd6f1 Extract, rename and konvert TypeMappingMode 2015-12-01 08:20:56 +03:00
Denis Zharkov
6cf7cd5c07 Minor. Rename VALUE -> DEFAULT 2015-12-01 08:20:56 +03:00
Denis Zharkov
8a748703c8 Simplify type mapping for builtin types 2015-12-01 08:20:55 +03:00
Ilya Gorbunov
e5dd719eec Fix warning about incompatible types. 2015-12-01 01:35:19 +03:00
Ilya Gorbunov
0ffce06356 Hide toMap with keySelector
#KT-6657
2015-12-01 01:18:46 +03:00
Ilya Gorbunov
ea60ab74a7 Replace deprecated toMap usages with toMapBy 2015-12-01 01:18:44 +03:00
Ilya Gorbunov
f107559a3c Docs: proper pluralization of 'entry' 2015-12-01 01:18:21 +03:00
Ilya Gorbunov
6ca647aecd Minor: cleanup asSequence() documentation. 2015-12-01 01:18:19 +03:00
Ilya Gorbunov
f596d9ac23 Provide asIterable also for CharSequences, Maps and Iterables.
KT-10152 Fixed
2015-12-01 01:18:18 +03:00
149 changed files with 2229 additions and 778 deletions

View File

@@ -90,7 +90,7 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
}
@Override
protected void reorderArgumentsIfNeeded(@NotNull List<? extends ArgumentAndDeclIndex> actualArgsWithDeclIndex) {
protected void reorderArgumentsIfNeeded(@NotNull List actualArgsWithDeclIndex) {
callGenerator.reorderArgumentsIfNeeded(actualArgsWithDeclIndex, valueParameterTypes);
}
}

View File

@@ -108,15 +108,13 @@ class CollectionStubMethodGenerator(
val genericSignatureInfo = overriddenMethod.getSpecialSignatureInfo()
val specialGenericSignature =
if (genericSignatureInfo != null)
genericSignatureInfo.signature
else
overriddenMethodSignature.genericsSignature
genericSignatureInfo?.replaceValueParametersIn(overriddenMethodSignature.genericsSignature)
?: overriddenMethodSignature.genericsSignature
val (asmMethod, valueParameters) =
// if remove(E) in Kotlin -> remove(Object) in Java
// so choose original signature
if (genericSignatureInfo == SpecialSignatureInfo.GENERIC_PARAMETER)
// if current method has special generic signature,
// like `Collection.remove(E): Boolean` in Kotlin, use original signature to obtain `remove(Object)`
if (genericSignatureInfo?.isObjectReplacedWithTypeParameter ?: false)
Pair(originalSignature.asmMethod, originalSignature.valueParameters)
else
Pair(overriddenMethodSignature.asmMethod, overriddenMethodSignature.valueParameters)

View File

@@ -886,7 +886,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
int modifiers = ACC_STATIC | ACC_FINAL | ACC_PUBLIC | (property.isConst() ? 0 : ACC_DEPRECATED);
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.Synthetic(DescriptorToSourceUtils.descriptorToDeclaration(property), property),
modifiers, context.getFieldName(property, false),
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType()),
type.getDescriptor(), typeMapper.mapFieldSignature(property.getType(), property),
info.defaultValue);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(property, type);
@@ -1559,7 +1559,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
protected void reorderArgumentsIfNeeded(@NotNull List<? extends ArgumentAndDeclIndex> args) {
protected void reorderArgumentsIfNeeded(@NotNull List args) {
}
}

View File

@@ -360,7 +360,7 @@ public class PropertyCodegen {
v.getSerializationBindings().put(FIELD_FOR_PROPERTY, propertyDescriptor, Pair.create(type, name));
FieldVisitor fv = builder.newField(JvmDeclarationOriginKt.OtherOrigin(element, propertyDescriptor), modifiers, name, type.getDescriptor(),
typeMapper.mapFieldSignature(jetType), defaultValue);
typeMapper.mapFieldSignature(jetType, propertyDescriptor), defaultValue);
Annotated fieldAnnotated = new AnnotatedWithFakeAnnotations(propertyDescriptor, annotations);
AnnotationCodegen.forField(fv, typeMapper).genAnnotations(fieldAnnotated, type, AnnotationUseSiteTarget.FIELD);

View File

@@ -19,16 +19,20 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.backend.common.bridges.DescriptorBasedFunctionHandle
import org.jetbrains.kotlin.backend.common.bridges.findAllReachableDeclarations
import org.jetbrains.kotlin.backend.common.bridges.findConcreteSuperDeclaration
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinWithDifferentJvmDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import java.util.*
@@ -149,12 +153,7 @@ public fun isValueArgumentForCallToMethodWithTypeCheckBarrier(
if (KtPsiUtil.deparenthesize(argumentExpression) !== element) return false
val candidateDescriptor = parentCall.getResolvedCall(bindingContext)?.candidateDescriptor as CallableMemberDescriptor?
?: return false
?: return false
if (candidateDescriptor.getSpecialSignatureInfo() == BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo.GENERIC_PARAMETER) {
return true
}
return false
return candidateDescriptor.getSpecialSignatureInfo()?.isObjectReplacedWithTypeParameter ?: false
}

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
@@ -49,3 +50,7 @@ fun generateIsCheck(
generateInstanceOfInstruction(v)
}
}
public fun SpecialSignatureInfo.replaceValueParametersIn(sourceSignature: String?): String?
= valueParametersSignature?.let { sourceSignature?.replace("^\\(.*\\)".toRegex(), "($it)") }

View File

@@ -778,7 +778,7 @@ public class InlineCodegen extends CallGenerator {
@Override
public void reorderArgumentsIfNeeded(
@NotNull List<? extends ArgumentAndDeclIndex> actualArgsWithDeclIndex, @NotNull List<? extends Type> valueParameterTypes
@NotNull List actualArgsWithDeclIndex, @NotNull List valueParameterTypes
) {
}

View File

@@ -75,6 +75,7 @@ public class InlineCodegenUtil {
public static final String INLINE_MARKER_FINALLY_END = "finallyEnd";
public static final String INLINE_TRANSFORMATION_SUFFIX = "$inlined";
public static final String INLINE_FUN_THIS_0_SUFFIX = "$inline_fun";
public static final String INLINE_FUN_VAR_SUFFIX = "$iv";
@Nullable
public static SMAPAndMethodNode getMethodNode(

View File

@@ -97,10 +97,6 @@ public class LocalVarRemapper {
//add entries only for shifted vars
if (SHIFT == info.status) {
int newIndex = ((StackValue.Local) info.value).index;
if (newIndex != 0 && "this".equals(name)) {
/*skip additional this for now*/
return;
}
mv.visitLocalVariable(name, desc, signature, start, end, newIndex);
}
}

View File

@@ -353,7 +353,9 @@ public class MethodInliner {
@NotNull String name, @NotNull String desc, String signature, @NotNull Label start, @NotNull Label end, int index
) {
if (isInliningLambda || InlineCodegenUtil.GENERATE_SMAP) {
super.visitLocalVariable(name, desc, signature, start, end, getNewIndex(index));
String varSuffix = inliningContext.isRoot() && !InlineCodegenUtil.isFakeLocalVariableForInline(name) ? INLINE_FUN_VAR_SUFFIX : "";
String varName = !varSuffix.isEmpty() && name.equals("this") ? name + "_" : name;
super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index));
}
}
};

View File

@@ -112,40 +112,6 @@ public class JetTypeMapper {
return bindingContext;
}
private enum JetTypeMapperMode {
/**
* foo.Bar is mapped to Lfoo/Bar;
*/
IMPL,
/**
* kotlin.Int is mapped to I
*/
VALUE,
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
*/
TYPE_PARAMETER,
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
* No projections allowed in immediate arguments
*/
SUPER_TYPE,
/**
* kotlin.reflect.KClass mapped to java.lang.Class
* Other types mapped as VALUE
*/
VALUE_FOR_ANNOTATION,
/**
* kotlin.reflect.KClass mapped to java.lang.Class
* Other types mapped as TYPE_PARAMETER
*/
TYPE_PARAMETER_FOR_ANNOTATION;
boolean isForAnnotation() {
return this == VALUE_FOR_ANNOTATION || this == TYPE_PARAMETER_FOR_ANNOTATION;
}
}
@NotNull
public Type mapOwner(@NotNull DeclarationDescriptor descriptor) {
return mapOwner(descriptor, true);
@@ -355,42 +321,53 @@ public class JetTypeMapper {
return Type.VOID_TYPE;
}
else if (descriptor instanceof FunctionDescriptor && forceBoxedReturnType((FunctionDescriptor) descriptor)) {
// TYPE_PARAMETER is a hack to automatically box the return type
// GENERIC_TYPE is a hack to automatically box the return type
//noinspection ConstantConditions
return mapType(descriptor.getReturnType(), sw, JetTypeMapperMode.TYPE_PARAMETER);
}
else if (DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration())) {
//noinspection ConstantConditions
return mapType(descriptor.getReturnType(), sw, JetTypeMapperMode.VALUE_FOR_ANNOTATION);
}
else {
return mapType(returnType, sw, JetTypeMapperMode.VALUE, Variance.OUT_VARIANCE);
return mapType(descriptor.getReturnType(), sw, TypeMappingMode.GENERIC_ARGUMENT);
}
return mapReturnType(descriptor, sw, returnType);
}
@NotNull
private Type mapType(@NotNull KotlinType jetType, @NotNull JetTypeMapperMode mode) {
private Type mapReturnType(@NotNull CallableDescriptor descriptor, @Nullable BothSignatureWriter sw, @NotNull KotlinType returnType) {
boolean isAnnotationMethod = DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration());
TypeMappingMode typeMappingModeFromAnnotation =
TypeMappingUtil.extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod);
if (typeMappingModeFromAnnotation != null) {
return mapType(returnType, sw, typeMappingModeFromAnnotation);
}
TypeMappingMode mappingMode = TypeMappingMode.getOptimalModeForReturnType(
returnType,
/* isAnnotationMethod = */ isAnnotationMethod);
return mapType(returnType, sw, mappingMode);
}
@NotNull
private Type mapType(@NotNull KotlinType jetType, @NotNull TypeMappingMode mode) {
return mapType(jetType, null, mode);
}
@NotNull
public Type mapSupertype(@NotNull KotlinType jetType, @Nullable BothSignatureWriter signatureVisitor) {
return mapType(jetType, signatureVisitor, JetTypeMapperMode.SUPER_TYPE);
return mapType(jetType, signatureVisitor, TypeMappingMode.SUPER_TYPE);
}
@NotNull
public Type mapTypeParameter(@NotNull KotlinType jetType, @Nullable BothSignatureWriter signatureVisitor) {
return mapType(jetType, signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER);
return mapType(jetType, signatureVisitor, TypeMappingMode.GENERIC_ARGUMENT);
}
@NotNull
public Type mapClass(@NotNull ClassifierDescriptor classifier) {
return mapType(classifier.getDefaultType(), null, JetTypeMapperMode.IMPL);
return mapType(classifier.getDefaultType(), null, TypeMappingMode.DEFAULT);
}
@NotNull
public Type mapType(@NotNull KotlinType jetType) {
return mapType(jetType, null, JetTypeMapperMode.VALUE);
return mapType(jetType, null, TypeMappingMode.DEFAULT);
}
@NotNull
@@ -403,7 +380,7 @@ public class JetTypeMapper {
public JvmMethodSignature mapAnnotationParameterSignature(@NotNull PropertyDescriptor descriptor) {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD);
sw.writeReturnType();
mapType(descriptor.getType(), sw, JetTypeMapperMode.VALUE_FOR_ANNOTATION);
mapType(descriptor.getType(), sw, TypeMappingMode.VALUE_FOR_ANNOTATION);
sw.writeReturnTypeEnd();
return sw.makeJvmMethodSignature(descriptor.getName().asString(), false);
}
@@ -413,37 +390,18 @@ public class JetTypeMapper {
return mapType(descriptor.getDefaultType());
}
@NotNull
private Type mapType(@NotNull KotlinType jetType, @Nullable BothSignatureWriter signatureVisitor, @NotNull JetTypeMapperMode mode) {
return mapType(jetType, signatureVisitor, mode, Variance.INVARIANT);
}
@NotNull
private Type mapType(
@NotNull KotlinType jetType,
@Nullable BothSignatureWriter signatureVisitor,
@NotNull JetTypeMapperMode kind,
@NotNull Variance howThisTypeIsUsed
@NotNull TypeMappingMode mode
) {
Type known = mapBuiltinType(jetType);
Type builtinType = mapBuiltinType(jetType);
boolean projectionsAllowed = kind != JetTypeMapperMode.SUPER_TYPE;
if (known != null) {
if (kind == JetTypeMapperMode.VALUE || kind == JetTypeMapperMode.VALUE_FOR_ANNOTATION) {
return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed);
}
else if (kind == JetTypeMapperMode.TYPE_PARAMETER || kind == JetTypeMapperMode.SUPER_TYPE ||
kind == JetTypeMapperMode.TYPE_PARAMETER_FOR_ANNOTATION) {
return mapKnownAsmType(jetType, boxType(known), signatureVisitor, howThisTypeIsUsed, projectionsAllowed);
}
else if (kind == JetTypeMapperMode.IMPL) {
// TODO: enable and fix tests
//throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType);
return mapKnownAsmType(jetType, known, signatureVisitor, howThisTypeIsUsed);
}
else {
throw new IllegalStateException("unknown kind: " + kind);
}
if (builtinType != null) {
Type asmType = mode.getNeedPrimitiveBoxing() ? boxType(builtinType) : builtinType;
writeGenericType(jetType, asmType, signatureVisitor, mode);
return asmType;
}
TypeConstructor constructor = jetType.getConstructor();
@@ -484,13 +442,10 @@ public class JetTypeMapper {
}
}
else {
arrayElementType = boxType(mapType(memberType, kind));
arrayElementType = boxType(mapType(memberType, mode));
if (signatureVisitor != null) {
signatureVisitor.writeArrayType();
JetTypeMapperMode newMode = kind.isForAnnotation() ?
JetTypeMapperMode.TYPE_PARAMETER_FOR_ANNOTATION :
JetTypeMapperMode.TYPE_PARAMETER;
mapType(memberType, signatureVisitor, newMode, memberProjection.getProjectionKind());
mapType(memberType, signatureVisitor, mode.toGenericArgumentMode(memberProjection.getProjectionKind()));
signatureVisitor.writeArrayEnd();
}
}
@@ -499,15 +454,15 @@ public class JetTypeMapper {
}
if (descriptor instanceof ClassDescriptor) {
Type asmType = kind.isForAnnotation() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
Type asmType = mode.isForAnnotationParameter() && KotlinBuiltIns.isKClass((ClassDescriptor) descriptor) ?
AsmTypes.JAVA_CLASS_TYPE :
computeAsmType((ClassDescriptor) descriptor.getOriginal());
writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, projectionsAllowed);
writeGenericType(jetType, asmType, signatureVisitor, mode);
return asmType;
}
if (descriptor instanceof TypeParameterDescriptor) {
Type type = mapType(getRepresentativeUpperBound((TypeParameterDescriptor) descriptor), kind);
Type type = mapType(getRepresentativeUpperBound((TypeParameterDescriptor) descriptor), mode);
if (signatureVisitor != null) {
signatureVisitor.writeTypeVariable(descriptor.getName(), type);
}
@@ -620,11 +575,10 @@ public class JetTypeMapper {
}
private void writeGenericType(
BothSignatureWriter signatureVisitor,
Type asmType,
KotlinType type,
Variance howThisTypeIsUsed,
boolean projectionsAllowed
@NotNull KotlinType type,
@NotNull Type asmType,
@Nullable BothSignatureWriter signatureVisitor,
@NotNull TypeMappingMode mode
) {
if (signatureVisitor != null) {
if (hasNothingInArguments(type) || type.getArguments().isEmpty()) {
@@ -650,17 +604,14 @@ public class JetTypeMapper {
writeGenericArguments(
signatureVisitor,
outermostInnerType.getArguments(), outermostClass.getDeclaredTypeParameters(),
howThisTypeIsUsed, projectionsAllowed);
outermostInnerType.getArguments(), outermostClass.getDeclaredTypeParameters(), mode);
for (PossiblyInnerType innerPart : innerTypesAsList.subList(1, innerTypesAsList.size())) {
ClassDescriptor classDescriptor = innerPart.getClassDescriptor();
signatureVisitor.writeInnerClass(getJvmShortName(classDescriptor));
writeGenericArguments(
signatureVisitor, innerPart.getArguments(),
classDescriptor.getDeclaredTypeParameters(),
howThisTypeIsUsed, projectionsAllowed
);
classDescriptor.getDeclaredTypeParameters(), mode);
}
signatureVisitor.writeClassEnd();
@@ -678,30 +629,28 @@ public class JetTypeMapper {
}
private void writeGenericArguments(
BothSignatureWriter signatureVisitor,
List<? extends TypeProjection> arguments,
List<? extends TypeParameterDescriptor> parameters,
Variance howThisTypeIsUsed,
boolean projectionsAllowed
@NotNull BothSignatureWriter signatureVisitor,
@NotNull List<? extends TypeProjection> arguments,
@NotNull List<? extends TypeParameterDescriptor> parameters,
@NotNull TypeMappingMode mode
) {
for (Pair<? extends TypeParameterDescriptor, ? extends TypeProjection> item : CollectionsKt.zip(parameters, arguments)) {
TypeParameterDescriptor parameter = item.getFirst();
TypeProjection argument = item.getSecond();
if (projectionsAllowed && argument.isStarProjection()) {
if (argument.isStarProjection()) {
signatureVisitor.writeUnboundedWildcard();
}
else {
Variance projectionKind = projectionsAllowed
? getEffectiveVariance(
parameter.getVariance(),
argument.getProjectionKind(),
howThisTypeIsUsed
)
: Variance.INVARIANT;
TypeMappingMode argumentMode = TypeMappingUtil.updateArgumentModeFromAnnotations(mode, argument.getType());
Variance projectionKind = getVarianceForWildcard(parameter, argument, argumentMode);
signatureVisitor.writeTypeArgument(projectionKind);
mapType(argument.getType(), signatureVisitor, JetTypeMapperMode.TYPE_PARAMETER);
mapType(argument.getType(), signatureVisitor,
argumentMode.toGenericArgumentMode(
TypeMappingUtil.getEffectiveVariance(parameter.getVariance(), argument.getProjectionKind())));
signatureVisitor.writeTypeArgumentEnd();
}
}
@@ -725,14 +674,34 @@ public class JetTypeMapper {
});
}
private static Variance getEffectiveVariance(Variance parameterVariance, Variance projectionKind, Variance howThisTypeIsUsed) {
// Return type must not contain wildcards
if (howThisTypeIsUsed == Variance.OUT_VARIANCE) return projectionKind;
@NotNull
private static Variance getVarianceForWildcard(
@NotNull TypeParameterDescriptor parameter,
@NotNull TypeProjection projection,
@NotNull TypeMappingMode mode
) {
Variance projectionKind = projection.getProjectionKind();
if (mode.getSkipDeclarationSiteWildcards() && projectionKind == Variance.INVARIANT) {
return Variance.INVARIANT;
}
Variance parameterVariance = parameter.getVariance();
if (parameterVariance == Variance.INVARIANT) {
return projectionKind;
}
if (projectionKind == Variance.INVARIANT) {
if (mode.getSkipDeclarationSiteWildcardsIfPossible() && !projection.isStarProjection()) {
if (parameterVariance == Variance.OUT_VARIANCE && TypeMappingUtil.isMostPreciseCovariantArgument(projection.getType())){
return Variance.INVARIANT;
}
if (parameterVariance == Variance.IN_VARIANCE
&& TypeMappingUtil.isMostPreciseContravariantArgument(projection.getType(), parameter)) {
return Variance.INVARIANT;
}
}
return parameterVariance;
}
if (parameterVariance == projectionKind) {
@@ -744,33 +713,6 @@ public class JetTypeMapper {
return Variance.OUT_VARIANCE;
}
private Type mapKnownAsmType(
KotlinType jetType,
Type asmType,
@Nullable BothSignatureWriter signatureVisitor,
@NotNull Variance howThisTypeIsUsed
) {
return mapKnownAsmType(jetType, asmType, signatureVisitor, howThisTypeIsUsed, true);
}
private Type mapKnownAsmType(
KotlinType jetType,
Type asmType,
@Nullable BothSignatureWriter signatureVisitor,
@NotNull Variance howThisTypeIsUsed,
boolean allowProjections
) {
if (signatureVisitor != null) {
if (jetType.getArguments().isEmpty()) {
signatureVisitor.writeAsmType(asmType);
}
else {
writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, allowProjections);
}
}
return asmType;
}
@NotNull
public CallableMethod mapToCallableMethod(@NotNull FunctionDescriptor descriptor, boolean superCall) {
if (descriptor instanceof ConstructorDescriptor) {
@@ -1041,7 +983,7 @@ public class JetTypeMapper {
writeAdditionalConstructorParameters((ConstructorDescriptor) f, sw);
for (ValueParameterDescriptor parameter : valueParameters) {
writeParameter(sw, parameter.getType());
writeParameter(sw, parameter.getType(), f);
}
if (f instanceof AccessorForConstructorDescriptor) {
@@ -1058,12 +1000,12 @@ public class JetTypeMapper {
ReceiverParameterDescriptor receiverParameter = f.getExtensionReceiverParameter();
if (receiverParameter != null) {
writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.getType());
writeParameter(sw, JvmMethodParameterKind.RECEIVER, receiverParameter.getType(), f);
}
for (ValueParameterDescriptor parameter : valueParameters) {
if (writeCustomParameter(f, parameter, sw)) continue;
writeParameter(sw, parameter.getType());
writeParameter(sw, parameter.getType(), f);
}
sw.writeReturnType();
@@ -1077,8 +1019,9 @@ public class JetTypeMapper {
SpecialSignatureInfo specialSignatureInfo = BuiltinMethodsWithSpecialGenericSignature.getSpecialSignatureInfo(f);
if (specialSignatureInfo != null) {
return new JvmMethodSignature(
signature.getAsmMethod(), specialSignatureInfo.getSignature(), signature.getValueParameters());
String newGenericSignature = CodegenUtilKt.replaceValueParametersIn(
specialSignatureInfo, signature.getGenericsSignature());
return new JvmMethodSignature(signature.getAsmMethod(), newGenericSignature, signature.getValueParameters());
}
}
@@ -1096,7 +1039,7 @@ public class JetTypeMapper {
if (SpecialBuiltinMembers.isFromJavaOrBuiltins(f)) return false;
if (overridden.getName().asString().equals("remove") && mapType(parameter.getType()).getSort() == Type.INT) {
writeParameter(sw, TypeUtils.makeNullable(parameter.getType()));
writeParameter(sw, TypeUtils.makeNullable(parameter.getType()), f);
return true;
}
@@ -1169,9 +1112,16 @@ public class JetTypeMapper {
}
@Nullable
public String mapFieldSignature(@NotNull KotlinType backingFieldType) {
public String mapFieldSignature(@NotNull KotlinType backingFieldType, @NotNull PropertyDescriptor propertyDescriptor) {
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.TYPE);
mapType(backingFieldType, sw, JetTypeMapperMode.VALUE);
if (!propertyDescriptor.isVar()) {
mapReturnType(propertyDescriptor, sw, backingFieldType);
}
else {
writeParameterType(sw, backingFieldType, propertyDescriptor);
}
return sw.makeJavaGenericSignature();
}
@@ -1189,7 +1139,7 @@ public class JetTypeMapper {
}
else return;
writeParameter(sw, JvmMethodParameterKind.THIS, thisType.getDefaultType());
writeParameter(sw, JvmMethodParameterKind.THIS, thisType.getDefaultType(), descriptor);
}
@NotNull
@@ -1223,7 +1173,7 @@ public class JetTypeMapper {
for (KotlinType jetType : typeParameterDescriptor.getUpperBounds()) {
if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
if (!isJvmInterface(jetType)) {
mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
break classBound;
}
}
@@ -1241,13 +1191,13 @@ public class JetTypeMapper {
if (classifier instanceof ClassDescriptor) {
if (isJvmInterface(jetType)) {
sw.writeInterfaceBound();
mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
sw.writeInterfaceBoundEnd();
}
}
else if (classifier instanceof TypeParameterDescriptor) {
sw.writeInterfaceBound();
mapType(jetType, sw, JetTypeMapperMode.TYPE_PARAMETER);
mapType(jetType, sw, TypeMappingMode.GENERIC_ARGUMENT);
sw.writeInterfaceBoundEnd();
}
else {
@@ -1256,16 +1206,50 @@ public class JetTypeMapper {
}
}
private void writeParameter(@NotNull BothSignatureWriter sw, @NotNull KotlinType type) {
writeParameter(sw, JvmMethodParameterKind.VALUE, type);
private void writeParameter(
@NotNull BothSignatureWriter sw,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
) {
writeParameter(sw, JvmMethodParameterKind.VALUE, type, callableDescriptor);
}
private void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull KotlinType type) {
private void writeParameter(
@NotNull BothSignatureWriter sw,
@NotNull JvmMethodParameterKind kind,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
) {
sw.writeParameterType(kind);
mapType(type, sw, JetTypeMapperMode.VALUE);
writeParameterType(sw, type, callableDescriptor);
sw.writeParameterTypeEnd();
}
private void writeParameterType(
@NotNull BothSignatureWriter sw,
@NotNull KotlinType type,
@Nullable CallableDescriptor callableDescriptor
) {
TypeMappingMode typeMappingMode;
TypeMappingMode typeMappingModeFromAnnotation =
TypeMappingUtil.extractTypeMappingModeFromAnnotation(callableDescriptor, type, /* isForAnnotationParameter = */ false);
if (typeMappingModeFromAnnotation != null) {
typeMappingMode = typeMappingModeFromAnnotation;
}
else if (TypeMappingUtil.isMethodWithDeclarationSiteWildcards(callableDescriptor) && !type.getArguments().isEmpty()) {
typeMappingMode = TypeMappingMode.GENERIC_ARGUMENT; // Render all wildcards
}
else {
typeMappingMode = TypeMappingMode.getOptimalModeForValueParameter(type);
}
mapType(type, sw, typeMappingMode);
}
private static void writeParameter(@NotNull BothSignatureWriter sw, @NotNull JvmMethodParameterKind kind, @NotNull Type type) {
sw.writeParameterType(kind);
sw.writeAsmType(type);
@@ -1277,18 +1261,20 @@ public class JetTypeMapper {
ClassDescriptor captureThis = getDispatchReceiverParameterForConstructorCall(descriptor, closure);
if (captureThis != null) {
writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType());
writeParameter(sw, JvmMethodParameterKind.OUTER, captureThis.getDefaultType(), descriptor);
}
KotlinType captureReceiverType = closure != null ? closure.getCaptureReceiverType() : null;
if (captureReceiverType != null) {
writeParameter(sw, JvmMethodParameterKind.RECEIVER, captureReceiverType);
writeParameter(sw, JvmMethodParameterKind.RECEIVER, captureReceiverType, descriptor);
}
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) {
writeParameter(sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType());
writeParameter(sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getIntType());
writeParameter(
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getStringType(), descriptor);
writeParameter(
sw, JvmMethodParameterKind.ENUM_NAME_OR_ORDINAL, DescriptorUtilsKt.getBuiltIns(descriptor).getIntType(), descriptor);
}
if (closure == null) return;
@@ -1384,11 +1370,11 @@ public class JetTypeMapper {
sw.writeParametersStart();
for (ScriptDescriptor importedScript : importedScripts) {
writeParameter(sw, importedScript.getDefaultType());
writeParameter(sw, importedScript.getDefaultType(), /* callableDescriptor = */ null);
}
for (ValueParameterDescriptor valueParameter : script.getUnsubstitutedPrimaryConstructor().getValueParameters()) {
writeParameter(sw, valueParameter.getType());
writeParameter(sw, valueParameter.getType(), /* callableDescriptor = */ null);
}
writeVoidReturn(sw);

View File

@@ -0,0 +1,112 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.state
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
internal class TypeMappingMode private constructor(
val needPrimitiveBoxing: Boolean = true,
val isForAnnotationParameter: Boolean = false,
// Here DeclarationSiteWildcards means wildcard generated because of declaration-site variance
val skipDeclarationSiteWildcards: Boolean = false,
val skipDeclarationSiteWildcardsIfPossible: Boolean = false,
private val genericArgumentMode: TypeMappingMode? = null,
private val genericContravariantArgumentMode: TypeMappingMode? = genericArgumentMode
) {
companion object {
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
*/
@JvmField
val GENERIC_ARGUMENT = TypeMappingMode()
/**
* kotlin.Int is mapped to I
*/
@JvmField
val DEFAULT = TypeMappingMode(genericArgumentMode = GENERIC_ARGUMENT, needPrimitiveBoxing = false)
/**
* kotlin.Int is mapped to Ljava/lang/Integer;
* No projections allowed in immediate arguments
*/
@JvmField
val SUPER_TYPE = TypeMappingMode(skipDeclarationSiteWildcards = true, genericArgumentMode = GENERIC_ARGUMENT)
/**
* kotlin.reflect.KClass mapped to java.lang.Class
* Other types mapped as DEFAULT
*/
@JvmField
val VALUE_FOR_ANNOTATION = TypeMappingMode(
isForAnnotationParameter = true,
needPrimitiveBoxing = false,
genericArgumentMode = TypeMappingMode(isForAnnotationParameter = true, genericArgumentMode = GENERIC_ARGUMENT))
@JvmStatic
fun getOptimalModeForValueParameter(
type: KotlinType
) = getOptimalModeForSignaturePart(type, isForAnnotationParameter = false, canBeUsedInSupertypePosition = true)
@JvmStatic
fun getOptimalModeForReturnType(
type: KotlinType,
isAnnotationMethod: Boolean
) = getOptimalModeForSignaturePart(type, isForAnnotationParameter = isAnnotationMethod, canBeUsedInSupertypePosition = false)
private fun getOptimalModeForSignaturePart(
type: KotlinType,
isForAnnotationParameter: Boolean,
canBeUsedInSupertypePosition: Boolean
): TypeMappingMode {
if (type.arguments.isEmpty()) return DEFAULT
val contravariantArgumentMode =
if (!canBeUsedInSupertypePosition)
TypeMappingMode(
isForAnnotationParameter = isForAnnotationParameter,
skipDeclarationSiteWildcards = false,
skipDeclarationSiteWildcardsIfPossible = true)
else
null
return TypeMappingMode(
isForAnnotationParameter = isForAnnotationParameter,
skipDeclarationSiteWildcards = !canBeUsedInSupertypePosition,
skipDeclarationSiteWildcardsIfPossible = true,
genericContravariantArgumentMode = contravariantArgumentMode)
}
@JvmStatic
fun createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards: Boolean,
isForAnnotationParameter: Boolean,
fallbackMode: TypeMappingMode? = null
) = TypeMappingMode(
isForAnnotationParameter = isForAnnotationParameter,
skipDeclarationSiteWildcards = skipDeclarationSiteWildcards,
genericArgumentMode = fallbackMode)
}
fun toGenericArgumentMode(effectiveVariance: Variance): TypeMappingMode =
when (effectiveVariance) {
Variance.IN_VARIANCE -> genericContravariantArgumentMode ?: this
else -> genericArgumentMode ?: this
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:JvmName("TypeMappingUtil")
package org.jetbrains.kotlin.codegen.state
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
fun KotlinType.isMostPreciseContravariantArgument(parameter: TypeParameterDescriptor): Boolean =
// TODO: probably class upper bound should be used
KotlinBuiltIns.isAnyOrNullableAny(this)
fun KotlinType.isMostPreciseCovariantArgument(): Boolean = !canHaveSubtypesIgnoringNullability()
private fun KotlinType.canHaveSubtypesIgnoringNullability(): Boolean {
val constructor = constructor
val descriptor = constructor.declarationDescriptor
when (descriptor) {
is TypeParameterDescriptor -> return true
is ClassDescriptor -> if (descriptor.modality.isOverridable) return true
}
for ((parameter, argument) in constructor.parameters.zip(arguments)) {
if (argument.isStarProjection) return true
val projectionKind = argument.projectionKind
val type = argument.type
val effectiveVariance = getEffectiveVariance(parameter.variance, projectionKind)
if (effectiveVariance == Variance.OUT_VARIANCE && !type.isMostPreciseCovariantArgument()) return true
if (effectiveVariance == Variance.IN_VARIANCE && !type.isMostPreciseContravariantArgument(parameter)) return true
}
return false
}
public fun getEffectiveVariance(parameterVariance: Variance, projectionKind: Variance): Variance {
if (parameterVariance === Variance.INVARIANT) {
return projectionKind
}
if (projectionKind === Variance.INVARIANT) {
return parameterVariance
}
if (parameterVariance === projectionKind) {
return parameterVariance
}
// In<out X> = In<*>
// Out<in X> = Out<*>
return Variance.OUT_VARIANCE
}
val CallableDescriptor?.isMethodWithDeclarationSiteWildcards: Boolean
get() {
if (this !is CallableMemberDescriptor) return false
return firstOverridden {
METHODS_WITH_DECLARATION_SITE_WILDCARDS.containsRaw(it.propertyIfAccessor.fqNameOrNull())
} != null
}
private val METHODS_WITH_DECLARATION_SITE_WILDCARDS = setOf(
FqName("kotlin.MutableCollection.addAll"),
FqName("kotlin.MutableList.addAll"),
FqName("kotlin.MutableMap.putAll")
)
internal fun TypeMappingMode.updateArgumentModeFromAnnotations(type: KotlinType): TypeMappingMode {
type.suppressWildcardsMode()?.let {
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards = it, isForAnnotationParameter = isForAnnotationParameter)
}
if (type.annotations.hasAnnotation(JVM_WILDCARD_ANNOTATION_FQ_NAME)) {
return TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards = false, isForAnnotationParameter = isForAnnotationParameter, fallbackMode = this)
}
return this
}
internal fun extractTypeMappingModeFromAnnotation(
callableDescriptor: CallableDescriptor?,
outerType: KotlinType,
isForAnnotationParameter: Boolean
): TypeMappingMode? =
(outerType.suppressWildcardsMode() ?: callableDescriptor?.suppressWildcardsMode())?.let {
if (outerType.arguments.isNotEmpty())
TypeMappingMode.createWithConstantDeclarationSiteWildcardsMode(
skipDeclarationSiteWildcards = it, isForAnnotationParameter = isForAnnotationParameter)
else
TypeMappingMode.DEFAULT
}
private fun DeclarationDescriptor.suppressWildcardsMode(): Boolean? =
parentsWithSelf.mapNotNull {
it.annotations.findAnnotation(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME)
}.firstOrNull().suppressWildcardsMode()
private fun KotlinType.suppressWildcardsMode(): Boolean? =
annotations.findAnnotation(JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME).suppressWildcardsMode()
private fun AnnotationDescriptor?.suppressWildcardsMode(): Boolean? {
return (this ?: return null).allValueArguments.values.firstOrNull()?.value as? Boolean ?: true
}
private val JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSuppressWildcards")
private val JVM_WILDCARD_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmWildcard")

View File

@@ -47,7 +47,7 @@ interface Conditional {
companion object {
val ANNOTATIONS: Map<String, Parser> = listOf<Parser>(JvmVersion, JsVersion, TargetName).toMap { it.name }
val ANNOTATIONS: Map<String, Parser> = listOf<Parser>(JvmVersion, JsVersion, TargetName).toMapBy { it.name }
}
}

View File

@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
import java.util.*
public class JvmPlatformParameters(
public val moduleByJavaClass: (JavaClass) -> ModuleInfo
public val moduleByJavaClass: (JavaClass) -> ModuleInfo?
) : PlatformAnalysisParameters
@@ -68,7 +68,10 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
// We don't have full control over idea resolve api so we allow for a situation which should not happen in Kotlin.
// For example, type in a java library can reference a class declared in a source root (is valid but rare case)
// Providing a fallback strategy in this case can hide future problems, so we should at least log to be able to diagnose those
val resolverForReferencedModule = resolverForProject.tryGetResolverForModule(referencedClassModule as M)
@Suppress("UNCHECKED_CAST")
val resolverForReferencedModule = referencedClassModule?.let { resolverForProject.tryGetResolverForModule(it as M) }
val resolverForModule = resolverForReferencedModule ?: run {
LOG.warn("Java referenced $referencedClassModule from $moduleInfo\nReferenced class was: $javaClass\n")
// in case referenced class lies outside of our resolver, resolve the class as if it is inside our module

View File

@@ -126,6 +126,8 @@ public class JetFlowInformationProvider {
markUnusedExpressions();
markIfWithoutElse();
markWhenWithoutElse();
}
@@ -692,6 +694,28 @@ public class JetFlowInformationProvider {
);
}
public void markIfWithoutElse() {
PseudocodeTraverserKt.traverse(
pseudocode, FORWARD, new JetFlowInformationProvider.FunctionVoid1<Instruction>() {
@Override
public void execute(@NotNull Instruction instruction) {
PseudoValue value = instruction instanceof InstructionWithValue
? ((InstructionWithValue) instruction).getOutputValue()
: null;
for (KtElement element : instruction.getOwner().getValueElements(value)) {
if (!(element instanceof KtIfExpression)) continue;
KtIfExpression ifExpression = (KtIfExpression) element;
if (ifExpression.getThen() != null && ifExpression.getElse() != null) continue;
if (BindingContextUtilsKt.isUsedAsExpression(ifExpression, trace.getBindingContext())) {
trace.report(INVALID_IF_AS_EXPRESSION.on(ifExpression));
}
}
}
}
);
}
public void markWhenWithoutElse() {
PseudocodeTraverserKt.traverse(
pseudocode, FORWARD, new JetFlowInformationProvider.FunctionVoid1<Instruction>() {

View File

@@ -48,12 +48,7 @@ public final class WhenChecker {
}
public static boolean mustHaveElse(@NotNull KtWhenExpression expression, @NotNull BindingTrace trace) {
KotlinType expectedType = trace.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expression);
boolean isUnit = expectedType != null && KotlinBuiltIns.isUnit(expectedType);
// Some "statements" are actually expressions returned from lambdas, their expected types are non-null
boolean isStatement = BindingContextUtilsKt.isUsedAsStatement(expression, trace.getBindingContext()) && expectedType == null;
return !isUnit && !isStatement && !isWhenExhaustive(expression, trace);
return !BindingContextUtilsKt.isUsedAsStatement(expression, trace.getBindingContext()) && !isWhenExhaustive(expression, trace);
}
public static boolean isWhenByEnum(@NotNull KtWhenExpression expression, @NotNull BindingContext context) {

View File

@@ -416,7 +416,7 @@ public class DefaultErrorMessages {
MAP.put(ELSE_MISPLACED_IN_WHEN, "'else' entry must be the last one in a when-expression");
MAP.put(COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT, "Deprecated syntax. Use '||' instead of commas in when-condition for 'when' without argument");
MAP.put(NO_ELSE_IN_WHEN, "'when' expression must contain 'else' branch");
MAP.put(NO_ELSE_IN_WHEN, "'when' expression must be exhaustive or contain an 'else' branch");
MAP.put(NON_EXHAUSTIVE_WHEN, "'when' expression contains only some variants and no 'else' branch");
MAP.put(TYPE_MISMATCH_IN_RANGE, "Type mismatch: incompatible types of range and element checked in it");

View File

@@ -157,7 +157,7 @@ public class TabledDescriptorRenderer {
@NotNull
public Renderer<KotlinType> getTypeRenderer() {
return Renderers.RENDER_TYPE;
return (Renderer<KotlinType>) Renderers.RENDER_TYPE;
}
protected void renderText(TextRenderer textRenderer, StringBuilder result) {

View File

@@ -40,9 +40,6 @@ public abstract class KtCodeFragment(
private var viewProvider = super<KtFile>.getViewProvider() as SingleRootFileViewProvider
private var imports = LinkedHashSet<String>()
private val additionalContextForLambda: PsiElement? by lazy {
this.getCopyableUserData(ADDITIONAL_CONTEXT_FOR_LAMBDA)?.invoke()
}
init {
getViewProvider().forceCachedPsi(this)
@@ -69,7 +66,7 @@ public abstract class KtCodeFragment(
override fun isValid() = true
override fun getContext() = additionalContextForLambda ?: context
override fun getContext() = context
override fun getResolveScope() = context?.getResolveScope() ?: super<KtFile>.getResolveScope()

View File

@@ -160,8 +160,8 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
@NotNull
@Override
public Collection<FqName> getSubPackagesOf(
@NotNull FqName fqName, @NotNull Function1<? super Name, ? extends Boolean> nameFilter
public Collection getSubPackagesOf(
@NotNull FqName fqName, @NotNull Function1 nameFilter
) {
LazyPackageDescriptor packageDescriptor = getPackageFragment(fqName);
if (packageDescriptor == null) {

View File

@@ -274,18 +274,12 @@ public class DataFlowAnalyzer {
@Nullable
public KotlinType checkImplicitCast(@Nullable KotlinType expressionType, @NotNull KtExpression expression, @NotNull ResolutionContext context, boolean isStatement) {
boolean isIfExpression = expression instanceof KtIfExpression;
if (expressionType != null && (context.expectedType == NO_EXPECTED_TYPE || isIfExpression)
&& context.contextDependency == INDEPENDENT && !isStatement
&& (KotlinBuiltIns.isUnit(expressionType) || KotlinBuiltIns.isAnyOrNullableAny(expressionType))
&& !DynamicTypesKt.isDynamic(expressionType)) {
if (isIfExpression && KotlinBuiltIns.isUnit(expressionType)) {
KtIfExpression ifExpression = (KtIfExpression) expression;
if (ifExpression.getThen() == null || ifExpression.getElse() == null) {
context.trace.report(INVALID_IF_AS_EXPRESSION.on((KtIfExpression) expression));
return expressionType;
}
}
else if (isIfExpression && context.expectedType != NO_EXPECTED_TYPE) {
if (expressionType != null
&& (context.expectedType == NO_EXPECTED_TYPE || isIfExpression)
&& context.contextDependency == INDEPENDENT && !isStatement
&& (KotlinBuiltIns.isUnit(expressionType) || KotlinBuiltIns.isAnyOrNullableAny(expressionType))
&& !DynamicTypesKt.isDynamic(expressionType)) {
if (isIfExpression && KotlinBuiltIns.isUnit(expressionType) || isIfExpression && context.expectedType != NO_EXPECTED_TYPE) {
return expressionType;
}
else {

View File

@@ -15,5 +15,6 @@ class A {
// VARIABLE : NAME=zzz TYPE=I INDEX=3
// VARIABLE : NAME=it TYPE=I INDEX=2
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=4
// VARIABLE : NAME=this_$iv TYPE=LA; INDEX=1
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=5
// VARIABLE : NAME=this TYPE=LA; INDEX=0

View File

@@ -20,6 +20,7 @@ class A {
// VARIABLE : NAME=zzz TYPE=I INDEX=4
// VARIABLE : NAME=l TYPE=I INDEX=3
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=5
// VARIABLE : NAME=p TYPE=I INDEX=2
// VARIABLE : NAME=this_$iv TYPE=LA; INDEX=1
// VARIABLE : NAME=p$iv TYPE=I INDEX=2
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=6
// VARIABLE : NAME=this TYPE=LA; INDEX=0

View File

@@ -15,6 +15,7 @@ class A {
// METHOD : A.foo()V
// VARIABLE : NAME=zzz TYPE=I INDEX=3
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=4
// VARIABLE : NAME=this_$iv TYPE=LA; INDEX=2
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=5
// VARIABLE : NAME=s TYPE=I INDEX=1
// VARIABLE : NAME=this TYPE=LA; INDEX=0

View File

@@ -20,9 +20,11 @@ class A {
// METHOD : A.foo()V
// VARIABLE : NAME=zz2 TYPE=I INDEX=5
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=6
// VARIABLE : NAME=this_$iv TYPE=LA; INDEX=4
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=7
// VARIABLE : NAME=z TYPE=I INDEX=3
// VARIABLE : NAME=$i$a$1 TYPE=I INDEX=8
// VARIABLE : NAME=this_$iv TYPE=LA; INDEX=2
// VARIABLE : NAME=$i$f$inlineFun TYPE=I INDEX=9
// VARIABLE : NAME=s TYPE=I INDEX=1
// VARIABLE : NAME=this TYPE=LA; INDEX=0

View File

@@ -1,9 +0,0 @@
fun box(): String {
var r = "Fail 0"
val x = 1
val y: Unit = when (x) {
1 -> { r = "OK" }
2 -> { r = "Fail 1" }
}
return r
}

View File

@@ -1,9 +0,0 @@
fun box(): String {
var r = "OK"
val x = 3
val y: Unit = when (x) {
1 -> { r = "Fail 0" }
2 -> { r = "Fail 1" }
}
return r
}

View File

@@ -1,11 +0,0 @@
var r = "Fail 0"
fun foo(x: Int) {
return when (x) {
1 -> { r = "OK" }
}
}
fun box(): String {
foo(1)
return r
}

View File

@@ -1,11 +0,0 @@
var r = "OK"
fun foo(x: Int) {
return when (x) {
1 -> { r = "Fail" }
}
}
fun box(): String {
foo(0)
return r
}

View File

@@ -0,0 +1,23 @@
public class JavaClass {
public static class C extends B {
public OutPair<String, Integer> foo() {
return super.foo();
}
public In<Object> bar() {
return super.bar();
}
}
public static String test() {
A a = new C();
if (!a.foo().getX().equals("OK")) return "fail 1";
if (!a.foo().getY().equals(123)) return "fail 2";
if (!a.bar().make("123").equals("123")) return "fail 3";
return "OK";
}
}

View File

@@ -0,0 +1,19 @@
class OutPair<out X, out Y>(val x: X, val y: Y)
class In<in Z> {
fun make(x: Z): String = x.toString()
}
@JvmSuppressWildcards(suppress = false)
interface A {
fun foo(): OutPair<CharSequence, Number>
fun bar(): In<String>
}
abstract class B : A {
override fun foo(): OutPair<String, Int> = OutPair("OK", 123)
override fun bar(): In<Any> = In()
}
fun box(): String {
return JavaClass.test();
}

View File

@@ -7,11 +7,12 @@ public abstract class AImpl {
throw UnsupportedOperationException()
}
@JvmSuppressWildcards(suppress = false)
fun addAll(elements: Collection<String>): Boolean {
throw UnsupportedOperationException()
}
fun addAll(index: Int, elements: Collection<String>): Boolean {
fun addAll(index: Int, elements: Collection<@JvmWildcard String>): Boolean {
throw UnsupportedOperationException()
}

View File

@@ -0,0 +1,13 @@
import java.util.*;
public class J {
private static class MyList<E> extends KList<E> {}
public static String foo() {
Collection<String> collection = new MyList<String>();
if (!collection.contains("ABCDE")) return "fail 1";
if (!collection.containsAll(Arrays.asList(1, 2, 3))) return "fail 2";
return "OK";
}
}

View File

@@ -0,0 +1,40 @@
open class KList<E> : List<E> {
override val size: Int
get() = throw UnsupportedOperationException()
override fun isEmpty(): Boolean {
throw UnsupportedOperationException()
}
override fun contains(o: E) = true
override fun containsAll(c: Collection<E>) = true
override fun iterator(): Iterator<E> {
throw UnsupportedOperationException()
}
override fun get(index: Int): E {
throw UnsupportedOperationException()
}
override fun indexOf(element: E): Int {
throw UnsupportedOperationException()
}
override fun lastIndexOf(element: E): Int {
throw UnsupportedOperationException()
}
override fun listIterator(): ListIterator<E> {
throw UnsupportedOperationException()
}
override fun listIterator(index: Int): ListIterator<E> {
throw UnsupportedOperationException()
}
override fun subList(fromIndex: Int, toIndex: Int): List<E> {
throw UnsupportedOperationException()
}
}
fun box() = J.foo()

View File

@@ -0,0 +1,13 @@
import java.util.*;
public class J {
private static class MyMap<K, V> extends KMap<K, V> {}
public static String foo() {
Map<String, Integer> collection = new MyMap<String, Integer>();
if (!collection.containsKey("ABCDE")) return "fail 1";
if (!collection.containsValue(1)) return "fail 2";
return "OK";
}
}

View File

@@ -0,0 +1,24 @@
open class KMap<K, V> : Map<K, V> {
override val size: Int
get() = throw UnsupportedOperationException()
override fun isEmpty(): Boolean {
throw UnsupportedOperationException()
}
override fun containsKey(key: K) = true
override fun containsValue(value: V) = true
override fun get(key: K): V? {
throw UnsupportedOperationException()
}
override val keys: Set<K>
get() = throw UnsupportedOperationException()
override val values: Collection<V>
get() = throw UnsupportedOperationException()
override val entries: Set<Map.Entry<K, V>>
get() = throw UnsupportedOperationException()
}
fun box() = J.foo()

View File

@@ -1,4 +1,4 @@
open class KList : MutableList<String> {
abstract class KList : MutableList<String> {
override val size: Int
get() = throw UnsupportedOperationException()

View File

@@ -0,0 +1,23 @@
public class JavaClass {
public static class C extends B {
public OutPair<String, Integer> foo() {
return super.foo();
}
public In<Object> bar() {
return super.bar();
}
}
public static String test() {
A a = new C();
if (!a.foo().getX().equals("OK")) return "fail 1";
if (!a.foo().getY().equals(123)) return "fail 2";
if (!a.bar().make("123").equals("123")) return "fail 3";
return "OK";
}
}

View File

@@ -0,0 +1,18 @@
class OutPair<out X, out Y>(val x: X, val y: Y)
class In<in Z> {
fun make(x: Z): String = x.toString()
}
interface A {
fun foo(): OutPair<@JvmWildcard CharSequence, @JvmSuppressWildcards(false) Number>
fun bar(): In<@JvmWildcard String>
}
abstract class B : A {
override fun foo(): OutPair<String, Int> = OutPair("OK", 123)
override fun bar(): In<Any> = In()
}
fun box(): String {
return JavaClass.test();
}

View File

@@ -58,23 +58,23 @@ fun box(): String {
val classField3 = clz.getDeclaredField("classField3");
if (classField3.getGenericType().toString() != "Zout<? extends java.lang.String>")
if (classField3.getGenericType().toString() != "Zout<java.lang.String>")
return "fail3:" + classField3.getGenericType();
val classField4 = clz.getDeclaredField("classField4");
if (classField4.getGenericType().toString() != "Zin<? super TParam>")
if (classField4.getGenericType().toString() != "Zin<TParam>")
return "fail4:" + classField4.getGenericType();
val classField5 = clz.getDeclaredField("delegateLazy\$delegate");
if (classField5.getGenericType().toString() != "kotlin.Lazy<? extends Z<TParam>>")
if (classField5.getGenericType().toString() != "kotlin.Lazy<Z<TParam>>")
return "fail5:" + classField5.getGenericType();
val classField6 = clz.getDeclaredField("delegateNotNull\$delegate");
if (classField6.getGenericType().toString() != "kotlin.properties.ReadWriteProperty<? super java.lang.Object, Z<TParam>>")
if (classField6.getGenericType().toString() != "kotlin.properties.ReadWriteProperty<java.lang.Object, Z<TParam>>")
return "fail6:" + classField6.getGenericType();

View File

@@ -0,0 +1,16 @@
interface A {
fun foo(): Collection<Any>
}
abstract class B : A {
override fun foo(): Collection<String> = null!!
}
fun box(): String {
val clazz = B::class.java
if (clazz.declaredMethods.first().genericReturnType.toString() != "java.util.Collection<java.lang.String>") return "fail 1"
if (clazz.methods.filter { it.name == "foo" }.size != 1) return "fail 2"
return "OK"
}

View File

@@ -0,0 +1,85 @@
fun idAny(x: Any) = x
fun <T> id(x: T) = x
fun idUnit(x: Unit) = x
class MList {
// MutableCollection<T>.add returns Boolean, but nobody cares
fun add(): Boolean = true
}
val mlist = MList()
fun work() {}
val xx1 = <!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>
val xx2: Unit = <!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>
val xx3 = idAny(<!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>)
val xx4 = id(<!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>)
val xx5 = idUnit(<!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>)
val xx6 = null ?: <!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>
val xx7 = "" + <!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>
val wxx1 = <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
val wxx2: Unit = <!NO_ELSE_IN_WHEN!>when<!> { true -> <!CONSTANT_EXPECTED_TYPE_MISMATCH!>42<!> }
val wxx3 = idAny(<!NO_ELSE_IN_WHEN!>when<!> { true -> 42 })
val wxx4 = id(<!NO_ELSE_IN_WHEN!>when<!> { true -> 42 })
val wxx5 = idUnit(<!NO_ELSE_IN_WHEN!>when<!> { true -> 42 })
val wxx6 = null ?: <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
val wxx7 = "" + <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
val fn1 = { if (true) <!UNUSED_EXPRESSION!>42<!> }
val fn2 = { if (true) mlist.add() }
val fn3 = { if (true) work() }
val fn4 = { <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 } }
val fn5 = { <!NO_ELSE_IN_WHEN!>when<!> { true -> mlist.add() } }
val fn6 = { when { true -> work() } }
val ufn1: () -> Unit = { if (true) <!UNUSED_EXPRESSION!>42<!> }
val ufn2: () -> Unit = { if (true) mlist.add() }
val ufn3: () -> Unit = { if (true) work() }
val ufn4: () -> Unit = { when { true -> <!UNUSED_EXPRESSION!>42<!> } }
val ufn5: () -> Unit = { when { true -> mlist.add() } }
val ufn6: () -> Unit = { when { true -> work() } }
fun f1() = <!INVALID_IF_AS_EXPRESSION!>if (true) work()<!>
fun f2() = <!INVALID_IF_AS_EXPRESSION!>if (true) mlist.add()<!>
fun f3() = <!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>
fun f4(): Unit = <!INVALID_IF_AS_EXPRESSION!>if (true) work()<!>
fun f5(): Unit = <!INVALID_IF_AS_EXPRESSION!>if (true) mlist.add()<!>
fun f6(): Unit = <!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>
fun g1() = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!><!NO_ELSE_IN_WHEN!>when<!> { true -> work() }<!>
fun g2() = <!NO_ELSE_IN_WHEN!>when<!> { true -> mlist.add() }
fun g3() = <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
fun g4(): Unit = <!NO_ELSE_IN_WHEN!>when<!> { true -> work() }
fun g5(): Unit = <!NO_ELSE_IN_WHEN!>when<!> { true -> <!TYPE_MISMATCH!>mlist.add()<!> }
fun g6(): Unit = <!NO_ELSE_IN_WHEN!>when<!> { true -> <!CONSTANT_EXPECTED_TYPE_MISMATCH!>42<!> }
fun foo1(x: String?) {
"" + <!INVALID_IF_AS_EXPRESSION!>if (true) 42<!>
w@while (true) {
x ?: if (true) break
x ?: when { true -> break@w }
}
}
fun foo2() {
if (true) {
mlist.add()
}
else if (true) {
mlist.add()
}
else if (true) {
mlist.add()
}
when {
true -> mlist.add()
else -> when {
true -> mlist.add()
else -> when {
true -> mlist.add()
}
}
}
}

View File

@@ -0,0 +1,55 @@
package
public val fn1: () -> kotlin.Unit
public val fn2: () -> kotlin.Unit
public val fn3: () -> kotlin.Unit
public val fn4: () -> kotlin.Int
public val fn5: () -> kotlin.Boolean
public val fn6: () -> kotlin.Unit
public val mlist: MList
public val ufn1: () -> kotlin.Unit
public val ufn2: () -> kotlin.Unit
public val ufn3: () -> kotlin.Unit
public val ufn4: () -> kotlin.Unit
public val ufn5: () -> kotlin.Unit
public val ufn6: () -> kotlin.Unit
public val wxx1: kotlin.Int
public val wxx2: kotlin.Unit
public val wxx3: kotlin.Any
public val wxx4: kotlin.Int
public val wxx5: kotlin.Unit
public val wxx6: kotlin.Int
public val wxx7: kotlin.String
public val xx1: kotlin.Unit
public val xx2: kotlin.Unit
public val xx3: kotlin.Any
public val xx4: kotlin.Unit
public val xx5: kotlin.Unit
public val xx6: kotlin.Unit
public val xx7: kotlin.String
public fun f1(): kotlin.Unit
public fun f2(): kotlin.Unit
public fun f3(): kotlin.Unit
public fun f4(): kotlin.Unit
public fun f5(): kotlin.Unit
public fun f6(): kotlin.Unit
public fun foo1(/*0*/ x: kotlin.String?): kotlin.Unit
public fun foo2(): kotlin.Unit
public fun g1(): kotlin.Unit
public fun g2(): kotlin.Boolean
public fun g3(): kotlin.Int
public fun g4(): kotlin.Unit
public fun g5(): kotlin.Unit
public fun g6(): kotlin.Unit
public fun </*0*/ T> id(/*0*/ x: T): T
public fun idAny(/*0*/ x: kotlin.Any): kotlin.Any
public fun idUnit(/*0*/ x: kotlin.Unit): kotlin.Unit
public fun work(): kotlin.Unit
public final class MList {
public constructor MList()
public final fun add(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}

View File

@@ -4,7 +4,7 @@ fun test(a: Boolean, b: Boolean): Int {
return if(a) {
1
} else {
<!TYPE_MISMATCH!>if (b) {
<!TYPE_MISMATCH, INVALID_IF_AS_EXPRESSION!>if (b) {
3
}<!>
}

View File

@@ -2,7 +2,7 @@ val flag = true
// type of a was checked by txt
val a/*: () -> Any*/ = l@ {
if (flag) return@l 4
<!INVALID_IF_AS_EXPRESSION!>if (flag) return@l 4<!>
}
val b/*: () -> Int */ = l@ {

View File

@@ -1,7 +1,7 @@
val flag = true
val a: () -> Int = l@ {
<!TYPE_MISMATCH!>if (flag) return@l 4<!>
<!TYPE_MISMATCH, INVALID_IF_AS_EXPRESSION!>if (flag) return@l 4<!>
}
val b: () -> Unit = l@ {
@@ -9,7 +9,7 @@ val b: () -> Unit = l@ {
}
val c: () -> Any = l@ {
if (flag) return@l 4
<!INVALID_IF_AS_EXPRESSION!>if (flag) return@l 4<!>
}
val d: () -> Int = l@ {

View File

@@ -1,5 +1,5 @@
fun foo(x: Int) {
val y: Unit = when (x) {
val y: Unit = <!NO_ELSE_IN_WHEN!>when<!> (x) {
2 -> {}
3 -> {}
}

View File

@@ -1,5 +1,5 @@
fun foo(x: Int) {
return when (x) {
return <!NO_ELSE_IN_WHEN!>when<!> (x) {
2 -> {}
3 -> {}
}

View File

@@ -0,0 +1,20 @@
fun test1() {
if (true) {
when (true) {
true -> println()
}
} else {
System.out?.println() // kotlin.Unit?
}
}
fun test2() {
val mlist = arrayListOf("")
if (true) {
when (true) {
true -> println()
}
} else {
mlist.add("") // kotlin.Boolean
}
}

View File

@@ -0,0 +1,4 @@
package
public fun test1(): kotlin.Unit
public fun test2(): kotlin.Unit

View File

@@ -3,4 +3,4 @@ class TestingKotlinCollections(val arguments: Collection<String>)
// method: TestingKotlinCollections::<init>
// jvm signature: (Ljava/util/Collection;)V
// generic signature: (Ljava/util/Collection<+Ljava/lang/String;>;)V
// generic signature: (Ljava/util/Collection<Ljava/lang/String;>;)V

View File

@@ -6,4 +6,4 @@ fun f(m: M<X, X>): M<X, X> = throw Exception()
// method: FunctionTwoTypeParametersKt::f
// jvm signature: (LM;)LM;
// generic signature: (LM<-LX;+LX;>;)LM<LX;LX;>;
// generic signature: (LM<-LX;LX;>;)LM<LX;LX;>;

View File

@@ -0,0 +1,40 @@
class Out<out T>
class In<in Z>
interface A<T, E> {
fun foo1(x: Out<T>): Out<T>
fun foo2(x: In<E>): In<E>
var prop: Out<T>
}
// method: A::foo1
// generic signature: (LOut<+TT;>;)LOut<TT;>;
// method: A::foo2
// generic signature: (LIn<-TE;>;)LIn<TE;>;
// method: A::getProp
// generic signature: ()LOut<TT;>;
// method: A::setProp
// generic signature: (LOut<+TT;>;)V
abstract class B : A<String, Any?> {
override final fun foo1(x: Out<String>): Out<String> = null!!
override final fun foo2(x: In<Any?>): In<Any?> = null!!
override final var prop: Out<String> = null!!
}
// method: B::foo1
// generic signature: (LOut<Ljava/lang/String;>;)LOut<Ljava/lang/String;>;
// method: B::foo2
// generic signature: (LIn<Ljava/lang/Object;>;)LIn<Ljava/lang/Object;>;
// method: B::getProp
// generic signature: ()LOut<Ljava/lang/String;>;
// method: B::setProp
// generic signature: (LOut<Ljava/lang/String;>;)V

View File

@@ -6,4 +6,4 @@ fun f(p: In<Out<X>>) {}
// method: InOfOutInInPositionKt::f
// jvm signature: (LIn;)V
// generic signature: (LIn<-LOut<+LX;>;>;)V
// generic signature: (LIn<-LOut<LX;>;>;)V

View File

@@ -6,4 +6,4 @@ fun f(): In<Out<X>> = throw Exception()
// method: InOfOutInOutPositionKt::f
// jvm signature: ()LIn;
// generic signature: ()LIn<LOut<+LX;>;>;
// generic signature: ()LIn<LOut<LX;>;>;

View File

@@ -0,0 +1,51 @@
class OutPair<out X, out Y>
class In<in Z>
interface A {
fun foo1(): OutPair<String, Int>
fun foo2(): OutPair<CharSequence, Int>
fun foo3(): OutPair<OutPair<CharSequence, Number>, Number>
fun foo4(): In<String>
fun foo5(): In<Any>
val prop1: OutPair<String, Int>
val prop2: OutPair<CharSequence, Int>
}
// method: A::foo1
// generic signature: ()LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;
// method: A::foo2
// generic signature: ()LOutPair<Ljava/lang/CharSequence;Ljava/lang/Integer;>;
// method: A::foo3
// generic signature: ()LOutPair<LOutPair<Ljava/lang/CharSequence;Ljava/lang/Number;>;Ljava/lang/Number;>;
// method: A::foo4
// generic signature: ()LIn<Ljava/lang/String;>;
// method: A::foo5
// generic signature: ()LIn<Ljava/lang/Object;>;
// method: A::getProp1
// generic signature: ()LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;
// method: A::getProp2
// generic signature: ()LOutPair<Ljava/lang/CharSequence;Ljava/lang/Integer;>;
abstract class B : A {
override fun foo2(): OutPair<CharSequence, Int> = null!!
override fun foo3(): OutPair<OutPair<String, Int>, Int> = null!!
override val prop2: OutPair<String, Int> = null!!
}
// method: B::foo2
// generic signature: ()LOutPair<Ljava/lang/CharSequence;Ljava/lang/Integer;>;
// method: B::foo3
// generic signature: ()LOutPair<LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;Ljava/lang/Integer;>;
// method: B::getProp2
// generic signature: ()LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;

View File

@@ -0,0 +1,58 @@
class OutPair<out X, out Y>
class In<in Z>
interface A {
fun foo1(x: OutPair<String, Int>)
fun foo2(x: OutPair<CharSequence, Int>)
fun foo3(x: In<String>)
fun foo4(x: In<Any>)
var prop1: OutPair<String, Int>
}
// method: A::foo1
// generic signature: (LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;)V
// method: A::foo2
// generic signature: (LOutPair<+Ljava/lang/CharSequence;Ljava/lang/Integer;>;)V
// method: A::foo3
// generic signature: (LIn<-Ljava/lang/String;>;)V
// method: A::foo4
// generic signature: (LIn<Ljava/lang/Object;>;)V
// method: A::getProp1
// generic signature: ()LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;
// method: A::setProp1
// generic signature: (LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;)V
abstract class B : A {
override final fun foo1(x: OutPair<String, Int>) {}
override final fun foo2(x: OutPair<CharSequence, Int>) {}
override final fun foo3(x: In<String>) {}
override final fun foo4(x: In<Any>) {}
override final var prop1: OutPair<String, Int> = null!!
}
// method: B::foo1
// generic signature: (LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;)V
// method: B::foo2
// generic signature: (LOutPair<+Ljava/lang/CharSequence;Ljava/lang/Integer;>;)V
// method: B::foo3
// generic signature: (LIn<-Ljava/lang/String;>;)V
// method: B::foo4
// generic signature: (LIn<Ljava/lang/Object;>;)V
// method: B::getProp1
// generic signature: ()LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;
// method: A::setProp1
// generic signature: (LOutPair<Ljava/lang/String;Ljava/lang/Integer;>;)V

View File

@@ -3,7 +3,7 @@ public val mutList: MutableList<String> = throw Exception()
// field: OutInFieldKt::list
// jvm signature: Ljava/util/List;
// generic signature: Ljava/util/List<+Ljava/lang/String;>;
// generic signature: Ljava/util/List<Ljava/lang/String;>;
// field: OutInFieldKt::mutList
// jvm signature: Ljava/util/List;

View File

@@ -2,4 +2,4 @@ fun f(p: List<String>) {}
// method: OutInInPositionKt::f
// jvm signature: (Ljava/util/List;)V
// generic signature: (Ljava/util/List<+Ljava/lang/String;>;)V
// generic signature: (Ljava/util/List<Ljava/lang/String;>;)V

View File

@@ -6,4 +6,4 @@ fun f(): Out<In<X>> = throw Exception()
// method: OutOfInInOutPositionKt::f
// jvm signature: ()LOut;
// generic signature: ()LOut<LIn<-LX;>;>;
// generic signature: ()LOut<LIn<LX;>;>;

View File

@@ -5,4 +5,4 @@ fun f(p: Out<Out<X>>) {}
// method: OutOfOutInInPositionKt::f
// jvm signature: (LOut;)V
// generic signature: (LOut<+LOut<+LX;>;>;)V
// generic signature: (LOut<LOut<LX;>;>;)V

View File

@@ -1,18 +1,15 @@
class Out<out T>
class X
// Why we want this to be translated to 'Out<Out<? extends X>> f()' instead of 'Out<Out<X>> f()'
// There are two instantiations of 'In' in this test: outer Out<...> and inner Out<X>
// So why do we want to put a wildcard on the inner one and not the outer?
// People don't want wildcards in return types, because they are _long_. So we try our best to remove wildcards where possible
// Not putting a wildcard on the outer occurrence is not imposing a restriction, actually it is removing one:
// anything that can be done with Out<? extends X> in Java can be done with Out<X>
// But omitting the wildcard on the inner occurrence is restrictive:
// one can add a List<String> to a List<List<? extends CharSequence>>,
// but not to a List<List<CharSequence>>,
// thus removing the wildcard would be restricting the use of the return value of the method, and we don't want do this.
// Why we want this to be translated to 'Out<Out<X>> f()' instead of 'Out<? extends Out<? extebds X>> f()'
// For return types default behaviour is skipping all declaration-site wildcards.
// The intuition behind this rule is simple: return types are basically used in subtype position
// (as an argument for another call), and here everything works well in case of 'out'-variance.
// For example we have 'Out<Out<T>>>' as subtype both for 'Out<Out<T>>>' and 'Out<? extends Out<? extends T>>>',
// so values of such type is more flexible in contrast to `Out<? extends Out<? extends T>>>` that could be used only
// for the second case.
fun f(): Out<Out<X>> = throw Exception()
// method: OutOfOutInOutPositionKt::f
// jvm signature: ()LOut;
// generic signature: ()LOut<LOut<+LX;>;>;
// generic signature: ()LOut<LOut<LX;>;>;

View File

@@ -5,4 +5,4 @@ var p: M<X> = throw Exception()
// method: PropertySetterOutKt::setP
// jvm signature: (LM;)V
// generic signature: (LM<+LX;>;)V
// generic signature: (LM<LX;>;)V

View File

@@ -0,0 +1,27 @@
class Out<out T>
class In<in R>
open class Open
@JvmSuppressWildcards(true)
fun deepOpen(x: Out<Out<Out<Open>>>) {}
// method: OnFunctionKt::deepOpen
// generic signature: (LOut<LOut<LOut<LOpen;>;>;>;)V
interface A<T> {
@JvmSuppressWildcards(true)
fun foo(): Out<T>
}
// method: A::foo
// generic signature: ()LOut<TT;>;
interface B {
@JvmSuppressWildcards(true)
fun foo(): In<Open>
}
// method: B::foo
// generic signature: ()LIn<LOpen;>;
@JvmSuppressWildcards(false)
fun bar(): Out<Open> = null!!
// method: OnFunctionKt::bar
// generic signature: ()LOut<+LOpen;>;

View File

@@ -0,0 +1,22 @@
class OutPair<out T, out E>
class Out<out F>
class In<in H>
class X
fun simpleOut(x: Out<@JvmWildcard X>) {}
// method: OnTypesKt::simpleOut
// generic signature: (LOut<+LX;>;)V
fun simpleIn(x: In<@JvmWildcard Any?>) {}
// method: OnTypesKt::simpleIn
// generic signature: (LIn<-Ljava/lang/Object;>;)V
fun falseTrueFalse(): @JvmSuppressWildcards(false) OutPair<X, @JvmSuppressWildcards OutPair<Out<X>, Out<@JvmSuppressWildcards(false) X>>> = null!!
// method: OnTypesKt::falseTrueFalse
// generic signature: ()LOutPair<+LX;LOutPair<LOut<LX;>;LOut<+LX;>;>;>;
open class Open
fun combination(): @JvmSuppressWildcards OutPair< Open, @JvmWildcard OutPair<Open, @JvmWildcard Out<Open>>> = null!!
// method: OnTypesKt::combination
// generic signature: ()LOutPair<LOpen;+LOutPair<LOpen;+LOut<LOpen;>;>;>;

View File

@@ -0,0 +1,12 @@
class Out<out T>
class In<in E>
@JvmSuppressWildcards(false)
fun foo(x: Boolean, y: Out<Int>): Int = 1
// method: PrimitiveTypesKt::foo
// generic signature: (ZLOut<+Ljava/lang/Integer;>;)I
@JvmSuppressWildcards(true)
fun bar(x: Boolean, y: In<Long>, z: @JvmSuppressWildcards(false) Long): Int = 1
// method: PrimitiveTypesKt::bar
// generic signature: (ZLIn<Ljava/lang/Long;>;J)I

View File

@@ -0,0 +1,25 @@
class Out<out T>
class OutPair<out X, out Y>
class In<in Z>
class Final
open class Open
// For value parameters we decided to skip wildcards if it doesn't make obtained signature weaker
// in a sense of set of acceptable arguments.
// More precisely:
//    a. We write wildcard for 'Out<T>' iff T ``can have subtypes ignoring nullability''
//    b. We write wildcard for 'In<T>' iff T is not equal to it's class upper bound (ignoring nullability again)
// Definition of ``can have subtypes ignoring nullability'' is straightforward and you can see it in commit.
fun openClassArgument(x: Out<Open>, y: In<Open>) {}
// method: ArgumentOverridabilityKt::openClassArgument
// generic signature: (LOut<+LOpen;>;LIn<-LOpen;>;)V
fun finalClassArgument(x: Out<Final>, y: In<Final>) {}
// method: ArgumentOverridabilityKt::finalClassArgument
// generic signature: (LOut<LFinal;>;LIn<-LFinal;>;)V
fun oneArgumentFinal(x: OutPair<Final, Open>) {}
// method: ArgumentOverridabilityKt::oneArgumentFinal
// generic signature: (LOutPair<LFinal;+LOpen;>;)V

View File

@@ -0,0 +1,23 @@
class Inv<E>
class Out<out T>
class OutPair<out Final, out Y>
class In<in Z>
class Final
open class Open
fun arrayOfOutOpen(x: Array<Out<Open>>) {}
// method: ArraysKt::arrayOfOutOpen
// generic signature: ([LOut<+LOpen;>;)V
fun arrayOfOutFinal(x: Array<Out<Final>>) {}
// method: ArraysKt::arrayOfOutFinal
// generic signature: ([LOut<LFinal;>;)V
fun outOfArrayOpen(x: Out<Array<Open>>) {}
// method: ArraysKt::outOfArrayOpen
// generic signature: (LOut<[LOpen;>;)V
fun outOfArrayOutOpen(x: Out<Array<out Open>>) {}
// method: ArraysKt::outOfArrayOutOpen
// generic signature: (LOut<+[LOpen;>;)V

View File

@@ -0,0 +1,12 @@
class Out<out T>
class In<in T : F?, F : CharSequence>
fun optimized(x: In<CharSequence, CharSequence>) {}
// method: ComplicatedInBoundsKt::optimized
// generic signature: (LIn<-Ljava/lang/CharSequence;Ljava/lang/CharSequence;>;)V
class In2<in T, F : In2<T, F>>
fun nonOptimized(x: In2<In2<*, *>, *>) {}
// method: ComplicatedInBoundsKt::nonOptimized
// generic signature: (LIn2<-LIn2<**>;*>;)V

View File

@@ -0,0 +1,12 @@
class Out<out T>
class Final
open class Open
fun deepOpen(x: Out<Out<Out<Open>>>) {}
// method: DeepOutKt::deepOpen
// generic signature: (LOut<+LOut<+LOut<+LOpen;>;>;>;)V
fun deepFinal(x: Out<Out<Out<Final>>>) {}
// method: DeepOutKt::deepFinal
// generic signature: (LOut<LOut<LOut<LFinal;>;>;>;)V

View File

@@ -0,0 +1,25 @@
class Out<out T>
class Final
open class Open
@JvmField
val NO_WILDCARDS: Out<Open> = Out()
// field: FieldsKt::NO_WILDCARDS
// generic signature: LOut<LOpen;>;
@JvmField
var HAS_WILDCARDS: Out<Open> = Out()
// field: FieldsKt::HAS_WILDCARDS
// generic signature: LOut<+LOpen;>;
@JvmField
var NO_WILDCARDS_VAR: Out<Final> = Out()
// field: FieldsKt::NO_WILDCARDS_VAR
// generic signature: LOut<LFinal;>;
@JvmSuppressWildcards
@JvmField
var SUPPRESSED: Out<Open> = Out()
// field: FieldsKt::SUPPRESSED
// generic signature: LOut<LOpen;>;

View File

@@ -0,0 +1,31 @@
class Out<out T>
class OutPair<out X, out Y>
class In<in Z>
class Inv<E>
open class Open
class Final
fun skipAllOutInvWildcards(): Inv<OutPair<Open, Out<Out<Open>>>> = null!!
// method: FinalReturnTypeKt::skipAllOutInvWildcards
// generic signature: ()LInv<LOutPair<LOpen;LOut<LOut<LOpen;>;>;>;>;
fun notDeepIn(): In<Final> = null!!
// method: FinalReturnTypeKt::notDeepIn
// generic signature: ()LIn<LFinal;>;
fun skipWildcardsUntilIn0(): Out<In<Out<Open>>> = null!!
// method: FinalReturnTypeKt::skipWildcardsUntilIn0
// generic signature: ()LOut<LIn<LOut<+LOpen;>;>;>;
fun skipWildcardsUntilIn1(): Out<In<Out<Final>>> = null!!
// method: FinalReturnTypeKt::skipWildcardsUntilIn1
// generic signature: ()LOut<LIn<LOut<LFinal;>;>;>;
fun skipWildcardsUntilIn2(): Out<In<OutPair<Final, Out<Open>>>> = null!!
// method: FinalReturnTypeKt::skipWildcardsUntilIn2
// generic signature: ()LOut<LIn<LOutPair<LFinal;+LOut<+LOpen;>;>;>;>;
fun skipWildcardsUntilInProjection(): Inv<in Out<Open>> = null!!
// method: FinalReturnTypeKt::skipWildcardsUntilInProjection
// generic signature: ()LInv<-LOut<+LOpen;>;>;

View File

@@ -0,0 +1,12 @@
class Out<out T>
class In<in Z>
class Final
fun outIn(x: Out<In<Final>>) {}
// method: OutInKt::outIn
// generic signature: (LOut<+LIn<-LFinal;>;>;)V
fun outInAny(x: Out<In<Any?>>) {}
// method: OutInKt::outInAny
// generic signature: (LOut<LIn<Ljava/lang/Object;>;>;)V

View File

@@ -0,0 +1,25 @@
class Inv<E>
class Out<out T>
class Final
open class Open
fun invInv(x: Out<Inv<Open>>) {}
// method: OutInvKt::invInv
// generic signature: (LOut<LInv<LOpen;>;>;)V
fun invOut(x: Out<Inv<out Open>>) {}
// method: OutInvKt::invOut
// generic signature: (LOut<+LInv<+LOpen;>;>;)V
fun invOutFinal(x: Out<Inv<out Final>>) {}
// method: OutInvKt::invOutFinal
// generic signature: (LOut<LInv<+LFinal;>;>;)V
fun invIn(x: Out<Inv<in Final>>) {}
// method: OutInvKt::invIn
// generic signature: (LOut<+LInv<-LFinal;>;>;)V
fun invInAny(x: Out<Inv<in Any>>) {}
// method: OutInvKt::invInAny
// generic signature: (LOut<LInv<-Ljava/lang/Object;>;>;)V

View File

@@ -0,0 +1,15 @@
class In<in Z>
class Out<out T>
class Final
fun inFinal(x: In<Final>) {}
// method: TopLevelInKt::inFinal
// generic signature: (LIn<-LFinal;>;)V
fun inAny(x: In<Any>) {}
// method: TopLevelInKt::inAny
// generic signature: (LIn<Ljava/lang/Object;>;)V
fun inOutFinal(x: In<Out<Final>>) {}
// method: TopLevelInKt::inOutFinal
// generic signature: (LIn<-LOut<LFinal;>;>;)V

View File

@@ -0,0 +1,24 @@
class Inv<X>
class Out<out T>
class Final
open class Open
fun invOpen(x: Inv<Open>) {}
// method: TopLevelInvKt::invOpen
// generic signature: (LInv<LOpen;>;)V
fun invFinal(x: Inv<Final>) {}
// method: TopLevelInvKt::invFinal
// generic signature: (LInv<LFinal;>;)V
fun invOutOpen(x: Inv<Out<Open>>) {}
// method: TopLevelInvKt::invOutOpen
// generic signature: (LInv<LOut<+LOpen;>;>;)V
fun invOutFinal(x: Inv<Out<Final>>) {}
// method: TopLevelInvKt::invOutFinal
// generic signature: (LInv<LOut<LFinal;>;>;)V
fun invOutProjectedOutFinal(x: Inv<out Out<Final>>) {}
// method: TopLevelInvKt::invOutProjectedOutFinal
// generic signature: (LInv<+LOut<LFinal;>;>;)V

View File

@@ -0,0 +1,8 @@
class Out<out T>
class In<in Z>
class Final
fun <Q : Final> typeParameter(x: Out<Q>, y: In<Q>) {}
// method: TypeParameterKt::typeParameter
// generic signature: <Q:LFinal;>(LOut<+TQ;>;LIn<-TQ;>;)V

View File

@@ -3282,6 +3282,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("ifWhenWithoutElse.kt")
public void testIfWhenWithoutElse() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.kt");
doTest(fileName);
}
@TestMetadata("improperElseInExpression.kt")
public void testImproperElseInExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.kt");

View File

@@ -71,6 +71,12 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
doTest(fileName);
}
@TestMetadata("kt10192.kt")
public void testKt10192() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/kt10192.kt");
doTest(fileName);
}
@TestMetadata("kt9078.kt")
public void testKt9078() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/kt9078.kt");

View File

@@ -8212,18 +8212,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("noElseAssigned.kt")
public void testNoElseAssigned() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/when/noElseAssigned.kt");
doTest(fileName);
}
@TestMetadata("noElseAssignedNoMatch.kt")
public void testNoElseAssignedNoMatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/when/noElseAssignedNoMatch.kt");
doTest(fileName);
}
@TestMetadata("noElseExhaustive.kt")
public void testNoElseExhaustive() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/when/noElseExhaustive.kt");
@@ -8242,18 +8230,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
doTest(fileName);
}
@TestMetadata("noElseInRetunedExpression.kt")
public void testNoElseInRetunedExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/when/noElseInRetunedExpression.kt");
doTest(fileName);
}
@TestMetadata("noElseInRetunedExpressionNoMatch.kt")
public void testNoElseInRetunedExpressionNoMatch() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/when/noElseInRetunedExpressionNoMatch.kt");
doTest(fileName);
}
@TestMetadata("noElseInStatement.kt")
public void testNoElseInStatement() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/when/noElseInStatement.kt");

View File

@@ -35,6 +35,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithJava"), Pattern.compile("^([^\\.]+)$"), true);
}
@TestMetadata("allWildcardsOnClass")
public void testAllWildcardsOnClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/allWildcardsOnClass/");
doTestWithJava(fileName);
}
@TestMetadata("annotatedSamFunExpression")
public void testAnnotatedSamFunExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/annotatedSamFunExpression/");
@@ -59,6 +65,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
doTestWithJava(fileName);
}
@TestMetadata("covariantOverrideWithDeclarationSiteProjection")
public void testCovariantOverrideWithDeclarationSiteProjection() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/covariantOverrideWithDeclarationSiteProjection/");
doTestWithJava(fileName);
}
@TestMetadata("deprecatedFieldForObject")
public void testDeprecatedFieldForObject() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/deprecatedFieldForObject/");
@@ -287,6 +299,18 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
doTestWithJava(fileName);
}
@TestMetadata("readOnlyList")
public void testReadOnlyList() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/readOnlyList/");
doTestWithJava(fileName);
}
@TestMetadata("readOnlyMap")
public void testReadOnlyMap() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/readOnlyMap/");
doTestWithJava(fileName);
}
@TestMetadata("removeAtInt")
public void testRemoveAtInt() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/collections/removeAtInt/");

View File

@@ -3696,6 +3696,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/genericSignature"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("covariantOverride.kt")
public void testCovariantOverride() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/genericSignature/covariantOverride.kt");
doTestWithStdlib(fileName);
}
@TestMetadata("kt5112.kt")
public void testKt5112() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/genericSignature/kt5112.kt");

View File

@@ -67,7 +67,7 @@ public interface AbstractSMAPBaseTest {
}.map {
val smap = it.getValue().mapNotNull { it.smap?.replaceHash() }.joinToString("\n")
SMAPAndFile(if (smap.isNotEmpty()) smap else null, it.key)
}.toMap { it.sourceFile }
}.toMapBy { it.sourceFile }
for (source in sourceData) {
val data = compiledData[source.sourceFile]

View File

@@ -67,7 +67,7 @@ public abstract class AbstractWriteSignatureTest : TestCaseWithTmpdir() {
expectations.check()
}
private class SignatureExpectation(val header: String, val name: String, expectedJvmSignature: String, expectedGenericSignature: String) {
private class SignatureExpectation(val header: String, val name: String, val expectedJvmSignature: String?, expectedGenericSignature: String) {
private var checked = false
private val expectedSignature = formatSignature(header, expectedJvmSignature, expectedGenericSignature)
@@ -76,7 +76,7 @@ public abstract class AbstractWriteSignatureTest : TestCaseWithTmpdir() {
fun check(name: String, actualJvmSignature: String, actualGenericSignature: String) {
if (this.name == name) {
checked = true
val actualSignature = formatSignature(header, actualJvmSignature, actualGenericSignature)
val actualSignature = formatSignature(header, expectedJvmSignature?.let { actualJvmSignature }, actualGenericSignature)
Assert.assertEquals(expectedSignature, actualSignature)
}
}
@@ -167,15 +167,15 @@ public abstract class AbstractWriteSignatureTest : TestCaseWithTmpdir() {
}
}
fun addClassExpectation(name: String, jvmSignature: String, genericSignature: String) {
fun addClassExpectation(name: String, jvmSignature: String?, genericSignature: String) {
classExpectations.add(SignatureExpectation("class: $name", name, jvmSignature, genericSignature))
}
fun addFieldExpectation(className: String, memberName: String, jvmSignature: String, genericSignature: String) {
fun addFieldExpectation(className: String, memberName: String, jvmSignature: String?, genericSignature: String) {
fieldExpectations.add(SignatureExpectation("field: $className::$memberName", memberName, jvmSignature, genericSignature))
}
fun addMethodExpectation(className: String, memberName: String, jvmSignature: String, genericSignature: String) {
fun addMethodExpectation(className: String, memberName: String, jvmSignature: String?, genericSignature: String) {
methodExpectations.add(SignatureExpectation("method: $className::$memberName", memberName, jvmSignature, genericSignature))
}
}
@@ -199,10 +199,11 @@ public abstract class AbstractWriteSignatureTest : TestCaseWithTmpdir() {
}
val jvmSignatureMatch = jvmSignatureRegex.matchExact(lines[lineNo+1])
val genericSignatureMatch = genericSignatureRegex.matchExact(lines[lineNo+2])
val genericSignatureMatch = genericSignatureRegex.matchExact(lines[lineNo+1])
?: genericSignatureRegex.matchExact(lines[lineNo+2])
if (jvmSignatureMatch != null && genericSignatureMatch != null) {
val jvmSignature = jvmSignatureMatch.group(1)
if (genericSignatureMatch != null) {
val jvmSignature = jvmSignatureMatch?.group(1)
val genericSignature = genericSignatureMatch.group(1)
val classSuite = expectations.getOrCreateClassSuite(className)
@@ -230,10 +231,13 @@ public abstract class AbstractWriteSignatureTest : TestCaseWithTmpdir() {
}
companion object {
fun formatSignature(header: String, jvmSignature: String, genericSignature: String): String =
"""// $header
// jvm signature: $jvmSignature
// generic signature: $genericSignature"""
fun formatSignature(header: String, jvmSignature: String?, genericSignature: String): String {
return listOf(
"$header",
jvmSignature?.let { "jvm signature: $it" },
"generic signature: $genericSignature"
).filterNotNull().joinToString("\n") { "// $it" }
}
val expectationRegex = Regex("^// (class|method|field): *([^:]+)(::(.+))? *(//.*)?")
val jvmSignatureRegex = Regex("^// jvm signature: *(.+) *(//.*)?")

View File

@@ -223,6 +223,12 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest {
doTest(fileName);
}
@TestMetadata("GenericOverrides.kt")
public void testGenericOverrides() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/GenericOverrides.kt");
doTest(fileName);
}
@TestMetadata("InInInPosition.kt")
public void testInInInPosition() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/InInInPosition.kt");
@@ -265,6 +271,18 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest {
doTest(fileName);
}
@TestMetadata("OpenMembersReturnType.kt")
public void testOpenMembersReturnType() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/OpenMembersReturnType.kt");
doTest(fileName);
}
@TestMetadata("OpenMembersValueParameter.kt")
public void testOpenMembersValueParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/OpenMembersValueParameter.kt");
doTest(fileName);
}
@TestMetadata("OutInField.kt")
public void testOutInField() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/OutInField.kt");
@@ -354,6 +372,108 @@ public class WriteSignatureTestGenerated extends AbstractWriteSignatureTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/SuperTypeWithVarianceInArguments.kt");
doTest(fileName);
}
@TestMetadata("compiler/testData/writeSignature/declarationSiteVariance/jvmWildcardAnnotations")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class JvmWildcardAnnotations extends AbstractWriteSignatureTest {
public void testAllFilesPresentInJvmWildcardAnnotations() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/writeSignature/declarationSiteVariance/jvmWildcardAnnotations"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("onFunction.kt")
public void testOnFunction() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/jvmWildcardAnnotations/onFunction.kt");
doTest(fileName);
}
@TestMetadata("onTypes.kt")
public void testOnTypes() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/jvmWildcardAnnotations/onTypes.kt");
doTest(fileName);
}
@TestMetadata("primitiveTypes.kt")
public void testPrimitiveTypes() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/jvmWildcardAnnotations/primitiveTypes.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class WildcardOptimization extends AbstractWriteSignatureTest {
public void testAllFilesPresentInWildcardOptimization() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("argumentOverridability.kt")
public void testArgumentOverridability() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/argumentOverridability.kt");
doTest(fileName);
}
@TestMetadata("arrays.kt")
public void testArrays() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/arrays.kt");
doTest(fileName);
}
@TestMetadata("complicatedInBounds.kt")
public void testComplicatedInBounds() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/complicatedInBounds.kt");
doTest(fileName);
}
@TestMetadata("deepOut.kt")
public void testDeepOut() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/deepOut.kt");
doTest(fileName);
}
@TestMetadata("fields.kt")
public void testFields() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/fields.kt");
doTest(fileName);
}
@TestMetadata("finalReturnType.kt")
public void testFinalReturnType() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/finalReturnType.kt");
doTest(fileName);
}
@TestMetadata("outIn.kt")
public void testOutIn() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/outIn.kt");
doTest(fileName);
}
@TestMetadata("outInv.kt")
public void testOutInv() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/outInv.kt");
doTest(fileName);
}
@TestMetadata("topLevelIn.kt")
public void testTopLevelIn() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/topLevelIn.kt");
doTest(fileName);
}
@TestMetadata("topLevelInv.kt")
public void testTopLevelInv() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/topLevelInv.kt");
doTest(fileName);
}
@TestMetadata("typeParameter.kt")
public void testTypeParameter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/typeParameter.kt");
doTest(fileName);
}
}
}
@TestMetadata("compiler/testData/writeSignature/nothing")

View File

@@ -27,13 +27,8 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.descriptorUtil.*
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.check
object BuiltinSpecialProperties {
private val PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP = mapOf(
@@ -60,7 +55,7 @@ object BuiltinSpecialProperties {
}
private fun CallableMemberDescriptor.hasBuiltinSpecialPropertyFqNameImpl(): Boolean {
if (FQ_NAMES.containsRaw(fqNameOrNull())) return true
if (fqNameOrNull() in FQ_NAMES) return true
if (!isFromBuiltins()) return false
return overriddenDescriptors.any { hasBuiltinSpecialPropertyFqName(it) }
@@ -108,7 +103,7 @@ object BuiltinMethodsWithSpecialGenericSignature {
ERASED_VALUE_PARAMETERS_FQ_NAMES.map { it.shortName() }.toSet()
private val CallableMemberDescriptor.hasErasedValueParametersInJava: Boolean
get() = ERASED_VALUE_PARAMETERS_FQ_NAMES.containsRaw(fqNameOrNull())
get() = fqNameOrNull() in ERASED_VALUE_PARAMETERS_FQ_NAMES
@JvmStatic
fun getOverriddenBuiltinFunctionWithErasedValueParametersInJava(
@@ -122,21 +117,22 @@ object BuiltinMethodsWithSpecialGenericSignature {
fun getDefaultValueForOverriddenBuiltinFunction(functionDescriptor: FunctionDescriptor): DefaultValue? {
if (functionDescriptor.name !in ERASED_VALUE_PARAMETERS_SHORT_NAMES) return null
return functionDescriptor.firstOverridden {
GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP.keys.containsRaw(it.fqNameOrNull())
it.fqNameOrNull() in GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP.keys
}?.let { GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP[it.fqNameSafe] }
}
val Name.sameAsBuiltinMethodWithErasedValueParameters: Boolean
get () = this in ERASED_VALUE_PARAMETERS_SHORT_NAMES
enum class SpecialSignatureInfo(val signature: String?) {
ONE_COLLECTION_PARAMETER("(Ljava/util/Collection<+Ljava/lang/Object;>;)Z"),
GENERIC_PARAMETER(null)
enum class SpecialSignatureInfo(val valueParametersSignature: String?, val isObjectReplacedWithTypeParameter: Boolean) {
ONE_COLLECTION_PARAMETER("Ljava/util/Collection<+Ljava/lang/Object;>;", false),
OBJECT_PARAMETER_NON_GENERIC(null, true),
OBJECT_PARAMETER_GENERIC("Ljava/lang/Object;", true)
}
fun CallableMemberDescriptor.isBuiltinWithSpecialDescriptorInJvm(): Boolean {
if (!isFromBuiltins()) return false
return getSpecialSignatureInfo() == SpecialSignatureInfo.GENERIC_PARAMETER || doesOverrideBuiltinWithDifferentJvmName()
return getSpecialSignatureInfo()?.isObjectReplacedWithTypeParameter ?: false || doesOverrideBuiltinWithDifferentJvmName()
}
@JvmStatic
@@ -144,11 +140,15 @@ object BuiltinMethodsWithSpecialGenericSignature {
val builtinFqName = firstOverridden { it is FunctionDescriptor && it.hasErasedValueParametersInJava }?.fqNameOrNull()
?: return null
return when (builtinFqName) {
in ERASED_COLLECTION_PARAMETER_FQ_NAMES -> SpecialSignatureInfo.ONE_COLLECTION_PARAMETER
in GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP -> SpecialSignatureInfo.GENERIC_PARAMETER
else -> error("Unexpected kind of special builtin: $builtinFqName")
}
if (builtinFqName in ERASED_COLLECTION_PARAMETER_FQ_NAMES) return SpecialSignatureInfo.ONE_COLLECTION_PARAMETER
val defaultValue = GENERIC_PARAMETERS_METHODS_TO_DEFAULT_VALUES_MAP[builtinFqName]!!
return if (defaultValue == DefaultValue.NULL)
// return type is some generic type as 'Map.get'
SpecialSignatureInfo.OBJECT_PARAMETER_GENERIC
else
SpecialSignatureInfo.OBJECT_PARAMETER_NON_GENERIC
}
}
@@ -212,8 +212,7 @@ fun <T : CallableMemberDescriptor> T.getOverriddenBuiltinWithDifferentJvmDescrip
if (!name.sameAsBuiltinMethodWithErasedValueParameters) return null
return firstOverridden {
it.isFromBuiltins()
&& it.getSpecialSignatureInfo() == BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo.GENERIC_PARAMETER
it.isFromBuiltins() && it.getSpecialSignatureInfo()?.isObjectReplacedWithTypeParameter ?: false
}?.original as T?
}
@@ -280,33 +279,6 @@ private fun CallableMemberDescriptor.isFromBuiltins(): Boolean {
this.module == this.builtIns.builtInsModule
}
private val CallableMemberDescriptor.propertyIfAccessor: CallableMemberDescriptor
get() = if (this is PropertyAccessorDescriptor) correspondingProperty else this
private fun CallableDescriptor.fqNameOrNull(): FqName? = fqNameUnsafe.check { it.isSafe }?.toSafe()
public fun CallableMemberDescriptor.firstOverridden(
predicate: (CallableMemberDescriptor) -> Boolean
): CallableMemberDescriptor? {
var result: CallableMemberDescriptor? = null
return DFS.dfs(listOf(this),
object : DFS.Neighbors<CallableMemberDescriptor> {
override fun getNeighbors(current: CallableMemberDescriptor?): Iterable<CallableMemberDescriptor> {
return current?.overriddenDescriptors ?: emptyList()
}
},
object : DFS.AbstractNodeHandler<CallableMemberDescriptor, CallableMemberDescriptor?>() {
override fun beforeChildren(current: CallableMemberDescriptor) = result == null
override fun afterChildren(current: CallableMemberDescriptor) {
if (result == null && predicate(current)) {
result = current
}
}
override fun result(): CallableMemberDescriptor? = result
}
)
}
public fun CallableMemberDescriptor.isFromJavaOrBuiltins() = isFromJava || isFromBuiltins()
private fun Map<FqName, Name>.getInversedShortNamesMap(): Map<Name, List<Name>> =

View File

@@ -262,9 +262,9 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
@NotNull
@Override
public Collection<DeclarationDescriptor> getContributedDescriptors(
public Collection getContributedDescriptors(
@NotNull DescriptorKindFilter kindFilter,
@NotNull Function1<? super Name, ? extends Boolean> nameFilter
@NotNull Function1 nameFilter
) {
return allDescriptors.invoke();
}

View File

@@ -14,11 +14,12 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.renderer;
package org.jetbrains.kotlin.renderer
import org.jetbrains.annotations.NotNull;
public interface Renderer<O> {
@NotNull
String render(@NotNull O object);
public interface Renderer<in O> {
fun render(obj: O): String
}
fun <O> Renderer(block: (O) -> String) = object : Renderer<O> {
override fun render(obj: O) = block(obj)
}

View File

@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.addToStdlib.check
public fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor = getCompanionObjectDescriptor() ?: this
@@ -197,3 +198,29 @@ public val DeclarationDescriptor.parentsWithSelf: Sequence<DeclarationDescriptor
public val DeclarationDescriptor.parents: Sequence<DeclarationDescriptor>
get() = parentsWithSelf.drop(1)
val CallableMemberDescriptor.propertyIfAccessor: CallableMemberDescriptor
get() = if (this is PropertyAccessorDescriptor) correspondingProperty else this
fun CallableDescriptor.fqNameOrNull(): FqName? = fqNameUnsafe.check { it.isSafe }?.toSafe()
public fun CallableMemberDescriptor.firstOverridden(
predicate: (CallableMemberDescriptor) -> Boolean
): CallableMemberDescriptor? {
var result: CallableMemberDescriptor? = null
return DFS.dfs(listOf(this),
object : DFS.Neighbors<CallableMemberDescriptor> {
override fun getNeighbors(current: CallableMemberDescriptor?): Iterable<CallableMemberDescriptor> {
return current?.overriddenDescriptors ?: emptyList()
}
},
object : DFS.AbstractNodeHandler<CallableMemberDescriptor, CallableMemberDescriptor?>() {
override fun beforeChildren(current: CallableMemberDescriptor) = result == null
override fun afterChildren(current: CallableMemberDescriptor) {
if (result == null && predicate(current)) {
result = current
}
}
override fun result(): CallableMemberDescriptor? = result
}
)
}

View File

@@ -77,8 +77,8 @@ public class ErrorUtils {
@NotNull
@Override
public Collection<FqName> getSubPackagesOf(
@NotNull FqName fqName, @NotNull Function1<? super Name, ? extends Boolean> nameFilter
public Collection getSubPackagesOf(
@NotNull FqName fqName, @NotNull Function1 nameFilter
) {
return emptyList();
}
@@ -193,8 +193,8 @@ public class ErrorUtils {
@NotNull
@Override
public Collection<DeclarationDescriptor> getContributedDescriptors(
@NotNull DescriptorKindFilter kindFilter, @NotNull Function1<? super Name, ? extends Boolean> nameFilter
public Collection getContributedDescriptors(
@NotNull DescriptorKindFilter kindFilter, @NotNull Function1 nameFilter
) {
return Collections.emptyList();
}
@@ -244,8 +244,8 @@ public class ErrorUtils {
@NotNull
@Override
public Collection<DeclarationDescriptor> getContributedDescriptors(
@NotNull DescriptorKindFilter kindFilter, @NotNull Function1<? super Name, ? extends Boolean> nameFilter
public Collection getContributedDescriptors(
@NotNull DescriptorKindFilter kindFilter, @NotNull Function1 nameFilter
) {
throw new IllegalStateException();
}

View File

@@ -151,15 +151,15 @@ public class LockBasedStorageManager implements StorageManager {
@NotNull
@Override
public <T> NotNullLazyValue<T> createLazyValueWithPostCompute(
@NotNull Function0<? extends T> computable,
final Function1<? super Boolean, ? extends T> onRecursiveCall,
@NotNull final Function1<? super T, ? extends Unit> postCompute
public NotNullLazyValue createLazyValueWithPostCompute(
@NotNull Function0 computable,
final Function1 onRecursiveCall,
@NotNull final Function1 postCompute
) {
return new LockBasedNotNullLazyValue<T>(computable) {
return new LockBasedNotNullLazyValue(computable) {
@NotNull
@Override
protected RecursionDetectedResult<T> recursionDetected(boolean firstTime) {
protected RecursionDetectedResult recursionDetected(boolean firstTime) {
if (onRecursiveCall == null) {
return super.recursionDetected(firstTime);
}
@@ -167,7 +167,7 @@ public class LockBasedStorageManager implements StorageManager {
}
@Override
protected void postCompute(@NotNull T value) {
protected void postCompute(@NotNull Object value) {
postCompute.invoke(value);
}
};
@@ -193,12 +193,12 @@ public class LockBasedStorageManager implements StorageManager {
@NotNull
@Override
public <T> NullableLazyValue<T> createNullableLazyValueWithPostCompute(
@NotNull Function0<? extends T> computable, @NotNull final Function1<? super T, ? extends Unit> postCompute
public NullableLazyValue createNullableLazyValueWithPostCompute(
@NotNull Function0 computable, @NotNull final Function1 postCompute
) {
return new LockBasedLazyValue<T>(computable) {
return new LockBasedLazyValue(computable) {
@Override
protected void postCompute(@Nullable T value) {
protected void postCompute(@Nullable Object value) {
postCompute.invoke(value);
}
};

View File

@@ -59,7 +59,7 @@ fun createModuleResolverProvider(
val jvmPlatformParameters = JvmPlatformParameters {
javaClass: JavaClass ->
val psiClass = (javaClass as JavaClassImpl).getPsi()
psiClass.getModuleInfo()
psiClass.getNullableModuleInfo()
}
val resolverForProject = analyzerFacade.setupResolverForProject(

View File

@@ -28,13 +28,20 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.roots.ModuleRootManager
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.utils.sure
fun PsiElement.getModuleInfo(): IdeaModuleInfo {
fun logAndReturnDefault(message: String): IdeaModuleInfo {
LOG.error("Could not find correct module information.\nReason: $message")
return NotUnderContentRootModuleInfo
}
fun PsiElement.getModuleInfo(): IdeaModuleInfo = this.getModuleInfo { reason ->
LOG.error("Could not find correct module information.\nReason: $reason")
NotUnderContentRootModuleInfo
}.sure { "Defaulting to NotUnderContentRootModuleInfo so null is not possible" }
fun PsiElement.getNullableModuleInfo(): IdeaModuleInfo? = this.getModuleInfo { reason ->
LOG.warn("Could not find correct module information.\nReason: $reason")
null
}
private fun PsiElement.getModuleInfo(onFailure: (String) -> IdeaModuleInfo?): IdeaModuleInfo? {
if (this is KtLightElement<*, *>) return this.getModuleInfoForLightElement()
val containingJetFile = (this as? KtElement)?.getContainingFile() as? KtFile
@@ -43,7 +50,7 @@ fun PsiElement.getModuleInfo(): IdeaModuleInfo {
val doNotAnalyze = containingJetFile?.doNotAnalyze
if (doNotAnalyze != null) {
return logAndReturnDefault(
return onFailure(
"Should not analyze element: ${getText()} in file ${containingJetFile?.getName() ?: " <no file>"}\n$doNotAnalyze"
)
}
@@ -53,15 +60,13 @@ fun PsiElement.getModuleInfo(): IdeaModuleInfo {
if (containingJetFile is KtCodeFragment) {
return containingJetFile.getContext()?.getModuleInfo()
?: logAndReturnDefault("Analyzing code fragment of type ${containingJetFile.javaClass} with no context element\nText:\n${containingJetFile.getText()}")
?: onFailure("Analyzing code fragment of type ${containingJetFile.javaClass} with no context element\nText:\n${containingJetFile.getText()}")
}
val project = getProject()
val containingFile = getContainingFile()
?: return logAndReturnDefault("Analyzing element of type $javaClass with no containing file\nText:\n${getText()}")
val containingFile = containingFile ?: return onFailure("Analyzing element of type $javaClass with no containing file\nText:\n$text")
val virtualFile = containingFile.getOriginalFile().getVirtualFile()
?: return logAndReturnDefault("Analyzing non-physical file $containingFile of type ${containingFile.javaClass}")
val virtualFile = containingFile.originalFile.virtualFile
?: return onFailure("Analyzing element of type $javaClass in non-physical file $containingFile of type ${containingFile.javaClass}\nText:\n$text")
return getModuleInfoByVirtualFile(
project,
@@ -115,8 +120,13 @@ private fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFil
}
private fun KtLightElement<*, *>.getModuleInfoForLightElement(): IdeaModuleInfo {
if (this is KtLightClassForDecompiledDeclaration) {
return getModuleInfoByVirtualFile(getProject(), getContainingFile().getVirtualFile(), false)
val decompiledClass = this.getParentOfType<KtLightClassForDecompiledDeclaration>(strict = false)
if (decompiledClass != null) {
return getModuleInfoByVirtualFile(
project,
containingFile.virtualFile.sure { "Decompiled class should be build from physical file" },
false
)
}
val element = getOrigin() ?: when (this) {
is FakeLightClassForFileOfPackage -> this.getContainingFile()!!

View File

@@ -44,7 +44,7 @@ public class HtmlTabledDescriptorRenderer extends TabledDescriptorRenderer {
@NotNull
@Override
public Renderer<KotlinType> getTypeRenderer() {
return IdeRenderers.HTML_RENDER_TYPE;
return (Renderer<KotlinType>) IdeRenderers.HTML_RENDER_TYPE;
}
@Override

View File

@@ -2,4 +2,4 @@ fun foo(list: List<String>) {
list.<caret>
}
// EXIST: { itemText: "firstOrNull", tailText: " {...} (predicate: (String) -> Boolean) for Iterable<T> in kotlin", typeText: "String?" }
// EXIST: { itemText: "toMap", tailText: " {...} (selector: (String) -> K) for Iterable<T> in kotlin", typeText: "Map<K, String>" }
// EXIST: { itemText: "toMapBy", tailText: " {...} (selector: (String) -> K) for Iterable<T> in kotlin", typeText: "Map<K, String>" }

View File

@@ -52,7 +52,7 @@ public fun Call.mapArgumentsToParameters(targetDescriptor: CallableDescriptor):
if (parameters.isEmpty()) return emptyMap()
val map = HashMap<ValueArgument, ValueParameterDescriptor>()
val parametersByName = parameters.toMap { it.getName() }
val parametersByName = parameters.toMapBy { it.getName() }
var positionalArgumentIndex: Int? = 0

View File

@@ -42,10 +42,12 @@ class HistoryKeyListener(
UP, DOWN
}
override fun keyReleased(e: KeyEvent): Unit = when (e.keyCode) {
KeyEvent.VK_UP -> moveHistoryCursor(HistoryMove.UP)
KeyEvent.VK_DOWN -> moveHistoryCursor(HistoryMove.DOWN)
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT -> prevCaretOffset = consoleEditor.caretModel.offset
override fun keyReleased(e: KeyEvent) {
when (e.keyCode) {
KeyEvent.VK_UP -> moveHistoryCursor(HistoryMove.UP)
KeyEvent.VK_DOWN -> moveHistoryCursor(HistoryMove.DOWN)
KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT -> prevCaretOffset = consoleEditor.caretModel.offset
}
}
private fun moveHistoryCursor(move: HistoryMove) {

View File

@@ -68,8 +68,8 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Kotlin
private val LOG = Logger.getInstance(javaClass<KotlinCopyPasteReferenceProcessor>())
private val IGNORE_REFERENCES_INSIDE: Array<Class<out KtElement>> = arrayOf(
javaClass<KtImportList>(),
javaClass<KtPackageDirective>()
KtImportList::class.java,
KtPackageDirective::class.java
)
override fun extractTransferableData(content: Transferable): List<KotlinReferenceTransferableData> {
@@ -139,7 +139,7 @@ public class KotlinCopyPasteReferenceProcessor() : CopyPastePostProcessor<Kotlin
) {
if (PsiTreeUtil.getNonStrictParentOfType(element, *IGNORE_REFERENCES_INSIDE) != null) return
element.forEachDescendantOfType<KtElement>(canGoInside = { it.javaClass !in IGNORE_REFERENCES_INSIDE }) { element ->
element.forEachDescendantOfType<KtElement>(canGoInside = { it.javaClass as Class<*> !in IGNORE_REFERENCES_INSIDE }) { element ->
val reference = element.mainReference ?: return@forEachDescendantOfType
val descriptors = reference.resolveToDescriptors(element.analyze()) //TODO: we could use partial body resolve for all references together

View File

@@ -116,10 +116,10 @@ class KotlinEditorTextProvider : EditorTextProvider {
}
private val NOT_ACCEPTED_AS_CONTEXT_TYPES =
arrayOf(javaClass<KtUserType>(), javaClass<KtImportDirective>(), javaClass<KtPackageDirective>())
arrayOf(KtUserType::class.java, KtImportDirective::class.java, KtPackageDirective::class.java)
fun isAcceptedAsCodeFragmentContext(element: PsiElement): Boolean {
return element.javaClass !in NOT_ACCEPTED_AS_CONTEXT_TYPES &&
return element.javaClass as Class<*> !in NOT_ACCEPTED_AS_CONTEXT_TYPES &&
PsiTreeUtil.getParentOfType(element, *NOT_ACCEPTED_AS_CONTEXT_TYPES) == null
}
}

Some files were not shown because too many files have changed in this diff Show More