From 671b8913edeaefae1f6941cc69c3209c3b69bddb Mon Sep 17 00:00:00 2001 From: svtk Date: Fri, 5 Aug 2011 17:43:32 +0400 Subject: [PATCH] frontend bugs fixed: fun f(): Int = "s" //was ok fun g(): Int { if (1 < 2) {} else {} }//was ok fun h(): Int { val a = 1 } //was ok --- .../jet/lang/cfg/JetControlFlowProcessor.java | 19 ++++++++++----- .../jetbrains/jet/lang/psi/JetVisitor.java | 2 +- .../jet/lang/types/JetTypeInferrer.java | 11 +++++++-- idea/testData/checker/FunctionReturnTypes.jet | 23 +++++++++++++++++-- idea/testData/checker/regression/Jet121.jet | 2 +- idea/testData/checker/regression/Jet183.jet | 2 +- .../jet/codegen/NamespaceGenTest.java | 2 +- 7 files changed, 47 insertions(+), 14 deletions(-) diff --git a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java index a9cee63c9e7..ddc6c990727 100644 --- a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java +++ b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java @@ -502,13 +502,20 @@ public class JetControlFlowProcessor { @Override public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); - if (preferBlock && !functionLiteral.hasParameterSpecification()) { - for (JetElement statement : functionLiteral.getBodyExpression().getStatements()) { - value(statement, true, false); + JetBlockExpression bodyExpression = expression.getFunctionLiteral().getBodyExpression(); + if (bodyExpression != null) { + List statements = bodyExpression.getStatements(); + if (preferBlock && !functionLiteral.hasParameterSpecification()) { + for (JetElement statement : statements) { + value(statement, true, false); + } + if (statements.isEmpty()) { + builder.readUnit(expression); + } + } + else { + generateSubroutineControlFlow(expression, statements, true); } - } - else { - generateSubroutineControlFlow(expression, functionLiteral.getBodyExpression().getStatements(), true); } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java index a487d529eb4..161985317ac 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java @@ -11,7 +11,7 @@ public class JetVisitor extends PsiElementVisitor { } public void visitDeclaration(JetDeclaration dcl) { - visitJetElement(dcl); + visitExpression(dcl); } public void visitNamespace(JetNamespace namespace) { diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index ce34b40bd75..662d4c38428 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -381,7 +381,15 @@ public class JetTypeInferrer { public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @Nullable final JetType expectedReturnType) { JetExpression bodyExpression = function.getBodyExpression(); assert bodyExpression != null; - new TypeInferrerVisitor(new TypeInferenceContext(trace, functionInnerScope, function.hasBlockBody(), DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, expectedReturnType)).getType(bodyExpression); + JetType returnedType = new TypeInferrerVisitor(new TypeInferenceContext(trace, functionInnerScope, function.hasBlockBody(), DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, expectedReturnType)).getType(bodyExpression); + + final boolean blockBody = function.hasBlockBody(); + if (!blockBody && expectedReturnType != null && returnedType != null) { + if (!semanticServices.getTypeChecker().isSubtypeOf(returnedType, expectedReturnType)) { + trace.getErrorHandler().typeMismatch(bodyExpression, expectedReturnType, returnedType); + } + } + List unreachableElements = Lists.newArrayList(); flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements); @@ -397,7 +405,6 @@ public class JetTypeInferrer { trace.getErrorHandler().genericError(element.getNode(), "Unreachable code"); } - final boolean blockBody = function.hasBlockBody(); List returnedExpressions = Lists.newArrayList(); flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions); diff --git a/idea/testData/checker/FunctionReturnTypes.jet b/idea/testData/checker/FunctionReturnTypes.jet index e3413d2ce59..26be382443a 100644 --- a/idea/testData/checker/FunctionReturnTypes.jet +++ b/idea/testData/checker/FunctionReturnTypes.jet @@ -23,8 +23,8 @@ fun foo(expr: StringBuilder): Int { fun unitShort() : Unit = () -fun unitShortConv() : Unit = 1 -fun unitShortNull() : Unit = null +fun unitShortConv() : Unit = 1 +fun unitShortNull() : Unit = null fun intEmpty() : Int {} fun intShortInfer() = 1 @@ -33,6 +33,9 @@ fun intShort() : Int = 1 fun intBlock() : Int {return 1} fun intBlock() : Int {1} +fun intString(): Int = "s" +fun intFunctionLiteral(): Int = { 10 } + fun blockReturnUnitMismatch() : Int {return} fun blockReturnValueTypeMismatch() : Int {return 3.4} fun blockReturnValueTypeMatch() : Int {return 1} @@ -109,6 +112,22 @@ fun blockReturnValueTypeMatch() : Int { return 1 else return 1.0 } +fun blockNoReturnIfValDeclaration(): Int { + val x = 1 +} +fun blockNoReturnIfEmptyIf(): Int { + if (1 < 2) {} else {} +} +fun blockNoReturnIfUnitInOneBranch(): Int { + if (1 < 2) { + return 1 + } else { + if (3 < 4) { + } else { + return 2 + } + } +} val a = return 1 diff --git a/idea/testData/checker/regression/Jet121.jet b/idea/testData/checker/regression/Jet121.jet index 72b6d63350e..fc29dfe5293 100644 --- a/idea/testData/checker/regression/Jet121.jet +++ b/idea/testData/checker/regression/Jet121.jet @@ -1,8 +1,8 @@ namespace jet121 { fun box() : String { val answer = apply("OK") { String.() : Int => - length get(0) + length } return if (answer == 2) "OK" else "FAIL" diff --git a/idea/testData/checker/regression/Jet183.jet b/idea/testData/checker/regression/Jet183.jet index 4505e912280..92c5cca572b 100644 --- a/idea/testData/checker/regression/Jet183.jet +++ b/idea/testData/checker/regression/Jet183.jet @@ -17,6 +17,6 @@ enum class Foo { -fun box(): String { +fun box() { val x: ProtocolState = ProtocolState.WAITING } diff --git a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index aaf311351e3..30a934920b6 100644 --- a/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -94,7 +94,7 @@ public class NamespaceGenTest extends CodegenTestCase { } public void testBoxedInt() throws Exception { - loadText("fun foo(a: Int?): Int = if (a != null) a else 239"); + loadText("fun foo(a: Int?) = if (a != null) a else 239"); final Method main = generateFunction(); assertEquals(610, main.invoke(null, 610)); assertEquals(239, main.invoke(null, new Object[]{null}));