Allow return statements in secondary constructors

This commit is contained in:
Denis Zharkov
2015-03-03 16:36:52 +03:00
parent 80e13d3f70
commit 61ae694be4
4 changed files with 42 additions and 2 deletions
@@ -460,7 +460,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
if (containingFunctionDescriptor != null) {
if (!InlineDescriptorUtils.checkNonLocalReturnUsage(containingFunctionDescriptor, expression, context.trace) ||
containingFunctionDescriptor instanceof ConstructorDescriptor) {
isClassInitializer(containingFunInfo)) {
// Unqualified, in a function literal
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
@@ -504,6 +504,11 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
return DataFlowUtils.checkType(resultType, expression, context, context.dataFlowInfo);
}
private static boolean isClassInitializer(@NotNull Pair<FunctionDescriptor, PsiElement> containingFunInfo) {
return containingFunInfo.getFirst() instanceof ConstructorDescriptor &&
!(containingFunInfo.getSecond() instanceof JetSecondaryConstructor);
}
@Override
public JetTypeInfo visitBreakExpression(@NotNull JetBreakExpression expression, ExpressionTypingContext context) {
LabelResolver.INSTANCE.resolveControlLabel(expression, context);
@@ -523,7 +528,10 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
@NotNull ExpressionTypingContext context
) {
JetType expectedType;
if (function instanceof JetFunction) {
if (function instanceof JetSecondaryConstructor) {
expectedType = KotlinBuiltIns.getInstance().getUnitType();
}
else if (function instanceof JetFunction) {
JetFunction jetFunction = (JetFunction) function;
expectedType = context.trace.get(EXPECTED_RETURN_TYPE, jetFunction);
@@ -0,0 +1,17 @@
class A {
init {
<!RETURN_NOT_ALLOWED!>return<!>
<!RETURN_NOT_ALLOWED!>return 1<!>
}
constructor() {
if (1 == 1) {
return
return <!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>
}
return
return <!TYPE_MISMATCH!>foo()<!>
}
fun foo(): Int = 1
}
@@ -0,0 +1,9 @@
package
internal final class A {
public constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final fun foo(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -10439,6 +10439,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("return.kt")
public void testReturn() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/return.kt");
doTest(fileName);
}
@TestMetadata("superAnyNonEmpty.kt")
public void testSuperAnyNonEmpty() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/secondaryConstructors/superAnyNonEmpty.kt");