mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-08 00:21:29 +00:00
Compare commits
215 Commits
rr/faster_
...
v1.3.61
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9686c9447 | ||
|
|
e001e267a9 | ||
|
|
a1fad954a4 | ||
|
|
0d97db0c9a | ||
|
|
6b773bc94e | ||
|
|
2da4cc27a9 | ||
|
|
a5b177543d | ||
|
|
42ac850dac | ||
|
|
587fc691f0 | ||
|
|
89e0fc4657 | ||
|
|
ee4a5cc22e | ||
|
|
fea32f2e29 | ||
|
|
7e77ddb00c | ||
|
|
d97b3a0431 | ||
|
|
047a732c83 | ||
|
|
2c38847343 | ||
|
|
590ef2d0bb | ||
|
|
3ad00e82ed | ||
|
|
19e95fdd1d | ||
|
|
e3927092a1 | ||
|
|
96721d5563 | ||
|
|
c63658ef18 | ||
|
|
12ae63864f | ||
|
|
ecb08303a2 | ||
|
|
82a35ae75a | ||
|
|
4955b77dfb | ||
|
|
c332e33433 | ||
|
|
68603acc2b | ||
|
|
b82cd43e66 | ||
|
|
d7d33d1757 | ||
|
|
eaa5c34f95 | ||
|
|
8a496cc6ec | ||
|
|
4158180941 | ||
|
|
00ff9116d8 | ||
|
|
947bcdd641 | ||
|
|
9fb9f9cb67 | ||
|
|
2f0905ab28 | ||
|
|
e9ba4e5d98 | ||
|
|
43d2eb4abe | ||
|
|
e37e2aea84 | ||
|
|
24e7dcbb0a | ||
|
|
c356568b58 | ||
|
|
dd783b0551 | ||
|
|
1ec9a165a4 | ||
|
|
775edbec3c | ||
|
|
fb28787eea | ||
|
|
3ae3c82f5c | ||
|
|
29a67cb908 | ||
|
|
f53746694f | ||
|
|
f9281b6bd3 | ||
|
|
d0190b9c95 | ||
|
|
e2f12382bf | ||
|
|
0a91f8518b | ||
|
|
67f589a2e3 | ||
|
|
53cf69387e | ||
|
|
28bf874a53 | ||
|
|
0b16a84c81 | ||
|
|
705cac2e61 | ||
|
|
95ebcbdb79 | ||
|
|
c1f6ed3f54 | ||
|
|
18cf7be818 | ||
|
|
a4f6590101 | ||
|
|
709fddae2d | ||
|
|
dac9dddd2d | ||
|
|
bf11fd5f73 | ||
|
|
abe3c67fa8 | ||
|
|
785d43d7ed | ||
|
|
f54ad390f7 | ||
|
|
6b5ef868b9 | ||
|
|
be773a0565 | ||
|
|
8fb5ccc7cf | ||
|
|
b997f32834 | ||
|
|
294617793a | ||
|
|
23bcc3939f | ||
|
|
133ad1090e | ||
|
|
62019adbfa | ||
|
|
bbc549742b | ||
|
|
a3998d87fb | ||
|
|
026046e48c | ||
|
|
58221ca078 | ||
|
|
b8b251bff9 | ||
|
|
1ba1660870 | ||
|
|
2140a7c2be | ||
|
|
1277ceafb8 | ||
|
|
8ab6c8cfac | ||
|
|
85271eeb1c | ||
|
|
b731cee2b1 | ||
|
|
9c9450ceb3 | ||
|
|
08c58d3184 | ||
|
|
23b380c382 | ||
|
|
e8dfcaca6f | ||
|
|
aa79948dba | ||
|
|
ee96a0902d | ||
|
|
eeff8f489b | ||
|
|
755940007d | ||
|
|
d424354c78 | ||
|
|
cbf8d117b8 | ||
|
|
2c937ec570 | ||
|
|
fa0e7c2961 | ||
|
|
c316438285 | ||
|
|
f29b26a95f | ||
|
|
8a83046d37 | ||
|
|
1f3db03a48 | ||
|
|
098212e2e4 | ||
|
|
2dd49cb0ba | ||
|
|
dc696ea816 | ||
|
|
c97a8d11f2 | ||
|
|
05c03d5b2e | ||
|
|
25676ceda7 | ||
|
|
7abdab0c09 | ||
|
|
9a053f6928 | ||
|
|
f2527dfdf4 | ||
|
|
5ab98732c8 | ||
|
|
79d467c595 | ||
|
|
d8ab61273a | ||
|
|
81f7e48abb | ||
|
|
4422c43815 | ||
|
|
bdc93e451d | ||
|
|
83a4fcf18d | ||
|
|
4c8d304e68 | ||
|
|
85d8a9f35d | ||
|
|
4406dad9e6 | ||
|
|
77ec036006 | ||
|
|
af0b1fe5b4 | ||
|
|
dfc6106e57 | ||
|
|
5f296d162b | ||
|
|
4491299d58 | ||
|
|
9276902ef0 | ||
|
|
fb1e768a52 | ||
|
|
2cdab841e5 | ||
|
|
14b6017089 | ||
|
|
73fa7c3b0e | ||
|
|
1c5cbc2449 | ||
|
|
6f74f230bb | ||
|
|
c0d3bc5218 | ||
|
|
5dea8e86a8 | ||
|
|
c021ca6264 | ||
|
|
2097d6de71 | ||
|
|
5cd1961b7e | ||
|
|
df676de30e | ||
|
|
2f1a90678d | ||
|
|
8761d1c621 | ||
|
|
b76b3d8fab | ||
|
|
30e12119a6 | ||
|
|
aac5475d93 | ||
|
|
0a64fdc40f | ||
|
|
2d7936c98b | ||
|
|
c715b42961 | ||
|
|
aa2f552f02 | ||
|
|
d2f5d87d41 | ||
|
|
9d9f3f17aa | ||
|
|
55150bfacc | ||
|
|
1e5050e5f3 | ||
|
|
07ab3b89b7 | ||
|
|
253077bdf4 | ||
|
|
9f15055b0e | ||
|
|
e7a794b814 | ||
|
|
1005f1f473 | ||
|
|
4866c7ccfe | ||
|
|
efcf136813 | ||
|
|
2437a8e43a | ||
|
|
2f42c88180 | ||
|
|
7a7c7c5f6e | ||
|
|
47bf4d3474 | ||
|
|
a8599875b5 | ||
|
|
0f78a45008 | ||
|
|
b230cdbcb0 | ||
|
|
3f1927887f | ||
|
|
bf8ccbc396 | ||
|
|
e5c0d4440a | ||
|
|
ba1e0c8c50 | ||
|
|
ef46414012 | ||
|
|
02c522db47 | ||
|
|
afaa730d7f | ||
|
|
a4899235f0 | ||
|
|
8561ff4f83 | ||
|
|
81f3106918 | ||
|
|
fc0b7b16e1 | ||
|
|
e8617a154c | ||
|
|
5f4c2405cc | ||
|
|
2c1ab9fc0b | ||
|
|
e8239aece9 | ||
|
|
456a03cb5b | ||
|
|
a8effec213 | ||
|
|
46fef9d71c | ||
|
|
6d905157b3 | ||
|
|
5f12ba992f | ||
|
|
cc8eec91fd | ||
|
|
5e4bfe09db | ||
|
|
574715616e | ||
|
|
f1f6963607 | ||
|
|
cfc8721cde | ||
|
|
d5d3e9a58b | ||
|
|
8a8e42a1fe | ||
|
|
e17f3edd3c | ||
|
|
b3ccda2f8d | ||
|
|
759141545a | ||
|
|
6c71264718 | ||
|
|
f4c170f156 | ||
|
|
2597ac278d | ||
|
|
ae4d8447c6 | ||
|
|
77a325b664 | ||
|
|
1fa392cdcd | ||
|
|
03896b1a02 | ||
|
|
5f397e27f8 | ||
|
|
10a1d10100 | ||
|
|
ca8cd19bff | ||
|
|
8320337b05 | ||
|
|
995b4637b8 | ||
|
|
7bbe89fd60 | ||
|
|
ed2ca98e01 | ||
|
|
7f403dc87f | ||
|
|
9fdd516582 | ||
|
|
1f2df0f018 | ||
|
|
087ada6b4e |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -52,4 +52,5 @@ kotlin-ultimate/
|
||||
node_modules/
|
||||
.rpt2_cache/
|
||||
libraries/tools/kotlin-test-js-runner/lib/
|
||||
libraries/tools/kotlin-source-map-loader/lib/
|
||||
local.properties
|
||||
|
||||
8682
ChangeLog.md
8682
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,6 @@ apply(plugin = "kotlinx.benchmark")
|
||||
plugins {
|
||||
java
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
@@ -169,7 +169,7 @@ extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.3.60-dev-12485"
|
||||
extra["versions.kotlin-native"] = "1.3.61"
|
||||
}
|
||||
|
||||
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
|
||||
@@ -527,6 +527,7 @@ tasks {
|
||||
dependsOn(":kotlin-script-util:test")
|
||||
dependsOn(":kotlin-scripting-compiler:test")
|
||||
dependsOn(":kotlin-scripting-common:test")
|
||||
dependsOn(":kotlin-scripting-jvm:test")
|
||||
dependsOn(":kotlin-scripting-jvm-host-test:test")
|
||||
dependsOn(":kotlin-scripting-jsr223-test:test")
|
||||
dependsOn(":kotlin-scripting-jvm-host-test:embeddableTest")
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="[Pill] IDEA Ultimate" type="Application" factoryName="Application" singleton="true">
|
||||
<log_file alias="idea.log" path="$PROJECT_DIR$/ideaSDK/system-idea/log/idea.log" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<module name="kotlin-ultimate.ultimate.ultimate-runner" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$PROJECT_DIR$/local/ideaSandbox -Didea.config.path=$PROJECT_DIR$/local/ideaSandbox/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin $ADDITIONAL_IDEA_ARGS$" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$IDEA_HOME_PATH$" />
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="" />
|
||||
<option name="TRANSPORT" value="0" />
|
||||
<option name="LOCAL" value="true" />
|
||||
</RunnerSettings>
|
||||
<RunnerSettings RunnerId="JavaRebel">
|
||||
<option name="bootstrapPath" />
|
||||
<option name="jrebelArgs" value="" />
|
||||
<option name="loggingEnabled" value="false" />
|
||||
<option name="useBootstrapDefaults" value="true" />
|
||||
</RunnerSettings>
|
||||
<RunnerSettings RunnerId="JavaRebel Debug">
|
||||
<option name="bootstrapPath" />
|
||||
<option name="debugPort" value="" />
|
||||
<option name="jrebelArgs" value="" />
|
||||
<option name="loggingEnabled" value="false" />
|
||||
<option name="transport" value="0" />
|
||||
<option name="useBootstrapDefaults" value="true" />
|
||||
<option name="DEBUG_PORT" value="" />
|
||||
<option name="TRANSPORT" value="0" />
|
||||
<option name="LOCAL" value="true" />
|
||||
</RunnerSettings>
|
||||
<RunnerSettings RunnerId="Profile " />
|
||||
<RunnerSettings RunnerId="Run" />
|
||||
<ConfigurationWrapper RunnerId="Debug" />
|
||||
<ConfigurationWrapper RunnerId="Profile " />
|
||||
<ConfigurationWrapper RunnerId="Run" />
|
||||
<method>
|
||||
<option name="BuildArtifacts" enabled="true">
|
||||
<artifact name="KotlinPlugin" />
|
||||
</option>
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1447,9 +1447,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
leaveTasks.add(answer -> {
|
||||
int index = myFrameMap.leave(functionDescriptor);
|
||||
|
||||
assert !functionDescriptor.getName().isSpecial()
|
||||
: "Local variable should be generated only for function with name: " + localFunction.getText();
|
||||
|
||||
String functionIndex = StringsKt.substringAfterLast(type.getInternalName(), '$', "");
|
||||
assert !functionIndex.isEmpty();
|
||||
|
||||
@@ -2536,6 +2533,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
|
||||
|
||||
if (isSuspendNoInlineCall) {
|
||||
addReturnsUnitMarkerIfNecessary(v, resolvedCall);
|
||||
|
||||
addSuspendMarker(v, false);
|
||||
addInlineMarker(v, false);
|
||||
}
|
||||
@@ -3297,7 +3296,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
else if (opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ ||
|
||||
opToken == KtTokens.EQEQEQ || opToken == KtTokens.EXCLEQEQEQ) {
|
||||
return generateEquals(
|
||||
expression.getLeft(), expression.getRight(), opToken, null,
|
||||
expression.getLeft(), expression.getRight(), opToken, null, null,
|
||||
bindingContext.get(BindingContext.PRIMITIVE_NUMERIC_COMPARISON_INFO, expression)
|
||||
);
|
||||
}
|
||||
@@ -3372,6 +3371,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
@Nullable KtExpression right,
|
||||
@NotNull IElementType opToken,
|
||||
@Nullable StackValue pregeneratedSubject,
|
||||
@Nullable KotlinType subjectKotlinType,
|
||||
@Nullable PrimitiveNumericComparisonInfo primitiveNumericComparisonInfo
|
||||
) {
|
||||
if (left == null || right == null) {
|
||||
@@ -3382,7 +3382,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
});
|
||||
}
|
||||
|
||||
KotlinType leftKotlinType = kotlinType(left);
|
||||
KotlinType leftKotlinType = (subjectKotlinType != null) ? subjectKotlinType : kotlinType(left);
|
||||
KotlinType rightKotlinType = kotlinType(right);
|
||||
boolean leftIsInlineClass = leftKotlinType != null && InlineClassesUtilsKt.isInlineClassType(leftKotlinType);
|
||||
boolean rightIsInlineClass = rightKotlinType != null && InlineClassesUtilsKt.isInlineClassType(rightKotlinType);
|
||||
@@ -3871,12 +3871,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
Type type = expressionType(exp);
|
||||
StackValue argument = pregeneratedExpr != null ? pregeneratedExpr : gen(exp);
|
||||
|
||||
if (kotlinType == null || TypeUtils.isNullableType(kotlinType)) {
|
||||
if (kotlinType == null || TypeUtils.isNullableType(kotlinType) || !InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
||||
return StackValue.compareWithNull(argument, (KtTokens.EQEQ == opToken || KtTokens.EQEQEQ == opToken) ? IFNONNULL : IFNULL);
|
||||
} else {
|
||||
// If exp has a non-nullable type, the comparison is vacuous.
|
||||
// For inline classes we cannot necessarily compare with null at all.
|
||||
// In this case the code below is necessary for correctness, not just an optimization.
|
||||
// If exp is an unboxed inline class value the comparison is vacuous
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
|
||||
argument.put(type, kotlinType, v);
|
||||
AsmUtil.pop(v, type);
|
||||
@@ -4892,10 +4890,10 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
return generateIsCheck(match, expression.getTypeReference(), expression.isNegated());
|
||||
}
|
||||
|
||||
private StackValue generateExpressionMatch(StackValue expressionToMatch, KtExpression subjectExpression, KtExpression patternExpression) {
|
||||
private StackValue generateExpressionMatch(StackValue expressionToMatch, KtExpression subjectExpression, KotlinType subjectKotlinType, KtExpression patternExpression) {
|
||||
if (expressionToMatch != null) {
|
||||
return generateEquals(
|
||||
subjectExpression, patternExpression, KtTokens.EQEQ, expressionToMatch,
|
||||
subjectExpression, patternExpression, KtTokens.EQEQ, expressionToMatch, subjectKotlinType,
|
||||
bindingContext.get(BindingContext.PRIMITIVE_NUMERIC_COMPARISON_INFO, patternExpression)
|
||||
);
|
||||
}
|
||||
@@ -4996,6 +4994,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
else {
|
||||
subjectLocal = -1;
|
||||
subjectType = Type.VOID_TYPE;
|
||||
subjectKotlinType = null;
|
||||
}
|
||||
|
||||
Label begin = new Label();
|
||||
@@ -5015,7 +5014,7 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
if (!whenEntry.isElse()) {
|
||||
KtWhenCondition[] conditions = whenEntry.getConditions();
|
||||
for (int i = 0; i < conditions.length; i++) {
|
||||
StackValue conditionValue = generateWhenCondition(subjectExpression, subjectType, subjectLocal, conditions[i]);
|
||||
StackValue conditionValue = generateWhenCondition(subjectExpression, subjectType, subjectKotlinType, subjectLocal, conditions[i]);
|
||||
BranchedValue.Companion.condJump(conditionValue, nextCondition, true, v);
|
||||
if (i < conditions.length - 1) {
|
||||
v.goTo(thisEntry);
|
||||
@@ -5069,21 +5068,21 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
}
|
||||
|
||||
private StackValue generateWhenCondition(KtExpression subjectExpression, Type subjectType, int subjectLocal, KtWhenCondition condition) {
|
||||
private StackValue generateWhenCondition(KtExpression subjectExpression, Type subjectType, KotlinType subjectKotlinType, int subjectLocal, KtWhenCondition condition) {
|
||||
if (condition instanceof KtWhenConditionInRange) {
|
||||
KtWhenConditionInRange conditionInRange = (KtWhenConditionInRange) condition;
|
||||
return generateIn(StackValue.local(subjectLocal, subjectType),
|
||||
return generateIn(StackValue.local(subjectLocal, subjectType, subjectKotlinType),
|
||||
conditionInRange.getRangeExpression(),
|
||||
conditionInRange.getOperationReference());
|
||||
}
|
||||
StackValue.Local match = subjectLocal == -1 ? null : StackValue.local(subjectLocal, subjectType);
|
||||
StackValue.Local match = subjectLocal == -1 ? null : StackValue.local(subjectLocal, subjectType, subjectKotlinType);
|
||||
if (condition instanceof KtWhenConditionIsPattern) {
|
||||
KtWhenConditionIsPattern patternCondition = (KtWhenConditionIsPattern) condition;
|
||||
return generateIsCheck(match, patternCondition.getTypeReference(), patternCondition.isNegated());
|
||||
}
|
||||
else if (condition instanceof KtWhenConditionWithExpression) {
|
||||
KtExpression patternExpression = ((KtWhenConditionWithExpression) condition).getExpression();
|
||||
return generateExpressionMatch(match, subjectExpression, patternExpression);
|
||||
return generateExpressionMatch(match, subjectExpression, subjectKotlinType, patternExpression);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("unsupported kind of when condition");
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.cfg.TailRecursionKind;
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext;
|
||||
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression;
|
||||
import org.jetbrains.kotlin.psi.ValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.TAIL_RECURSION_CALL;
|
||||
|
||||
public class TailRecursionCodegen {
|
||||
|
||||
@NotNull
|
||||
private final MethodContext context;
|
||||
@NotNull
|
||||
private final ExpressionCodegen codegen;
|
||||
@NotNull
|
||||
private final InstructionAdapter v;
|
||||
@NotNull
|
||||
private final GenerationState state;
|
||||
|
||||
public TailRecursionCodegen(
|
||||
@NotNull MethodContext context,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
this.context = context;
|
||||
this.codegen = codegen;
|
||||
this.v = v;
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public boolean isTailRecursion(@NotNull ResolvedCall<?> resolvedCall) {
|
||||
TailRecursionKind status = state.getBindingContext().get(TAIL_RECURSION_CALL, resolvedCall.getCall());
|
||||
return status != null && status.isDoGenerateTailRecursion();
|
||||
}
|
||||
|
||||
public void generateTailRecursion(ResolvedCall<?> resolvedCall) {
|
||||
CallableDescriptor fd = CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction(resolvedCall.getResultingDescriptor());
|
||||
assert fd instanceof FunctionDescriptor : "Resolved call doesn't refer to the function descriptor: " + fd;
|
||||
CallableMethod callable = (CallableMethod) codegen.resolveToCallable((FunctionDescriptor) fd, false, resolvedCall);
|
||||
|
||||
List<ResolvedValueArgument> arguments = resolvedCall.getValueArgumentsByIndex();
|
||||
if (arguments == null) {
|
||||
throw new IllegalStateException("Failed to arrange value arguments by index: " + fd);
|
||||
}
|
||||
|
||||
if (((FunctionDescriptor) fd).isSuspend()) {
|
||||
AsmUtil.pop(v, callable.getValueParameters().get(callable.getValueParameters().size() - 1).getAsmType());
|
||||
}
|
||||
|
||||
assignParameterValues(fd, callable, arguments);
|
||||
if (callable.getExtensionReceiverType() != null) {
|
||||
if (resolvedCall.getExtensionReceiver() != fd.getExtensionReceiverParameter().getValue()) {
|
||||
StackValue expression = context.getReceiverExpression(codegen.typeMapper);
|
||||
expression.store(StackValue.onStack(callable.getExtensionReceiverType()), v, true);
|
||||
}
|
||||
else {
|
||||
AsmUtil.pop(v, callable.getExtensionReceiverType());
|
||||
}
|
||||
}
|
||||
|
||||
if (callable.getDispatchReceiverType() != null) {
|
||||
AsmUtil.pop(v, callable.getDispatchReceiverType());
|
||||
}
|
||||
|
||||
v.goTo(context.getMethodStartLabel());
|
||||
}
|
||||
|
||||
private void assignParameterValues(
|
||||
CallableDescriptor fd,
|
||||
CallableMethod callableMethod,
|
||||
List<ResolvedValueArgument> valueArguments
|
||||
) {
|
||||
List<Type> types = callableMethod.getValueParameterTypes();
|
||||
for (ValueParameterDescriptor parameterDescriptor : Lists.reverse(fd.getValueParameters())) {
|
||||
ResolvedValueArgument arg = valueArguments.get(parameterDescriptor.getIndex());
|
||||
Type type = types.get(parameterDescriptor.getIndex());
|
||||
|
||||
if (arg instanceof ExpressionValueArgument) {
|
||||
ExpressionValueArgument ev = (ExpressionValueArgument) arg;
|
||||
ValueArgument argument = ev.getValueArgument();
|
||||
KtExpression argumentExpression = argument == null ? null : argument.getArgumentExpression();
|
||||
|
||||
if (argumentExpression instanceof KtSimpleNameExpression) {
|
||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(argumentExpression, state.getBindingContext());
|
||||
if (resolvedCall != null && resolvedCall.getResultingDescriptor().equals(parameterDescriptor.getOriginal())) {
|
||||
// do nothing: we shouldn't store argument to itself again
|
||||
AsmUtil.pop(v, type);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//assign the parameter below
|
||||
}
|
||||
else if (arg instanceof DefaultValueArgument) {
|
||||
AsmUtil.pop(v, type);
|
||||
DefaultParameterValueLoader.DEFAULT.genValue(parameterDescriptor, codegen).put(type, v);
|
||||
}
|
||||
else if (arg instanceof VarargValueArgument) {
|
||||
// assign the parameter below
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unknown argument type: " + arg + " in " + fd);
|
||||
}
|
||||
|
||||
store(parameterDescriptor, type);
|
||||
}
|
||||
}
|
||||
|
||||
private void store(ValueParameterDescriptor parameterDescriptor, Type type) {
|
||||
int index = getParameterVariableIndex(parameterDescriptor);
|
||||
v.store(index, type);
|
||||
}
|
||||
|
||||
private int getParameterVariableIndex(ValueParameterDescriptor parameterDescriptor) {
|
||||
int index = codegen.lookupLocalIndex(parameterDescriptor);
|
||||
if (index == -1) {
|
||||
// in the case of a generic function recursively calling itself, the parameters on the call site are substituted
|
||||
index = codegen.lookupLocalIndex(parameterDescriptor.getOriginal());
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
throw new IllegalStateException("Failed to obtain parameter index: " + parameterDescriptor);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.context.MethodContext
|
||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.TAIL_RECURSION_CALL
|
||||
|
||||
class TailRecursionCodegen(
|
||||
private val context: MethodContext,
|
||||
private val codegen: ExpressionCodegen,
|
||||
private val v: InstructionAdapter,
|
||||
private val state: GenerationState
|
||||
) {
|
||||
|
||||
fun isTailRecursion(resolvedCall: ResolvedCall<*>): Boolean {
|
||||
val status = state.bindingContext.get(TAIL_RECURSION_CALL, resolvedCall.call)
|
||||
return status != null && status.isDoGenerateTailRecursion
|
||||
}
|
||||
|
||||
fun generateTailRecursion(resolvedCall: ResolvedCall<*>) {
|
||||
val fd = resolvedCall.resultingDescriptor.unwrapInitialDescriptorForSuspendFunction().let {
|
||||
it as? FunctionDescriptor
|
||||
?: error("Resolved call doesn't refer to the function descriptor: $it")
|
||||
}
|
||||
val callable = codegen.resolveToCallable(fd, false, resolvedCall) as CallableMethod
|
||||
|
||||
val arguments = resolvedCall.valueArgumentsByIndex ?: throw IllegalStateException("Failed to arrange value arguments by index: $fd")
|
||||
|
||||
if (fd.isSuspend) {
|
||||
AsmUtil.pop(v, callable.getValueParameters().last().asmType)
|
||||
}
|
||||
|
||||
assignParameterValues(fd, callable, arguments)
|
||||
if (callable.extensionReceiverType != null) {
|
||||
if (resolvedCall.extensionReceiver != fd.extensionReceiverParameter!!.value) {
|
||||
val expression = context.getReceiverExpression(codegen.typeMapper)
|
||||
expression.store(StackValue.onStack(callable.extensionReceiverType), v, true)
|
||||
} else {
|
||||
AsmUtil.pop(v, callable.extensionReceiverType)
|
||||
}
|
||||
}
|
||||
|
||||
if (callable.dispatchReceiverType != null) {
|
||||
AsmUtil.pop(v, callable.dispatchReceiverType)
|
||||
}
|
||||
|
||||
v.goTo(context.methodStartLabel)
|
||||
}
|
||||
|
||||
private fun assignParameterValues(
|
||||
fd: CallableDescriptor,
|
||||
callableMethod: CallableMethod,
|
||||
valueArguments: List<ResolvedValueArgument>
|
||||
) {
|
||||
val properDefaultInitialization =
|
||||
state.languageVersionSettings.supportsFeature(LanguageFeature.ProperComputationOrderOfTailrecDefaultParameters)
|
||||
|
||||
val types = callableMethod.valueParameterTypes
|
||||
loop@ for (parameterDescriptor in fd.valueParameters.asReversed()) {
|
||||
val arg = valueArguments[parameterDescriptor.index]
|
||||
val type = types[parameterDescriptor.index]
|
||||
|
||||
when (arg) {
|
||||
is ExpressionValueArgument -> {
|
||||
val argumentExpression = arg.valueArgument?.getArgumentExpression()
|
||||
|
||||
if (argumentExpression is KtSimpleNameExpression) {
|
||||
val resolvedCall = argumentExpression.getResolvedCall(state.bindingContext)
|
||||
if (resolvedCall?.resultingDescriptor == parameterDescriptor.original) {
|
||||
// do nothing: we shouldn't store argument to itself again
|
||||
AsmUtil.pop(v, type)
|
||||
continue@loop
|
||||
}
|
||||
}
|
||||
//assign the parameter below
|
||||
}
|
||||
is DefaultValueArgument -> {
|
||||
AsmUtil.pop(v, type)
|
||||
if (properDefaultInitialization) {
|
||||
//Initialization in proper order is performed in loop below
|
||||
continue@loop
|
||||
} else {
|
||||
DefaultParameterValueLoader.DEFAULT.genValue(parameterDescriptor, codegen).put(type, v)
|
||||
}
|
||||
}
|
||||
is VarargValueArgument -> {
|
||||
// assign the parameter below
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unknown argument type: $arg in $fd")
|
||||
}
|
||||
|
||||
store(parameterDescriptor, type)
|
||||
}
|
||||
|
||||
if (properDefaultInitialization) {
|
||||
for (parameterDescriptor in fd.valueParameters) {
|
||||
val arg = valueArguments[parameterDescriptor.index]
|
||||
val type = types[parameterDescriptor.index]
|
||||
|
||||
if (arg is DefaultValueArgument) {
|
||||
DefaultParameterValueLoader.DEFAULT.genValue(parameterDescriptor, codegen).put(type, v)
|
||||
store(parameterDescriptor, type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun store(parameterDescriptor: ValueParameterDescriptor, type: Type) {
|
||||
val index = getParameterVariableIndex(parameterDescriptor)
|
||||
v.store(index, type)
|
||||
}
|
||||
|
||||
private fun getParameterVariableIndex(parameterDescriptor: ValueParameterDescriptor): Int {
|
||||
var index = codegen.lookupLocalIndex(parameterDescriptor)
|
||||
if (index == -1) {
|
||||
// in the case of a generic function recursively calling itself, the parameters on the call site are substituted
|
||||
index = codegen.lookupLocalIndex(parameterDescriptor.original)
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
throw IllegalStateException("Failed to obtain parameter index: $parameterDescriptor")
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
||||
}
|
||||
@@ -161,9 +161,10 @@ private fun <Signature> findSuperImplementationForStubDelegation(
|
||||
// Implementation in super-class already has proper signature
|
||||
if (signatureByDescriptor(function) == signatureByDescriptor(implementation.descriptor)) return null
|
||||
|
||||
assert(function.modality == Modality.OPEN) {
|
||||
"Should generate stubs only for non-abstract built-ins, but ${function.name} is ${function.modality}"
|
||||
}
|
||||
// TODO: Enable the assertion once KT-34507 is fixed
|
||||
// assert(function.modality == Modality.OPEN) {
|
||||
// "Should generate stubs only for non-abstract built-ins, but ${function.name} is ${function.modality}"
|
||||
// }
|
||||
|
||||
return implementation.descriptor
|
||||
}
|
||||
|
||||
@@ -83,8 +83,7 @@ class CoroutineTransformerMethodVisitor(
|
||||
override fun performTransformations(methodNode: MethodNode) {
|
||||
removeFakeContinuationConstructorCall(methodNode)
|
||||
|
||||
// Remove redundant markers which came from compiled bytecode
|
||||
cleanUpReturnsUnitMarkers(methodNode)
|
||||
replaceReturnsUnitMarkersWithPushingUnitOnStack(methodNode)
|
||||
|
||||
replaceFakeContinuationsWithRealOnes(
|
||||
methodNode,
|
||||
@@ -228,8 +227,51 @@ class CoroutineTransformerMethodVisitor(
|
||||
)
|
||||
}
|
||||
|
||||
private fun cleanUpReturnsUnitMarkers(methodNode: MethodNode) {
|
||||
for (marker in methodNode.instructions.asSequence().filter(::isReturnsUnitMarker)) {
|
||||
/* Put { POP, GETSTATIC Unit } after suspension point if suspension point is a call of suspend function, that returns Unit.
|
||||
*
|
||||
* Otherwise, upon resume, the function would seem to not return Unit, despite being declared as returning Unit.
|
||||
*
|
||||
* This happens when said function is tail-call and its callee does not return Unit.
|
||||
*
|
||||
* Let's have an example
|
||||
*
|
||||
* suspend fun int(): Int = suspendCoroutine { ...; 1 }
|
||||
*
|
||||
* suspend fun unit() {
|
||||
* int()
|
||||
* }
|
||||
*
|
||||
* suspend fun main() {
|
||||
* println(unit())
|
||||
* }
|
||||
*
|
||||
* So, in order to understand the necessity of { POP, GETSTATIC Unit } inside `main`, we need to consider two different scenarios
|
||||
*
|
||||
* 1. `unit` is not a tail-call function.
|
||||
* 2. `unit` is a tail-call function.
|
||||
*
|
||||
* When `unit` is a not tail-call function, calling `resumeWith` on its continuation will resume `unit`,
|
||||
* it will hit { GETSTATIC Unit; ARETURN } and this Unit will be the result of the suspend call. `unit`'s continuation will then call
|
||||
* `main` continuation's `resumeWith`, passing the Unit instance. The continuation in turn will resume `main` and the Unit will be
|
||||
* the result of `unit()` call. This result will then printed.
|
||||
*
|
||||
* However, when `unit` is a tail-call function, there is no continuation, generated for it. This is the point of tail-call
|
||||
* optimization. Thus, resume call will skip `unit` and land direcly in `main` continuation's `resumeWith`. And its result is not
|
||||
* Unit. Thus, we must ignore this result on call-site and use Unit instead. In other words, POP the result and GETSTATIC Unit
|
||||
* instead.
|
||||
*/
|
||||
private fun replaceReturnsUnitMarkersWithPushingUnitOnStack(methodNode: MethodNode) {
|
||||
for (marker in methodNode.instructions.asSequence().filter(::isReturnsUnitMarker).toList()) {
|
||||
assert(marker.next?.next?.let { isAfterSuspendMarker(it) } == true) {
|
||||
"Expected AfterSuspendMarker after ReturnUnitMarker, got ${marker.next?.next}"
|
||||
}
|
||||
methodNode.instructions.insert(
|
||||
marker.next.next,
|
||||
withInstructionAdapter {
|
||||
pop()
|
||||
getstatic("kotlin/Unit", "INSTANCE", "Lkotlin/Unit;")
|
||||
}
|
||||
)
|
||||
methodNode.instructions.removeAll(listOf(marker.previous, marker))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +46,10 @@ class TypeRemapper private constructor(
|
||||
}
|
||||
|
||||
fun registerTypeParameter(name: String) {
|
||||
assert(typeParametersMapping[name] == null) {
|
||||
"Type parameter already registered $name"
|
||||
}
|
||||
//TODO: enable after KT-34656 proper fix
|
||||
// assert(typeParametersMapping[name] == null) {
|
||||
// "Type parameter already registered $name"
|
||||
// }
|
||||
typeParametersMapping[name] = TypeParameter(name, name, false, null)
|
||||
}
|
||||
|
||||
|
||||
@@ -403,6 +403,30 @@ fun addInlineMarker(v: InstructionAdapter, isStartNotEnd: Boolean) {
|
||||
)
|
||||
}
|
||||
|
||||
internal fun addReturnsUnitMarkerIfNecessary(v: InstructionAdapter, resolvedCall: ResolvedCall<*>) {
|
||||
val wrapperDescriptor = resolvedCall.candidateDescriptor.safeAs<FunctionDescriptor>() ?: return
|
||||
val unsubstitutedDescriptor = wrapperDescriptor.unwrapInitialDescriptorForSuspendFunction()
|
||||
|
||||
val typeSubstitutor = TypeSubstitutor.create(
|
||||
unsubstitutedDescriptor.typeParameters
|
||||
.withIndex()
|
||||
.associateBy({ it.value.typeConstructor }) {
|
||||
TypeProjectionImpl(resolvedCall.typeArguments[wrapperDescriptor.typeParameters[it.index]] ?: return)
|
||||
}
|
||||
)
|
||||
|
||||
val substitutedDescriptor = unsubstitutedDescriptor.substitute(typeSubstitutor) ?: return
|
||||
val returnType = substitutedDescriptor.returnType ?: return
|
||||
|
||||
if (KotlinBuiltIns.isUnit(returnType)) {
|
||||
addReturnsUnitMarker(v)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addReturnsUnitMarker(v: InstructionAdapter) {
|
||||
v.emitInlineMarker(INLINE_MARKER_RETURNS_UNIT)
|
||||
}
|
||||
|
||||
fun addSuspendMarker(v: InstructionAdapter, isStartNotEnd: Boolean) {
|
||||
v.emitInlineMarker(if (isStartNotEnd) INLINE_MARKER_BEFORE_SUSPEND_ID else INLINE_MARKER_AFTER_SUSPEND_ID)
|
||||
}
|
||||
|
||||
@@ -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-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.optimization.fixStack
|
||||
@@ -78,7 +67,8 @@ private fun insertSaveRestoreStackMarkers(
|
||||
|
||||
if (tryStartLabel !in saveStackMarkerByTryLabel) {
|
||||
val nopNode = tryStartLabel.findNextOrNull { it.hasOpcode() }!!
|
||||
assert(nopNode.opcode == Opcodes.NOP) { "${methodNode.instructions.indexOf(nopNode)}: try block should start with NOP" }
|
||||
// FIXME: Uncomment when KT-35035 is fixed.
|
||||
// assert(nopNode.opcode == Opcodes.NOP) { "${methodNode.instructions.indexOf(nopNode)}: try block should start with NOP" }
|
||||
|
||||
val newTryStartLabel = LabelNode(Label())
|
||||
newTryStartLabels[tryStartLabel] = newTryStartLabel
|
||||
|
||||
@@ -64,7 +64,8 @@ class GenerationState private constructor(
|
||||
val outDirectory: File?,
|
||||
private val onIndependentPartCompilationEnd: GenerationStateEventCallback,
|
||||
wantsDiagnostics: Boolean,
|
||||
val jvmBackendClassResolver: JvmBackendClassResolver
|
||||
val jvmBackendClassResolver: JvmBackendClassResolver,
|
||||
val isIrBackend: Boolean
|
||||
) {
|
||||
|
||||
class Builder(
|
||||
@@ -111,12 +112,16 @@ class GenerationState private constructor(
|
||||
fun jvmBackendClassResolver(v: JvmBackendClassResolver) =
|
||||
apply { jvmBackendClassResolver = v }
|
||||
|
||||
var isIrBackend: Boolean = configuration.getBoolean(JVMConfigurationKeys.IR)
|
||||
fun isIrBackend(v: Boolean) =
|
||||
apply { isIrBackend = v }
|
||||
|
||||
fun build() =
|
||||
GenerationState(
|
||||
project, builderFactory, module, bindingContext, files, configuration,
|
||||
generateDeclaredClassFilter, codegenFactory, targetId,
|
||||
moduleName, outDirectory, onIndependentPartCompilationEnd, wantsDiagnostics,
|
||||
jvmBackendClassResolver
|
||||
jvmBackendClassResolver, isIrBackend
|
||||
)
|
||||
}
|
||||
|
||||
@@ -196,7 +201,6 @@ class GenerationState private constructor(
|
||||
)
|
||||
val bindingContext: BindingContext = bindingTrace.bindingContext
|
||||
val mainFunctionDetector = MainFunctionDetector(bindingContext, languageVersionSettings)
|
||||
val isIrBackend = configuration.get(JVMConfigurationKeys.IR) ?: false
|
||||
val typeMapper: KotlinTypeMapper = KotlinTypeMapper(
|
||||
this.bindingContext,
|
||||
classBuilderMode,
|
||||
|
||||
@@ -3,6 +3,15 @@
|
||||
<version>1.2</version>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.analyzeCompleteHandlerExtension"
|
||||
interface="org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension"
|
||||
area="IDEA_PROJECT"/>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.callResolutionInterceptorExtension"
|
||||
interface="org.jetbrains.kotlin.extensions.CallResolutionInterceptorExtension"
|
||||
area="IDEA_PROJECT"/>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.typeResolutionInterceptorExtension"
|
||||
interface="org.jetbrains.kotlin.extensions.TypeResolutionInterceptorExtension"
|
||||
area="IDEA_PROJECT"/>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.diagnosticSuppressor"
|
||||
interface="org.jetbrains.kotlin.resolve.diagnostics.DiagnosticSuppressor"/>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.expressionCodegenExtension"
|
||||
|
||||
@@ -72,6 +72,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
|
||||
// Advanced options
|
||||
|
||||
@GradleOption(DefaultValues.BooleanFalseDefault::class)
|
||||
@Argument(value = "-Xuse-ir", description = "Use the IR backend")
|
||||
var useIR: Boolean by FreezableVar(false)
|
||||
|
||||
|
||||
@@ -19,13 +19,11 @@ package org.jetbrains.kotlin.cli.common.environment
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
|
||||
fun setIdeaIoUseFallback() {
|
||||
if (SystemInfo.isWindows) {
|
||||
val properties = System.getProperties()
|
||||
val properties = System.getProperties()
|
||||
|
||||
properties.setProperty("idea.io.use.nio2", java.lang.Boolean.TRUE.toString())
|
||||
properties.setProperty("idea.io.use.nio2", java.lang.Boolean.TRUE.toString())
|
||||
|
||||
if (!(SystemInfo.isJavaVersionAtLeast(1, 7, 0) && "1.7.0-ea" != SystemInfo.JAVA_VERSION)) {
|
||||
properties.setProperty("idea.io.use.fallback", java.lang.Boolean.TRUE.toString())
|
||||
}
|
||||
if (!(SystemInfo.isJavaVersionAtLeast(1, 7, 0) && "1.7.0-ea" != SystemInfo.JAVA_VERSION)) {
|
||||
properties.setProperty("idea.io.use.fallback", java.lang.Boolean.TRUE.toString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
|
||||
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
@@ -28,19 +29,18 @@ import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||
import org.jetbrains.kotlin.ir.backend.js.generateKLib
|
||||
import org.jetbrains.kotlin.ir.backend.js.jsPhases
|
||||
import org.jetbrains.kotlin.ir.backend.js.jsResolveLibraries
|
||||
import org.jetbrains.kotlin.js.config.EcmaVersion
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.js.config.JsConfig
|
||||
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
||||
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.KotlinLibrarySearchPathResolver
|
||||
import org.jetbrains.kotlin.library.UnresolvedLibrary
|
||||
import org.jetbrains.kotlin.library.toUnresolvedLibraries
|
||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
import org.jetbrains.kotlin.utils.JsMetadataVersion
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import org.jetbrains.kotlin.utils.join
|
||||
@@ -142,21 +142,15 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
// TODO: Handle non-empty main call arguments
|
||||
val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList<String>()
|
||||
|
||||
val unresolvedLibraries = libraries.toUnresolvedLibraries
|
||||
// Configure resolver to only understands absolute path libraries.
|
||||
val libraryResolver = KotlinLibrarySearchPathResolver<KotlinLibrary>(
|
||||
repositories = emptyList(),
|
||||
directLibs = libraries,
|
||||
distributionKlib = null,
|
||||
localKotlinDir = null,
|
||||
skipCurrentDir = true
|
||||
// TODO: pass logger attached to message collector here.
|
||||
).libraryResolver()
|
||||
val resolvedLibraries = libraryResolver.resolveWithDependencies(unresolvedLibraries, true, true, true)
|
||||
val friendDependencies = resolvedLibraries.getFullList()
|
||||
.filter {
|
||||
it.moduleName in friendLibraries
|
||||
}
|
||||
val resolvedLibraries = jsResolveLibraries(
|
||||
libraries,
|
||||
messageCollectorLogger(configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY] ?: error("Could not find message collector"))
|
||||
)
|
||||
|
||||
val friendAbsolutePaths = friendLibraries.map { File(it).absolutePath }
|
||||
val friendDependencies = resolvedLibraries.getFullList().filter {
|
||||
it.libraryFile.absolutePath in friendAbsolutePaths
|
||||
}
|
||||
|
||||
val produceKind = produceMap[arguments.irProduceOnly]
|
||||
if (produceKind == null) {
|
||||
@@ -345,3 +339,14 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun messageCollectorLogger(collector: MessageCollector) = object : Logger {
|
||||
override fun warning(message: String)= collector.report(STRONG_WARNING, message)
|
||||
override fun error(message: String) = collector.report(ERROR, message)
|
||||
override fun log(message: String) = collector.report(LOGGING, message)
|
||||
override fun fatal(message: String): Nothing {
|
||||
collector.report(ERROR, message)
|
||||
(collector as? GroupingMessageCollector)?.flush()
|
||||
kotlin.error(message)
|
||||
}
|
||||
}
|
||||
@@ -25,14 +25,11 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.LOGGING
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartProviderBase
|
||||
import org.jetbrains.kotlin.load.kotlin.loadModuleMapping
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.PackageParts
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||
import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.EOFException
|
||||
import java.io.PrintStream
|
||||
@@ -40,49 +37,10 @@ import java.io.PrintStream
|
||||
class JvmPackagePartProvider(
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
private val scope: GlobalSearchScope
|
||||
) : PackagePartProvider, MetadataPartProvider {
|
||||
private data class ModuleMappingInfo(val root: VirtualFile, val mapping: ModuleMapping, val name: String)
|
||||
|
||||
) : JvmPackagePartProviderBase<VirtualFile>() {
|
||||
private val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
|
||||
|
||||
private val loadedModules: MutableList<ModuleMappingInfo> = SmartList()
|
||||
|
||||
override fun findPackageParts(packageFqName: String): List<String> {
|
||||
val rootToPackageParts = getPackageParts(packageFqName)
|
||||
if (rootToPackageParts.isEmpty()) return emptyList()
|
||||
|
||||
val result = linkedSetOf<String>()
|
||||
val visitedMultifileFacades = linkedSetOf<String>()
|
||||
for ((_, packageParts) in rootToPackageParts) {
|
||||
for (name in packageParts.parts) {
|
||||
val facadeName = packageParts.getMultifileFacadeName(name)
|
||||
if (facadeName == null || facadeName !in visitedMultifileFacades) {
|
||||
result.add(name)
|
||||
}
|
||||
}
|
||||
packageParts.parts.mapNotNullTo(visitedMultifileFacades, packageParts::getMultifileFacadeName)
|
||||
}
|
||||
return result.toList()
|
||||
}
|
||||
|
||||
override fun findMetadataPackageParts(packageFqName: String): List<String> =
|
||||
getPackageParts(packageFqName).values.flatMap(PackageParts::metadataParts).distinct()
|
||||
|
||||
@Synchronized
|
||||
private fun getPackageParts(packageFqName: String): Map<VirtualFile, PackageParts> {
|
||||
val result = mutableMapOf<VirtualFile, PackageParts>()
|
||||
for ((root, mapping) in loadedModules) {
|
||||
val newParts = mapping.findPackageParts(packageFqName) ?: continue
|
||||
result[root]?.let { parts -> parts += newParts } ?: result.put(root, newParts)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun getAnnotationsOnBinaryModule(moduleName: String): List<ClassId> {
|
||||
return loadedModules.mapNotNull { (_, mapping, name) ->
|
||||
if (name == moduleName) mapping.moduleData.annotations.map(ClassId::fromString) else null
|
||||
}.flatten()
|
||||
}
|
||||
override val loadedModules: MutableList<ModuleMappingInfo<VirtualFile>> = SmartList()
|
||||
|
||||
fun addRoots(roots: List<JavaRoot>, messageCollector: MessageCollector) {
|
||||
for ((root, type) in roots) {
|
||||
@@ -93,29 +51,40 @@ class JvmPackagePartProvider(
|
||||
for (moduleFile in metaInf.children) {
|
||||
if (!moduleFile.name.endsWith(ModuleMapping.MAPPING_FILE_EXT)) continue
|
||||
|
||||
try {
|
||||
val mapping = ModuleMapping.loadModuleMapping(
|
||||
moduleFile.contentsToByteArray(), moduleFile.toString(), deserializationConfiguration
|
||||
) { incompatibleVersion ->
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is " +
|
||||
"$incompatibleVersion, expected version is ${JvmMetadataVersion.INSTANCE}.",
|
||||
CompilerMessageLocation.create(moduleFile.path)
|
||||
)
|
||||
}
|
||||
loadedModules.add(ModuleMappingInfo(root, mapping, moduleFile.nameWithoutExtension))
|
||||
} catch (e: EOFException) {
|
||||
messageCollector.report(
|
||||
ERROR, "Error occurred when reading the module: ${e.message}", CompilerMessageLocation.create(moduleFile.path)
|
||||
)
|
||||
messageCollector.report(
|
||||
LOGGING,
|
||||
String(ByteArrayOutputStream().also { e.printStackTrace(PrintStream(it)) }.toByteArray()),
|
||||
CompilerMessageLocation.create(moduleFile.path)
|
||||
)
|
||||
tryLoadModuleMapping(
|
||||
{ moduleFile.contentsToByteArray() }, moduleFile.toString(), moduleFile.path,
|
||||
deserializationConfiguration, messageCollector
|
||||
)?.let {
|
||||
loadedModules.add(ModuleMappingInfo(root, it, moduleFile.nameWithoutExtension))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun tryLoadModuleMapping(
|
||||
getModuleBytes: () -> ByteArray,
|
||||
debugName: String,
|
||||
modulePath: String,
|
||||
deserializationConfiguration: CompilerDeserializationConfiguration,
|
||||
messageCollector: MessageCollector
|
||||
): ModuleMapping? = try {
|
||||
ModuleMapping.loadModuleMapping(getModuleBytes(), debugName, deserializationConfiguration) { incompatibleVersion ->
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is " +
|
||||
"$incompatibleVersion, expected version is ${JvmMetadataVersion.INSTANCE}.",
|
||||
CompilerMessageLocation.create(modulePath)
|
||||
)
|
||||
}
|
||||
} catch (e: EOFException) {
|
||||
messageCollector.report(
|
||||
ERROR, "Error occurred when reading the module: ${e.message}", CompilerMessageLocation.create(modulePath)
|
||||
)
|
||||
messageCollector.report(
|
||||
LOGGING,
|
||||
String(ByteArrayOutputStream().also { e.printStackTrace(PrintStream(it)) }.toByteArray()),
|
||||
CompilerMessageLocation.create(modulePath)
|
||||
)
|
||||
null
|
||||
}
|
||||
|
||||
@@ -85,6 +85,8 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.extensions.*
|
||||
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
|
||||
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.js.translate.extensions.JsSyntheticTranslateExtension
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
@@ -585,6 +587,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
IrGenerationExtension.registerExtensionPoint(project)
|
||||
ScriptEvaluationExtension.registerExtensionPoint(project)
|
||||
ShellExtension.registerExtensionPoint(project)
|
||||
TypeResolutionInterceptor.registerExtensionPoint(project)
|
||||
CandidateInterceptor.registerExtensionPoint(project)
|
||||
}
|
||||
|
||||
internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) {
|
||||
|
||||
@@ -354,6 +354,8 @@ object KotlinToJVMBytecodeCompiler {
|
||||
module
|
||||
).onIndependentPartCompilationEnd(
|
||||
createOutputFilesFlushingCallbackIfPossible(moduleConfiguration)
|
||||
).isIrBackend(
|
||||
true
|
||||
).build()
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
@@ -624,6 +626,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
)
|
||||
.withModule(module)
|
||||
.onIndependentPartCompilationEnd(createOutputFilesFlushingCallbackIfPossible(configuration))
|
||||
.isIrBackend(isIR)
|
||||
.build()
|
||||
|
||||
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
|
||||
@@ -55,6 +55,7 @@ import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentPr
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
@@ -125,7 +126,11 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
targetEnvironment: TargetEnvironment = CompilerEnvironment,
|
||||
sourceModuleSearchScope: GlobalSearchScope = newModuleSearchScope(project, files)
|
||||
): ComponentProvider {
|
||||
val moduleContext = createModuleContext(project, configuration)
|
||||
val jvmTarget = configuration.get(JVMConfigurationKeys.JVM_TARGET, JvmTarget.DEFAULT)
|
||||
val languageVersionSettings = configuration.languageVersionSettings
|
||||
val jvmPlatform = JvmPlatforms.jvmPlatformByTargetVersion(jvmTarget)
|
||||
|
||||
val moduleContext = createModuleContext(project, configuration, jvmPlatform)
|
||||
|
||||
val storageManager = moduleContext.storageManager
|
||||
val module = moduleContext.module
|
||||
@@ -140,9 +145,6 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
val sourceScope = if (separateModules) sourceModuleSearchScope else GlobalSearchScope.allScope(project)
|
||||
val moduleClassResolver = SourceOrBinaryModuleClassResolver(sourceScope)
|
||||
|
||||
val jvmTarget = configuration.get(JVMConfigurationKeys.JVM_TARGET, JvmTarget.DEFAULT)
|
||||
val languageVersionSettings = configuration.languageVersionSettings
|
||||
|
||||
val fallbackBuiltIns = JvmBuiltIns(storageManager, JvmBuiltIns.Kind.FALLBACK).apply {
|
||||
initialize(builtInsModule, languageVersionSettings)
|
||||
}.builtInsModule
|
||||
@@ -161,14 +163,14 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
val dependencyModule = if (separateModules) {
|
||||
val dependenciesContext = ContextForNewModule(
|
||||
moduleContext, Name.special("<dependencies of ${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"),
|
||||
module.builtIns, null
|
||||
module.builtIns, jvmPlatform
|
||||
)
|
||||
|
||||
// Scope for the dependency module contains everything except files present in the scope for the source module
|
||||
val dependencyScope = GlobalSearchScope.notScope(sourceScope)
|
||||
|
||||
val dependenciesContainer = createContainerForLazyResolveWithJava(
|
||||
JvmPlatforms.jvmPlatformByTargetVersion(jvmTarget),
|
||||
jvmPlatform,
|
||||
dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, moduleClassResolver,
|
||||
targetEnvironment, lookupTracker, expectActualTracker,
|
||||
packagePartProvider(dependencyScope), languageVersionSettings,
|
||||
@@ -200,7 +202,7 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
// to be stored in CliLightClassGenerationSupport, and it better be the source one (otherwise light classes would not be found)
|
||||
// TODO: get rid of duplicate invocation of CodeAnalyzerInitializer#initialize, or refactor CliLightClassGenerationSupport
|
||||
val container = createContainerForLazyResolveWithJava(
|
||||
JvmPlatforms.jvmPlatformByTargetVersion(jvmTarget),
|
||||
jvmPlatform,
|
||||
moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, moduleClassResolver,
|
||||
targetEnvironment, lookupTracker, expectActualTracker,
|
||||
partProvider, languageVersionSettings,
|
||||
@@ -275,11 +277,11 @@ object TopDownAnalyzerFacadeForJVM {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createModuleContext(project: Project, configuration: CompilerConfiguration): MutableModuleContext {
|
||||
private fun createModuleContext(project: Project, configuration: CompilerConfiguration, platform: TargetPlatform?): MutableModuleContext {
|
||||
val projectContext = ProjectContext(project, "TopDownAnalyzer for JVM")
|
||||
val builtIns = JvmBuiltIns(projectContext.storageManager, JvmBuiltIns.Kind.FROM_DEPENDENCIES)
|
||||
return ContextForNewModule(
|
||||
projectContext, Name.special("<${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"), builtIns, null
|
||||
projectContext, Name.special("<${configuration.getNotNull(CommonConfigurationKeys.MODULE_NAME)}>"), builtIns, platform
|
||||
).apply {
|
||||
builtIns.builtInsModule = module
|
||||
}
|
||||
|
||||
@@ -17,13 +17,14 @@ jvmTarget = "1.8"
|
||||
val ktorExcludesForDaemon : List<Pair<String, String>> by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
compile(project(":compiler:cli"))
|
||||
compile(project(":compiler:cli-js"))
|
||||
compile(project(":daemon-common-new"))
|
||||
compile(project(":compiler:incremental-compilation-impl"))
|
||||
compile(commonDep("org.fusesource.jansi", "jansi"))
|
||||
compile(commonDep("org.jline", "jline"))
|
||||
|
||||
compileOnly(project(":compiler:cli"))
|
||||
compileOnly(project(":compiler:cli-js"))
|
||||
compileOnly(project(":compiler:incremental-compilation-impl"))
|
||||
compileOnly(project(":daemon-common-new"))
|
||||
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("trove4j") }
|
||||
|
||||
|
||||
@@ -469,6 +469,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/ProjectionsInSupertypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("properDefaultInitializationInTailrec.kt")
|
||||
public void testProperDefaultInitializationInTailrec() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/properDefaultInitializationInTailrec.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Properties.kt")
|
||||
public void testProperties() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/Properties.kt");
|
||||
@@ -609,6 +614,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/SyntaxErrorInTestHighlightingEof.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOnVirtualMember.kt")
|
||||
public void testTailRecOnVirtualMember() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOnVirtualMember.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOnVirtualMemberError.kt")
|
||||
public void testTailRecOnVirtualMemberError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOnVirtualMemberError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOverridden.kt")
|
||||
public void testTailRecOverridden() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOverridden.kt");
|
||||
@@ -679,6 +694,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/UnitValue.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unproperDefaultInitializationInTailrec.kt")
|
||||
public void testUnproperDefaultInitializationInTailrec() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/unproperDefaultInitializationInTailrec.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Unresolved.kt")
|
||||
public void testUnresolved() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/Unresolved.kt");
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.checkers
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtConstantExpression
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
import org.jetbrains.kotlin.resolve.jvm.getCompileTimeConstant
|
||||
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberOrNullableType
|
||||
|
||||
object DefaultCheckerInTailrec : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (declaration !is KtNamedFunction || descriptor !is FunctionDescriptor || !descriptor.isTailrec) return
|
||||
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ProperComputationOrderOfTailrecDefaultParameters)) return
|
||||
|
||||
val defaultValues = descriptor.valueParameters.filter { it.declaresDefaultValue() }.filter {
|
||||
val parameterDeclaration = DescriptorToSourceUtils.descriptorToDeclaration(it)
|
||||
if (parameterDeclaration is KtParameter) {
|
||||
parameterDeclaration.defaultValue?.let {
|
||||
getCompileTimeConstant(
|
||||
it,
|
||||
context.trace.bindingContext,
|
||||
false,
|
||||
context.languageVersionSettings.supportsFeature(LanguageFeature.InlineConstVals)
|
||||
)?.let { const ->
|
||||
val type = const.getType(descriptor.module)
|
||||
return@filter !(KotlinBuiltIns.isPrimitiveTypeOrNullablePrimitiveType(type) ||
|
||||
KotlinBuiltIns.isStringOrNullableString(type))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
if (defaultValues.size > 1) {
|
||||
context.trace.report(ErrorsJvm.TAILREC_WITH_DEFAULTS.on(declaration))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,6 +151,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
"See https://youtrack.jetbrains.com/issue/KT-18053 for more details";
|
||||
MAP.put(CONCURRENT_HASH_MAP_CONTAINS_OPERATOR, MESSAGE_FOR_CONCURRENT_HASH_MAP_CONTAINS);
|
||||
MAP.put(CONCURRENT_HASH_MAP_CONTAINS_OPERATOR_ERROR, MESSAGE_FOR_CONCURRENT_HASH_MAP_CONTAINS);
|
||||
MAP.put(TAILREC_WITH_DEFAULTS, "Computation order of non-constant default arguments in tail-recursive functions will change in 1.4. See KT-31540 for more details");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -10,10 +10,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.*;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry;
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.PositioningStrategies.*;
|
||||
@@ -135,6 +132,8 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory0<PsiElement> CONCURRENT_HASH_MAP_CONTAINS_OPERATOR = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<PsiElement> CONCURRENT_HASH_MAP_CONTAINS_OPERATOR_ERROR = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtNamedFunction> TAILREC_WITH_DEFAULTS = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
Object _initializer = new Object() {
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.memberScopeAsImportingScope
|
||||
|
||||
open class PartialAnalysisHandlerExtension : AnalysisHandlerExtension {
|
||||
protected open val analyzePartially: Boolean
|
||||
open val analyzePartially: Boolean
|
||||
get() = true
|
||||
|
||||
override fun doAnalysis(
|
||||
|
||||
@@ -38,7 +38,8 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
|
||||
JvmAnnotationsTargetNonExistentAccessorChecker(),
|
||||
BadInheritedJavaSignaturesChecker,
|
||||
JvmMultifileClassStateChecker,
|
||||
SynchronizedOnInlineMethodChecker
|
||||
SynchronizedOnInlineMethodChecker,
|
||||
DefaultCheckerInTailrec
|
||||
),
|
||||
|
||||
additionalCallCheckers = listOf(
|
||||
|
||||
@@ -585,6 +585,8 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtParameter> VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtNamedFunction> NO_TAIL_CALLS_FOUND = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtNamedFunction> TAILREC_ON_VIRTUAL_MEMBER = DiagnosticFactory0.create(WARNING, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtNamedFunction> TAILREC_ON_VIRTUAL_MEMBER_ERROR = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
|
||||
DiagnosticFactory0<KtParameter>
|
||||
ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE = DiagnosticFactory0.create(ERROR, PARAMETER_DEFAULT_VALUE);
|
||||
|
||||
@@ -203,7 +203,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(SPREAD_OF_LAMBDA_OR_CALLABLE_REFERENCE, "The spread operator (*foo) cannot be applied to lambda argument or callable reference");
|
||||
|
||||
MAP.put(MANY_LAMBDA_EXPRESSION_ARGUMENTS, "Only one lambda expression is allowed outside a parenthesized argument list");
|
||||
MAP.put(UNEXPECTED_TRAILING_LAMBDA_ON_A_NEW_LINE, "Expression is treated a trailing lambda argument; consider separating it from call with semicolon");
|
||||
MAP.put(UNEXPECTED_TRAILING_LAMBDA_ON_A_NEW_LINE, "Expression is treated as a trailing lambda argument; consider separating it from call with semicolon");
|
||||
MAP.put(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER, "This property must either have a type annotation, be initialized or be delegated");
|
||||
MAP.put(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER, "This variable must either have a type annotation or be initialized");
|
||||
|
||||
@@ -619,6 +619,9 @@ public class DefaultErrorMessages {
|
||||
MAP.put(ILLEGAL_SELECTOR, "The expression cannot be a selector (occur after a dot)");
|
||||
|
||||
MAP.put(NO_TAIL_CALLS_FOUND, "A function is marked as tail-recursive but no tail calls are found");
|
||||
MAP.put(TAILREC_ON_VIRTUAL_MEMBER, "Tailrec on open members is deprecated");
|
||||
MAP.put(TAILREC_ON_VIRTUAL_MEMBER_ERROR, "Tailrec is not allowed on open members");
|
||||
|
||||
MAP.put(VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION, "A type annotation is required on a value parameter");
|
||||
MAP.put(BREAK_OR_CONTINUE_OUTSIDE_A_LOOP, "'break' and 'continue' are only allowed inside a loop");
|
||||
MAP.put(BREAK_OR_CONTINUE_IN_WHEN, "'break' and 'continue' are not allowed in 'when' statements. Consider using labels to continue/break from the outer loop");
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.internal
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolutionOldInference
|
||||
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
|
||||
|
||||
@UseExperimental(InternalNonStableExtensionPoints::class)
|
||||
class CandidateInterceptor(project: Project) {
|
||||
private val extensions = getInstances(project)
|
||||
|
||||
fun interceptResolvedCandidates(
|
||||
candidates: Collection<NewResolutionOldInference.MyCandidate>,
|
||||
context: BasicCallResolutionContext,
|
||||
candidateResolver: CandidateResolver,
|
||||
callResolver: CallResolver?,
|
||||
name: Name,
|
||||
kind: NewResolutionOldInference.ResolutionKind,
|
||||
tracing: TracingStrategy
|
||||
) = extensions.fold(candidates) { it, extension ->
|
||||
extension.interceptCandidates(it, context, candidateResolver, callResolver, name, kind, tracing)
|
||||
}
|
||||
|
||||
fun interceptCandidates(
|
||||
candidates: Collection<FunctionDescriptor>,
|
||||
scopeTower: ImplicitScopeTower,
|
||||
resolutionContext: BasicCallResolutionContext,
|
||||
resolutionScope: ResolutionScope,
|
||||
callResolver: CallResolver?,
|
||||
name: Name,
|
||||
location: LookupLocation
|
||||
): Collection<FunctionDescriptor> = extensions.fold(candidates) { it, extension ->
|
||||
extension.interceptCandidates(it, scopeTower, resolutionContext, resolutionScope, callResolver, name, location)
|
||||
}
|
||||
|
||||
companion object : ProjectExtensionDescriptor<CallResolutionInterceptorExtension>(
|
||||
"org.jetbrains.kotlin.extensions.internal.callResolutionInterceptorExtension",
|
||||
CallResolutionInterceptorExtension::class.java
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.internal
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolutionOldInference
|
||||
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
||||
|
||||
|
||||
/**
|
||||
* This is marker for non-stable experimental extension points.
|
||||
* Extension points marked with this meta-annotation will be broken in the future version.
|
||||
* Please do not use them in general code.
|
||||
*/
|
||||
@Experimental(level = Experimental.Level.ERROR)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
internal annotation class InternalNonStableExtensionPoints
|
||||
|
||||
@InternalNonStableExtensionPoints
|
||||
interface TypeResolutionInterceptorExtension {
|
||||
fun interceptFunctionLiteralDescriptor(
|
||||
expression: KtLambdaExpression,
|
||||
context: ExpressionTypingContext,
|
||||
descriptor: AnonymousFunctionDescriptor
|
||||
): AnonymousFunctionDescriptor = descriptor
|
||||
|
||||
fun interceptType(
|
||||
element: KtElement,
|
||||
context: ExpressionTypingContext,
|
||||
resultType: KotlinType
|
||||
): KotlinType = resultType
|
||||
}
|
||||
|
||||
@InternalNonStableExtensionPoints
|
||||
interface CallResolutionInterceptorExtension {
|
||||
fun interceptCandidates(
|
||||
candidates: Collection<NewResolutionOldInference.MyCandidate>,
|
||||
context: BasicCallResolutionContext,
|
||||
candidateResolver: CandidateResolver,
|
||||
callResolver: CallResolver?,
|
||||
name: Name,
|
||||
kind: NewResolutionOldInference.ResolutionKind,
|
||||
tracing: TracingStrategy
|
||||
): Collection<NewResolutionOldInference.MyCandidate> = candidates
|
||||
|
||||
fun interceptCandidates(
|
||||
candidates: Collection<FunctionDescriptor>,
|
||||
scopeTower: ImplicitScopeTower,
|
||||
resolutionContext: BasicCallResolutionContext,
|
||||
resolutionScope: ResolutionScope,
|
||||
callResolver: CallResolver?,
|
||||
name: Name,
|
||||
location: LookupLocation
|
||||
): Collection<FunctionDescriptor> = candidates
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.internal
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
|
||||
|
||||
@UseExperimental(InternalNonStableExtensionPoints::class)
|
||||
class TypeResolutionInterceptor(project: Project) {
|
||||
private val extensions = getInstances(project)
|
||||
|
||||
fun interceptFunctionLiteralDescriptor(
|
||||
expression: KtLambdaExpression,
|
||||
context: ExpressionTypingContext,
|
||||
descriptor: AnonymousFunctionDescriptor
|
||||
) = extensions.fold(descriptor) { it, extension ->
|
||||
extension.interceptFunctionLiteralDescriptor(expression, context, it)
|
||||
}
|
||||
|
||||
fun interceptType(
|
||||
element: KtElement,
|
||||
context: ExpressionTypingContext,
|
||||
resultType: KotlinType?
|
||||
): KotlinType? {
|
||||
// null means that source code has errors and in such scenarios shouldn't be passed into extension point
|
||||
if (resultType == null) return null
|
||||
|
||||
return extensions.fold(resultType) { it, extension ->
|
||||
extension.interceptType(element, context, it)
|
||||
}
|
||||
}
|
||||
|
||||
fun isEmpty() = extensions.isEmpty()
|
||||
|
||||
companion object : ProjectExtensionDescriptor<TypeResolutionInterceptorExtension>(
|
||||
"org.jetbrains.kotlin.extensions.internal.typeResolutionInterceptorExtension",
|
||||
TypeResolutionInterceptorExtension::class.java
|
||||
)
|
||||
}
|
||||
@@ -31,7 +31,8 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
||||
AnnotationClassTargetAndRetentionChecker(),
|
||||
ReservedMembersAndConstructsForInlineClass(),
|
||||
ResultClassInReturnTypeChecker(),
|
||||
LocalVariableTypeParametersChecker()
|
||||
LocalVariableTypeParametersChecker(),
|
||||
TailrecFunctionChecker
|
||||
)
|
||||
|
||||
private val DEFAULT_CALL_CHECKERS = listOf(
|
||||
|
||||
@@ -185,8 +185,10 @@ public class CallResolver {
|
||||
NewResolutionOldInference.ResolutionKind.Invoke.INSTANCE);
|
||||
}
|
||||
|
||||
// this declaration is used by compiler plugins
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> computeTasksAndResolveCall(
|
||||
public <D extends CallableDescriptor> OverloadResolutionResults<D> computeTasksAndResolveCall(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull Name name,
|
||||
@NotNull KtReferenceExpression referenceExpression,
|
||||
@@ -196,8 +198,10 @@ public class CallResolver {
|
||||
return computeTasksAndResolveCall(context, name, tracing, kind);
|
||||
}
|
||||
|
||||
// this declaration is used by compiler plugins
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> computeTasksAndResolveCall(
|
||||
public <D extends CallableDescriptor> OverloadResolutionResults<D> computeTasksAndResolveCall(
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull Name name,
|
||||
@NotNull TracingStrategy tracing,
|
||||
|
||||
@@ -27,7 +27,9 @@ import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isBinaryRemOperator
|
||||
@@ -49,10 +51,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.*
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDynamicExtensionAnnotation
|
||||
import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.canBeResolvedWithoutDeprecation
|
||||
import org.jetbrains.kotlin.types.DeferredType
|
||||
@@ -74,7 +73,9 @@ class NewResolutionOldInference(
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val coroutineInferenceSupport: CoroutineInferenceSupport,
|
||||
private val deprecationResolver: DeprecationResolver,
|
||||
private val typeApproximator: TypeApproximator
|
||||
private val typeApproximator: TypeApproximator,
|
||||
private val callResolver: CallResolver,
|
||||
private val candidateInterceptor: CandidateInterceptor
|
||||
) {
|
||||
sealed class ResolutionKind {
|
||||
abstract internal fun createTowerProcessor(
|
||||
@@ -173,7 +174,7 @@ class NewResolutionOldInference(
|
||||
|
||||
val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor)
|
||||
val scopeTower = ImplicitScopeTowerImpl(
|
||||
context, dynamicScope, syntheticScopes, context.call.createLookupLocation(), typeApproximator
|
||||
context, dynamicScope, syntheticScopes, context.call.createLookupLocation(), typeApproximator, callResolver, candidateInterceptor
|
||||
)
|
||||
|
||||
val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)
|
||||
@@ -207,6 +208,8 @@ class NewResolutionOldInference(
|
||||
)
|
||||
}
|
||||
|
||||
candidates = candidateInterceptor.interceptResolvedCandidates(candidates, context, candidateResolver, callResolver, name, kind, tracing)
|
||||
|
||||
if (candidates.isEmpty()) {
|
||||
if (reportAdditionalDiagnosticIfNoCandidates(context, nameToResolve, kind, scopeTower, detailedReceiver)) {
|
||||
return OverloadResolutionResultsImpl.nameNotFound()
|
||||
@@ -353,12 +356,14 @@ class NewResolutionOldInference(
|
||||
return true
|
||||
}
|
||||
|
||||
private class ImplicitScopeTowerImpl(
|
||||
val resolutionContext: ResolutionContext<*>,
|
||||
public class ImplicitScopeTowerImpl(
|
||||
val resolutionContext: BasicCallResolutionContext,
|
||||
override val dynamicScope: MemberScope,
|
||||
override val syntheticScopes: SyntheticScopes,
|
||||
override val location: LookupLocation,
|
||||
override val typeApproximator: TypeApproximator
|
||||
override val typeApproximator: TypeApproximator,
|
||||
val callResolver: CallResolver,
|
||||
val candidateInterceptor: CandidateInterceptor
|
||||
) : ImplicitScopeTower {
|
||||
private val cache = HashMap<ReceiverValue, ReceiverValueWithSmartCastInfo>()
|
||||
|
||||
@@ -373,9 +378,18 @@ class NewResolutionOldInference(
|
||||
|
||||
override val isNewInferenceEnabled: Boolean
|
||||
get() = resolutionContext.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
|
||||
|
||||
override fun interceptCandidates(
|
||||
resolutionScope: ResolutionScope,
|
||||
name: Name,
|
||||
initialResults: Collection<FunctionDescriptor>,
|
||||
location: LookupLocation
|
||||
): Collection<FunctionDescriptor> {
|
||||
return candidateInterceptor.interceptCandidates(initialResults, this, resolutionContext, resolutionScope, callResolver, name, location)
|
||||
}
|
||||
}
|
||||
|
||||
internal class MyCandidate(
|
||||
class MyCandidate(
|
||||
// Diagnostics that are already computed
|
||||
// if resultingApplicability is successful they must be the same as `diagnostics`,
|
||||
// otherwise they might be a bit different but result remains unsuccessful
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.contracts.EffectSystem
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -67,7 +68,8 @@ class PSICallResolver(
|
||||
private val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter,
|
||||
private val deprecationResolver: DeprecationResolver,
|
||||
private val moduleDescriptor: ModuleDescriptor,
|
||||
private val callableReferenceResolver: CallableReferenceResolver
|
||||
private val callableReferenceResolver: CallableReferenceResolver,
|
||||
private val candidateInterceptor: CandidateInterceptor
|
||||
) {
|
||||
private val givenCandidatesName = Name.special("<given candidates>")
|
||||
|
||||
@@ -397,6 +399,15 @@ class PSICallResolver(
|
||||
context.transformToReceiverWithSmartCastInfo(implicitReceiver.value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun interceptCandidates(
|
||||
resolutionScope: ResolutionScope,
|
||||
name: Name,
|
||||
initialResults: Collection<FunctionDescriptor>,
|
||||
location: LookupLocation
|
||||
): Collection<FunctionDescriptor> {
|
||||
return candidateInterceptor.interceptCandidates(initialResults, this, context, resolutionScope, null, name, location)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class FactoryProviderForInvoke(
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.checkers
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.resolve.isEffectivelyFinal
|
||||
|
||||
object TailrecFunctionChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (declaration !is KtNamedFunction || descriptor !is FunctionDescriptor || !descriptor.isTailrec) return
|
||||
|
||||
if (descriptor.isEffectivelyFinal(false)) return
|
||||
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitTailrecOnVirtualMember)) {
|
||||
context.trace.report(Errors.TAILREC_ON_VIRTUAL_MEMBER.on(declaration))
|
||||
} else {
|
||||
context.trace.report(Errors.TAILREC_ON_VIRTUAL_MEMBER_ERROR.on(declaration))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.isEffectivelyFinal
|
||||
|
||||
class InlineAnalyzerExtension(
|
||||
private val reasonableInlineRules: Iterable<ReasonableInlineRule>,
|
||||
@@ -159,7 +160,8 @@ class InlineAnalyzerExtension(
|
||||
}
|
||||
}
|
||||
|
||||
if (callableDescriptor.isEffectivelyFinal()) {
|
||||
//TODO: actually it should be isEffectivelyFinal(false), but looks like it requires committee decision: KT-34372)
|
||||
if (callableDescriptor.isEffectivelyFinal(true)) {
|
||||
if (overridesAnything) {
|
||||
trace.report(Errors.OVERRIDE_BY_INLINE.on(functionOrProperty))
|
||||
}
|
||||
@@ -168,12 +170,6 @@ class InlineAnalyzerExtension(
|
||||
trace.report(Errors.DECLARATION_CANT_BE_INLINED.on(functionOrProperty))
|
||||
}
|
||||
|
||||
private fun CallableMemberDescriptor.isEffectivelyFinal(): Boolean =
|
||||
modality == Modality.FINAL ||
|
||||
containingDeclaration.let { containingDeclaration ->
|
||||
containingDeclaration is ClassDescriptor && containingDeclaration.modality == Modality.FINAL
|
||||
}
|
||||
|
||||
private fun checkHasInlinableAndNullability(functionDescriptor: FunctionDescriptor, function: KtFunction, trace: BindingTrace) {
|
||||
var hasInlineArgs = false
|
||||
function.valueParameters.zip(functionDescriptor.valueParameters).forEach { (parameter, descriptor) ->
|
||||
|
||||
@@ -5,7 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.types.DeferredType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
@@ -24,3 +27,11 @@ fun FunctionDescriptor.isFunctionForExpectTypeFromCastFeature(): Boolean {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
internal fun CallableMemberDescriptor.isEffectivelyFinal(ignoreEnumClassFinality: Boolean): Boolean =
|
||||
modality == Modality.FINAL ||
|
||||
containingDeclaration.let { parent ->
|
||||
(ignoreEnumClassFinality || !DescriptorUtils.isEnumClass(parent)) &&
|
||||
parent is ClassDescriptor && parent.modality == Modality.FINAL
|
||||
}
|
||||
@@ -1635,7 +1635,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
if (baseExpression == null) {
|
||||
return TypeInfoFactoryKt.noTypeInfo(context);
|
||||
}
|
||||
return facade.getTypeInfo(baseExpression, context, isStatement);
|
||||
if (components.typeResolutionInterceptor.isEmpty()) return facade.getTypeInfo(baseExpression, context, isStatement);
|
||||
|
||||
KotlinType newExpectedType = components.typeResolutionInterceptor.interceptType(baseExpression, context, context.expectedType);
|
||||
KotlinTypeInfo resultTypeInfo = facade.getTypeInfo(baseExpression, newExpectedType == context.expectedType ? context : context.replaceExpectedType(newExpectedType), isStatement);
|
||||
KotlinType newResultType = components.typeResolutionInterceptor.interceptType(baseExpression, context, resultTypeInfo.getType());
|
||||
components.dataFlowAnalyzer.checkType(newResultType, expression, context);
|
||||
return resultTypeInfo.getType() == newResultType ? resultTypeInfo : resultTypeInfo.replaceType(newResultType);
|
||||
}
|
||||
|
||||
protected void resolveAnnotationsOnExpression(KtAnnotatedExpression expression, ExpressionTypingContext context) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.resolve.calls.checkers.RttiExpressionChecker;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver;
|
||||
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor;
|
||||
import org.jetbrains.kotlin.types.WrappedTypeFactory;
|
||||
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker;
|
||||
|
||||
@@ -64,6 +65,7 @@ public class ExpressionTypingComponents {
|
||||
/*package*/ ContractParsingServices contractParsingServices;
|
||||
/*package*/ DataFlowValueFactory dataFlowValueFactory;
|
||||
/*package*/ NewKotlinTypeChecker kotlinTypeChecker;
|
||||
/*package*/ TypeResolutionInterceptor typeResolutionInterceptor;
|
||||
|
||||
|
||||
@Inject
|
||||
@@ -245,4 +247,9 @@ public class ExpressionTypingComponents {
|
||||
public void setKotlinTypeChecker(@NotNull NewKotlinTypeChecker kotlinTypeChecker) {
|
||||
this.kotlinTypeChecker = kotlinTypeChecker;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setTypeResolutionInterceptor(@NotNull TypeResolutionInterceptor typeResolutionInterceptor) {
|
||||
this.typeResolutionInterceptor = typeResolutionInterceptor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,8 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.checkReservedPrefixWord
|
||||
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYieldBeforeLambda
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.EXPECTED_RETURN_TYPE
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker
|
||||
@@ -147,7 +144,12 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
val safeReturnType = computeReturnType(expression, context, functionDescriptor, functionTypeExpected)
|
||||
functionDescriptor.setReturnType(safeReturnType)
|
||||
|
||||
val resultType = functionDescriptor.createFunctionType(components.builtIns, suspendFunctionTypeExpected)!!
|
||||
val resultType = components.typeResolutionInterceptor.interceptType(
|
||||
expression,
|
||||
context,
|
||||
functionDescriptor.createFunctionType(components.builtIns, suspendFunctionTypeExpected)!!
|
||||
)
|
||||
|
||||
if (functionTypeExpected) {
|
||||
// all checks were done before
|
||||
return createTypeInfo(resultType, context)
|
||||
@@ -175,7 +177,9 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
components.annotationResolver.resolveAnnotationsWithArguments(context.scope, expression.getAnnotationEntries(), context.trace),
|
||||
CallableMemberDescriptor.Kind.DECLARATION, functionLiteral.toSourceElement(),
|
||||
context.expectedType.isSuspendFunctionType()
|
||||
)
|
||||
).let {
|
||||
facade.components.typeResolutionInterceptor.interceptFunctionLiteralDescriptor(expression, context, it)
|
||||
}
|
||||
components.functionDescriptorResolver.initializeFunctionDescriptorAndExplicitReturnType(
|
||||
context.scope.ownerDescriptor, context.scope, functionLiteral,
|
||||
functionDescriptor, context.trace, context.expectedType, context.dataFlowInfo
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.isNullable
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.isNullConst
|
||||
@@ -45,8 +46,9 @@ class Equals(val operator: IElementType) : IntrinsicMethod() {
|
||||
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
|
||||
val (a, b) = expression.receiverAndArgs()
|
||||
if (a.isNullConst() || b.isNullConst()) {
|
||||
val value = if (a.isNullConst()) b.accept(codegen, data) else a.accept(codegen, data)
|
||||
return if (a.type.isNullable() && b.type.isNullable())
|
||||
val irValue = if (a.isNullConst()) b else a
|
||||
val value = irValue.accept(codegen, data)
|
||||
return if (!isPrimitive(value.type) && (irValue.type.classOrNull?.owner?.isInline != true || irValue.type.isNullable()))
|
||||
BooleanNullCheck(value)
|
||||
else
|
||||
BooleanConstantFalseCheck(value)
|
||||
|
||||
@@ -105,7 +105,10 @@ class DeclarationTable(
|
||||
}
|
||||
}
|
||||
|
||||
if (this is IrLazyDeclarationBase) return false
|
||||
// Currently this check is skipped because LazyIr
|
||||
// can be generated by kotlinx-serialization compiler plugin
|
||||
|
||||
// if (this is IrLazyDeclarationBase) return false
|
||||
|
||||
if (parent is IrPackageFragment) return true
|
||||
|
||||
|
||||
@@ -1325,7 +1325,6 @@ open class IrFileSerializer(
|
||||
file.declarations
|
||||
.filterIsInstance<IrProperty>()
|
||||
.filter { it.backingField?.initializer != null && !it.isConst }
|
||||
.filter { it.visibility.let { it == Visibilities.PUBLIC || it == Visibilities.INTERNAL } }
|
||||
.forEach { proto.addExplicitlyExportedToCompiler(serializeIrSymbol(it.backingField!!.symbol)) }
|
||||
|
||||
// TODO: Konan specific
|
||||
|
||||
@@ -59,50 +59,62 @@ abstract class KotlinIrLinker(
|
||||
) : DescriptorUniqIdAware, IrDeserializer {
|
||||
|
||||
|
||||
sealed class DeserializationState {
|
||||
sealed class DeserializationState<T> {
|
||||
val deserializedSymbols = mutableMapOf<UniqId, IrSymbol>()
|
||||
val reachableTopLevels = mutableSetOf<UniqId>()
|
||||
val deserializedTopLevels = mutableSetOf<UniqId>()
|
||||
|
||||
operator fun contains(key: UniqId) = key in deserializedSymbols
|
||||
operator fun get(key: UniqId): IrSymbol = deserializedSymbols[key] ?: error("No deserialized symbol found for $key")
|
||||
|
||||
abstract fun addUniqID(key: UniqId)
|
||||
protected open fun peekReachableKey(): UniqId? = reachableTopLevels.firstOrNull()
|
||||
abstract fun processPendingDeclaration(processor: (T) -> Unit)
|
||||
|
||||
class ModuleDeserializationState(val module: IrModuleDeserializer): DeserializationState<IrModuleDeserializer.IrDeserializerForFile>() {
|
||||
private val filesWithPendingTopLevels = mutableSetOf<IrModuleDeserializer.IrDeserializerForFile>()
|
||||
|
||||
fun enqueueFile(fileDeserializer: IrModuleDeserializer.IrDeserializerForFile) {
|
||||
filesWithPendingTopLevels.add(fileDeserializer)
|
||||
module.enqueueModule()
|
||||
}
|
||||
|
||||
class ModuleDeserializationState(val module: IrModuleDeserializer): DeserializationState() {
|
||||
override fun addUniqID(key: UniqId) {
|
||||
module.addModuleReachableTopLevel(key)
|
||||
val fileDeserializer = module.moduleReversedFileIndex[key] ?: error("No file found for key $key")
|
||||
fileDeserializer.fileLocalDeserializationState.addUniqID(key)
|
||||
|
||||
enqueueFile(fileDeserializer)
|
||||
}
|
||||
|
||||
override fun processPendingDeclaration(processor: (IrModuleDeserializer.IrDeserializerForFile) -> Unit) {
|
||||
while (filesWithPendingTopLevels.isNotEmpty()) {
|
||||
val pendingDeserializer = filesWithPendingTopLevels.first()
|
||||
|
||||
processor(pendingDeserializer)
|
||||
|
||||
filesWithPendingTopLevels.remove(pendingDeserializer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleDeserializationState: DeserializationState() {
|
||||
class SimpleDeserializationState: DeserializationState<UniqId>() {
|
||||
private val reachableTopLevels = LinkedHashSet<UniqId>()
|
||||
|
||||
override fun addUniqID(key: UniqId) {
|
||||
reachableTopLevels.add(key)
|
||||
}
|
||||
|
||||
override fun peekReachableKey(): UniqId {
|
||||
return reachableTopLevels.firstOrNull() ?: error("Expecting non-empty set")
|
||||
}
|
||||
}
|
||||
override fun processPendingDeclaration(processor: (UniqId) -> Unit) {
|
||||
while (reachableTopLevels.isNotEmpty()) {
|
||||
val reachableKey = reachableTopLevels.first()
|
||||
|
||||
fun processPendingDeclaration(processor: (UniqId) -> Unit) {
|
||||
do {
|
||||
if (deserializedSymbols[reachableKey]?.isBound == true) {
|
||||
reachableTopLevels.remove(reachableKey)
|
||||
continue
|
||||
}
|
||||
|
||||
val reachableKey = peekReachableKey() ?: return
|
||||
processor(reachableKey)
|
||||
|
||||
if (deserializedSymbols[reachableKey]?.isBound == true) {
|
||||
reachableTopLevels.remove(reachableKey)
|
||||
deserializedTopLevels.add(reachableKey)
|
||||
continue
|
||||
}
|
||||
|
||||
processor(reachableKey)
|
||||
|
||||
reachableTopLevels.remove(reachableKey)
|
||||
deserializedTopLevels.add(reachableKey)
|
||||
|
||||
} while (reachableTopLevels.isNotEmpty())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +139,7 @@ abstract class KotlinIrLinker(
|
||||
protected val moduleResolvedForwardDeclarations = mutableMapOf<UniqId, UniqId>()
|
||||
|
||||
private val moduleDeserializationState = DeserializationState.ModuleDeserializationState(this)
|
||||
private val moduleReversedFileIndex = mutableMapOf<UniqId, IrDeserializerForFile>()
|
||||
val moduleReversedFileIndex = mutableMapOf<UniqId, IrDeserializerForFile>()
|
||||
private val moduleDependencies by lazy {
|
||||
moduleDescriptor.allDependencyModules.filter { it != moduleDescriptor }.map { deserializersForModules[it]!! }
|
||||
}
|
||||
@@ -135,8 +147,11 @@ abstract class KotlinIrLinker(
|
||||
// This is a heavy initializer
|
||||
val module = deserializeIrModuleHeader()
|
||||
|
||||
inner class IrDeserializerForFile(private var annotationsProto: ProtoAnnotations?, private val fileIndex: Int, onlyHeaders: Boolean) :
|
||||
IrFileDeserializer(logger, builtIns, symbolTable) {
|
||||
inner class IrDeserializerForFile(
|
||||
private var annotationsProto: ProtoAnnotations?,
|
||||
private val fileIndex: Int,
|
||||
onlyHeaders: Boolean
|
||||
) : IrFileDeserializer(logger, builtIns, symbolTable) {
|
||||
|
||||
private var fileLoops = mutableMapOf<Int, IrLoopBase>()
|
||||
|
||||
@@ -285,7 +300,7 @@ abstract class KotlinIrLinker(
|
||||
return moduleDependencies.firstOrNull { key in it.moduleReversedFileIndex }
|
||||
}
|
||||
|
||||
private fun getStateForID(key: UniqId): DeserializationState {
|
||||
private fun getStateForID(key: UniqId): DeserializationState<*> {
|
||||
if (key.isLocal) return fileLocalDeserializationState
|
||||
if (isGlobalUniqID(key)) return globalDeserializationState
|
||||
return getModuleForTopLevelId(key)?.moduleDeserializationState ?: handleNoModuleDeserializerFound(key)
|
||||
@@ -315,7 +330,7 @@ abstract class KotlinIrLinker(
|
||||
|
||||
resolvedForwardDeclarations[key]?.let {
|
||||
val fdState = getStateForID(it)
|
||||
fdState.addUniqID(it)
|
||||
if (it !in fdState) fdState.addUniqID(it)
|
||||
}
|
||||
|
||||
referenceDeserializedSymbol(proto, descriptor)
|
||||
@@ -381,17 +396,14 @@ abstract class KotlinIrLinker(
|
||||
}
|
||||
}
|
||||
|
||||
fun deserializeFileAnnotationsIfFirstUse() {
|
||||
fun deserializeFileImplicitDataIfFirstUse() {
|
||||
annotationsProto?.let {
|
||||
file.annotations.addAll(deserializeAnnotations(it))
|
||||
annotationsProto = null
|
||||
}
|
||||
}
|
||||
|
||||
fun deserializeFileTopLevelDeclaration(key: UniqId) {
|
||||
|
||||
fileLocalDeserializationState.addUniqID(key)
|
||||
|
||||
fun deserializeAllFileReachableTopLevel() {
|
||||
fileLocalDeserializationState.processPendingDeclaration {
|
||||
val declaration = deserializeDeclaration(it)
|
||||
file.declarations.add(declaration)
|
||||
@@ -405,7 +417,14 @@ abstract class KotlinIrLinker(
|
||||
|
||||
val fileEntry = NaiveSourceBasedFileEntryImpl(fileName, fileProto.fileEntry.lineStartOffsetsList.toIntArray())
|
||||
|
||||
val fileDeserializer = IrDeserializerForFile(fileProto.annotations, fileIndex, !deserializationStrategy.needBodies)
|
||||
val fileDeserializer =
|
||||
IrDeserializerForFile(fileProto.annotations, fileIndex, !deserializationStrategy.needBodies).apply {
|
||||
// Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations.
|
||||
// Thus we schedule their deserialization in deserializer's constructor.
|
||||
fileProto.explicitlyExportedToCompilerList.forEach {
|
||||
fileLocalDeserializationState.addUniqID(loadSymbolData(it.index).topLevelUniqId.uniqId())
|
||||
}
|
||||
}
|
||||
|
||||
val fqName = fileDeserializer.deserializeFqName(fileProto.fqName)
|
||||
|
||||
@@ -417,24 +436,22 @@ abstract class KotlinIrLinker(
|
||||
fileDeserializer.file = file
|
||||
fileToDeserializerMap[file] = fileDeserializer
|
||||
|
||||
fileProto.declarationIdList.forEach {
|
||||
val uniqId = it.uniqId()
|
||||
assert(uniqId.isPublic)
|
||||
moduleReversedFileIndex.getOrPut(uniqId) { fileDeserializer }
|
||||
val fileUniqIdIndex = fileProto.declarationIdList.map { UniqId(it.index, it.isLocal) }
|
||||
|
||||
fileUniqIdIndex.forEach {
|
||||
moduleReversedFileIndex.getOrPut(it) { fileDeserializer }
|
||||
}
|
||||
|
||||
val forceLoadedIds = deserializationStrategy.run {
|
||||
when {
|
||||
theWholeWorld -> fileProto.declarationIdList
|
||||
explicitlyExported -> fileProto.explicitlyExportedToCompilerList.map {
|
||||
fileDeserializer.loadSymbolData(it.index).topLevelUniqId
|
||||
}
|
||||
else -> emptyList()
|
||||
if (deserializationStrategy.theWholeWorld) {
|
||||
for (id in fileUniqIdIndex) {
|
||||
assert(id.isPublic)
|
||||
moduleDeserializationState.addUniqID(id)
|
||||
}
|
||||
moduleDeserializationState.enqueueFile(fileDeserializer)
|
||||
} else if (deserializationStrategy.explicitlyExported) {
|
||||
moduleDeserializationState.enqueueFile(fileDeserializer)
|
||||
}
|
||||
|
||||
forceLoadedIds.forEach { moduleDeserializationState.addUniqID(it.uniqId().also { i -> assert(i.isPublic) }) }
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
@@ -447,25 +464,23 @@ abstract class KotlinIrLinker(
|
||||
files.add(deserializeIrFile(ProtoFile.parseFrom(readFile(moduleDescriptor, i), newInstance()), i))
|
||||
}
|
||||
|
||||
|
||||
return IrModuleFragmentImpl(moduleDescriptor, builtIns, files)
|
||||
}
|
||||
|
||||
fun deserializeAllModuleReachableTopLevels() {
|
||||
|
||||
moduleDeserializationState.processPendingDeclaration {
|
||||
val fileDeserializer = moduleReversedFileIndex[it]
|
||||
?: error("No file deserializer for key $it")
|
||||
|
||||
fileDeserializer.deserializeFileTopLevelDeclaration(it)
|
||||
fileDeserializer.deserializeFileAnnotationsIfFirstUse()
|
||||
moduleDeserializationState.processPendingDeclaration { fileDeserializer ->
|
||||
fileDeserializer.deserializeFileImplicitDataIfFirstUse()
|
||||
fileDeserializer.deserializeAllFileReachableTopLevel()
|
||||
}
|
||||
}
|
||||
|
||||
fun addModuleReachableTopLevel(topLevelKey: UniqId) {
|
||||
moduleDeserializationState.reachableTopLevels.add(topLevelKey)
|
||||
fun enqueueModule() {
|
||||
modulesWithReachableTopLevels.add(this)
|
||||
}
|
||||
|
||||
fun addModuleReachableTopLevel(key: UniqId) {
|
||||
moduleDeserializationState.addUniqID(key)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract val descriptorReferenceDeserializer: DescriptorReferenceDeserializer
|
||||
@@ -499,7 +514,7 @@ abstract class KotlinIrLinker(
|
||||
protected abstract fun readFileCount(moduleDescriptor: ModuleDescriptor): Int
|
||||
|
||||
protected abstract fun checkAccessibility(declarationDescriptor: DeclarationDescriptor): Boolean
|
||||
protected open fun handleNoModuleDeserializerFound(key: UniqId): DeserializationState {
|
||||
protected open fun handleNoModuleDeserializerFound(key: UniqId): DeserializationState<*> {
|
||||
error("Deserializer for declaration $key is not found")
|
||||
}
|
||||
|
||||
@@ -522,7 +537,6 @@ abstract class KotlinIrLinker(
|
||||
"Locally accessible declarations should not be accessed here $topLevelDescriptor"
|
||||
}
|
||||
|
||||
|
||||
if (topLevelDescriptor !is DeserializedClassDescriptor && topLevelDescriptor !is DeserializedCallableMemberDescriptor) {
|
||||
return null
|
||||
}
|
||||
@@ -589,7 +603,7 @@ abstract class KotlinIrLinker(
|
||||
}
|
||||
}
|
||||
|
||||
private fun deserializeIrModuleHeader(
|
||||
fun deserializeIrModuleHeader(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
deserializationStrategy: DeserializationStrategy = DeserializationStrategy.ONLY_REFERENCED
|
||||
): IrModuleFragment {
|
||||
|
||||
@@ -12,8 +12,13 @@ import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataPackageFragment
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
|
||||
internal val DeclarationDescriptor.isExpectMember: Boolean
|
||||
get() = this is MemberDescriptor && this.isExpect
|
||||
@@ -49,3 +54,23 @@ internal fun <T : CallableMemberDescriptor> T.resolveFakeOverrideMaybeAbstract()
|
||||
// This is Native specific. Try to eliminate.
|
||||
val ModuleDescriptor.isForwardDeclarationModule get() =
|
||||
name == Name.special("<forward declarations>")
|
||||
|
||||
private fun sourceByIndex(descriptor: CallableMemberDescriptor, index: Int): SourceFile {
|
||||
val fragment = descriptor.findPackage() as KlibMetadataPackageFragment
|
||||
return fragment.fileRegistry.sourceFile(index)
|
||||
}
|
||||
|
||||
fun CallableMemberDescriptor.findSourceFile(): SourceFile {
|
||||
val source = this.source.containingFile
|
||||
if (source != SourceFile.NO_SOURCE_FILE)
|
||||
return source
|
||||
return when {
|
||||
this is DeserializedSimpleFunctionDescriptor && proto.hasExtension(KlibMetadataProtoBuf.functionFile) ->
|
||||
sourceByIndex(
|
||||
this, proto.getExtension(KlibMetadataProtoBuf.functionFile))
|
||||
this is DeserializedPropertyDescriptor && proto.hasExtension(KlibMetadataProtoBuf.propertyFile) ->
|
||||
sourceByIndex(
|
||||
this, proto.getExtension(KlibMetadataProtoBuf.propertyFile))
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
* 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.ir.backend.js.lower.serialization.metadata
|
||||
package org.jetbrains.kotlin.backend.common.serialization.metadata
|
||||
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataPackageFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.ir.backend.js.lower.serialization.metadata
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.extractFileId
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataPackageFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
||||
|
||||
|
||||
class KlibMetadataFileRegistry {
|
||||
private val fileIdsImpl = mutableMapOf<KlibFileMetadata, Int>()
|
||||
|
||||
fun lookup(file: KlibFileMetadata) = fileIdsImpl.getOrPut(file) { fileIdsImpl.size }
|
||||
|
||||
val fileIds: Map<KlibFileMetadata, Int>
|
||||
get() = fileIdsImpl
|
||||
|
||||
fun getFileId(descriptor: DeclarationDescriptor): Int? {
|
||||
if (!DescriptorUtils.isTopLevelDeclaration(descriptor) || descriptor !is DeclarationDescriptorWithSource) return null
|
||||
|
||||
val fileId = descriptor.extractFileId()
|
||||
if (fileId != null) {
|
||||
(descriptor.containingDeclaration as? KlibMetadataPackageFragment)?.let { packageFragment ->
|
||||
return this.lookup(KotlinDeserializedFileMetadata(packageFragment, fileId))
|
||||
}
|
||||
}
|
||||
|
||||
val file = descriptor.source.containingFile as? PsiSourceFile ?: return null
|
||||
|
||||
val psiFile = file.psiFile
|
||||
return (psiFile as? KtFile)?.let { this.lookup(KotlinPsiFileMetadata(it)) }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,8 +11,7 @@ import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.KlibMetadataFileRegistry
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.KotlinPsiFileMetadata
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataFileRegistry
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||
@@ -35,7 +34,6 @@ abstract class KlibMetadataSerializer(
|
||||
val metadataVersion: BinaryVersion,
|
||||
val descriptorTable: DescriptorTable
|
||||
) {
|
||||
|
||||
val fileRegistry = KlibMetadataFileRegistry()
|
||||
|
||||
lateinit var serializerContext: SerializerContext
|
||||
@@ -57,7 +55,7 @@ abstract class KlibMetadataSerializer(
|
||||
languageVersionSettings,
|
||||
metadataVersion,
|
||||
::declarationTableHandler,
|
||||
{descriptor -> fileRegistry.getFileId(descriptor) } ,
|
||||
{descriptor: DeclarationDescriptorWithSource -> fileRegistry.assign(descriptor.source.containingFile) } ,
|
||||
KlibMetadataStringTable()
|
||||
)
|
||||
return SerializerContext(
|
||||
@@ -82,10 +80,6 @@ abstract class KlibMetadataSerializer(
|
||||
|
||||
val (stringTableProto, nameTableProto) = serializerExtension.stringTable.buildProto()
|
||||
|
||||
// TODO: we place files table to each and every fragment.
|
||||
// Need to refactor it out sonehow.
|
||||
val files = serializeFiles(fileRegistry, bindingContext, AnnotationSerializer(serializerExtension.stringTable))
|
||||
|
||||
return ProtoBuf.PackageFragment.newBuilder()
|
||||
.setPackage(packageProto)
|
||||
.addAllClass_(classesProto.map { it.first })
|
||||
@@ -95,7 +89,6 @@ abstract class KlibMetadataSerializer(
|
||||
classesProto.forEach {
|
||||
packageFragment.addExtension(KlibMetadataProtoBuf.className, it.second )
|
||||
}
|
||||
packageFragment.setExtension(KlibMetadataProtoBuf.packageFragmentFiles, files)
|
||||
packageFragment.setExtension(KlibMetadataProtoBuf.isEmpty, isEmpty)
|
||||
packageFragment.setExtension(KlibMetadataProtoBuf.fqName, fqName.asString())
|
||||
}
|
||||
@@ -224,32 +217,17 @@ abstract class KlibMetadataSerializer(
|
||||
}
|
||||
|
||||
private fun serializeFiles(
|
||||
fileRegistry: KlibMetadataFileRegistry,
|
||||
bindingContext: BindingContext,
|
||||
serializer: AnnotationSerializer
|
||||
): KlibMetadataProtoBuf.Files {
|
||||
val filesProto = KlibMetadataProtoBuf.Files.newBuilder()
|
||||
for ((file, id) in fileRegistry.fileIds.entries.sortedBy { it.value }) {
|
||||
header: KlibMetadataProtoBuf.Header.Builder,
|
||||
fileRegistry: KlibMetadataFileRegistry
|
||||
) {
|
||||
|
||||
fileRegistry.filesAndClear().map { it.name ?: "" }.forEach {
|
||||
val fileProto = KlibMetadataProtoBuf.File.newBuilder()
|
||||
if (id != filesProto.fileCount) {
|
||||
fileProto.id = id
|
||||
}
|
||||
val annotations = when (file) {
|
||||
is KotlinPsiFileMetadata -> file.ktFile.annotationEntries.map { bindingContext[BindingContext.ANNOTATION, it]!! }
|
||||
//is KotlinDeserializedFileMetadata -> file.packageFragment.fileMap[file.fileId]!!.annotations
|
||||
else -> TODO("support other file types")
|
||||
}
|
||||
for (annotation in annotations.filterOutSourceAnnotations()) {
|
||||
fileProto.addAnnotation(serializer.serializeAnnotation(annotation))
|
||||
}
|
||||
val name = when (file) {
|
||||
is KotlinPsiFileMetadata -> file.ktFile.getName()
|
||||
else -> TODO("support other file types")
|
||||
}
|
||||
fileProto.name = name
|
||||
filesProto.addFile(fileProto)
|
||||
.setName(it)
|
||||
.build()
|
||||
|
||||
header.addFile(fileProto)
|
||||
}
|
||||
return filesProto.build()
|
||||
}
|
||||
|
||||
protected fun getPackagesFqNames(module: ModuleDescriptor): Set<FqName> {
|
||||
@@ -296,6 +274,9 @@ abstract class KlibMetadataSerializer(
|
||||
emptyPackages.forEach {
|
||||
header.addEmptyPackage(it)
|
||||
}
|
||||
|
||||
serializeFiles(header, fileRegistry)
|
||||
|
||||
return header.build()
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class KlibMetadataSerializerExtension(
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
override val metadataVersion: BinaryVersion,
|
||||
val declarationTableHandler: (DeclarationDescriptor) -> KlibMetadataProtoBuf.DescriptorUniqId?,
|
||||
val descriptorFileId: (DeclarationDescriptor) -> Int?,
|
||||
val descriptorFileId: (DeclarationDescriptorWithSource) -> Int?,
|
||||
override val stringTable: StringTableImpl
|
||||
) : KotlinSerializerExtensionBase(KlibMetadataSerializerProtocol) {
|
||||
override fun shouldUseTypeTable(): Boolean = true
|
||||
|
||||
@@ -12,7 +12,7 @@ dependencies {
|
||||
|
||||
testCompile(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
testCompile(project(":compiler:frontend"))
|
||||
testCompile(project(":compiler:cli"))
|
||||
testCompile(project(":compiler:cli-js"))
|
||||
testCompile(project(":compiler:util"))
|
||||
|
||||
testRuntime(project(":kotlin-reflect"))
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
@@ -41,6 +42,7 @@ import org.jetbrains.kotlin.library.impl.buildKoltinLibrary
|
||||
import org.jetbrains.kotlin.library.impl.createKotlinLibrary
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
|
||||
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -51,6 +53,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import java.io.File
|
||||
import org.jetbrains.kotlin.konan.file.File as KFile
|
||||
@@ -80,6 +83,29 @@ private val CompilerConfiguration.metadataVersion
|
||||
|
||||
class KotlinFileSerializedData(val metadata: ByteArray, val irData: SerializedIrFile)
|
||||
|
||||
// TODO: This is a temporary set of library resolver policies for js compiler.
|
||||
fun jsResolveLibraries(libraries: List<String>, logger: Logger): KotlinLibraryResolveResult {
|
||||
val unresolvedLibraries = libraries.map { UnresolvedLibrary(it ,null) }
|
||||
val libraryAbsolutePaths = libraries.map{ File(it).absolutePath }
|
||||
// Configure the resolver to only work with absolute paths for now.
|
||||
val libraryResolver = KotlinLibrarySearchPathResolver<KotlinLibrary>(
|
||||
repositories = emptyList(),
|
||||
directLibs = libraryAbsolutePaths,
|
||||
distributionKlib = null,
|
||||
localKotlinDir = null,
|
||||
skipCurrentDir = false,
|
||||
logger = logger
|
||||
).libraryResolver()
|
||||
val resolvedLibraries =
|
||||
libraryResolver.resolveWithDependencies(
|
||||
unresolvedLibraries = unresolvedLibraries,
|
||||
noStdLib = true,
|
||||
noDefaultLibs = true,
|
||||
noEndorsedLibs = true
|
||||
)
|
||||
return resolvedLibraries
|
||||
}
|
||||
|
||||
fun generateKLib(
|
||||
project: Project,
|
||||
files: List<KtFile>,
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.ir.backend.js.lower.serialization.metadata
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceFile
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
|
||||
class JsKlibMetadataPackageFragment(
|
||||
fqName: FqName,
|
||||
storageManager: StorageManager,
|
||||
module: ModuleDescriptor,
|
||||
proto: ProtoBuf.PackageFragment,
|
||||
header: KlibMetadataProtoBuf.Header,
|
||||
metadataVersion: JsKlibMetadataVersion,
|
||||
configuration: DeserializationConfiguration
|
||||
) : DeserializedPackageFragmentImpl(
|
||||
fqName, storageManager, module, proto, metadataVersion, JsContainerSource(fqName, header, configuration)
|
||||
) {
|
||||
val fileMap: Map<Int, FileHolder> =
|
||||
proto.getExtension(KlibMetadataProtoBuf.packageFragmentFiles).fileList.withIndex().associate { (index, file) ->
|
||||
(if (file.hasId()) file.id else index) to FileHolder(file.annotationList)
|
||||
}
|
||||
|
||||
private lateinit var annotationDeserializer: AnnotationDeserializer
|
||||
|
||||
override fun initialize(components: DeserializationComponents) {
|
||||
super.initialize(components)
|
||||
this.annotationDeserializer = AnnotationDeserializer(components.moduleDescriptor, components.notFoundClasses)
|
||||
}
|
||||
|
||||
inner class FileHolder(private val annotationsProto: List<ProtoBuf.Annotation>) {
|
||||
val annotations: List<AnnotationDescriptor> by storageManager.createLazyValue {
|
||||
annotationsProto.map { annotationDeserializer.deserializeAnnotation(it, nameResolver) }
|
||||
}
|
||||
}
|
||||
|
||||
class JsContainerSource(
|
||||
private val fqName: FqName,
|
||||
header: KlibMetadataProtoBuf.Header,
|
||||
configuration: DeserializationConfiguration
|
||||
) : DeserializedContainerSource {
|
||||
val annotations: List<ClassId> =
|
||||
if (header.annotationCount == 0) emptyList()
|
||||
else NameResolverImpl(header.strings, header.qualifiedNames).let { nameResolver ->
|
||||
// TODO: read arguments of module annotations
|
||||
header.annotationList.map { annotation -> nameResolver.getClassId(annotation.id) }
|
||||
}
|
||||
|
||||
// TODO
|
||||
override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE
|
||||
|
||||
// This is null because we look for incompatible libraries in dependencies in the beginning of the compilation anyway,
|
||||
// and refuse to compile against them completely
|
||||
override val incompatibility: IncompatibleVersionErrorData<*>?
|
||||
get() = null
|
||||
|
||||
override val isPreReleaseInvisible: Boolean =
|
||||
configuration.reportErrorsOnPreReleaseDependencies && (header.flags and 1) != 0
|
||||
|
||||
override val presentableString: String
|
||||
get() = "Package '$fqName'"
|
||||
}
|
||||
}
|
||||
@@ -9,15 +9,13 @@ import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.vfs.StandardFileSystems
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.js.messageCollectorLogger
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.KotlinLibrarySearchPathResolver
|
||||
import org.jetbrains.kotlin.library.UnresolvedLibrary
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
@@ -117,18 +115,9 @@ fun main(args: Array<String>) {
|
||||
error("Please set path to .klm file: `-o some/dir/module-name.klm`")
|
||||
}
|
||||
|
||||
val dependencyAbsolutePaths = dependencies.map{ File(it).absolutePath }
|
||||
val unresolvedLibraries = dependencies.map { UnresolvedLibrary(it, null) }
|
||||
// Configure the resolver to only understand absolute path libraries.
|
||||
val libraryResolver = KotlinLibrarySearchPathResolver<KotlinLibrary>(
|
||||
repositories = emptyList(),
|
||||
directLibs = dependencyAbsolutePaths,
|
||||
distributionKlib = null,
|
||||
localKotlinDir = null,
|
||||
skipCurrentDir = true
|
||||
// TODO: pass logger attached to message collector here.
|
||||
).libraryResolver()
|
||||
val resolvedLibraries = libraryResolver.resolveWithDependencies(unresolvedLibraries, true, true, true)
|
||||
val resolvedLibraries = jsResolveLibraries(
|
||||
dependencies, messageCollectorLogger(MessageCollector.NONE)
|
||||
)
|
||||
|
||||
buildKLib(File(outputPath).absolutePath, listOfKtFilesFrom(inputFiles), outputPath, resolvedLibraries, listOfKtFilesFrom(commonSources))
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ private class ClassFilterForClassOrObject(private val classOrObject: KtClassOrOb
|
||||
if (classOrObject === processingClassOrObject) return true
|
||||
|
||||
// process all children
|
||||
if (classOrObject.isAncestor(processingClassOrObject, true) || processingClassOrObject.isAncestor(classOrObject, true)) {
|
||||
if (classOrObject.isAncestor(processingClassOrObject, true)) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -196,8 +196,9 @@ private class ClassFilterForClassOrObject(private val classOrObject: KtClassOrOb
|
||||
return false
|
||||
}
|
||||
|
||||
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject) =
|
||||
shouldGenerateClassMembers(processingClassOrObject)
|
||||
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject)
|
||||
// generate outer classes but not their members
|
||||
= shouldGenerateClassMembers(processingClassOrObject) || processingClassOrObject.isAncestor(classOrObject, true)
|
||||
|
||||
override fun shouldGenerateScript(script: KtScript) = PsiTreeUtil.isAncestor(script, classOrObject, false)
|
||||
override fun shouldGenerateCodeFragment(script: KtCodeFragment) = false
|
||||
|
||||
@@ -21,13 +21,15 @@ import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.util.ArrayUtil
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import gnu.trove.THashMap
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
class KotlinClassInnerStuffCache(val myClass: PsiExtensibleClass, externalDependencies: List<Any>) {
|
||||
private val myTracker = SimpleModificationTracker()
|
||||
private val dependencies: List<Any> = externalDependencies + myTracker
|
||||
|
||||
fun <T : Any> get(initializer: () -> T) = object : Lazy<T> {
|
||||
// Note: holder is used as initialization monitor as well
|
||||
private val lock = ReentrantLock()
|
||||
private val holder = lazyPub {
|
||||
PsiCachedValueImpl(PsiManager.getInstance(myClass.project),
|
||||
CachedValueProvider<T> {
|
||||
@@ -49,18 +51,23 @@ class KotlinClassInnerStuffCache(val myClass: PsiExtensibleClass, externalDepend
|
||||
// Assumption 1: Lets say A calculation requires another value e.g. B to be calculated
|
||||
// Assumption 2: Thread T2 wants to calculate value for B
|
||||
|
||||
// to avoid dead-lock case we mark thread as doing calculation and acquire lock only once per thread
|
||||
// to avoid dead-lock
|
||||
// - we mark thread as doing calculation and acquire lock only once per thread
|
||||
// as a trade-off to prevent dependent value could be calculated several time
|
||||
// due to CAS (within putUserDataIfAbsent etc) the same instance of calculated value will be used
|
||||
|
||||
if (!initIsRunning.get()) {
|
||||
synchronized(holder) {
|
||||
// TODO: NOTE: acquire lock for a several seconds to avoid dead-lock via resolve is a WORKAROUND
|
||||
|
||||
if (!initIsRunning.get() && lock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
initIsRunning.set(true)
|
||||
try {
|
||||
computeValue()
|
||||
} finally {
|
||||
initIsRunning.set(false)
|
||||
}
|
||||
} finally {
|
||||
lock.unlock()
|
||||
}
|
||||
} else {
|
||||
computeValue()
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.EXTERNAL_KEYWORD
|
||||
import org.jetbrains.kotlin.lexer.KtTokens.REIFIED_KEYWORD
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||
@@ -276,6 +277,7 @@ internal class UltraLightMembersCreator(
|
||||
))
|
||||
PsiModifier.STRICTFP -> declaration is KtFunction && declaration.hasAnnotation(STRICTFP_ANNOTATION_FQ_NAME)
|
||||
PsiModifier.SYNCHRONIZED -> declaration is KtFunction && declaration.hasAnnotation(SYNCHRONIZED_ANNOTATION_FQ_NAME)
|
||||
PsiModifier.NATIVE -> declaration is KtFunction && declaration.hasModifier(EXTERNAL_KEYWORD)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataProviderForFileFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory.cast
|
||||
@@ -49,7 +50,8 @@ fun getJvmSignatureDiagnostics(element: PsiElement, otherDiagnostics: Diagnostic
|
||||
}
|
||||
|
||||
fun getDiagnosticsForClass(ktClassOrObject: KtClassOrObject): Diagnostics {
|
||||
val lightClassDataHolder = KtLightClassForSourceDeclaration.getLightClassDataHolder(ktClassOrObject)
|
||||
val outermostClass = getOutermostClassOrObject(ktClassOrObject)
|
||||
val lightClassDataHolder = KtLightClassForSourceDeclaration.getLightClassDataHolder(outermostClass)
|
||||
if (lightClassDataHolder is InvalidLightClassDataHolder) {
|
||||
return Diagnostics.EMPTY
|
||||
}
|
||||
|
||||
@@ -472,6 +472,8 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m
|
||||
return file.importDirectives
|
||||
}
|
||||
|
||||
fun createClassKeyword(): PsiElement = createClass("class A").getClassKeyword()!!
|
||||
|
||||
fun createPrimaryConstructor(text: String = ""): KtPrimaryConstructor {
|
||||
return createClass(if (text.isNotEmpty()) "class A $text" else "class A()").primaryConstructor!!
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DiagnosticReporter
|
||||
@@ -45,6 +43,13 @@ interface ImplicitScopeTower {
|
||||
val isNewInferenceEnabled: Boolean
|
||||
|
||||
val typeApproximator: TypeApproximator
|
||||
|
||||
fun interceptCandidates(
|
||||
resolutionScope: ResolutionScope,
|
||||
name: Name,
|
||||
initialResults: Collection<FunctionDescriptor>,
|
||||
location: LookupLocation
|
||||
): Collection<FunctionDescriptor>
|
||||
}
|
||||
|
||||
interface ScopeTowerLevel {
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||
@@ -207,7 +210,7 @@ internal class QualifierScopeTowerLevel(scopeTower: ImplicitScopeTower, val qual
|
||||
.getContributedFunctionsAndConstructors(
|
||||
name,
|
||||
location,
|
||||
scopeTower.syntheticScopes
|
||||
scopeTower
|
||||
).map {
|
||||
createCandidateDescriptor(it, dispatchReceiver = null)
|
||||
}
|
||||
@@ -255,7 +258,7 @@ internal open class ScopeBasedTowerLevel protected constructor(
|
||||
): Collection<CandidateWithBoundDispatchReceiver> {
|
||||
val result: ArrayList<CandidateWithBoundDispatchReceiver> = ArrayList()
|
||||
|
||||
resolutionScope.getContributedFunctionsAndConstructors(name, location, scopeTower.syntheticScopes).mapTo(result) {
|
||||
resolutionScope.getContributedFunctionsAndConstructors(name, location, scopeTower).mapTo(result) {
|
||||
createCandidateDescriptor(
|
||||
it,
|
||||
dispatchReceiver = null,
|
||||
@@ -366,7 +369,7 @@ private fun KotlinType?.getInnerConstructors(name: Name, location: LookupLocatio
|
||||
private fun ResolutionScope.getContributedFunctionsAndConstructors(
|
||||
name: Name,
|
||||
location: LookupLocation,
|
||||
syntheticScopes: SyntheticScopes
|
||||
scopeTower: ImplicitScopeTower
|
||||
): Collection<FunctionDescriptor> {
|
||||
val result = ArrayList<FunctionDescriptor>(getContributedFunctions(name, location))
|
||||
|
||||
@@ -374,10 +377,10 @@ private fun ResolutionScope.getContributedFunctionsAndConstructors(
|
||||
result.addAll(getConstructorsOfClassifier(it))
|
||||
}
|
||||
|
||||
result.addAll(syntheticScopes.collectSyntheticStaticFunctions(this, name, location))
|
||||
result.addAll(syntheticScopes.collectSyntheticConstructors(this, name, location))
|
||||
result.addAll(scopeTower.syntheticScopes.collectSyntheticStaticFunctions(this, name, location))
|
||||
result.addAll(scopeTower.syntheticScopes.collectSyntheticConstructors(this, name, location))
|
||||
|
||||
return result.toList()
|
||||
return scopeTower.interceptCandidates(this, name, result, location)
|
||||
}
|
||||
|
||||
private fun getConstructorsOfClassifier(classifier: ClassifierDescriptor?): List<ConstructorDescriptor> {
|
||||
|
||||
@@ -9,5 +9,7 @@ class Foo {
|
||||
operator fun plus(increment: Int): Foo {}
|
||||
fun String.onString(a: (Int) -> Any?): Foo {}
|
||||
|
||||
external fun externalFun(a: Int): String { return "" }
|
||||
|
||||
class Inner {}
|
||||
}
|
||||
|
||||
@@ -7,3 +7,5 @@ public fun nullableVararg(vararg o: Any?): Unit
|
||||
|
||||
operator fun plus(increment: Int): Foo {}
|
||||
fun String.onString(a: (Int) -> Any?): Foo {}
|
||||
|
||||
external fun externalFun(a: Int): String { return "" }
|
||||
15
compiler/testData/codegen/box/collections/removeClash.kt
vendored
Normal file
15
compiler/testData/codegen/box/collections/removeClash.kt
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
class Queue<T>(override val size: Int) : Collection<T> {
|
||||
override fun contains(element: T): Boolean = TODO()
|
||||
|
||||
override fun containsAll(elements: Collection<T>): Boolean = TODO()
|
||||
|
||||
override fun isEmpty(): Boolean = TODO()
|
||||
|
||||
override fun iterator(): Iterator<T> = TODO()
|
||||
|
||||
fun remove(v: T): Any = v as Any
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return Queue<String>(1).remove("OK") as String
|
||||
}
|
||||
33
compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt
vendored
Normal file
33
compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FULL_JDK
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
|
||||
var c: Continuation<*>? = null
|
||||
|
||||
suspend fun <T> tx(lambda: () -> T): T = suspendCoroutine { c = it; lambda() }
|
||||
|
||||
object Dummy
|
||||
|
||||
suspend fun suspect() {
|
||||
tx { Dummy }
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var res: Any? = null
|
||||
builder {
|
||||
res = suspect()
|
||||
}
|
||||
|
||||
(c as? Continuation<Dummy>)?.resume(Dummy)
|
||||
|
||||
return if (res != Unit) "$res" else "OK"
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FULL_JDK
|
||||
// WITH_RUNTIME
|
||||
// WITH_REFLECT
|
||||
// WITH_COROUTINES
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.reflect.full.callSuspend
|
||||
import kotlin.reflect.KCallable
|
||||
|
||||
var c: Continuation<*>? = null
|
||||
|
||||
suspend fun <T> tx(lambda: () -> T): T = suspendCoroutine { c = it; lambda() }
|
||||
|
||||
object Dummy
|
||||
|
||||
suspend fun suspect() {
|
||||
tx { Dummy }
|
||||
}
|
||||
|
||||
fun builder(c: suspend () -> Unit) {
|
||||
c.startCoroutine(EmptyContinuation)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var res: Any? = null
|
||||
builder {
|
||||
res = (::suspect as KCallable<*>).callSuspend()
|
||||
}
|
||||
|
||||
(c as? Continuation<Dummy>)?.resume(Dummy)
|
||||
|
||||
return if (res != Unit) "$res" else "OK"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// !LANGUAGE: +ProperComputationOrderOfTailrecDefaultParameters
|
||||
// DONT_RUN_GENERATED_CODE: JS
|
||||
// IGNORE_BACKEND: JVM
|
||||
|
||||
var counter = 0
|
||||
fun inc() = counter++
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// !LANGUAGE: +ProperComputationOrderOfTailrecDefaultParameters
|
||||
// Flag above doesn't matter cause 1 default value is passed explicitly in tail recursion call
|
||||
// DONT_RUN_GENERATED_CODE: JS
|
||||
|
||||
var counter = 0
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// !LANGUAGE: -ProperComputationOrderOfTailrecDefaultParameters
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
|
||||
var counter = 0
|
||||
fun calc(counter: Int) = if (counter % 2 == 0) "K" else "O"
|
||||
|
||||
<!TAILREC_WITH_DEFAULTS!>tailrec fun test(x: Int, y: String = calc(counter++), z: String = calc(counter++)): String<!> {
|
||||
if (x > 0)
|
||||
return y + z
|
||||
|
||||
return test(x + 1)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return test(0)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package
|
||||
|
||||
public var counter: kotlin.Int
|
||||
public fun box(): kotlin.String
|
||||
public fun calc(/*0*/ counter: kotlin.Int): kotlin.String
|
||||
public tailrec fun test(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.String = ..., /*2*/ z: kotlin.String = ...): kotlin.String
|
||||
9
compiler/testData/codegen/box/functions/functionExpression/insideGenericLambda.kt
vendored
Normal file
9
compiler/testData/codegen/box/functions/functionExpression/insideGenericLambda.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
fun <T> block(block: () -> T): T = block()
|
||||
fun foo() {}
|
||||
|
||||
fun test(): () -> Unit = block { fun() = foo() }
|
||||
|
||||
fun box(): String {
|
||||
test()
|
||||
return "OK"
|
||||
}
|
||||
9
compiler/testData/codegen/box/inlineClasses/kt34268.kt
vendored
Normal file
9
compiler/testData/codegen/box/inlineClasses/kt34268.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
|
||||
fun box(): String {
|
||||
return when(val foo = 42UL) {
|
||||
42UL -> "OK"
|
||||
else -> "Fail"
|
||||
}
|
||||
}
|
||||
18
compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt
vendored
Normal file
18
compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// FILE: Unsound.java
|
||||
|
||||
import test.Wrap;
|
||||
|
||||
public class Unsound {
|
||||
public static <T> Wrap<T> get() {
|
||||
return new Wrap<T>(null);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
class Wrap<T>(val x: T)
|
||||
|
||||
fun box(): String = if ((Unsound.get<String>() as Wrap<String>).x == null) "OK" else "Fail"
|
||||
21
compiler/testData/codegen/box/platformTypes/unsafeNullCheckWithPrimitive.kt
vendored
Normal file
21
compiler/testData/codegen/box/platformTypes/unsafeNullCheckWithPrimitive.kt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// FILE: Unsound.java
|
||||
|
||||
import test.Wrap;
|
||||
|
||||
public class Unsound {
|
||||
public static <T> Wrap<T> get() {
|
||||
return new Wrap<T>(null);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
class Wrap<T>(val x: T)
|
||||
|
||||
// JVM IR generates bytecode that fails with NPE because it unwraps the value with `Number.intValue()`,
|
||||
// whereas JVM generates a simple null check without unwrapping the box.
|
||||
fun box(): String = if ((Unsound.get<Int>() as Wrap<Int>).x == null) "OK" else "Fail"
|
||||
15
compiler/testData/codegen/box/properties/initOrderMultiModule.kt
vendored
Normal file
15
compiler/testData/codegen/box/properties/initOrderMultiModule.kt
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
|
||||
// KT-34273
|
||||
|
||||
class Foo(val str: String)
|
||||
|
||||
private val foo1 = Foo("OK")
|
||||
|
||||
val foo2 = foo1
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: main.kt
|
||||
|
||||
fun box(): String = foo2.str
|
||||
24
compiler/testData/codegen/box/properties/sideEffectInTopLevelInitializerMultiModule.kt
vendored
Normal file
24
compiler/testData/codegen/box/properties/sideEffectInTopLevelInitializerMultiModule.kt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
// MODULE: lib1
|
||||
// FILE: lib1.kt
|
||||
|
||||
// KT-34273
|
||||
|
||||
var foo = "Fail"
|
||||
|
||||
// MODULE: lib2(lib1)
|
||||
// FILE: lib2.kt
|
||||
|
||||
private val bar = run {
|
||||
foo = "OK"
|
||||
42
|
||||
}
|
||||
|
||||
|
||||
// MODULE: main(lib1, lib2)
|
||||
// FILE: main.kt
|
||||
|
||||
// TODO: the proper behaviour of this test is still open design issue
|
||||
// K/N & K/JS used to go like this when JVM fails
|
||||
|
||||
fun box(): String = foo
|
||||
11
compiler/testData/codegen/box/ranges/unsigned/kt35004.kt
vendored
Normal file
11
compiler/testData/codegen/box/ranges/unsigned/kt35004.kt
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
|
||||
fun ULong.foobar() =
|
||||
when (this) {
|
||||
in 0U..1U -> "OK"
|
||||
else -> throw AssertionError("$this")
|
||||
}
|
||||
|
||||
fun box(): String = 0UL.foobar()
|
||||
@@ -35,6 +35,7 @@ fun box(): String {
|
||||
assertEquals("Short?", get1<Short>().toString())
|
||||
assertEquals("Map<in Short?, Array<Short>>?", get2<Short>().toString())
|
||||
assertEquals("Map<in List<Short>?, Array<List<Short>>>?", get2<List<Short>>().toString())
|
||||
assertEquals("Map<in List<dynamic>?, Array<List<dynamic>>>?", get2<List<dynamic>>().toString())
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
22
compiler/testData/codegen/box/reflection/typeOf/js/typeOfReifiedUnit.kt
vendored
Normal file
22
compiler/testData/codegen/box/reflection/typeOf/js/typeOfReifiedUnit.kt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||
// TARGET_BACKEND: JS
|
||||
// IGNORE_BACKEND: JS_IR
|
||||
// WITH_REFLECT
|
||||
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
fun sideEffects() {
|
||||
println("Side effect")
|
||||
}
|
||||
|
||||
inline fun <reified T> foo(): String {
|
||||
sideEffects()
|
||||
val x = typeOf<T>().toString()
|
||||
return x
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (foo<kotlin.Unit>() != "Unit")
|
||||
return "FAIL"
|
||||
return "OK"
|
||||
}
|
||||
18
compiler/testData/codegen/box/regressions/kt24913.kt
vendored
Normal file
18
compiler/testData/codegen/box/regressions/kt24913.kt
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
class Outer<T> (val v: T) {
|
||||
val prop: Any?
|
||||
|
||||
init {
|
||||
class Inner(val v: T) {
|
||||
override fun toString() = v.toString()
|
||||
}
|
||||
|
||||
val value: Inner = Inner(v)
|
||||
prop = value
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return Outer("OK").prop.toString()
|
||||
}
|
||||
21
compiler/testData/codegen/boxInline/anonymousObject/kt34656.kt
vendored
Normal file
21
compiler/testData/codegen/boxInline/anonymousObject/kt34656.kt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// FILE: 1.kt
|
||||
package test
|
||||
|
||||
interface Foo {
|
||||
fun call(): String
|
||||
}
|
||||
|
||||
inline fun f(crossinline g: () -> String) = object: Foo {
|
||||
fun <T> foo() = g()
|
||||
fun <T> bar() = "K"
|
||||
override fun call(): String = foo<String>() + bar<String>()
|
||||
}
|
||||
|
||||
// FILE: 2.kt
|
||||
import test.*
|
||||
|
||||
val x = f { "O" }
|
||||
|
||||
fun box() : String {
|
||||
return x.call()
|
||||
}
|
||||
40
compiler/testData/codegen/boxInline/suspend/catchBlockNop.kt
vendored
Normal file
40
compiler/testData/codegen/boxInline/suspend/catchBlockNop.kt
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// FILE: test.kt
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
const val DEBUG = false
|
||||
inline fun inlineFun(b: () -> Unit) {
|
||||
if (DEBUG) {
|
||||
inlineFunReal(b)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun inlineFunReal(b: () -> Unit) {
|
||||
try {
|
||||
b()
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: box.kt
|
||||
fun builder(c: suspend () -> Unit) {}
|
||||
|
||||
class Sample {
|
||||
fun test() {
|
||||
inlineFun {
|
||||
builder {
|
||||
inlineFun {
|
||||
suspendFun()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun suspendFun() {}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
Sample().test()
|
||||
return "OK"
|
||||
}
|
||||
39
compiler/testData/diagnostics/tests/properDefaultInitializationInTailrec.kt
vendored
Normal file
39
compiler/testData/diagnostics/tests/properDefaultInitializationInTailrec.kt
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
//!LANGUAGE: +ProperComputationOrderOfTailrecDefaultParameters
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
fun withEffects(): String = "OK"
|
||||
|
||||
const val Z = "123"
|
||||
|
||||
enum class EnumA {
|
||||
A
|
||||
}
|
||||
|
||||
tailrec fun foo(i: Int = 1, c: Char = '2', s: String = "1234", b: Boolean = true, d: Double = 1.0, l: Long = 1L, y: String = withEffects()) {
|
||||
foo(i, c, s, b, d, l, y)
|
||||
}
|
||||
|
||||
|
||||
tailrec fun foo2(x: Int = 1, y: String = withEffects(), z: String = Z) {
|
||||
foo2(x, y, z)
|
||||
}
|
||||
|
||||
tailrec fun foo3(y: String = withEffects()) {
|
||||
foo3(y)
|
||||
}
|
||||
|
||||
tailrec fun foo4(x: String = withEffects(), y: String = withEffects()) {
|
||||
foo4(x, y)
|
||||
}
|
||||
|
||||
tailrec fun foo5(x: String = withEffects(), y: String = withEffects(), z: String = withEffects()) {
|
||||
foo5(x, y, z)
|
||||
}
|
||||
|
||||
tailrec fun foo6(x: String = withEffects(), y: EnumA = EnumA.A) {
|
||||
foo6(x, y)
|
||||
}
|
||||
|
||||
tailrec fun foo7(x: String = withEffects(), y: KClass<out EnumA> = EnumA.A::class) {
|
||||
foo7(x, y)
|
||||
}
|
||||
30
compiler/testData/diagnostics/tests/properDefaultInitializationInTailrec.txt
vendored
Normal file
30
compiler/testData/diagnostics/tests/properDefaultInitializationInTailrec.txt
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package
|
||||
|
||||
public const val Z: kotlin.String = "123"
|
||||
public tailrec fun foo(/*0*/ i: kotlin.Int = ..., /*1*/ c: kotlin.Char = ..., /*2*/ s: kotlin.String = ..., /*3*/ b: kotlin.Boolean = ..., /*4*/ d: kotlin.Double = ..., /*5*/ l: kotlin.Long = ..., /*6*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo2(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ..., /*2*/ z: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo3(/*0*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo4(/*0*/ x: kotlin.String = ..., /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo5(/*0*/ x: kotlin.String = ..., /*1*/ y: kotlin.String = ..., /*2*/ z: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo6(/*0*/ x: kotlin.String = ..., /*1*/ y: EnumA = ...): kotlin.Unit
|
||||
public tailrec fun foo7(/*0*/ x: kotlin.String = ..., /*1*/ y: kotlin.reflect.KClass<out EnumA> = ...): kotlin.Unit
|
||||
public fun withEffects(): kotlin.String
|
||||
|
||||
public final enum class EnumA : kotlin.Enum<EnumA> {
|
||||
enum entry A
|
||||
|
||||
private constructor EnumA()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: EnumA): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<EnumA!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): EnumA
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<EnumA>
|
||||
}
|
||||
171
compiler/testData/diagnostics/tests/tailRecOnVirtualMember.kt
vendored
Normal file
171
compiler/testData/diagnostics/tests/tailRecOnVirtualMember.kt
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
//!LANGUAGE: -ProhibitTailrecOnVirtualMember
|
||||
|
||||
open class A {
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec open fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>internal tailrec open fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>protected tailrec open fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
|
||||
private tailrec fun boo(y: Int) {
|
||||
boo(y)
|
||||
}
|
||||
|
||||
internal tailrec fun baa(y: Int) {
|
||||
baa(y)
|
||||
}
|
||||
}
|
||||
|
||||
open class B : A() {
|
||||
final tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
final tailrec override fun bar(y: Int) {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
final tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open class C : A() {
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
|
||||
object D : A() {
|
||||
tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
tailrec override fun bar(y: Int) {
|
||||
bar(y - 1)
|
||||
}
|
||||
|
||||
tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
|
||||
sealed class E : A() {
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec override fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
|
||||
class E1 : E() {
|
||||
tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
tailrec override fun bar(y: Int) {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class F {
|
||||
F0,
|
||||
F1() {
|
||||
tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
tailrec override fun bar(y: Int) {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
};
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec open fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>internal tailrec open fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>protected tailrec open fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
|
||||
private tailrec fun boo(y: Int) {
|
||||
boo(y)
|
||||
}
|
||||
|
||||
internal tailrec fun baa(y: Int) {
|
||||
baa(y)
|
||||
}
|
||||
}
|
||||
|
||||
enum class G {
|
||||
|
||||
G1;
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>tailrec open fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>internal tailrec open fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER!>protected tailrec open fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
|
||||
private tailrec fun boo(y: Int) {
|
||||
boo(y)
|
||||
}
|
||||
|
||||
internal tailrec fun baa(y: Int) {
|
||||
baa(y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val z = object : A() {
|
||||
tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
tailrec override fun bar(y: Int) {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
125
compiler/testData/diagnostics/tests/tailRecOnVirtualMember.txt
vendored
Normal file
125
compiler/testData/diagnostics/tests/tailRecOnVirtualMember.txt
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
package
|
||||
|
||||
public val z: A
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
internal final tailrec fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
private final tailrec fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class B : A {
|
||||
public constructor B()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal final override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected final override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class C : A {
|
||||
public constructor C()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public object D : A {
|
||||
private constructor D()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public sealed class E : A {
|
||||
private constructor E()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public final class E1 : E {
|
||||
public constructor E1()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
public final enum class F : kotlin.Enum<F> {
|
||||
enum entry F0
|
||||
|
||||
enum entry F1
|
||||
|
||||
private constructor F()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
internal final tailrec fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
private final tailrec fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: F): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public open tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<F!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): F
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<F>
|
||||
}
|
||||
|
||||
public final enum class G : kotlin.Enum<G> {
|
||||
enum entry G1
|
||||
|
||||
private constructor G()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
internal final tailrec fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
private final tailrec fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: G): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public open tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<G!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): G
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<G>
|
||||
}
|
||||
170
compiler/testData/diagnostics/tests/tailRecOnVirtualMemberError.kt
vendored
Normal file
170
compiler/testData/diagnostics/tests/tailRecOnVirtualMemberError.kt
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
//!LANGUAGE: +ProhibitTailrecOnVirtualMember
|
||||
|
||||
open class A {
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
|
||||
private tailrec fun boo(y: Int) {
|
||||
boo(y)
|
||||
}
|
||||
|
||||
internal tailrec fun baa(y: Int) {
|
||||
baa(y)
|
||||
}
|
||||
}
|
||||
|
||||
open class B : A() {
|
||||
final tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
final tailrec override fun bar(y: Int) {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
final tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open class C : A() {
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
|
||||
object D : A() {
|
||||
tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
tailrec override fun bar(y: Int) {
|
||||
bar(y - 1)
|
||||
}
|
||||
|
||||
tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
|
||||
sealed class E : A() {
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec override fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
|
||||
class E1 : E() {
|
||||
tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
tailrec override fun bar(y: Int) {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class F {
|
||||
F0,
|
||||
F1() {
|
||||
tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
tailrec override fun bar(y: Int) {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
};
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
|
||||
private tailrec fun boo(y: Int) {
|
||||
boo(y)
|
||||
}
|
||||
|
||||
internal tailrec fun baa(y: Int) {
|
||||
baa(y)
|
||||
}
|
||||
}
|
||||
|
||||
enum class G {
|
||||
|
||||
G1;
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>tailrec open fun foo(x: Int)<!> {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>internal tailrec open fun bar(y: Int)<!> {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
<!TAILREC_ON_VIRTUAL_MEMBER_ERROR!>protected tailrec open fun baz(y: Int)<!> {
|
||||
baz(y)
|
||||
}
|
||||
|
||||
private tailrec fun boo(y: Int) {
|
||||
boo(y)
|
||||
}
|
||||
|
||||
internal tailrec fun baa(y: Int) {
|
||||
baa(y)
|
||||
}
|
||||
}
|
||||
|
||||
val z = object : A() {
|
||||
tailrec override fun foo(x: Int) {
|
||||
foo(x)
|
||||
}
|
||||
|
||||
tailrec override fun bar(y: Int) {
|
||||
bar(y)
|
||||
}
|
||||
|
||||
tailrec override fun baz(y: Int) {
|
||||
baz(y)
|
||||
}
|
||||
}
|
||||
125
compiler/testData/diagnostics/tests/tailRecOnVirtualMemberError.txt
vendored
Normal file
125
compiler/testData/diagnostics/tests/tailRecOnVirtualMemberError.txt
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
package
|
||||
|
||||
public val z: A
|
||||
|
||||
public open class A {
|
||||
public constructor A()
|
||||
internal final tailrec fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
private final tailrec fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class B : A {
|
||||
public constructor B()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal final override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected final override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class C : A {
|
||||
public constructor C()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public object D : A {
|
||||
private constructor D()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public sealed class E : A {
|
||||
private constructor E()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
public final class E1 : E {
|
||||
public constructor E1()
|
||||
internal final override /*1*/ tailrec /*fake_override*/ fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open override /*1*/ tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open override /*1*/ tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
invisible_fake final override /*1*/ tailrec /*fake_override*/ fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
public final enum class F : kotlin.Enum<F> {
|
||||
enum entry F0
|
||||
|
||||
enum entry F1
|
||||
|
||||
private constructor F()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
internal final tailrec fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
private final tailrec fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: F): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public open tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<F!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): F
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<F>
|
||||
}
|
||||
|
||||
public final enum class G : kotlin.Enum<G> {
|
||||
enum entry G1
|
||||
|
||||
private constructor G()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
internal final tailrec fun baa(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
internal open tailrec fun bar(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected open tailrec fun baz(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
private final tailrec fun boo(/*0*/ y: kotlin.Int): kotlin.Unit
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: G): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public open tailrec fun foo(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<G!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): G
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<G>
|
||||
}
|
||||
39
compiler/testData/diagnostics/tests/unproperDefaultInitializationInTailrec.kt
vendored
Normal file
39
compiler/testData/diagnostics/tests/unproperDefaultInitializationInTailrec.kt
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
//!LANGUAGE: -ProperComputationOrderOfTailrecDefaultParameters
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
fun withEffects(): String = "OK"
|
||||
|
||||
const val Z = "123"
|
||||
|
||||
enum class EnumA {
|
||||
A
|
||||
}
|
||||
|
||||
tailrec fun foo(i: Int = 1, c: Char = '2', s: String = "1234", b: Boolean = true, d: Double = 1.0, l: Long = 1L, y: String = withEffects()) {
|
||||
foo(i, c, s, b, d, l, y)
|
||||
}
|
||||
|
||||
tailrec fun foo2(x: Int = 1, y: String = withEffects(), z: String = Z) {
|
||||
foo2(x, y, z)
|
||||
}
|
||||
|
||||
tailrec fun foo3(y: String = withEffects()) {
|
||||
foo3(y)
|
||||
}
|
||||
|
||||
<!TAILREC_WITH_DEFAULTS!>tailrec fun foo4(x: String = withEffects(), y: String = withEffects())<!> {
|
||||
foo4(x, y)
|
||||
}
|
||||
|
||||
<!TAILREC_WITH_DEFAULTS!>tailrec fun foo5(x: String = withEffects(), y: String = withEffects(), z: String = withEffects())<!> {
|
||||
foo5(x, y, z)
|
||||
}
|
||||
|
||||
<!TAILREC_WITH_DEFAULTS!>tailrec fun foo6(x: String = withEffects(), y: EnumA = EnumA.A)<!> {
|
||||
foo6(x, y)
|
||||
}
|
||||
|
||||
<!TAILREC_WITH_DEFAULTS!>tailrec fun foo7(x: String = withEffects(), y: KClass<out EnumA> = EnumA.A::class)<!> {
|
||||
foo7(x, y)
|
||||
}
|
||||
30
compiler/testData/diagnostics/tests/unproperDefaultInitializationInTailrec.txt
vendored
Normal file
30
compiler/testData/diagnostics/tests/unproperDefaultInitializationInTailrec.txt
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package
|
||||
|
||||
public const val Z: kotlin.String = "123"
|
||||
public tailrec fun foo(/*0*/ i: kotlin.Int = ..., /*1*/ c: kotlin.Char = ..., /*2*/ s: kotlin.String = ..., /*3*/ b: kotlin.Boolean = ..., /*4*/ d: kotlin.Double = ..., /*5*/ l: kotlin.Long = ..., /*6*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo2(/*0*/ x: kotlin.Int = ..., /*1*/ y: kotlin.String = ..., /*2*/ z: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo3(/*0*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo4(/*0*/ x: kotlin.String = ..., /*1*/ y: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo5(/*0*/ x: kotlin.String = ..., /*1*/ y: kotlin.String = ..., /*2*/ z: kotlin.String = ...): kotlin.Unit
|
||||
public tailrec fun foo6(/*0*/ x: kotlin.String = ..., /*1*/ y: EnumA = ...): kotlin.Unit
|
||||
public tailrec fun foo7(/*0*/ x: kotlin.String = ..., /*1*/ y: kotlin.reflect.KClass<out EnumA> = ...): kotlin.Unit
|
||||
public fun withEffects(): kotlin.String
|
||||
|
||||
public final enum class EnumA : kotlin.Enum<EnumA> {
|
||||
enum entry A
|
||||
|
||||
private constructor EnumA()
|
||||
public final override /*1*/ /*fake_override*/ val name: kotlin.String
|
||||
public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int
|
||||
protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any
|
||||
public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: EnumA): kotlin.Int
|
||||
public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit
|
||||
public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class<EnumA!>!
|
||||
public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): EnumA
|
||||
public final /*synthesized*/ fun values(): kotlin.Array<EnumA>
|
||||
}
|
||||
@@ -5,73 +5,73 @@ Output:
|
||||
-- JVM --
|
||||
Exit code: COMPILATION_ERROR
|
||||
Output:
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:1:12: error: expected function 'f1' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:1:12: error: expected function 'f1' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because return type is different:
|
||||
public actual fun f1(): String
|
||||
|
||||
expect fun f1()
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:5:14: error: expected function 'f3' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:5:14: error: expected function 'f3' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because parameter types are different:
|
||||
public actual fun f3(name: Double): Unit
|
||||
|
||||
expect fun f3(name: String)
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:6:24: error: expected function 'f3ext' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:6:24: error: expected function 'f3ext' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because parameter types are different:
|
||||
public actual fun Double.f3ext(): Unit
|
||||
|
||||
expect fun String.f3ext()
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:8:14: error: expected function 'f4' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:8:14: error: expected function 'f4' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because parameter shapes are different (extension vs non-extension):
|
||||
public actual fun String.f4(): Unit
|
||||
|
||||
expect fun f4(name: String)
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:10:12: error: expected function 'f5' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:10:12: error: expected function 'f5' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because parameter shapes are different (extension vs non-extension):
|
||||
public actual fun f5(name: String): Unit
|
||||
|
||||
expect fun String.f5()
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:12:14: error: expected function 'f6' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:12:14: error: expected function 'f6' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because number of value parameters is different:
|
||||
public actual fun f6(p2: Int): Unit
|
||||
|
||||
expect fun f6(p1: String, p2: Int)
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:14:12: error: expected function 'f7' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:14:12: error: expected function 'f7' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because number of type parameters is different:
|
||||
public actual fun <K, V> f7(): Unit
|
||||
|
||||
expect fun <T> f7()
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:19:12: error: expected function 'f11' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:19:12: error: expected function 'f11' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because upper bounds of type parameters are different:
|
||||
public actual fun <T : Annotation> f11(): Unit
|
||||
|
||||
expect fun <T : Number> f11()
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:20:12: error: expected function 'f12' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:20:12: error: expected function 'f12' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because upper bounds of type parameters are different:
|
||||
public actual fun <U : MutableList<out String>> f12(): Unit
|
||||
|
||||
expect fun <U : MutableList<String>> f12()
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:21:12: error: expected function 'f13' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:21:12: error: expected function 'f13' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because upper bounds of type parameters are different:
|
||||
public actual fun <A, B : Comparable<B>> f13(): Unit
|
||||
|
||||
expect fun <A, B : Comparable<A>> f13()
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:32:15: error: expected function 'f21' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:32:15: error: expected function 'f21' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because parameter types are different:
|
||||
public actual fun f21(c: Unit.() -> Unit): Unit
|
||||
|
||||
expect fun f21(c: suspend Unit.() -> Unit)
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:33:15: error: expected function 'f22' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleCallables/common.kt:33:15: error: expected function 'f22' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because parameter types are different:
|
||||
public actual fun f22(c: suspend Unit.() -> Unit): Unit
|
||||
|
||||
|
||||
@@ -5,19 +5,19 @@ Output:
|
||||
-- JVM --
|
||||
Exit code: COMPILATION_ERROR
|
||||
Output:
|
||||
compiler/testData/multiplatform/incompatibleClasses/common.kt:14:16: error: expected class 'C1' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleClasses/common.kt:14:16: error: expected class 'C1' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because number of type parameters is different:
|
||||
public final actual class C1<A, Extra>
|
||||
|
||||
expect class C1<A>
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleClasses/common.kt:16:16: error: expected class 'C3' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleClasses/common.kt:16:16: error: expected class 'C3' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because upper bounds of type parameters are different:
|
||||
public final actual class C3<D, E : D?>
|
||||
|
||||
expect class C3<D, E : D>
|
||||
^
|
||||
compiler/testData/multiplatform/incompatibleClasses/common.kt:18:16: error: expected class 'C4' has no actual declaration in module
|
||||
compiler/testData/multiplatform/incompatibleClasses/common.kt:18:16: error: expected class 'C4' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because upper bounds of type parameters are different:
|
||||
public actual typealias C4<F> = C4Impl<F>
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ Output:
|
||||
-- JVM --
|
||||
Exit code: COMPILATION_ERROR
|
||||
Output:
|
||||
compiler/testData/multiplatform/missingOverload/common.kt:7:13: error: expected function 'g' has no actual declaration in module
|
||||
compiler/testData/multiplatform/missingOverload/common.kt:7:13: error: expected function 'g' has no actual declaration in module for JVM
|
||||
The following declaration is incompatible because parameter types are different:
|
||||
public actual fun g(a: Any): Unit
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ fun useInSignature(a: A) = a.toString()
|
||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:9:1: error: this annotation is not applicable to target 'class'
|
||||
@OptionalExpectation
|
||||
^
|
||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:10:14: error: expected class 'NotAnAnnotationClass' has no actual declaration in module
|
||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:10:14: error: expected class 'NotAnAnnotationClass' has no actual declaration in module for JVM
|
||||
expect class NotAnAnnotationClass
|
||||
^
|
||||
compiler/testData/multiplatform/optionalExpectationIncorrectUse/common.kt:12:1: error: '@OptionalExpectation' can only be used on an expected annotation class
|
||||
|
||||
@@ -471,6 +471,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/ProjectionsInSupertypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("properDefaultInitializationInTailrec.kt")
|
||||
public void testProperDefaultInitializationInTailrec() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/properDefaultInitializationInTailrec.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Properties.kt")
|
||||
public void testProperties() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/Properties.kt");
|
||||
@@ -611,6 +616,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/SyntaxErrorInTestHighlightingEof.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOnVirtualMember.kt")
|
||||
public void testTailRecOnVirtualMember() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOnVirtualMember.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOnVirtualMemberError.kt")
|
||||
public void testTailRecOnVirtualMemberError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOnVirtualMemberError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOverridden.kt")
|
||||
public void testTailRecOverridden() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOverridden.kt");
|
||||
@@ -681,6 +696,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/diagnostics/tests/UnitValue.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unproperDefaultInitializationInTailrec.kt")
|
||||
public void testUnproperDefaultInitializationInTailrec() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/unproperDefaultInitializationInTailrec.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Unresolved.kt")
|
||||
public void testUnresolved() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/Unresolved.kt");
|
||||
@@ -24004,6 +24024,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/defaultArgsWithSideEffects2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArgsWithSideEffectsOld.kt")
|
||||
public void testDefaultArgsWithSideEffectsOld() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/defaultArgsWithSideEffectsOld.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionTailCall.kt")
|
||||
public void testExtensionTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/extensionTailCall.kt");
|
||||
|
||||
@@ -471,6 +471,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/ProjectionsInSupertypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("properDefaultInitializationInTailrec.kt")
|
||||
public void testProperDefaultInitializationInTailrec() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/properDefaultInitializationInTailrec.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Properties.kt")
|
||||
public void testProperties() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/Properties.kt");
|
||||
@@ -611,6 +616,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/SyntaxErrorInTestHighlightingEof.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOnVirtualMember.kt")
|
||||
public void testTailRecOnVirtualMember() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOnVirtualMember.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOnVirtualMemberError.kt")
|
||||
public void testTailRecOnVirtualMemberError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOnVirtualMemberError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("tailRecOverridden.kt")
|
||||
public void testTailRecOverridden() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/tailRecOverridden.kt");
|
||||
@@ -681,6 +696,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/diagnostics/tests/UnitValue.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unproperDefaultInitializationInTailrec.kt")
|
||||
public void testUnproperDefaultInitializationInTailrec() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/unproperDefaultInitializationInTailrec.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Unresolved.kt")
|
||||
public void testUnresolved() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/Unresolved.kt");
|
||||
@@ -23924,6 +23944,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/defaultArgsWithSideEffects2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArgsWithSideEffectsOld.kt")
|
||||
public void testDefaultArgsWithSideEffectsOld() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/defaultArgsWithSideEffectsOld.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionTailCall.kt")
|
||||
public void testExtensionTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/extensionTailCall.kt");
|
||||
|
||||
@@ -4453,6 +4453,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/collections/removeAtInt.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("removeClash.kt")
|
||||
public void testRemoveClash() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/collections/removeClash.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("strList.kt")
|
||||
public void testStrList() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/collections/strList.kt");
|
||||
@@ -8399,6 +8404,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/tailCallOptimizations/tryCatch.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("unitFunReturnsNonUnit.kt")
|
||||
public void testUnitFunReturnsNonUnit() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnit.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unitFunReturnsNonUnitCallSuspend.kt")
|
||||
public void testUnitFunReturnsNonUnitCallSuspend() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unitFunReturnsNonUnitCallSuspend.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unreachable.kt")
|
||||
public void testUnreachable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/unreachable.kt");
|
||||
@@ -9998,6 +10013,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/defaultArgsWithSideEffects2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArgsWithSideEffectsOld.kt")
|
||||
public void testDefaultArgsWithSideEffectsOld() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/defaultArgsWithSideEffectsOld.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionTailCall.kt")
|
||||
public void testExtensionTailCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/diagnostics/functions/tailRecursion/extensionTailCall.kt");
|
||||
@@ -11483,6 +11503,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/functions/functionExpression/functionLiteralExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("insideGenericLambda.kt")
|
||||
public void testInsideGenericLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/functions/functionExpression/insideGenericLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreParameters.kt")
|
||||
public void testUnderscoreParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/functions/functionExpression/underscoreParameters.kt");
|
||||
@@ -12750,6 +12775,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt28920_javaPrimitiveType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt34268.kt")
|
||||
public void testKt34268() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/kt34268.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mangledDefaultParameterFunction.kt")
|
||||
public void testMangledDefaultParameterFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/mangledDefaultParameterFunction.kt");
|
||||
@@ -17454,6 +17484,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/platformTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||
}
|
||||
|
||||
@TestMetadata("unsafeNullCheck.kt")
|
||||
public void testUnsafeNullCheck() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheck.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unsafeNullCheckWithPrimitive.kt")
|
||||
public void testUnsafeNullCheckWithPrimitive() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/platformTypes/unsafeNullCheckWithPrimitive.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/platformTypes/primitives")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -18303,6 +18343,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/properties/genericPropertyMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("initOrderMultiModule.kt")
|
||||
public void testInitOrderMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/initOrderMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaPropertyBoxedGetter.kt")
|
||||
public void testJavaPropertyBoxedGetter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/javaPropertyBoxedGetter.kt");
|
||||
@@ -18513,6 +18558,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/properties/protectedJavaPropertyInCompanion.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sideEffectInTopLevelInitializerMultiModule.kt")
|
||||
public void testSideEffectInTopLevelInitializerMultiModule() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/sideEffectInTopLevelInitializerMultiModule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("substituteJavaSuperField.kt")
|
||||
public void testSubstituteJavaSuperField() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/properties/substituteJavaSuperField.kt");
|
||||
@@ -19949,6 +19999,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/ranges/unsigned/inMixedUnsignedRange.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt35004.kt")
|
||||
public void testKt35004() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/unsigned/kt35004.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/ranges/unsigned/expression")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -22997,6 +23052,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/regressions/kt2318.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt24913.kt")
|
||||
public void testKt24913() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/regressions/kt24913.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("Kt2495Test.kt")
|
||||
public void testKt2495Test() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/regressions/Kt2495Test.kt");
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user