From 78ab4b6ae7f2f5cbf053c3d9cea03d9fb06ea518 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 3 May 2012 03:49:10 +0400 Subject: [PATCH] Added functions logic in SpecifyTypesExplicitlyAction. --- .../jetbrains/jet/plugin/JetBundle.properties | 1 + .../SpecifyTypeExplicitlyAction.java | 79 +++++++++++++------ .../jet/plugin/quickfix/QuickFixes.java | 2 - ...erInternalProtectedFunWithoutReturnType.kt | 6 ++ .../afterProtectedFunWithoutReturnType.kt | 2 +- .../afterPublicFunWithoutReturnType.kt | 2 +- ...reInternalProtectedFunWithoutReturnType.kt | 2 +- .../typeAddition/beforeNoAddErrorType.kt | 2 +- .../beforeProtectedFunWithoutReturnType.kt | 2 +- .../beforePublicFunWithoutBody.kt | 2 +- .../beforePublicFunWithoutReturnType.kt | 2 +- 11 files changed, 70 insertions(+), 32 deletions(-) create mode 100644 idea/testData/quickfix/typeAddition/afterInternalProtectedFunWithoutReturnType.kt diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index d949b7cec59..6079753e73c 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -30,6 +30,7 @@ new.kotlin.file.action=Kotlin File import.fix=Import imports.chooser.title=Imports specify.type.explicitly.action.family.name=Specify Type Explicitly +specify.type.explicitly.add.return.type.action.name=Specify Return Type Explicitly specify.type.explicitly.add.action.name=Specify Type Explicitly specify.type.explicitly.remove.action.name=Remove Explicitly Specified Type diff --git a/idea/src/org/jetbrains/jet/plugin/intentions/SpecifyTypeExplicitlyAction.java b/idea/src/org/jetbrains/jet/plugin/intentions/SpecifyTypeExplicitlyAction.java index ae3269014cf..b2f192a235c 100644 --- a/idea/src/org/jetbrains/jet/plugin/intentions/SpecifyTypeExplicitlyAction.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/SpecifyTypeExplicitlyAction.java @@ -23,16 +23,20 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetFunction; +import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.project.AnalyzeSingleFileUtil; +import org.jetbrains.jet.plugin.quickfix.AddReturnTypeFix; import org.jetbrains.jet.plugin.refactoring.introduceVariable.JetChangePropertyActions; /** @@ -41,6 +45,8 @@ import org.jetbrains.jet.plugin.refactoring.introduceVariable.JetChangePropertyA */ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction { private JetType targetType; + private boolean isFunction; + private boolean disabledForError; public SpecifyTypeExplicitlyAction() { @@ -54,7 +60,12 @@ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction { @NotNull @Override public String getText() { - return targetType == null ? JetBundle.message("specify.type.explicitly.remove.action.name") : JetBundle.message("specify.type.explicitly.add.action.name"); + if (isFunction) { + return JetBundle.message("specify.type.explicitly.add.return.type.action.name"); + } + else { + return targetType == null ? JetBundle.message("specify.type.explicitly.remove.action.name") : JetBundle.message("specify.type.explicitly.add.action.name"); + } } @NotNull @@ -65,37 +76,59 @@ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction { @Override public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - JetProperty property = (JetProperty)element.getParent(); - if (targetType == null) { - JetChangePropertyActions.removeTypeAnnotation(project, property); + PsiElement parent = element.getParent(); + if (parent instanceof JetProperty) { + JetProperty property = (JetProperty) parent; + if (targetType == null) { + JetChangePropertyActions.removeTypeAnnotation(project, property); + } else { + JetChangePropertyActions.addTypeAnnotation(project, property, targetType); + } + } else if (parent instanceof JetNamedFunction) { + assert targetType != null; + parent.replace(AddReturnTypeFix.addFunctionType(project, (JetFunction) parent, targetType)); } else { - JetChangePropertyActions.addTypeAnnotation(project, property, targetType); + assert false; } } @Override public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - if (!(element.getParent() instanceof JetProperty) || PsiTreeUtil.isAncestor(((JetProperty)element.getParent()).getInitializer(), element, false)) { + if (element.getParent() instanceof JetProperty && !PsiTreeUtil.isAncestor(((JetProperty) element.getParent()).getInitializer(), element, false)) { + isFunction = false; + if (((JetProperty)element.getParent()).getPropertyTypeRef() != null) { + targetType = null; + return true; + } + } + else if (element.getParent() instanceof JetNamedFunction && ((JetNamedFunction) element.getParent()).getReturnTypeRef() == null + && !((JetNamedFunction) element.getParent()).hasBlockBody()) { + isFunction = true; + } + else { return false; } - JetProperty property = (JetProperty)element.getParent(); - boolean hasTypeSpecified = property.getPropertyTypeRef() != null; - if (hasTypeSpecified) { - targetType = null; - } else { - BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile((JetFile)element.getContainingFile()); - DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, property); - assert descriptor instanceof VariableDescriptor; - targetType = ((VariableDescriptor)descriptor).getType(); - if (ErrorUtils.isErrorType(targetType)) { - return false; - } - if (disabledForError) { - for (Diagnostic diagnostic : bindingContext.getDiagnostics()) { - if (Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE == diagnostic.getFactory() && property == diagnostic.getPsiElement()) { - return false; - } + BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile((JetFile)element.getContainingFile()); + DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element.getParent()); + + if (descriptor instanceof VariableDescriptor) { + targetType = ((VariableDescriptor) descriptor).getType(); + } + else if (descriptor instanceof SimpleFunctionDescriptor) { + targetType = ((SimpleFunctionDescriptor) descriptor).getReturnType(); + } + else { + assert false; + } + + if (targetType == null || ErrorUtils.isErrorType(targetType)) { + return false; + } + if (disabledForError) { + for (Diagnostic diagnostic : bindingContext.getDiagnostics()) { + if (Errors.PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE == diagnostic.getFactory() && element.getParent() == diagnostic.getPsiElement()) { + return false; } } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index ebd50c228ed..d728a2918c0 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -114,8 +114,6 @@ public class QuickFixes { factories.put(REDUNDANT_MODIFIER_IN_GETTER, removeRedundantModifierFactory); factories.put(ILLEGAL_MODIFIER, removeModifierFactory); - factories.put(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, AddReturnTypeFix.createFactory()); - JetIntentionActionFactory changeToBackingFieldFactory = ChangeToBackingFieldFix.createFactory(); factories.put(INITIALIZATION_USING_BACKING_FIELD_CUSTOM_SETTER, changeToBackingFieldFactory); factories.put(INITIALIZATION_USING_BACKING_FIELD_OPEN_SETTER, changeToBackingFieldFactory); diff --git a/idea/testData/quickfix/typeAddition/afterInternalProtectedFunWithoutReturnType.kt b/idea/testData/quickfix/typeAddition/afterInternalProtectedFunWithoutReturnType.kt new file mode 100644 index 00000000000..38f7fb1755e --- /dev/null +++ b/idea/testData/quickfix/typeAddition/afterInternalProtectedFunWithoutReturnType.kt @@ -0,0 +1,6 @@ +// "Specify Return Type Explicitly" "true" +package a + +class A() { + internal protected fun foo() : Int = 1 +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeAddition/afterProtectedFunWithoutReturnType.kt b/idea/testData/quickfix/typeAddition/afterProtectedFunWithoutReturnType.kt index 70453ac2e71..36a08c7701c 100644 --- a/idea/testData/quickfix/typeAddition/afterProtectedFunWithoutReturnType.kt +++ b/idea/testData/quickfix/typeAddition/afterProtectedFunWithoutReturnType.kt @@ -1,4 +1,4 @@ -// "Add return type declaration" "true" +// "Specify Return Type Explicitly" "true" package a class A() { diff --git a/idea/testData/quickfix/typeAddition/afterPublicFunWithoutReturnType.kt b/idea/testData/quickfix/typeAddition/afterPublicFunWithoutReturnType.kt index 5b1e3062cb5..98b5c833d42 100644 --- a/idea/testData/quickfix/typeAddition/afterPublicFunWithoutReturnType.kt +++ b/idea/testData/quickfix/typeAddition/afterPublicFunWithoutReturnType.kt @@ -1,4 +1,4 @@ -// "Add return type declaration" "true" +// "Specify Return Type Explicitly" "true" package a class A() { diff --git a/idea/testData/quickfix/typeAddition/beforeInternalProtectedFunWithoutReturnType.kt b/idea/testData/quickfix/typeAddition/beforeInternalProtectedFunWithoutReturnType.kt index 9269030be65..94cd735eb48 100644 --- a/idea/testData/quickfix/typeAddition/beforeInternalProtectedFunWithoutReturnType.kt +++ b/idea/testData/quickfix/typeAddition/beforeInternalProtectedFunWithoutReturnType.kt @@ -1,4 +1,4 @@ -// "Add return type declaration" "false" +// "Specify Return Type Explicitly" "true" package a class A() { diff --git a/idea/testData/quickfix/typeAddition/beforeNoAddErrorType.kt b/idea/testData/quickfix/typeAddition/beforeNoAddErrorType.kt index 40c84f90829..fa02f0364ab 100644 --- a/idea/testData/quickfix/typeAddition/beforeNoAddErrorType.kt +++ b/idea/testData/quickfix/typeAddition/beforeNoAddErrorType.kt @@ -1,4 +1,4 @@ -// "Add return type declaration" "false" +// "Specify Return Type Explicitly" "false" class A() { public val t = foo() diff --git a/idea/testData/quickfix/typeAddition/beforeProtectedFunWithoutReturnType.kt b/idea/testData/quickfix/typeAddition/beforeProtectedFunWithoutReturnType.kt index 6502ee78846..bc85d49fb64 100644 --- a/idea/testData/quickfix/typeAddition/beforeProtectedFunWithoutReturnType.kt +++ b/idea/testData/quickfix/typeAddition/beforeProtectedFunWithoutReturnType.kt @@ -1,4 +1,4 @@ -// "Add return type declaration" "true" +// "Specify Return Type Explicitly" "true" package a class A() { diff --git a/idea/testData/quickfix/typeAddition/beforePublicFunWithoutBody.kt b/idea/testData/quickfix/typeAddition/beforePublicFunWithoutBody.kt index 7d0a2a28d85..d3736b8c09f 100644 --- a/idea/testData/quickfix/typeAddition/beforePublicFunWithoutBody.kt +++ b/idea/testData/quickfix/typeAddition/beforePublicFunWithoutBody.kt @@ -1,4 +1,4 @@ -// "Add return type declaration" "false" +// "Specify Return Type Explicitly" "false" package a class A() { diff --git a/idea/testData/quickfix/typeAddition/beforePublicFunWithoutReturnType.kt b/idea/testData/quickfix/typeAddition/beforePublicFunWithoutReturnType.kt index 1c0f34f03ab..fa546bde289 100644 --- a/idea/testData/quickfix/typeAddition/beforePublicFunWithoutReturnType.kt +++ b/idea/testData/quickfix/typeAddition/beforePublicFunWithoutReturnType.kt @@ -1,4 +1,4 @@ -// "Add return type declaration" "true" +// "Specify Return Type Explicitly" "true" package a class A() {