diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/AddKotlinSignatureAnnotation.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/AddKotlinSignatureAnnotation.java index 1bc206d8ac8..04d3cd5bdea 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/AddKotlinSignatureAnnotation.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/AddKotlinSignatureAnnotation.java @@ -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) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureBalloon.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureBalloon.java index 8ac0c76c2be..af8f4852cc3 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureBalloon.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureBalloon.java @@ -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); + } } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerProvider.java index cdf972cca3b..af977b05a39 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerProvider.java @@ -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 TOOLTIP_PROVIDER = new Function() { + private static final Function TOOLTIP_PROVIDER = new Function() { @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); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java new file mode 100644 index 00000000000..a5ee46c0f4f --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java @@ -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(); + } +}