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
This commit is contained in:
svtk
2011-08-05 17:43:32 +04:00
parent 7b27ac1766
commit 671b8913ed
7 changed files with 47 additions and 14 deletions
@@ -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<JetElement> 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);
}
}
@@ -11,7 +11,7 @@ public class JetVisitor extends PsiElementVisitor {
}
public void visitDeclaration(JetDeclaration dcl) {
visitJetElement(dcl);
visitExpression(dcl);
}
public void visitNamespace(JetNamespace namespace) {
@@ -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<JetElement> 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<JetExpression> returnedExpressions = Lists.newArrayList();
flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions);
+21 -2
View File
@@ -23,8 +23,8 @@ fun foo(expr: StringBuilder): Int {
fun unitShort() : Unit = ()
fun unitShortConv() : Unit = 1
fun unitShortNull() : Unit = null
fun unitShortConv() : Unit = <error>1</error>
fun unitShortNull() : Unit = <error>null</error>
fun intEmpty() : Int <error>{}</error>
fun intShortInfer() = 1
@@ -33,6 +33,9 @@ fun intShort() : Int = 1
fun intBlock() : Int {return 1}
fun intBlock() : Int {<error>1</error>}
fun intString(): Int = <error>"s"</error>
fun intFunctionLiteral(): Int = <error>{ 10 }</error>
fun blockReturnUnitMismatch() : Int {<error>return</error>}
fun blockReturnValueTypeMismatch() : Int {return <error>3.4</error>}
fun blockReturnValueTypeMatch() : Int {return 1}
@@ -109,6 +112,22 @@ fun blockReturnValueTypeMatch() : Int {
return 1
else return <error>1.0</error>
}
fun blockNoReturnIfValDeclaration(): Int {
<error>val x = 1</error>
}
fun blockNoReturnIfEmptyIf(): Int {
if (1 < 2) <error>{}</error> else <error>{}</error>
}
fun blockNoReturnIfUnitInOneBranch(): Int {
if (1 < 2) {
return 1
} else {
if (3 < 4) <error>{
}</error> else {
return 2
}
}
}
val a = <error>return 1</error>
+1 -1
View File
@@ -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"
+1 -1
View File
@@ -17,6 +17,6 @@ enum class Foo<T> {
fun box(): String {
fun box() {
val x: ProtocolState = ProtocolState.WAITING
}
@@ -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}));