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
|
||||
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}''
|
||||
|
||||
@@ -74,12 +74,12 @@ public class ChangeFunctionLiteralReturnTypeFix extends JetIntentionAction<JetFu
|
||||
return;
|
||||
}
|
||||
|
||||
JetParameter correspondingParameter = QuickFixUtil.getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(element);
|
||||
JetParameter correspondingParameter = QuickFixUtil.getParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(element);
|
||||
if (correspondingParameter != null) {
|
||||
JetTypeReference correspondingParameterTypeRef = correspondingParameter.getTypeReference();
|
||||
JetType parameterType = context.get(BindingContext.TYPE, correspondingParameterTypeRef);
|
||||
if (parameterType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(eventualFunctionLiteralType, parameterType)) {
|
||||
appropriateQuickFix = new ChangeFunctionParameterTypeFix(correspondingParameter, eventualFunctionLiteralType);
|
||||
appropriateQuickFix = new ChangeParameterTypeFix(correspondingParameter, eventualFunctionLiteralType);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+12
-8
@@ -28,27 +28,31 @@ import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
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 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
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<? extends CallableDescriptor> 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;
|
||||
|
||||
+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");
|
||||
}
|
||||
|
||||
@TestMetadata("beforeChangePrimaryConstructorParameterType.kt")
|
||||
public void testChangePrimaryConstructorParameterType() throws Exception {
|
||||
doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression")
|
||||
|
||||
Reference in New Issue
Block a user