Moved various util methods related for reading and editing Kotlin signature annotation utils to util class. Moved invokeEditSignature() to EditSignatureBalloon. Added static imports. Reformatted code a little bit.

This commit is contained in:
Evgeny Gerashchenko
2012-08-30 19:33:58 +04:00
parent bdccb28ebe
commit 19e4803b79
4 changed files with 134 additions and 115 deletions
@@ -46,6 +46,8 @@ import org.jetbrains.jet.resolve.DescriptorRenderer;
import javax.swing.*;
import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.*;
/**
* @author Evgeny Gerashchenko
* @since 16 Aug 2012
@@ -87,7 +89,7 @@ public class AddKotlinSignatureAnnotation extends BaseIntentionAction implements
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
PsiMethod method = findMethod(file, editor.getCaretModel().getOffset());
if (method == null) return false;
if (KotlinSignatureInJavaMarkerProvider.findKotlinSignatureAnnotation(method) != null) return false;
if (findKotlinSignatureAnnotation(method) != null) return false;
if (method.getModifierList().hasExplicitModifier(PsiModifier.PRIVATE)) return false;
return createFix(method, "").isAvailable(project, editor, file);
}
@@ -106,13 +108,12 @@ public class AddKotlinSignatureAnnotation extends BaseIntentionAction implements
boolean successful) {
busConnection.disconnect();
if (successful && owner == method
&& KotlinSignatureInJavaMarkerProvider.KOTLIN_SIGNATURE_ANNOTATION.equals(annotationFQName)) {
if (successful && owner == method && KOTLIN_SIGNATURE_ANNOTATION.equals(annotationFQName)) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
KotlinSignatureInJavaMarkerProvider.refresh(project);
KotlinSignatureInJavaMarkerProvider.invokeEditSignature(method, editor, null);
refreshMarkers(project);
EditSignatureBalloon.invokeEditSignature(method, editor, null);
}
}, ModalityState.NON_MODAL);
}
@@ -123,8 +124,7 @@ public class AddKotlinSignatureAnnotation extends BaseIntentionAction implements
@NotNull
private static AddAnnotationFix createFix(@NotNull PsiMethod method, @NotNull String signature) {
return new AddAnnotationFix(KotlinSignatureInJavaMarkerProvider.KOTLIN_SIGNATURE_ANNOTATION, method,
EditSignatureBalloon.signatureToNameValuePairs(method.getProject(), signature));
return new AddAnnotationFix(KOTLIN_SIGNATURE_ANNOTATION, method, signatureToNameValuePairs(method.getProject(), signature));
}
private static String getDefaultSignature(@NotNull Project project, @NotNull PsiMethod method) {
@@ -17,19 +17,24 @@
package org.jetbrains.jet.plugin.codeInsight.ktSignature;
import com.intellij.codeInsight.ExternalAnnotationsManager;
import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.EditorSettings;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupAdapter;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.*;
import com.intellij.ui.awt.RelativePoint;
@@ -44,6 +49,8 @@ import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.*;
/**
* @author Evgeny Gerashchenko
* @since 10.08.12
@@ -191,12 +198,11 @@ class EditSignatureBalloon {
private void deleteAndHide() {
new WriteCommandAction(project) {
@Override
protected void run(final Result result) throws Throwable {
ExternalAnnotationsManager.getInstance(project)
.deannotate(method, KotlinSignatureInJavaMarkerProvider.KOTLIN_SIGNATURE_ANNOTATION);
protected void run(Result result) throws Throwable {
ExternalAnnotationsManager.getInstance(project).deannotate(method, KOTLIN_SIGNATURE_ANNOTATION);
}
}.execute();
KotlinSignatureInJavaMarkerProvider.refresh(project);
refreshMarkers(project);
balloon.hide();
}
@@ -206,10 +212,9 @@ class EditSignatureBalloon {
if (!previousSignature.equals(newSignature)) {
new WriteCommandAction(project) {
@Override
protected void run(final Result result) throws Throwable {
protected void run(Result result) throws Throwable {
ExternalAnnotationsManager.getInstance(project).editExternalAnnotation(
method, KotlinSignatureInJavaMarkerProvider.KOTLIN_SIGNATURE_ANNOTATION,
signatureToNameValuePairs(project, newSignature));
method, KOTLIN_SIGNATURE_ANNOTATION, signatureToNameValuePairs(project, newSignature));
}
}.execute();
}
@@ -217,9 +222,33 @@ class EditSignatureBalloon {
balloon.hide();
}
static PsiNameValuePair[] signatureToNameValuePairs(@NotNull Project project, @NotNull String signature) {
return JavaPsiFacade.getElementFactory(project).createAnnotationFromText(
"@" + KotlinSignatureInJavaMarkerProvider.KOTLIN_SIGNATURE_ANNOTATION
+ "(value=\"" + StringUtil.escapeStringCharacters(signature) + "\")", null).getParameterList().getAttributes();
static void invokeEditSignature(@NotNull PsiMethod element, @NotNull Editor editor, @Nullable Point point) {
PsiAnnotation annotation = findKotlinSignatureAnnotation(element);
assert annotation != null;
if (annotation.getContainingFile() == element.getContainingFile()) {
// not external, go to
for (PsiNameValuePair pair : annotation.getParameterList().getAttributes()) {
if (pair.getName() == null || "value".equals(pair.getName())) {
PsiAnnotationMemberValue value = pair.getValue();
if (value != null) {
PsiElement firstChild = value.getFirstChild();
VirtualFile virtualFile = value.getContainingFile().getVirtualFile();
if (firstChild != null && firstChild.getNode().getElementType() == JavaTokenType.STRING_LITERAL
&& virtualFile != null) {
new OpenFileDescriptor(value.getProject(), virtualFile, value.getTextOffset() + 1).navigate(true);
}
else {
NavigationUtil.activateFileWithPsiElement(value);
}
}
}
}
}
else {
PsiMethod annotationOwner = getAnnotationOwner(element);
boolean editable = ExternalAnnotationsManager.getInstance(element.getProject())
.isExternalAnnotationWritable(annotationOwner, KOTLIN_SIGNATURE_ANNOTATION);
new EditSignatureBalloon(annotationOwner, getKotlinSignature(annotation), editable).show(point, editor);
}
}
}
@@ -17,36 +17,28 @@
package org.jetbrains.jet.plugin.codeInsight.ktSignature;
import com.intellij.codeHighlighting.Pass;
import com.intellij.codeInsight.ExternalAnnotationsManager;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler;
import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProvider;
import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.ide.DataManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.compiled.ClsElementImpl;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.plugin.JetIcons;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.List;
import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.*;
/**
* @author Evgeny Gerashchenko
* @since 3 August 2012
@@ -54,7 +46,7 @@ import java.util.List;
public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
private static final String SHOW_MARKERS_PROPERTY = "kotlin.signature.markers.enabled";
private static final Function<PsiElement,String> TOOLTIP_PROVIDER = new Function<PsiElement, String>() {
private static final Function<PsiElement, String> TOOLTIP_PROVIDER = new Function<PsiElement, String>() {
@Override
public String fun(PsiElement element) {
PsiAnnotation annotation = findKotlinSignatureAnnotation(element);
@@ -73,56 +65,11 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext(e.getComponent()));
assert editor != null;
invokeEditSignature(element, editor, e.getPoint());
EditSignatureBalloon.invokeEditSignature(element, editor, e.getPoint());
}
};
static final String KOTLIN_SIGNATURE_ANNOTATION = JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName();
@Nullable
static PsiAnnotation findKotlinSignatureAnnotation(@NotNull PsiElement element) {
if (!(element instanceof PsiMethod)) return null;
PsiMethod annotationOwner = getAnnotationOwner(element);
PsiAnnotation annotation =
JavaDescriptorResolver.findAnnotation(annotationOwner, KOTLIN_SIGNATURE_ANNOTATION);
if (annotation == null) return null;
if (annotation.getParameterList().getAttributes().length == 0) return null;
return annotation;
}
static PsiMethod getAnnotationOwner(PsiElement element) {
PsiMethod annotationOwner = element.getOriginalElement() instanceof PsiMethod
? (PsiMethod) element.getOriginalElement()
: (PsiMethod) element;
if (!annotationOwner.isPhysical()) {
ASTNode node = SourceTreeToPsiMap.psiElementToTree(element);
if (node != null) {
PsiCompiledElement compiledElement = node.getUserData(ClsElementImpl.COMPILED_ELEMENT);
if (compiledElement instanceof PsiMethod) {
annotationOwner = (PsiMethod) compiledElement;
}
}
}
return annotationOwner;
}
@NotNull
private static String getKotlinSignature(@NotNull PsiAnnotation kotlinSignatureAnnotation) {
PsiNameValuePair pair = kotlinSignatureAnnotation.getParameterList().getAttributes()[0];
PsiAnnotationMemberValue value = pair.getValue();
if (value == null) {
return "null";
}
else if (value instanceof PsiLiteralExpression) {
Object valueObject = ((PsiLiteralExpression) value).getValue();
return valueObject == null ? "null" : StringUtil.unescapeStringCharacters(valueObject.toString());
}
else {
return value.getText();
}
}
@Override
@Nullable
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
@@ -143,40 +90,6 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider {
public static void setMarkersEnabled(@NotNull Project project, boolean value) {
PropertiesComponent.getInstance(project).setValue(SHOW_MARKERS_PROPERTY, Boolean.toString(value));
refresh(project);
}
static void refresh(@NotNull Project project) {
DaemonCodeAnalyzer.getInstance(project).restart();
}
static void invokeEditSignature(@NotNull PsiMethod element, @NotNull Editor editor, @Nullable Point point) {
PsiAnnotation annotation = findKotlinSignatureAnnotation(element);
assert annotation != null;
if (annotation.getContainingFile() == element.getContainingFile()) {
// not external, go to
for (PsiNameValuePair pair : annotation.getParameterList().getAttributes()) {
if (pair.getName() == null || "value".equals(pair.getName())) {
PsiAnnotationMemberValue value = pair.getValue();
if (value != null) {
PsiElement firstChild = value.getFirstChild();
VirtualFile virtualFile = value.getContainingFile().getVirtualFile();
if (firstChild != null && firstChild.getNode().getElementType() == JavaTokenType.STRING_LITERAL
&& virtualFile != null) {
new OpenFileDescriptor(value.getProject(), virtualFile, value.getTextOffset() + 1).navigate(true);
}
else {
NavigationUtil.activateFileWithPsiElement(value);
}
}
}
}
}
else {
PsiMethod annotationOwner = getAnnotationOwner(element);
boolean editable = ExternalAnnotationsManager.getInstance(element.getProject())
.isExternalAnnotationWritable(annotationOwner, KOTLIN_SIGNATURE_ANNOTATION);
new EditSignatureBalloon(annotationOwner, getKotlinSignature(annotation), editable).show(point, editor);
}
refreshMarkers(project);
}
}
@@ -0,0 +1,77 @@
package org.jetbrains.jet.plugin.codeInsight.ktSignature;
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.compiled.ClsElementImpl;
import com.intellij.psi.impl.source.SourceTreeToPsiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
/**
* @author Evgeny Gerashchenko
* @since 30 August 2012
*/
class KotlinSignatureUtil {
static final String KOTLIN_SIGNATURE_ANNOTATION = JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName();
private KotlinSignatureUtil() {
}
static PsiMethod getAnnotationOwner(PsiElement element) {
PsiMethod annotationOwner = element.getOriginalElement() instanceof PsiMethod
? (PsiMethod) element.getOriginalElement()
: (PsiMethod) element;
if (!annotationOwner.isPhysical()) {
ASTNode node = SourceTreeToPsiMap.psiElementToTree(element);
if (node != null) {
PsiCompiledElement compiledElement = node.getUserData(ClsElementImpl.COMPILED_ELEMENT);
if (compiledElement instanceof PsiMethod) {
annotationOwner = (PsiMethod) compiledElement;
}
}
}
return annotationOwner;
}
@NotNull
static String getKotlinSignature(@NotNull PsiAnnotation kotlinSignatureAnnotation) {
PsiNameValuePair pair = kotlinSignatureAnnotation.getParameterList().getAttributes()[0];
PsiAnnotationMemberValue value = pair.getValue();
if (value == null) {
return "null";
}
else if (value instanceof PsiLiteralExpression) {
Object valueObject = ((PsiLiteralExpression) value).getValue();
return valueObject == null ? "null" : StringUtil.unescapeStringCharacters(valueObject.toString());
}
else {
return value.getText();
}
}
@NotNull
static PsiNameValuePair[] signatureToNameValuePairs(@NotNull Project project, @NotNull String signature) {
return JavaPsiFacade.getElementFactory(project).createAnnotationFromText(
"@" + KOTLIN_SIGNATURE_ANNOTATION + "(value=\"" + StringUtil.escapeStringCharacters(signature) + "\")", null)
.getParameterList().getAttributes();
}
@Nullable
static PsiAnnotation findKotlinSignatureAnnotation(@NotNull PsiElement element) {
if (!(element instanceof PsiMethod)) return null;
PsiMethod annotationOwner = getAnnotationOwner(element);
PsiAnnotation annotation = JavaDescriptorResolver.findAnnotation(annotationOwner, KOTLIN_SIGNATURE_ANNOTATION);
if (annotation == null) return null;
if (annotation.getParameterList().getAttributes().length == 0) return null;
return annotation;
}
static void refreshMarkers(@NotNull Project project) {
DaemonCodeAnalyzer.getInstance(project).restart();
}
}