mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-27 00:21:29 +00:00
Compare commits
209 Commits
rr/stdlib/
...
native-sup
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42beac30f3 | ||
|
|
39ee351fbd | ||
|
|
ac6a43a641 | ||
|
|
8fb40abeea | ||
|
|
7fc57dce9f | ||
|
|
42f4c68de2 | ||
|
|
65d7ecd14e | ||
|
|
41327d4acd | ||
|
|
dcbe8da490 | ||
|
|
3d04f85ff3 | ||
|
|
36ffc8aff4 | ||
|
|
5109a346c2 | ||
|
|
885e5f5b26 | ||
|
|
9df4c5fbb8 | ||
|
|
939151a345 | ||
|
|
e38d513a89 | ||
|
|
6b10f32964 | ||
|
|
a9d845381c | ||
|
|
e33f4c8075 | ||
|
|
64c313ab57 | ||
|
|
98fc47850b | ||
|
|
01a318288a | ||
|
|
b74a0506cf | ||
|
|
4995d05caa | ||
|
|
87d7c76868 | ||
|
|
76e08fb698 | ||
|
|
d9ba6c16ec | ||
|
|
51534b6e00 | ||
|
|
472ad212d7 | ||
|
|
fe57e3607e | ||
|
|
2f8d5edb2e | ||
|
|
45f920af9a | ||
|
|
dd8c950df5 | ||
|
|
c9c7841e44 | ||
|
|
a504ce350e | ||
|
|
1ae294d84b | ||
|
|
142b39ff4d | ||
|
|
0a8705d458 | ||
|
|
22b5241ee3 | ||
|
|
3d8467011d | ||
|
|
9a74fe0b8d | ||
|
|
69dd8b06c5 | ||
|
|
da30cd9e70 | ||
|
|
9f418262c5 | ||
|
|
c2a2b61852 | ||
|
|
62bd9d5c0d | ||
|
|
3437168f3e | ||
|
|
97d0689108 | ||
|
|
4a4705c3a7 | ||
|
|
23351a214d | ||
|
|
08cfcf6a89 | ||
|
|
387f582b4f | ||
|
|
58f0b657dd | ||
|
|
38bd91e870 | ||
|
|
9b19454e83 | ||
|
|
0f632a2115 | ||
|
|
8e552dac42 | ||
|
|
8d8591204c | ||
|
|
03fb1c554a | ||
|
|
7a3f5d05a7 | ||
|
|
0e6528eef6 | ||
|
|
a64beaac67 | ||
|
|
c0080b9465 | ||
|
|
1a4fe89b8b | ||
|
|
b7eef26f7d | ||
|
|
89e92b08d8 | ||
|
|
ec406de257 | ||
|
|
9f8fa3c385 | ||
|
|
3776b9519c | ||
|
|
c2788bd6cf | ||
|
|
de970d9c7d | ||
|
|
07d1795ed0 | ||
|
|
ba6a8b4c44 | ||
|
|
3f260876ce | ||
|
|
605ab1687e | ||
|
|
2b398f89f4 | ||
|
|
1dd8cf7364 | ||
|
|
f9e1f1c922 | ||
|
|
179237063f | ||
|
|
6b8fc04124 | ||
|
|
9b472e9d2c | ||
|
|
db007f0633 | ||
|
|
2d8315ac7d | ||
|
|
a85afb0f39 | ||
|
|
486f81c7ad | ||
|
|
e656ca1e01 | ||
|
|
bb7b46bcc1 | ||
|
|
17748f8c0a | ||
|
|
333f92b601 | ||
|
|
ec8dedba41 | ||
|
|
e56ae1119f | ||
|
|
51f744b665 | ||
|
|
cbcf2f0c4c | ||
|
|
904731fd98 | ||
|
|
358871973b | ||
|
|
7e0ea77451 | ||
|
|
adabc91d36 | ||
|
|
bbe89adc3d | ||
|
|
89be3fa02d | ||
|
|
e03f554b92 | ||
|
|
ca67fa58f1 | ||
|
|
ea8e6a26aa | ||
|
|
b0fde84573 | ||
|
|
6dd95e8d59 | ||
|
|
9b85a9a62c | ||
|
|
e3ab92851b | ||
|
|
04b8e52eb2 | ||
|
|
a49271e936 | ||
|
|
62af63edc1 | ||
|
|
85995da53a | ||
|
|
417de7f18f | ||
|
|
5cd0bb0662 | ||
|
|
610d3a3d19 | ||
|
|
0d137a6d47 | ||
|
|
e58cc9a4af | ||
|
|
7a40b2b788 | ||
|
|
98d93268db | ||
|
|
67c69ff63c | ||
|
|
a6f6f2df98 | ||
|
|
2cdee89745 | ||
|
|
3944250ce0 | ||
|
|
c9715e1a4e | ||
|
|
b309d58d2a | ||
|
|
904052811e | ||
|
|
bdb89bf876 | ||
|
|
34893a88a3 | ||
|
|
3d55aa4487 | ||
|
|
a7e0da6a83 | ||
|
|
e1ed2d7579 | ||
|
|
018f824ae3 | ||
|
|
2ebc7e282f | ||
|
|
32325f8acc | ||
|
|
8c31d30e5d | ||
|
|
cb845b0e6a | ||
|
|
8c9331ee33 | ||
|
|
aca312ce2e | ||
|
|
72583d6287 | ||
|
|
5bbb3b5ee4 | ||
|
|
1c5b8f7bf7 | ||
|
|
e04eaa5a1a | ||
|
|
2026a0bef0 | ||
|
|
442b1c370b | ||
|
|
7e98a6c94b | ||
|
|
e100ee5a5a | ||
|
|
797bd6b4ab | ||
|
|
8bc13a9c22 | ||
|
|
a5b6470b3b | ||
|
|
ff9bcf5cdf | ||
|
|
67b46a3a69 | ||
|
|
6cbe723f1d | ||
|
|
ea6902a374 | ||
|
|
0be78e98af | ||
|
|
a54210cb71 | ||
|
|
623a778960 | ||
|
|
61569e4a8a | ||
|
|
d3d12bf361 | ||
|
|
6fa8994cfb | ||
|
|
89821cf9b8 | ||
|
|
93d3e79c80 | ||
|
|
15819a00b9 | ||
|
|
765ba955dd | ||
|
|
54e913d423 | ||
|
|
da7143ca7e | ||
|
|
560ea729e0 | ||
|
|
c1d3fe0af4 | ||
|
|
090256db33 | ||
|
|
ba1a0cedcb | ||
|
|
befcce9c79 | ||
|
|
16258bb965 | ||
|
|
38ccb1a8dd | ||
|
|
0146147273 | ||
|
|
9f55d4957a | ||
|
|
d7faaf1ffd | ||
|
|
e0746ee76a | ||
|
|
51fef5fe05 | ||
|
|
9f2e853d59 | ||
|
|
81b6bbecf6 | ||
|
|
f271f46e08 | ||
|
|
da2d6c247b | ||
|
|
201c7be31b | ||
|
|
82b5a7f8e7 | ||
|
|
700bd4aecf | ||
|
|
8a8142ed9e | ||
|
|
1e73bdeaef | ||
|
|
9d4faca7f3 | ||
|
|
b514f9c265 | ||
|
|
3704897fef | ||
|
|
da2bf0090c | ||
|
|
480a21d7fb | ||
|
|
ee501d50ea | ||
|
|
e2fe2a6354 | ||
|
|
6c043333fd | ||
|
|
d92701e19a | ||
|
|
6cc218a2ae | ||
|
|
edc18a1819 | ||
|
|
9f4a0b6bf0 | ||
|
|
dd33b5745b | ||
|
|
f22bfc9ed8 | ||
|
|
99ab4a5bc9 | ||
|
|
88d37f619c | ||
|
|
8490161f0c | ||
|
|
e154928f00 | ||
|
|
4f5057d343 | ||
|
|
dc75f81244 | ||
|
|
9124ddf783 | ||
|
|
cf38350784 | ||
|
|
81a6fb575f | ||
|
|
b9714c8406 | ||
|
|
2fbb9f79fa |
7
.idea/dictionaries/dmitriy_dolovov.xml
generated
Normal file
7
.idea/dictionaries/dmitriy_dolovov.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="dmitriy.dolovov">
|
||||
<words>
|
||||
<w>konan</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
5877
ChangeLog.md
5877
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,7 @@ internal object KotlinAntTaskUtil {
|
||||
}
|
||||
|
||||
val compilerJar: File by jar("kotlin-compiler.jar")
|
||||
val runtimeJar: File by jar("kotlin-runtime.jar")
|
||||
val runtimeJar: File by jar("kotlin-stdlib.jar")
|
||||
val reflectJar: File by jar("kotlin-reflect.jar")
|
||||
|
||||
private fun jar(name: String) = lazy {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
import proguard.gradle.ProGuardTask
|
||||
|
||||
buildscript {
|
||||
extra["defaultSnapshotVersion"] = "1.2-SNAPSHOT"
|
||||
extra["defaultSnapshotVersion"] = "1.3-SNAPSHOT"
|
||||
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.70-dev-491", onlySuccessBootstrap = false))
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.3-M2-eap-135", projectExtId = "Kotlin_13M2_Compiler", onlySuccessBootstrap = false))
|
||||
|
||||
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
|
||||
|
||||
@@ -81,7 +81,7 @@ val defaultSnapshotVersion: String by extra
|
||||
val buildNumber by extra(findProperty("build.number")?.toString() ?: defaultSnapshotVersion)
|
||||
val kotlinVersion by extra(findProperty("deployVersion")?.toString() ?: buildNumber)
|
||||
|
||||
val kotlinLanguageVersion by extra("1.2")
|
||||
val kotlinLanguageVersion by extra("1.3")
|
||||
|
||||
allprojects {
|
||||
group = "org.jetbrains.kotlin"
|
||||
@@ -307,7 +307,7 @@ allprojects {
|
||||
|
||||
configureJvmProject(javaHome!!, jvmTarget!!)
|
||||
|
||||
val commonCompilerArgs = listOfNotNull("-Xallow-kotlin-package", "-Xread-deserialized-contracts", "-Xprogressive".takeIf { hasProperty("test.progressive.mode") })
|
||||
val commonCompilerArgs = listOfNotNull("-Xallow-kotlin-package", "-Xread-deserialized-contracts", "-Xprogressive".takeIf { hasProperty("test.progressive.mode") }, "-XXLanguage:-ReleaseCoroutines")
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
|
||||
kotlinOptions {
|
||||
|
||||
@@ -141,8 +141,7 @@ fun Project.runIdeTask(name: String, ideaPluginDir: File, ideaSandboxDir: File,
|
||||
"-Dapple.laf.useScreenMenuBar=true",
|
||||
"-Dapple.awt.graphics.UseQuartz=true",
|
||||
"-Dsun.io.useCanonCaches=false",
|
||||
"-Dplugin.path=${ideaPluginDir.absolutePath}",
|
||||
"-Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar"
|
||||
"-Dplugin.path=${ideaPluginDir.absolutePath}"
|
||||
)
|
||||
|
||||
if (rootProject.findProperty("versions.androidStudioRelease") != null) {
|
||||
|
||||
@@ -47,7 +47,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
}
|
||||
|
||||
private fun prepareAndroidModule() {
|
||||
println("Copying kotlin-runtime.jar and kotlin-reflect.jar in android module...")
|
||||
println("Copying kotlin-stdlib.jar and kotlin-reflect.jar in android module...")
|
||||
copyKotlinRuntimeJars()
|
||||
|
||||
println("Check 'libs' folder in tested android module...")
|
||||
@@ -60,7 +60,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
||||
private fun copyKotlinRuntimeJars() {
|
||||
FileUtil.copy(
|
||||
ForTestCompileRuntime.runtimeJarForTests(),
|
||||
File(pathManager.libsFolderInAndroidTmpFolder + "/kotlin-runtime.jar")
|
||||
File(pathManager.libsFolderInAndroidTmpFolder + "/kotlin-stdlib.jar")
|
||||
)
|
||||
FileUtil.copy(
|
||||
ForTestCompileRuntime.reflectJarForTests(),
|
||||
|
||||
@@ -60,7 +60,7 @@ abstract class FunctionsFromAnyGenerator(protected val declaration: KtClassOrObj
|
||||
generateEqualsMethod(function, properties)
|
||||
}
|
||||
|
||||
private val primaryConstructorProperties: List<PropertyDescriptor>
|
||||
protected val primaryConstructorProperties: List<PropertyDescriptor>
|
||||
get() = primaryConstructorParameters
|
||||
.filter { it.hasValOrVar() }
|
||||
.map { bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it)!! }
|
||||
|
||||
@@ -25,10 +25,12 @@ import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
@@ -165,10 +167,17 @@ public abstract class AnnotationCodegen {
|
||||
if (isInvisibleFromTheOutside(descriptor)) return;
|
||||
if (descriptor instanceof ValueParameterDescriptor && isInvisibleFromTheOutside(descriptor.getContainingDeclaration())) return;
|
||||
|
||||
// No need to annotate annotation methods since they're always non-null
|
||||
if (descriptor instanceof PropertyGetterDescriptor &&
|
||||
DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (returnType != null && !AsmUtil.isPrimitive(returnType)) {
|
||||
generateNullabilityAnnotation(descriptor.getReturnType(), annotationDescriptorsAlreadyPresent);
|
||||
}
|
||||
}
|
||||
|
||||
if (unwrapped instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) unwrapped;
|
||||
if (classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) {
|
||||
@@ -337,11 +346,22 @@ public abstract class AnnotationCodegen {
|
||||
}
|
||||
|
||||
private void genAnnotationArguments(AnnotationDescriptor annotationDescriptor, AnnotationVisitor annotationVisitor) {
|
||||
ClassDescriptor annotationClass = DescriptorUtilsKt.getAnnotationClass(annotationDescriptor);
|
||||
for (Map.Entry<Name, ConstantValue<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
|
||||
genCompileTimeValue(entry.getKey().asString(), entry.getValue(), annotationVisitor);
|
||||
genCompileTimeValue(getAnnotationArgumentJvmName(annotationClass, entry.getKey()), entry.getValue(), annotationVisitor);
|
||||
}
|
||||
}
|
||||
|
||||
private String getAnnotationArgumentJvmName(@Nullable ClassDescriptor annotationClass, @NotNull Name parameterName) {
|
||||
if (annotationClass == null) return parameterName.asString();
|
||||
|
||||
Collection<PropertyDescriptor> variables =
|
||||
annotationClass.getUnsubstitutedMemberScope().getContributedVariables(parameterName, NoLookupLocation.FROM_BACKEND);
|
||||
if (variables.size() != 1) return parameterName.asString();
|
||||
|
||||
return typeMapper.mapAnnotationParameterName(variables.iterator().next());
|
||||
}
|
||||
|
||||
private void genCompileTimeValue(
|
||||
@Nullable String name,
|
||||
@NotNull ConstantValue<?> value,
|
||||
|
||||
@@ -4605,7 +4605,8 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
|
||||
CodegenUtilKt.generateAsCast(v, rightKotlinType, boxedRightType, safeAs);
|
||||
CodegenUtilKt.generateAsCast(v, rightKotlinType, boxedRightType, safeAs,
|
||||
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
|
||||
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
@@ -4658,7 +4659,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return null;
|
||||
}
|
||||
|
||||
CodegenUtilKt.generateIsCheck(v, rhsKotlinType, type);
|
||||
CodegenUtilKt.generateIsCheck(v, rhsKotlinType, type, state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
@@ -231,7 +232,7 @@ public class FunctionCodegen {
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, CodegenUtilKt.unwrapFrontendVersion(functionDescriptor), asmMethod);
|
||||
}
|
||||
|
||||
generateMethodAnnotations(functionDescriptor, asmMethod, mv);
|
||||
generateMethodAnnotations(functionDescriptor, asmMethod, mv, memberCodegen, typeMapper);
|
||||
|
||||
generateParameterAnnotations(functionDescriptor, mv, jvmSignature);
|
||||
GenerateJava8ParameterNamesKt.generateParameterNames(functionDescriptor, mv, jvmSignature, state, (flags & ACC_SYNTHETIC) != 0);
|
||||
@@ -431,7 +432,8 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
if (!functionDescriptor.isExternal()) {
|
||||
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen, state.getJvmDefaultMode());
|
||||
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen, state.getJvmDefaultMode(),
|
||||
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
|
||||
}
|
||||
else if (staticInCompanionObject) {
|
||||
// native @JvmStatic foo() in companion object should delegate to the static native function moved to the outer class
|
||||
@@ -472,14 +474,6 @@ public class FunctionCodegen {
|
||||
);
|
||||
}
|
||||
|
||||
private void generateMethodAnnotations(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
Method asmMethod,
|
||||
MethodVisitor mv
|
||||
) {
|
||||
generateMethodAnnotations(functionDescriptor, asmMethod, mv, memberCodegen, typeMapper);
|
||||
}
|
||||
|
||||
public static void generateMethodAnnotations(
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
Method asmMethod,
|
||||
@@ -614,7 +608,8 @@ public class FunctionCodegen {
|
||||
@NotNull JvmMethodSignature signature,
|
||||
@NotNull FunctionGenerationStrategy strategy,
|
||||
@NotNull MemberCodegen<?> parentCodegen,
|
||||
@NotNull JvmDefaultMode jvmDefaultMode
|
||||
@NotNull JvmDefaultMode jvmDefaultMode,
|
||||
boolean isReleaseCoroutines
|
||||
) {
|
||||
mv.visitCode();
|
||||
|
||||
@@ -624,7 +619,8 @@ public class FunctionCodegen {
|
||||
KotlinTypeMapper typeMapper = parentCodegen.typeMapper;
|
||||
if (BuiltinSpecialBridgesUtil.shouldHaveTypeSafeBarrier(functionDescriptor, typeMapper::mapAsmMethod)) {
|
||||
generateTypeCheckBarrierIfNeeded(
|
||||
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), null, typeMapper);
|
||||
new InstructionAdapter(mv), functionDescriptor, signature.getReturnType(), null, typeMapper,
|
||||
isReleaseCoroutines);
|
||||
}
|
||||
|
||||
Label methodEnd;
|
||||
@@ -1447,7 +1443,8 @@ public class FunctionCodegen {
|
||||
MemberCodegen.markLineNumberForDescriptor(owner.getThisDescriptor(), iv);
|
||||
|
||||
if (delegateTo.getArgumentTypes().length > 0 && isSpecialBridge) {
|
||||
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes(), typeMapper);
|
||||
generateTypeCheckBarrierIfNeeded(iv, descriptor, bridge.getReturnType(), delegateTo.getArgumentTypes(), typeMapper,
|
||||
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.ReleaseCoroutines));
|
||||
}
|
||||
|
||||
iv.load(0, OBJECT_TYPE);
|
||||
@@ -1492,7 +1489,8 @@ public class FunctionCodegen {
|
||||
@NotNull FunctionDescriptor descriptor,
|
||||
@NotNull Type returnType,
|
||||
@Nullable Type[] delegateParameterTypes,
|
||||
@NotNull KotlinTypeMapper typeMapper
|
||||
@NotNull KotlinTypeMapper typeMapper,
|
||||
boolean isReleaseCoroutines
|
||||
) {
|
||||
BuiltinMethodsWithSpecialGenericSignature.TypeSafeBarrierDescription typeSafeBarrierDescription =
|
||||
BuiltinMethodsWithSpecialGenericSignature.getDefaultValueForOverriddenBuiltinFunction(descriptor);
|
||||
@@ -1526,7 +1524,7 @@ public class FunctionCodegen {
|
||||
} else {
|
||||
targetBoxedType = boxType(delegateParameterTypes[i]);
|
||||
}
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, targetBoxedType);
|
||||
CodegenUtilKt.generateIsCheck(iv, kotlinType, targetBoxedType, isReleaseCoroutines);
|
||||
iv.ifeq(defaultBranch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,12 @@ class JvmRuntimeTypes(module: ModuleDescriptor, private val languageVersionSetti
|
||||
createCoroutineSuperClass("RestrictedSuspendLambda")
|
||||
}
|
||||
|
||||
private val suspendFunctionInterface by lazy {
|
||||
if (languageVersionSettings.isReleaseCoroutines())
|
||||
createClass(kotlinCoroutinesJvmInternalPackage, "SuspendFunction", ClassKind.INTERFACE)
|
||||
else null
|
||||
}
|
||||
|
||||
private fun createCoroutineSuperClass(className: String): ClassDescriptor {
|
||||
return if (languageVersionSettings.isReleaseCoroutines())
|
||||
createClass(kotlinCoroutinesJvmInternalPackage, className)
|
||||
@@ -145,7 +151,8 @@ class JvmRuntimeTypes(module: ModuleDescriptor, private val languageVersionSetti
|
||||
referencedFunction.isSuspend
|
||||
)
|
||||
|
||||
return listOf(functionReference.defaultType, functionType)
|
||||
val suspendFunctionType = if (referencedFunction.isSuspend) suspendFunctionInterface?.defaultType else null
|
||||
return listOfNotNull(functionReference.defaultType, functionType, suspendFunctionType)
|
||||
}
|
||||
|
||||
fun getSupertypeForPropertyReference(descriptor: VariableDescriptorWithAccessors, isMutable: Boolean, isBound: Boolean): KotlinType {
|
||||
|
||||
@@ -56,8 +56,7 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAn
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTIES;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||
@@ -266,15 +265,21 @@ public class PropertyCodegen {
|
||||
@Nullable FunctionDescriptor expectedAnnotationConstructor
|
||||
) {
|
||||
JvmMethodGenericSignature signature = typeMapper.mapAnnotationParameterSignature(descriptor);
|
||||
String name = parameter.getName();
|
||||
if (name == null) return;
|
||||
Method asmMethod = signature.getAsmMethod();
|
||||
MethodVisitor mv = v.newMethod(
|
||||
JvmDeclarationOriginKt.OtherOrigin(parameter, descriptor), ACC_PUBLIC | ACC_ABSTRACT, name,
|
||||
signature.getAsmMethod().getDescriptor(),
|
||||
JvmDeclarationOriginKt.OtherOrigin(parameter, descriptor),
|
||||
ACC_PUBLIC | ACC_ABSTRACT,
|
||||
asmMethod.getName(),
|
||||
asmMethod.getDescriptor(),
|
||||
signature.getGenericsSignature(),
|
||||
null
|
||||
);
|
||||
|
||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||
assert getter != null : "Annotation property should have a getter: " + descriptor;
|
||||
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, getter, asmMethod);
|
||||
FunctionCodegen.generateMethodAnnotations(getter, asmMethod, mv, memberCodegen, typeMapper);
|
||||
|
||||
KtExpression defaultValue = loadAnnotationArgumentDefaultValue(parameter, descriptor, expectedAnnotationConstructor);
|
||||
if (defaultValue != null) {
|
||||
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -62,7 +62,8 @@ import java.util.*
|
||||
fun generateIsCheck(
|
||||
v: InstructionAdapter,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type
|
||||
asmType: Type,
|
||||
isReleaseCoroutines: Boolean
|
||||
) {
|
||||
if (TypeUtils.isNullableType(kotlinType)) {
|
||||
val nope = Label()
|
||||
@@ -73,7 +74,7 @@ fun generateIsCheck(
|
||||
|
||||
ifnull(nope)
|
||||
|
||||
TypeIntrinsics.instanceOf(this, kotlinType, asmType)
|
||||
TypeIntrinsics.instanceOf(this, kotlinType, asmType, isReleaseCoroutines)
|
||||
|
||||
goTo(end)
|
||||
|
||||
@@ -84,7 +85,7 @@ fun generateIsCheck(
|
||||
mark(end)
|
||||
}
|
||||
} else {
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType, isReleaseCoroutines)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +93,8 @@ fun generateAsCast(
|
||||
v: InstructionAdapter,
|
||||
kotlinType: KotlinType,
|
||||
asmType: Type,
|
||||
isSafe: Boolean
|
||||
isSafe: Boolean,
|
||||
isReleaseCoroutines: Boolean
|
||||
) {
|
||||
if (!isSafe) {
|
||||
if (!TypeUtils.isNullableType(kotlinType)) {
|
||||
@@ -101,7 +103,7 @@ fun generateAsCast(
|
||||
} else {
|
||||
with(v) {
|
||||
dup()
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType)
|
||||
TypeIntrinsics.instanceOf(v, kotlinType, asmType, isReleaseCoroutines)
|
||||
val ok = Label()
|
||||
ifne(ok)
|
||||
pop()
|
||||
|
||||
@@ -432,7 +432,8 @@ class CoroutineCodegenForLambda private constructor(
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = v.thisName,
|
||||
isForNamedFunction = false,
|
||||
languageVersionSettings = languageVersionSettings
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
sourceFile = element.containingFile.name
|
||||
)
|
||||
}
|
||||
|
||||
@@ -511,7 +512,7 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
|
||||
v.newField(
|
||||
JvmDeclarationOrigin.NO_ORIGIN, Opcodes.ACC_SYNTHETIC or AsmUtil.NO_FLAG_PACKAGE_PRIVATE,
|
||||
DATA_FIELD_NAME, AsmTypes.OBJECT_TYPE.descriptor, null, null
|
||||
languageVersionSettings.dataFieldName(), AsmTypes.OBJECT_TYPE.descriptor, null, null
|
||||
)
|
||||
|
||||
if (!languageVersionSettings.isReleaseCoroutines()) {
|
||||
@@ -529,7 +530,7 @@ class CoroutineCodegenForNamedFunction private constructor(
|
||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
StackValue.field(
|
||||
AsmTypes.OBJECT_TYPE, Type.getObjectType(v.thisName), DATA_FIELD_NAME, false,
|
||||
AsmTypes.OBJECT_TYPE, Type.getObjectType(v.thisName), languageVersionSettings.dataFieldName(), false,
|
||||
StackValue.LOCAL_0
|
||||
).store(StackValue.local(1, AsmTypes.OBJECT_TYPE), codegen.v)
|
||||
|
||||
|
||||
@@ -34,6 +34,14 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
|
||||
|
||||
private const val COROUTINES_METADATA_SOURCE_FILES_JVM_NAME = "f"
|
||||
private const val COROUTINES_METADATA_LINE_NUMBERS_JVM_NAME = "l"
|
||||
private const val COROUTINES_METADATA_LOCAL_NAMES_JVM_NAME = "n"
|
||||
private const val COROUTINES_METADATA_SPILLED_JVM_NAME = "s"
|
||||
private const val COROUTINES_METADATA_INDEX_TO_LABEL_JVM_NAME = "i"
|
||||
private const val COROUTINES_METADATA_METHOD_NAME_JVM_NAME = "m"
|
||||
private const val COROUTINES_METADATA_CLASS_NAME_JVM_NAME = "c"
|
||||
|
||||
class CoroutineTransformerMethodVisitor(
|
||||
delegate: MethodVisitor,
|
||||
access: Int,
|
||||
@@ -47,10 +55,13 @@ class CoroutineTransformerMethodVisitor(
|
||||
private val shouldPreserveClassInitialization: Boolean,
|
||||
private val lineNumber: Int,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val sourceFile: String,
|
||||
// It's only matters for named functions, may differ from '!isStatic(access)' in case of DefaultImpls
|
||||
private val needDispatchReceiver: Boolean = false,
|
||||
// May differ from containingClassInternalName in case of DefaultImpls
|
||||
private val internalNameForDispatchReceiver: String? = null
|
||||
private val internalNameForDispatchReceiver: String? = null,
|
||||
// For crossinline lambdas we do not generate DebugMetadata annotation, otherwise it will be generated twice
|
||||
private val isCrossinlineLambda: Boolean = false
|
||||
) : TransformationMethodVisitor(delegate, access, name, desc, signature, exceptions) {
|
||||
|
||||
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
|
||||
@@ -109,7 +120,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
UninitializedStoresProcessor(methodNode, shouldPreserveClassInitialization).run()
|
||||
|
||||
spillVariables(suspensionPoints, methodNode)
|
||||
val spilledToVariableMapping = spillVariables(suspensionPoints, methodNode)
|
||||
|
||||
val suspendMarkerVarIndex = methodNode.maxLocals++
|
||||
|
||||
@@ -118,9 +129,9 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
|
||||
val defaultLabel = LabelNode()
|
||||
val tableSwitchLabel = LabelNode()
|
||||
methodNode.instructions.apply {
|
||||
val startLabel = LabelNode()
|
||||
val tableSwitchLabel = LabelNode()
|
||||
|
||||
// tableswitch(this.label)
|
||||
insertBefore(
|
||||
@@ -164,6 +175,45 @@ class CoroutineTransformerMethodVisitor(
|
||||
defaultLabel
|
||||
)
|
||||
}
|
||||
|
||||
if (languageVersionSettings.isReleaseCoroutines() && !isCrossinlineLambda) {
|
||||
val suspensionPointLabelNodes = listOf(tableSwitchLabel) + suspensionPointLabels.map {
|
||||
it.label.info.safeAs<LabelNode>()
|
||||
.sure { "suspensionPointLabel shall have valid info. Check state-machine generation." }
|
||||
}
|
||||
writeDebugMetadata(methodNode, suspensionPointLabelNodes, spilledToVariableMapping)
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeDebugMetadata(
|
||||
methodNode: MethodNode,
|
||||
suspensionPointLabels: List<LabelNode>,
|
||||
spilledToLocalMapping: List<List<SpilledVariableDescriptor>>
|
||||
) {
|
||||
val lines = suspensionPointLabels.map { label ->
|
||||
label.safeAs<AbstractInsnNode>()?.findNextOrNull { it is LineNumberNode }.safeAs<LineNumberNode>()?.line ?: -1
|
||||
}
|
||||
val metadata = classBuilderForCoroutineState.newAnnotation(DEBUG_METADATA_ANNOTATION_ASM_TYPE.descriptor, true)
|
||||
// TODO: support inlined functions (similar to SMAP)
|
||||
metadata.visitArray(COROUTINES_METADATA_SOURCE_FILES_JVM_NAME).also { v ->
|
||||
lines.forEach { v.visit(null, sourceFile) }
|
||||
}.visitEnd()
|
||||
metadata.visit(COROUTINES_METADATA_LINE_NUMBERS_JVM_NAME, lines.toIntArray())
|
||||
|
||||
val debugIndexToLabel = spilledToLocalMapping.withIndex().flatMap { (labelIndex, list) ->
|
||||
list.map { labelIndex }
|
||||
}
|
||||
val variablesMapping = spilledToLocalMapping.flatten()
|
||||
metadata.visit(COROUTINES_METADATA_INDEX_TO_LABEL_JVM_NAME, debugIndexToLabel.toIntArray())
|
||||
metadata.visitArray(COROUTINES_METADATA_SPILLED_JVM_NAME).also { v ->
|
||||
variablesMapping.forEach { v.visit(null, it.fieldName) }
|
||||
}.visitEnd()
|
||||
metadata.visitArray(COROUTINES_METADATA_LOCAL_NAMES_JVM_NAME).also { v ->
|
||||
variablesMapping.forEach { v.visit(null, it.variableName) }
|
||||
}.visitEnd()
|
||||
metadata.visit(COROUTINES_METADATA_METHOD_NAME_JVM_NAME, methodNode.name)
|
||||
metadata.visit(COROUTINES_METADATA_CLASS_NAME_JVM_NAME, containingClassInternalName)
|
||||
metadata.visitEnd()
|
||||
}
|
||||
|
||||
private fun addContinuationToLvt(methodNode: MethodNode, startLabel: LabelNode, endLabel: LabelNode) {
|
||||
@@ -307,7 +357,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
visitLabel(afterCoroutineStateCreated)
|
||||
|
||||
visitVarInsn(Opcodes.ALOAD, continuationIndex)
|
||||
getfield(classBuilderForCoroutineState.thisName, DATA_FIELD_NAME, AsmTypes.OBJECT_TYPE.descriptor)
|
||||
getfield(classBuilderForCoroutineState.thisName, languageVersionSettings.dataFieldName(), AsmTypes.OBJECT_TYPE.descriptor)
|
||||
visitVarInsn(Opcodes.ASTORE, dataIndex)
|
||||
|
||||
if (!languageVersionSettings.isReleaseCoroutines()) {
|
||||
@@ -364,7 +414,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun spillVariables(suspensionPoints: List<SuspensionPoint>, methodNode: MethodNode) {
|
||||
private fun spillVariables(suspensionPoints: List<SuspensionPoint>, methodNode: MethodNode): List<List<SpilledVariableDescriptor>> {
|
||||
val instructions = methodNode.instructions
|
||||
val frames = performRefinedTypeAnalysis(methodNode, containingClassInternalName)
|
||||
fun AbstractInsnNode.index() = instructions.indexOf(this)
|
||||
@@ -373,6 +423,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
val postponedActions = mutableListOf<() -> Unit>()
|
||||
val maxVarsCountByType = mutableMapOf<Type, Int>()
|
||||
val livenessFrames = analyzeLiveness(methodNode)
|
||||
val spilledToVariableMapping = arrayListOf<List<SpilledVariableDescriptor>>()
|
||||
|
||||
for (suspension in suspensionPoints) {
|
||||
val suspensionCallBegin = suspension.suspensionCallBegin
|
||||
@@ -399,6 +450,8 @@ class CoroutineTransformerMethodVisitor(
|
||||
// NB: it's also rather useful for sake of optimization
|
||||
val livenessFrame = livenessFrames[suspensionCallBegin.index()]
|
||||
|
||||
val spilledToVariable = arrayListOf<SpilledVariableDescriptor>()
|
||||
|
||||
// 0 - this
|
||||
// 1 - parameter
|
||||
// ...
|
||||
@@ -434,6 +487,8 @@ class CoroutineTransformerMethodVisitor(
|
||||
varsCountByType[normalizedType] = indexBySort
|
||||
|
||||
val fieldName = normalizedType.fieldNameForVar(indexBySort)
|
||||
localVariableName(methodNode, index, suspension.suspensionCallEnd.next.index())
|
||||
?.let { spilledToVariable.add(SpilledVariableDescriptor(fieldName, it)) }
|
||||
|
||||
postponedActions.add {
|
||||
with(instructions) {
|
||||
@@ -456,6 +511,8 @@ class CoroutineTransformerMethodVisitor(
|
||||
}
|
||||
}
|
||||
|
||||
spilledToVariableMapping.add(spilledToVariable)
|
||||
|
||||
varsCountByType.forEach {
|
||||
maxVarsCountByType[it.key] = Math.max(maxVarsCountByType[it.key] ?: 0, it.value)
|
||||
}
|
||||
@@ -472,6 +529,19 @@ class CoroutineTransformerMethodVisitor(
|
||||
)
|
||||
}
|
||||
}
|
||||
return spilledToVariableMapping
|
||||
}
|
||||
|
||||
private fun localVariableName(
|
||||
methodNode: MethodNode,
|
||||
index: Int,
|
||||
suspensionCallIndex: Int
|
||||
): String? {
|
||||
val variable = methodNode.localVariables.find {
|
||||
index == it.index && methodNode.instructions.indexOf(it.start) <= suspensionCallIndex
|
||||
&& suspensionCallIndex < methodNode.instructions.indexOf(it.end)
|
||||
}
|
||||
return variable?.name
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -637,6 +707,8 @@ class CoroutineTransformerMethodVisitor(
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
private data class SpilledVariableDescriptor(val fieldName: String, val variableName: String)
|
||||
}
|
||||
|
||||
internal fun InstructionAdapter.generateContinuationConstructorCall(
|
||||
|
||||
@@ -70,7 +70,8 @@ open class SuspendFunctionGenerationStrategy(
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
|
||||
languageVersionSettings = languageVersionSettings
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
sourceFile = declaration.containingFile.name
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -54,20 +54,26 @@ const val COROUTINE_LABEL_FIELD_NAME = "label"
|
||||
const val SUSPEND_FUNCTION_CREATE_METHOD_NAME = "create"
|
||||
const val DO_RESUME_METHOD_NAME = "doResume"
|
||||
const val INVOKE_SUSPEND_METHOD_NAME = "invokeSuspend"
|
||||
const val DATA_FIELD_NAME = "data"
|
||||
const val EXCEPTION_FIELD_NAME = "exception"
|
||||
|
||||
private val RELEASE_COROUTINES_VERSION_SETTINGS = LanguageVersionSettingsImpl(LanguageVersion.KOTLIN_1_3, ApiVersion.KOTLIN_1_3)
|
||||
|
||||
fun LanguageVersionSettings.isResumeImplMethodName(name: String) =
|
||||
if (isReleaseCoroutines())
|
||||
name == INVOKE_SUSPEND_METHOD_NAME
|
||||
else
|
||||
name == DO_RESUME_METHOD_NAME
|
||||
|
||||
fun LanguageVersionSettings.dataFieldName(): String = if (isReleaseCoroutines()) "result" else "data"
|
||||
|
||||
fun isResumeImplMethodNameFromAnyLanguageSettings(name: String) = name == INVOKE_SUSPEND_METHOD_NAME || name == DO_RESUME_METHOD_NAME
|
||||
|
||||
fun LanguageVersionSettings.coroutinesJvmInternalPackageFqName() =
|
||||
coroutinesPackageFqName().child(Name.identifier("jvm")).child(Name.identifier("internal"))
|
||||
|
||||
val DEBUG_METADATA_ANNOTATION_ASM_TYPE = RELEASE_COROUTINES_VERSION_SETTINGS.coroutinesJvmInternalPackageFqName()
|
||||
.child(Name.identifier("DebugMetadata")).topLevelClassAsmType()
|
||||
|
||||
fun LanguageVersionSettings.continuationAsmType() =
|
||||
continuationInterfaceFqName().topLevelClassAsmType()
|
||||
|
||||
|
||||
@@ -452,7 +452,9 @@ class AnonymousObjectTransformer(
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
shouldPreserveClassInitialization = state.constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
containingClassInternalName = builder.thisName,
|
||||
isForNamedFunction = false
|
||||
isForNamedFunction = false,
|
||||
sourceFile = sourceInfo ?: "",
|
||||
isCrossinlineLambda = inliningContext.isContinuation
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -481,7 +483,8 @@ class AnonymousObjectTransformer(
|
||||
containingClassInternalName = builder.thisName,
|
||||
isForNamedFunction = true,
|
||||
needDispatchReceiver = true,
|
||||
internalNameForDispatchReceiver = builder.thisName
|
||||
internalNameForDispatchReceiver = builder.thisName,
|
||||
sourceFile = sourceInfo ?: ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.bytecode
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.classId
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnly
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -74,7 +75,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
|
||||
private val initialFrameSize = codegen.frameMap.currentSize
|
||||
|
||||
private val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings)
|
||||
private val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings, state.languageVersionSettings.isReleaseCoroutines())
|
||||
|
||||
protected val functionDescriptor: FunctionDescriptor =
|
||||
if (InlineUtil.isArrayConstructorWithLambda(function))
|
||||
|
||||
@@ -57,7 +57,7 @@ class ReificationArgument(
|
||||
}
|
||||
}
|
||||
|
||||
class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?) {
|
||||
class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?, private val isReleaseCoroutines: Boolean) {
|
||||
enum class OperationKind {
|
||||
NEW_ARRAY, AS, SAFE_AS, IS, JAVA_CLASS, ENUM_REIFIED;
|
||||
|
||||
@@ -168,7 +168,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
if (stubCheckcast !is TypeInsnNode) return false
|
||||
|
||||
val newMethodNode = MethodNode(API)
|
||||
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
|
||||
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe, isReleaseCoroutines)
|
||||
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubCheckcast)
|
||||
@@ -188,7 +188,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
|
||||
if (stubInstanceOf !is TypeInsnNode) return false
|
||||
|
||||
val newMethodNode = MethodNode(API)
|
||||
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
|
||||
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType, isReleaseCoroutines)
|
||||
|
||||
instructions.insert(insn, newMethodNode.instructions)
|
||||
instructions.remove(stubInstanceOf)
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.context.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
@@ -188,7 +189,10 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
else -> FunctionGenerationStrategy.FunctionDefault(state, expression as KtDeclarationWithBody)
|
||||
}
|
||||
|
||||
FunctionCodegen.generateMethodBody(adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen, state.jvmDefaultMode)
|
||||
FunctionCodegen.generateMethodBody(
|
||||
adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen, state.jvmDefaultMode,
|
||||
state.languageVersionSettings.isReleaseCoroutines()
|
||||
)
|
||||
|
||||
if (isLambda) {
|
||||
codegen.propagateChildReifiedTypeParametersUsages(parentCodegen.reifiedTypeParametersUsages)
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.intrinsics
|
||||
@@ -19,8 +8,10 @@ package org.jetbrains.kotlin.codegen.intrinsics
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -28,7 +19,8 @@ import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import kotlin.text.Regex
|
||||
|
||||
object TypeIntrinsics {
|
||||
@JvmStatic fun instanceOf(v: InstructionAdapter, jetType: KotlinType, boxedAsmType: Type) {
|
||||
@JvmStatic
|
||||
fun instanceOf(v: InstructionAdapter, jetType: KotlinType, boxedAsmType: Type, isReleaseCoroutines: Boolean) {
|
||||
val functionTypeArity = getFunctionTypeArity(jetType)
|
||||
if (functionTypeArity >= 0) {
|
||||
v.iconst(functionTypeArity)
|
||||
@@ -36,6 +28,30 @@ object TypeIntrinsics {
|
||||
return
|
||||
}
|
||||
|
||||
if (isReleaseCoroutines) {
|
||||
val suspendFunctionTypeArity = getSuspendFunctionTypeArity(jetType)
|
||||
if (suspendFunctionTypeArity >= 0) {
|
||||
val notSuspendLambda = Label()
|
||||
val end = Label()
|
||||
|
||||
with(v) {
|
||||
dup()
|
||||
instanceOf(AsmTypes.SUSPEND_FUNCTION_TYPE)
|
||||
ifeq(notSuspendLambda)
|
||||
iconst(suspendFunctionTypeArity + 1)
|
||||
typeIntrinsic(IS_FUNCTON_OF_ARITY_METHOD_NAME, IS_FUNCTON_OF_ARITY_DESCRIPTOR)
|
||||
goTo(end)
|
||||
|
||||
mark(notSuspendLambda)
|
||||
pop()
|
||||
iconst(0)
|
||||
|
||||
mark(end)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val isMutableCollectionMethodName = getIsMutableCollectionMethodName(jetType)
|
||||
if (isMutableCollectionMethodName != null) {
|
||||
v.typeIntrinsic(isMutableCollectionMethodName, IS_MUTABLE_COLLECTION_METHOD_DESCRIPTOR)
|
||||
@@ -148,16 +164,25 @@ object TypeIntrinsics {
|
||||
}
|
||||
|
||||
private val KOTLIN_FUNCTION_INTERFACE_REGEX = Regex("^kotlin\\.Function([0-9]+)$")
|
||||
private val KOTLIN_SUSPEND_FUNCTION_INTERFACE_REGEX = Regex("^kotlin\\.coroutines\\.SuspendFunction([0-9]+)$")
|
||||
|
||||
/**
|
||||
* @return function type arity (non-negative), or -1 if the given type is not a function type
|
||||
*/
|
||||
private fun getFunctionTypeArity(jetType: KotlinType): Int {
|
||||
val classFqName = getClassFqName(jetType) ?: return -1
|
||||
val match = KOTLIN_FUNCTION_INTERFACE_REGEX.find(classFqName.asString()) ?: return -1
|
||||
private fun getFunctionTypeArity(kotlinType: KotlinType): Int = getFunctionTypeArityByRegex(kotlinType, KOTLIN_FUNCTION_INTERFACE_REGEX)
|
||||
|
||||
private fun getFunctionTypeArityByRegex(kotlinType: KotlinType, regex: Regex): Int {
|
||||
val classFqName = getClassFqName(kotlinType) ?: return -1
|
||||
val match = regex.find(classFqName.asString()) ?: return -1
|
||||
return Integer.valueOf(match.groups[1]!!.value)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return function type arity (non-negative, not counting continuation), or -1 if the given type is not a function type
|
||||
*/
|
||||
private fun getSuspendFunctionTypeArity(kotlinType: KotlinType): Int =
|
||||
getFunctionTypeArityByRegex(kotlinType, KOTLIN_SUSPEND_FUNCTION_INTERFACE_REGEX)
|
||||
|
||||
private fun typeIntrinsicNode(methodName: String, methodDescriptor: String): MethodInsnNode =
|
||||
MethodInsnNode(Opcodes.INVOKESTATIC, INTRINSICS_CLASS, methodName, methodDescriptor, false)
|
||||
|
||||
|
||||
@@ -489,7 +489,13 @@ public class KotlinTypeMapper {
|
||||
sw.writeReturnType();
|
||||
mapType(descriptor.getType(), sw, TypeMappingMode.VALUE_FOR_ANNOTATION);
|
||||
sw.writeReturnTypeEnd();
|
||||
return sw.makeJvmMethodSignature(descriptor.getName().asString());
|
||||
return sw.makeJvmMethodSignature(mapAnnotationParameterName(descriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String mapAnnotationParameterName(@NotNull PropertyDescriptor descriptor) {
|
||||
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||
return getter != null ? mapFunctionName(getter, OwnerKind.IMPLEMENTATION) : descriptor.getName().asString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -651,17 +657,21 @@ public class KotlinTypeMapper {
|
||||
List<TypeParameterDescriptor> parameters = classDescriptor.getDeclaredTypeParameters();
|
||||
List<TypeProjection> arguments = type.getArguments();
|
||||
|
||||
if (classDescriptor instanceof FunctionClassDescriptor &&
|
||||
((FunctionClassDescriptor) classDescriptor).getFunctionKind() == FunctionClassDescriptor.Kind.KFunction) {
|
||||
// kotlin.reflect.KFunction{n}<P1, ... Pn, R> is mapped to kotlin.reflect.KFunction<R> on JVM (see JavaToKotlinClassMap).
|
||||
// So for these classes, we need to skip all type arguments except the very last one
|
||||
writeGenericArguments(
|
||||
signatureVisitor,
|
||||
Collections.singletonList(CollectionsKt.last(arguments)),
|
||||
Collections.singletonList(CollectionsKt.last(parameters)),
|
||||
mode
|
||||
);
|
||||
return;
|
||||
if (classDescriptor instanceof FunctionClassDescriptor) {
|
||||
FunctionClassDescriptor functionClass = (FunctionClassDescriptor) classDescriptor;
|
||||
if (functionClass.hasBigArity() ||
|
||||
functionClass.getFunctionKind() == FunctionClassDescriptor.Kind.KFunction) {
|
||||
// kotlin.reflect.KFunction{n}<P1, ..., Pn, R> is mapped to kotlin.reflect.KFunction<R> (for all n), and
|
||||
// kotlin.Function{n}<P1, ..., Pn, R> is mapped to kotlin.jvm.functions.FunctionN<R> (for n > 22).
|
||||
// So for these classes, we need to skip all type arguments except the very last one
|
||||
writeGenericArguments(
|
||||
signatureVisitor,
|
||||
Collections.singletonList(CollectionsKt.last(arguments)),
|
||||
Collections.singletonList(CollectionsKt.last(parameters)),
|
||||
mode
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
writeGenericArguments(signatureVisitor, arguments, parameters, mode);
|
||||
@@ -1072,6 +1082,11 @@ public class KotlinTypeMapper {
|
||||
return name;
|
||||
}
|
||||
|
||||
String manglingSuffix = InlineClassManglingUtilsKt.getInlineClassValueParametersManglingSuffix(descriptor);
|
||||
if (manglingSuffix != null) {
|
||||
name += "-" + manglingSuffix;
|
||||
}
|
||||
|
||||
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||
if (Visibilities.isPrivate(descriptor.getVisibility()) && !(descriptor instanceof ConstructorDescriptor) && !"<clinit>".equals(name)) {
|
||||
String partName = getPartSimpleNameForMangling(descriptor);
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen.state
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.load.kotlin.getRepresentativeUpperBound
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.SUCCESS_OR_FAILURE_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.security.MessageDigest
|
||||
|
||||
fun getInlineClassValueParametersManglingSuffix(descriptor: CallableMemberDescriptor): String? {
|
||||
if (descriptor !is FunctionDescriptor) return null
|
||||
if (descriptor is ConstructorDescriptor) return null
|
||||
|
||||
val actualValueParameterTypes = listOfNotNull(descriptor.extensionReceiverParameter?.type) + descriptor.valueParameters.map { it.type }
|
||||
|
||||
if (actualValueParameterTypes.none { it.requiresFunctionNameMangling() }) return null
|
||||
|
||||
return md5radix36string(collectSignatureForMangling(actualValueParameterTypes))
|
||||
}
|
||||
|
||||
private fun KotlinType.requiresFunctionNameMangling() =
|
||||
isInlineClassThatRequiresMangling() || isTypeParameterWithUpperBoundThatRequiresMangling()
|
||||
|
||||
private fun KotlinType.isInlineClassThatRequiresMangling() =
|
||||
isInlineClassType() && !isDontMangleClass(this.constructor.declarationDescriptor as ClassDescriptor)
|
||||
|
||||
private fun isDontMangleClass(classDescriptor: ClassDescriptor) =
|
||||
classDescriptor.fqNameSafe == SUCCESS_OR_FAILURE_FQ_NAME
|
||||
|
||||
private fun KotlinType.isTypeParameterWithUpperBoundThatRequiresMangling(): Boolean {
|
||||
val descriptor = constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false
|
||||
return getRepresentativeUpperBound(descriptor).requiresFunctionNameMangling()
|
||||
}
|
||||
|
||||
private fun collectSignatureForMangling(types: List<KotlinType>) =
|
||||
types.joinToString { getSignatureElementForMangling(it) }
|
||||
|
||||
private fun getSignatureElementForMangling(type: KotlinType): String = buildString {
|
||||
val descriptor = type.constructor.declarationDescriptor ?: return ""
|
||||
when (descriptor) {
|
||||
is ClassDescriptor -> {
|
||||
append('L')
|
||||
append(descriptor.fqNameUnsafe)
|
||||
if (type.isMarkedNullable) append('?')
|
||||
append(';')
|
||||
}
|
||||
|
||||
is TypeParameterDescriptor -> {
|
||||
append(getSignatureElementForMangling(getRepresentativeUpperBound(descriptor)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun md5radix36string(signatureForMangling: String): String {
|
||||
val d = MessageDigest.getInstance("MD5").digest(signatureForMangling.toByteArray())
|
||||
var acc = 0L
|
||||
for (i in 0..4) {
|
||||
acc = (acc shl 8) + (d[i].toLong() and 0xFFL)
|
||||
}
|
||||
return acc.toString(36)
|
||||
}
|
||||
@@ -37,12 +37,11 @@ fun patchTypeParametersForDefaultImplMethod(function: CallableMemberDescriptor):
|
||||
|
||||
val existingNames = (functionTypeParameterNames + interfaceTypeParameters.map { it.name.asString() }).toMutableSet()
|
||||
|
||||
val mappingForInterfaceTypeParameters = conflictedTypeParameters.associateBy ({ it }) {
|
||||
typeParameter ->
|
||||
val mappingForInterfaceTypeParameters = conflictedTypeParameters.associateBy({ it }) { typeParameter ->
|
||||
|
||||
val newNamePrefix = typeParameter.name.asString() + "_I"
|
||||
val newName = newNamePrefix + generateSequence(1) { x -> x + 1 }.first {
|
||||
index -> (newNamePrefix + index) !in existingNames
|
||||
val newName = newNamePrefix + generateSequence(1) { x -> x + 1 }.first { index ->
|
||||
(newNamePrefix + index) !in existingNames
|
||||
}
|
||||
|
||||
existingNames.add(newName)
|
||||
@@ -58,21 +57,25 @@ fun patchTypeParametersForDefaultImplMethod(function: CallableMemberDescriptor):
|
||||
val additionalTypeParameters = interfaceTypeParameters.map { typeParameter ->
|
||||
mappingForInterfaceTypeParameters[typeParameter] ?: typeParameter
|
||||
}
|
||||
var resultTypeParameters = mutableListOf<TypeParameterDescriptor>()
|
||||
val resultTypeParameters = mutableListOf<TypeParameterDescriptor>()
|
||||
DescriptorSubstitutor.substituteTypeParameters(additionalTypeParameters, substitution, classDescriptor, resultTypeParameters)
|
||||
|
||||
return ReceiverTypeAndTypeParameters(substitutor.substitute(classDescriptor.defaultType, Variance.INVARIANT)!!, resultTypeParameters)
|
||||
}
|
||||
|
||||
fun CallableMemberDescriptor.createTypeParameterWithNewName(descriptor: TypeParameterDescriptor, newName: String): TypeParameterDescriptorImpl {
|
||||
fun CallableMemberDescriptor.createTypeParameterWithNewName(
|
||||
descriptor: TypeParameterDescriptor,
|
||||
newName: String
|
||||
): TypeParameterDescriptorImpl {
|
||||
val newDescriptor = TypeParameterDescriptorImpl.createForFurtherModification(
|
||||
this,
|
||||
descriptor.annotations,
|
||||
descriptor.isReified,
|
||||
descriptor.variance,
|
||||
Name.identifier(newName),
|
||||
descriptor.index,
|
||||
descriptor.source)
|
||||
this,
|
||||
descriptor.annotations,
|
||||
descriptor.isReified,
|
||||
descriptor.variance,
|
||||
Name.identifier(newName),
|
||||
descriptor.index,
|
||||
descriptor.source
|
||||
)
|
||||
descriptor.upperBounds.forEach {
|
||||
newDescriptor.addUpperBound(it)
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ val testDistProjects = listOf(
|
||||
":kotlin-stdlib",
|
||||
":kotlin-stdlib-jre7",
|
||||
":kotlin-stdlib-jre8",
|
||||
":kotlin-stdlib-jdk7",
|
||||
":kotlin-stdlib-jdk8",
|
||||
":kotlin-stdlib-js",
|
||||
":kotlin-reflect",
|
||||
":kotlin-test:kotlin-test-jvm",
|
||||
|
||||
@@ -41,6 +41,14 @@ sourceSets {
|
||||
"test" { }
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
|
||||
kotlinOptions {
|
||||
languageVersion = "1.2"
|
||||
apiVersion = "1.2"
|
||||
freeCompilerArgs += "-Xskip-metadata-version-check"
|
||||
}
|
||||
}
|
||||
|
||||
testsJar {}
|
||||
|
||||
projectTest {
|
||||
|
||||
@@ -33,6 +33,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
const val WARN = "warn"
|
||||
const val ERROR = "error"
|
||||
const val ENABLE = "enable"
|
||||
const val DEFAULT = "default"
|
||||
}
|
||||
|
||||
@get:Transient
|
||||
@@ -108,7 +109,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
valueDescription = "{enable|warn|error}",
|
||||
description = "Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier"
|
||||
)
|
||||
var coroutinesState: String? by NullableStringFreezableVar(WARN)
|
||||
var coroutinesState: String? by NullableStringFreezableVar(DEFAULT)
|
||||
|
||||
@Argument(
|
||||
value = "-Xnew-inference",
|
||||
@@ -208,7 +209,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
when (coroutinesState) {
|
||||
CommonCompilerArguments.ERROR -> put(LanguageFeature.Coroutines, LanguageFeature.State.ENABLED_WITH_ERROR)
|
||||
CommonCompilerArguments.ENABLE -> put(LanguageFeature.Coroutines, LanguageFeature.State.ENABLED)
|
||||
CommonCompilerArguments.WARN -> {
|
||||
CommonCompilerArguments.WARN, CommonCompilerArguments.DEFAULT -> {
|
||||
}
|
||||
else -> {
|
||||
val message = "Invalid value of -Xcoroutines (should be: enable, warn or error): " + coroutinesState
|
||||
@@ -303,6 +304,18 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
)
|
||||
}
|
||||
|
||||
val deprecatedVersion = when {
|
||||
languageVersion < LanguageVersion.FIRST_SUPPORTED -> "Language version ${languageVersion.versionString}"
|
||||
apiVersion < LanguageVersion.FIRST_SUPPORTED -> "API version ${apiVersion.versionString}"
|
||||
else -> null
|
||||
}
|
||||
if (deprecatedVersion != null) {
|
||||
collector.report(
|
||||
CompilerMessageSeverity.STRONG_WARNING,
|
||||
"$deprecatedVersion is deprecated and its support will be removed in a future version of Kotlin"
|
||||
)
|
||||
}
|
||||
|
||||
if (progressiveMode && languageVersion < LanguageVersion.LATEST_STABLE) {
|
||||
collector.report(
|
||||
CompilerMessageSeverity.STRONG_WARNING,
|
||||
@@ -311,12 +324,23 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
)
|
||||
}
|
||||
|
||||
return LanguageVersionSettingsImpl(
|
||||
val languageVersionSettings = LanguageVersionSettingsImpl(
|
||||
languageVersion,
|
||||
ApiVersion.createByLanguageVersion(apiVersion),
|
||||
configureAnalysisFlags(collector),
|
||||
configureLanguageFeatures(collector)
|
||||
)
|
||||
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)) {
|
||||
if (coroutinesState != DEFAULT) {
|
||||
collector.report(
|
||||
CompilerMessageSeverity.STRONG_WARNING,
|
||||
"-Xcoroutines has no effect: coroutines are enabled anyway in 1.3 and beyond"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return languageVersionSettings
|
||||
}
|
||||
|
||||
private fun parseVersion(collector: MessageCollector, value: String?, versionOf: String): LanguageVersion? =
|
||||
|
||||
@@ -19,7 +19,7 @@ sourceSets {
|
||||
|
||||
runtimeJar {
|
||||
manifest.attributes.put("Main-Class", "org.jetbrains.kotlin.runner.Main")
|
||||
manifest.attributes.put("Class-Path", "kotlin-runtime.jar")
|
||||
manifest.attributes.put("Class-Path", "kotlin-stdlib.jar")
|
||||
}
|
||||
|
||||
dist()
|
||||
|
||||
@@ -96,7 +96,7 @@ object Main {
|
||||
classpath.addPath(".")
|
||||
}
|
||||
|
||||
classpath.addPath(KOTLIN_HOME.toString() + "/lib/kotlin-runtime.jar")
|
||||
classpath.addPath(KOTLIN_HOME.toString() + "/lib/kotlin-stdlib.jar")
|
||||
|
||||
if (!noReflect) {
|
||||
classpath.addPath(KOTLIN_HOME.toString() + "/lib/kotlin-reflect.jar")
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm;
|
||||
@@ -74,6 +63,8 @@ public class AsmTypes {
|
||||
public static final Type K_MUTABLE_PROPERTY1_TYPE = reflect("KMutableProperty1");
|
||||
public static final Type K_MUTABLE_PROPERTY2_TYPE = reflect("KMutableProperty2");
|
||||
|
||||
public static final Type SUSPEND_FUNCTION_TYPE = Type.getObjectType("kotlin/coroutines/jvm/internal/SuspendFunction");
|
||||
|
||||
public static final String REFLECTION = "kotlin/jvm/internal/Reflection";
|
||||
|
||||
public static final String REF_TYPE_PREFIX = "kotlin/jvm/internal/Ref$";
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.contracts.parsing
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
|
||||
interface ContractParsingDiagnosticsCollector {
|
||||
fun unsupportedFeature(languageVersionSettings: LanguageVersionSettings)
|
||||
fun contractNotAllowed(message: String)
|
||||
fun badDescription(message: String, reportOn: KtElement)
|
||||
|
||||
fun flushDiagnostics(parsingFailed: Boolean)
|
||||
fun hasErrors(): Boolean
|
||||
|
||||
|
||||
object EMPTY : ContractParsingDiagnosticsCollector {
|
||||
override fun contractNotAllowed(message: String) {}
|
||||
override fun badDescription(message: String, reportOn: KtElement) {}
|
||||
override fun unsupportedFeature(languageVersionSettings: LanguageVersionSettings) { }
|
||||
|
||||
override fun flushDiagnostics(parsingFailed: Boolean) {}
|
||||
|
||||
override fun hasErrors(): Boolean = false
|
||||
}
|
||||
}
|
||||
|
||||
class TraceBasedCollector(private val bindingTrace: BindingTrace, mainCall: KtExpression) : ContractParsingDiagnosticsCollector {
|
||||
private val diagnostics: MutableList<Diagnostic> = mutableListOf()
|
||||
private val mainCallReportTarget = (mainCall as? KtCallExpression)?.calleeExpression ?: mainCall
|
||||
|
||||
override fun contractNotAllowed(message: String) {
|
||||
diagnostics += Errors.CONTRACT_NOT_ALLOWED.on(mainCallReportTarget, message)
|
||||
}
|
||||
|
||||
override fun badDescription(message: String, reportOn: KtElement) {
|
||||
diagnostics += Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(reportOn, message)
|
||||
}
|
||||
|
||||
override fun unsupportedFeature(languageVersionSettings: LanguageVersionSettings) {
|
||||
diagnostics += Errors.UNSUPPORTED_FEATURE.on(
|
||||
mainCallReportTarget,
|
||||
LanguageFeature.AllowContractsForCustomFunctions to languageVersionSettings
|
||||
)
|
||||
}
|
||||
|
||||
override fun flushDiagnostics(parsingFailed: Boolean) {
|
||||
if (parsingFailed && diagnostics.isEmpty()) {
|
||||
diagnostics += Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(mainCallReportTarget, "Error in contract description")
|
||||
}
|
||||
|
||||
diagnostics.forEach { bindingTrace.report(it) }
|
||||
}
|
||||
|
||||
|
||||
override fun hasErrors(): Boolean = diagnostics.isNotEmpty()
|
||||
}
|
||||
@@ -21,9 +21,11 @@ import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.contracts.description.ContractDescription
|
||||
import org.jetbrains.kotlin.contracts.description.ContractProviderKey
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.isOverridable
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isContractDescriptionCallPsiCheck
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
@@ -33,47 +35,80 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
||||
|
||||
class ContractParsingServices(val languageVersionSettings: LanguageVersionSettings) {
|
||||
fun checkContractAndRecordIfPresent(expression: KtExpression, trace: BindingTrace, scope: LexicalScope, isFirstStatement: Boolean) {
|
||||
val ownerDescriptor = scope.ownerDescriptor
|
||||
if (!expression.isContractDescriptionCallPsiCheck() || ownerDescriptor !is FunctionDescriptor) return
|
||||
val contractProvider = ownerDescriptor.getUserData(ContractProviderKey)
|
||||
if (!expression.isContractDescriptionCallPsiCheck()) return // fastpath
|
||||
|
||||
val collector = TraceBasedCollector(trace, expression)
|
||||
val callContext = ContractCallContext(expression, isFirstStatement, scope, trace.bindingContext)
|
||||
val parsedContract = doCheckContract(collector, callContext)
|
||||
|
||||
collector.flushDiagnostics(parsingFailed = parsedContract == null)
|
||||
|
||||
val contractProviderIfAny = (scope.ownerDescriptor as? FunctionDescriptor)?.getUserData(ContractProviderKey)
|
||||
|
||||
if (collector.hasErrors())
|
||||
contractProviderIfAny?.setContractDescription(null)
|
||||
else
|
||||
contractProviderIfAny?.setContractDescription(parsedContract)
|
||||
}
|
||||
|
||||
private fun doCheckContract(collector: ContractParsingDiagnosticsCollector, callContext: ContractCallContext): ContractDescription? {
|
||||
val expression = callContext.contractCallExpression
|
||||
val bindingContext = callContext.bindingContext
|
||||
|
||||
if (!expression.isContractDescriptionCallPreciseCheck(bindingContext)) return null
|
||||
|
||||
checkFeatureEnabled(collector)
|
||||
checkContractAllowedHere(collector, callContext)
|
||||
|
||||
return if (!collector.hasErrors())
|
||||
PsiContractParserDispatcher(collector, callContext).parseContract()
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
private fun checkFeatureEnabled(collector: ContractParsingDiagnosticsCollector) {
|
||||
val isFeatureTurnedOn = languageVersionSettings.supportsFeature(LanguageFeature.AllowContractsForCustomFunctions) ||
|
||||
// This condition is here for technical purposes of compiling 1.2-runtime with contracts
|
||||
languageVersionSettings.getFlag(AnalysisFlag.Flags.allowKotlinPackage)
|
||||
|
||||
val contractDescriptor = when {
|
||||
!expression.isContractDescriptionCallPreciseCheck(trace.bindingContext) -> null
|
||||
|
||||
!isFeatureTurnedOn -> {
|
||||
trace.report(
|
||||
Errors.UNSUPPORTED_FEATURE.on(
|
||||
expression,
|
||||
LanguageFeature.AllowContractsForCustomFunctions to languageVersionSettings
|
||||
)
|
||||
)
|
||||
null
|
||||
}
|
||||
|
||||
!isContractAllowedHere(scope) || !isFirstStatement -> {
|
||||
trace.report(Errors.CONTRACT_NOT_ALLOWED.on(expression))
|
||||
null
|
||||
}
|
||||
|
||||
else -> parseContract(expression, trace, ownerDescriptor)
|
||||
if (!isFeatureTurnedOn) {
|
||||
collector.unsupportedFeature(languageVersionSettings)
|
||||
}
|
||||
|
||||
contractProvider?.setContractDescription(contractDescriptor)
|
||||
}
|
||||
|
||||
internal fun isContractDescriptionCall(expression: KtExpression, context: BindingContext): Boolean =
|
||||
expression.isContractDescriptionCallPsiCheck() && expression.isContractDescriptionCallPreciseCheck(context)
|
||||
private fun checkContractAllowedHere(collector: ContractParsingDiagnosticsCollector, callContext: ContractCallContext) {
|
||||
val functionDescriptor = callContext.ownerDescriptor as? FunctionDescriptor
|
||||
val scope = callContext.scope
|
||||
|
||||
private fun parseContract(expression: KtExpression?, trace: BindingTrace, ownerDescriptor: FunctionDescriptor): ContractDescription? =
|
||||
PsiContractParserDispatcher(trace, this).parseContract(expression, ownerDescriptor)
|
||||
if (!callContext.isFirstStatement)
|
||||
collector.contractNotAllowed("Contract should be the first statement")
|
||||
|
||||
private fun isContractAllowedHere(scope: LexicalScope): Boolean =
|
||||
scope.kind == LexicalScopeKind.CODE_BLOCK && (scope.parent as? LexicalScope)?.kind == LexicalScopeKind.FUNCTION_INNER_SCOPE
|
||||
if (functionDescriptor == null)
|
||||
collector.contractNotAllowed("Contracts are allowed only for functions")
|
||||
|
||||
|
||||
if (callContext.ownerDescriptor.containingDeclaration !is PackageFragmentDescriptor
|
||||
|| scope.kind != LexicalScopeKind.CODE_BLOCK
|
||||
|| (scope.parent as? LexicalScope)?.kind != LexicalScopeKind.FUNCTION_INNER_SCOPE
|
||||
)
|
||||
collector.contractNotAllowed("Contracts are allowed only for top-level functions")
|
||||
|
||||
if (functionDescriptor?.isOperator == true) collector.contractNotAllowed("Contracts are not allowed for operator functions")
|
||||
|
||||
if (functionDescriptor?.isSuspend == true) collector.contractNotAllowed("Contracts are not allowed for suspend functions")
|
||||
|
||||
if (functionDescriptor?.isOverridable == true) collector.contractNotAllowed("Contracts are not allowed for open functions")
|
||||
}
|
||||
|
||||
private fun KtExpression.isContractDescriptionCallPreciseCheck(context: BindingContext): Boolean =
|
||||
getResolvedCall(context)?.resultingDescriptor?.isContractCallDescriptor() ?: false
|
||||
}
|
||||
|
||||
class ContractCallContext(
|
||||
val contractCallExpression: KtExpression,
|
||||
val isFirstStatement: Boolean,
|
||||
val scope: LexicalScope,
|
||||
val bindingContext: BindingContext
|
||||
) {
|
||||
val ownerDescriptor: DeclarationDescriptor = scope.ownerDescriptor
|
||||
val functionDescriptor: FunctionDescriptor = ownerDescriptor as FunctionDescriptor
|
||||
}
|
||||
@@ -19,26 +19,48 @@ package org.jetbrains.kotlin.contracts.parsing
|
||||
import org.jetbrains.kotlin.contracts.description.*
|
||||
import org.jetbrains.kotlin.contracts.description.expressions.*
|
||||
import org.jetbrains.kotlin.descriptors.ValueDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.CastDiagnosticsUtil
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
|
||||
internal class PsiConditionParser(
|
||||
private val collector: ContractParsingDiagnosticsCollector,
|
||||
private val callContext: ContractCallContext,
|
||||
private val dispatcher: PsiContractParserDispatcher
|
||||
) : KtVisitor<BooleanExpression?, Unit>() {
|
||||
|
||||
internal class PsiConditionParser(val trace: BindingTrace, val dispatcher: PsiContractParserDispatcher) :
|
||||
KtVisitor<BooleanExpression?, Unit>() {
|
||||
override fun visitIsExpression(expression: KtIsExpression, data: Unit): BooleanExpression? {
|
||||
val variable = dispatcher.parseVariable(expression.leftHandSide) ?: return null
|
||||
val typeReference = expression.typeReference ?: return null
|
||||
val type = trace[BindingContext.TYPE, typeReference] ?: return null
|
||||
val type = callContext.bindingContext[BindingContext.TYPE, typeReference]?.unwrap() ?: return null
|
||||
val descriptor = type.constructor.declarationDescriptor
|
||||
|
||||
if (type is CapturedType) {
|
||||
collector.badDescription("references to captured types are forbidden in contracts", typeReference)
|
||||
return null
|
||||
}
|
||||
|
||||
if (descriptor is AbstractTypeParameterDescriptor) {
|
||||
collector.badDescription("references to type parameters are forbidden in contracts", typeReference)
|
||||
return null
|
||||
}
|
||||
|
||||
// This should be reported as "Can't check for erased" error, but we explicitly abort contract parsing. Just in case.
|
||||
if (CastDiagnosticsUtil.isCastErased(variable.descriptor.type, type, KotlinTypeChecker.DEFAULT)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return IsInstancePredicate(variable, type, expression.isNegated)
|
||||
}
|
||||
|
||||
override fun visitKtElement(element: KtElement, data: Unit): BooleanExpression? {
|
||||
val resolvedCall = element.getResolvedCall(trace.bindingContext)
|
||||
val resolvedCall = element.getResolvedCall(callContext.bindingContext)
|
||||
val descriptor = resolvedCall?.resultingDescriptor ?: return null
|
||||
|
||||
// boolean variable
|
||||
@@ -55,20 +77,11 @@ internal class PsiConditionParser(val trace: BindingTrace, val dispatcher: PsiCo
|
||||
val right = dispatcher.parseValue(resolvedCall.firstArgumentAsExpressionOrNull()) ?: return null
|
||||
val isNegated = (element as? KtBinaryExpression)?.operationToken == KtTokens.EXCLEQ ?: false
|
||||
|
||||
if (left is ConstantReference && left == ConstantReference.NULL && right is VariableReference) {
|
||||
return IsNullPredicate(right, isNegated)
|
||||
}
|
||||
|
||||
if (right is ConstantReference && right == ConstantReference.NULL && left is VariableReference) {
|
||||
return IsNullPredicate(left, isNegated)
|
||||
}
|
||||
|
||||
trace.report(Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(element, "only equality comparisons with 'null' allowed"))
|
||||
return null
|
||||
return processEquals(left, right, isNegated, element)
|
||||
}
|
||||
|
||||
else -> {
|
||||
trace.report(Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(element, "unsupported construction"))
|
||||
collector.badDescription("unsupported construction", element)
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -80,7 +93,7 @@ internal class PsiConditionParser(val trace: BindingTrace, val dispatcher: PsiCo
|
||||
}
|
||||
|
||||
override fun visitCallExpression(expression: KtCallExpression, data: Unit?): BooleanExpression? {
|
||||
trace.report(Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(expression, "call-expressions are not supported yet"))
|
||||
collector.badDescription("call-expressions are not supported yet", expression)
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -90,6 +103,7 @@ internal class PsiConditionParser(val trace: BindingTrace, val dispatcher: PsiCo
|
||||
when (expression.operationToken) {
|
||||
KtTokens.ANDAND -> operationConstructor = ::LogicalAnd
|
||||
KtTokens.OROR -> operationConstructor = ::LogicalOr
|
||||
KtTokens.EXCLEQEQEQ, KtTokens.EQEQEQ -> return parseIdentityEquals(expression)
|
||||
else -> return super.visitBinaryExpression(expression, data) // pass binary expression further
|
||||
}
|
||||
|
||||
@@ -98,15 +112,39 @@ internal class PsiConditionParser(val trace: BindingTrace, val dispatcher: PsiCo
|
||||
return operationConstructor(left, right)
|
||||
}
|
||||
|
||||
private fun parseIdentityEquals(expression: KtBinaryExpression): BooleanExpression? {
|
||||
val lhs = dispatcher.parseValue(expression.left) ?: return null
|
||||
val rhs = dispatcher.parseValue(expression.right) ?: return null
|
||||
|
||||
return processEquals(lhs, rhs, expression.operationToken == KtTokens.EXCLEQEQEQ, expression)
|
||||
}
|
||||
|
||||
private fun processEquals(
|
||||
left: ContractDescriptionValue,
|
||||
right: ContractDescriptionValue,
|
||||
isNegated: Boolean,
|
||||
reportOn: KtElement
|
||||
): BooleanExpression? {
|
||||
return when {
|
||||
left is ConstantReference && left == ConstantReference.NULL && right is VariableReference -> IsNullPredicate(right, isNegated)
|
||||
|
||||
right is ConstantReference && right == ConstantReference.NULL && left is VariableReference -> IsNullPredicate(left, isNegated)
|
||||
|
||||
else -> {
|
||||
collector.badDescription("only equality comparisons with 'null' allowed", reportOn)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun visitUnaryExpression(expression: KtUnaryExpression, data: Unit): BooleanExpression? {
|
||||
if (expression.operationToken != KtTokens.EXCL) return super.visitUnaryExpression(expression, data)
|
||||
val arg = expression.baseExpression?.accept(this, data) ?: return null
|
||||
if (arg !is ContractDescriptionValue) {
|
||||
trace.report(
|
||||
Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(
|
||||
expression.baseExpression!!,
|
||||
"negations in contract description can be applied only to variables/values"
|
||||
)
|
||||
collector.badDescription(
|
||||
"negations in contract description can be applied only to variables/values",
|
||||
expression.baseExpression!!
|
||||
)
|
||||
}
|
||||
return LogicalNot(arg)
|
||||
|
||||
@@ -22,17 +22,18 @@ import org.jetbrains.kotlin.psi.KtConstantExpression
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtVisitor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
internal class PsiConstantParser(val trace: BindingTrace) : KtVisitor<ConstantReference?, Unit>() {
|
||||
internal class PsiConstantParser(private val callContext: ContractCallContext) : KtVisitor<ConstantReference?, Unit>() {
|
||||
override fun visitKtElement(element: KtElement, data: Unit?): ConstantReference? = null
|
||||
|
||||
override fun visitConstantExpression(expression: KtConstantExpression, data: Unit?): ConstantReference? {
|
||||
val type: KotlinType = trace.getType(expression) ?: return null
|
||||
val type: KotlinType = callContext.bindingContext.getType(expression) ?: return null
|
||||
|
||||
val compileTimeConstant: CompileTimeConstant<*> = callContext.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression)
|
||||
?: return null
|
||||
|
||||
val compileTimeConstant: CompileTimeConstant<*> = trace.get(BindingContext.COMPILE_TIME_VALUE, expression) ?: return null
|
||||
val value: Any? = compileTimeConstant.getValue(type)
|
||||
|
||||
return when (value) {
|
||||
|
||||
@@ -31,56 +31,80 @@ import org.jetbrains.kotlin.contracts.parsing.ContractsDslNames.RETURNS_NOT_NULL
|
||||
import org.jetbrains.kotlin.contracts.parsing.effects.PsiCallsEffectParser
|
||||
import org.jetbrains.kotlin.contracts.parsing.effects.PsiConditionalEffectParser
|
||||
import org.jetbrains.kotlin.contracts.parsing.effects.PsiReturnsEffectParser
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
|
||||
internal class PsiContractParserDispatcher(val trace: BindingTrace, val contractParsingServices: ContractParsingServices) {
|
||||
private val conditionParser = PsiConditionParser(trace, this)
|
||||
private val constantParser = PsiConstantParser(trace)
|
||||
internal class PsiContractParserDispatcher(
|
||||
private val collector: ContractParsingDiagnosticsCollector,
|
||||
private val callContext: ContractCallContext
|
||||
) {
|
||||
private val conditionParser = PsiConditionParser(collector, callContext, this)
|
||||
private val constantParser = PsiConstantParser(callContext)
|
||||
private val effectsParsers: Map<Name, PsiEffectParser> = mapOf(
|
||||
RETURNS_EFFECT to PsiReturnsEffectParser(trace, this),
|
||||
RETURNS_NOT_NULL_EFFECT to PsiReturnsEffectParser(trace, this),
|
||||
CALLS_IN_PLACE_EFFECT to PsiCallsEffectParser(trace, this),
|
||||
CONDITIONAL_EFFECT to PsiConditionalEffectParser(trace, this)
|
||||
RETURNS_EFFECT to PsiReturnsEffectParser(collector, callContext, this),
|
||||
RETURNS_NOT_NULL_EFFECT to PsiReturnsEffectParser(collector, callContext, this),
|
||||
CALLS_IN_PLACE_EFFECT to PsiCallsEffectParser(collector, callContext, this),
|
||||
CONDITIONAL_EFFECT to PsiConditionalEffectParser(collector, callContext, this)
|
||||
)
|
||||
|
||||
fun parseContract(expression: KtExpression?, ownerDescriptor: FunctionDescriptor): ContractDescription? {
|
||||
if (expression == null) return null
|
||||
if (!contractParsingServices.isContractDescriptionCall(expression, trace.bindingContext)) return null
|
||||
fun parseContract(): ContractDescription? {
|
||||
// Must be non-null because of checks in 'checkContractAndRecordIfPresent', but actually is not, see EA-124365
|
||||
val resolvedCall = callContext.contractCallExpression.getResolvedCall(callContext.bindingContext) ?: return null
|
||||
|
||||
// Must be non-null due to 'isContractDescriptionCall' check, but actually is not, see EA-124365
|
||||
val resolvedCall = expression.getResolvedCall(trace.bindingContext) ?: return null
|
||||
|
||||
val lambda = resolvedCall.firstArgumentAsExpressionOrNull() as? KtLambdaExpression ?: return null
|
||||
val firstArgumentExpression = resolvedCall.firstArgumentAsExpressionOrNull()
|
||||
val lambda = if (firstArgumentExpression is KtLambdaExpression) {
|
||||
firstArgumentExpression
|
||||
} else {
|
||||
val reportOn = firstArgumentExpression ?: callContext.contractCallExpression
|
||||
collector.badDescription("first argument of 'contract'-call should be a lambda expression", reportOn)
|
||||
return null
|
||||
}
|
||||
|
||||
val effects = lambda.bodyExpression?.statements?.mapNotNull { parseEffect(it) } ?: return null
|
||||
|
||||
if (effects.isEmpty()) return null
|
||||
|
||||
return ContractDescription(effects, ownerDescriptor)
|
||||
return ContractDescription(effects, callContext.functionDescriptor)
|
||||
}
|
||||
|
||||
fun parseCondition(expression: KtExpression?): BooleanExpression? = expression?.accept(conditionParser, Unit)
|
||||
|
||||
fun parseEffect(expression: KtExpression?): EffectDeclaration? {
|
||||
if (expression == null) return null
|
||||
val returnType = expression.getType(trace.bindingContext) ?: return null
|
||||
if (!isValidEffectDeclaration(expression)) return null
|
||||
|
||||
val returnType = expression.getType(callContext.bindingContext) ?: return null
|
||||
val parser = effectsParsers[returnType.constructor.declarationDescriptor?.name]
|
||||
if (parser == null) {
|
||||
trace.report(Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(expression, "Unrecognized effect"))
|
||||
collector.badDescription("unrecognized effect", expression)
|
||||
return null
|
||||
}
|
||||
|
||||
return parser.tryParseEffect(expression)
|
||||
}
|
||||
|
||||
private fun isValidEffectDeclaration(expression: KtExpression): Boolean {
|
||||
if (expression !is KtCallExpression && expression !is KtBinaryExpression) {
|
||||
collector.badDescription("unexpected construction in contract description", expression)
|
||||
return false
|
||||
}
|
||||
|
||||
val resultingDescriptor = expression.getResolvedCall(callContext.bindingContext)?.resultingDescriptor ?: return false
|
||||
if (!resultingDescriptor.isFromContractDsl()) {
|
||||
collector.badDescription("effects can be produced only by direct calls to ContractsDSL", expression)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun parseConstant(expression: KtExpression?): ConstantReference? {
|
||||
if (expression == null) return null
|
||||
return expression.accept(constantParser, Unit)
|
||||
@@ -88,24 +112,15 @@ internal class PsiContractParserDispatcher(val trace: BindingTrace, val contract
|
||||
|
||||
fun parseVariable(expression: KtExpression?): VariableReference? {
|
||||
if (expression == null) return null
|
||||
val descriptor = expression.getResolvedCall(trace.bindingContext)?.resultingDescriptor ?: return null
|
||||
val descriptor = expression.getResolvedCall(callContext.bindingContext)?.resultingDescriptor ?: return null
|
||||
if (descriptor !is ParameterDescriptor) {
|
||||
trace.report(
|
||||
Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(
|
||||
expression,
|
||||
"only references to parameters are allowed in contract description"
|
||||
)
|
||||
)
|
||||
collector.badDescription("only references to parameters are allowed in contract description", expression)
|
||||
return null
|
||||
}
|
||||
|
||||
if (descriptor is ReceiverParameterDescriptor && descriptor.type.constructor.declarationDescriptor?.isFromContractDsl() == true) {
|
||||
trace.report(
|
||||
Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(
|
||||
expression,
|
||||
"only references to parameters are allowed. Did you miss label on <this>?"
|
||||
)
|
||||
)
|
||||
collector.badDescription("only references to parameters are allowed. Did you miss label on <this>?", expression)
|
||||
return null
|
||||
}
|
||||
|
||||
return if (KotlinBuiltIns.isBoolean(descriptor.type))
|
||||
|
||||
@@ -76,6 +76,10 @@ fun DeclarationDescriptor.isReturnsEffectDescriptor(): Boolean = equalsDslDescri
|
||||
|
||||
fun DeclarationDescriptor.isReturnsNotNullDescriptor(): Boolean = equalsDslDescriptor(RETURNS_NOT_NULL)
|
||||
|
||||
fun DeclarationDescriptor.isReturnsWildcardDescriptor(): Boolean = equalsDslDescriptor(RETURNS) &&
|
||||
this is FunctionDescriptor &&
|
||||
valueParameters.isEmpty()
|
||||
|
||||
fun DeclarationDescriptor.isEffectDescriptor(): Boolean = equalsDslDescriptor(EFFECT)
|
||||
|
||||
fun DeclarationDescriptor.isCallsInPlaceEffectDescriptor(): Boolean = equalsDslDescriptor(CALLS_IN_PLACE)
|
||||
|
||||
@@ -24,5 +24,8 @@ internal interface PsiEffectParser {
|
||||
fun tryParseEffect(expression: KtExpression): EffectDeclaration?
|
||||
}
|
||||
|
||||
internal abstract class AbstractPsiEffectParser(val trace: BindingTrace, val contractParserDispatcher: PsiContractParserDispatcher) :
|
||||
PsiEffectParser
|
||||
internal abstract class AbstractPsiEffectParser(
|
||||
val collector: ContractParsingDiagnosticsCollector,
|
||||
val callContext: ContractCallContext,
|
||||
val contractParserDispatcher: PsiContractParserDispatcher
|
||||
) : PsiEffectParser
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.contracts.description.EffectDeclaration
|
||||
import org.jetbrains.kotlin.contracts.description.InvocationKind
|
||||
import org.jetbrains.kotlin.contracts.parsing.*
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||
@@ -29,12 +29,13 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
|
||||
|
||||
internal class PsiCallsEffectParser(
|
||||
trace: BindingTrace,
|
||||
collector: ContractParsingDiagnosticsCollector,
|
||||
callContext: ContractCallContext,
|
||||
contractParserDispatcher: PsiContractParserDispatcher
|
||||
) : AbstractPsiEffectParser(trace, contractParserDispatcher) {
|
||||
) : AbstractPsiEffectParser(collector, callContext, contractParserDispatcher) {
|
||||
|
||||
override fun tryParseEffect(expression: KtExpression): EffectDeclaration? {
|
||||
val resolvedCall = expression.getResolvedCall(trace.bindingContext) ?: return null
|
||||
val resolvedCall = expression.getResolvedCall(callContext.bindingContext) ?: return null
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
|
||||
if (!descriptor.isCallsInPlaceEffectDescriptor()) return null
|
||||
@@ -45,15 +46,21 @@ internal class PsiCallsEffectParser(
|
||||
|
||||
val kind = when (kindArgument) {
|
||||
is DefaultValueArgument -> InvocationKind.UNKNOWN
|
||||
is ExpressionValueArgument -> kindArgument.valueArgument?.getArgumentExpression()?.toInvocationKind(trace) ?: return null
|
||||
else -> return null
|
||||
is ExpressionValueArgument -> kindArgument.valueArgument?.getArgumentExpression()?.toInvocationKind(callContext.bindingContext)
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (kind == null) {
|
||||
val reportOn = (kindArgument as? ExpressionValueArgument)?.valueArgument?.getArgumentExpression() ?: expression
|
||||
collector.badDescription("unrecognized InvocationKind", reportOn)
|
||||
return null
|
||||
}
|
||||
|
||||
return CallsEffectDeclaration(lambda, kind)
|
||||
}
|
||||
|
||||
private fun KtExpression.toInvocationKind(trace: BindingTrace): InvocationKind? {
|
||||
val descriptor = this.getResolvedCall(trace.bindingContext)?.resultingDescriptor ?: return null
|
||||
private fun KtExpression.toInvocationKind(bindingContext: BindingContext): InvocationKind? {
|
||||
val descriptor = this.getResolvedCall(bindingContext)?.resultingDescriptor ?: return null
|
||||
if (!descriptor.parents.first().isInvocationKindEnum()) return null
|
||||
|
||||
return when (descriptor.fqNameSafe.shortName()) {
|
||||
|
||||
@@ -18,23 +18,19 @@ package org.jetbrains.kotlin.contracts.parsing.effects
|
||||
|
||||
import org.jetbrains.kotlin.contracts.description.ConditionalEffectDeclaration
|
||||
import org.jetbrains.kotlin.contracts.description.EffectDeclaration
|
||||
import org.jetbrains.kotlin.contracts.parsing.AbstractPsiEffectParser
|
||||
import org.jetbrains.kotlin.contracts.parsing.PsiContractParserDispatcher
|
||||
import org.jetbrains.kotlin.contracts.parsing.firstArgumentAsExpressionOrNull
|
||||
import org.jetbrains.kotlin.contracts.parsing.isImpliesCallDescriptor
|
||||
import org.jetbrains.kotlin.contracts.parsing.*
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
internal class PsiConditionalEffectParser(
|
||||
trace: BindingTrace,
|
||||
collector: ContractParsingDiagnosticsCollector,
|
||||
callContext: ContractCallContext,
|
||||
dispatcher: PsiContractParserDispatcher
|
||||
) : AbstractPsiEffectParser(trace, dispatcher) {
|
||||
) : AbstractPsiEffectParser(collector, callContext, dispatcher) {
|
||||
override fun tryParseEffect(expression: KtExpression): EffectDeclaration? {
|
||||
val resolvedCall = expression.getResolvedCall(trace.bindingContext) ?: return null
|
||||
|
||||
val resolvedCall = expression.getResolvedCall(callContext.bindingContext) ?: return null
|
||||
if (!resolvedCall.resultingDescriptor.isImpliesCallDescriptor()) return null
|
||||
|
||||
val effect = contractParserDispatcher.parseEffect(resolvedCall.dispatchReceiver.safeAs<ExpressionReceiver>()?.expression)
|
||||
|
||||
@@ -20,40 +20,32 @@ import org.jetbrains.kotlin.contracts.description.EffectDeclaration
|
||||
import org.jetbrains.kotlin.contracts.description.ReturnsEffectDeclaration
|
||||
import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference
|
||||
import org.jetbrains.kotlin.contracts.parsing.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
|
||||
internal class PsiReturnsEffectParser(
|
||||
trace: BindingTrace,
|
||||
collector: ContractParsingDiagnosticsCollector,
|
||||
callContext: ContractCallContext,
|
||||
contractParserDispatcher: PsiContractParserDispatcher
|
||||
) : AbstractPsiEffectParser(trace, contractParserDispatcher) {
|
||||
) : AbstractPsiEffectParser(collector, callContext, contractParserDispatcher) {
|
||||
override fun tryParseEffect(expression: KtExpression): EffectDeclaration? {
|
||||
val resolvedCall = expression.getResolvedCall(trace.bindingContext) ?: return null
|
||||
val resolvedCall = expression.getResolvedCall(callContext.bindingContext) ?: return null
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
|
||||
if (descriptor.isReturnsNotNullDescriptor())
|
||||
return ReturnsEffectDeclaration(ConstantReference.NOT_NULL)
|
||||
if (descriptor.isReturnsNotNullDescriptor()) return ReturnsEffectDeclaration(ConstantReference.NOT_NULL)
|
||||
if (descriptor.isReturnsWildcardDescriptor()) return ReturnsEffectDeclaration(ConstantReference.WILDCARD)
|
||||
|
||||
if (!descriptor.isReturnsEffectDescriptor()) return null
|
||||
|
||||
val argumentExpression = resolvedCall.firstArgumentAsExpressionOrNull()
|
||||
val constantValue = if (argumentExpression == null) {
|
||||
ConstantReference.WILDCARD
|
||||
} else {
|
||||
// Note that we distinguish absence of an argument and unparsed argument
|
||||
val constant = contractParserDispatcher.parseConstant(argumentExpression)
|
||||
if (constant == null) {
|
||||
trace.report(
|
||||
Errors.ERROR_IN_CONTRACT_DESCRIPTION.on(
|
||||
argumentExpression,
|
||||
"only true/false/null constants in Returns-effect are currently supported"
|
||||
)
|
||||
)
|
||||
return null
|
||||
}
|
||||
constant
|
||||
val constantValue = if (argumentExpression != null) contractParserDispatcher.parseConstant(argumentExpression) else null
|
||||
|
||||
if (constantValue == null) {
|
||||
collector.badDescription(
|
||||
"only true/false/null constants in Returns-effect are currently supported",
|
||||
argumentExpression ?: expression
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
return ReturnsEffectDeclaration(constantValue)
|
||||
|
||||
@@ -1049,7 +1049,7 @@ public interface Errors {
|
||||
|
||||
// Function contracts
|
||||
DiagnosticFactory1<KtElement, String> ERROR_IN_CONTRACT_DESCRIPTION = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<KtElement> CONTRACT_NOT_ALLOWED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<KtElement, String> CONTRACT_NOT_ALLOWED = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
// Error sets
|
||||
ImmutableSet<? extends DiagnosticFactory<?>> UNRESOLVED_REFERENCE_DIAGNOSTICS = ImmutableSet.of(
|
||||
|
||||
@@ -941,7 +941,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(PLUGIN_INFO, "{0}", (d, c) -> d.getText());
|
||||
|
||||
MAP.put(ERROR_IN_CONTRACT_DESCRIPTION, "Error in contract description: {0}", TO_STRING);
|
||||
MAP.put(CONTRACT_NOT_ALLOWED, "Contract is not allowed here");
|
||||
MAP.put(CONTRACT_NOT_ALLOWED, "{0}", TO_STRING);
|
||||
|
||||
MAP.setImmutable();
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.extensions
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPoint
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
|
||||
open class ApplicationExtensionDescriptor<T>(name: String, private val extensionClass: Class<T>) {
|
||||
val extensionPointName: ExtensionPointName<T> = ExtensionPointName.create(name)
|
||||
|
||||
fun registerExtensionPoint() {
|
||||
Extensions.getRootArea().registerExtensionPoint(
|
||||
extensionPointName.name,
|
||||
extensionClass.name,
|
||||
ExtensionPoint.Kind.INTERFACE
|
||||
)
|
||||
}
|
||||
|
||||
fun registerExtension(extension: T) {
|
||||
Extensions.getRootArea().getExtensionPoint(extensionPointName).registerExtension(extension)
|
||||
}
|
||||
|
||||
fun getInstances(): List<T> {
|
||||
val projectArea = Extensions.getRootArea()
|
||||
if (!projectArea.hasExtensionPoint(extensionPointName.name)) return listOf()
|
||||
|
||||
return projectArea.getExtensionPoint(extensionPointName).extensions.toList()
|
||||
}
|
||||
}
|
||||
@@ -31,8 +31,6 @@ val JVM_FIELD_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmField")
|
||||
|
||||
val JVM_DEFAULT_FQ_NAME = FqName("kotlin.jvm.JvmDefault")
|
||||
|
||||
private val IMPLICIT_INTEGER_COERCION_ANNOTATION_FQ_NAME = FqName("kotlin.internal.ImplicitIntegerCoercion")
|
||||
|
||||
fun CallableMemberDescriptor.hasJvmDefaultAnnotation() =
|
||||
DescriptorUtils.getDirectMember(this).annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME)
|
||||
|
||||
@@ -41,10 +39,6 @@ fun DeclarationDescriptor.hasJvmStaticAnnotation(): Boolean {
|
||||
return annotations.findAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) != null
|
||||
}
|
||||
|
||||
fun DeclarationDescriptor.hasImplicitIntegerCoercionAnnotation(): Boolean {
|
||||
return annotations.findAnnotation(IMPLICIT_INTEGER_COERCION_ANNOTATION_FQ_NAME) != null
|
||||
}
|
||||
|
||||
private val JVM_SYNTHETIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmSynthetic")
|
||||
|
||||
fun DeclarationDescriptor.hasJvmSyntheticAnnotation() = findJvmSyntheticAnnotation() != null
|
||||
|
||||
@@ -6,15 +6,16 @@
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.KotlinCompilerVersion
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.isPreRelease
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
||||
|
||||
class CompilerDeserializationConfiguration(languageVersionSettings: LanguageVersionSettings) : DeserializationConfiguration {
|
||||
override val skipMetadataVersionCheck = languageVersionSettings.getFlag(AnalysisFlag.skipMetadataVersionCheck)
|
||||
|
||||
override val reportErrorsOnPreReleaseDependencies = !skipMetadataVersionCheck && !languageVersionSettings.isPreRelease()
|
||||
override val reportErrorsOnPreReleaseDependencies =
|
||||
!skipMetadataVersionCheck && !languageVersionSettings.isPreRelease() && !KotlinCompilerVersion.isPreRelease()
|
||||
|
||||
override val typeAliasesAllowed = languageVersionSettings.supportsFeature(LanguageFeature.TypeAliases)
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
object ImplicitIntegerCoercion {
|
||||
|
||||
val MODULE_CAPABILITY = ModuleDescriptor.Capability<Boolean>("ImplicitIntegerCoercion")
|
||||
|
||||
fun isEnabledForParameter(descriptor: ParameterDescriptor): Boolean = isEnabledFor(descriptor)
|
||||
|
||||
fun isEnabledForConstVal(descriptor: VariableDescriptor): Boolean = isEnabledFor(descriptor)
|
||||
|
||||
private fun isEnabledFor(descriptor: DeclarationDescriptor): Boolean =
|
||||
descriptor.hasImplicitIntegerCoercionAnnotation() ||
|
||||
DescriptorUtils.getContainingModuleOrNull(descriptor)
|
||||
?.getCapability(ImplicitIntegerCoercion.MODULE_CAPABILITY) == true
|
||||
|
||||
private val IMPLICIT_INTEGER_COERCION_ANNOTATION_FQ_NAME = FqName("kotlin.internal.ImplicitIntegerCoercion")
|
||||
|
||||
private fun DeclarationDescriptor.hasImplicitIntegerCoercionAnnotation(): Boolean {
|
||||
return annotations.findAnnotation(IMPLICIT_INTEGER_COERCION_ANNOTATION_FQ_NAME) != null
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls;
|
||||
@@ -198,7 +187,8 @@ public class ArgumentTypeResolver {
|
||||
public KotlinTypeInfo getArgumentTypeInfo(
|
||||
@Nullable KtExpression expression,
|
||||
@NotNull CallResolutionContext<?> context,
|
||||
@NotNull ResolveArgumentsMode resolveArgumentsMode
|
||||
@NotNull ResolveArgumentsMode resolveArgumentsMode,
|
||||
boolean suspendFunctionTypeExpected
|
||||
) {
|
||||
if (expression == null) {
|
||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
@@ -206,7 +196,7 @@ public class ArgumentTypeResolver {
|
||||
|
||||
KtFunction functionLiteralArgument = getFunctionLiteralArgumentIfAny(expression, context);
|
||||
if (functionLiteralArgument != null) {
|
||||
return getFunctionLiteralTypeInfo(expression, functionLiteralArgument, context, resolveArgumentsMode);
|
||||
return getFunctionLiteralTypeInfo(expression, functionLiteralArgument, context, resolveArgumentsMode, suspendFunctionTypeExpected);
|
||||
}
|
||||
|
||||
KtCallableReferenceExpression callableReferenceExpression = getCallableReferenceExpressionIfAny(expression, context);
|
||||
@@ -319,10 +309,11 @@ public class ArgumentTypeResolver {
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull KtFunction functionLiteral,
|
||||
@NotNull CallResolutionContext<?> context,
|
||||
@NotNull ResolveArgumentsMode resolveArgumentsMode
|
||||
@NotNull ResolveArgumentsMode resolveArgumentsMode,
|
||||
boolean suspendFunctionTypeExpected
|
||||
) {
|
||||
if (resolveArgumentsMode == SHAPE_FUNCTION_ARGUMENTS) {
|
||||
KotlinType type = getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, true);
|
||||
KotlinType type = getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, true, suspendFunctionTypeExpected);
|
||||
return TypeInfoFactoryKt.createTypeInfo(type, context);
|
||||
}
|
||||
return expressionTypingServices.getTypeInfo(expression, context.replaceContextDependency(INDEPENDENT));
|
||||
@@ -333,7 +324,8 @@ public class ArgumentTypeResolver {
|
||||
@NotNull KtFunction function,
|
||||
@NotNull LexicalScope scope,
|
||||
@NotNull BindingTrace trace,
|
||||
boolean expectedTypeIsUnknown
|
||||
boolean expectedTypeIsUnknown,
|
||||
boolean suspendFunctionTypeExpected
|
||||
) {
|
||||
boolean isFunctionLiteral = function instanceof KtFunctionLiteral;
|
||||
if (function.getValueParameterList() == null && isFunctionLiteral) {
|
||||
@@ -363,7 +355,7 @@ public class ArgumentTypeResolver {
|
||||
return expectedTypeIsUnknown && isFunctionLiteral
|
||||
? functionPlaceholders.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true)
|
||||
: FunctionTypesKt.createFunctionType(
|
||||
builtIns, Annotations.Companion.getEMPTY(), receiverType, parameterTypes, parameterNames, returnType
|
||||
builtIns, Annotations.Companion.getEMPTY(), receiverType, parameterTypes, parameterNames, returnType, suspendFunctionTypeExpected
|
||||
);
|
||||
}
|
||||
|
||||
@@ -399,7 +391,7 @@ public class ArgumentTypeResolver {
|
||||
|
||||
CallResolutionContext<?> newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument));
|
||||
// Here we go inside arguments and determine additional data flow information for them
|
||||
KotlinTypeInfo typeInfoForCall = getArgumentTypeInfo(expression, newContext, resolveArgumentsMode);
|
||||
KotlinTypeInfo typeInfoForCall = getArgumentTypeInfo(expression, newContext, resolveArgumentsMode, false);
|
||||
infoForArguments.updateInfo(argument, typeInfoForCall.getDataFlowInfo());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls
|
||||
@@ -25,7 +14,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.CONSTRAINT_SYSTEM_COMPLETER
|
||||
import org.jetbrains.kotlin.resolve.annotations.hasImplicitIntegerCoercionAnnotation
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInvokeCallOnVariable
|
||||
@@ -350,7 +338,7 @@ class CallCompleter(
|
||||
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, expression) ?: updatedType
|
||||
}
|
||||
|
||||
if (parameter?.hasImplicitIntegerCoercionAnnotation() == true) {
|
||||
if (parameter != null && ImplicitIntegerCoercion.isEnabledForParameter(parameter)) {
|
||||
val argumentCompileTimeValue = context.trace[BindingContext.COMPILE_TIME_VALUE, deparenthesized]
|
||||
if (argumentCompileTimeValue != null && argumentCompileTimeValue.parameters.isConvertableConstVal) {
|
||||
val generalNumberType = createTypeForConvertableConstant(argumentCompileTimeValue)
|
||||
@@ -367,7 +355,7 @@ class CallCompleter(
|
||||
// While the expected type is not known, the function literal arguments are not analyzed (to analyze function literal bodies once),
|
||||
// but they should be analyzed when the expected type is known (during the call completion).
|
||||
ArgumentTypeResolver.getFunctionLiteralArgumentIfAny(expression, context)?.let { functionLiteralArgument ->
|
||||
argumentTypeResolver.getFunctionLiteralTypeInfo(expression, functionLiteralArgument, context, RESOLVE_FUNCTION_ARGUMENTS)
|
||||
argumentTypeResolver.getFunctionLiteralTypeInfo(expression, functionLiteralArgument, context, RESOLVE_FUNCTION_ARGUMENTS, false)
|
||||
}
|
||||
|
||||
// While the expected type is not known, (possibly overloaded) callable references can have placeholder types
|
||||
|
||||
@@ -1,23 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls
|
||||
|
||||
import com.google.common.collect.Lists
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
@@ -362,7 +352,7 @@ class CandidateResolver(
|
||||
val expectedType = getEffectiveExpectedType(parameterDescriptor, argument, context)
|
||||
|
||||
val newContext = context.replaceDataFlowInfo(infoForArguments.getInfo(argument)).replaceExpectedType(expectedType)
|
||||
val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(expression, newContext, resolveFunctionArgumentBodies)
|
||||
val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(expression, newContext, resolveFunctionArgumentBodies, expectedType.isSuspendFunctionType)
|
||||
val type = typeInfoForCall.type
|
||||
infoForArguments.updateInfo(argument, typeInfoForCall.dataFlowInfo)
|
||||
|
||||
|
||||
@@ -1,25 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.builtins.*
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
@@ -261,7 +247,12 @@ class GenericCandidateResolver(
|
||||
val dataFlowInfoForArgument = context.candidateCall.dataFlowInfoForArguments.getInfo(valueArgument)
|
||||
val newContext = context.replaceExpectedType(expectedType).replaceDataFlowInfo(dataFlowInfoForArgument)
|
||||
|
||||
val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(argumentExpression, newContext, resolveFunctionArgumentBodies)
|
||||
val typeInfoForCall = argumentTypeResolver.getArgumentTypeInfo(
|
||||
argumentExpression,
|
||||
newContext,
|
||||
resolveFunctionArgumentBodies,
|
||||
expectedType?.isSuspendFunctionType == true
|
||||
)
|
||||
context.candidateCall.dataFlowInfoForArguments.updateInfo(valueArgument, typeInfoForCall.dataFlowInfo)
|
||||
|
||||
val constraintPosition = VALUE_PARAMETER_POSITION.position(valueParameterDescriptor.index)
|
||||
@@ -435,7 +426,13 @@ class GenericCandidateResolver(
|
||||
var expectedType = newSubstitution.buildSubstitutor().substitute(effectiveExpectedType, Variance.IN_VARIANCE)
|
||||
|
||||
if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) {
|
||||
expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, false)
|
||||
expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(
|
||||
functionLiteral,
|
||||
context.scope,
|
||||
context.trace,
|
||||
false,
|
||||
expectedType?.isSuspendFunctionType == true
|
||||
)
|
||||
}
|
||||
if (expectedType == null || !expectedType.isBuiltinFunctionalTypeOrSubtype || hasUnknownFunctionParameter(expectedType)) {
|
||||
return
|
||||
@@ -463,7 +460,8 @@ class GenericCandidateResolver(
|
||||
.replaceDataFlowInfo(dataFlowInfoForArgument).replaceResolutionResultsCache(temporaryToResolveFunctionLiteral.cache)
|
||||
.replaceContextDependency(INDEPENDENT)
|
||||
val type = argumentTypeResolver.getFunctionLiteralTypeInfo(
|
||||
argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS
|
||||
argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS,
|
||||
expectedType.isSuspendFunctionType
|
||||
).type
|
||||
if (!mismatch[0]) {
|
||||
constraintSystem.addSubtypeConstraint(type, effectiveExpectedTypeInSystem, position)
|
||||
@@ -476,8 +474,10 @@ class GenericCandidateResolver(
|
||||
val newContext = context.replaceExpectedType(expectedTypeWithEstimatedReturnType).replaceDataFlowInfo(dataFlowInfoForArgument)
|
||||
.replaceContextDependency(INDEPENDENT)
|
||||
val type =
|
||||
argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS)
|
||||
.type
|
||||
argumentTypeResolver.getFunctionLiteralTypeInfo(
|
||||
argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS,
|
||||
expectedType.isSuspendFunctionType
|
||||
).type
|
||||
constraintSystem.addSubtypeConstraint(type, effectiveExpectedTypeInSystem, position)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.inference
|
||||
@@ -178,7 +167,7 @@ class CoroutineInferenceSupport(
|
||||
val newContext = context.replaceExpectedType(newExpectedType)
|
||||
.replaceDataFlowInfo(context.candidateCall.dataFlowInfoForArguments.getInfo(valueArgument))
|
||||
.replaceContextDependency(ContextDependency.INDEPENDENT).replaceTraceAndCache(temporaryForCoroutine)
|
||||
argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS)
|
||||
argumentTypeResolver.getFunctionLiteralTypeInfo(argumentExpression, functionLiteral, newContext, RESOLVE_FUNCTION_ARGUMENTS, true)
|
||||
|
||||
inferenceData.reportInferenceResult(csBuilder)
|
||||
}
|
||||
@@ -260,7 +249,7 @@ class CoroutineInferenceSupport(
|
||||
context: CallResolutionContext<*>
|
||||
): KotlinTypeInfo {
|
||||
getFunctionLiteralArgumentIfAny(expression, context)?.let {
|
||||
return argumentTypeResolver.getFunctionLiteralTypeInfo(expression, it, context, RESOLVE_FUNCTION_ARGUMENTS)
|
||||
return argumentTypeResolver.getFunctionLiteralTypeInfo(expression, it, context, RESOLVE_FUNCTION_ARGUMENTS, false)
|
||||
}
|
||||
|
||||
getCallableReferenceExpressionIfAny(expression, context)?.let {
|
||||
|
||||
@@ -64,8 +64,7 @@ internal class DataFlowInfoImpl private constructor(
|
||||
nullability: Nullability,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
newTypeInfoBuilder: SetMultimap<DataFlowValue, KotlinType>? = null,
|
||||
// TODO: remove me in version 1.3! I'm very dirty hack!
|
||||
// In normal circumstances this should be always true
|
||||
// XXX: set to false only as a workaround for OI, see KT-26357 for details (in NI everything works automagically)
|
||||
recordUnstable: Boolean = true
|
||||
) {
|
||||
if (value.isStable || recordUnstable) {
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.COLLECTION_LITERAL_CALL
|
||||
import org.jetbrains.kotlin.resolve.annotations.hasImplicitIntegerCoercionAnnotation
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getEffectiveExpectedType
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
@@ -366,7 +365,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
return when (constantValue) {
|
||||
is ErrorValue, is EnumValue -> return null
|
||||
is NullValue -> StringValue("null")
|
||||
else -> StringValue(constantValue.value.toString())
|
||||
else -> StringValue(constantValue.stringTemplateValue())
|
||||
}.wrap(compileTimeConstant.parameters)
|
||||
}
|
||||
|
||||
@@ -750,7 +749,7 @@ private class ConstantExpressionEvaluatorVisitor(
|
||||
|
||||
val isConvertableConstVal =
|
||||
callableDescriptor.isConst &&
|
||||
callableDescriptor.hasImplicitIntegerCoercionAnnotation() &&
|
||||
ImplicitIntegerCoercion.isEnabledForConstVal(callableDescriptor) &&
|
||||
callableDescriptor.compileTimeInitializer is IntValue
|
||||
|
||||
return callableDescriptor.compileTimeInitializer?.wrap(
|
||||
@@ -1220,4 +1219,4 @@ fun CompileTimeConstant<*>.isStandaloneOnlyConstant(): Boolean {
|
||||
is TypedCompileTimeConstant -> this.constantValue.isStandaloneOnlyConstant()
|
||||
else -> return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -118,11 +118,11 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
val expectedType = context.expectedType
|
||||
|
||||
val functionalTypeExpected = expectedType.isBuiltinFunctionalType()
|
||||
val suspendFunctionTypeExpected = expectedType.isSuspendFunctionType()
|
||||
|
||||
val resultType = functionDescriptor.createFunctionType(suspendFunctionTypeExpected)
|
||||
// We forbid anonymous function expressions to suspend type coercion for now, until `suspend fun` syntax is supported
|
||||
val resultType = functionDescriptor.createFunctionType(suspendFunction = false)
|
||||
|
||||
if (components.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) && functionalTypeExpected)
|
||||
if (components.languageVersionSettings.supportsFeature(LanguageFeature.NewInference) && functionalTypeExpected && !expectedType.isSuspendFunctionType)
|
||||
createTypeInfo(resultType, context)
|
||||
else
|
||||
components.dataFlowAnalyzer.createCheckedTypeInfo(resultType, context, function)
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
@@ -650,14 +651,17 @@ class ExpressionCodegen(
|
||||
StackValue.putUnitInstance(mv)
|
||||
}
|
||||
val boxedType = boxType(asmType)
|
||||
generateAsCast(mv, expression.typeOperand.toKotlinType(), boxedType, expression.operator == IrTypeOperator.SAFE_CAST)
|
||||
generateAsCast(
|
||||
mv, expression.typeOperand.toKotlinType(), boxedType, expression.operator == IrTypeOperator.SAFE_CAST,
|
||||
state.languageVersionSettings.isReleaseCoroutines()
|
||||
)
|
||||
return onStack(boxedType)
|
||||
}
|
||||
|
||||
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> {
|
||||
gen(expression.argument, OBJECT_TYPE, data)
|
||||
val type = boxType(asmType)
|
||||
generateIsCheck(mv, expression.typeOperand.toKotlinType(), type)
|
||||
generateIsCheck(mv, expression.typeOperand.toKotlinType(), type, state.languageVersionSettings.isReleaseCoroutines())
|
||||
if (IrTypeOperator.NOT_INSTANCEOF == expression.operator) {
|
||||
StackValue.not(StackValue.onStack(Type.BOOLEAN_TYPE)).put(Type.BOOLEAN_TYPE, mv)
|
||||
}
|
||||
|
||||
@@ -39,6 +39,10 @@ public final class Boolean : kotlin.Comparable<kotlin.Boolean> {
|
||||
public final operator fun not(): kotlin.Boolean
|
||||
public final infix fun or(/*0*/ other: kotlin.Boolean): kotlin.Boolean
|
||||
public final infix fun xor(/*0*/ other: kotlin.Boolean): kotlin.Boolean
|
||||
|
||||
@kotlin.SinceKotlin(version = "1.3") public companion object Companion {
|
||||
/*primary*/ private constructor Companion()
|
||||
}
|
||||
}
|
||||
|
||||
public final class BooleanArray {
|
||||
@@ -117,6 +121,10 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte> {
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Byte
|
||||
public const final val MIN_VALUE: kotlin.Byte
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Byte
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,12 +163,20 @@ public final class Char : kotlin.Comparable<kotlin.Char> {
|
||||
public final fun <get-MAX_LOW_SURROGATE>(): kotlin.Char
|
||||
public const final val MAX_SURROGATE: kotlin.Char
|
||||
public final fun <get-MAX_SURROGATE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val MAX_VALUE: kotlin.Char
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Char
|
||||
public const final val MIN_HIGH_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_HIGH_SURROGATE>(): kotlin.Char
|
||||
public const final val MIN_LOW_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_LOW_SURROGATE>(): kotlin.Char
|
||||
public const final val MIN_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_SURROGATE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val MIN_VALUE: kotlin.Char
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,6 +491,10 @@ public final class Int : kotlin.Number, kotlin.Comparable<kotlin.Int> {
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Int
|
||||
public const final val MIN_VALUE: kotlin.Int
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,6 +581,10 @@ public final class Long : kotlin.Number, kotlin.Comparable<kotlin.Long> {
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Long
|
||||
public const final val MIN_VALUE: kotlin.Long
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Long
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,6 +697,10 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short> {
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Short
|
||||
public const final val MIN_VALUE: kotlin.Short
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Short
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ public final class Boolean : kotlin.Comparable<kotlin.Boolean>, java.io.Serializ
|
||||
public final operator fun not(): kotlin.Boolean
|
||||
public final infix fun or(/*0*/ other: kotlin.Boolean): kotlin.Boolean
|
||||
public final infix fun xor(/*0*/ other: kotlin.Boolean): kotlin.Boolean
|
||||
|
||||
@kotlin.SinceKotlin(version = "1.3") public companion object Companion {
|
||||
/*primary*/ private constructor Companion()
|
||||
}
|
||||
}
|
||||
|
||||
public final class BooleanArray : kotlin.Any, kotlin.Cloneable, java.io.Serializable {
|
||||
@@ -119,6 +123,10 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Byte
|
||||
public const final val MIN_VALUE: kotlin.Byte
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Byte
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,12 +166,20 @@ public final class Char : kotlin.Comparable<kotlin.Char>, java.io.Serializable {
|
||||
public final fun <get-MAX_LOW_SURROGATE>(): kotlin.Char
|
||||
public const final val MAX_SURROGATE: kotlin.Char
|
||||
public final fun <get-MAX_SURROGATE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val MAX_VALUE: kotlin.Char
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Char
|
||||
public const final val MIN_HIGH_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_HIGH_SURROGATE>(): kotlin.Char
|
||||
public const final val MIN_LOW_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_LOW_SURROGATE>(): kotlin.Char
|
||||
public const final val MIN_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_SURROGATE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val MIN_VALUE: kotlin.Char
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,6 +505,10 @@ public final class Int : kotlin.Number, kotlin.Comparable<kotlin.Int>, java.io.S
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Int
|
||||
public const final val MIN_VALUE: kotlin.Int
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,6 +596,10 @@ public final class Long : kotlin.Number, kotlin.Comparable<kotlin.Long>, java.io
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Long
|
||||
public const final val MIN_VALUE: kotlin.Long
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Long
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -689,6 +713,10 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Short
|
||||
public const final val MIN_VALUE: kotlin.Short
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Short
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ public final class Boolean : kotlin.Comparable<kotlin.Boolean>, java.io.Serializ
|
||||
public final operator fun not(): kotlin.Boolean
|
||||
public final infix fun or(/*0*/ other: kotlin.Boolean): kotlin.Boolean
|
||||
public final infix fun xor(/*0*/ other: kotlin.Boolean): kotlin.Boolean
|
||||
|
||||
@kotlin.SinceKotlin(version = "1.3") public companion object Companion {
|
||||
/*primary*/ private constructor Companion()
|
||||
}
|
||||
}
|
||||
|
||||
public final class BooleanArray : kotlin.Any, kotlin.Cloneable, java.io.Serializable {
|
||||
@@ -119,6 +123,10 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Byte
|
||||
public const final val MIN_VALUE: kotlin.Byte
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Byte
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,12 +166,20 @@ public final class Char : kotlin.Comparable<kotlin.Char>, java.io.Serializable {
|
||||
public final fun <get-MAX_LOW_SURROGATE>(): kotlin.Char
|
||||
public const final val MAX_SURROGATE: kotlin.Char
|
||||
public final fun <get-MAX_SURROGATE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val MAX_VALUE: kotlin.Char
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Char
|
||||
public const final val MIN_HIGH_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_HIGH_SURROGATE>(): kotlin.Char
|
||||
public const final val MIN_LOW_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_LOW_SURROGATE>(): kotlin.Char
|
||||
public const final val MIN_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_SURROGATE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val MIN_VALUE: kotlin.Char
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,6 +507,10 @@ public final class Int : kotlin.Number, kotlin.Comparable<kotlin.Int>, java.io.S
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Int
|
||||
public const final val MIN_VALUE: kotlin.Int
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -578,6 +598,10 @@ public final class Long : kotlin.Number, kotlin.Comparable<kotlin.Long>, java.io
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Long
|
||||
public const final val MIN_VALUE: kotlin.Long
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Long
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,6 +715,10 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Short
|
||||
public const final val MIN_VALUE: kotlin.Short
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Short
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,10 @@ public final class Boolean : kotlin.Comparable<kotlin.Boolean>, java.io.Serializ
|
||||
public final operator fun not(): kotlin.Boolean
|
||||
public final infix fun or(/*0*/ other: kotlin.Boolean): kotlin.Boolean
|
||||
public final infix fun xor(/*0*/ other: kotlin.Boolean): kotlin.Boolean
|
||||
|
||||
@kotlin.SinceKotlin(version = "1.3") public companion object Companion {
|
||||
/*primary*/ private constructor Companion()
|
||||
}
|
||||
}
|
||||
|
||||
public final class BooleanArray : kotlin.Any, kotlin.Cloneable, java.io.Serializable {
|
||||
@@ -119,6 +123,10 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Byte
|
||||
public const final val MIN_VALUE: kotlin.Byte
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Byte
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,12 +166,20 @@ public final class Char : kotlin.Comparable<kotlin.Char>, java.io.Serializable {
|
||||
public final fun <get-MAX_LOW_SURROGATE>(): kotlin.Char
|
||||
public const final val MAX_SURROGATE: kotlin.Char
|
||||
public final fun <get-MAX_SURROGATE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val MAX_VALUE: kotlin.Char
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Char
|
||||
public const final val MIN_HIGH_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_HIGH_SURROGATE>(): kotlin.Char
|
||||
public const final val MIN_LOW_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_LOW_SURROGATE>(): kotlin.Char
|
||||
public const final val MIN_SURROGATE: kotlin.Char
|
||||
public final fun <get-MIN_SURROGATE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val MIN_VALUE: kotlin.Char
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Char
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,6 +505,10 @@ public final class Int : kotlin.Number, kotlin.Comparable<kotlin.Int>, java.io.S
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Int
|
||||
public const final val MIN_VALUE: kotlin.Int
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,6 +596,10 @@ public final class Long : kotlin.Number, kotlin.Comparable<kotlin.Long>, java.io
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Long
|
||||
public const final val MIN_VALUE: kotlin.Long
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Long
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
@@ -689,6 +713,10 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
|
||||
public final fun <get-MAX_VALUE>(): kotlin.Short
|
||||
public const final val MIN_VALUE: kotlin.Short
|
||||
public final fun <get-MIN_VALUE>(): kotlin.Short
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BITS: kotlin.Int
|
||||
public final fun <get-SIZE_BITS>(): kotlin.Int
|
||||
@kotlin.SinceKotlin(version = "1.3") public const final val SIZE_BYTES: kotlin.Int
|
||||
public final fun <get-SIZE_BYTES>(): kotlin.Int
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.internal.ContractsDsl
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun <T> myRun(block: () -> T): T {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun myRun(block: () -> Unit): Unit {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun myRun(block: () -> Unit): Unit {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun <T> myRun(block: () -> T): T {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun <T> myRun(block: () -> T): T {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun myRun(block: () -> Unit): Unit {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.internal.ContractsDsl
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun callsAndInverts(b: Boolean, block: () -> Unit): Boolean {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun myRun(block: () -> Unit) {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun <T> myRun(block: () -> T): T {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun <T> myRun(block: () -> T): T {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun <T, R> T.myLet(block: (T) -> R): R {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun myRun(block: () -> Unit): Unit {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect +UseReturnsEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun callsAndInverts(b: Boolean, block: () -> Unit): Boolean {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun myRun(block: () -> Unit) {
|
||||
contract {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// !LANGUAGE: +AllowContractsForCustomFunctions +UseCallsInPlaceEffect
|
||||
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
|
||||
|
||||
import kotlin.internal.contracts.*
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun <T> myRun(block: () -> T): T {
|
||||
contract {
|
||||
|
||||
@@ -11,10 +11,9 @@ suspend fun foo(data: Data, body: suspend (Data) -> Unit) {
|
||||
body(data)
|
||||
}
|
||||
|
||||
// METHOD : DataClassKt$test$2.doResume(Ljava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;
|
||||
// METHOD : DataClassKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LDataClassKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=data TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=throwable TYPE=Ljava/lang/Throwable; INDEX=2
|
||||
// VARIABLE : NAME=$x_param_y_param TYPE=LData; INDEX=3
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=y_param TYPE=I INDEX=5
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$x_param_y_param TYPE=LData; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=I INDEX=4
|
||||
|
||||
@@ -17,11 +17,10 @@ suspend fun B.bar(): String {
|
||||
|
||||
suspend fun test() = B.bar()
|
||||
|
||||
// METHOD : ExtensionComponentsKt$bar$3.doResume(Ljava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;
|
||||
// METHOD : ExtensionComponentsKt$bar$3.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LExtensionComponentsKt$bar$3; INDEX=0
|
||||
// VARIABLE : NAME=data TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=throwable TYPE=Ljava/lang/Throwable; INDEX=2
|
||||
// VARIABLE : NAME=$x_param_y_param_z_param TYPE=LA; INDEX=3
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=5
|
||||
// VARIABLE : NAME=z_param TYPE=I INDEX=6
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$x_param_y_param_z_param TYPE=LA; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=z_param TYPE=I INDEX=5
|
||||
|
||||
@@ -5,10 +5,9 @@ suspend fun <X, Y> foo(a: A<X, Y>, block: suspend (A<X, Y>) -> String) = block(a
|
||||
|
||||
suspend fun test() = foo(A("OK", 1)) { (x_param, y_param) -> x_param + (y_param.toString()) }
|
||||
|
||||
// METHOD : GenericKt$test$2.doResume(Ljava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;
|
||||
// METHOD : GenericKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LGenericKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=data TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=throwable TYPE=Ljava/lang/Throwable; INDEX=2
|
||||
// VARIABLE : NAME=$x_param_y_param TYPE=LA; INDEX=3
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=y_param TYPE=I INDEX=5
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$x_param_y_param TYPE=LA; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=I INDEX=4
|
||||
|
||||
@@ -5,9 +5,9 @@ suspend inline fun foo(a: A, block: suspend (A) -> String): String = block(a)
|
||||
|
||||
suspend fun test() = foo(A("O", "K")) { (x_param, y_param) -> x_param + y_param }
|
||||
|
||||
// METHOD : InlineKt.test(Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
|
||||
// METHOD : InlineKt.test(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=<name for destructuring parameter 0> TYPE=LA; INDEX=3
|
||||
// VARIABLE : NAME=continuation TYPE=Lkotlin/coroutines/experimental/Continuation; INDEX=2
|
||||
// VARIABLE : NAME=continuation TYPE=Lkotlin/coroutines/Continuation; INDEX=2
|
||||
// VARIABLE : NAME=$x_param_y_param TYPE=LA; INDEX=5
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=6
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=7
|
||||
|
||||
@@ -5,10 +5,9 @@ suspend fun foo(a: A, block: suspend (Int, A, String) -> String): String = block
|
||||
|
||||
suspend fun test() = foo(A("O", "K")) { i_param, (x_param, y_param), v_param -> i_param.toString() + x_param + y_param + v_param }
|
||||
|
||||
// METHOD : OtherParametersKt$test$2.doResume(Ljava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;
|
||||
// METHOD : OtherParametersKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LOtherParametersKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=data TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=throwable TYPE=Ljava/lang/Throwable; INDEX=2
|
||||
// VARIABLE : NAME=$x_param_y_param TYPE=LA; INDEX=3
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=5
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$x_param_y_param TYPE=LA; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=4
|
||||
|
||||
@@ -9,10 +9,9 @@ suspend fun foo(a: A, block: suspend (A) -> String): String = block(a)
|
||||
|
||||
suspend fun test() = foo(A()) { (x_param, _, y_param) -> x_param + y_param }
|
||||
|
||||
// METHOD : UnderscoreNamesKt$test$2.doResume(Ljava/lang/Object;Ljava/lang/Throwable;)Ljava/lang/Object;
|
||||
// METHOD : UnderscoreNamesKt$test$2.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
|
||||
// VARIABLE : NAME=this TYPE=LUnderscoreNamesKt$test$2; INDEX=0
|
||||
// VARIABLE : NAME=data TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=throwable TYPE=Ljava/lang/Throwable; INDEX=2
|
||||
// VARIABLE : NAME=$x_param_$_$_y_param TYPE=LA; INDEX=3
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=4
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=5
|
||||
// VARIABLE : NAME=result TYPE=Ljava/lang/Object; INDEX=1
|
||||
// VARIABLE : NAME=$x_param_$_$_y_param TYPE=LA; INDEX=2
|
||||
// VARIABLE : NAME=x_param TYPE=Ljava/lang/String; INDEX=3
|
||||
// VARIABLE : NAME=y_param TYPE=Ljava/lang/String; INDEX=4
|
||||
|
||||
@@ -2,4 +2,4 @@ $TESTDATA_DIR$/languageVersion.kt
|
||||
-output
|
||||
$TEMP_DIR$/out.js
|
||||
-language-version
|
||||
1.0
|
||||
1.2
|
||||
|
||||
6
compiler/testData/cli/js/languageVersion.kt
vendored
6
compiler/testData/cli/js/languageVersion.kt
vendored
@@ -1,5 +1,5 @@
|
||||
package test
|
||||
|
||||
sealed class Base
|
||||
|
||||
class Derived : Base()
|
||||
annotation class Outer {
|
||||
class Nested
|
||||
}
|
||||
|
||||
6
compiler/testData/cli/js/languageVersion.out
vendored
6
compiler/testData/cli/js/languageVersion.out
vendored
@@ -1,4 +1,4 @@
|
||||
compiler/testData/cli/js/languageVersion.kt:5:17: error: this type is sealed, so it can be inherited by only its own nested classes or objects
|
||||
class Derived : Base()
|
||||
^
|
||||
compiler/testData/cli/js/languageVersion.kt:4:5: error: members are not allowed in annotation class
|
||||
class Nested
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
|
||||
2
compiler/testData/cli/jvm/apiVersion.args
vendored
2
compiler/testData/cli/jvm/apiVersion.args
vendored
@@ -2,4 +2,4 @@ $TESTDATA_DIR$/apiVersion.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-api-version
|
||||
1.0
|
||||
1.2
|
||||
|
||||
2
compiler/testData/cli/jvm/apiVersion.kt
vendored
2
compiler/testData/cli/jvm/apiVersion.kt
vendored
@@ -1,3 +1,3 @@
|
||||
fun test() {
|
||||
""::class.isInstance(42)
|
||||
""::class.sealedSubclasses
|
||||
}
|
||||
|
||||
9
compiler/testData/cli/jvm/apiVersion.out
vendored
9
compiler/testData/cli/jvm/apiVersion.out
vendored
@@ -1,7 +1,4 @@
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:5: error: the feature "bound callable references" is only available since API version 1.1
|
||||
""::class.isInstance(42)
|
||||
^
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:15: error: unresolved reference: isInstance
|
||||
""::class.isInstance(42)
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:15: error: unresolved reference: sealedSubclasses
|
||||
""::class.sealedSubclasses
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
COMPILATION_ERROR
|
||||
|
||||
3
compiler/testData/cli/jvm/apiVersion1.0.out
vendored
3
compiler/testData/cli/jvm/apiVersion1.0.out
vendored
@@ -1,3 +1,4 @@
|
||||
warning: language version 1.1 is deprecated and its support will be removed in a future version of Kotlin
|
||||
compiler/testData/cli/jvm/apiVersion1.0.kt:8:1: error: the feature "coroutines" is only available since API version 1.1 (see: https://kotlinlang.org/docs/diagnostics/experimental-coroutines)
|
||||
suspend fun test() {
|
||||
^
|
||||
@@ -10,4 +11,4 @@ compiler/testData/cli/jvm/apiVersion1.0.kt:10:5: error: the feature "bound calla
|
||||
compiler/testData/cli/jvm/apiVersion1.0.kt:15:11: error: the feature "local delegated properties" is only available since API version 1.1
|
||||
val b by lazy { "" }
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
COMPILATION_ERROR
|
||||
|
||||
@@ -2,4 +2,4 @@ $TESTDATA_DIR$/apiVersionAndSinceNewerKotlin.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-api-version
|
||||
1.0
|
||||
1.2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@SinceKotlin("1.0")
|
||||
@SinceKotlin("1.2")
|
||||
fun old() {}
|
||||
|
||||
@SinceKotlin("1.1")
|
||||
@SinceKotlin("1.3")
|
||||
fun new() {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
compiler/testData/cli/jvm/apiVersionAndSinceNewerKotlin.kt:4:1: warning: the version is greater than the specified API version 1.0
|
||||
@SinceKotlin("1.1")
|
||||
compiler/testData/cli/jvm/apiVersionAndSinceNewerKotlin.kt:4:1: warning: the version is greater than the specified API version 1.2
|
||||
@SinceKotlin("1.3")
|
||||
^
|
||||
OK
|
||||
|
||||
@@ -2,6 +2,6 @@ $TESTDATA_DIR$/apiVersion.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-api-version
|
||||
1.1
|
||||
1.3
|
||||
-language-version
|
||||
1.0
|
||||
1.2
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
error: -api-version (1.1) cannot be greater than -language-version (1.0)
|
||||
error: -api-version (1.3) cannot be greater than -language-version (1.2)
|
||||
COMPILATION_ERROR
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
error: unknown API version: 239.42
|
||||
Supported API versions: 1.0, 1.1, 1.2, 1.3 (EXPERIMENTAL), 1.4 (EXPERIMENTAL)
|
||||
Supported API versions: 1.0, 1.1, 1.2, 1.3, 1.4 (EXPERIMENTAL)
|
||||
COMPILATION_ERROR
|
||||
|
||||
@@ -1 +1 @@
|
||||
$TESTDATA_DIR$/apiVersion.kt -d $TEMP_DIR$ -api-version 1.0 -language-version 1.1
|
||||
$TESTDATA_DIR$/apiVersion.kt -d $TEMP_DIR$ -api-version 1.2 -language-version 1.3
|
||||
|
||||
@@ -2,6 +2,6 @@ $TESTDATA_DIR$/apiVersion.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-api-version
|
||||
1.0
|
||||
1.2
|
||||
-language-version
|
||||
1.1
|
||||
1.3
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:5: error: the feature "bound callable references" is only available since API version 1.1
|
||||
""::class.isInstance(42)
|
||||
^
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:15: error: unresolved reference: isInstance
|
||||
""::class.isInstance(42)
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:15: error: unresolved reference: sealedSubclasses
|
||||
""::class.sealedSubclasses
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
COMPILATION_ERROR
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:5: error: the feature "bound callable references" is only available since API version 1.1
|
||||
""::class.isInstance(42)
|
||||
^
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:15: error: unresolved reference: isInstance
|
||||
""::class.isInstance(42)
|
||||
compiler/testData/cli/jvm/apiVersion.kt:2:15: error: unresolved reference: sealedSubclasses
|
||||
""::class.sealedSubclasses
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
-X"some escaped \" sequence \\"
|
||||
$TESTDATA_DIR$/apiVersion.kt
|
||||
-d
|
||||
$TEMP_DIR$ -api-version 1.0 -language-version 1.1
|
||||
$TEMP_DIR$ -api-version 1.2 -language-version 1.3
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user