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..e508fd07
--- /dev/null
+++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/lexer/GoModLexer.java
@@ -0,0 +1,640 @@
+// 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\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[59];
+ 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\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\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[59];
+ 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\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[1488];
+ 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\1\0"+
+ "\1\1\3\0\1\11\43\1";
+
+ private static int [] zzUnpackAttribute() {
+ int [] result = new int[59];
+ 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..59d393fe
--- /dev/null
+++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/parser/GoModParser.java
@@ -0,0 +1,379 @@
+// 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 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 = 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;
+ }
+
+ // 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_5", 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..c935fa23
--- /dev/null
+++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/GoModReplaceSpec.java
@@ -0,0 +1,10 @@
+// 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 {
+
+}
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..bddb12e9
--- /dev/null
+++ b/src/main/gen/org/jboss/tools/intellij/componentanalysis/golang/build/psi/impl/GoModReplaceSpecImpl.java
@@ -0,0 +1,30 @@
+// 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);
+ }
+
+}
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..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
@@ -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 {
+ 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() {
return GoCAInspection.SHORT_NAME;
@@ -43,47 +41,90 @@ 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(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
+ 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(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);
+ }
+ }
+ }
+ }
}
- return Collections.emptyMap();
+ return resultMap;
}
@Override
@@ -98,23 +139,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-9a-zA-Z\\-+._]*)").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..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
@@ -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 {
+ 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);
}
@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..51ff6835
--- /dev/null
+++ b/src/main/java/org/jboss/tools/intellij/componentanalysis/golang/build/goMod.bnf
@@ -0,0 +1,62 @@
+{
+ 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
+
+ MODULE='module'
+ GO='go'
+ REQUIRE='require'
+ REPLACE='replace'
+ EXCLUDE='exclude'
+ INDIRECT='indirect'
+
+ LPAREN='('
+ RPAREN=')'
+ ARROW='=>'
+
+ IDENTIFIER
+ VERSION
+
+ NEWLINE
+ ]
+}
+
+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 VERSION? 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..bc455807
--- /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 - 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_\.\/\-]*)
+
+%%
+
+ {
+ {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..8396f138 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 (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.
@@ -478,7 +479,6 @@
org.jetbrains.idea.maven
com.redhat.devtools.intellij.telemetry
Docker
- org.jetbrains.plugins.go
@@ -532,6 +532,18 @@
+
+
+
+
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