Introduce Variable: Do not create separate template to edit type reference
#KT-4314 Fixed
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -141,24 +141,8 @@ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction {
|
||||
return type == null ? ErrorUtils.createErrorType("null type") : type;
|
||||
}
|
||||
|
||||
public static void addTypeAnnotation(Project project, @Nullable Editor editor, @NotNull JetCallableDeclaration declaration, @NotNull JetType exprType) {
|
||||
if (editor != null) {
|
||||
addTypeAnnotationWithTemplate(project, editor, declaration, exprType);
|
||||
}
|
||||
else {
|
||||
declaration.setTypeReference(anyTypeRef(project));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addTypeAnnotationWithTemplate(
|
||||
@NotNull Project project,
|
||||
@NotNull Editor editor,
|
||||
@NotNull final JetCallableDeclaration declaration,
|
||||
@NotNull JetType exprType
|
||||
) {
|
||||
assert !exprType.isError() : "Unexpected error type, should have been checked before: "
|
||||
+ JetPsiUtil.getElementTextWithContext(declaration) + ", type = " + exprType;
|
||||
|
||||
@NotNull
|
||||
public static Expression createTypeExpressionForTemplate(JetType exprType) {
|
||||
ClassifierDescriptor descriptor = exprType.getConstructor().getDeclarationDescriptor();
|
||||
boolean isAnonymous = descriptor != null && DescriptorUtils.isAnonymousObject(descriptor);
|
||||
|
||||
@@ -166,7 +150,7 @@ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction {
|
||||
List<JetType> types = isAnonymous ? new ArrayList<JetType>() : Lists.newArrayList(exprType);
|
||||
types.addAll(allSupertypes);
|
||||
|
||||
Expression expression = new JetTypeLookupExpression<JetType>(
|
||||
return new JetTypeLookupExpression<JetType>(
|
||||
types,
|
||||
types.iterator().next(),
|
||||
JetBundle.message("specify.type.explicitly.add.action.name")
|
||||
@@ -181,6 +165,39 @@ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction {
|
||||
return IdeDescriptorRenderers.SOURCE_CODE.renderType(element);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void addTypeAnnotation(Project project, @Nullable Editor editor, @NotNull JetCallableDeclaration declaration, @NotNull JetType exprType) {
|
||||
if (editor != null) {
|
||||
addTypeAnnotationWithTemplate(project, editor, declaration, exprType);
|
||||
}
|
||||
else {
|
||||
declaration.setTypeReference(anyTypeRef(project));
|
||||
}
|
||||
}
|
||||
|
||||
public static TemplateEditingAdapter createTypeReferencePostprocessor(final JetCallableDeclaration declaration) {
|
||||
return new TemplateEditingAdapter() {
|
||||
@Override
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
JetTypeReference typeRef = declaration.getTypeReference();
|
||||
if (typeRef != null) {
|
||||
ShortenReferences.INSTANCE$.process(typeRef);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static void addTypeAnnotationWithTemplate(
|
||||
@NotNull Project project,
|
||||
@NotNull Editor editor,
|
||||
@NotNull JetCallableDeclaration declaration,
|
||||
@NotNull JetType exprType
|
||||
) {
|
||||
assert !exprType.isError() : "Unexpected error type, should have been checked before: "
|
||||
+ JetPsiUtil.getElementTextWithContext(declaration) + ", type = " + exprType;
|
||||
|
||||
Expression expression = createTypeExpressionForTemplate(exprType);
|
||||
|
||||
declaration.setTypeReference(anyTypeRef(project));
|
||||
|
||||
@@ -195,15 +212,7 @@ public class SpecifyTypeExplicitlyAction extends PsiElementBaseIntentionAction {
|
||||
editor.getCaretModel().moveToOffset(newTypeRef.getNode().getStartOffset());
|
||||
|
||||
TemplateManagerImpl manager = new TemplateManagerImpl(project);
|
||||
manager.startTemplate(editor, builder.buildInlineTemplate(), new TemplateEditingAdapter() {
|
||||
@Override
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
JetTypeReference typeRef = declaration.getTypeReference();
|
||||
if (typeRef != null) {
|
||||
ShortenReferences.INSTANCE$.process(typeRef);
|
||||
}
|
||||
}
|
||||
});
|
||||
manager.startTemplate(editor, builder.buildInlineTemplate(), createTypeReferencePostprocessor(declaration));
|
||||
}
|
||||
|
||||
private static JetTypeReference anyTypeRef(@NotNull Project project) {
|
||||
|
||||
+67
-6
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.refactoring.introduce.introduceVariable;
|
||||
|
||||
import com.intellij.codeInsight.template.TemplateBuilderImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
@@ -23,25 +26,29 @@ import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.refactoring.introduce.inplace.InplaceVariableIntroducer;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction;
|
||||
import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
public class KotlinInplaceVariableIntroducer extends InplaceVariableIntroducer<JetExpression> {
|
||||
|
||||
@@ -117,12 +124,19 @@ public class KotlinInplaceVariableIntroducer extends InplaceVariableIntroducer<J
|
||||
}
|
||||
}
|
||||
}
|
||||
SpecifyTypeExplicitlyAction.addTypeAnnotation(myProject, myEditor, myProperty, myExprType);
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
|
||||
String renderedType = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(myExprType);
|
||||
myProperty.setTypeReference(new JetPsiFactory(myProject).createType(renderedType));
|
||||
}
|
||||
else {
|
||||
myProperty.setTypeReference(null);
|
||||
}
|
||||
|
||||
TemplateState templateState =
|
||||
TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(myEditor));
|
||||
if (templateState != null) {
|
||||
myEditor.putUserData(INTRODUCE_RESTART, true);
|
||||
templateState.cancelTemplate();
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
@@ -145,6 +159,10 @@ public class KotlinInplaceVariableIntroducer extends InplaceVariableIntroducer<J
|
||||
}
|
||||
});
|
||||
|
||||
if (myEditor.getUserData(INTRODUCE_RESTART) == Boolean.TRUE) {
|
||||
myInitialName = myProperty.getName();
|
||||
performInplaceRefactoring(getSuggestionsForNextRun());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -171,6 +189,49 @@ public class KotlinInplaceVariableIntroducer extends InplaceVariableIntroducer<J
|
||||
return panel;
|
||||
}
|
||||
|
||||
private LinkedHashSet<String> getSuggestionsForNextRun() {
|
||||
LinkedHashSet<String> nameSuggestions;
|
||||
String currentName = myProperty.getName();
|
||||
if (myNameSuggestions.contains(currentName)) {
|
||||
nameSuggestions = myNameSuggestions;
|
||||
}
|
||||
else {
|
||||
nameSuggestions = new LinkedHashSet<String>();
|
||||
nameSuggestions.add(currentName);
|
||||
nameSuggestions.addAll(myNameSuggestions);
|
||||
}
|
||||
return nameSuggestions;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAdditionalVariables(TemplateBuilderImpl builder) {
|
||||
JetTypeReference typeReference = myProperty.getTypeReference();
|
||||
if (typeReference != null) {
|
||||
builder.replaceElement(typeReference, SpecifyTypeExplicitlyAction.createTypeExpressionForTemplate(myExprType));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean buildTemplateAndStart(
|
||||
Collection<PsiReference> refs,
|
||||
Collection<Pair<PsiElement, TextRange>> stringUsages,
|
||||
PsiElement scope,
|
||||
PsiFile containingFile
|
||||
) {
|
||||
myEditor.putUserData(INTRODUCE_RESTART, false);
|
||||
//noinspection ConstantConditions
|
||||
myEditor.getCaretModel().moveToOffset(getNameIdentifier().getTextOffset());
|
||||
boolean result = super.buildTemplateAndStart(refs, stringUsages, scope, containingFile);
|
||||
|
||||
TemplateState templateState =
|
||||
TemplateManagerImpl.getTemplateState(InjectedLanguageUtil.getTopLevelEditor(myEditor));
|
||||
if (templateState != null && myProperty.getTypeReference() != null) {
|
||||
templateState.addTemplateStateListener(SpecifyTypeExplicitlyAction.createTypeReferencePostprocessor(myProperty));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
if (!myReplaceOccurrence || myExprMarker == null) {
|
||||
|
||||
Reference in New Issue
Block a user