From f36438dee29c7468c4011ba30c26bf00db9f1c12 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 29 Sep 2011 21:34:39 +0400 Subject: [PATCH] Type checking for default values --- .../lang/descriptors/MutableClassDescriptor.java | 2 +- .../jetbrains/jet/lang/psi/JetConstructor.java | 3 ++- .../jet/lang/psi/JetDeclarationWithBody.java | 8 +++++++- .../lang/psi/JetFunctionLiteralExpression.java | 10 ++++++++-- .../jet/lang/psi/JetPropertyAccessor.java | 11 +++++++++++ .../jetbrains/jet/lang/resolve/BodyResolver.java | 15 ++++++++++++++- .../jet/lang/resolve/ClassDescriptorResolver.java | 2 +- .../org/jetbrains/jet/lang/types/CallMaker.java | 2 +- .../quick/DefaultValuesTypechecking.jet | 5 +++++ .../quick/NamedArgumentsAndDefaultValues.jet | 2 +- 10 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 idea/testData/checkerWithErrorTypes/quick/DefaultValuesTypechecking.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java index 2400cad6510..d9a993b4155 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/MutableClassDescriptor.java @@ -85,7 +85,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme public void addConstructor(@NotNull ConstructorDescriptor constructorDescriptor) { assert constructorDescriptor.getContainingDeclaration() == this; -// assert constructorDescriptor.getTypeParameters().size() == getTypeConstructor().getParameters().size(); +// assert constructorDescriptor.getTypeParameters().size() == getTypeConstructor().getValueParameters().size(); constructors.add(constructorDescriptor); if (defaultType != null) { // constructorDescriptor.getTypeParameters().addAll(typeParameters); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstructor.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstructor.java index bc53af61e4b..0971e9553a6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstructor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstructor.java @@ -32,8 +32,9 @@ public class JetConstructor extends JetDeclaration implements JetDeclarationWith return (JetParameterList) findChildByType(JetNodeTypes.VALUE_PARAMETER_LIST); } + @Override @NotNull - public List getParameters() { + public List getValueParameters() { JetParameterList list = getParameterList(); return list != null ? list.getParameters() : Collections.emptyList(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDeclarationWithBody.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDeclarationWithBody.java index 2cd3c48b0db..115a953a9d0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDeclarationWithBody.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDeclarationWithBody.java @@ -1,12 +1,15 @@ package org.jetbrains.jet.lang.psi; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; + /** * @author abreslav */ -public interface JetDeclarationWithBody { +public interface JetDeclarationWithBody extends PsiElement { @Nullable JetExpression getBodyExpression(); @@ -20,5 +23,8 @@ public interface JetDeclarationWithBody { @NotNull JetElement asElement(); + + @NotNull + List getValueParameters(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionLiteralExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionLiteralExpression.java index 070bf524ff3..efed8a90e56 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionLiteralExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionLiteralExpression.java @@ -2,9 +2,9 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; -import org.jetbrains.jet.lexer.JetTokens; + +import java.util.List; /** * @author max @@ -29,6 +29,12 @@ public class JetFunctionLiteralExpression extends JetExpression implements JetDe return (JetFunctionLiteral) findChildByType(JetNodeTypes.FUNCTION_LITERAL); } + @NotNull + @Override + public List getValueParameters() { + return getFunctionLiteral().getValueParameters(); + } + @Override public JetBlockExpression getBodyExpression() { return getFunctionLiteral().getBodyExpression(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java index 0b9154333f2..a1aa5e418c9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lexer.JetTokens; +import java.util.Collections; import java.util.List; /** @@ -44,6 +45,16 @@ public class JetPropertyAccessor extends JetDeclaration implements JetFunctionOr return parameters.get(0); } + @NotNull + @Override + public List getValueParameters() { + JetParameter parameter = getParameter(); + if (parameter == null) { + return Collections.emptyList(); + } + return Collections.singletonList(parameter); + } + @Nullable @Override public JetExpression getBodyExpression() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index c38be41fffb..c8255af2f9d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -549,8 +549,8 @@ public class BodyResolver { @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, @NotNull JetScope declaringScope) { - JetExpression bodyExpression = function.getBodyExpression(); + JetExpression bodyExpression = function.getBodyExpression(); if (bodyExpression != null) { JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(function.asElement(), bodyExpression); JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace, flowInformationProvider); @@ -558,6 +558,19 @@ public class BodyResolver { typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor); } + JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace, JetFlowInformationProvider.THROW_EXCEPTION); + List valueParameters = function.getValueParameters(); + for (int i = 0; i < valueParameters.size(); i++) { + ValueParameterDescriptor valueParameterDescriptor = functionDescriptor.getValueParameters().get(i); + if (valueParameterDescriptor.hasDefaultValue()) { + JetParameter jetParameter = valueParameters.get(i); + JetExpression defaultValue = jetParameter.getDefaultValue(); + if (defaultValue != null) { + typeInferrer.getType(declaringScope, defaultValue, valueParameterDescriptor.getOutType()); + } + } + } + assert functionDescriptor.getReturnType() != null; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index baf401bde60..1672a1329c8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -692,7 +692,7 @@ public class ClassDescriptorResolver { @NotNull public ConstructorDescriptorImpl resolveSecondaryConstructorDescriptor(@NotNull JetScope scope, @NotNull ClassDescriptor classDescriptor, @NotNull JetConstructor constructor) { - return createConstructorDescriptor(scope, classDescriptor, false, constructor.getModifierList(), constructor, classDescriptor.getTypeConstructor().getParameters(), constructor.getParameters()); + return createConstructorDescriptor(scope, classDescriptor, false, constructor.getModifierList(), constructor, classDescriptor.getTypeConstructor().getParameters(), constructor.getValueParameters()); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/CallMaker.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/CallMaker.java index 16fa5949118..8da61d725d0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/CallMaker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/CallMaker.java @@ -17,8 +17,8 @@ public class CallMaker { private static class ExpressionValueArgument implements ValueArgument { private final JetExpression expression; - private final PsiElement reportErrorsOn; + private ExpressionValueArgument(@NotNull JetExpression expression) { this(expression, expression); } diff --git a/idea/testData/checkerWithErrorTypes/quick/DefaultValuesTypechecking.jet b/idea/testData/checkerWithErrorTypes/quick/DefaultValuesTypechecking.jet new file mode 100644 index 00000000000..55df425bc64 --- /dev/null +++ b/idea/testData/checkerWithErrorTypes/quick/DefaultValuesTypechecking.jet @@ -0,0 +1,5 @@ +val x = "" + +fun bar(x : Int = "", y : Int = x, z : String = y) { + +} diff --git a/idea/testData/checkerWithErrorTypes/quick/NamedArgumentsAndDefaultValues.jet b/idea/testData/checkerWithErrorTypes/quick/NamedArgumentsAndDefaultValues.jet index b4ef3f1e47c..9e75a3ae821 100644 --- a/idea/testData/checkerWithErrorTypes/quick/NamedArgumentsAndDefaultValues.jet +++ b/idea/testData/checkerWithErrorTypes/quick/NamedArgumentsAndDefaultValues.jet @@ -1,7 +1,7 @@ fun foo(a : Int = 1, b : String = "abc") { } -fun bar(x : Int = "", y : Int = 1, z : String) { +fun bar(x : Int = 1, y : Int = 1, z : String) { } fun test() {