QuickFix: change type of constructor parameter to match value argument in invocation
This commit is contained in:
@@ -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
|
remove.no.name.function.return.type=Remove explicitly specified function return type
|
||||||
change.element.type=Change ''{0}'' type to ''{1}''
|
change.element.type=Change ''{0}'' type to ''{1}''
|
||||||
change.function.parameter.type=Change parameter ''{0}'' type of function ''{1}'' to ''{2}''
|
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=Change type from ''{0}'' to ''{1}''
|
||||||
change.type.family=Change Type
|
change.type.family=Change Type
|
||||||
add.parameters.to.function=Add parameter{0} to function ''{1}''
|
add.parameters.to.function=Add parameter{0} to function ''{1}''
|
||||||
|
|||||||
@@ -74,12 +74,12 @@ public class ChangeFunctionLiteralReturnTypeFix extends JetIntentionAction<JetFu
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
JetParameter correspondingParameter = QuickFixUtil.getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(element);
|
JetParameter correspondingParameter = QuickFixUtil.getParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(element);
|
||||||
if (correspondingParameter != null) {
|
if (correspondingParameter != null) {
|
||||||
JetTypeReference correspondingParameterTypeRef = correspondingParameter.getTypeReference();
|
JetTypeReference correspondingParameterTypeRef = correspondingParameter.getTypeReference();
|
||||||
JetType parameterType = context.get(BindingContext.TYPE, correspondingParameterTypeRef);
|
JetType parameterType = context.get(BindingContext.TYPE, correspondingParameterTypeRef);
|
||||||
if (parameterType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(eventualFunctionLiteralType, parameterType)) {
|
if (parameterType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(eventualFunctionLiteralType, parameterType)) {
|
||||||
appropriateQuickFix = new ChangeFunctionParameterTypeFix(correspondingParameter, eventualFunctionLiteralType);
|
appropriateQuickFix = new ChangeParameterTypeFix(correspondingParameter, eventualFunctionLiteralType);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-8
@@ -28,27 +28,31 @@ import org.jetbrains.jet.lang.types.JetType;
|
|||||||
import org.jetbrains.jet.plugin.JetBundle;
|
import org.jetbrains.jet.plugin.JetBundle;
|
||||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||||
|
|
||||||
public class ChangeFunctionParameterTypeFix extends JetIntentionAction<JetParameter> {
|
public class ChangeParameterTypeFix extends JetIntentionAction<JetParameter> {
|
||||||
private final String renderedType;
|
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);
|
super(element);
|
||||||
renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type);
|
renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type);
|
||||||
JetFunction function = PsiTreeUtil.getParentOfType(element, JetFunction.class);
|
JetNamedDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetNamedDeclaration.class);
|
||||||
FqName functionFQName = function == null ? null : JetPsiUtil.getFQName(function);
|
isPrimaryConstructorParameter = declaration instanceof JetClass;
|
||||||
containingFunctionName = functionFQName == null ? null : functionFQName.getFqName();
|
FqName declarationFQName = declaration == null ? null : JetPsiUtil.getFQName(declaration);
|
||||||
|
containingDeclarationName = declarationFQName == null ? null : declarationFQName.asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
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
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public String getText() {
|
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
|
@NotNull
|
||||||
@@ -89,7 +89,7 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF
|
|||||||
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor());
|
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor());
|
||||||
if (declaration instanceof JetFunction) {
|
if (declaration instanceof JetFunction) {
|
||||||
JetParameter binaryOperatorParameter = ((JetFunction) declaration).getValueParameterList().getParameters().get(0);
|
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);
|
QuickFixUtil.getParentElementOfType(diagnostic, JetFunctionLiteralExpression.class);
|
||||||
if (functionLiteralExpression != null && functionLiteralExpression.getBodyExpression() == expression) {
|
if (functionLiteralExpression != null && functionLiteralExpression.getBodyExpression() == expression) {
|
||||||
JetParameter correspondingParameter =
|
JetParameter correspondingParameter =
|
||||||
QuickFixUtil.getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(functionLiteralExpression);
|
QuickFixUtil.getParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(functionLiteralExpression);
|
||||||
JetType functionLiteralExpressionType = context.get(BindingContext.EXPRESSION_TYPE, functionLiteralExpression);
|
JetType functionLiteralExpressionType = context.get(BindingContext.EXPRESSION_TYPE, functionLiteralExpression);
|
||||||
if (correspondingParameter != null && functionLiteralExpressionType != null) {
|
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:
|
// 2) When an argument is passed inside value argument list:
|
||||||
else {
|
else {
|
||||||
JetValueArgument valueArgument = QuickFixUtil.getParentElementOfType(diagnostic, JetValueArgument.class);
|
JetValueArgument valueArgument = QuickFixUtil.getParentElementOfType(diagnostic, JetValueArgument.class);
|
||||||
if (valueArgument != null && valueArgument.getArgumentExpression() == expression) {
|
if (valueArgument != null && QuickFixUtil.canEvaluateTo(valueArgument.getArgumentExpression(), expression)) {
|
||||||
JetParameter correspondingParameter = QuickFixUtil.getFunctionParameterCorrespondingToValueArgumentPassedInCall(valueArgument);
|
JetParameter correspondingParameter = QuickFixUtil.getParameterCorrespondingToValueArgumentPassedInCall(valueArgument);
|
||||||
JetType valueArgumentType = context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression());
|
JetType valueArgumentType = context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression());
|
||||||
if (correspondingParameter != null && valueArgumentType != null) {
|
if (correspondingParameter != null && valueArgumentType != null) {
|
||||||
actions.add(new ChangeFunctionParameterTypeFix(correspondingParameter, valueArgumentType));
|
actions.add(new ChangeParameterTypeFix(correspondingParameter, valueArgumentType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,30 +95,33 @@ public class QuickFixUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetParameterList getParameterListOfCalledFunction(@NotNull JetCallExpression callExpression) {
|
public static JetParameterList getParameterListOfCallee(@NotNull JetCallExpression callExpression) {
|
||||||
BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) callExpression.getContainingFile()).getBindingContext();
|
BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) callExpression.getContainingFile()).getBindingContext();
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = context.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression());
|
||||||
if (resolvedCall == null) return null;
|
if (resolvedCall == null) return null;
|
||||||
PsiElement functionDeclaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor());
|
PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor());
|
||||||
if (functionDeclaration instanceof JetFunction) {
|
if (declaration instanceof JetFunction) {
|
||||||
return ((JetFunction) functionDeclaration).getValueParameterList();
|
return ((JetFunction) declaration).getValueParameterList();
|
||||||
|
}
|
||||||
|
if (declaration instanceof JetClass) {
|
||||||
|
return ((JetClass) declaration).getPrimaryConstructorParameterList();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetParameter getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(@NotNull JetFunctionLiteralExpression functionLiteralExpression) {
|
public static JetParameter getParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(@NotNull JetFunctionLiteralExpression functionLiteralExpression) {
|
||||||
if (!(functionLiteralExpression.getParent() instanceof JetCallExpression)) {
|
if (!(functionLiteralExpression.getParent() instanceof JetCallExpression)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JetCallExpression callExpression = (JetCallExpression) functionLiteralExpression.getParent();
|
JetCallExpression callExpression = (JetCallExpression) functionLiteralExpression.getParent();
|
||||||
JetParameterList parameterList = getParameterListOfCalledFunction(callExpression);
|
JetParameterList parameterList = getParameterListOfCallee(callExpression);
|
||||||
if (parameterList == null) return null;
|
if (parameterList == null) return null;
|
||||||
return parameterList.getParameters().get(parameterList.getParameters().size() - 1);
|
return parameterList.getParameters().get(parameterList.getParameters().size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetParameter getFunctionParameterCorrespondingToValueArgumentPassedInCall(@NotNull JetValueArgument valueArgument) {
|
public static JetParameter getParameterCorrespondingToValueArgumentPassedInCall(@NotNull JetValueArgument valueArgument) {
|
||||||
if (!(valueArgument.getParent() instanceof JetValueArgumentList)) {
|
if (!(valueArgument.getParent() instanceof JetValueArgumentList)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -127,7 +130,7 @@ public class QuickFixUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
JetCallExpression callExpression = (JetCallExpression) valueArgumentList.getParent();
|
JetCallExpression callExpression = (JetCallExpression) valueArgumentList.getParent();
|
||||||
JetParameterList parameterList = getParameterListOfCalledFunction(callExpression);
|
JetParameterList parameterList = getParameterListOfCallee(callExpression);
|
||||||
if (parameterList == null) return null;
|
if (parameterList == null) return null;
|
||||||
int position = valueArgumentList.getArguments().indexOf(valueArgument);
|
int position = valueArgumentList.getArguments().indexOf(valueArgument);
|
||||||
if (position == -1) return null;
|
if (position == -1) return null;
|
||||||
|
|||||||
+5
@@ -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) ""<caret> else "")
|
||||||
|
}
|
||||||
+5
@@ -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) ""<caret> else "")
|
||||||
|
}
|
||||||
@@ -1476,6 +1476,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType5.kt");
|
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")
|
@TestMetadata("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression")
|
||||||
|
|||||||
Reference in New Issue
Block a user