diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 6f7ebde6deb..a68d3edbb91 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -64,6 +64,7 @@ remove.function.return.type=Remove explicitly specified return type in ''{0}'' f remove.no.name.function.return.type=Remove explicitly specified function return type change.element.type=Change ''{0}'' type to ''{1}'' change.function.parameter.type=Change parameter ''{0}'' type of function ''{1}'' to ''{2}'' +change.primary.constructor.parameter.type=Change parameter ''{0}'' type of primary constructor of class ''{1}'' to ''{2}'' change.type=Change type from ''{0}'' to ''{1}'' change.type.family=Change Type add.parameters.to.function=Add parameter{0} to function ''{1}'' diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java index c7ac17cd164..3027cba79c4 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java @@ -74,12 +74,12 @@ public class ChangeFunctionLiteralReturnTypeFix extends JetIntentionAction { +public class ChangeParameterTypeFix extends JetIntentionAction { private final String renderedType; - private final String containingFunctionName; + private final String containingDeclarationName; + private final boolean isPrimaryConstructorParameter; - public ChangeFunctionParameterTypeFix(@NotNull JetParameter element, @NotNull JetType type) { + public ChangeParameterTypeFix(@NotNull JetParameter element, @NotNull JetType type) { super(element); renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); - JetFunction function = PsiTreeUtil.getParentOfType(element, JetFunction.class); - FqName functionFQName = function == null ? null : JetPsiUtil.getFQName(function); - containingFunctionName = functionFQName == null ? null : functionFQName.getFqName(); + JetNamedDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetNamedDeclaration.class); + isPrimaryConstructorParameter = declaration instanceof JetClass; + FqName declarationFQName = declaration == null ? null : JetPsiUtil.getFQName(declaration); + containingDeclarationName = declarationFQName == null ? null : declarationFQName.asString(); } @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - return super.isAvailable(project, editor, file) && containingFunctionName != null; + return super.isAvailable(project, editor, file) && containingDeclarationName != null; } @NotNull @Override public String getText() { - return JetBundle.message("change.function.parameter.type", element.getName(), containingFunctionName, renderedType); + return isPrimaryConstructorParameter ? + JetBundle.message("change.primary.constructor.parameter.type", element.getName(), containingDeclarationName, renderedType) : + JetBundle.message("change.function.parameter.type", element.getName(), containingDeclarationName, renderedType); } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java index ec304583cb9..9eb2dd5314b 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java @@ -89,7 +89,7 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor()); if (declaration instanceof JetFunction) { JetParameter binaryOperatorParameter = ((JetFunction) declaration).getValueParameterList().getParameters().get(0); - actions.add(new ChangeFunctionParameterTypeFix(binaryOperatorParameter, expressionType)); + actions.add(new ChangeParameterTypeFix(binaryOperatorParameter, expressionType)); } } } @@ -113,20 +113,20 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF QuickFixUtil.getParentElementOfType(diagnostic, JetFunctionLiteralExpression.class); if (functionLiteralExpression != null && functionLiteralExpression.getBodyExpression() == expression) { JetParameter correspondingParameter = - QuickFixUtil.getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(functionLiteralExpression); + QuickFixUtil.getParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(functionLiteralExpression); JetType functionLiteralExpressionType = context.get(BindingContext.EXPRESSION_TYPE, functionLiteralExpression); if (correspondingParameter != null && functionLiteralExpressionType != null) { - actions.add(new ChangeFunctionParameterTypeFix(correspondingParameter, functionLiteralExpressionType)); + actions.add(new ChangeParameterTypeFix(correspondingParameter, functionLiteralExpressionType)); } } // 2) When an argument is passed inside value argument list: else { JetValueArgument valueArgument = QuickFixUtil.getParentElementOfType(diagnostic, JetValueArgument.class); - if (valueArgument != null && valueArgument.getArgumentExpression() == expression) { - JetParameter correspondingParameter = QuickFixUtil.getFunctionParameterCorrespondingToValueArgumentPassedInCall(valueArgument); + if (valueArgument != null && QuickFixUtil.canEvaluateTo(valueArgument.getArgumentExpression(), expression)) { + JetParameter correspondingParameter = QuickFixUtil.getParameterCorrespondingToValueArgumentPassedInCall(valueArgument); JetType valueArgumentType = context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression()); if (correspondingParameter != null && valueArgumentType != null) { - actions.add(new ChangeFunctionParameterTypeFix(correspondingParameter, valueArgumentType)); + actions.add(new ChangeParameterTypeFix(correspondingParameter, valueArgumentType)); } } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java index c7d003be348..11380a56cc4 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java @@ -95,30 +95,33 @@ public class QuickFixUtil { } @Nullable - public static JetParameterList getParameterListOfCalledFunction(@NotNull JetCallExpression callExpression) { + public static JetParameterList getParameterListOfCallee(@NotNull JetCallExpression callExpression) { BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) callExpression.getContainingFile()).getBindingContext(); ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()); if (resolvedCall == null) return null; - PsiElement functionDeclaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); - if (functionDeclaration instanceof JetFunction) { - return ((JetFunction) functionDeclaration).getValueParameterList(); + PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); + if (declaration instanceof JetFunction) { + return ((JetFunction) declaration).getValueParameterList(); + } + if (declaration instanceof JetClass) { + return ((JetClass) declaration).getPrimaryConstructorParameterList(); } return null; } @Nullable - public static JetParameter getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(@NotNull JetFunctionLiteralExpression functionLiteralExpression) { + public static JetParameter getParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(@NotNull JetFunctionLiteralExpression functionLiteralExpression) { if (!(functionLiteralExpression.getParent() instanceof JetCallExpression)) { return null; } JetCallExpression callExpression = (JetCallExpression) functionLiteralExpression.getParent(); - JetParameterList parameterList = getParameterListOfCalledFunction(callExpression); + JetParameterList parameterList = getParameterListOfCallee(callExpression); if (parameterList == null) return null; return parameterList.getParameters().get(parameterList.getParameters().size() - 1); } @Nullable - public static JetParameter getFunctionParameterCorrespondingToValueArgumentPassedInCall(@NotNull JetValueArgument valueArgument) { + public static JetParameter getParameterCorrespondingToValueArgumentPassedInCall(@NotNull JetValueArgument valueArgument) { if (!(valueArgument.getParent() instanceof JetValueArgumentList)) { return null; } @@ -127,7 +130,7 @@ public class QuickFixUtil { return null; } JetCallExpression callExpression = (JetCallExpression) valueArgumentList.getParent(); - JetParameterList parameterList = getParameterListOfCalledFunction(callExpression); + JetParameterList parameterList = getParameterListOfCallee(callExpression); if (parameterList == null) return null; int position = valueArgumentList.getArguments().indexOf(valueArgument); if (position == -1) return null; diff --git a/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangePrimaryConstructorParameterType.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangePrimaryConstructorParameterType.kt new file mode 100644 index 00000000000..9acd1ad0389 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangePrimaryConstructorParameterType.kt @@ -0,0 +1,5 @@ +// "Change parameter 'a' type of primary constructor of class 'B' to 'String'" "true" +class B(val a: String) +fun foo() { + B(if (true) "" else "") +} diff --git a/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt new file mode 100644 index 00000000000..7e39c54a4a1 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt @@ -0,0 +1,5 @@ +// "Change parameter 'a' type of primary constructor of class 'B' to 'String'" "true" +class B(val a: Int) +fun foo() { + B(if (true) "" else "") +} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 5ad88c7a44e..fe3b3c67a02 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1476,6 +1476,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType5.kt"); } + @TestMetadata("beforeChangePrimaryConstructorParameterType.kt") + public void testChangePrimaryConstructorParameterType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt"); + } + } @TestMetadata("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression")