JET-113 Check returns in secondary constructors
This commit is contained in:
@@ -11,6 +11,7 @@ import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.JetTypeInferrer;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -727,7 +728,7 @@ public class TopDownAnalyzer {
|
||||
JetFlowInformationProvider flowInformationProvider = classDescriptorResolver.computeFlowData(declaration, bodyExpression);
|
||||
JetTypeInferrer typeInferrer = semanticServices.getTypeInferrer(traceForConstructors, flowInformationProvider);
|
||||
|
||||
typeInferrer.getType(functionInnerScope, bodyExpression, true, null);
|
||||
typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, descriptor, JetStandardClasses.getUnitType());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -308,9 +308,44 @@ public class JetTypeInferrer {
|
||||
|
||||
public void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) {
|
||||
final JetType expectedReturnType = functionDescriptor.getUnsubstitutedReturnType();
|
||||
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);
|
||||
checkFunctionReturnType(functionInnerScope, function, functionDescriptor, expectedReturnType);
|
||||
// Map<JetElement, JetType> typeMap = collectReturnedExpressionsWithTypes(outerScope, function, functionDescriptor, expectedReturnType);
|
||||
// if (typeMap.isEmpty()) {
|
||||
// return; // The function returns Nothing
|
||||
// }
|
||||
// for (Map.Entry<JetElement, JetType> entry : typeMap.entrySet()) {
|
||||
// JetType actualType = entry.getValue();
|
||||
// JetElement element = entry.getKey();
|
||||
// JetTypeChecker typeChecker = semanticServices.getTypeChecker();
|
||||
// if (!typeChecker.isSubtypeOf(actualType, expectedReturnType)) {
|
||||
// if (typeChecker.isConvertibleBySpecialConversion(actualType, expectedReturnType)) {
|
||||
// if (expectedReturnType.getConstructor().equals(JetStandardClasses.getUnitType().getConstructor())
|
||||
// && element.getParent() instanceof JetReturnExpression) {
|
||||
// trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type Unit");
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// if (element == function) {
|
||||
// JetExpression bodyExpression = function.getBodyExpression();
|
||||
// assert bodyExpression != null;
|
||||
// trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType);
|
||||
// }
|
||||
// else if (element instanceof JetExpression) {
|
||||
// JetExpression expression = (JetExpression) element;
|
||||
// trace.getErrorHandler().typeMismatch(expression, expectedReturnType, actualType);
|
||||
// }
|
||||
// else {
|
||||
// trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type " + expectedReturnType);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @Nullable final JetType expectedReturnType) {
|
||||
JetExpression bodyExpression = function.getBodyExpression();
|
||||
assert bodyExpression != null;
|
||||
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);
|
||||
new TypeInferrerVisitor(functionInnerScope, function.hasBlockBody(), DataFlowInfo.getEmpty(), null, expectedReturnType).getType(bodyExpression);
|
||||
|
||||
List<JetElement> unreachableElements = Lists.newArrayList();
|
||||
@@ -356,37 +391,6 @@ public class JetTypeInferrer {
|
||||
}
|
||||
});
|
||||
}
|
||||
// Map<JetElement, JetType> typeMap = collectReturnedExpressionsWithTypes(outerScope, function, functionDescriptor, expectedReturnType);
|
||||
// if (typeMap.isEmpty()) {
|
||||
// return; // The function returns Nothing
|
||||
// }
|
||||
// for (Map.Entry<JetElement, JetType> entry : typeMap.entrySet()) {
|
||||
// JetType actualType = entry.getValue();
|
||||
// JetElement element = entry.getKey();
|
||||
// JetTypeChecker typeChecker = semanticServices.getTypeChecker();
|
||||
// if (!typeChecker.isSubtypeOf(actualType, expectedReturnType)) {
|
||||
// if (typeChecker.isConvertibleBySpecialConversion(actualType, expectedReturnType)) {
|
||||
// if (expectedReturnType.getConstructor().equals(JetStandardClasses.getUnitType().getConstructor())
|
||||
// && element.getParent() instanceof JetReturnExpression) {
|
||||
// trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type Unit");
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// if (element == function) {
|
||||
// JetExpression bodyExpression = function.getBodyExpression();
|
||||
// assert bodyExpression != null;
|
||||
// trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType);
|
||||
// }
|
||||
// else if (element instanceof JetExpression) {
|
||||
// JetExpression expression = (JetExpression) element;
|
||||
// trace.getErrorHandler().typeMismatch(expression, expectedReturnType, actualType);
|
||||
// }
|
||||
// else {
|
||||
// trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type " + expectedReturnType);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -110,4 +110,13 @@ fun blockReturnValueTypeMatch() : Int {
|
||||
else return <error>1.0</error>
|
||||
}
|
||||
|
||||
val a = <error>return 1</error>
|
||||
val a = <error>return 1</error>
|
||||
|
||||
class A() {
|
||||
this(a : Int) : this() {
|
||||
if (a == 1)
|
||||
return
|
||||
return <error>1</error>
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user