mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Groovy: 'implement interface' intention should work with generic classes
This commit is contained in:
+37
-30
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -29,24 +29,26 @@ import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.actions.GroovyTemplates;
|
||||
import org.jetbrains.plugins.groovy.annotator.intentions.CreateClassActionBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrExtendsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplementsClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeParameterList;
|
||||
|
||||
/**
|
||||
@@ -75,14 +77,13 @@ public class GrCreateSubclassAction extends CreateSubclassAction {
|
||||
|
||||
new WriteCommandAction(project, getTitle(psiClass), getTitle(psiClass)) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
protected void run(@NotNull Result result) throws Throwable {
|
||||
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
|
||||
|
||||
final GrTypeParameterList oldTypeParameterList = psiClass.getTypeParameterList();
|
||||
|
||||
try {
|
||||
targetClass.set(CreateClassActionBase.createClassByType(targetDirectory, className, PsiManager.getInstance(project), psiClass,
|
||||
GroovyTemplates.GROOVY_CLASS, true));
|
||||
targetClass.set(CreateClassActionBase.createClassByType(targetDirectory, className, PsiManager.getInstance(project), psiClass, GroovyTemplates.GROOVY_CLASS, true));
|
||||
}
|
||||
catch (final IncorrectOperationException e) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@@ -96,10 +97,9 @@ public class GrCreateSubclassAction extends CreateSubclassAction {
|
||||
return;
|
||||
}
|
||||
startTemplate(oldTypeParameterList, project, psiClass, targetClass.get(), false);
|
||||
PsiElement element = targetClass.get();
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(element);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
if (targetClass.get() == null) return null;
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() && !psiClass.hasTypeParameters()) {
|
||||
|
||||
@@ -118,22 +118,15 @@ public class GrCreateSubclassAction extends CreateSubclassAction {
|
||||
boolean includeClassName) {
|
||||
PsiElementFactory jfactory = JavaPsiFacade.getElementFactory(project);
|
||||
final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(project);
|
||||
GrCodeReferenceElement ref = elementFactory.createCodeReferenceElementFromClass(psiClass);
|
||||
GrCodeReferenceElement stubRef = elementFactory.createCodeReferenceElementFromClass(psiClass);
|
||||
try {
|
||||
if (psiClass.isInterface()) {
|
||||
GrImplementsClause clause = targetClass.getImplementsClause();
|
||||
if (clause == null) {
|
||||
clause = (GrImplementsClause)targetClass.addAfter(elementFactory.createImplementsClause(), targetClass.getNameIdentifierGroovy());
|
||||
}
|
||||
ref = (GrCodeReferenceElement)clause.add(ref);
|
||||
}
|
||||
else {
|
||||
GrExtendsClause clause = targetClass.getExtendsClause();
|
||||
if (clause == null) {
|
||||
clause = (GrExtendsClause)targetClass.addAfter(elementFactory.createExtendsClause(), targetClass.getNameIdentifierGroovy());
|
||||
}
|
||||
ref = (GrCodeReferenceElement)clause.add(ref);
|
||||
GrReferenceList clause = psiClass.isInterface() ? targetClass.getImplementsClause() : targetClass.getExtendsClause();
|
||||
if (clause == null) {
|
||||
GrReferenceList stubRefList = psiClass.isInterface() ? elementFactory.createImplementsClause() : elementFactory.createExtendsClause();
|
||||
clause = (GrExtendsClause)targetClass.addAfter(stubRefList, targetClass.getNameIdentifierGroovy());
|
||||
}
|
||||
GrCodeReferenceElement ref = (GrCodeReferenceElement)clause.add(stubRef);
|
||||
|
||||
if (psiClass.hasTypeParameters() || includeClassName) {
|
||||
final Editor editor = CodeInsightUtil.positionCursor(project, targetClass.getContainingFile(), targetClass.getLBrace());
|
||||
final TemplateBuilderImpl templateBuilder = editor == null || ApplicationManager.getApplication().isUnitTestMode() ? null
|
||||
@@ -143,19 +136,31 @@ public class GrCreateSubclassAction extends CreateSubclassAction {
|
||||
templateBuilder.replaceElement(targetClass.getNameIdentifier(), targetClass.getName());
|
||||
}
|
||||
|
||||
if (oldTypeParameterList != null) {
|
||||
if (oldTypeParameterList != null && oldTypeParameterList.getTypeParameters().length > 0) {
|
||||
GrTypeArgumentList existingList = ref.getTypeArgumentList();
|
||||
final GrTypeParameterList typeParameterList =
|
||||
(GrTypeParameterList)targetClass.addAfter(elementFactory.createTypeParameterList(), targetClass.getNameIdentifierGroovy());
|
||||
|
||||
GrTypeArgumentList argList;
|
||||
if (existingList == null) {
|
||||
GrCodeReferenceElement codeRef = elementFactory.createCodeReferenceElementFromText("A<T>");
|
||||
argList = ((GrTypeArgumentList)ref.add(codeRef.getTypeArgumentList()));
|
||||
argList.getTypeArgumentElements()[0].delete();
|
||||
}
|
||||
else {
|
||||
argList = existingList;
|
||||
}
|
||||
|
||||
for (PsiTypeParameter parameter : oldTypeParameterList.getTypeParameters()) {
|
||||
final PsiElement param = ref.getTypeArgumentList().add(elementFactory.createTypeElement(jfactory.createType(parameter)));
|
||||
final PsiElement param = argList.add(elementFactory.createTypeElement(jfactory.createType(parameter)));
|
||||
if (templateBuilder != null) {
|
||||
templateBuilder.replaceElement(param, param.getText());
|
||||
}
|
||||
|
||||
typeParameterList.add(elementFactory.createTypeParameter(parameter.getName(), parameter.getExtendsListTypes()));
|
||||
}
|
||||
}
|
||||
|
||||
final GrTypeParameterList typeParameterList = targetClass.getTypeParameterList();
|
||||
assert typeParameterList != null;
|
||||
typeParameterList.replace(oldTypeParameterList);
|
||||
|
||||
if (templateBuilder != null) {
|
||||
templateBuilder.setEndVariableBefore(ref);
|
||||
final Template template = templateBuilder.buildTemplate();
|
||||
@@ -166,12 +171,14 @@ public class GrCreateSubclassAction extends CreateSubclassAction {
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
|
||||
final TextRange textRange = targetClass.getTextRange();
|
||||
final int startClassOffset = textRange.getStartOffset();
|
||||
final RangeMarker startClassOffset = editor.getDocument().createRangeMarker(textRange.getStartOffset(), textRange.getEndOffset());
|
||||
startClassOffset.setGreedyToLeft(true);
|
||||
startClassOffset.setGreedyToRight(true);
|
||||
editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset());
|
||||
CreateFromUsageBaseFix.startTemplate(editor, template, project, new TemplateEditingAdapter() {
|
||||
@Override
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
chooseAndImplement(psiClass, project,PsiTreeUtil.getParentOfType(containingFile.findElementAt(startClassOffset), GrTypeDefinition.class),editor);
|
||||
chooseAndImplement(psiClass, project,PsiTreeUtil.getParentOfType(containingFile.findElementAt(startClassOffset.getStartOffset()), GrTypeDefinition.class),editor);
|
||||
}
|
||||
}, getTitle(psiClass));
|
||||
}
|
||||
|
||||
+26
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.types;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
@@ -63,4 +64,28 @@ public class GrTypeArgumentListImpl extends GroovyPsiElementImpl implements GrTy
|
||||
public boolean isDiamond() {
|
||||
return getTypeArgumentElements().length == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode addInternal(ASTNode first, ASTNode last, ASTNode anchor, Boolean before) {
|
||||
if (first == last && first.getPsi() instanceof GrTypeElement) {
|
||||
if (anchor == null) {
|
||||
anchor = getLastChild().getNode();
|
||||
before = true;
|
||||
}
|
||||
if (getTypeArgumentElements().length > 0) {
|
||||
if (before == null || before.booleanValue()) {
|
||||
getNode().addLeaf(GroovyTokenTypes.mCOMMA, ",", anchor);
|
||||
}
|
||||
else {
|
||||
getNode().addLeaf(GroovyTokenTypes.mCOMMA, ",", anchor.getTreeNext());
|
||||
}
|
||||
}
|
||||
|
||||
return super.addInternal(first, last, anchor, before);
|
||||
}
|
||||
|
||||
else {
|
||||
return super.addInternal(first, last, anchor, before);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user