Error on 'if' without an 'else' branch when used as an expression
This commit is contained in:
@@ -27,7 +27,9 @@ public object SystemOutLogger : Logger {
|
|||||||
private fun out(level: String, msg: CharSequence) = println("[$level] $msg")
|
private fun out(level: String, msg: CharSequence) = println("[$level] $msg")
|
||||||
|
|
||||||
public var isDebugEnabled: Boolean = true
|
public var isDebugEnabled: Boolean = true
|
||||||
override fun debug(msg: CharSequence) = if (isDebugEnabled) out("DEBUG", msg)
|
override fun debug(msg: CharSequence) {
|
||||||
|
if (isDebugEnabled) out("DEBUG", msg)
|
||||||
|
}
|
||||||
override fun info(msg: CharSequence) = out("INFO", msg)
|
override fun info(msg: CharSequence) = out("INFO", msg)
|
||||||
override fun warn(msg: CharSequence) = out("WARN", msg)
|
override fun warn(msg: CharSequence) = out("WARN", msg)
|
||||||
override fun error(msg: CharSequence) = out("ERROR", msg)
|
override fun error(msg: CharSequence) = out("ERROR", msg)
|
||||||
|
|||||||
@@ -610,6 +610,8 @@ public interface Errors {
|
|||||||
|
|
||||||
DiagnosticFactory0<JetElement> SENSELESS_NULL_IN_WHEN = DiagnosticFactory0.create(WARNING);
|
DiagnosticFactory0<JetElement> SENSELESS_NULL_IN_WHEN = DiagnosticFactory0.create(WARNING);
|
||||||
|
|
||||||
|
DiagnosticFactory0<JetIfExpression> INVALID_IF_AS_EXPRESSION = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
// Nullability
|
// Nullability
|
||||||
|
|
||||||
DiagnosticFactory1<PsiElement, JetType> UNSAFE_CALL = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, JetType> UNSAFE_CALL = DiagnosticFactory1.create(ERROR);
|
||||||
|
|||||||
+2
@@ -537,6 +537,8 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(SENSELESS_COMPARISON, "Condition ''{0}'' is always ''{1}''", ELEMENT_TEXT, TO_STRING);
|
MAP.put(SENSELESS_COMPARISON, "Condition ''{0}'' is always ''{1}''", ELEMENT_TEXT, TO_STRING);
|
||||||
MAP.put(SENSELESS_NULL_IN_WHEN, "Expression under 'when' is never equal to null");
|
MAP.put(SENSELESS_NULL_IN_WHEN, "Expression under 'when' is never equal to null");
|
||||||
|
|
||||||
|
MAP.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression");
|
||||||
|
|
||||||
MAP.put(OVERRIDING_FINAL_MEMBER, "''{0}'' in ''{1}'' is final and cannot be overridden", NAME, NAME);
|
MAP.put(OVERRIDING_FINAL_MEMBER, "''{0}'' in ''{1}'' is final and cannot be overridden", NAME, NAME);
|
||||||
MAP.put(CANNOT_WEAKEN_ACCESS_PRIVILEGE, "Cannot weaken access privilege ''{0}'' for ''{1}'' in ''{2}''", TO_STRING, NAME, NAME);
|
MAP.put(CANNOT_WEAKEN_ACCESS_PRIVILEGE, "Cannot weaken access privilege ''{0}'' for ''{1}'' in ''{2}''", TO_STRING, NAME, NAME);
|
||||||
MAP.put(CANNOT_CHANGE_ACCESS_PRIVILEGE, "Cannot change access privilege ''{0}'' for ''{1}'' in ''{2}''", TO_STRING, NAME, NAME);
|
MAP.put(CANNOT_CHANGE_ACCESS_PRIVILEGE, "Cannot change access privilege ''{0}'' for ''{1}'' in ''{2}''", TO_STRING, NAME, NAME);
|
||||||
|
|||||||
@@ -504,8 +504,11 @@ public class CandidateResolver(
|
|||||||
private fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.shouldContinue() =
|
private fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.shouldContinue() =
|
||||||
candidateResolveMode == CandidateResolveMode.FULLY || candidateCall.getStatus().possibleTransformToSuccess()
|
candidateResolveMode == CandidateResolveMode.FULLY || candidateCall.getStatus().possibleTransformToSuccess()
|
||||||
|
|
||||||
private inline fun <D : CallableDescriptor> CallCandidateResolutionContext<D>
|
private inline fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.check(
|
||||||
.check(checker: CallCandidateResolutionContext<D>.() -> Unit): Unit = if (shouldContinue()) checker()
|
checker: CallCandidateResolutionContext<D>.() -> Unit
|
||||||
|
) {
|
||||||
|
if (shouldContinue()) checker()
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.
|
private inline fun <D : CallableDescriptor> CallCandidateResolutionContext<D>.
|
||||||
checkAndReport(checker: CallCandidateResolutionContext<D>.() -> ResolutionStatus) {
|
checkAndReport(checker: CallCandidateResolutionContext<D>.() -> ResolutionStatus) {
|
||||||
|
|||||||
@@ -256,10 +256,21 @@ public class DataFlowAnalyzer {
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public JetType checkImplicitCast(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context, boolean isStatement) {
|
public JetType checkImplicitCast(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context, boolean isStatement) {
|
||||||
if (expressionType != null && context.expectedType == NO_EXPECTED_TYPE && context.contextDependency == INDEPENDENT && !isStatement
|
boolean isIfExpression = expression instanceof JetIfExpression;
|
||||||
|
if (expressionType != null && (context.expectedType == NO_EXPECTED_TYPE || isIfExpression)
|
||||||
|
&& context.contextDependency == INDEPENDENT && !isStatement
|
||||||
&& (KotlinBuiltIns.isUnit(expressionType) || KotlinBuiltIns.isAnyOrNullableAny(expressionType))
|
&& (KotlinBuiltIns.isUnit(expressionType) || KotlinBuiltIns.isAnyOrNullableAny(expressionType))
|
||||||
&& !DynamicTypesKt.isDynamic(expressionType)) {
|
&& !DynamicTypesKt.isDynamic(expressionType)) {
|
||||||
context.trace.report(IMPLICIT_CAST_TO_UNIT_OR_ANY.on(expression, expressionType));
|
if (isIfExpression && KotlinBuiltIns.isUnit(expressionType)) {
|
||||||
|
JetIfExpression ifExpression = (JetIfExpression) expression;
|
||||||
|
if (ifExpression.getThen() == null || ifExpression.getElse() == null) {
|
||||||
|
context.trace.report(INVALID_IF_AS_EXPRESSION.on((JetIfExpression) expression));
|
||||||
|
return expressionType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
context.trace.report(IMPLICIT_CAST_TO_UNIT_OR_ANY.on(expression, expressionType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return expressionType;
|
return expressionType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
fun box(): String {
|
|
||||||
if (true);
|
|
||||||
if (false);
|
|
||||||
val iftrue = if (true);
|
|
||||||
val iffalse = if (false);
|
|
||||||
|
|
||||||
var state = 0
|
|
||||||
val k = if (state++==1);
|
|
||||||
if (state != 1) return "Fail: $state"
|
|
||||||
|
|
||||||
return "OK"
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
fun box(): String {
|
|
||||||
val a = if(true) {
|
|
||||||
}
|
|
||||||
return if (a.toString() == "kotlin.Unit") "OK" else "fail"
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
fun foo(condition: Boolean): String {
|
|
||||||
val u = if (condition) {
|
|
||||||
"OK"
|
|
||||||
} else {
|
|
||||||
}
|
|
||||||
return u.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun box() = foo(true)
|
|
||||||
+7
-2
@@ -1,5 +1,10 @@
|
|||||||
fun unsupportedEx() = if (true) throw UnsupportedOperationException()
|
fun unsupportedEx() {
|
||||||
fun runtimeEx() = if (true) throw RuntimeException()
|
if (true) throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runtimeEx() {
|
||||||
|
if (true) throw RuntimeException()
|
||||||
|
}
|
||||||
|
|
||||||
fun test1() : String {
|
fun test1() : String {
|
||||||
var s = "";
|
var s = "";
|
||||||
|
|||||||
+7
-2
@@ -1,5 +1,10 @@
|
|||||||
fun unsupportedEx() = if (true) throw UnsupportedOperationException()
|
fun unsupportedEx() {
|
||||||
fun runtimeEx() = if (true) throw RuntimeException()
|
if (true) throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runtimeEx() {
|
||||||
|
if (true) throw RuntimeException()
|
||||||
|
}
|
||||||
|
|
||||||
fun test1WithFinally() : String {
|
fun test1WithFinally() : String {
|
||||||
var s = "";
|
var s = "";
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
// This test checks that our bytecode is consistent with javac bytecode
|
// This test checks that our bytecode is consistent with javac bytecode
|
||||||
|
|
||||||
fun _assert(condition: Boolean): Unit =
|
fun _assert(condition: Boolean) {
|
||||||
if (!condition) throw AssertionError("Fail")
|
if (!condition) throw AssertionError("Fail")
|
||||||
|
}
|
||||||
|
|
||||||
fun _assertFalse(condition: Boolean) = _assert(!condition)
|
fun _assertFalse(condition: Boolean) = _assert(!condition)
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -4,9 +4,9 @@ class A (val p: String, p1: String, p2: String) {
|
|||||||
|
|
||||||
var cond2: String = ""
|
var cond2: String = ""
|
||||||
|
|
||||||
val prop1 = if (cond1(p)) p1
|
val prop1 = if (cond1(p)) p1 else null
|
||||||
|
|
||||||
val prop2 = if (cond2(p)) else;
|
val prop2 = if (cond2(p)) p2 else null;
|
||||||
|
|
||||||
|
|
||||||
fun cond1(p: String): Boolean {
|
fun cond1(p: String): Boolean {
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ class A (val p: String, p1: String, p2: String) {
|
|||||||
|
|
||||||
val prop: String = if (p == "test") p1 else p2
|
val prop: String = if (p == "test") p1 else p2
|
||||||
|
|
||||||
val prop1 = if (cond1(p)) p1
|
val prop1 = if (cond1(p)) p1 else false
|
||||||
|
|
||||||
val prop2 = if (cond2(p)) else;
|
val prop2 = if (cond2(p)) true else false
|
||||||
|
|
||||||
fun cond1(p: String): Boolean {
|
fun cond1(p: String): Boolean {
|
||||||
cond1 = "cond1"
|
cond1 = "cond1"
|
||||||
|
|||||||
@@ -69,10 +69,10 @@ fun blockReturnValueTypeMatch1() : Int {
|
|||||||
return if (1 > 2) <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> else <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2.0<!>
|
return if (1 > 2) <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1.0<!> else <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2.0<!>
|
||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch2() : Int {
|
fun blockReturnValueTypeMatch2() : Int {
|
||||||
return <!TYPE_MISMATCH!>if (1 > 2) 1<!>
|
return <!TYPE_MISMATCH, INVALID_IF_AS_EXPRESSION!>if (1 > 2) 1<!>
|
||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch3() : Int {
|
fun blockReturnValueTypeMatch3() : Int {
|
||||||
return <!TYPE_MISMATCH!>if (1 > 2) else 1<!>
|
return <!TYPE_MISMATCH, INVALID_IF_AS_EXPRESSION!>if (1 > 2) else 1<!>
|
||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch4() : Int {
|
fun blockReturnValueTypeMatch4() : Int {
|
||||||
if (1 > 2)
|
if (1 > 2)
|
||||||
@@ -105,7 +105,7 @@ fun blockReturnValueTypeMatch9() : Int {
|
|||||||
<!UNUSED_EXPRESSION!>1.0<!>
|
<!UNUSED_EXPRESSION!>1.0<!>
|
||||||
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
|
||||||
fun blockReturnValueTypeMatch10() : Int {
|
fun blockReturnValueTypeMatch10() : Int {
|
||||||
return <!TYPE_MISMATCH!>if (1 > 2)
|
return <!TYPE_MISMATCH, INVALID_IF_AS_EXPRESSION!>if (1 > 2)
|
||||||
1<!>
|
1<!>
|
||||||
}
|
}
|
||||||
fun blockReturnValueTypeMatch11() : Int {
|
fun blockReturnValueTypeMatch11() : Int {
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ fun test() {
|
|||||||
if (false);
|
if (false);
|
||||||
if (true);
|
if (true);
|
||||||
|
|
||||||
val x = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!>if (false)<!>;
|
val x = <!INVALID_IF_AS_EXPRESSION!>if (false)<!>;
|
||||||
foo(x)
|
foo(x)
|
||||||
|
|
||||||
val y: Unit = if (false);
|
val y: Unit = <!INVALID_IF_AS_EXPRESSION!>if (false)<!>;
|
||||||
foo(y)
|
foo(y)
|
||||||
|
|
||||||
foo({if (1==1);}())
|
foo({if (1==1);}())
|
||||||
|
|
||||||
return if (true);
|
return <!INVALID_IF_AS_EXPRESSION!>if (true)<!>;
|
||||||
}
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
|
|
||||||
|
fun example() {
|
||||||
|
val a = if (true) true else false
|
||||||
|
val b = <!INVALID_IF_AS_EXPRESSION!>if (true) else false<!>
|
||||||
|
val c = <!INVALID_IF_AS_EXPRESSION!>if (true) true<!>
|
||||||
|
val d = <!INVALID_IF_AS_EXPRESSION!>if (true) true else<!>;
|
||||||
|
val e = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!>if (true) {} else false<!>
|
||||||
|
val f = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!>if (true) true else {}<!>
|
||||||
|
|
||||||
|
{
|
||||||
|
if (true) <!UNUSED_EXPRESSION!>true<!>
|
||||||
|
}();
|
||||||
|
|
||||||
|
{
|
||||||
|
if (true) true else false
|
||||||
|
}();
|
||||||
|
|
||||||
|
{
|
||||||
|
if (true) {} else false
|
||||||
|
}();
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
if (true) true else {}
|
||||||
|
}()
|
||||||
|
|
||||||
|
fun t(): Boolean {
|
||||||
|
return <!TYPE_MISMATCH, INVALID_IF_AS_EXPRESSION!>if (true) true<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (true) <!CONSTANT_EXPECTED_TYPE_MISMATCH!>true<!> else {}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun example(): kotlin.Unit
|
||||||
@@ -7,5 +7,5 @@ fun test(a: Boolean, b: Boolean): Int {
|
|||||||
<!TYPE_MISMATCH!>if (b) {
|
<!TYPE_MISMATCH!>if (b) {
|
||||||
3
|
3
|
||||||
}<!>
|
}<!>
|
||||||
} // no error, but must be
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -34,7 +34,7 @@ fun foo() {
|
|||||||
fun box() : Int {
|
fun box() : Int {
|
||||||
val d = 2
|
val d = 2
|
||||||
var z = 0
|
var z = 0
|
||||||
when(d) {
|
when(d) {
|
||||||
5, 3 -> z++
|
5, 3 -> z++
|
||||||
else -> z = -1000
|
else -> z = -1000
|
||||||
}
|
}
|
||||||
@@ -100,10 +100,10 @@ fun testImplicitCoercion() {
|
|||||||
else -> <!UNUSED_CHANGED_VALUE!>z--<!>
|
else -> <!UNUSED_CHANGED_VALUE!>z--<!>
|
||||||
}<!>
|
}<!>
|
||||||
|
|
||||||
var <!UNUSED_VARIABLE!>iff<!> = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!>if (true) {
|
var <!UNUSED_VARIABLE!>iff<!> = <!INVALID_IF_AS_EXPRESSION!>if (true) {
|
||||||
<!UNUSED_VALUE!>z =<!> 34
|
<!UNUSED_VALUE!>z =<!> 34
|
||||||
}<!>
|
}<!>
|
||||||
val <!UNUSED_VARIABLE!>g<!> = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!>if (true) 4<!>
|
val <!UNUSED_VARIABLE!>g<!> = <!INVALID_IF_AS_EXPRESSION!>if (true) 4<!>
|
||||||
val <!UNUSED_VARIABLE!>h<!> = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!>if (false) 4 else {}<!>
|
val <!UNUSED_VARIABLE!>h<!> = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!>if (false) 4 else {}<!>
|
||||||
|
|
||||||
bar(if (true) {
|
bar(if (true) {
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@ fun f3(s: Number?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun f4(s: Int?) {
|
fun f4(s: Int?) {
|
||||||
var u = <!IMPLICIT_CAST_TO_UNIT_OR_ANY!>if (s!! == 42)<!>;
|
var u = <!INVALID_IF_AS_EXPRESSION!>if (s!! == 42)<!>;
|
||||||
if (u == Unit) u = if (s == 239);
|
if (u == Unit) u = <!INVALID_IF_AS_EXPRESSION!>if (s == 239)<!>;
|
||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
val flag = true
|
val flag = true
|
||||||
|
|
||||||
// type of a was checked by txt
|
// type of a was checked by txt
|
||||||
val a/*: () -> Any*/ = l@ { // commonSupertype(Int, Unit) = Any
|
val a/*: () -> Any*/ = l@ {
|
||||||
if (flag) return@l 4
|
if (flag) return@l 4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-5
@@ -2,10 +2,6 @@ fun foo() {
|
|||||||
if (0 < 1) {
|
if (0 < 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val u: Unit = if (0 < 1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2 3 6 7 6 9
|
// 2 3 5
|
||||||
|
|||||||
@@ -3258,6 +3258,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("improperElseInExpression.kt")
|
||||||
|
public void testImproperElseInExpression() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("jumpAcrossFunctionBoundary.kt")
|
@TestMetadata("jumpAcrossFunctionBoundary.kt")
|
||||||
public void testJumpAcrossFunctionBoundary() throws Exception {
|
public void testJumpAcrossFunctionBoundary() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlStructures/jumpAcrossFunctionBoundary.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlStructures/jumpAcrossFunctionBoundary.kt");
|
||||||
|
|||||||
-18
@@ -2053,12 +2053,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("emptyIf.kt")
|
|
||||||
public void testEmptyIf() throws Exception {
|
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/emptyIf.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("emptyWhile.kt")
|
@TestMetadata("emptyWhile.kt")
|
||||||
public void testEmptyWhile() throws Exception {
|
public void testEmptyWhile() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/emptyWhile.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/emptyWhile.kt");
|
||||||
@@ -2149,12 +2143,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("kt2062.kt")
|
|
||||||
public void testKt2062() throws Exception {
|
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/kt2062.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("kt2147.kt")
|
@TestMetadata("kt2147.kt")
|
||||||
public void testKt2147() throws Exception {
|
public void testKt2147() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/kt2147.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/kt2147.kt");
|
||||||
@@ -2197,12 +2185,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("kt2598.kt")
|
|
||||||
public void testKt2598() throws Exception {
|
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/kt2598.kt");
|
|
||||||
doTest(fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
@TestMetadata("kt299.kt")
|
@TestMetadata("kt299.kt")
|
||||||
public void testKt299() throws Exception {
|
public void testKt299() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/kt299.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/kt299.kt");
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ import org.jetbrains.kotlin.generators.builtins.ranges.GenerateRanges
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
|
|
||||||
fun assertExists(file: File): Unit =
|
fun assertExists(file: File) {
|
||||||
if (!file.exists()) error("Output dir does not exist: ${file.getAbsolutePath()}")
|
if (!file.exists()) error("Output dir does not exist: ${file.getAbsolutePath()}")
|
||||||
|
}
|
||||||
|
|
||||||
val BUILT_INS_NATIVE_DIR = File("core/builtins/native/")
|
val BUILT_INS_NATIVE_DIR = File("core/builtins/native/")
|
||||||
val BUILT_INS_SRC_DIR = File("core/builtins/src/")
|
val BUILT_INS_SRC_DIR = File("core/builtins/src/")
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// IS_APPLICABLE: false
|
// IS_APPLICABLE: false
|
||||||
|
// ERROR: 'if' must have both main and 'else' branches if used as an expression
|
||||||
// ERROR: Expression 'if "test" is String' of type 'kotlin.Unit' cannot be invoked as a function. The function invoke() is not found
|
// ERROR: Expression 'if "test" is String' of type 'kotlin.Unit' cannot be invoked as a function. The function invoke() is not found
|
||||||
|
|
||||||
fun doSomething<T>(a: T) {}
|
fun doSomething<T>(a: T) {}
|
||||||
|
|||||||
@@ -320,7 +320,9 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
|
|||||||
val compilerServices = Services.Builder()
|
val compilerServices = Services.Builder()
|
||||||
.register(javaClass<IncrementalCompilationComponents>(), IncrementalCompilationComponentsImpl(incrementalCaches, lookupTracker))
|
.register(javaClass<IncrementalCompilationComponents>(), IncrementalCompilationComponentsImpl(incrementalCaches, lookupTracker))
|
||||||
.register(javaClass<CompilationCanceledStatus>(), object : CompilationCanceledStatus {
|
.register(javaClass<CompilationCanceledStatus>(), object : CompilationCanceledStatus {
|
||||||
override fun checkCanceled(): Unit = if (context.getCancelStatus().isCanceled()) throw CompilationCanceledException()
|
override fun checkCanceled() {
|
||||||
|
if (context.getCancelStatus().isCanceled()) throw CompilationCanceledException()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
|||||||
@@ -42,19 +42,20 @@ public fun parseFunction(code: String, offset: Int, reporter: ErrorReporter, sco
|
|||||||
private class FunctionParsingObserver : Observer {
|
private class FunctionParsingObserver : Observer {
|
||||||
var functionsStarted = 0
|
var functionsStarted = 0
|
||||||
|
|
||||||
override fun update(o: Observable?, arg: Any?): Unit =
|
override fun update(o: Observable?, arg: Any?) {
|
||||||
when (arg) {
|
when (arg) {
|
||||||
is ParserEvents.OnFunctionParsingStart -> {
|
is ParserEvents.OnFunctionParsingStart -> {
|
||||||
functionsStarted++
|
functionsStarted++
|
||||||
}
|
}
|
||||||
is ParserEvents.OnFunctionParsingEnd -> {
|
is ParserEvents.OnFunctionParsingEnd -> {
|
||||||
functionsStarted--
|
functionsStarted--
|
||||||
|
|
||||||
if (functionsStarted == 0) {
|
if (functionsStarted == 0) {
|
||||||
arg.tokenStream.ungetToken(TokenStream.EOF)
|
arg.tokenStream.ungetToken(TokenStream.EOF)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ fun bar(s: String, value: Boolean): Boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val a = if (true || if(bar("A", false)) {2} else {3} == 0) { }
|
val a = if (true || if(bar("A", false)) {2} else {3} == 0) true else false
|
||||||
assertEquals("", global)
|
assertEquals("", global)
|
||||||
|
|
||||||
true || if(bar("A", false)) {2} else {3} == 0
|
true || if(bar("A", false)) {2} else {3} == 0
|
||||||
|
|||||||
Reference in New Issue
Block a user