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:
@@ -502,13 +502,20 @@ public class JetControlFlowProcessor {
|
|||||||
@Override
|
@Override
|
||||||
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
||||||
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
|
||||||
if (preferBlock && !functionLiteral.hasParameterSpecification()) {
|
JetBlockExpression bodyExpression = expression.getFunctionLiteral().getBodyExpression();
|
||||||
for (JetElement statement : functionLiteral.getBodyExpression().getStatements()) {
|
if (bodyExpression != null) {
|
||||||
value(statement, true, false);
|
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) {
|
public void visitDeclaration(JetDeclaration dcl) {
|
||||||
visitJetElement(dcl);
|
visitExpression(dcl);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitNamespace(JetNamespace namespace) {
|
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) {
|
public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @Nullable final JetType expectedReturnType) {
|
||||||
JetExpression bodyExpression = function.getBodyExpression();
|
JetExpression bodyExpression = function.getBodyExpression();
|
||||||
assert bodyExpression != null;
|
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();
|
List<JetElement> unreachableElements = Lists.newArrayList();
|
||||||
flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements);
|
flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements);
|
||||||
@@ -397,7 +405,6 @@ public class JetTypeInferrer {
|
|||||||
trace.getErrorHandler().genericError(element.getNode(), "Unreachable code");
|
trace.getErrorHandler().genericError(element.getNode(), "Unreachable code");
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean blockBody = function.hasBlockBody();
|
|
||||||
List<JetExpression> returnedExpressions = Lists.newArrayList();
|
List<JetExpression> returnedExpressions = Lists.newArrayList();
|
||||||
flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions);
|
flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions);
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ fun foo(expr: StringBuilder): Int {
|
|||||||
|
|
||||||
|
|
||||||
fun unitShort() : Unit = ()
|
fun unitShort() : Unit = ()
|
||||||
fun unitShortConv() : Unit = 1
|
fun unitShortConv() : Unit = <error>1</error>
|
||||||
fun unitShortNull() : Unit = null
|
fun unitShortNull() : Unit = <error>null</error>
|
||||||
|
|
||||||
fun intEmpty() : Int <error>{}</error>
|
fun intEmpty() : Int <error>{}</error>
|
||||||
fun intShortInfer() = 1
|
fun intShortInfer() = 1
|
||||||
@@ -33,6 +33,9 @@ fun intShort() : Int = 1
|
|||||||
fun intBlock() : Int {return 1}
|
fun intBlock() : Int {return 1}
|
||||||
fun intBlock() : Int {<error>1</error>}
|
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 blockReturnUnitMismatch() : Int {<error>return</error>}
|
||||||
fun blockReturnValueTypeMismatch() : Int {return <error>3.4</error>}
|
fun blockReturnValueTypeMismatch() : Int {return <error>3.4</error>}
|
||||||
fun blockReturnValueTypeMatch() : Int {return 1}
|
fun blockReturnValueTypeMatch() : Int {return 1}
|
||||||
@@ -109,6 +112,22 @@ fun blockReturnValueTypeMatch() : Int {
|
|||||||
return 1
|
return 1
|
||||||
else return <error>1.0</error>
|
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>
|
val a = <error>return 1</error>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
namespace jet121 {
|
namespace jet121 {
|
||||||
fun box() : String {
|
fun box() : String {
|
||||||
val answer = apply("OK") { String.() : Int =>
|
val answer = apply("OK") { String.() : Int =>
|
||||||
length
|
|
||||||
get(0)
|
get(0)
|
||||||
|
length
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (answer == 2) "OK" else "FAIL"
|
return if (answer == 2) "OK" else "FAIL"
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ enum class Foo<T> {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box() {
|
||||||
val x: ProtocolState = ProtocolState.WAITING
|
val x: ProtocolState = ProtocolState.WAITING
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class NamespaceGenTest extends CodegenTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testBoxedInt() throws Exception {
|
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();
|
final Method main = generateFunction();
|
||||||
assertEquals(610, main.invoke(null, 610));
|
assertEquals(610, main.invoke(null, 610));
|
||||||
assertEquals(239, main.invoke(null, new Object[]{null}));
|
assertEquals(239, main.invoke(null, new Object[]{null}));
|
||||||
|
|||||||
Reference in New Issue
Block a user