From a53a760b889b22e6ad90b6805e45b3f55dfa08e8 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 16 Nov 2015 11:43:48 +0100 Subject: [PATCH] [java] correct highlighting of JVM agent manifest headers (IDEA-147979) --- .../lang/manifest/ManifestBundle.properties | 2 ++ .../header/impl/ClassReferenceParser.java | 36 ++++++++++++++++--- .../impl/StandardManifestHeaderParsers.java | 8 ++--- .../manifest/ManifestHighlightingTest.java | 16 +++++++-- .../com/intellij/spellchecker/jetbrains.dic | 2 ++ 5 files changed, 53 insertions(+), 11 deletions(-) diff --git a/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.properties b/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.properties index 7fe98d7431e7..34fb9fc0d8d6 100644 --- a/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.properties +++ b/java/manifest/src/org/jetbrains/lang/manifest/ManifestBundle.properties @@ -5,6 +5,8 @@ manifest.header.expected=Header expected header.name.invalid=Invalid header name header.reference.invalid=Invalid reference header.main.class.invalid=Invalid main class +header.pre-main.class.invalid=Invalid pre-main class +header.agent.class.invalid=Invalid agent class inspection.group=Manifest inspection.newline.message=Manifest file doesn't end with a final newline diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/impl/ClassReferenceParser.java b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/ClassReferenceParser.java index 0d42000f1dce..b4ff7292005c 100644 --- a/java/manifest/src/org/jetbrains/lang/manifest/header/impl/ClassReferenceParser.java +++ b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/ClassReferenceParser.java @@ -23,9 +23,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiReference; +import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.ProjectScope; @@ -38,6 +36,10 @@ import org.jetbrains.lang.manifest.psi.HeaderValue; import org.jetbrains.lang.manifest.psi.HeaderValuePart; public class ClassReferenceParser extends StandardHeaderParser { + public static final String MAIN_CLASS = "Main-Class"; + public static final String PREMAIN_CLASS = "Premain-Class"; + public static final String AGENT_CLASS = "Agent-Class"; + public static final HeaderParser INSTANCE = new ClassReferenceParser(); @NotNull @@ -86,11 +88,35 @@ public class ClassReferenceParser extends StandardHeaderParser { } protected boolean checkClass(@NotNull HeaderValuePart valuePart, @NotNull PsiClass aClass, @NotNull AnnotationHolder holder) { - if (!PsiMethodUtil.hasMainMethod(aClass)) { + String header = ((Header)valuePart.getParent()).getName(); + + if (header.equals(MAIN_CLASS) && !PsiMethodUtil.hasMainMethod(aClass)) { holder.createErrorAnnotation(valuePart.getHighlightingRange(), ManifestBundle.message("header.main.class.invalid")); return true; } + if (header.equals(PREMAIN_CLASS) && !hasInstrumenterMethod(aClass, "premain")) { + holder.createErrorAnnotation(valuePart.getHighlightingRange(), ManifestBundle.message("header.pre-main.class.invalid")); + return true; + } + + if (header.equals(AGENT_CLASS) && !hasInstrumenterMethod(aClass, "agentmain")) { + holder.createErrorAnnotation(valuePart.getHighlightingRange(), ManifestBundle.message("header.agent.class.invalid")); + return true; + } + return false; } -} + + private static boolean hasInstrumenterMethod(PsiClass aClass, String methodName) { + for (PsiMethod method : aClass.findMethodsByName(methodName, false)) { + if (PsiType.VOID.equals(method.getReturnType()) && + method.hasModifierProperty(PsiModifier.PUBLIC) && + method.hasModifierProperty(PsiModifier.STATIC)) { + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardManifestHeaderParsers.java b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardManifestHeaderParsers.java index 8fe6ad580522..b6947849a2bd 100644 --- a/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardManifestHeaderParsers.java +++ b/java/manifest/src/org/jetbrains/lang/manifest/header/impl/StandardManifestHeaderParsers.java @@ -43,7 +43,7 @@ public class StandardManifestHeaderParsers implements HeaderParserProvider { myParsers.put("Created-By", StandardHeaderParser.INSTANCE); myParsers.put("Signature-Version", StandardHeaderParser.INSTANCE); myParsers.put("Class-Path", StandardHeaderParser.INSTANCE); - myParsers.put("Main-Class", ClassReferenceParser.INSTANCE); + myParsers.put(ClassReferenceParser.MAIN_CLASS, ClassReferenceParser.INSTANCE); myParsers.put("Implementation-Title", StandardHeaderParser.INSTANCE); myParsers.put("Implementation-Version", StandardHeaderParser.INSTANCE); myParsers.put("Implementation-Vendor", StandardHeaderParser.INSTANCE); @@ -59,8 +59,8 @@ public class StandardManifestHeaderParsers implements HeaderParserProvider { myParsers.put("MD5-Digest", StandardHeaderParser.INSTANCE); myParsers.put("SHA-Digest", StandardHeaderParser.INSTANCE); myParsers.put("Magic", StandardHeaderParser.INSTANCE); - myParsers.put("Premain-Class", ClassReferenceParser.INSTANCE); - myParsers.put("Agent-Class", ClassReferenceParser.INSTANCE); + myParsers.put(ClassReferenceParser.PREMAIN_CLASS, ClassReferenceParser.INSTANCE); + myParsers.put(ClassReferenceParser.AGENT_CLASS, ClassReferenceParser.INSTANCE); myParsers.put("Boot-Class-Path", StandardHeaderParser.INSTANCE); myParsers.put("Can-Redefine-Classes", StandardHeaderParser.INSTANCE); myParsers.put("Can-Retransform-Classes", StandardHeaderParser.INSTANCE); @@ -72,4 +72,4 @@ public class StandardManifestHeaderParsers implements HeaderParserProvider { public Map getHeaderParsers() { return myParsers; } -} +} \ No newline at end of file diff --git a/java/manifest/test/org/jetbrains/lang/manifest/ManifestHighlightingTest.java b/java/manifest/test/org/jetbrains/lang/manifest/ManifestHighlightingTest.java index 459ef1cea009..e873156b2b6e 100644 --- a/java/manifest/test/org/jetbrains/lang/manifest/ManifestHighlightingTest.java +++ b/java/manifest/test/org/jetbrains/lang/manifest/ManifestHighlightingTest.java @@ -30,11 +30,23 @@ public class ManifestHighlightingTest extends LightCodeInsightFixtureTestCase { doTest( "Main-Class: \n" + "Main-Class: org.acme.Main\n" + - "Main-Class: java.lang.String\n"); + "Main-Class: java.lang.String\n" + + "Main-Class: pkg.C1\n"); + } + + public void testAgentHeaders() { + doTest( + "Premain-Class: pkg.C1\n" + + "Premain-Class: pkg.C2\n" + + "Agent-Class: pkg.C1\n" + + "Agent-Class: pkg.C3\n"); } private void doTest(String text) { + myFixture.addClass("package pkg;\n\nclass C1 { public static void main(String... args) { } }"); + myFixture.addClass("package pkg;\n\nclass C2 { public static void premain() { } }"); + myFixture.addClass("package pkg;\n\nclass C3 { public static void agentmain() { } }"); myFixture.configureByText("MANIFEST.MF", text); myFixture.checkHighlighting(true, false, false); } -} +} \ No newline at end of file diff --git a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic index a51614d5a84e..e8c7baa61466 100644 --- a/spellchecker/src/com/intellij/spellchecker/jetbrains.dic +++ b/spellchecker/src/com/intellij/spellchecker/jetbrains.dic @@ -1,4 +1,5 @@ accessor +agentmain aggregator ajax akka @@ -431,6 +432,7 @@ postprocessor pragma prebuilt prefetch +premain prepend prepended prepends