From e8ea9105aee1650769e7f16b6e852ccfb9d06624 Mon Sep 17 00:00:00 2001 From: Chao Wang Date: Tue, 9 Sep 2025 13:12:50 +0800 Subject: [PATCH 1/3] feat: Go Plugin dependency removal Signed-off-by: Chao Wang --- README.md | 2 +- gradle.properties | 2 +- .../golang/build/lexer/GoModLexer.java | 638 ++++++++++++++++++ .../golang/build/parser/GoModParser.java | 362 ++++++++++ .../golang/build/psi/GoModExcludeBlock.java | 13 + .../golang/build/psi/GoModExcludeSpec.java | 16 + .../build/psi/GoModExcludeStatement.java | 16 + .../golang/build/psi/GoModGoStatement.java | 13 + .../golang/build/psi/GoModItem.java | 19 + .../build/psi/GoModModuleStatement.java | 13 + .../golang/build/psi/GoModReplaceBlock.java | 13 + .../golang/build/psi/GoModReplaceSpec.java | 13 + .../build/psi/GoModReplaceStatement.java | 16 + .../golang/build/psi/GoModRequireBlock.java | 13 + .../golang/build/psi/GoModRequireSpec.java | 16 + .../build/psi/GoModRequireStatement.java | 16 + .../golang/build/psi/GoModStatement.java | 25 + .../golang/build/psi/GoModTypes.java | 84 +++ .../golang/build/psi/GoModVisitor.java | 66 ++ .../build/psi/impl/GoModExcludeBlockImpl.java | 36 + .../build/psi/impl/GoModExcludeSpecImpl.java | 42 ++ .../psi/impl/GoModExcludeStatementImpl.java | 42 ++ .../build/psi/impl/GoModGoStatementImpl.java | 36 + .../golang/build/psi/impl/GoModItemImpl.java | 48 ++ .../psi/impl/GoModModuleStatementImpl.java | 36 + .../build/psi/impl/GoModReplaceBlockImpl.java | 36 + .../build/psi/impl/GoModReplaceSpecImpl.java | 36 + .../psi/impl/GoModReplaceStatementImpl.java | 42 ++ .../build/psi/impl/GoModRequireBlockImpl.java | 36 + .../build/psi/impl/GoModRequireSpecImpl.java | 42 ++ .../psi/impl/GoModRequireStatementImpl.java | 42 ++ .../build/psi/impl/GoModStatementImpl.java | 60 ++ .../golang/GoCAAnnotator.java | 181 +++-- .../golang/GoCAIntentionAction.java | 31 +- .../golang/build/filetype/GoModFileType.java | 47 ++ .../componentanalysis/golang/build/goMod.bnf | 63 ++ .../componentanalysis/golang/build/goMod.flex | 68 ++ .../golang/build/lang/GoModLanguage.java | 22 + .../golang/build/lexer/GoModLexerAdapter.java | 20 + .../golang/build/psi/GoModElementType.java | 23 + .../golang/build/psi/GoModFile.java | 35 + .../build/psi/GoModParserDefinition.java | 67 ++ .../golang/build/psi/GoModTokenSets.java | 18 + .../golang/build/psi/GoModTokenType.java | 28 + src/main/resources/META-INF/go.xml | 11 - src/main/resources/META-INF/plugin.xml | 16 +- 46 files changed, 2441 insertions(+), 79 deletions(-) create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeBlock.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeSpec.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeStatement.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModGoStatement.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModItem.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModModuleStatement.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceBlock.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceStatement.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireBlock.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireSpec.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireStatement.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModStatement.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTypes.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModVisitor.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeBlockImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeSpecImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeStatementImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModGoStatementImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModItemImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModModuleStatementImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceBlockImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceStatementImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireBlockImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireSpecImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireStatementImpl.java create mode 100644 src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModStatementImpl.java create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/filetype/GoModFileType.java create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.flex create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/lang/GoModLanguage.java create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexerAdapter.java create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModElementType.java create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModFile.java create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModParserDefinition.java create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTokenSets.java create mode 100644 src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTokenType.java delete mode 100644 src/main/resources/META-INF/go.xml diff --git a/README.md b/README.md index e9a755e0..6882bf5f 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ vulnerability report. - For Maven projects, analyzing a `pom.xml` file, you must have the `mvn` binary in your IDE's `PATH` environment. - For Node projects, analyzing a `package.json` file, you must have one of the corresponding package manager `npm`, `pnpm` or `yarn`, `node` binaries in your IDE's `PATH` environment. -- For Golang projects, analyzing a `go.mod` file, you must have the `go` binary in your IDE's `PATH` environment. Furthermore, Golang projects can only be analyzed with IntelliJ Ultimate Edition. +- For Golang projects, analyzing a `go.mod` file, you must have the `go` binary in your IDE's `PATH` environment. - For Python projects, analyzing a `requirements.txt` file, you must have the `python3` and `pip3` binaries in your IDE's `PATH` environment. - For Gradle projects, analyzing a `build.gradle` file or `build.gradle.kts` file, you must have the `gradle` binary in your system's `PATH` environment. diff --git a/gradle.properties b/gradle.properties index ca7785ef..a813fb97 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ gradleVersion=8.5 # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html platformBundledPlugins=org.jetbrains.plugins.yaml,com.intellij.java,org.jetbrains.idea.maven -platformPlugins=com.redhat.devtools.intellij.telemetry:1.1.0.52,org.jetbrains.plugins.go:251.23774.200,Docker:251.23774.37 +platformPlugins=com.redhat.devtools.intellij.telemetry:1.1.0.52,Docker:251.23774.37 # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib kotlin.stdlib.default.dependency=false diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java new file mode 100644 index 00000000..c61f1d3c --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java @@ -0,0 +1,638 @@ +// Generated by JFlex 1.9.2 http://jflex.de/ (tweaked for IntelliJ platform) +// source: goMod.flex + +package org.jboss.tools.intellij.componentanalysis.golang.build.lexer; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.tree.IElementType; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes; +import com.intellij.psi.TokenType; + + +class GoModLexer implements FlexLexer { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0 + }; + + /** + * Top-level table for translating characters to character classes + */ + private static final int [] ZZ_CMAP_TOP = zzUnpackcmap_top(); + + private static final String ZZ_CMAP_TOP_PACKED_0 = + "\1\0\u10ff\u0100"; + + private static int [] zzUnpackcmap_top() { + int [] result = new int[4352]; + int offset = 0; + offset = zzUnpackcmap_top(ZZ_CMAP_TOP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackcmap_top(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Second-level tables for translating characters to character classes + */ + private static final int [] ZZ_CMAP_BLOCKS = zzUnpackcmap_blocks(); + + private static final String ZZ_CMAP_BLOCKS_PACKED_0 = + "\11\0\1\1\1\2\1\0\1\1\1\3\22\0\1\1"+ + "\7\0\1\4\1\5\1\0\1\6\1\0\1\7\1\10"+ + "\1\11\12\12\3\0\1\13\1\14\2\0\32\15\4\0"+ + "\1\15\1\0\1\16\1\15\1\17\1\20\1\21\1\15"+ + "\1\22\1\15\1\23\2\15\1\24\1\25\1\26\1\27"+ + "\1\30\1\31\1\32\1\15\1\33\1\34\1\35\1\15"+ + "\1\36\2\15\u0185\0"; + + private static int [] zzUnpackcmap_blocks() { + int [] result = new int[512]; + int offset = 0; + offset = zzUnpackcmap_blocks(ZZ_CMAP_BLOCKS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackcmap_blocks(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\1\0\1\1\1\2\1\3\1\1\1\4\1\5\1\1"+ + "\1\6\1\1\7\7\1\10\3\0\1\11\1\7\1\12"+ + "\3\7\3\6\13\7\1\6\7\7\1\13\2\7\1\14"+ + "\1\7\1\15\1\16\1\17"; + + private static int [] zzUnpackAction() { + int [] result = new int[57]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\37\0\76\0\37\0\135\0\37\0\37\0\174"+ + "\0\233\0\272\0\331\0\370\0\u0117\0\u0136\0\u0155\0\u0174"+ + "\0\u0193\0\u01b2\0\u01d1\0\u01f0\0\u020f\0\37\0\u022e\0\331"+ + "\0\u024d\0\u026c\0\u028b\0\u02aa\0\u01d1\0\u02c9\0\u02e8\0\u0307"+ + "\0\u0326\0\u0345\0\u0364\0\u0383\0\u03a2\0\u03c1\0\u03e0\0\u03ff"+ + "\0\u041e\0\u043d\0\u045c\0\u047b\0\u049a\0\u04b9\0\u04d8\0\u04f7"+ + "\0\u0516\0\331\0\u0535\0\u0554\0\331\0\u0573\0\331\0\331"+ + "\0\331"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[57]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length() - 1; + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpacktrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\2\1\3\1\4\1\5\1\6\1\7\3\2\1\10"+ + "\1\11\1\12\1\2\4\13\1\14\1\15\1\16\1\13"+ + "\1\17\4\13\1\20\2\13\1\21\1\13\40\0\1\3"+ + "\37\0\1\4\45\0\1\22\33\0\1\23\1\24\1\25"+ + "\1\0\1\11\40\0\1\26\31\0\4\13\2\0\22\13"+ + "\7\0\4\13\2\0\21\13\1\27\7\0\4\13\2\0"+ + "\12\13\1\30\7\13\7\0\4\13\2\0\11\13\1\31"+ + "\10\13\7\0\4\13\2\0\12\13\1\32\7\13\7\0"+ + "\4\13\2\0\4\13\1\33\15\13\7\0\3\13\1\34"+ + "\2\0\22\13\2\22\2\0\33\22\7\0\2\35\1\0"+ + "\1\35\2\0\22\35\7\0\2\36\1\0\1\36\2\0"+ + "\22\36\12\0\1\11\33\0\4\13\2\0\2\13\1\37"+ + "\17\13\7\0\4\13\2\0\3\13\1\40\16\13\7\0"+ + "\4\13\2\0\3\13\1\41\16\13\7\0\4\13\2\0"+ + "\13\13\1\42\1\43\5\13\6\0\1\23\1\44\1\21"+ + "\1\13\1\34\2\0\22\13\6\0\1\23\2\36\1\0"+ + "\1\36\2\0\22\36\7\0\4\13\2\0\7\13\1\45"+ + "\12\13\7\0\4\13\2\0\6\13\1\46\13\13\7\0"+ + "\4\13\2\0\17\13\1\47\2\13\7\0\4\13\2\0"+ + "\7\13\1\50\12\13\7\0\4\13\2\0\17\13\1\51"+ + "\2\13\7\0\2\52\1\13\1\52\2\0\22\52\7\0"+ + "\4\13\2\0\17\13\1\53\2\13\7\0\4\13\2\0"+ + "\15\13\1\54\4\13\7\0\4\13\2\0\7\13\1\55"+ + "\12\13\7\0\4\13\2\0\1\13\1\56\20\13\7\0"+ + "\4\13\2\0\6\13\1\57\13\13\6\0\1\23\2\52"+ + "\1\13\1\52\2\0\22\52\7\0\4\13\2\0\3\13"+ + "\1\60\16\13\7\0\4\13\2\0\4\13\1\61\15\13"+ + "\7\0\4\13\2\0\4\13\1\62\15\13\7\0\4\13"+ + "\2\0\2\13\1\63\17\13\7\0\4\13\2\0\15\13"+ + "\1\64\4\13\7\0\4\13\2\0\4\13\1\65\15\13"+ + "\7\0\4\13\2\0\2\13\1\66\17\13\7\0\4\13"+ + "\2\0\4\13\1\67\15\13\7\0\4\13\2\0\4\13"+ + "\1\70\15\13\7\0\4\13\2\0\16\13\1\71\3\13"; + + private static int [] zzUnpacktrans() { + int [] result = new int[1426]; + int offset = 0; + offset = zzUnpacktrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpacktrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String[] ZZ_ERROR_MSG = { + "Unknown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state {@code aState} + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\1\0\1\11\1\1\1\11\1\1\2\11\13\1\3\0"+ + "\1\11\43\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[57]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private CharSequence zzBuffer = ""; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** Number of newlines encountered up to the start of the matched text. */ + @SuppressWarnings("unused") + private int yyline; + + /** Number of characters from the last newline up to the start of the matched text. */ + @SuppressWarnings("unused") + protected int yycolumn; + + /** Number of characters up to the start of the matched text. */ + @SuppressWarnings("unused") + private long yychar; + + /** Whether the scanner is currently at the beginning of a line. */ + @SuppressWarnings("unused") + private boolean zzAtBOL = true; + + /** Whether the user-EOF-code has already been executed. */ + @SuppressWarnings("unused") + private boolean zzEOFDone; + + /* user code: */ + public GoModLexer() { + this((java.io.Reader)null); + } + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + GoModLexer(java.io.Reader in) { + this.zzReader = in; + } + + + /** Returns the maximum size of the scanner buffer, which limits the size of tokens. */ + private int zzMaxBufferLen() { + return Integer.MAX_VALUE; + } + + /** Whether the scanner buffer can grow to accommodate a larger token. */ + private boolean zzCanGrow() { + return true; + } + + /** + * Translates raw input code points to DFA table row + */ + private static int zzCMap(int input) { + int offset = input & 255; + return offset == input ? ZZ_CMAP_BLOCKS[offset] : ZZ_CMAP_BLOCKS[ZZ_CMAP_TOP[input >> 8] | offset]; + } + + public final int getTokenStart() { + return zzStartRead; + } + + public final int getTokenEnd() { + return getTokenStart() + yylength(); + } + + public void reset(CharSequence buffer, int start, int end, int initialState) { + zzBuffer = buffer; + zzCurrentPos = zzMarkedPos = zzStartRead = start; + zzAtEOF = false; + zzAtBOL = true; + zzEndRead = end; + yybegin(initialState); + } + + /** + * Refills the input buffer. + * + * @return {@code false}, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + return true; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final CharSequence yytext() { + return zzBuffer.subSequence(zzStartRead, zzMarkedPos); + } + + + /** + * Returns the character at position {@code pos} from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer.charAt(zzStartRead+pos); + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occurred while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public IElementType advance() throws java.io.IOException + { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + CharSequence zzBufferL = zzBuffer; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + } + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL); + zzCurrentPosL += Character.charCount(zzInput); + } + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL); + zzCurrentPosL += Character.charCount(zzInput); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMap(zzInput) ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + return null; + } + else { + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { return TokenType.BAD_CHARACTER; + } + // fall through + case 16: break; + case 2: + { return TokenType.WHITE_SPACE; + } + // fall through + case 17: break; + case 3: + { return GoModTypes.NEWLINE; + } + // fall through + case 18: break; + case 4: + { return GoModTypes.LPAREN; + } + // fall through + case 19: break; + case 5: + { return GoModTypes.RPAREN; + } + // fall through + case 20: break; + case 6: + { return GoModTypes.VERSION; + } + // fall through + case 21: break; + case 7: + { return GoModTypes.IDENTIFIER; + } + // fall through + case 22: break; + case 8: + { return GoModTypes.COMMENT; + } + // fall through + case 23: break; + case 9: + { return GoModTypes.ARROW; + } + // fall through + case 24: break; + case 10: + { return GoModTypes.GO; + } + // fall through + case 25: break; + case 11: + { return GoModTypes.MODULE; + } + // fall through + case 26: break; + case 12: + { return GoModTypes.EXCLUDE; + } + // fall through + case 27: break; + case 13: + { return GoModTypes.REPLACE; + } + // fall through + case 28: break; + case 14: + { return GoModTypes.REQUIRE; + } + // fall through + case 29: break; + case 15: + { return GoModTypes.INDIRECT; + } + // fall through + case 30: break; + default: + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java new file mode 100644 index 00000000..35685cdc --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java @@ -0,0 +1,362 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.parser; + +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiBuilder.Marker; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import static com.intellij.lang.parser.GeneratedParserUtilBase.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.lang.ASTNode; +import com.intellij.psi.tree.TokenSet; +import com.intellij.lang.PsiParser; +import com.intellij.lang.LightPsiParser; + +@SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"}) +public class GoModParser implements PsiParser, LightPsiParser { + + public ASTNode parse(IElementType t, PsiBuilder b) { + parseLight(t, b); + return b.getTreeBuilt(); + } + + public void parseLight(IElementType t, PsiBuilder b) { + boolean r; + b = adapt_builder_(t, b, this, null); + Marker m = enter_section_(b, 0, _COLLAPSE_, null); + r = parse_root_(t, b); + exit_section_(b, 0, m, t, r, true, TRUE_CONDITION); + } + + protected boolean parse_root_(IElementType t, PsiBuilder b) { + return parse_root_(t, b, 0); + } + + static boolean parse_root_(IElementType t, PsiBuilder b, int l) { + return goModFile(b, l + 1); + } + + /* ********************************************************** */ + // LPAREN (excludeSpec | COMMENT | NEWLINE)* RPAREN + public static boolean excludeBlock(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "excludeBlock")) return false; + if (!nextTokenIs(b, LPAREN)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, LPAREN); + r = r && excludeBlock_1(b, l + 1); + r = r && consumeToken(b, RPAREN); + exit_section_(b, m, EXCLUDE_BLOCK, r); + return r; + } + + // (excludeSpec | COMMENT | NEWLINE)* + private static boolean excludeBlock_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "excludeBlock_1")) return false; + while (true) { + int c = current_position_(b); + if (!excludeBlock_1_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "excludeBlock_1", c)) break; + } + return true; + } + + // excludeSpec | COMMENT | NEWLINE + private static boolean excludeBlock_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "excludeBlock_1_0")) return false; + boolean r; + r = excludeSpec(b, l + 1); + if (!r) r = consumeToken(b, COMMENT); + if (!r) r = consumeToken(b, NEWLINE); + return r; + } + + /* ********************************************************** */ + // IDENTIFIER VERSION? (COMMENT)* + public static boolean excludeSpec(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "excludeSpec")) return false; + if (!nextTokenIs(b, IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, IDENTIFIER); + r = r && excludeSpec_1(b, l + 1); + r = r && excludeSpec_2(b, l + 1); + exit_section_(b, m, EXCLUDE_SPEC, r); + return r; + } + + // VERSION? + private static boolean excludeSpec_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "excludeSpec_1")) return false; + consumeToken(b, VERSION); + return true; + } + + // (COMMENT)* + private static boolean excludeSpec_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "excludeSpec_2")) return false; + while (true) { + int c = current_position_(b); + if (!consumeToken(b, COMMENT)) break; + if (!empty_element_parsed_guard_(b, "excludeSpec_2", c)) break; + } + return true; + } + + /* ********************************************************** */ + // EXCLUDE (excludeSpec | excludeBlock) + public static boolean excludeStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "excludeStatement")) return false; + if (!nextTokenIs(b, EXCLUDE)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, EXCLUDE); + r = r && excludeStatement_1(b, l + 1); + exit_section_(b, m, EXCLUDE_STATEMENT, r); + return r; + } + + // excludeSpec | excludeBlock + private static boolean excludeStatement_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "excludeStatement_1")) return false; + boolean r; + r = excludeSpec(b, l + 1); + if (!r) r = excludeBlock(b, l + 1); + return r; + } + + /* ********************************************************** */ + // item* + static boolean goModFile(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "goModFile")) return false; + while (true) { + int c = current_position_(b); + if (!item(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "goModFile", c)) break; + } + return true; + } + + /* ********************************************************** */ + // GO VERSION + public static boolean goStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "goStatement")) return false; + if (!nextTokenIs(b, GO)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, GO, VERSION); + exit_section_(b, m, GO_STATEMENT, r); + return r; + } + + /* ********************************************************** */ + // statement | COMMENT | NEWLINE + public static boolean item(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "item")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, ITEM, ""); + r = statement(b, l + 1); + if (!r) r = consumeToken(b, COMMENT); + if (!r) r = consumeToken(b, NEWLINE); + exit_section_(b, l, m, r, false, null); + return r; + } + + /* ********************************************************** */ + // MODULE IDENTIFIER + public static boolean moduleStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "moduleStatement")) return false; + if (!nextTokenIs(b, MODULE)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, MODULE, IDENTIFIER); + exit_section_(b, m, MODULE_STATEMENT, r); + return r; + } + + /* ********************************************************** */ + // LPAREN (replaceSpec | COMMENT | NEWLINE)* RPAREN + public static boolean replaceBlock(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceBlock")) return false; + if (!nextTokenIs(b, LPAREN)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, LPAREN); + r = r && replaceBlock_1(b, l + 1); + r = r && consumeToken(b, RPAREN); + exit_section_(b, m, REPLACE_BLOCK, r); + return r; + } + + // (replaceSpec | COMMENT | NEWLINE)* + private static boolean replaceBlock_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceBlock_1")) return false; + while (true) { + int c = current_position_(b); + if (!replaceBlock_1_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "replaceBlock_1", c)) break; + } + return true; + } + + // replaceSpec | COMMENT | NEWLINE + private static boolean replaceBlock_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceBlock_1_0")) return false; + boolean r; + r = replaceSpec(b, l + 1); + if (!r) r = consumeToken(b, COMMENT); + if (!r) r = consumeToken(b, NEWLINE); + return r; + } + + /* ********************************************************** */ + // IDENTIFIER ARROW IDENTIFIER VERSION (COMMENT)* + public static boolean replaceSpec(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceSpec")) return false; + if (!nextTokenIs(b, IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, IDENTIFIER, ARROW, IDENTIFIER, VERSION); + r = r && replaceSpec_4(b, l + 1); + exit_section_(b, m, REPLACE_SPEC, r); + return r; + } + + // (COMMENT)* + private static boolean replaceSpec_4(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceSpec_4")) return false; + while (true) { + int c = current_position_(b); + if (!consumeToken(b, COMMENT)) break; + if (!empty_element_parsed_guard_(b, "replaceSpec_4", c)) break; + } + return true; + } + + /* ********************************************************** */ + // REPLACE (replaceSpec | replaceBlock) + public static boolean replaceStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceStatement")) return false; + if (!nextTokenIs(b, REPLACE)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, REPLACE); + r = r && replaceStatement_1(b, l + 1); + exit_section_(b, m, REPLACE_STATEMENT, r); + return r; + } + + // replaceSpec | replaceBlock + private static boolean replaceStatement_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceStatement_1")) return false; + boolean r; + r = replaceSpec(b, l + 1); + if (!r) r = replaceBlock(b, l + 1); + return r; + } + + /* ********************************************************** */ + // LPAREN (requireSpec | COMMENT | NEWLINE)* RPAREN + public static boolean requireBlock(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "requireBlock")) return false; + if (!nextTokenIs(b, LPAREN)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, LPAREN); + r = r && requireBlock_1(b, l + 1); + r = r && consumeToken(b, RPAREN); + exit_section_(b, m, REQUIRE_BLOCK, r); + return r; + } + + // (requireSpec | COMMENT | NEWLINE)* + private static boolean requireBlock_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "requireBlock_1")) return false; + while (true) { + int c = current_position_(b); + if (!requireBlock_1_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "requireBlock_1", c)) break; + } + return true; + } + + // requireSpec | COMMENT | NEWLINE + private static boolean requireBlock_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "requireBlock_1_0")) return false; + boolean r; + r = requireSpec(b, l + 1); + if (!r) r = consumeToken(b, COMMENT); + if (!r) r = consumeToken(b, NEWLINE); + return r; + } + + /* ********************************************************** */ + // IDENTIFIER VERSION (INDIRECT | COMMENT)* + public static boolean requireSpec(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "requireSpec")) return false; + if (!nextTokenIs(b, IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, IDENTIFIER, VERSION); + r = r && requireSpec_2(b, l + 1); + exit_section_(b, m, REQUIRE_SPEC, r); + return r; + } + + // (INDIRECT | COMMENT)* + private static boolean requireSpec_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "requireSpec_2")) return false; + while (true) { + int c = current_position_(b); + if (!requireSpec_2_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "requireSpec_2", c)) break; + } + return true; + } + + // INDIRECT | COMMENT + private static boolean requireSpec_2_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "requireSpec_2_0")) return false; + boolean r; + r = consumeToken(b, INDIRECT); + if (!r) r = consumeToken(b, COMMENT); + return r; + } + + /* ********************************************************** */ + // REQUIRE (requireSpec | requireBlock) + public static boolean requireStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "requireStatement")) return false; + if (!nextTokenIs(b, REQUIRE)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, REQUIRE); + r = r && requireStatement_1(b, l + 1); + exit_section_(b, m, REQUIRE_STATEMENT, r); + return r; + } + + // requireSpec | requireBlock + private static boolean requireStatement_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "requireStatement_1")) return false; + boolean r; + r = requireSpec(b, l + 1); + if (!r) r = requireBlock(b, l + 1); + return r; + } + + /* ********************************************************** */ + // moduleStatement | goStatement | requireStatement | replaceStatement | excludeStatement + public static boolean statement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "statement")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, STATEMENT, ""); + r = moduleStatement(b, l + 1); + if (!r) r = goStatement(b, l + 1); + if (!r) r = requireStatement(b, l + 1); + if (!r) r = replaceStatement(b, l + 1); + if (!r) r = excludeStatement(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeBlock.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeBlock.java new file mode 100644 index 00000000..7aa185a7 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeBlock.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModExcludeBlock extends PsiElement { + + @NotNull + List getExcludeSpecList(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeSpec.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeSpec.java new file mode 100644 index 00000000..29a44919 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeSpec.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModExcludeSpec extends PsiElement { + + @NotNull + PsiElement getIdentifier(); + + @Nullable + PsiElement getVersion(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeStatement.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeStatement.java new file mode 100644 index 00000000..8c19ff7e --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModExcludeStatement.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModExcludeStatement extends PsiElement { + + @Nullable + GoModExcludeBlock getExcludeBlock(); + + @Nullable + GoModExcludeSpec getExcludeSpec(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModGoStatement.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModGoStatement.java new file mode 100644 index 00000000..273784d6 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModGoStatement.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModGoStatement extends PsiElement { + + @NotNull + PsiElement getVersion(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModItem.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModItem.java new file mode 100644 index 00000000..39248e9c --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModItem.java @@ -0,0 +1,19 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModItem extends PsiElement { + + @Nullable + GoModStatement getStatement(); + + @Nullable + PsiElement getComment(); + + @Nullable + PsiElement getNewline(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModModuleStatement.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModModuleStatement.java new file mode 100644 index 00000000..f462cb72 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModModuleStatement.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModModuleStatement extends PsiElement { + + @NotNull + PsiElement getIdentifier(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceBlock.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceBlock.java new file mode 100644 index 00000000..96fac7ec --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceBlock.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModReplaceBlock extends PsiElement { + + @NotNull + List getReplaceSpecList(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java new file mode 100644 index 00000000..c28878a0 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModReplaceSpec extends PsiElement { + + @NotNull + PsiElement getVersion(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceStatement.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceStatement.java new file mode 100644 index 00000000..46b891ad --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceStatement.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModReplaceStatement extends PsiElement { + + @Nullable + GoModReplaceBlock getReplaceBlock(); + + @Nullable + GoModReplaceSpec getReplaceSpec(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireBlock.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireBlock.java new file mode 100644 index 00000000..7f409664 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireBlock.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModRequireBlock extends PsiElement { + + @NotNull + List getRequireSpecList(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireSpec.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireSpec.java new file mode 100644 index 00000000..adba1ea1 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireSpec.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModRequireSpec extends PsiElement { + + @NotNull + PsiElement getIdentifier(); + + @NotNull + PsiElement getVersion(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireStatement.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireStatement.java new file mode 100644 index 00000000..6cdc80de --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModRequireStatement.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModRequireStatement extends PsiElement { + + @Nullable + GoModRequireBlock getRequireBlock(); + + @Nullable + GoModRequireSpec getRequireSpec(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModStatement.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModStatement.java new file mode 100644 index 00000000..ab4e9915 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModStatement.java @@ -0,0 +1,25 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface GoModStatement extends PsiElement { + + @Nullable + GoModExcludeStatement getExcludeStatement(); + + @Nullable + GoModGoStatement getGoStatement(); + + @Nullable + GoModModuleStatement getModuleStatement(); + + @Nullable + GoModReplaceStatement getReplaceStatement(); + + @Nullable + GoModRequireStatement getRequireStatement(); + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTypes.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTypes.java new file mode 100644 index 00000000..d1b27f7a --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTypes.java @@ -0,0 +1,84 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.PsiElement; +import com.intellij.lang.ASTNode; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl.*; + +public interface GoModTypes { + + IElementType EXCLUDE_BLOCK = new GoModElementType("EXCLUDE_BLOCK"); + IElementType EXCLUDE_SPEC = new GoModElementType("EXCLUDE_SPEC"); + IElementType EXCLUDE_STATEMENT = new GoModElementType("EXCLUDE_STATEMENT"); + IElementType GO_STATEMENT = new GoModElementType("GO_STATEMENT"); + IElementType ITEM = new GoModElementType("ITEM"); + IElementType MODULE_STATEMENT = new GoModElementType("MODULE_STATEMENT"); + IElementType REPLACE_BLOCK = new GoModElementType("REPLACE_BLOCK"); + IElementType REPLACE_SPEC = new GoModElementType("REPLACE_SPEC"); + IElementType REPLACE_STATEMENT = new GoModElementType("REPLACE_STATEMENT"); + IElementType REQUIRE_BLOCK = new GoModElementType("REQUIRE_BLOCK"); + IElementType REQUIRE_SPEC = new GoModElementType("REQUIRE_SPEC"); + IElementType REQUIRE_STATEMENT = new GoModElementType("REQUIRE_STATEMENT"); + IElementType STATEMENT = new GoModElementType("STATEMENT"); + + IElementType ARROW = new GoModTokenType("=>"); + IElementType COMMENT = new GoModTokenType("COMMENT"); + IElementType EXCLUDE = new GoModTokenType("exclude"); + IElementType GO = new GoModTokenType("go"); + IElementType IDENTIFIER = new GoModTokenType("IDENTIFIER"); + IElementType INDIRECT = new GoModTokenType("indirect"); + IElementType LPAREN = new GoModTokenType("("); + IElementType MODULE = new GoModTokenType("module"); + IElementType NEWLINE = new GoModTokenType("NEWLINE"); + IElementType REPLACE = new GoModTokenType("replace"); + IElementType REQUIRE = new GoModTokenType("require"); + IElementType RPAREN = new GoModTokenType(")"); + IElementType VERSION = new GoModTokenType("VERSION"); + + class Factory { + public static PsiElement createElement(ASTNode node) { + IElementType type = node.getElementType(); + if (type == EXCLUDE_BLOCK) { + return new GoModExcludeBlockImpl(node); + } + else if (type == EXCLUDE_SPEC) { + return new GoModExcludeSpecImpl(node); + } + else if (type == EXCLUDE_STATEMENT) { + return new GoModExcludeStatementImpl(node); + } + else if (type == GO_STATEMENT) { + return new GoModGoStatementImpl(node); + } + else if (type == ITEM) { + return new GoModItemImpl(node); + } + else if (type == MODULE_STATEMENT) { + return new GoModModuleStatementImpl(node); + } + else if (type == REPLACE_BLOCK) { + return new GoModReplaceBlockImpl(node); + } + else if (type == REPLACE_SPEC) { + return new GoModReplaceSpecImpl(node); + } + else if (type == REPLACE_STATEMENT) { + return new GoModReplaceStatementImpl(node); + } + else if (type == REQUIRE_BLOCK) { + return new GoModRequireBlockImpl(node); + } + else if (type == REQUIRE_SPEC) { + return new GoModRequireSpecImpl(node); + } + else if (type == REQUIRE_STATEMENT) { + return new GoModRequireStatementImpl(node); + } + else if (type == STATEMENT) { + return new GoModStatementImpl(node); + } + throw new AssertionError("Unknown element type: " + type); + } + } +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModVisitor.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModVisitor.java new file mode 100644 index 00000000..e03bf3c7 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModVisitor.java @@ -0,0 +1,66 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiElement; + +public class GoModVisitor extends PsiElementVisitor { + + public void visitExcludeBlock(@NotNull GoModExcludeBlock o) { + visitPsiElement(o); + } + + public void visitExcludeSpec(@NotNull GoModExcludeSpec o) { + visitPsiElement(o); + } + + public void visitExcludeStatement(@NotNull GoModExcludeStatement o) { + visitPsiElement(o); + } + + public void visitGoStatement(@NotNull GoModGoStatement o) { + visitPsiElement(o); + } + + public void visitItem(@NotNull GoModItem o) { + visitPsiElement(o); + } + + public void visitModuleStatement(@NotNull GoModModuleStatement o) { + visitPsiElement(o); + } + + public void visitReplaceBlock(@NotNull GoModReplaceBlock o) { + visitPsiElement(o); + } + + public void visitReplaceSpec(@NotNull GoModReplaceSpec o) { + visitPsiElement(o); + } + + public void visitReplaceStatement(@NotNull GoModReplaceStatement o) { + visitPsiElement(o); + } + + public void visitRequireBlock(@NotNull GoModRequireBlock o) { + visitPsiElement(o); + } + + public void visitRequireSpec(@NotNull GoModRequireSpec o) { + visitPsiElement(o); + } + + public void visitRequireStatement(@NotNull GoModRequireStatement o) { + visitPsiElement(o); + } + + public void visitStatement(@NotNull GoModStatement o) { + visitPsiElement(o); + } + + public void visitPsiElement(@NotNull PsiElement o) { + visitElement(o); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeBlockImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeBlockImpl.java new file mode 100644 index 00000000..ea555017 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeBlockImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModExcludeBlockImpl extends ASTWrapperPsiElement implements GoModExcludeBlock { + + public GoModExcludeBlockImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitExcludeBlock(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public List getExcludeSpecList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, GoModExcludeSpec.class); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeSpecImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeSpecImpl.java new file mode 100644 index 00000000..ab394dda --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeSpecImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModExcludeSpecImpl extends ASTWrapperPsiElement implements GoModExcludeSpec { + + public GoModExcludeSpecImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitExcludeSpec(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public PsiElement getIdentifier() { + return findNotNullChildByType(IDENTIFIER); + } + + @Override + @Nullable + public PsiElement getVersion() { + return findChildByType(VERSION); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeStatementImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeStatementImpl.java new file mode 100644 index 00000000..fc2c25a7 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModExcludeStatementImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModExcludeStatementImpl extends ASTWrapperPsiElement implements GoModExcludeStatement { + + public GoModExcludeStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitExcludeStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @Nullable + public GoModExcludeBlock getExcludeBlock() { + return findChildByClass(GoModExcludeBlock.class); + } + + @Override + @Nullable + public GoModExcludeSpec getExcludeSpec() { + return findChildByClass(GoModExcludeSpec.class); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModGoStatementImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModGoStatementImpl.java new file mode 100644 index 00000000..b9096e6b --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModGoStatementImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModGoStatementImpl extends ASTWrapperPsiElement implements GoModGoStatement { + + public GoModGoStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitGoStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public PsiElement getVersion() { + return findNotNullChildByType(VERSION); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModItemImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModItemImpl.java new file mode 100644 index 00000000..70efdf7a --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModItemImpl.java @@ -0,0 +1,48 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModItemImpl extends ASTWrapperPsiElement implements GoModItem { + + public GoModItemImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitItem(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @Nullable + public GoModStatement getStatement() { + return findChildByClass(GoModStatement.class); + } + + @Override + @Nullable + public PsiElement getComment() { + return findChildByType(COMMENT); + } + + @Override + @Nullable + public PsiElement getNewline() { + return findChildByType(NEWLINE); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModModuleStatementImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModModuleStatementImpl.java new file mode 100644 index 00000000..5d263c38 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModModuleStatementImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModModuleStatementImpl extends ASTWrapperPsiElement implements GoModModuleStatement { + + public GoModModuleStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitModuleStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public PsiElement getIdentifier() { + return findNotNullChildByType(IDENTIFIER); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceBlockImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceBlockImpl.java new file mode 100644 index 00000000..aaa63183 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceBlockImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModReplaceBlockImpl extends ASTWrapperPsiElement implements GoModReplaceBlock { + + public GoModReplaceBlockImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitReplaceBlock(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public List getReplaceSpecList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, GoModReplaceSpec.class); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java new file mode 100644 index 00000000..a68ba5fe --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModReplaceSpecImpl extends ASTWrapperPsiElement implements GoModReplaceSpec { + + public GoModReplaceSpecImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitReplaceSpec(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public PsiElement getVersion() { + return findNotNullChildByType(VERSION); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceStatementImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceStatementImpl.java new file mode 100644 index 00000000..0b3211bb --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceStatementImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModReplaceStatementImpl extends ASTWrapperPsiElement implements GoModReplaceStatement { + + public GoModReplaceStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitReplaceStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @Nullable + public GoModReplaceBlock getReplaceBlock() { + return findChildByClass(GoModReplaceBlock.class); + } + + @Override + @Nullable + public GoModReplaceSpec getReplaceSpec() { + return findChildByClass(GoModReplaceSpec.class); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireBlockImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireBlockImpl.java new file mode 100644 index 00000000..b3ce1ae5 --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireBlockImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModRequireBlockImpl extends ASTWrapperPsiElement implements GoModRequireBlock { + + public GoModRequireBlockImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitRequireBlock(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public List getRequireSpecList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, GoModRequireSpec.class); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireSpecImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireSpecImpl.java new file mode 100644 index 00000000..6e08581f --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireSpecImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModRequireSpecImpl extends ASTWrapperPsiElement implements GoModRequireSpec { + + public GoModRequireSpecImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitRequireSpec(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public PsiElement getIdentifier() { + return findNotNullChildByType(IDENTIFIER); + } + + @Override + @NotNull + public PsiElement getVersion() { + return findNotNullChildByType(VERSION); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireStatementImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireStatementImpl.java new file mode 100644 index 00000000..9d2bfe4d --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModRequireStatementImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModRequireStatementImpl extends ASTWrapperPsiElement implements GoModRequireStatement { + + public GoModRequireStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitRequireStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @Nullable + public GoModRequireBlock getRequireBlock() { + return findChildByClass(GoModRequireBlock.class); + } + + @Override + @Nullable + public GoModRequireSpec getRequireSpec() { + return findChildByClass(GoModRequireSpec.class); + } + +} diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModStatementImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModStatementImpl.java new file mode 100644 index 00000000..7a39ce9b --- /dev/null +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModStatementImpl.java @@ -0,0 +1,60 @@ +// This is a generated file. Not intended for manual editing. +package org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.util.PsiTreeUtil; +import static org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.*; + +public class GoModStatementImpl extends ASTWrapperPsiElement implements GoModStatement { + + public GoModStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull GoModVisitor visitor) { + visitor.visitStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof GoModVisitor) accept((GoModVisitor)visitor); + else super.accept(visitor); + } + + @Override + @Nullable + public GoModExcludeStatement getExcludeStatement() { + return findChildByClass(GoModExcludeStatement.class); + } + + @Override + @Nullable + public GoModGoStatement getGoStatement() { + return findChildByClass(GoModGoStatement.class); + } + + @Override + @Nullable + public GoModModuleStatement getModuleStatement() { + return findChildByClass(GoModModuleStatement.class); + } + + @Override + @Nullable + public GoModReplaceStatement getReplaceStatement() { + return findChildByClass(GoModReplaceStatement.class); + } + + @Override + @Nullable + public GoModRequireStatement getRequireStatement() { + return findChildByClass(GoModRequireStatement.class); + } + +} diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAAnnotator.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAAnnotator.java index a38664e0..d52f81b2 100644 --- a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAAnnotator.java +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAAnnotator.java @@ -11,13 +11,8 @@ package org.jboss.tools.intellij.componentanalysis.golang; -import com.goide.vgo.mod.psi.VgoModuleSpec; -import com.goide.vgo.mod.psi.VgoReplaceDirective; -import com.goide.vgo.mod.psi.VgoRequireDirective; -import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiTreeUtil; import com.redhat.exhort.api.v4.DependencyReport; import org.jboss.tools.intellij.componentanalysis.CAAnnotator; import org.jboss.tools.intellij.componentanalysis.CAIntentionAction; @@ -25,17 +20,20 @@ import org.jboss.tools.intellij.componentanalysis.Dependency; import org.jboss.tools.intellij.componentanalysis.VulnerabilitySource; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static org.jboss.tools.intellij.componentanalysis.CAUtil.EXHORT_IGNORE; public class GoCAAnnotator extends CAAnnotator { + private static final Pattern REQUIRE_PATTERN = Pattern.compile("^\\s*([a-zA-Z0-9._/-]+)\\s+(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)(?:\\s*//.*)?$"); + private static final Pattern REPLACE_PATTERN = Pattern.compile("^\\s*([a-zA-Z0-9._/-]+)\\s*=>\\s*([a-zA-Z0-9._/-]+)\\s+(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)(?:\\s*//.*)?$"); + @Override protected String getInspectionShortName() { return GoCAInspection.SHORT_NAME; @@ -43,47 +41,84 @@ protected String getInspectionShortName() { @Override protected Map> getDependencies(PsiFile file) { - if ("go.mod".equals(file.getName())) { - Map> resultMap = new HashMap<>(); - - VgoRequireDirective[] requires = PsiTreeUtil.getChildrenOfType(file, VgoRequireDirective.class); - if (requires != null) { - Arrays.stream(requires) - .flatMap(r -> r.getModuleSpecList().stream()) - .filter(m -> { - PsiComment[] comments = PsiTreeUtil.getChildrenOfType(m, PsiComment.class); - if (comments != null) { - return Arrays.stream(comments) - .noneMatch(c -> c.getText().contains(EXHORT_IGNORE)); - } - return true; - }) - .forEach(m -> resultMap.computeIfAbsent(createDependency(m), k -> new LinkedList<>()).add(m)); - } + if (!"go.mod".equals(file.getName())) { + return Collections.emptyMap(); + } + + Map> resultMap = new HashMap<>(); + String fileText = file.getText(); + String[] lines = fileText.split("\\n"); - VgoReplaceDirective[] replaces = PsiTreeUtil.getChildrenOfType(file, VgoReplaceDirective.class); - if (replaces != null) { - Arrays.stream(replaces) - .flatMap(r -> r.getReplacementList().stream()) - .filter(r -> { - PsiComment[] comments = PsiTreeUtil.getChildrenOfType(r, PsiComment.class); - if (comments != null) { - return Arrays.stream(comments) - .noneMatch(c -> c.getText().contains(EXHORT_IGNORE)); - } - return true; - }) - .map(r -> r.getTarget()) - .filter(Objects::nonNull) - .filter(t -> t.getModuleVersion() != null) - .forEach(m -> resultMap.computeIfAbsent(createDependency(m), k -> new LinkedList<>()).add(m)); + boolean inRequireBlock = false; + boolean inReplaceBlock = false; + for (int i = 0; i < lines.length; i++) { + String line = lines[i].trim(); + + // Track require/replace blocks + if (line.startsWith("require")) { + inRequireBlock = line.contains("("); + continue; + } + if (line.startsWith("replace")) { + inReplaceBlock = line.contains("("); + continue; + } + if (line.equals(")")) { + inRequireBlock = false; + inReplaceBlock = false; + continue; } - return resultMap; + // Skip if line contains exhortignore + if (line.contains(EXHORT_IGNORE)) { + continue; + } + + PsiElement lineElement = findElementAtLine(file, i); + if (lineElement == null) continue; + + if (inRequireBlock) { + Matcher requireMatcher = REQUIRE_PATTERN.matcher(line); + if (requireMatcher.matches()) { + String modulePath = requireMatcher.group(1); + String version = requireMatcher.group(2); + Dependency dependency = createDependency(modulePath, version); + resultMap.computeIfAbsent(dependency, k -> new LinkedList<>()).add(lineElement); + } + } else if (inReplaceBlock) { + Matcher replaceMatcher = REPLACE_PATTERN.matcher(line); + if (replaceMatcher.matches()) { + String targetPath = replaceMatcher.group(2); + String version = replaceMatcher.group(3); + Dependency dependency = createDependency(targetPath, version); + resultMap.computeIfAbsent(dependency, k -> new LinkedList<>()).add(lineElement); + } + } else { + // Single line require/replace + if (line.startsWith("require ")) { + String requireLine = line.substring(8).trim(); + Matcher requireMatcher = REQUIRE_PATTERN.matcher(requireLine); + if (requireMatcher.matches()) { + String modulePath = requireMatcher.group(1); + String version = requireMatcher.group(2); + Dependency dependency = createDependency(modulePath, version); + resultMap.computeIfAbsent(dependency, k -> new LinkedList<>()).add(lineElement); + } + } else if (line.startsWith("replace ")) { + String replaceLine = line.substring(8).trim(); + Matcher replaceMatcher = REPLACE_PATTERN.matcher(replaceLine); + if (replaceMatcher.matches()) { + String targetPath = replaceMatcher.group(2); + String version = replaceMatcher.group(3); + Dependency dependency = createDependency(targetPath, version); + resultMap.computeIfAbsent(dependency, k -> new LinkedList<>()).add(lineElement); + } + } + } } - return Collections.emptyMap(); + return resultMap; } @Override @@ -98,23 +133,57 @@ protected CAUpdateManifestIntentionAction patchManifest(PsiElement element, Depe @Override protected boolean isQuickFixApplicable(PsiElement element) { - return element instanceof VgoModuleSpec && ((VgoModuleSpec) element).getModuleVersion() != null; + return element != null && element.getContainingFile().getName().equals("go.mod"); } - private static Dependency createDependency(final VgoModuleSpec m) { - String name = m.getIdentifier().getText(); - int index = name.lastIndexOf("/"); + private PsiElement findElementAtLine(PsiFile file, int lineNumber) { + String[] lines = file.getText().split("\\n"); + if (lineNumber >= lines.length) return null; + + int lineStartOffset = 0; + for (int i = 0; i < lineNumber; i++) { + lineStartOffset += lines[i].length() + 1; // +1 for newline + } + + String line = lines[lineNumber]; + + // Find version in the line using regex to get precise position + Matcher versionMatcher = Pattern.compile("(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)").matcher(line); + if (versionMatcher.find()) { + int versionStart = lineStartOffset + versionMatcher.start(); + int versionEnd = lineStartOffset + versionMatcher.end(); + + // Find the PSI element that covers the version + PsiElement versionElement = file.findElementAt(versionStart); + if (versionElement != null) { + // Make sure we get an element that covers the full version + while (versionElement != null && + versionElement.getTextRange().getEndOffset() < versionEnd) { + versionElement = versionElement.getParent(); + } + return versionElement; + } + } + + // Fallback to middle of line if version not found + if (lineStartOffset < file.getTextLength()) { + return file.findElementAt(lineStartOffset + line.length() / 2); + } + return null; + } + + private static Dependency createDependency(String modulePath, String version) { + String name = modulePath; String namespace = null; - if (index > 0) { - namespace = name.substring(0, index); - name = name.substring(index + 1); - } else if (index == 0) { - name = name.substring(index + 1); + + int lastSlash = modulePath.lastIndexOf("/"); + if (lastSlash > 0) { + namespace = modulePath.substring(0, lastSlash); + name = modulePath.substring(lastSlash + 1); + } else if (lastSlash == 0) { + name = modulePath.substring(1); } - PsiElement mv = m.getModuleVersion(); - String version = mv != null - ? mv.getText() - : null; + return new Dependency("golang", namespace, name, version); } -} +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAIntentionAction.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAIntentionAction.java index 397f9640..9a29e694 100644 --- a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAIntentionAction.java +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAIntentionAction.java @@ -11,11 +11,11 @@ package org.jboss.tools.intellij.componentanalysis.golang; -import com.goide.vgo.mod.psi.VgoModuleSpec; -import com.goide.vgo.mod.psi.impl.VgoElementFactory; import com.intellij.codeInsight.intention.FileModifier; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.redhat.exhort.api.v4.DependencyReport; @@ -24,18 +24,33 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public final class GoCAIntentionAction extends CAIntentionAction { + private static final Pattern VERSION_PATTERN = Pattern.compile("(\\s+)(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)"); + GoCAIntentionAction(PsiElement element, VulnerabilitySource source, DependencyReport report) { super(element, source, report); } @Override protected void updateVersion(@NotNull Project project, Editor editor, PsiFile file, String version) { - VgoModuleSpec spec = (VgoModuleSpec) element; - String identifier = spec.getIdentifier().getText(); - VgoModuleSpec newSpec = VgoElementFactory.createModuleSpec(project, identifier + " " + version); - if (newSpec != null) { - element.replace(newSpec); + Document document = PsiDocumentManager.getInstance(project).getDocument(file); + if (document == null) return; + + // Find the line containing our element + int offset = element.getTextOffset(); + int lineNumber = document.getLineNumber(offset); + int lineStart = document.getLineStartOffset(lineNumber); + int lineEnd = document.getLineEndOffset(lineNumber); + String lineText = document.getText().substring(lineStart, lineEnd); + + // Replace the version in the line + Matcher matcher = VERSION_PATTERN.matcher(lineText); + if (matcher.find()) { + String newLineText = lineText.substring(0, matcher.start(2)) + version + lineText.substring(matcher.end(2)); + document.replaceString(lineStart, lineEnd, newLineText); } } @@ -48,4 +63,4 @@ protected void updateVersion(@NotNull Project project, Editor editor, PsiFile fi public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return file != null && "go.mod".equals(file.getName()); } -} +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/filetype/GoModFileType.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/filetype/GoModFileType.java new file mode 100644 index 00000000..5fc534fe --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/filetype/GoModFileType.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang.build.filetype; + +import com.intellij.openapi.fileTypes.LanguageFileType; +import org.jboss.tools.intellij.componentanalysis.golang.build.lang.GoModLanguage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class GoModFileType extends LanguageFileType { + public static final GoModFileType INSTANCE = new GoModFileType(); + + private GoModFileType() { + super(GoModLanguage.INSTANCE); + } + + @Override + public @NotNull String getName() { + return "rhda-go-mod"; + } + + @Override + public @NotNull String getDescription() { + return "Go module file"; + } + + @Override + public @NotNull String getDefaultExtension() { + return "mod"; + } + + @Override + public @Nullable Icon getIcon() { + return null; + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf new file mode 100644 index 00000000..a0d8ef53 --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf @@ -0,0 +1,63 @@ +{ + parserClass="org.jboss.tools.intellij.componentanalysis.golang.build.parser.GoModParser" + + extends="com.intellij.extapi.psi.ASTWrapperPsiElement" + + psiClassPrefix="GoMod" + psiImplClassSuffix="Impl" + psiPackage="org.jboss.tools.intellij.componentanalysis.golang.build.psi" + psiImplPackage="org.jboss.tools.intellij.componentanalysis.golang.build.psi.impl" + + elementTypeHolderClass="org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes" + elementTypeClass="org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModElementType" + tokenTypeClass="org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTokenType" + + tokens=[ + COMMENT='regexp://.*' + + MODULE='module' + GO='go' + REQUIRE='require' + REPLACE='replace' + EXCLUDE='exclude' + INDIRECT='indirect' + + LPAREN='(' + RPAREN=')' + ARROW='=>' + + IDENTIFIER='regexp:[a-zA-Z_][a-zA-Z0-9_./\-]*' + VERSION='regexp:v?[0-9]+(\.[0-9]+)*(\-[a-zA-Z0-9\-_.]+)?(\+[a-zA-Z0-9\-_.]+)?' + + WHITESPACE='regexp:\s+' + NEWLINE='regexp:\r?\n' + ] +} + +goModFile ::= item* + +item ::= statement | COMMENT | NEWLINE + +statement ::= moduleStatement | goStatement | requireStatement | replaceStatement | excludeStatement + +moduleStatement ::= MODULE IDENTIFIER + +goStatement ::= GO VERSION + +requireStatement ::= REQUIRE (requireSpec | requireBlock) + +requireBlock ::= LPAREN (requireSpec | COMMENT | NEWLINE)* RPAREN + +requireSpec ::= IDENTIFIER VERSION (INDIRECT | COMMENT)* + +replaceStatement ::= REPLACE (replaceSpec | replaceBlock) + +replaceBlock ::= LPAREN (replaceSpec | COMMENT | NEWLINE)* RPAREN + +replaceSpec ::= IDENTIFIER ARROW IDENTIFIER VERSION (COMMENT)* + +excludeStatement ::= EXCLUDE (excludeSpec | excludeBlock) + +excludeBlock ::= LPAREN (excludeSpec | COMMENT | NEWLINE)* RPAREN + +excludeSpec ::= IDENTIFIER VERSION? (COMMENT)* \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.flex b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.flex new file mode 100644 index 00000000..baa7b0e8 --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.flex @@ -0,0 +1,68 @@ +package org.jboss.tools.intellij.componentanalysis.golang.build.lexer; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.tree.IElementType; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes; +import com.intellij.psi.TokenType; + +%% + +%class GoModLexer +%implements FlexLexer +%function advance +%type IElementType +%unicode + +%{ + public GoModLexer() { + this((java.io.Reader)null); + } +%} + +// Whitespace and line endings +WHITESPACE = [ \t\f]+ +NEWLINE = \r?\n + +// Comments +COMMENT = "//"[^\r\n]* + +// Keywords +MODULE = "module" +GO = "go" +REQUIRE = "require" +REPLACE = "replace" +EXCLUDE = "exclude" +INDIRECT = "indirect" + +// Operators and delimiters +LPAREN = "(" +RPAREN = ")" +ARROW = "=>" + +// Identifiers and versions +IDENTIFIER = [a-zA-Z_][a-zA-Z0-9_./\-]* +VERSION = v?[0-9]+(\.[0-9]+)*(\-[a-zA-Z0-9\-_.]+)?(\+[a-zA-Z0-9\-_.]+)? + +%% + + { + {WHITESPACE} { return TokenType.WHITE_SPACE; } + {NEWLINE} { return GoModTypes.NEWLINE; } + {COMMENT} { return GoModTypes.COMMENT; } + + {MODULE} { return GoModTypes.MODULE; } + {GO} { return GoModTypes.GO; } + {REQUIRE} { return GoModTypes.REQUIRE; } + {REPLACE} { return GoModTypes.REPLACE; } + {EXCLUDE} { return GoModTypes.EXCLUDE; } + {INDIRECT} { return GoModTypes.INDIRECT; } + + {LPAREN} { return GoModTypes.LPAREN; } + {RPAREN} { return GoModTypes.RPAREN; } + {ARROW} { return GoModTypes.ARROW; } + + {VERSION} { return GoModTypes.VERSION; } + {IDENTIFIER} { return GoModTypes.IDENTIFIER; } + + [^] { return TokenType.BAD_CHARACTER; } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/lang/GoModLanguage.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/lang/GoModLanguage.java new file mode 100644 index 00000000..3fe4f29b --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/lang/GoModLanguage.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang.build.lang; + +import com.intellij.lang.Language; + +public class GoModLanguage extends Language { + public static final GoModLanguage INSTANCE = new GoModLanguage(); + + private GoModLanguage() { + super("rhda-go-mod"); + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexerAdapter.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexerAdapter.java new file mode 100644 index 00000000..47d22e79 --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexerAdapter.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang.build.lexer; + +import com.intellij.lexer.FlexAdapter; + +public class GoModLexerAdapter extends FlexAdapter { + public GoModLexerAdapter() { + super(new GoModLexer()); + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModElementType.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModElementType.java new file mode 100644 index 00000000..7b0460fe --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModElementType.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import com.intellij.psi.tree.IElementType; +import org.jboss.tools.intellij.componentanalysis.golang.build.lang.GoModLanguage; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class GoModElementType extends IElementType { + public GoModElementType(@NotNull @NonNls String debugName) { + super(debugName, GoModLanguage.INSTANCE); + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModFile.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModFile.java new file mode 100644 index 00000000..43ad0859 --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModFile.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import com.intellij.extapi.psi.PsiFileBase; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.FileViewProvider; +import org.jboss.tools.intellij.componentanalysis.golang.build.filetype.GoModFileType; +import org.jboss.tools.intellij.componentanalysis.golang.build.lang.GoModLanguage; +import org.jetbrains.annotations.NotNull; + +public class GoModFile extends PsiFileBase { + public GoModFile(@NotNull FileViewProvider viewProvider) { + super(viewProvider, GoModLanguage.INSTANCE); + } + + @Override + public @NotNull FileType getFileType() { + return GoModFileType.INSTANCE; + } + + @Override + public String toString() { + return "Go Module File"; + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModParserDefinition.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModParserDefinition.java new file mode 100644 index 00000000..c1589f04 --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModParserDefinition.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.ParserDefinition; +import com.intellij.lang.PsiParser; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.project.Project; +import com.intellij.psi.FileViewProvider; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.tree.IFileElementType; +import com.intellij.psi.tree.TokenSet; +import org.jboss.tools.intellij.componentanalysis.golang.build.lang.GoModLanguage; +import org.jboss.tools.intellij.componentanalysis.golang.build.lexer.GoModLexerAdapter; +import org.jboss.tools.intellij.componentanalysis.golang.build.parser.GoModParser; +import org.jetbrains.annotations.NotNull; + +public class GoModParserDefinition implements ParserDefinition { + + private static final IFileElementType FILE = new IFileElementType(GoModLanguage.INSTANCE); + + @Override + public @NotNull Lexer createLexer(Project project) { + return new GoModLexerAdapter(); + } + + @Override + public @NotNull PsiParser createParser(Project project) { + return new GoModParser(); + } + + @Override + public @NotNull IFileElementType getFileNodeType() { + return FILE; + } + + @Override + public @NotNull TokenSet getCommentTokens() { + return GoModTokenSets.COMMENTS; + } + + @Override + public @NotNull TokenSet getStringLiteralElements() { + return TokenSet.EMPTY; + } + + @Override + public @NotNull PsiElement createElement(ASTNode node) { + return GoModTypes.Factory.createElement(node); + } + + @Override + public @NotNull PsiFile createFile(@NotNull FileViewProvider viewProvider) { + return new GoModFile(viewProvider); + } +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTokenSets.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTokenSets.java new file mode 100644 index 00000000..74c017de --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTokenSets.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import com.intellij.psi.tree.TokenSet; + +public class GoModTokenSets { + public static final TokenSet COMMENTS = TokenSet.create(GoModTypes.COMMENT); +} \ No newline at end of file diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTokenType.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTokenType.java new file mode 100644 index 00000000..30267a09 --- /dev/null +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModTokenType.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang.build.psi; + +import com.intellij.psi.tree.IElementType; +import org.jboss.tools.intellij.componentanalysis.golang.build.lang.GoModLanguage; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class GoModTokenType extends IElementType { + public GoModTokenType(@NotNull @NonNls String debugName) { + super(debugName, GoModLanguage.INSTANCE); + } + + @Override + public String toString() { + return "GoModTokenType." + super.toString(); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/go.xml b/src/main/resources/META-INF/go.xml deleted file mode 100644 index c66fd07c..00000000 --- a/src/main/resources/META-INF/go.xml +++ /dev/null @@ -1,11 +0,0 @@ - - com.intellij.modules.platform - - - - - \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index bb021ba7..096b6e1e 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -42,7 +42,7 @@ node binaries in your IDE's PATH environment. It also requires a corresponding lock file to be present in order to analyze package.json files.
  • For Golang projects, analyzing a go.mod file, you must have the go binary in your - IDE's PATH environment. Furthermore, Golang projects can only be analyzed with IntelliJ Ultimate Edition. + IDE's PATH environment.
  • For Python projects, analyzing a requirements.txt file, you must have the python3 and pip3 binaries in your IDE's PATH environment. @@ -411,6 +411,7 @@ 1.2.0

    +

    Go Plugin dependency removal. Golang projects now can be analyzed with IntelliJ Community Edition.

    Add support for user-configurable patterns/globs for excluding manifests from Component Analysis.

    1.1.0

    Added support for Gradle manifest files.

    @@ -478,7 +479,6 @@ org.jetbrains.idea.maven com.redhat.devtools.intellij.telemetry Docker - org.jetbrains.plugins.go @@ -532,6 +532,18 @@ + + + + Date: Tue, 16 Sep 2025 11:50:33 +0800 Subject: [PATCH 2/3] fix: more parser fixes Signed-off-by: Chao Wang --- .../golang/build/lexer/GoModLexer.java | 96 ++++++++++--------- .../golang/build/parser/GoModParser.java | 25 ++++- .../golang/build/psi/GoModReplaceSpec.java | 3 - .../build/psi/impl/GoModReplaceSpecImpl.java | 6 -- .../golang/GoCAAnnotator.java | 28 +++--- .../golang/GoCAIntentionAction.java | 2 +- .../componentanalysis/golang/build/goMod.bnf | 19 ++-- .../componentanalysis/golang/build/goMod.flex | 8 +- src/main/resources/META-INF/plugin.xml | 2 +- 9 files changed, 102 insertions(+), 87 deletions(-) diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java index c61f1d3c..e508fd07 100644 --- a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java @@ -97,13 +97,13 @@ private static int zzUnpackcmap_blocks(String packed, int offset, int [] result) private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\1\0\1\1\1\2\1\3\1\1\1\4\1\5\1\1"+ - "\1\6\1\1\7\7\1\10\3\0\1\11\1\7\1\12"+ - "\3\7\3\6\13\7\1\6\7\7\1\13\2\7\1\14"+ - "\1\7\1\15\1\16\1\17"; + "\1\0\1\1\1\2\1\3\1\1\1\4\1\5\2\1"+ + "\1\6\1\1\7\7\1\0\1\10\3\0\1\11\1\7"+ + "\1\12\3\7\3\6\13\7\1\6\7\7\1\13\2\7"+ + "\1\14\1\7\1\15\1\16\1\17"; private static int [] zzUnpackAction() { - int [] result = new int[57]; + int [] result = new int[59]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -130,15 +130,15 @@ private static int zzUnpackAction(String packed, int offset, int [] result) { private static final String ZZ_ROWMAP_PACKED_0 = "\0\0\0\37\0\76\0\37\0\135\0\37\0\37\0\174"+ "\0\233\0\272\0\331\0\370\0\u0117\0\u0136\0\u0155\0\u0174"+ - "\0\u0193\0\u01b2\0\u01d1\0\u01f0\0\u020f\0\37\0\u022e\0\331"+ - "\0\u024d\0\u026c\0\u028b\0\u02aa\0\u01d1\0\u02c9\0\u02e8\0\u0307"+ + "\0\u0193\0\u01b2\0\u01d1\0\u01f0\0\u020f\0\u022e\0\u024d\0\37"+ + "\0\u026c\0\370\0\u028b\0\u02aa\0\u02c9\0\u02e8\0\u020f\0\u0307"+ "\0\u0326\0\u0345\0\u0364\0\u0383\0\u03a2\0\u03c1\0\u03e0\0\u03ff"+ "\0\u041e\0\u043d\0\u045c\0\u047b\0\u049a\0\u04b9\0\u04d8\0\u04f7"+ - "\0\u0516\0\331\0\u0535\0\u0554\0\331\0\u0573\0\331\0\331"+ - "\0\331"; + "\0\u0516\0\u0535\0\u0554\0\370\0\u0573\0\u0592\0\370\0\u05b1"+ + "\0\370\0\370\0\370"; private static int [] zzUnpackRowMap() { - int [] result = new int[57]; + int [] result = new int[59]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -161,42 +161,44 @@ private static int zzUnpackRowMap(String packed, int offset, int [] result) { private static final int [] ZZ_TRANS = zzUnpacktrans(); private static final String ZZ_TRANS_PACKED_0 = - "\1\2\1\3\1\4\1\5\1\6\1\7\3\2\1\10"+ - "\1\11\1\12\1\2\4\13\1\14\1\15\1\16\1\13"+ - "\1\17\4\13\1\20\2\13\1\21\1\13\40\0\1\3"+ - "\37\0\1\4\45\0\1\22\33\0\1\23\1\24\1\25"+ - "\1\0\1\11\40\0\1\26\31\0\4\13\2\0\22\13"+ - "\7\0\4\13\2\0\21\13\1\27\7\0\4\13\2\0"+ - "\12\13\1\30\7\13\7\0\4\13\2\0\11\13\1\31"+ - "\10\13\7\0\4\13\2\0\12\13\1\32\7\13\7\0"+ - "\4\13\2\0\4\13\1\33\15\13\7\0\3\13\1\34"+ - "\2\0\22\13\2\22\2\0\33\22\7\0\2\35\1\0"+ - "\1\35\2\0\22\35\7\0\2\36\1\0\1\36\2\0"+ - "\22\36\12\0\1\11\33\0\4\13\2\0\2\13\1\37"+ - "\17\13\7\0\4\13\2\0\3\13\1\40\16\13\7\0"+ - "\4\13\2\0\3\13\1\41\16\13\7\0\4\13\2\0"+ - "\13\13\1\42\1\43\5\13\6\0\1\23\1\44\1\21"+ - "\1\13\1\34\2\0\22\13\6\0\1\23\2\36\1\0"+ - "\1\36\2\0\22\36\7\0\4\13\2\0\7\13\1\45"+ - "\12\13\7\0\4\13\2\0\6\13\1\46\13\13\7\0"+ - "\4\13\2\0\17\13\1\47\2\13\7\0\4\13\2\0"+ - "\7\13\1\50\12\13\7\0\4\13\2\0\17\13\1\51"+ - "\2\13\7\0\2\52\1\13\1\52\2\0\22\52\7\0"+ - "\4\13\2\0\17\13\1\53\2\13\7\0\4\13\2\0"+ - "\15\13\1\54\4\13\7\0\4\13\2\0\7\13\1\55"+ - "\12\13\7\0\4\13\2\0\1\13\1\56\20\13\7\0"+ - "\4\13\2\0\6\13\1\57\13\13\6\0\1\23\2\52"+ - "\1\13\1\52\2\0\22\52\7\0\4\13\2\0\3\13"+ - "\1\60\16\13\7\0\4\13\2\0\4\13\1\61\15\13"+ - "\7\0\4\13\2\0\4\13\1\62\15\13\7\0\4\13"+ - "\2\0\2\13\1\63\17\13\7\0\4\13\2\0\15\13"+ - "\1\64\4\13\7\0\4\13\2\0\4\13\1\65\15\13"+ - "\7\0\4\13\2\0\2\13\1\66\17\13\7\0\4\13"+ - "\2\0\4\13\1\67\15\13\7\0\4\13\2\0\4\13"+ - "\1\70\15\13\7\0\4\13\2\0\16\13\1\71\3\13"; + "\1\2\1\3\1\4\1\5\1\6\1\7\2\2\1\10"+ + "\1\11\1\12\1\13\1\2\4\14\1\15\1\16\1\17"+ + "\1\14\1\20\4\14\1\21\2\14\1\22\1\14\40\0"+ + "\1\3\37\0\1\4\44\0\1\23\35\0\2\14\1\24"+ + "\1\14\2\0\22\14\6\0\1\25\1\26\1\27\1\0"+ + "\1\12\40\0\1\30\31\0\4\14\2\0\22\14\7\0"+ + "\4\14\2\0\21\14\1\31\7\0\4\14\2\0\12\14"+ + "\1\32\7\14\7\0\4\14\2\0\11\14\1\33\10\14"+ + "\7\0\4\14\2\0\12\14\1\34\7\14\7\0\4\14"+ + "\2\0\4\14\1\35\15\14\7\0\3\14\1\36\2\0"+ + "\22\14\11\0\1\14\25\0\2\24\2\0\33\24\7\0"+ + "\2\37\1\0\1\37\2\0\22\37\7\0\2\40\1\0"+ + "\1\40\2\0\22\40\12\0\1\12\33\0\4\14\2\0"+ + "\2\14\1\41\17\14\7\0\4\14\2\0\3\14\1\42"+ + "\16\14\7\0\4\14\2\0\3\14\1\43\16\14\7\0"+ + "\4\14\2\0\13\14\1\44\1\45\5\14\6\0\1\25"+ + "\1\46\1\22\1\14\1\36\2\0\22\14\6\0\1\25"+ + "\2\40\1\0\1\40\2\0\22\40\7\0\4\14\2\0"+ + "\7\14\1\47\12\14\7\0\4\14\2\0\6\14\1\50"+ + "\13\14\7\0\4\14\2\0\17\14\1\51\2\14\7\0"+ + "\4\14\2\0\7\14\1\52\12\14\7\0\4\14\2\0"+ + "\17\14\1\53\2\14\7\0\2\54\1\14\1\54\2\0"+ + "\22\54\7\0\4\14\2\0\17\14\1\55\2\14\7\0"+ + "\4\14\2\0\15\14\1\56\4\14\7\0\4\14\2\0"+ + "\7\14\1\57\12\14\7\0\4\14\2\0\1\14\1\60"+ + "\20\14\7\0\4\14\2\0\6\14\1\61\13\14\6\0"+ + "\1\25\2\54\1\14\1\54\2\0\22\54\7\0\4\14"+ + "\2\0\3\14\1\62\16\14\7\0\4\14\2\0\4\14"+ + "\1\63\15\14\7\0\4\14\2\0\4\14\1\64\15\14"+ + "\7\0\4\14\2\0\2\14\1\65\17\14\7\0\4\14"+ + "\2\0\15\14\1\66\4\14\7\0\4\14\2\0\4\14"+ + "\1\67\15\14\7\0\4\14\2\0\2\14\1\70\17\14"+ + "\7\0\4\14\2\0\4\14\1\71\15\14\7\0\4\14"+ + "\2\0\4\14\1\72\15\14\7\0\4\14\2\0\16\14"+ + "\1\73\3\14"; private static int [] zzUnpacktrans() { - int [] result = new int[1426]; + int [] result = new int[1488]; int offset = 0; offset = zzUnpacktrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -234,11 +236,11 @@ private static int zzUnpacktrans(String packed, int offset, int [] result) { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\0\1\11\1\1\1\11\1\1\2\11\13\1\3\0"+ - "\1\11\43\1"; + "\1\0\1\11\1\1\1\11\1\1\2\11\13\1\1\0"+ + "\1\1\3\0\1\11\43\1"; private static int [] zzUnpackAttribute() { - int [] result = new int[57]; + int [] result = new int[59]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java index 35685cdc..59d393fe 100644 --- a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java @@ -209,25 +209,42 @@ private static boolean replaceBlock_1_0(PsiBuilder b, int l) { } /* ********************************************************** */ - // IDENTIFIER ARROW IDENTIFIER VERSION (COMMENT)* + // IDENTIFIER VERSION? ARROW IDENTIFIER VERSION? (COMMENT)* public static boolean replaceSpec(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "replaceSpec")) return false; if (!nextTokenIs(b, IDENTIFIER)) return false; boolean r; Marker m = enter_section_(b); - r = consumeTokens(b, 0, IDENTIFIER, ARROW, IDENTIFIER, VERSION); + r = consumeToken(b, IDENTIFIER); + r = r && replaceSpec_1(b, l + 1); + r = r && consumeTokens(b, 0, ARROW, IDENTIFIER); r = r && replaceSpec_4(b, l + 1); + r = r && replaceSpec_5(b, l + 1); exit_section_(b, m, REPLACE_SPEC, r); return r; } - // (COMMENT)* + // VERSION? + private static boolean replaceSpec_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceSpec_1")) return false; + consumeToken(b, VERSION); + return true; + } + + // VERSION? private static boolean replaceSpec_4(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "replaceSpec_4")) return false; + consumeToken(b, VERSION); + return true; + } + + // (COMMENT)* + private static boolean replaceSpec_5(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "replaceSpec_5")) return false; while (true) { int c = current_position_(b); if (!consumeToken(b, COMMENT)) break; - if (!empty_element_parsed_guard_(b, "replaceSpec_4", c)) break; + if (!empty_element_parsed_guard_(b, "replaceSpec_5", c)) break; } return true; } diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java index c28878a0..c935fa23 100644 --- a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java @@ -7,7 +7,4 @@ public interface GoModReplaceSpec extends PsiElement { - @NotNull - PsiElement getVersion(); - } diff --git a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java index a68ba5fe..bddb12e9 100644 --- a/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java +++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java @@ -27,10 +27,4 @@ public void accept(@NotNull PsiElementVisitor visitor) { else super.accept(visitor); } - @Override - @NotNull - public PsiElement getVersion() { - return findNotNullChildByType(VERSION); - } - } diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAAnnotator.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAAnnotator.java index d52f81b2..4343e749 100644 --- a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAAnnotator.java +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAAnnotator.java @@ -31,8 +31,8 @@ import static org.jboss.tools.intellij.componentanalysis.CAUtil.EXHORT_IGNORE; public class GoCAAnnotator extends CAAnnotator { - private static final Pattern REQUIRE_PATTERN = Pattern.compile("^\\s*([a-zA-Z0-9._/-]+)\\s+(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)(?:\\s*//.*)?$"); - private static final Pattern REPLACE_PATTERN = Pattern.compile("^\\s*([a-zA-Z0-9._/-]+)\\s*=>\\s*([a-zA-Z0-9._/-]+)\\s+(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)(?:\\s*//.*)?$"); + public static final Pattern REQUIRE_PATTERN = Pattern.compile("^\\s*([a-zA-Z0-9._/-]+)\\s+(v?[0-9]+(?:\\.[0-9]+)*[0-9a-zA-Z\\-+._]*)(?:\\s*//.*)?$"); + public static final Pattern REPLACE_PATTERN = Pattern.compile("^\\s*([a-zA-Z0-9._/-]+)\\s+(?:(v?[0-9]+(?:\\.[0-9]+)*[0-9a-zA-Z\\-+._]*)\\s+)?=>\\s*([a-zA-Z0-9._/:-]+|\\.\\.?/[a-zA-Z0-9._/-]*|/[a-zA-Z0-9._/-]*)(?:\\s+(v?[0-9]+(?:\\.[0-9]+)*[0-9a-zA-Z\\-+._]*))?(?:\\s*//.*)?$"); @Override protected String getInspectionShortName() { @@ -89,10 +89,13 @@ protected Map> getDependencies(PsiFile file) { } else if (inReplaceBlock) { Matcher replaceMatcher = REPLACE_PATTERN.matcher(line); if (replaceMatcher.matches()) { - String targetPath = replaceMatcher.group(2); - String version = replaceMatcher.group(3); - Dependency dependency = createDependency(targetPath, version); - resultMap.computeIfAbsent(dependency, k -> new LinkedList<>()).add(lineElement); + String targetPath = replaceMatcher.group(3); + String version = replaceMatcher.group(4) != null ? replaceMatcher.group(4) : replaceMatcher.group(2); + // Only analyze if target is not a local path and has a version + if (version != null && !targetPath.startsWith("./") && !targetPath.startsWith("../") && !targetPath.startsWith("/")) { + Dependency dependency = createDependency(targetPath, version); + resultMap.computeIfAbsent(dependency, k -> new LinkedList<>()).add(lineElement); + } } } else { // Single line require/replace @@ -109,10 +112,13 @@ protected Map> getDependencies(PsiFile file) { String replaceLine = line.substring(8).trim(); Matcher replaceMatcher = REPLACE_PATTERN.matcher(replaceLine); if (replaceMatcher.matches()) { - String targetPath = replaceMatcher.group(2); - String version = replaceMatcher.group(3); - Dependency dependency = createDependency(targetPath, version); - resultMap.computeIfAbsent(dependency, k -> new LinkedList<>()).add(lineElement); + String targetPath = replaceMatcher.group(3); + String version = replaceMatcher.group(4) != null ? replaceMatcher.group(4) : replaceMatcher.group(2); + // Only analyze if target is not a local path and has a version + if (version != null && !targetPath.startsWith("./") && !targetPath.startsWith("../") && !targetPath.startsWith("/")) { + Dependency dependency = createDependency(targetPath, version); + resultMap.computeIfAbsent(dependency, k -> new LinkedList<>()).add(lineElement); + } } } } @@ -148,7 +154,7 @@ private PsiElement findElementAtLine(PsiFile file, int lineNumber) { String line = lines[lineNumber]; // Find version in the line using regex to get precise position - Matcher versionMatcher = Pattern.compile("(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)").matcher(line); + Matcher versionMatcher = Pattern.compile("(v?[0-9]+(?:\\.[0-9]+)*[0-9a-zA-Z\\-+._]*)").matcher(line); if (versionMatcher.find()) { int versionStart = lineStartOffset + versionMatcher.start(); int versionEnd = lineStartOffset + versionMatcher.end(); diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAIntentionAction.java b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAIntentionAction.java index 9a29e694..d1e0f669 100644 --- a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAIntentionAction.java +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/GoCAIntentionAction.java @@ -28,7 +28,7 @@ import java.util.regex.Pattern; public final class GoCAIntentionAction extends CAIntentionAction { - private static final Pattern VERSION_PATTERN = Pattern.compile("(\\s+)(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)"); + public static final Pattern VERSION_PATTERN = Pattern.compile("(\\s+)(v?[0-9]+\\.[0-9]+\\.[0-9]+\\S*)"); GoCAIntentionAction(PsiElement element, VulnerabilitySource source, DependencyReport report) { super(element, source, report); diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf index a0d8ef53..51ff6835 100644 --- a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf @@ -13,24 +13,23 @@ tokenTypeClass="org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTokenType" tokens=[ - COMMENT='regexp://.*' - + COMMENT + MODULE='module' GO='go' REQUIRE='require' REPLACE='replace' EXCLUDE='exclude' INDIRECT='indirect' - + LPAREN='(' RPAREN=')' ARROW='=>' - - IDENTIFIER='regexp:[a-zA-Z_][a-zA-Z0-9_./\-]*' - VERSION='regexp:v?[0-9]+(\.[0-9]+)*(\-[a-zA-Z0-9\-_.]+)?(\+[a-zA-Z0-9\-_.]+)?' - - WHITESPACE='regexp:\s+' - NEWLINE='regexp:\r?\n' + + IDENTIFIER + VERSION + + NEWLINE ] } @@ -54,7 +53,7 @@ replaceStatement ::= REPLACE (replaceSpec | replaceBlock) replaceBlock ::= LPAREN (replaceSpec | COMMENT | NEWLINE)* RPAREN -replaceSpec ::= IDENTIFIER ARROW IDENTIFIER VERSION (COMMENT)* +replaceSpec ::= IDENTIFIER VERSION? ARROW IDENTIFIER VERSION? (COMMENT)* excludeStatement ::= EXCLUDE (excludeSpec | excludeBlock) diff --git a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.flex b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.flex index baa7b0e8..bc455807 100644 --- a/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.flex +++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.flex @@ -39,9 +39,9 @@ LPAREN = "(" RPAREN = ")" ARROW = "=>" -// Identifiers and versions -IDENTIFIER = [a-zA-Z_][a-zA-Z0-9_./\-]* -VERSION = v?[0-9]+(\.[0-9]+)*(\-[a-zA-Z0-9\-_.]+)?(\+[a-zA-Z0-9\-_.]+)? +// Identifiers and versions - VERSION must come before IDENTIFIER to avoid conflicts +VERSION = v?[0-9]+(\.[0-9]+)*(-[0-9a-zA-Z\-_.]+)?(\+[0-9a-zA-Z\-_.]+)? +IDENTIFIER = (\.\.\/[a-zA-Z0-9_\.\/\-]*|\/[a-zA-Z0-9_\.\/\-]+|[a-zA-Z_][a-zA-Z0-9_\.\/\-]*) %% @@ -56,7 +56,7 @@ VERSION = v?[0-9]+(\.[0-9]+)*(\-[a-zA-Z0-9\-_.]+)?(\+[a-zA-Z0-9\-_.]+)? {REPLACE} { return GoModTypes.REPLACE; } {EXCLUDE} { return GoModTypes.EXCLUDE; } {INDIRECT} { return GoModTypes.INDIRECT; } - + {LPAREN} { return GoModTypes.LPAREN; } {RPAREN} { return GoModTypes.RPAREN; } {ARROW} { return GoModTypes.ARROW; } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 096b6e1e..8396f138 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -411,7 +411,7 @@ 1.2.0

    -

    Go Plugin dependency removal. Golang projects now can be analyzed with IntelliJ Community Edition.

    +

    Go Plugin dependency removal. Golang projects now can be analyzed with IntelliJ Community Edition (no longer requires Ultimate Edition).

    Add support for user-configurable patterns/globs for excluding manifests from Component Analysis.

    1.1.0

    Added support for Gradle manifest files.

    From 1c1b2d5e2f1eba165779cb56cb0db96d9f6da1a7 Mon Sep 17 00:00:00 2001 From: Chao Wang Date: Tue, 16 Sep 2025 12:55:39 +0800 Subject: [PATCH 3/3] test: Add GoModGeneratedParserTest.java and GoModParserTest.java --- .../golang/GoModGeneratedParserTest.java | 159 +++++++ .../golang/GoModParserTest.java | 388 ++++++++++++++++++ 2 files changed, 547 insertions(+) create mode 100644 src/test/java/org/jboss/tools/intellij/componentanalysis/golang/GoModGeneratedParserTest.java create mode 100644 src/test/java/org/jboss/tools/intellij/componentanalysis/golang/GoModParserTest.java diff --git a/src/test/java/org/jboss/tools/intellij/componentanalysis/golang/GoModGeneratedParserTest.java b/src/test/java/org/jboss/tools/intellij/componentanalysis/golang/GoModGeneratedParserTest.java new file mode 100644 index 00000000..3a9bd653 --- /dev/null +++ b/src/test/java/org/jboss/tools/intellij/componentanalysis/golang/GoModGeneratedParserTest.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * Copyright (c) 2025 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiFileFactory; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.testFramework.fixtures.BasePlatformTestCase; +import org.jboss.tools.intellij.componentanalysis.golang.build.filetype.GoModFileType; +import org.jboss.tools.intellij.componentanalysis.golang.build.lexer.GoModLexerAdapter; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModFile; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModGoStatement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModModuleStatement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModReplaceStatement; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModRequireBlock; +import org.jboss.tools.intellij.componentanalysis.golang.build.psi.GoModTypes; + +import java.util.Collection; + +/** + * Tests for the generated parser classes from goMod.bnf and goMod.flex. + * These tests verify the PSI element creation and structure parsing. + */ +public class GoModGeneratedParserTest extends BasePlatformTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + public void testLexerExists() { + // Test that the generated lexer can be instantiated + Lexer lexer = new GoModLexerAdapter(); + assertNotNull("Generated lexer should be instantiable", lexer); + + // Test basic lexer functionality + String simpleContent = "module test"; + lexer.start(simpleContent); + assertNotNull("Lexer should start with a token", lexer.getTokenType()); + } + + public void testParserCreatesCorrectPSIStructure() { + // Test parsing a simple go.mod file first + String simpleContent = "module test\ngo 1.18\n"; + PsiFile psiFile = createGoModFile(simpleContent); + + assertNotNull("PSI file should be created", psiFile); + assertTrue("Should be GoModFile", psiFile instanceof GoModFile); + + // Debug: Print all children to see what's actually created + System.out.println("PSI file children:"); + for (PsiElement child : psiFile.getChildren()) { + System.out.println(" " + child.getClass().getSimpleName() + ": " + child.getText()); + } + + // Test basic elements exist + Collection moduleStatements = PsiTreeUtil.findChildrenOfType(psiFile, GoModModuleStatement.class); + assertEquals("Should find 1 module statement", 1, moduleStatements.size()); + + Collection goStatements = PsiTreeUtil.findChildrenOfType(psiFile, GoModGoStatement.class); + assertEquals("Should find 1 go statement", 1, goStatements.size()); + } + + public void testRequireBlockParsing() { + // Test simple require block parsing + String requireBlockContent = "module test\nrequire (\n github.com/gin-gonic/gin v1.4.0\n)"; + + PsiFile psiFile = createGoModFile(requireBlockContent); + assertNotNull("Should create PSI file", psiFile); + + Collection requireBlocks = PsiTreeUtil.findChildrenOfType(psiFile, GoModRequireBlock.class); + if (!requireBlocks.isEmpty()) { + GoModRequireBlock requireBlock = requireBlocks.iterator().next(); + assertNotNull("Should parse require block", requireBlock); + } + } + + public void testReplaceBlockParsing() { + // Test simple replace parsing + String replaceContent = "module test\nreplace github.com/gin-gonic/gin => github.com/myfork/gin v1.9.1"; + + PsiFile psiFile = createGoModFile(replaceContent); + assertNotNull("Should create PSI file", psiFile); + + Collection replaceStatements = PsiTreeUtil.findChildrenOfType(psiFile, GoModReplaceStatement.class); + assertFalse("Should find replace statement", replaceStatements.isEmpty()); + } + + public void testSingleLineStatements() { + // Test that parser can handle single line statements - very basic test + String singleLineContent = "module test\nrequire github.com/gin-gonic/gin v1.4.0\n"; + + PsiFile psiFile = createGoModFile(singleLineContent); + assertNotNull("Should create PSI file", psiFile); + + // Just verify some PSI structure exists, don't be too specific about what + assertTrue("Should have some child elements", psiFile.getChildren().length > 0); + } + + public void testCommentHandling() { + // Test that comments don't break parsing + String commentContent = "module test\n// This is a comment\ngo 1.18\n"; + + PsiFile psiFile = createGoModFile(commentContent); + assertNotNull("Should parse file with comments", psiFile); + + Collection goStatements = PsiTreeUtil.findChildrenOfType(psiFile, GoModGoStatement.class); + assertEquals("Should find go statement despite comment", 1, goStatements.size()); + } + + public void testBasicParserFunctionality() { + // Test that the parser can create a PSI file and basic elements + String simpleContent = "module test\ngo 1.18\n"; + + PsiFile psiFile = createGoModFile(simpleContent); + assertNotNull("Should create PSI file", psiFile); + assertTrue("Should be GoModFile", psiFile instanceof GoModFile); + + // Test that basic parsing works + GoModModuleStatement moduleStatement = PsiTreeUtil.findChildOfType(psiFile, GoModModuleStatement.class); + assertNotNull("Should find module statement", moduleStatement); + + GoModGoStatement goStatement = PsiTreeUtil.findChildOfType(psiFile, GoModGoStatement.class); + assertNotNull("Should find go statement", goStatement); + } + + public void testGeneratedPSIElementTypes() { + // Test that the generated PSI element types exist and work + assertNotNull("REQUIRE_SPEC type should exist", GoModTypes.REQUIRE_SPEC); + assertNotNull("REPLACE_SPEC type should exist", GoModTypes.REPLACE_SPEC); + assertNotNull("MODULE_STATEMENT type should exist", GoModTypes.MODULE_STATEMENT); + assertNotNull("GO_STATEMENT type should exist", GoModTypes.GO_STATEMENT); + + // Test token types + assertNotNull("MODULE token should exist", GoModTypes.MODULE); + assertNotNull("REQUIRE token should exist", GoModTypes.REQUIRE); + assertNotNull("REPLACE token should exist", GoModTypes.REPLACE); + assertNotNull("VERSION token should exist", GoModTypes.VERSION); + assertNotNull("IDENTIFIER token should exist", GoModTypes.IDENTIFIER); + } + + private PsiFile createGoModFile(String content) { + Project project = getProject(); + return PsiFileFactory.getInstance(project) + .createFileFromText("go.mod", GoModFileType.INSTANCE, content); + } +} \ No newline at end of file diff --git a/src/test/java/org/jboss/tools/intellij/componentanalysis/golang/GoModParserTest.java b/src/test/java/org/jboss/tools/intellij/componentanalysis/golang/GoModParserTest.java new file mode 100644 index 00000000..ec1a65c2 --- /dev/null +++ b/src/test/java/org/jboss/tools/intellij/componentanalysis/golang/GoModParserTest.java @@ -0,0 +1,388 @@ +/******************************************************************************* + * Copyright (c) 2025 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package org.jboss.tools.intellij.componentanalysis.golang; + +import org.junit.Test; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + + +/** + * Tests for go.mod parsing patterns and scenarios based on real go.mod files. + * These tests verify the parsing logic using the actual patterns from GoCAAnnotator. + */ +public class GoModParserTest { + + @Test + public void testParseRequireLines_FromGoModFileA() { + // Test require lines from the first go.mod file + String[] requireLines = { + " github.com/gin-gonic/gin v1.4.0", + " github.com/spf13/viper v1.3.2", + " google.golang.org/protobuf v1.30.0", + " golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect", + " github.com/dgrijalva/jwt-go v3.2.0+incompatible" + }; + + for (String line : requireLines) { + Matcher matcher = GoCAAnnotator.REQUIRE_PATTERN.matcher(line); + assertTrue("Should match require line: " + line, matcher.matches()); + + String module = matcher.group(1); + String version = matcher.group(2); + + assertNotNull("Module should not be null", module); + assertNotNull("Version should not be null", version); + + // Verify specific extractions + if (line.contains("gin-gonic")) { + assertEquals("github.com/gin-gonic/gin", module); + assertEquals("v1.4.0", version); + } else if (line.contains("crypto")) { + assertEquals("golang.org/x/crypto", module); + assertEquals("v0.0.0-20190308221718-c2843e01d9a2", version); + } else if (line.contains("incompatible")) { + assertEquals("github.com/dgrijalva/jwt-go", module); + assertEquals("v3.2.0+incompatible", version); + } + } + } + + @Test + public void testParseRequireLines_FromGoModFileB() { + // Test require lines from the second go.mod file + String[] requireLines = { + " golang.org/x/net v0.10.0", + " google.golang.org/protobuf v1.30.0", + " github.com/google/go-cmp v0.5.9 // indirect", + " golang.org/x/text v0.9.0 // indirect" + }; + + for (String line : requireLines) { + Matcher matcher = GoCAAnnotator.REQUIRE_PATTERN.matcher(line); + assertTrue("Should match require line: " + line, matcher.matches()); + + String module = matcher.group(1); + String version = matcher.group(2); + + assertNotNull("Module should not be null", module); + assertNotNull("Version should not be null", version); + + // Verify specific extractions + if (line.contains("x/net")) { + assertEquals("golang.org/x/net", module); + assertEquals("v0.10.0", version); + } else if (line.contains("go-cmp")) { + assertEquals("github.com/google/go-cmp", module); + assertEquals("v0.5.9", version); + } + } + } + + @Test + public void testParseReplaceLines_FromGoModFileA() { + // Test replace lines from the first go.mod file + String[] replaceLines = { + " github.com/gin-gonic/gin v1.9.1 => github.com/myfork/gin v1.9.1-patch.2", + "replace github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20250416174521-4eb003743b54", + "replace github.com/myorg/anotherlib => /Users/chao/workspace/anotherlib" + }; + + for (String line : replaceLines) { + // Strip "replace " prefix if present, just like GoCAAnnotator does + String replaceLine = line.startsWith("replace ") ? line.substring(8).trim() : line.trim(); + Matcher matcher = GoCAAnnotator.REPLACE_PATTERN.matcher(replaceLine); + assertTrue("Should match replace line: " + line, matcher.matches()); + + String sourceModule = matcher.group(1); + String sourceVersion = matcher.group(2); + String targetPath = matcher.group(3); + String targetVersion = matcher.group(4); + + assertNotNull("Source module should not be null", sourceModule); + assertNotNull("Target path should not be null", targetPath); + + // Verify specific extractions + if (line.contains("gin-gonic")) { + assertEquals("github.com/gin-gonic/gin", sourceModule); + assertEquals("v1.9.1", sourceVersion); + assertEquals("github.com/myfork/gin", targetPath); + assertEquals("v1.9.1-patch.2", targetVersion); + } else if (line.contains("ginkgo")) { + assertEquals("github.com/onsi/ginkgo/v2", sourceModule); + assertNull("Ginkgo source version should be null", sourceVersion); + assertEquals("github.com/openshift/onsi-ginkgo/v2", targetPath); + assertEquals("v2.6.1-0.20250416174521-4eb003743b54", targetVersion); + } else if (line.contains("anotherlib")) { + assertEquals("github.com/myorg/anotherlib", sourceModule); + assertNull("Anotherlib source version should be null", sourceVersion); + assertEquals("/Users/chao/workspace/anotherlib", targetPath); + assertNull("Anotherlib target version should be null", targetVersion); + } + } + } + + @Test + public void testVersionFormats() { + // Test various version formats from both go.mod files + String[] versionFormats = { + "v1.4.0", // Standard semantic version + "v1.3.2", // Standard version + "v1.30.0", // Standard version + "v0.10.0", // Standard version + "v0.0.0-20190308221718-c2843e01d9a2", // Pseudo-version (timestamp) + "v3.2.0+incompatible", // Incompatible version + "v2.6.1-0.20250416174521-4eb003743b54", // Complex version with timestamp + "v1.9.1-patch.2", // Custom patch version + "v0.5.9", // Standard version + "v0.9.0" // Standard version + }; + + Pattern versionPattern = Pattern.compile("v?[0-9]+(?:\\.[0-9]+)*[0-9a-zA-Z\\-+._]*"); + + for (String version : versionFormats) { + Matcher matcher = versionPattern.matcher(version); + assertTrue("Should match version format: " + version, matcher.matches()); + } + } + + @Test + public void testModuleNameFormats() { + // Test various module name formats from both go.mod files + String[] moduleNames = { + "github.com/gin-gonic/gin", + "github.com/spf13/viper", + "google.golang.org/protobuf", + "golang.org/x/crypto", + "golang.org/x/net", + "github.com/dgrijalva/jwt-go", + "github.com/google/go-cmp", + "golang.org/x/text", + "github.com/onsi/ginkgo/v2", + "github.com/openshift/onsi-ginkgo/v2", + "github.com/myfork/gin", + "github.com/myorg/anotherlib" + }; + + Pattern modulePattern = Pattern.compile("[a-zA-Z0-9._/-]+"); + + for (String module : moduleNames) { + Matcher matcher = modulePattern.matcher(module); + assertTrue("Should match module name: " + module, matcher.matches()); + } + } + + @Test + public void testPathFormats() { + // Test path formats from the go.mod files + String[] pathFormats = { + "../viper-local", // Relative path (commented in file) + "/Users/chao/workspace/anotherlib", // Absolute path + "github.com/myfork/gin", // Module path + "github.com/openshift/onsi-ginkgo/v2" // Module path with version + }; + + // Pattern for identifiers including paths + Pattern pathPattern = Pattern.compile("(\\.\\.?/[a-zA-Z0-9._/-]*|/[a-zA-Z0-9._/-]+|[a-zA-Z_][a-zA-Z0-9._/-]*)"); + + for (String path : pathFormats) { + Matcher matcher = pathPattern.matcher(path); + assertTrue("Should match path format: " + path, matcher.matches()); + } + } + + @Test + public void testCommentHandling() { + // Test lines with comments from both files + String[] linesWithComments = { + " golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect", + " github.com/google/go-cmp v0.5.9 // indirect", + " golang.org/x/text v0.9.0 // indirect", + "// github.com/spf13/viper v1.3.2 => ../viper-local" + }; + + for (String line : linesWithComments) { + Matcher requireMatcher = GoCAAnnotator.REQUIRE_PATTERN.matcher(line); + if (line.trim().startsWith("//")) { + // Commented out line - should not match require pattern + assertFalse("Commented line should not match require pattern: " + line, + requireMatcher.matches()); + } else { + // Line with inline comment - should still match + assertTrue("Line with inline comment should match: " + line, + requireMatcher.matches()); + } + } + } + + @Test + public void testGoVersionStatements() { + // Test go version statements from both files + String[] goVersions = { + "go 1.18", + "go 1.20" + }; + + Pattern goPattern = Pattern.compile("^\\s*go\\s+([0-9]+\\.[0-9]+)\\s*$"); + + for (String goVersion : goVersions) { + Matcher matcher = goPattern.matcher(goVersion); + assertTrue("Should match go version: " + goVersion, matcher.matches()); + + String version = matcher.group(1); + assertTrue("Version should be valid", version.equals("1.18") || version.equals("1.20")); + } + } + + @Test + public void testExcludeStatements() { + // Test exclude statement from the first file + String excludeLine = "exclude github.com/gin-gonic/gin v1.5.0"; + + Pattern excludePattern = Pattern.compile("^\\s*exclude\\s+([a-zA-Z0-9._/-]+)\\s+(v?[0-9]+(?:\\.[0-9]+)*[0-9a-zA-Z\\-+._]*)\\s*$"); + + Matcher matcher = excludePattern.matcher(excludeLine); + assertTrue("Should match exclude statement", matcher.matches()); + + String module = matcher.group(1); + String version = matcher.group(2); + + assertEquals("github.com/gin-gonic/gin", module); + assertEquals("v1.5.0", version); + } + + @Test + public void testComplexRealWorldScenarios() { + // Test parsing a complete require block structure + String[] requireBlockLines = { + "require (", + " github.com/gin-gonic/gin v1.4.0", + " github.com/spf13/viper v1.3.2", + " google.golang.org/protobuf v1.30.0", + " golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect", + " github.com/dgrijalva/jwt-go v3.2.0+incompatible", + ")" + }; + + int validRequireLines = 0; + for (String line : requireBlockLines) { + if (line.trim().equals("require (") || line.trim().equals(")")) { + // Block delimiters - not require specs + continue; + } + + Matcher matcher = GoCAAnnotator.REQUIRE_PATTERN.matcher(line); + if (matcher.matches()) { + validRequireLines++; + } + } + + assertEquals("Should find 5 valid require specifications", 5, validRequireLines); + } + + @Test + public void testVersionPatternFromGoCAIntentionAction() { + // Test the VERSION_PATTERN used for version updates in GoCAIntentionAction + String[] testLines = { + " github.com/gin-gonic/gin v1.4.0", + " github.com/spf13/viper v1.3.2", + " google.golang.org/protobuf v1.30.0", + " golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 // indirect", + " github.com/dgrijalva/jwt-go v3.2.0+incompatible", + " golang.org/x/net v0.10.0", + " github.com/google/go-cmp v0.5.9 // indirect", + " golang.org/x/text v0.9.0 // indirect", + "github.com/gin-gonic/gin v1.9.1 => github.com/myfork/gin v1.9.1-patch.2", + "github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20250416174521-4eb003743b54" + }; + + for (String line : testLines) { + Matcher matcher = GoCAIntentionAction.VERSION_PATTERN.matcher(line); + assertTrue("Should find version in line: " + line, matcher.find()); + + String whitespace = matcher.group(1); + String version = matcher.group(2); + + assertNotNull("Whitespace should not be null", whitespace); + assertNotNull("Version should not be null", version); + assertFalse("Should have whitespace before version", whitespace.isEmpty()); + + // Verify specific version extractions + if (line.contains("gin-gonic/gin v1.4.0")) { + assertEquals("v1.4.0", version); + } else if (line.contains("crypto")) { + assertEquals("v0.0.0-20190308221718-c2843e01d9a2", version); + } else if (line.contains("incompatible")) { + assertEquals("v3.2.0+incompatible", version); + } else if (line.contains("v2.6.1-0.20250416174521-4eb003743b54")) { + assertEquals("v2.6.1-0.20250416174521-4eb003743b54", version); + } + } + } + + @Test + public void testVersionPatternCapturingGroups() { + // Test that VERSION_PATTERN correctly captures whitespace and version for replacement + String testLine = " github.com/gin-gonic/gin v1.4.0"; + Matcher matcher = GoCAIntentionAction.VERSION_PATTERN.matcher(testLine); + + assertTrue("Should match the line", matcher.find()); + + String whitespace = matcher.group(1); + String version = matcher.group(2); + + assertEquals("Should capture whitespace", " ", whitespace); + assertEquals("Should capture version", "v1.4.0", version); + + // Test version replacement scenario + String newVersion = "v1.5.0"; + String updatedLine = testLine.substring(0, matcher.start(2)) + newVersion + testLine.substring(matcher.end(2)); + assertEquals("Should replace version correctly", " github.com/gin-gonic/gin v1.5.0", updatedLine); + } + + @Test + public void testVersionPatternEdgeCases() { + // Test edge cases for VERSION_PATTERN + String[] shouldMatch = { + " v1.2.3", // Basic semantic version + " v0.0.1", // With more whitespace + "\tv1.0.0", // With tab + " 1.2.3", // Version without 'v' prefix + " v1.2.3-alpha", // Pre-release version + " v1.2.3+build", // Build metadata + " v1.2.3-alpha+build" // Both pre-release and build + }; + + String[] shouldNotMatch = { + "v1.2.3", // No leading whitespace + " v1.2", // Only major.minor (VERSION_PATTERN expects major.minor.patch) + " version1.2.3", // Extra text before version + "github.com/module", // Module name only + }; + + for (String line : shouldMatch) { + Matcher matcher = GoCAIntentionAction.VERSION_PATTERN.matcher(line); + assertTrue("Should match: '" + line + "'", matcher.find()); + } + + for (String line : shouldNotMatch) { + Matcher matcher = GoCAIntentionAction.VERSION_PATTERN.matcher(line); + assertFalse("Should NOT match: '" + line + "'", matcher.find()); + } + } +} \ No newline at end of file