diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index c48c0fe..de9cc50 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -15,11 +15,12 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 with: - java-version: 11 + java-version: '17' + distribution: 'temurin' - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0aba9cd..72268f4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,17 +10,18 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Set up JDK 11 - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 with: - java-version: 11 + java-version: '17' + distribution: 'temurin' - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle run: ./gradlew clean build - name: Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 if: startsWith(github.ref, 'refs/tags/') with: files: | diff --git a/build.gradle b/build.gradle index a67aa08..6d00968 100644 --- a/build.gradle +++ b/build.gradle @@ -17,8 +17,9 @@ buildscript { plugins { id 'java' id 'idea' - id 'org.jetbrains.intellij' version '1.3.0' - id "org.jetbrains.kotlin.jvm" version "1.6.10" + id 'org.jetbrains.intellij.platform' version '2.0.1' + id "org.jetbrains.kotlin.jvm" version "1.9.25" + id "org.jetbrains.grammarkit" version "2022.3.2.2" } apply plugin: "kotlin" @@ -29,40 +30,52 @@ version '0.1.6-beta1' repositories { mavenLocal() mavenCentral() + maven { url 'https://jitpack.io' } + intellijPlatform { + defaultRepositories() + } } compileJava { - sourceCompatibility = '11' - targetCompatibility = '11' + sourceCompatibility = '17' + targetCompatibility = '17' } -compileKotlin { - kotlinOptions.jvmTarget = "1.8" -} -compileTestKotlin { - kotlinOptions.jvmTarget = "1.8" -} +//compileKotlin { +// kotlinOptions.jvmTarget = "1.8" +//} +//compileTestKotlin { +// kotlinOptions.jvmTarget = "1.8" +//} dependencies { - compile fileTree(include: ['*.jar'], dir: 'lib') - compile('com.bloxbean.cardano:cardano-client-lib:0.3.0') { + intellijPlatform { + intellijIdeaCommunity("2023.3.6") + plugin("com.redhat.devtools.lsp4ij:0.5.0") + pluginVerifier() + zipSigner() + instrumentationTools() + } + + implementation fileTree(include: ['*.jar'], dir: 'lib') + implementation('com.bloxbean.cardano:cardano-client-lib:0.4.3') { exclude group: 'org.slf4j', module: 'slf4j-api' } - compile('com.bloxbean.cardano:cardano-client-backend-blockfrost:0.3.0') { + implementation('com.bloxbean.cardano:cardano-client-backend-blockfrost:0.4.3') { exclude group: 'org.slf4j', module: 'slf4j-api' exclude group: 'com.bloxbean.cardano', module: 'cardano-client-lib' } - compile('com.bloxbean.cardano:cardano-client-backend-koios:0.3.0') { + implementation('com.bloxbean.cardano:cardano-client-backend-koios:0.4.3') { exclude group: 'org.slf4j', module: 'slf4j-api' exclude group: 'com.bloxbean.cardano', module: 'cardano-client-lib' } - + implementation('com.moandjiezana.toml:toml4j:0.7.2') implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10") compileOnly 'org.projectlombok:lombok:1.18.20' annotationProcessor 'org.projectlombok:lombok:1.18.20' - testCompile group: 'junit', name: 'junit', version: '4.12' + testImplementation group: 'junit', name: 'junit', version: '4.12' } sourceSets.main.java.srcDirs('src/main/gen', 'src/main/idea') @@ -74,13 +87,33 @@ String changeLogAsHtml() { renderer.render(changeLogDocument) } -intellij { - version = '2021.1' - //type = 'IC' - plugins = ['java'] +grammarKit { + jflexRelease = "1.7.0-1" + grammarKitRelease = "2021.1.2" + generateLexer { + sourceFile = file('src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/_AikenLexer.flex') + targetOutputDir = file('src/main/gen/com/bloxbean/intelliada/idea/aiken/lang') + } - updateSinceUntilBuild = false + generateParser { + sourceFile = file('src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/Aiken.bnf') + targetRootOutputDir = file('src/main/gen') + pathToParser = 'com/bloxbean/intelliada/idea/aiken/lang/parser' + pathToPsiRoot = 'com/bloxbean/intelliada/idea/aiken/lang/psi' + } } + +//intellij { +// version = '2023.2' +//// version = "232-EAP-SNAPSHOT" +//// type = "IU" +//// version = "2024.1.4" +//// type = "IU" +// type = 'IC' +// plugins = ['java'] +// +// updateSinceUntilBuild = false +//} patchPluginXml { changeNotes = changeLogAsHtml() } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 703238f..b5fc5a7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip diff --git a/idea-flex.skeleton b/idea-flex.skeleton new file mode 100644 index 0000000..2183999 --- /dev/null +++ b/idea-flex.skeleton @@ -0,0 +1,248 @@ + + /** 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 = ...; + + /** lexical states */ +--- lexical states, charmap + + /* 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" + }; + +--- isFinal list + /** 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; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + +--- user class code + +--- constructor declaration + + 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 + */ +--- zzScanError declaration + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + +--- throws clause + } + + + /** + * 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()! + */ +--- yypushback decl (contains zzScanError exception) + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + +--- zzDoEOF + /** + * 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 + */ +--- yylex declaration + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + CharSequence zzBufferL = zzBuffer; + +--- local declarations + + while (true) { + zzMarkedPosL = zzMarkedPos; + +--- start admin (line, char, col count) + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + +--- start admin (lexstate etc) + + zzForAction: { + while (true) { + +--- next input, line, col, char count, next transition, isFinal action + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; +--- line count update + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; +--- char count update + + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; +--- eofvalue + } + else { +--- actions + default: +--- no match + } + } + } + } + +--- main + +} diff --git a/jflex-1.7.0-2.jar b/jflex-1.7.0-2.jar new file mode 100644 index 0000000..c152c2c Binary files /dev/null and b/jflex-1.7.0-2.jar differ diff --git a/jflex-1.9.1.jar b/jflex-1.9.1.jar new file mode 100644 index 0000000..544ae1a Binary files /dev/null and b/jflex-1.9.1.jar differ diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/_AikenLexer.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/_AikenLexer.java new file mode 100644 index 0000000..915dc3d --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/_AikenLexer.java @@ -0,0 +1,823 @@ +/* The following code was generated by JFlex 1.7.0-1 tweaked for IntelliJ platform */ + +package com.bloxbean.intelliada.idea.aiken.lang; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.tree.IElementType; + +import static com.intellij.psi.TokenType.BAD_CHARACTER; +import static com.intellij.psi.TokenType.WHITE_SPACE; +import static com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; + + +/** + * This class is a scanner generated by + * JFlex 1.7.0-1 + * from the specification file /Users/satya/work/bloxbean/intelliada/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/_AikenLexer.flex + */ +public class _AikenLexer 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 + }; + + /** + * Translates characters to character classes + * Chosen bits are [7, 7, 7] + * Total runtime size is 1928 bytes + */ + public static int ZZ_CMAP(int ch) { + return ZZ_CMAP_A[(ZZ_CMAP_Y[ZZ_CMAP_Z[ch>>14]|((ch>>7)&0x7f)]<<7)|(ch&0x7f)]; + } + + /* The ZZ_CMAP_Z table has 68 entries */ + static final char ZZ_CMAP_Z[] = zzUnpackCMap( + "\1\0\103\200"); + + /* The ZZ_CMAP_Y table has 256 entries */ + static final char ZZ_CMAP_Y[] = zzUnpackCMap( + "\1\0\1\1\53\2\1\3\22\2\1\4\37\2\1\3\237\2"); + + /* The ZZ_CMAP_A table has 640 entries */ + static final char ZZ_CMAP_A[] = zzUnpackCMap( + "\11\0\1\1\1\2\3\1\22\0\1\1\1\50\1\7\3\0\1\54\1\0\1\43\1\44\1\57\1\51\1\46"+ + "\1\52\1\60\1\6\12\4\1\45\1\0\1\55\1\47\1\56\2\0\32\5\1\41\1\10\1\42\1\0\1"+ + "\3\1\0\1\30\1\24\1\32\1\33\1\14\1\13\1\3\1\20\1\12\1\3\1\35\1\15\1\3\1\21"+ + "\1\27\1\22\1\31\1\11\1\16\1\25\1\23\1\36\1\17\1\34\1\26\1\3\1\37\1\53\1\40"+ + "\7\0\1\1\32\0\1\1\337\0\1\1\177\0\13\1\35\0\2\1\5\0\1\1\57\0\1\1\40\0"); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\1\1\1\2\1\3\1\4\1\1\1\5\1\6\1\7"+ + "\14\4\1\10\1\11\1\12\1\13\1\14\1\15\1\16"+ + "\1\17\1\20\1\21\1\22\1\23\2\2\1\24\1\25"+ + "\1\26\1\27\1\30\2\0\1\31\1\32\1\33\13\4"+ + "\1\34\1\4\1\35\5\4\1\36\1\37\1\40\1\34"+ + "\1\41\1\42\1\43\1\44\1\45\1\0\3\4\1\46"+ + "\1\4\1\47\1\50\5\4\1\42\2\4\1\51\1\4"+ + "\1\52\1\53\1\4\1\54\1\4\1\55\1\56\1\57"+ + "\5\4\1\60\1\4\1\61\1\62\1\4\1\63\1\64"+ + "\3\4\1\65"; + + private static int [] zzUnpackAction() { + int [] result = new int[114]; + 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\61\0\142\0\223\0\304\0\365\0\u0126\0\u0157"+ + "\0\u0188\0\u01b9\0\u01ea\0\u021b\0\u024c\0\u027d\0\u02ae\0\u02df"+ + "\0\u0310\0\u0341\0\u0372\0\u03a3\0\61\0\61\0\61\0\61"+ + "\0\61\0\61\0\61\0\61\0\u03d4\0\61\0\61\0\u0405"+ + "\0\u0436\0\u0467\0\61\0\61\0\61\0\u0498\0\u04c9\0\u04fa"+ + "\0\u052b\0\223\0\223\0\223\0\u055c\0\u058d\0\u05be\0\u05ef"+ + "\0\u0620\0\u0651\0\u0682\0\u06b3\0\u06e4\0\u0715\0\u0746\0\223"+ + "\0\u0777\0\223\0\u07a8\0\u07d9\0\u080a\0\u083b\0\u086c\0\61"+ + "\0\61\0\61\0\61\0\61\0\61\0\61\0\u04c9\0\61"+ + "\0\u089d\0\u08ce\0\u08ff\0\u0930\0\223\0\u0961\0\223\0\223"+ + "\0\u0992\0\u09c3\0\u09f4\0\u0a25\0\u0a56\0\223\0\u0a87\0\u0ab8"+ + "\0\223\0\u0ae9\0\223\0\223\0\u0b1a\0\223\0\u0b4b\0\223"+ + "\0\223\0\223\0\u0b7c\0\u0bad\0\u0bde\0\u0c0f\0\u0c40\0\223"+ + "\0\u0c71\0\223\0\223\0\u0ca2\0\223\0\223\0\u0cd3\0\u0d04"+ + "\0\u0d35\0\223"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[114]; + 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(); + 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\2\3\1\4\1\5\1\6\1\7\1\10\1\2"+ + "\1\4\1\11\1\12\1\13\1\14\1\4\1\15\2\4"+ + "\1\16\1\17\1\4\1\20\1\4\1\21\1\22\1\4"+ + "\1\23\3\4\1\24\1\25\1\26\1\27\1\30\1\31"+ + "\1\32\1\33\1\34\1\35\1\36\1\37\1\40\1\41"+ + "\1\42\1\43\1\44\1\45\1\46\62\0\2\3\61\0"+ + "\2\4\4\0\26\4\26\0\1\5\57\0\3\6\3\0"+ + "\26\6\30\0\1\47\52\0\7\50\1\0\1\51\50\50"+ + "\3\0\2\4\4\0\2\4\1\52\2\4\1\53\20\4"+ + "\25\0\2\4\4\0\10\4\1\54\6\4\1\55\6\4"+ + "\25\0\2\4\4\0\4\4\1\56\16\4\1\57\2\4"+ + "\25\0\2\4\4\0\3\4\1\60\22\4\25\0\2\4"+ + "\4\0\7\4\1\61\16\4\25\0\2\4\4\0\12\4"+ + "\1\62\13\4\25\0\2\4\4\0\5\4\1\63\20\4"+ + "\25\0\2\4\4\0\1\64\2\4\1\65\11\4\1\66"+ + "\1\67\7\4\25\0\2\4\4\0\1\70\10\4\1\71"+ + "\14\4\25\0\2\4\4\0\5\4\1\72\2\4\1\73"+ + "\15\4\25\0\2\4\4\0\7\4\1\74\6\4\1\75"+ + "\7\4\25\0\2\4\4\0\1\4\1\76\15\4\1\77"+ + "\6\4\71\0\1\100\6\0\1\101\60\0\1\102\55\0"+ + "\1\103\2\0\1\104\56\0\1\105\64\0\1\106\2\107"+ + "\1\0\56\107\7\50\1\110\1\51\50\50\10\0\1\111"+ + "\53\0\2\4\4\0\1\4\1\112\24\4\25\0\2\4"+ + "\4\0\5\4\1\113\20\4\25\0\2\4\4\0\11\4"+ + "\1\114\14\4\25\0\2\4\4\0\14\4\1\115\11\4"+ + "\25\0\2\4\4\0\3\4\1\116\22\4\25\0\2\4"+ + "\4\0\13\4\1\117\12\4\25\0\2\4\4\0\3\4"+ + "\1\120\22\4\25\0\2\4\4\0\17\4\1\121\6\4"+ + "\25\0\2\4\4\0\5\4\1\122\20\4\25\0\2\4"+ + "\4\0\11\4\1\123\14\4\25\0\2\4\4\0\22\4"+ + "\1\124\3\4\25\0\2\4\4\0\17\4\1\125\6\4"+ + "\25\0\2\4\4\0\22\4\1\126\3\4\25\0\2\4"+ + "\4\0\3\4\1\127\22\4\25\0\2\4\4\0\10\4"+ + "\1\130\15\4\25\0\2\4\4\0\17\4\1\131\6\4"+ + "\25\0\2\4\4\0\4\4\1\132\21\4\22\0\7\50"+ + "\3\0\1\50\2\0\4\50\1\0\3\50\1\0\33\50"+ + "\3\0\2\4\4\0\4\4\1\133\21\4\25\0\2\4"+ + "\4\0\3\4\1\134\22\4\25\0\2\4\4\0\3\4"+ + "\1\135\22\4\25\0\2\4\4\0\10\4\1\136\15\4"+ + "\25\0\2\4\4\0\21\4\1\137\4\4\25\0\2\4"+ + "\4\0\14\4\1\140\11\4\25\0\2\4\4\0\3\4"+ + "\1\141\22\4\25\0\2\4\4\0\16\4\1\142\7\4"+ + "\25\0\2\4\4\0\20\4\1\143\5\4\25\0\2\4"+ + "\4\0\21\4\1\144\4\4\25\0\2\4\4\0\5\4"+ + "\1\145\20\4\25\0\2\4\4\0\1\4\1\146\24\4"+ + "\25\0\2\4\4\0\21\4\1\147\4\4\25\0\2\4"+ + "\4\0\3\4\1\150\22\4\25\0\2\4\4\0\12\4"+ + "\1\151\13\4\25\0\2\4\4\0\24\4\1\152\1\4"+ + "\25\0\2\4\4\0\14\4\1\153\11\4\25\0\2\4"+ + "\4\0\22\4\1\154\3\4\25\0\2\4\4\0\14\4"+ + "\1\155\11\4\25\0\2\4\4\0\3\4\1\156\22\4"+ + "\25\0\2\4\4\0\17\4\1\157\6\4\25\0\2\4"+ + "\4\0\14\4\1\160\11\4\25\0\2\4\4\0\16\4"+ + "\1\161\7\4\25\0\2\4\4\0\1\162\25\4\22\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[3430]; + 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 aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\1\1\1\11\22\1\10\11\1\1\2\11\3\1\3\11"+ + "\2\1\2\0\26\1\7\11\1\1\1\11\1\0\51\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[114]; + 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; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /* user code: */ + public _AikenLexer() { + this((java.io.Reader)null); + } + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + public _AikenLexer(java.io.Reader in) { + this.zzReader = in; + } + + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + int size = 0; + for (int i = 0, length = packed.length(); i < length; i += 2) { + size += packed.charAt(i); + } + char[] map = new char[size]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < packed.length()) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + 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 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 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 occured 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/*, zzEndReadL*/); + 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/*, zzEndReadL*/); + zzCurrentPosL += Character.charCount(zzInput); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + ZZ_CMAP(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 NUMBER; + } + // fall through + case 54: break; + case 2: + { return BAD_CHARACTER; + } + // fall through + case 55: break; + case 3: + { return WHITE_SPACE; + } + // fall through + case 56: break; + case 4: + { return IDENTIFIER; + } + // fall through + case 57: break; + case 5: + { return UPPER_IDENTIFIER; + } + // fall through + case 58: break; + case 6: + { return DIV; + } + // fall through + case 59: break; + case 7: + { return QUOTE; + } + // fall through + case 60: break; + case 8: + { return LBRACE; + } + // fall through + case 61: break; + case 9: + { return RBRACE; + } + // fall through + case 62: break; + case 10: + { return LBRACK; + } + // fall through + case 63: break; + case 11: + { return RBRACK; + } + // fall through + case 64: break; + case 12: + { return LPAREN; + } + // fall through + case 65: break; + case 13: + { return RPAREN; + } + // fall through + case 66: break; + case 14: + { return COLON; + } + // fall through + case 67: break; + case 15: + { return COMMA; + } + // fall through + case 68: break; + case 16: + { return EQ; + } + // fall through + case 69: break; + case 17: + { return BANG; + } + // fall through + case 70: break; + case 18: + { return PLUS; + } + // fall through + case 71: break; + case 19: + { return MINUS; + } + // fall through + case 72: break; + case 20: + { return LT; + } + // fall through + case 73: break; + case 21: + { return GT; + } + // fall through + case 74: break; + case 22: + { return MUL; + } + // fall through + case 75: break; + case 23: + { return DOT; + } + // fall through + case 76: break; + case 24: + { return DIVDIV; + } + // fall through + case 77: break; + case 25: + { return IF; + } + // fall through + case 78: break; + case 26: + { return IS; + } + // fall through + case 79: break; + case 27: + { return FN; + } + // fall through + case 80: break; + case 28: + { return OR; + } + // fall through + case 81: break; + case 29: + { return AS; + } + // fall through + case 82: break; + case 30: + { return EQEQ; + } + // fall through + case 83: break; + case 31: + { return FAT_ARROW; + } + // fall through + case 84: break; + case 32: + { return ARROW; + } + // fall through + case 85: break; + case 33: + { return PIPE; + } + // fall through + case 86: break; + case 34: + { return AND; + } + // fall through + case 87: break; + case 35: + { return DOTDOT; + } + // fall through + case 88: break; + case 36: + { return COMMENT; + } + // fall through + case 89: break; + case 37: + { return STRING_CONTENT; + } + // fall through + case 90: break; + case 38: + { return LET; + } + // fall through + case 91: break; + case 39: + { return PUB; + } + // fall through + case 92: break; + case 40: + { return USE; + } + // fall through + case 93: break; + case 41: + { return VIA; + } + // fall through + case 94: break; + case 42: + { return FAIL; + } + // fall through + case 95: break; + case 43: + { return ELSE; + } + // fall through + case 96: break; + case 44: + { return WHEN; + } + // fall through + case 97: break; + case 45: + { return TEST; + } + // fall through + case 98: break; + case 46: + { return TYPE; + } + // fall through + case 99: break; + case 47: + { return TODO; + } + // fall through + case 100: break; + case 48: + { return TRACE; + } + // fall through + case 101: break; + case 49: + { return CHECK; + } + // fall through + case 102: break; + case 50: + { return CONST; + } + // fall through + case 103: break; + case 51: + { return EXPECT; + } + // fall through + case 104: break; + case 52: + { return OPAQUE; + } + // fall through + case 105: break; + case 53: + { return VALIDATOR; + } + // fall through + case 106: break; + default: + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/parser/AikenParser.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/parser/AikenParser.java new file mode 100644 index 0000000..50e6ac0 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/parser/AikenParser.java @@ -0,0 +1,800 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.parser; + +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiBuilder.Marker; +import static com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import static com.bloxbean.intelliada.idea.aiken.lang.psi.impl.AikenParserUtil.*; +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 AikenParser 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 aikenFile(b, l + 1); + } + + /* ********************************************************** */ + // topLevelDefinition* + static boolean aikenFile(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "aikenFile")) return false; + while (true) { + int c = current_position_(b); + if (!topLevelDefinition(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "aikenFile", c)) break; + } + return true; + } + + /* ********************************************************** */ + // CONST IDENTIFIER EQ variableValue + public static boolean constantStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "constantStatement")) return false; + if (!nextTokenIs(b, CONST)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, CONST, IDENTIFIER, EQ); + r = r && variableValue(b, l + 1); + exit_section_(b, m, CONSTANT_STATEMENT, r); + return r; + } + + /* ********************************************************** */ + // constructorIdentifier typeIdentifier [COMMA] + static boolean constructorElement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "constructorElement")) return false; + if (!nextTokenIs(b, IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = constructorIdentifier(b, l + 1); + r = r && typeIdentifier(b, l + 1); + r = r && constructorElement_2(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // [COMMA] + private static boolean constructorElement_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "constructorElement_2")) return false; + consumeToken(b, COMMA); + return true; + } + + /* ********************************************************** */ + // IDENTIFIER COLON + public static boolean constructorIdentifier(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "constructorIdentifier")) return false; + if (!nextTokenIs(b, IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, IDENTIFIER, COLON); + exit_section_(b, m, CONSTRUCTOR_IDENTIFIER, r); + return r; + } + + /* ********************************************************** */ + // UPPER_IDENTIFIER + public static boolean constructorName(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "constructorName")) return false; + if (!nextTokenIs(b, UPPER_IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, UPPER_IDENTIFIER); + exit_section_(b, m, CONSTRUCTOR_NAME, r); + return r; + } + + /* ********************************************************** */ + // [IDENTIFIER DOT] IDENTIFIER LPAREN [functionCallParam*] RPAREN [PIPE functionCall] + public static boolean functionCall(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCall")) return false; + if (!nextTokenIs(b, IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = functionCall_0(b, l + 1); + r = r && consumeTokens(b, 0, IDENTIFIER, LPAREN); + r = r && functionCall_3(b, l + 1); + r = r && consumeToken(b, RPAREN); + r = r && functionCall_5(b, l + 1); + exit_section_(b, m, FUNCTION_CALL, r); + return r; + } + + // [IDENTIFIER DOT] + private static boolean functionCall_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCall_0")) return false; + parseTokens(b, 0, IDENTIFIER, DOT); + return true; + } + + // [functionCallParam*] + private static boolean functionCall_3(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCall_3")) return false; + functionCall_3_0(b, l + 1); + return true; + } + + // functionCallParam* + private static boolean functionCall_3_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCall_3_0")) return false; + while (true) { + int c = current_position_(b); + if (!functionCallParam(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "functionCall_3_0", c)) break; + } + return true; + } + + // [PIPE functionCall] + private static boolean functionCall_5(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCall_5")) return false; + functionCall_5_0(b, l + 1); + return true; + } + + // PIPE functionCall + private static boolean functionCall_5_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCall_5_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, PIPE); + r = r && functionCall(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + /* ********************************************************** */ + // ((IDENTIFIER COLON variableValue) | variableValue)[COMMA] + public static boolean functionCallParam(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCallParam")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, FUNCTION_CALL_PARAM, ""); + r = functionCallParam_0(b, l + 1); + r = r && functionCallParam_1(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + // (IDENTIFIER COLON variableValue) | variableValue + private static boolean functionCallParam_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCallParam_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = functionCallParam_0_0(b, l + 1); + if (!r) r = variableValue(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // IDENTIFIER COLON variableValue + private static boolean functionCallParam_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCallParam_0_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, IDENTIFIER, COLON); + r = r && variableValue(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // [COMMA] + private static boolean functionCallParam_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionCallParam_1")) return false; + consumeToken(b, COMMA); + return true; + } + + /* ********************************************************** */ + // [PUB] FN IDENTIFIER LPAREN [(constructorElement)*] RPAREN [functionStatementType] LBRACE [innerDefinition*] RBRACE + public static boolean functionStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatement")) return false; + if (!nextTokenIs(b, "", FN, PUB)) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, FUNCTION_STATEMENT, ""); + r = functionStatement_0(b, l + 1); + r = r && consumeTokens(b, 0, FN, IDENTIFIER, LPAREN); + r = r && functionStatement_4(b, l + 1); + r = r && consumeToken(b, RPAREN); + r = r && functionStatement_6(b, l + 1); + r = r && consumeToken(b, LBRACE); + r = r && functionStatement_8(b, l + 1); + r = r && consumeToken(b, RBRACE); + exit_section_(b, l, m, r, false, null); + return r; + } + + // [PUB] + private static boolean functionStatement_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatement_0")) return false; + consumeToken(b, PUB); + return true; + } + + // [(constructorElement)*] + private static boolean functionStatement_4(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatement_4")) return false; + functionStatement_4_0(b, l + 1); + return true; + } + + // (constructorElement)* + private static boolean functionStatement_4_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatement_4_0")) return false; + while (true) { + int c = current_position_(b); + if (!functionStatement_4_0_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "functionStatement_4_0", c)) break; + } + return true; + } + + // (constructorElement) + private static boolean functionStatement_4_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatement_4_0_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = constructorElement(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // [functionStatementType] + private static boolean functionStatement_6(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatement_6")) return false; + functionStatementType(b, l + 1); + return true; + } + + // [innerDefinition*] + private static boolean functionStatement_8(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatement_8")) return false; + functionStatement_8_0(b, l + 1); + return true; + } + + // innerDefinition* + private static boolean functionStatement_8_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatement_8_0")) return false; + while (true) { + int c = current_position_(b); + if (!innerDefinition(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "functionStatement_8_0", c)) break; + } + return true; + } + + /* ********************************************************** */ + // ARROW typeIdentifier + public static boolean functionStatementType(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "functionStatementType")) return false; + if (!nextTokenIs(b, ARROW)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, ARROW); + r = r && typeIdentifier(b, l + 1); + exit_section_(b, m, FUNCTION_STATEMENT_TYPE, r); + return r; + } + + /* ********************************************************** */ + // USE importStatementElement + public static boolean importStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatement")) return false; + if (!nextTokenIs(b, USE)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, USE); + r = r && importStatementElement(b, l + 1); + exit_section_(b, m, IMPORT_STATEMENT, r); + return r; + } + + /* ********************************************************** */ + // IDENTIFIER ('/' IDENTIFIER [importStatementTypes])* + public static boolean importStatementElement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementElement")) return false; + if (!nextTokenIs(b, IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, IDENTIFIER); + r = r && importStatementElement_1(b, l + 1); + exit_section_(b, m, IMPORT_STATEMENT_ELEMENT, r); + return r; + } + + // ('/' IDENTIFIER [importStatementTypes])* + private static boolean importStatementElement_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementElement_1")) return false; + while (true) { + int c = current_position_(b); + if (!importStatementElement_1_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "importStatementElement_1", c)) break; + } + return true; + } + + // '/' IDENTIFIER [importStatementTypes] + private static boolean importStatementElement_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementElement_1_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, DIV, IDENTIFIER); + r = r && importStatementElement_1_0_2(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // [importStatementTypes] + private static boolean importStatementElement_1_0_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementElement_1_0_2")) return false; + importStatementTypes(b, l + 1); + return true; + } + + /* ********************************************************** */ + // DOT LBRACE ((UPPER_IDENTIFIER|IDENTIFIER) [COMMA])* RBRACE + public static boolean importStatementTypes(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementTypes")) return false; + if (!nextTokenIs(b, DOT)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, DOT, LBRACE); + r = r && importStatementTypes_2(b, l + 1); + r = r && consumeToken(b, RBRACE); + exit_section_(b, m, IMPORT_STATEMENT_TYPES, r); + return r; + } + + // ((UPPER_IDENTIFIER|IDENTIFIER) [COMMA])* + private static boolean importStatementTypes_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementTypes_2")) return false; + while (true) { + int c = current_position_(b); + if (!importStatementTypes_2_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "importStatementTypes_2", c)) break; + } + return true; + } + + // (UPPER_IDENTIFIER|IDENTIFIER) [COMMA] + private static boolean importStatementTypes_2_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementTypes_2_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = importStatementTypes_2_0_0(b, l + 1); + r = r && importStatementTypes_2_0_1(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // UPPER_IDENTIFIER|IDENTIFIER + private static boolean importStatementTypes_2_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementTypes_2_0_0")) return false; + boolean r; + r = consumeToken(b, UPPER_IDENTIFIER); + if (!r) r = consumeToken(b, IDENTIFIER); + return r; + } + + // [COMMA] + private static boolean importStatementTypes_2_0_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "importStatementTypes_2_0_1")) return false; + consumeToken(b, COMMA); + return true; + } + + /* ********************************************************** */ + // COMMENT + // | variableStatement + // | constantStatement + // | functionCall + static boolean innerDefinition(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "innerDefinition")) return false; + boolean r; + r = consumeToken(b, COMMENT); + if (!r) r = variableStatement(b, l + 1); + if (!r) r = constantStatement(b, l + 1); + if (!r) r = functionCall(b, l + 1); + return r; + } + + /* ********************************************************** */ + // importStatement + // | typeStatement + // | validatorStatement + // | functionStatement + // | COMMENT + // | ([PUB] constantStatement) + static boolean topLevelDefinition(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "topLevelDefinition")) return false; + boolean r; + Marker m = enter_section_(b); + r = importStatement(b, l + 1); + if (!r) r = typeStatement(b, l + 1); + if (!r) r = validatorStatement(b, l + 1); + if (!r) r = functionStatement(b, l + 1); + if (!r) r = consumeToken(b, COMMENT); + if (!r) r = topLevelDefinition_5(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // [PUB] constantStatement + private static boolean topLevelDefinition_5(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "topLevelDefinition_5")) return false; + boolean r; + Marker m = enter_section_(b); + r = topLevelDefinition_5_0(b, l + 1); + r = r && constantStatement(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // [PUB] + private static boolean topLevelDefinition_5_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "topLevelDefinition_5_0")) return false; + consumeToken(b, PUB); + return true; + } + + /* ********************************************************** */ + // [IDENTIFIER DOT] UPPER_IDENTIFIER [LPAREN typeIdentifierInnerType [typeIdentifierInnerType*] RPAREN] + public static boolean typeIdentifier(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeIdentifier")) return false; + if (!nextTokenIs(b, "", IDENTIFIER, UPPER_IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, TYPE_IDENTIFIER, ""); + r = typeIdentifier_0(b, l + 1); + r = r && consumeToken(b, UPPER_IDENTIFIER); + r = r && typeIdentifier_2(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + // [IDENTIFIER DOT] + private static boolean typeIdentifier_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeIdentifier_0")) return false; + parseTokens(b, 0, IDENTIFIER, DOT); + return true; + } + + // [LPAREN typeIdentifierInnerType [typeIdentifierInnerType*] RPAREN] + private static boolean typeIdentifier_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeIdentifier_2")) return false; + typeIdentifier_2_0(b, l + 1); + return true; + } + + // LPAREN typeIdentifierInnerType [typeIdentifierInnerType*] RPAREN + private static boolean typeIdentifier_2_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeIdentifier_2_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, LPAREN); + r = r && typeIdentifierInnerType(b, l + 1); + r = r && typeIdentifier_2_0_2(b, l + 1); + r = r && consumeToken(b, RPAREN); + exit_section_(b, m, null, r); + return r; + } + + // [typeIdentifierInnerType*] + private static boolean typeIdentifier_2_0_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeIdentifier_2_0_2")) return false; + typeIdentifier_2_0_2_0(b, l + 1); + return true; + } + + // typeIdentifierInnerType* + private static boolean typeIdentifier_2_0_2_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeIdentifier_2_0_2_0")) return false; + while (true) { + int c = current_position_(b); + if (!typeIdentifierInnerType(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "typeIdentifier_2_0_2_0", c)) break; + } + return true; + } + + /* ********************************************************** */ + // typeIdentifier [COMMA] + public static boolean typeIdentifierInnerType(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeIdentifierInnerType")) return false; + if (!nextTokenIs(b, "", IDENTIFIER, UPPER_IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, TYPE_IDENTIFIER_INNER_TYPE, ""); + r = typeIdentifier(b, l + 1); + r = r && typeIdentifierInnerType_1(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + // [COMMA] + private static boolean typeIdentifierInnerType_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeIdentifierInnerType_1")) return false; + consumeToken(b, COMMA); + return true; + } + + /* ********************************************************** */ + // UPPER_IDENTIFIER + public static boolean typeName(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeName")) return false; + if (!nextTokenIs(b, UPPER_IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, UPPER_IDENTIFIER); + exit_section_(b, m, TYPE_NAME, r); + return r; + } + + /* ********************************************************** */ + // [PUB] TYPE typeName ('<' IDENTIFIER '>')? LBRACE (constructorElement | (typeStatementConstructor | typeStatementConstructorNoArg)*) RBRACE + public static boolean typeStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatement")) return false; + if (!nextTokenIs(b, "", PUB, TYPE)) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, TYPE_STATEMENT, ""); + r = typeStatement_0(b, l + 1); + r = r && consumeToken(b, TYPE); + r = r && typeName(b, l + 1); + r = r && typeStatement_3(b, l + 1); + r = r && consumeToken(b, LBRACE); + r = r && typeStatement_5(b, l + 1); + r = r && consumeToken(b, RBRACE); + exit_section_(b, l, m, r, false, null); + return r; + } + + // [PUB] + private static boolean typeStatement_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatement_0")) return false; + consumeToken(b, PUB); + return true; + } + + // ('<' IDENTIFIER '>')? + private static boolean typeStatement_3(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatement_3")) return false; + typeStatement_3_0(b, l + 1); + return true; + } + + // '<' IDENTIFIER '>' + private static boolean typeStatement_3_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatement_3_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, LT, IDENTIFIER, GT); + exit_section_(b, m, null, r); + return r; + } + + // constructorElement | (typeStatementConstructor | typeStatementConstructorNoArg)* + private static boolean typeStatement_5(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatement_5")) return false; + boolean r; + Marker m = enter_section_(b); + r = constructorElement(b, l + 1); + if (!r) r = typeStatement_5_1(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // (typeStatementConstructor | typeStatementConstructorNoArg)* + private static boolean typeStatement_5_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatement_5_1")) return false; + while (true) { + int c = current_position_(b); + if (!typeStatement_5_1_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "typeStatement_5_1", c)) break; + } + return true; + } + + // typeStatementConstructor | typeStatementConstructorNoArg + private static boolean typeStatement_5_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatement_5_1_0")) return false; + boolean r; + r = typeStatementConstructor(b, l + 1); + if (!r) r = typeStatementConstructorNoArg(b, l + 1); + return r; + } + + /* ********************************************************** */ + // constructorName (LBRACE|LPAREN) (constructorElement | IDENTIFIER)* (RBRACE|RPAREN) + public static boolean typeStatementConstructor(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatementConstructor")) return false; + if (!nextTokenIs(b, UPPER_IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = constructorName(b, l + 1); + r = r && typeStatementConstructor_1(b, l + 1); + r = r && typeStatementConstructor_2(b, l + 1); + r = r && typeStatementConstructor_3(b, l + 1); + exit_section_(b, m, TYPE_STATEMENT_CONSTRUCTOR, r); + return r; + } + + // LBRACE|LPAREN + private static boolean typeStatementConstructor_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatementConstructor_1")) return false; + boolean r; + r = consumeToken(b, LBRACE); + if (!r) r = consumeToken(b, LPAREN); + return r; + } + + // (constructorElement | IDENTIFIER)* + private static boolean typeStatementConstructor_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatementConstructor_2")) return false; + while (true) { + int c = current_position_(b); + if (!typeStatementConstructor_2_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "typeStatementConstructor_2", c)) break; + } + return true; + } + + // constructorElement | IDENTIFIER + private static boolean typeStatementConstructor_2_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatementConstructor_2_0")) return false; + boolean r; + r = constructorElement(b, l + 1); + if (!r) r = consumeToken(b, IDENTIFIER); + return r; + } + + // RBRACE|RPAREN + private static boolean typeStatementConstructor_3(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatementConstructor_3")) return false; + boolean r; + r = consumeToken(b, RBRACE); + if (!r) r = consumeToken(b, RPAREN); + return r; + } + + /* ********************************************************** */ + // constructorName + public static boolean typeStatementConstructorNoArg(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "typeStatementConstructorNoArg")) return false; + if (!nextTokenIs(b, UPPER_IDENTIFIER)) return false; + boolean r; + Marker m = enter_section_(b); + r = constructorName(b, l + 1); + exit_section_(b, m, TYPE_STATEMENT_CONSTRUCTOR_NO_ARG, r); + return r; + } + + /* ********************************************************** */ + // VALIDATOR IDENTIFIER [LPAREN [(constructorElement)*] RPAREN] LBRACE [innerDefinition*] RBRACE + public static boolean validatorStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "validatorStatement")) return false; + if (!nextTokenIs(b, VALIDATOR)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, VALIDATOR, IDENTIFIER); + r = r && validatorStatement_2(b, l + 1); + r = r && consumeToken(b, LBRACE); + r = r && validatorStatement_4(b, l + 1); + r = r && consumeToken(b, RBRACE); + exit_section_(b, m, VALIDATOR_STATEMENT, r); + return r; + } + + // [LPAREN [(constructorElement)*] RPAREN] + private static boolean validatorStatement_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "validatorStatement_2")) return false; + validatorStatement_2_0(b, l + 1); + return true; + } + + // LPAREN [(constructorElement)*] RPAREN + private static boolean validatorStatement_2_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "validatorStatement_2_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, LPAREN); + r = r && validatorStatement_2_0_1(b, l + 1); + r = r && consumeToken(b, RPAREN); + exit_section_(b, m, null, r); + return r; + } + + // [(constructorElement)*] + private static boolean validatorStatement_2_0_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "validatorStatement_2_0_1")) return false; + validatorStatement_2_0_1_0(b, l + 1); + return true; + } + + // (constructorElement)* + private static boolean validatorStatement_2_0_1_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "validatorStatement_2_0_1_0")) return false; + while (true) { + int c = current_position_(b); + if (!validatorStatement_2_0_1_0_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "validatorStatement_2_0_1_0", c)) break; + } + return true; + } + + // (constructorElement) + private static boolean validatorStatement_2_0_1_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "validatorStatement_2_0_1_0_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = constructorElement(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // [innerDefinition*] + private static boolean validatorStatement_4(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "validatorStatement_4")) return false; + validatorStatement_4_0(b, l + 1); + return true; + } + + // innerDefinition* + private static boolean validatorStatement_4_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "validatorStatement_4_0")) return false; + while (true) { + int c = current_position_(b); + if (!innerDefinition(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "validatorStatement_4_0", c)) break; + } + return true; + } + + /* ********************************************************** */ + // LET IDENTIFIER EQ variableValue + public static boolean variableStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "variableStatement")) return false; + if (!nextTokenIs(b, LET)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, LET, IDENTIFIER, EQ); + r = r && variableValue(b, l + 1); + exit_section_(b, m, VARIABLE_STATEMENT, r); + return r; + } + + /* ********************************************************** */ + // functionCall | UPPER_IDENTIFIER | typeIdentifier | IDENTIFIER | NUMBER | STRING_CONTENT + public static boolean variableValue(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "variableValue")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, VARIABLE_VALUE, ""); + r = functionCall(b, l + 1); + if (!r) r = consumeToken(b, UPPER_IDENTIFIER); + if (!r) r = typeIdentifier(b, l + 1); + if (!r) r = consumeToken(b, IDENTIFIER); + if (!r) r = consumeToken(b, NUMBER); + if (!r) r = consumeToken(b, STRING_CONTENT); + exit_section_(b, l, m, r, false, null); + return r; + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstantStatement.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstantStatement.java new file mode 100644 index 0000000..0478bae --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstantStatement.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenConstantStatement extends PsiElement { + + @NotNull + AikenVariableValue getVariableValue(); + + @NotNull + PsiElement getIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstructorIdentifier.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstructorIdentifier.java new file mode 100644 index 0000000..33ea89f --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstructorIdentifier.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenConstructorIdentifier extends PsiElement { + + @NotNull + PsiElement getIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstructorName.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstructorName.java new file mode 100644 index 0000000..814d286 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenConstructorName.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenConstructorName extends PsiElement { + + @NotNull + PsiElement getUpperIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionCall.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionCall.java new file mode 100644 index 0000000..6286e62 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionCall.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenFunctionCall extends PsiElement { + + @Nullable + AikenFunctionCall getFunctionCall(); + + @NotNull + List getFunctionCallParamList(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionCallParam.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionCallParam.java new file mode 100644 index 0000000..ebb165a --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionCallParam.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenFunctionCallParam extends PsiElement { + + @NotNull + AikenVariableValue getVariableValue(); + + @Nullable + PsiElement getIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionStatement.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionStatement.java new file mode 100644 index 0000000..01e3791 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionStatement.java @@ -0,0 +1,31 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenFunctionStatement extends PsiElement { + + @NotNull + List getConstantStatementList(); + + @NotNull + List getConstructorIdentifierList(); + + @NotNull + List getFunctionCallList(); + + @Nullable + AikenFunctionStatementType getFunctionStatementType(); + + @NotNull + List getTypeIdentifierList(); + + @NotNull + List getVariableStatementList(); + + @NotNull + PsiElement getIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionStatementType.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionStatementType.java new file mode 100644 index 0000000..aeb7e4f --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFunctionStatementType.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenFunctionStatementType extends PsiElement { + + @NotNull + AikenTypeIdentifier getTypeIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatement.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatement.java new file mode 100644 index 0000000..7381384 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatement.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenImportStatement extends PsiElement { + + @NotNull + AikenImportStatementElement getImportStatementElement(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatementElement.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatementElement.java new file mode 100644 index 0000000..c6836a5 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatementElement.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenImportStatementElement extends PsiElement { + + @NotNull + List getImportStatementTypesList(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatementTypes.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatementTypes.java new file mode 100644 index 0000000..61b2c40 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenImportStatementTypes.java @@ -0,0 +1,10 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenImportStatementTypes extends PsiElement { + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeIdentifier.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeIdentifier.java new file mode 100644 index 0000000..0cd10a4 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeIdentifier.java @@ -0,0 +1,19 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenTypeIdentifier extends PsiElement { + + @NotNull + List getTypeIdentifierInnerTypeList(); + + @Nullable + PsiElement getIdentifier(); + + @NotNull + PsiElement getUpperIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeIdentifierInnerType.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeIdentifierInnerType.java new file mode 100644 index 0000000..30f0b8e --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeIdentifierInnerType.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenTypeIdentifierInnerType extends PsiElement { + + @NotNull + AikenTypeIdentifier getTypeIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeName.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeName.java new file mode 100644 index 0000000..afd761f --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeName.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenTypeName extends PsiElement { + + @NotNull + PsiElement getUpperIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatement.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatement.java new file mode 100644 index 0000000..abd01af --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatement.java @@ -0,0 +1,28 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenTypeStatement extends PsiElement { + + @Nullable + AikenConstructorIdentifier getConstructorIdentifier(); + + @Nullable + AikenTypeIdentifier getTypeIdentifier(); + + @NotNull + AikenTypeName getTypeName(); + + @NotNull + List getTypeStatementConstructorList(); + + @NotNull + List getTypeStatementConstructorNoArgList(); + + @Nullable + PsiElement getIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatementConstructor.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatementConstructor.java new file mode 100644 index 0000000..0a5e549 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatementConstructor.java @@ -0,0 +1,19 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenTypeStatementConstructor extends PsiElement { + + @NotNull + List getConstructorIdentifierList(); + + @NotNull + AikenConstructorName getConstructorName(); + + @NotNull + List getTypeIdentifierList(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatementConstructorNoArg.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatementConstructorNoArg.java new file mode 100644 index 0000000..f93356c --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypeStatementConstructorNoArg.java @@ -0,0 +1,13 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenTypeStatementConstructorNoArg extends PsiElement { + + @NotNull + AikenConstructorName getConstructorName(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypes.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypes.java new file mode 100644 index 0000000..e432f18 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTypes.java @@ -0,0 +1,155 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.PsiElement; +import com.intellij.lang.ASTNode; +import com.bloxbean.intelliada.idea.aiken.lang.psi.impl.*; + +public interface AikenTypes { + + IElementType CONSTANT_STATEMENT = new AikenElementType("CONSTANT_STATEMENT"); + IElementType CONSTRUCTOR_IDENTIFIER = new AikenElementType("CONSTRUCTOR_IDENTIFIER"); + IElementType CONSTRUCTOR_NAME = new AikenElementType("CONSTRUCTOR_NAME"); + IElementType FUNCTION_CALL = new AikenElementType("FUNCTION_CALL"); + IElementType FUNCTION_CALL_PARAM = new AikenElementType("FUNCTION_CALL_PARAM"); + IElementType FUNCTION_STATEMENT = new AikenElementType("FUNCTION_STATEMENT"); + IElementType FUNCTION_STATEMENT_TYPE = new AikenElementType("FUNCTION_STATEMENT_TYPE"); + IElementType IMPORT_STATEMENT = new AikenElementType("IMPORT_STATEMENT"); + IElementType IMPORT_STATEMENT_ELEMENT = new AikenElementType("IMPORT_STATEMENT_ELEMENT"); + IElementType IMPORT_STATEMENT_TYPES = new AikenElementType("IMPORT_STATEMENT_TYPES"); + IElementType TYPE_IDENTIFIER = new AikenElementType("TYPE_IDENTIFIER"); + IElementType TYPE_IDENTIFIER_INNER_TYPE = new AikenElementType("TYPE_IDENTIFIER_INNER_TYPE"); + IElementType TYPE_NAME = new AikenElementType("TYPE_NAME"); + IElementType TYPE_STATEMENT = new AikenElementType("TYPE_STATEMENT"); + IElementType TYPE_STATEMENT_CONSTRUCTOR = new AikenElementType("TYPE_STATEMENT_CONSTRUCTOR"); + IElementType TYPE_STATEMENT_CONSTRUCTOR_NO_ARG = new AikenElementType("TYPE_STATEMENT_CONSTRUCTOR_NO_ARG"); + IElementType VALIDATOR_STATEMENT = new AikenElementType("VALIDATOR_STATEMENT"); + IElementType VARIABLE_STATEMENT = new AikenElementType("VARIABLE_STATEMENT"); + IElementType VARIABLE_VALUE = new AikenElementType("VARIABLE_VALUE"); + + IElementType AND = new AikenTokenType("&&"); + IElementType ARROW = new AikenTokenType("->"); + IElementType AS = new AikenTokenType("as"); + IElementType BANG = new AikenTokenType("!"); + IElementType CHECK = new AikenTokenType("check"); + IElementType COLON = new AikenTokenType(":"); + IElementType COMMA = new AikenTokenType(","); + IElementType COMMENT = new AikenTokenType("COMMENT"); + IElementType CONST = new AikenTokenType("const"); + IElementType DIV = new AikenTokenType("/"); + IElementType DIVDIV = new AikenTokenType("//"); + IElementType DOC_COMMENT = new AikenTokenType("DOC_COMMENT"); + IElementType DOT = new AikenTokenType("."); + IElementType DOTDOT = new AikenTokenType(".."); + IElementType ELSE = new AikenTokenType("else"); + IElementType EQ = new AikenTokenType("="); + IElementType EQEQ = new AikenTokenType("=="); + IElementType EXPECT = new AikenTokenType("expect"); + IElementType EXTERNAL = new AikenTokenType("external"); + IElementType FAIL = new AikenTokenType("fail"); + IElementType FAT_ARROW = new AikenTokenType("=>"); + IElementType FN = new AikenTokenType("fn"); + IElementType GT = new AikenTokenType(">"); + IElementType IDENTIFIER = new AikenTokenType("IDENTIFIER"); + IElementType IF = new AikenTokenType("if"); + IElementType IS = new AikenTokenType("is"); + IElementType LBRACE = new AikenTokenType("{"); + IElementType LBRACK = new AikenTokenType("["); + IElementType LET = new AikenTokenType("let"); + IElementType LPAREN = new AikenTokenType("("); + IElementType LT = new AikenTokenType("<"); + IElementType MINT = new AikenTokenType("mint"); + IElementType MINUS = new AikenTokenType("-"); + IElementType MODULE_COMMENT = new AikenTokenType("MODULE_COMMENT"); + IElementType MUL = new AikenTokenType("*"); + IElementType NUMBER = new AikenTokenType("NUMBER"); + IElementType OPAQUE = new AikenTokenType("opaque"); + IElementType OR = new AikenTokenType("||"); + IElementType PIPE = new AikenTokenType("|>"); + IElementType PLUS = new AikenTokenType("+"); + IElementType PROPOSE = new AikenTokenType("propose"); + IElementType PUB = new AikenTokenType("pub"); + IElementType PUBLISH = new AikenTokenType("publish"); + IElementType QUOTE = new AikenTokenType("\""); + IElementType RBRACE = new AikenTokenType("}"); + IElementType RBRACK = new AikenTokenType("]"); + IElementType RPAREN = new AikenTokenType(")"); + IElementType SPEND = new AikenTokenType("spend"); + IElementType STRING_CONTENT = new AikenTokenType("STRING_CONTENT"); + IElementType TEST = new AikenTokenType("test"); + IElementType TODO = new AikenTokenType("todo"); + IElementType TRACE = new AikenTokenType("trace"); + IElementType TYPE = new AikenTokenType("type"); + IElementType UPPER_IDENTIFIER = new AikenTokenType("UPPER_IDENTIFIER"); + IElementType USE = new AikenTokenType("use"); + IElementType VALIDATOR = new AikenTokenType("validator"); + IElementType VIA = new AikenTokenType("via"); + IElementType VOTE = new AikenTokenType("vote"); + IElementType WHEN = new AikenTokenType("when"); + IElementType WITHDRAW = new AikenTokenType("withdraw"); + + class Factory { + public static PsiElement createElement(ASTNode node) { + IElementType type = node.getElementType(); + if (type == CONSTANT_STATEMENT) { + return new AikenConstantStatementImpl(node); + } + else if (type == CONSTRUCTOR_IDENTIFIER) { + return new AikenConstructorIdentifierImpl(node); + } + else if (type == CONSTRUCTOR_NAME) { + return new AikenConstructorNameImpl(node); + } + else if (type == FUNCTION_CALL) { + return new AikenFunctionCallImpl(node); + } + else if (type == FUNCTION_CALL_PARAM) { + return new AikenFunctionCallParamImpl(node); + } + else if (type == FUNCTION_STATEMENT) { + return new AikenFunctionStatementImpl(node); + } + else if (type == FUNCTION_STATEMENT_TYPE) { + return new AikenFunctionStatementTypeImpl(node); + } + else if (type == IMPORT_STATEMENT) { + return new AikenImportStatementImpl(node); + } + else if (type == IMPORT_STATEMENT_ELEMENT) { + return new AikenImportStatementElementImpl(node); + } + else if (type == IMPORT_STATEMENT_TYPES) { + return new AikenImportStatementTypesImpl(node); + } + else if (type == TYPE_IDENTIFIER) { + return new AikenTypeIdentifierImpl(node); + } + else if (type == TYPE_IDENTIFIER_INNER_TYPE) { + return new AikenTypeIdentifierInnerTypeImpl(node); + } + else if (type == TYPE_NAME) { + return new AikenTypeNameImpl(node); + } + else if (type == TYPE_STATEMENT) { + return new AikenTypeStatementImpl(node); + } + else if (type == TYPE_STATEMENT_CONSTRUCTOR) { + return new AikenTypeStatementConstructorImpl(node); + } + else if (type == TYPE_STATEMENT_CONSTRUCTOR_NO_ARG) { + return new AikenTypeStatementConstructorNoArgImpl(node); + } + else if (type == VALIDATOR_STATEMENT) { + return new AikenValidatorStatementImpl(node); + } + else if (type == VARIABLE_STATEMENT) { + return new AikenVariableStatementImpl(node); + } + else if (type == VARIABLE_VALUE) { + return new AikenVariableValueImpl(node); + } + throw new AssertionError("Unknown element type: " + type); + } + } +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenValidatorStatement.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenValidatorStatement.java new file mode 100644 index 0000000..0f33f98 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenValidatorStatement.java @@ -0,0 +1,28 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenValidatorStatement extends PsiElement { + + @NotNull + List getConstantStatementList(); + + @NotNull + List getConstructorIdentifierList(); + + @NotNull + List getFunctionCallList(); + + @NotNull + List getTypeIdentifierList(); + + @NotNull + List getVariableStatementList(); + + @NotNull + PsiElement getIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVariableStatement.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVariableStatement.java new file mode 100644 index 0000000..8922bf9 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVariableStatement.java @@ -0,0 +1,16 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenVariableStatement extends PsiElement { + + @NotNull + AikenVariableValue getVariableValue(); + + @NotNull + PsiElement getIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVariableValue.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVariableValue.java new file mode 100644 index 0000000..1d895c6 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVariableValue.java @@ -0,0 +1,28 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import java.util.List; +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElement; + +public interface AikenVariableValue extends PsiElement { + + @Nullable + AikenFunctionCall getFunctionCall(); + + @Nullable + AikenTypeIdentifier getTypeIdentifier(); + + @Nullable + PsiElement getIdentifier(); + + @Nullable + PsiElement getNumber(); + + @Nullable + PsiElement getStringContent(); + + @Nullable + PsiElement getUpperIdentifier(); + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVisitor.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVisitor.java new file mode 100644 index 0000000..aa7c63f --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenVisitor.java @@ -0,0 +1,90 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import org.jetbrains.annotations.*; +import com.intellij.psi.PsiElementVisitor; +import com.intellij.psi.PsiElement; + +public class AikenVisitor extends PsiElementVisitor { + + public void visitConstantStatement(@NotNull AikenConstantStatement o) { + visitPsiElement(o); + } + + public void visitConstructorIdentifier(@NotNull AikenConstructorIdentifier o) { + visitPsiElement(o); + } + + public void visitConstructorName(@NotNull AikenConstructorName o) { + visitPsiElement(o); + } + + public void visitFunctionCall(@NotNull AikenFunctionCall o) { + visitPsiElement(o); + } + + public void visitFunctionCallParam(@NotNull AikenFunctionCallParam o) { + visitPsiElement(o); + } + + public void visitFunctionStatement(@NotNull AikenFunctionStatement o) { + visitPsiElement(o); + } + + public void visitFunctionStatementType(@NotNull AikenFunctionStatementType o) { + visitPsiElement(o); + } + + public void visitImportStatement(@NotNull AikenImportStatement o) { + visitPsiElement(o); + } + + public void visitImportStatementElement(@NotNull AikenImportStatementElement o) { + visitPsiElement(o); + } + + public void visitImportStatementTypes(@NotNull AikenImportStatementTypes o) { + visitPsiElement(o); + } + + public void visitTypeIdentifier(@NotNull AikenTypeIdentifier o) { + visitPsiElement(o); + } + + public void visitTypeIdentifierInnerType(@NotNull AikenTypeIdentifierInnerType o) { + visitPsiElement(o); + } + + public void visitTypeName(@NotNull AikenTypeName o) { + visitPsiElement(o); + } + + public void visitTypeStatement(@NotNull AikenTypeStatement o) { + visitPsiElement(o); + } + + public void visitTypeStatementConstructor(@NotNull AikenTypeStatementConstructor o) { + visitPsiElement(o); + } + + public void visitTypeStatementConstructorNoArg(@NotNull AikenTypeStatementConstructorNoArg o) { + visitPsiElement(o); + } + + public void visitValidatorStatement(@NotNull AikenValidatorStatement o) { + visitPsiElement(o); + } + + public void visitVariableStatement(@NotNull AikenVariableStatement o) { + visitPsiElement(o); + } + + public void visitVariableValue(@NotNull AikenVariableValue o) { + visitPsiElement(o); + } + + public void visitPsiElement(@NotNull PsiElement o) { + visitElement(o); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstantStatementImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstantStatementImpl.java new file mode 100644 index 0000000..83cae7b --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstantStatementImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenConstantStatementImpl extends ASTWrapperPsiElement implements AikenConstantStatement { + + public AikenConstantStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitConstantStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public AikenVariableValue getVariableValue() { + return findNotNullChildByClass(AikenVariableValue.class); + } + + @Override + @NotNull + public PsiElement getIdentifier() { + return findNotNullChildByType(IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstructorIdentifierImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstructorIdentifierImpl.java new file mode 100644 index 0000000..7923cff --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstructorIdentifierImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenConstructorIdentifierImpl extends ASTWrapperPsiElement implements AikenConstructorIdentifier { + + public AikenConstructorIdentifierImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitConstructorIdentifier(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public PsiElement getIdentifier() { + return findNotNullChildByType(IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstructorNameImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstructorNameImpl.java new file mode 100644 index 0000000..eb2afc3 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenConstructorNameImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenConstructorNameImpl extends ASTWrapperPsiElement implements AikenConstructorName { + + public AikenConstructorNameImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitConstructorName(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public PsiElement getUpperIdentifier() { + return findNotNullChildByType(UPPER_IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionCallImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionCallImpl.java new file mode 100644 index 0000000..5f4299f --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionCallImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenFunctionCallImpl extends ASTWrapperPsiElement implements AikenFunctionCall { + + public AikenFunctionCallImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitFunctionCall(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @Nullable + public AikenFunctionCall getFunctionCall() { + return findChildByClass(AikenFunctionCall.class); + } + + @Override + @NotNull + public List getFunctionCallParamList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenFunctionCallParam.class); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionCallParamImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionCallParamImpl.java new file mode 100644 index 0000000..34d95b2 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionCallParamImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenFunctionCallParamImpl extends ASTWrapperPsiElement implements AikenFunctionCallParam { + + public AikenFunctionCallParamImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitFunctionCallParam(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public AikenVariableValue getVariableValue() { + return findNotNullChildByClass(AikenVariableValue.class); + } + + @Override + @Nullable + public PsiElement getIdentifier() { + return findChildByType(IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionStatementImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionStatementImpl.java new file mode 100644 index 0000000..394a5d6 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionStatementImpl.java @@ -0,0 +1,72 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenFunctionStatementImpl extends ASTWrapperPsiElement implements AikenFunctionStatement { + + public AikenFunctionStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitFunctionStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public List getConstantStatementList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenConstantStatement.class); + } + + @Override + @NotNull + public List getConstructorIdentifierList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenConstructorIdentifier.class); + } + + @Override + @NotNull + public List getFunctionCallList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenFunctionCall.class); + } + + @Override + @Nullable + public AikenFunctionStatementType getFunctionStatementType() { + return findChildByClass(AikenFunctionStatementType.class); + } + + @Override + @NotNull + public List getTypeIdentifierList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenTypeIdentifier.class); + } + + @Override + @NotNull + public List getVariableStatementList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenVariableStatement.class); + } + + @Override + @NotNull + public PsiElement getIdentifier() { + return findNotNullChildByType(IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionStatementTypeImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionStatementTypeImpl.java new file mode 100644 index 0000000..51783e6 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenFunctionStatementTypeImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenFunctionStatementTypeImpl extends ASTWrapperPsiElement implements AikenFunctionStatementType { + + public AikenFunctionStatementTypeImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitFunctionStatementType(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public AikenTypeIdentifier getTypeIdentifier() { + return findNotNullChildByClass(AikenTypeIdentifier.class); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementElementImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementElementImpl.java new file mode 100644 index 0000000..52ecbdd --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementElementImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenImportStatementElementImpl extends ASTWrapperPsiElement implements AikenImportStatementElement { + + public AikenImportStatementElementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitImportStatementElement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public List getImportStatementTypesList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenImportStatementTypes.class); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementImpl.java new file mode 100644 index 0000000..fd7283a --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenImportStatementImpl extends ASTWrapperPsiElement implements AikenImportStatement { + + public AikenImportStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitImportStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public AikenImportStatementElement getImportStatementElement() { + return findNotNullChildByClass(AikenImportStatementElement.class); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementTypesImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementTypesImpl.java new file mode 100644 index 0000000..103171b --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenImportStatementTypesImpl.java @@ -0,0 +1,30 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenImportStatementTypesImpl extends ASTWrapperPsiElement implements AikenImportStatementTypes { + + public AikenImportStatementTypesImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitImportStatementTypes(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeIdentifierImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeIdentifierImpl.java new file mode 100644 index 0000000..5b52968 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeIdentifierImpl.java @@ -0,0 +1,48 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenTypeIdentifierImpl extends ASTWrapperPsiElement implements AikenTypeIdentifier { + + public AikenTypeIdentifierImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitTypeIdentifier(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public List getTypeIdentifierInnerTypeList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenTypeIdentifierInnerType.class); + } + + @Override + @Nullable + public PsiElement getIdentifier() { + return findChildByType(IDENTIFIER); + } + + @Override + @NotNull + public PsiElement getUpperIdentifier() { + return findNotNullChildByType(UPPER_IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeIdentifierInnerTypeImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeIdentifierInnerTypeImpl.java new file mode 100644 index 0000000..3fe72a6 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeIdentifierInnerTypeImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenTypeIdentifierInnerTypeImpl extends ASTWrapperPsiElement implements AikenTypeIdentifierInnerType { + + public AikenTypeIdentifierInnerTypeImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitTypeIdentifierInnerType(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public AikenTypeIdentifier getTypeIdentifier() { + return findNotNullChildByClass(AikenTypeIdentifier.class); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeNameImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeNameImpl.java new file mode 100644 index 0000000..adf0c5e --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeNameImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenTypeNameImpl extends ASTWrapperPsiElement implements AikenTypeName { + + public AikenTypeNameImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitTypeName(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public PsiElement getUpperIdentifier() { + return findNotNullChildByType(UPPER_IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementConstructorImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementConstructorImpl.java new file mode 100644 index 0000000..3c94e15 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementConstructorImpl.java @@ -0,0 +1,48 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenTypeStatementConstructorImpl extends ASTWrapperPsiElement implements AikenTypeStatementConstructor { + + public AikenTypeStatementConstructorImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitTypeStatementConstructor(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public List getConstructorIdentifierList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenConstructorIdentifier.class); + } + + @Override + @NotNull + public AikenConstructorName getConstructorName() { + return findNotNullChildByClass(AikenConstructorName.class); + } + + @Override + @NotNull + public List getTypeIdentifierList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenTypeIdentifier.class); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementConstructorNoArgImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementConstructorNoArgImpl.java new file mode 100644 index 0000000..2e0b427 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementConstructorNoArgImpl.java @@ -0,0 +1,36 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenTypeStatementConstructorNoArgImpl extends ASTWrapperPsiElement implements AikenTypeStatementConstructorNoArg { + + public AikenTypeStatementConstructorNoArgImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitTypeStatementConstructorNoArg(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public AikenConstructorName getConstructorName() { + return findNotNullChildByClass(AikenConstructorName.class); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementImpl.java new file mode 100644 index 0000000..e927b82 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenTypeStatementImpl.java @@ -0,0 +1,66 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenTypeStatementImpl extends ASTWrapperPsiElement implements AikenTypeStatement { + + public AikenTypeStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitTypeStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @Nullable + public AikenConstructorIdentifier getConstructorIdentifier() { + return findChildByClass(AikenConstructorIdentifier.class); + } + + @Override + @Nullable + public AikenTypeIdentifier getTypeIdentifier() { + return findChildByClass(AikenTypeIdentifier.class); + } + + @Override + @NotNull + public AikenTypeName getTypeName() { + return findNotNullChildByClass(AikenTypeName.class); + } + + @Override + @NotNull + public List getTypeStatementConstructorList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenTypeStatementConstructor.class); + } + + @Override + @NotNull + public List getTypeStatementConstructorNoArgList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenTypeStatementConstructorNoArg.class); + } + + @Override + @Nullable + public PsiElement getIdentifier() { + return findChildByType(IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenValidatorStatementImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenValidatorStatementImpl.java new file mode 100644 index 0000000..735d609 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenValidatorStatementImpl.java @@ -0,0 +1,66 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenValidatorStatementImpl extends ASTWrapperPsiElement implements AikenValidatorStatement { + + public AikenValidatorStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitValidatorStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public List getConstantStatementList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenConstantStatement.class); + } + + @Override + @NotNull + public List getConstructorIdentifierList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenConstructorIdentifier.class); + } + + @Override + @NotNull + public List getFunctionCallList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenFunctionCall.class); + } + + @Override + @NotNull + public List getTypeIdentifierList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenTypeIdentifier.class); + } + + @Override + @NotNull + public List getVariableStatementList() { + return PsiTreeUtil.getChildrenOfTypeAsList(this, AikenVariableStatement.class); + } + + @Override + @NotNull + public PsiElement getIdentifier() { + return findNotNullChildByType(IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenVariableStatementImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenVariableStatementImpl.java new file mode 100644 index 0000000..6ac7693 --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenVariableStatementImpl.java @@ -0,0 +1,42 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenVariableStatementImpl extends ASTWrapperPsiElement implements AikenVariableStatement { + + public AikenVariableStatementImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitVariableStatement(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @NotNull + public AikenVariableValue getVariableValue() { + return findNotNullChildByClass(AikenVariableValue.class); + } + + @Override + @NotNull + public PsiElement getIdentifier() { + return findNotNullChildByType(IDENTIFIER); + } + +} diff --git a/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenVariableValueImpl.java b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenVariableValueImpl.java new file mode 100644 index 0000000..320fedc --- /dev/null +++ b/src/main/gen/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenVariableValueImpl.java @@ -0,0 +1,66 @@ +// This is a generated file. Not intended for manual editing. +package com.bloxbean.intelliada.idea.aiken.lang.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 com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; + +public class AikenVariableValueImpl extends ASTWrapperPsiElement implements AikenVariableValue { + + public AikenVariableValueImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull AikenVisitor visitor) { + visitor.visitVariableValue(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof AikenVisitor) accept((AikenVisitor)visitor); + else super.accept(visitor); + } + + @Override + @Nullable + public AikenFunctionCall getFunctionCall() { + return findChildByClass(AikenFunctionCall.class); + } + + @Override + @Nullable + public AikenTypeIdentifier getTypeIdentifier() { + return findChildByClass(AikenTypeIdentifier.class); + } + + @Override + @Nullable + public PsiElement getIdentifier() { + return findChildByType(IDENTIFIER); + } + + @Override + @Nullable + public PsiElement getNumber() { + return findChildByType(NUMBER); + } + + @Override + @Nullable + public PsiElement getStringContent() { + return findChildByType(STRING_CONTENT); + } + + @Override + @Nullable + public PsiElement getUpperIdentifier() { + return findChildByType(UPPER_IDENTIFIER); + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/account/action/CreateAccountAction.java b/src/main/java/com/bloxbean/intelliada/idea/account/action/CreateAccountAction.java index 1b60827..ec4f66b 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/account/action/CreateAccountAction.java +++ b/src/main/java/com/bloxbean/intelliada/idea/account/action/CreateAccountAction.java @@ -27,7 +27,6 @@ import com.bloxbean.intelliada.idea.account.ui.CreateAccountDialog; import com.bloxbean.intelliada.idea.core.util.Network; import com.bloxbean.intelliada.idea.core.util.NetworkUtil; -import com.bloxbean.intelliada.idea.core.util.Networks; import com.bloxbean.intelliada.idea.toolwindow.CardanoConsole; import com.bloxbean.intelliada.idea.util.IdeaUtil; import com.intellij.icons.AllIcons; @@ -36,8 +35,6 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; -import com.twelvemonkeys.lang.StringUtil; import org.jetbrains.annotations.NotNull; import java.security.NoSuchAlgorithmException; diff --git a/src/main/java/com/bloxbean/intelliada/idea/account/ui/ListAccountDialog.java b/src/main/java/com/bloxbean/intelliada/idea/account/ui/ListAccountDialog.java index 737fbad..547825a 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/account/ui/ListAccountDialog.java +++ b/src/main/java/com/bloxbean/intelliada/idea/account/ui/ListAccountDialog.java @@ -53,8 +53,8 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.awt.RelativePoint; -import com.twelvemonkeys.lang.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageClient.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageClient.java new file mode 100644 index 0000000..0feb95b --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageClient.java @@ -0,0 +1,20 @@ +package com.bloxbean.intelliada.idea.aiken; + +import com.intellij.openapi.project.Project; +import com.redhat.devtools.lsp4ij.ServerStatus; +import com.redhat.devtools.lsp4ij.client.LanguageClientImpl; + +public class AikenLanguageClient extends LanguageClientImpl { + + public AikenLanguageClient(Project project) { + super(project); + } + + @Override + public void handleServerStatusChanged(ServerStatus serverStatus) { + if (serverStatus == ServerStatus.started) { + triggerChangeConfiguration(); + } + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageServer.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageServer.java new file mode 100644 index 0000000..8e0594a --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageServer.java @@ -0,0 +1,28 @@ +package com.bloxbean.intelliada.idea.aiken; + +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationHelperService; +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.project.Project; +import com.redhat.devtools.lsp4ij.server.ProcessStreamConnectionProvider; + +import java.util.List; + +public class AikenLanguageServer extends ProcessStreamConnectionProvider { + + public AikenLanguageServer(Project project) { + var aikenSdk = AikenConfigurationHelperService.getCompilerLocalSDK(project); + + if (aikenSdk == null) { + IdeaUtil.showNotification(project, "Aiken LSP", "Aiken executable not found", NotificationType.WARNING, null); + return; + } + List aikenCmds = aikenSdk.getAikenCommand(); + + aikenCmds.add("lsp"); + aikenCmds.add("--stdio"); + super.setCommands(aikenCmds); + super.setWorkingDirectory(project.getBasePath()); + super.setIncludeSystemEnvironmentVariables(true); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageServerFactory.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageServerFactory.java new file mode 100644 index 0000000..a988c32 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/AikenLanguageServerFactory.java @@ -0,0 +1,33 @@ +package com.bloxbean.intelliada.idea.aiken; + +import com.intellij.openapi.project.Project; +import com.redhat.devtools.lsp4ij.LanguageServerEnablementSupport; +import com.redhat.devtools.lsp4ij.LanguageServerFactory; +import com.redhat.devtools.lsp4ij.client.LanguageClientImpl; +import com.redhat.devtools.lsp4ij.server.StreamConnectionProvider; +import org.jetbrains.annotations.NotNull; + +public class AikenLanguageServerFactory implements LanguageServerFactory, LanguageServerEnablementSupport { + private boolean enabled = true; + @Override + public @NotNull StreamConnectionProvider createConnectionProvider(@NotNull Project project) { + return new AikenLanguageServer(project); + } + + @Override + public @NotNull LanguageClientImpl createLanguageClient(@NotNull Project project) { + var languageClient = new AikenLanguageClient(project); + return languageClient; + } + + @Override + public boolean isEnabled(@NotNull Project project) { + return enabled; + } + + @Override + public void setEnabled(boolean enabled, @NotNull Project project) { + this.enabled = enabled; + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/action/AikenActionGroup.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/action/AikenActionGroup.java new file mode 100644 index 0000000..c349b7c --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/action/AikenActionGroup.java @@ -0,0 +1,41 @@ +package com.bloxbean.intelliada.idea.aiken.action; + +import com.bloxbean.intelliada.idea.aiken.common.AikenIcons; +import com.bloxbean.intelliada.idea.aiken.module.AikenModuleType; +import com.bloxbean.intelliada.idea.aiken.module.pkg.AikenTomlService; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.project.Project; + +public class AikenActionGroup extends DefaultActionGroup { + @Override + public void update(AnActionEvent event) { + Project project = event.getProject(); + + DataContext dataContext = event.getDataContext(); + final Module module = LangDataKeys.MODULE.getData(dataContext); + + final ModuleType moduleType = module == null ? null : ModuleType.get(module); + boolean isAikenModule = moduleType instanceof AikenModuleType; + + //Try to check if aiken.toml file available. + //For non-Aiken modules + if(!isAikenModule) { + AikenTomlService aikenTomlService = AikenTomlService.getInstance(project); + if (aikenTomlService != null) + isAikenModule = aikenTomlService.isAikenProject(); + } + + if(isAikenModule) { + event.getPresentation().setVisible(true); + event.getPresentation().setIcon(AikenIcons.AIKEN_ICON); + } else { + event.getPresentation().setVisible(false); + event.getPresentation().setIcon(AikenIcons.AIKEN_ICON); + } + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/action/NewAikenFileAction.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/action/NewAikenFileAction.java new file mode 100644 index 0000000..6f41fa9 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/action/NewAikenFileAction.java @@ -0,0 +1,110 @@ +package com.bloxbean.intelliada.idea.aiken.action; + +import com.bloxbean.intelliada.idea.aiken.action.util.AikenFileTemplateUtil; +import com.bloxbean.intelliada.idea.aiken.common.AikenIcons; +import com.bloxbean.intelliada.idea.aiken.module.AikenModuleType; +import com.bloxbean.intelliada.idea.aiken.module.pkg.AikenTomlService; +import com.intellij.icons.AllIcons; +import com.intellij.ide.actions.CreateFileFromTemplateDialog; +import com.intellij.ide.actions.CreateFromTemplateAction; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.fileTemplates.FileTemplateUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidatorEx; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Properties; + +public class NewAikenFileAction extends CreateFromTemplateAction { + + public NewAikenFileAction() { + super("Aiken File", null, AikenIcons.AIKEN_ICON); + } + + @Override + protected boolean isAvailable(DataContext dataContext) { + + final Module module = LangDataKeys.MODULE.getData(dataContext); + final ModuleType moduleType = module == null ? null : ModuleType.get(module); + boolean isAikenModule = moduleType instanceof AikenModuleType; + + if(!isAikenModule && module != null) { //For non aiken modules. Check if aiken.toml available. + AikenTomlService aikenTomlService = AikenTomlService.getInstance(module.getProject()); + if (aikenTomlService != null) + isAikenModule = aikenTomlService.isAikenProject(); + } + + return super.isAvailable(dataContext) && isAikenModule; + } + + @Override + protected String getActionName(PsiDirectory directory, String newName, String templateName) { + return "Creating File " + newName; + } + + @Override + protected void buildDialog(Project project, PsiDirectory directory, CreateFileFromTemplateDialog.Builder builder) { +// builder.setTitle(IdeBundle.message("action.create.new.class")); + builder.setTitle("Create Aiken file"); + for (FileTemplate fileTemplate : AikenFileTemplateUtil.getApplicableTemplates()) { + final String templateName = fileTemplate.getName(); + final String shortName = AikenFileTemplateUtil.getTemplateShortName(templateName); + final Icon icon = AllIcons.FileTypes.Any_type; + builder.addKind(shortName, icon, templateName); + } + builder.setValidator(new InputValidatorEx() { + @Override + public String getErrorText(String inputString) { + if (inputString.length() > 0 && !StringUtil.isJavaIdentifier(inputString)) { + return "This is not a valid Aiken file name"; + } + return null; + } + + @Override + public boolean checkInput(String inputString) { + return true; + } + + @Override + public boolean canClose(String inputString) { + return !StringUtil.isEmptyOrSpaces(inputString) && getErrorText(inputString) == null; + } + }); + } + + @Nullable + @Override + protected PsiFile createFile(String akName, String templateName, PsiDirectory dir) { + try { + return createFile(akName, dir, templateName).getContainingFile(); + } + catch (Exception e) { + if(LOG.isDebugEnabled()) { + LOG.error("Unable to create aiken file"); + } + throw new RuntimeException(e); + } + } + + private static PsiElement createFile(String className, @NotNull PsiDirectory directory, final String templateName) + throws Exception { + final Properties props = new Properties(FileTemplateManager.getDefaultInstance().getDefaultProperties()); + props.setProperty(FileTemplate.ATTRIBUTE_NAME, className); + + final FileTemplate template = FileTemplateManager.getDefaultInstance().getInternalTemplate(templateName); + + return FileTemplateUtil.createFromTemplate(template, className, props, directory, NewAikenFileAction.class.getClassLoader()); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/action/util/AikenFileTemplateUtil.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/action/util/AikenFileTemplateUtil.java new file mode 100644 index 0000000..0d88477 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/action/util/AikenFileTemplateUtil.java @@ -0,0 +1,39 @@ +package com.bloxbean.intelliada.idea.aiken.action.util; + +import com.bloxbean.intelliada.idea.aiken.lang.AikenFileType; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.openapi.util.Condition; +import com.intellij.util.SmartList; +import com.intellij.util.containers.ContainerUtil; + +import java.util.List; + +public class AikenFileTemplateUtil { + + private final static String AIKEN_TEMPLATE_PREFIX = "Aiken."; + + public static List getApplicableTemplates() { + return getApplicableTemplates(new Condition() { + @Override + public boolean value(FileTemplate fileTemplate) { + return AikenFileType.INSTANCE.getDefaultExtension().equals(fileTemplate.getExtension()) + && fileTemplate.getName().startsWith(AIKEN_TEMPLATE_PREFIX); + } + }); + } + + public static List getApplicableTemplates(Condition filter) { + final List applicableTemplates = new SmartList(); + applicableTemplates.addAll(ContainerUtil.findAll(FileTemplateManager.getDefaultInstance().getInternalTemplates(), filter)); + //applicableTemplates.addAll(ContainerUtil.findAll(FileTemplateManager.getInstance().getAllTemplates(), filter)); + return applicableTemplates; + } + + public static String getTemplateShortName(String templateName) { + if (templateName.startsWith(AIKEN_TEMPLATE_PREFIX)) { + return templateName.substring(AIKEN_TEMPLATE_PREFIX.length()); + } + return templateName; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/color/AikenColors.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/color/AikenColors.java new file mode 100644 index 0000000..72572b4 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/color/AikenColors.java @@ -0,0 +1,23 @@ +package com.bloxbean.intelliada.idea.aiken.color; + +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; + +import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey; + +public class AikenColors { + public static final TextAttributesKey COMMENT = + createTextAttributesKey("Comment//Comment", DefaultLanguageHighlighterColors.LINE_COMMENT); + public static final TextAttributesKey DOC_COMMENT = + createTextAttributesKey("Comment//Documentation", DefaultLanguageHighlighterColors.DOC_COMMENT); + public static final TextAttributesKey MODULE_COMMENT = + createTextAttributesKey("Comment//Module Documentation", DefaultLanguageHighlighterColors.LINE_COMMENT); + public static final TextAttributesKey KEYWORD = + createTextAttributesKey("Keyword", DefaultLanguageHighlighterColors.KEYWORD); + public static final TextAttributesKey STRING = + createTextAttributesKey("String", DefaultLanguageHighlighterColors.STRING); + public static final TextAttributesKey IDENTIFIER = + createTextAttributesKey("Identifier//Type", DefaultLanguageHighlighterColors.CLASS_NAME); + public static final TextAttributesKey TYPE_NAME = + createTextAttributesKey("TypeName", DefaultLanguageHighlighterColors.CLASS_NAME); +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/comment/AikenCommenter.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/comment/AikenCommenter.java new file mode 100644 index 0000000..54c418e --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/comment/AikenCommenter.java @@ -0,0 +1,78 @@ +package com.bloxbean.intelliada.idea.aiken.comment; + +import com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes; +import com.intellij.codeInsight.generation.IndentedCommenter; +import com.intellij.lang.CodeDocumentationAwareCommenter; +import com.intellij.psi.PsiComment; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.Nullable; + +public class AikenCommenter implements CodeDocumentationAwareCommenter, IndentedCommenter { + public static final String COMMENT = "// "; + public static final String DOC_COMMENT = "/// "; + + @Override + public @Nullable Boolean forceIndentedLineComment() { + return true; + } + + @Override + public @Nullable IElementType getLineCommentTokenType() { + return AikenTypes.COMMENT; + } + + @Override + public @Nullable IElementType getBlockCommentTokenType() { + return null; + } + + @Override + public @Nullable IElementType getDocumentationCommentTokenType() { + return AikenTypes.DOC_COMMENT; + } + + @Override + public @Nullable String getDocumentationCommentPrefix() { + return null; + } + + @Override + public @Nullable String getDocumentationCommentLinePrefix() { + return DOC_COMMENT; + } + + @Override + public @Nullable String getDocumentationCommentSuffix() { + return null; + } + + @Override + public boolean isDocumentationComment(PsiComment element) { + return false; + } + + @Override + public @Nullable String getLineCommentPrefix() { + return COMMENT; + } + + @Override + public @Nullable String getBlockCommentPrefix() { + return null; + } + + @Override + public @Nullable String getBlockCommentSuffix() { + return null; + } + + @Override + public @Nullable String getCommentedBlockCommentPrefix() { + return null; + } + + @Override + public @Nullable String getCommentedBlockCommentSuffix() { + return null; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/common/AikenIcons.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/common/AikenIcons.java new file mode 100644 index 0000000..0cb2b15 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/common/AikenIcons.java @@ -0,0 +1,11 @@ +package com.bloxbean.intelliada.idea.aiken.common; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class AikenIcons { + public static final Icon FILE = IconLoader.getIcon("/icons/aiken.png", AikenIcons.class); + public static final Icon MODULE = IconLoader.getIcon("/icons/aiken_module.png", AikenIcons.class); + public static final Icon AIKEN_ICON = IconLoader.getIcon("/icons/aiken_module.png", AikenIcons.class);; +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/AikenCompileService.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/AikenCompileService.java new file mode 100644 index 0000000..c452b12 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/AikenCompileService.java @@ -0,0 +1,125 @@ +package com.bloxbean.intelliada.idea.aiken.compile; + +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationHelperService; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessListener; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.SystemInfo; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class AikenCompileService extends BaseCompileService { + private AikenSDK localSDK; + private String cwd; + + public AikenCompileService(@NotNull Project project) throws SDKNotConfigured { + this.cwd = project.getBasePath(); + + localSDK = AikenConfigurationHelperService.getCompilerLocalSDK(project); + if(localSDK == null) { + throw new SDKNotConfigured("Aiken SDK is not configured."); + } + } + + @Override + public void compile(String sourceFilePath, CompilationResultListener listener) { + List cmd = new ArrayList<>(); + cmd.add(localSDK.getPath() + File.separator + getAikenCommand()); + cmd.add("build"); + + OSProcessHandler handler; + try { + handler = new OSProcessHandler( + new GeneralCommandLine(cmd).withWorkDirectory(cwd) + ); + + } catch (ExecutionException ex) { + failed(listener, sourceFilePath, "Compilation failed : " + ex.getMessage(), ex); + return; + } + + listener.info("Compiling Aiken file ..."); + listener.attachProcess(handler); + + handler.addProcessListener(new ProcessListener() { + @Override + public void startNotified(@NotNull ProcessEvent event) { + + } + + @Override + public void processTerminated(@NotNull ProcessEvent event) { + if(event.getExitCode() == 0) { + listener.info("Compilation successful."); + listener.onSuccessful(sourceFilePath); + } else { + failed(listener, sourceFilePath, "Compilation failed.", new CompileException("Aiken compilation process failed with error.")); + } + } + + @Override + public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { + + } + }); + } + + public void format(String sourceFilePath, CompilationResultListener listener) { + List cmd = new ArrayList<>(); + cmd.add(localSDK.getPath() + File.separator + getAikenCommand()); + cmd.add("fmt"); + cmd.add(sourceFilePath); + + OSProcessHandler handler; + try { + handler = new OSProcessHandler( + new GeneralCommandLine(cmd).withWorkDirectory(cwd) + ); + + } catch (ExecutionException ex) { + failed(listener, sourceFilePath, "Formatting failed : " + ex.getMessage(), ex); + return; + } + + listener.info("Formatting Aiken file ..."); + listener.attachProcess(handler); + + handler.addProcessListener(new ProcessListener() { + @Override + public void startNotified(@NotNull ProcessEvent event) { + + } + + @Override + public void processTerminated(@NotNull ProcessEvent event) { + if(event.getExitCode() == 0) { + listener.info("Formatting successful."); + listener.onSuccessful(sourceFilePath); + } else { + failed(listener, sourceFilePath, "Formatting failed.", new CompileException("Aiken formatting failed with error.")); + } + } + + @Override + public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { + + } + }); + } + + private String getAikenCommand() { + String aikenCmd = "aiken"; + if(SystemInfo.isWindows) + aikenCmd = "aiken.exe"; + + return aikenCmd; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/BaseCompileService.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/BaseCompileService.java new file mode 100644 index 0000000..5e414f1 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/BaseCompileService.java @@ -0,0 +1,12 @@ +package com.bloxbean.intelliada.idea.aiken.compile; + +import com.intellij.openapi.diagnostic.Logger; + +public abstract class BaseCompileService implements CompileService{ + private final static Logger LOG = Logger.getInstance(BaseCompileService.class); + + protected void failed(CompilationResultListener resultListener, String source, String message, Throwable t) { + resultListener.error(message); + resultListener.onFailure(source, t); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompilationResultListener.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompilationResultListener.java new file mode 100644 index 0000000..c9fd72d --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompilationResultListener.java @@ -0,0 +1,24 @@ +package com.bloxbean.intelliada.idea.aiken.compile; + +import com.intellij.execution.process.OSProcessHandler; + +public interface CompilationResultListener { + default public void attachProcess(OSProcessHandler processHandler) { + + } + + public void error(String message); + public void info(String message); + public void warn(String msg); + + @Deprecated + public void onSuccessful(String sourceFile); + public void onFailure(String sourceFile, Throwable t); + + default public void error(String message, Throwable t) { + error(message + " : " + t.getMessage()); + } + + default public void onSuccessfulCompile(String sourceFile, String outputFile, String contractHash) {} + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompileException.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompileException.java new file mode 100644 index 0000000..19aa64a --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompileException.java @@ -0,0 +1,7 @@ +package com.bloxbean.intelliada.idea.aiken.compile; + +public class CompileException extends Throwable { + public CompileException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompileService.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompileService.java new file mode 100644 index 0000000..d2b29be --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/CompileService.java @@ -0,0 +1,5 @@ +package com.bloxbean.intelliada.idea.aiken.compile; + +public interface CompileService { + void compile(String source, CompilationResultListener compilationResultListener); +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/SDKNotConfigured.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/SDKNotConfigured.java new file mode 100644 index 0000000..7e51747 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/SDKNotConfigured.java @@ -0,0 +1,7 @@ +package com.bloxbean.intelliada.idea.aiken.compile; + +public class SDKNotConfigured extends Throwable { + public SDKNotConfigured(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/action/AikenBuildAction.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/action/AikenBuildAction.java new file mode 100644 index 0000000..3587a16 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/action/AikenBuildAction.java @@ -0,0 +1,166 @@ + +package com.bloxbean.intelliada.idea.aiken.compile.action; + +import com.bloxbean.intelliada.idea.aiken.compile.AikenCompileService; +import com.bloxbean.intelliada.idea.aiken.compile.CompilationResultListener; +import com.bloxbean.intelliada.idea.aiken.compile.CompileService; +import com.bloxbean.intelliada.idea.aiken.compile.SDKNotConfigured; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationAction; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationHelperService; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.bloxbean.intelliada.idea.aiken.lang.psi.AikenFile; +import com.bloxbean.intelliada.idea.toolwindow.CardanoConsole; +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.icons.AllIcons; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; + +public class AikenBuildAction extends AnAction { + private final static Logger LOG = Logger.getInstance(AikenBuildAction.class); + + public AikenBuildAction() { + super(AllIcons.Actions.Compile); + } + + @Override + public void update(@NotNull AnActionEvent e) { + super.update(e); + + PsiFile file = e.getDataContext().getData(CommonDataKeys.PSI_FILE); + + if (file != null && file instanceof AikenFile) { + e.getPresentation().setEnabled(true); + } else { + e.getPresentation().setVisible(false); + e.getPresentation().setEnabled(false); + } + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + if (LOG.isDebugEnabled()) + LOG.debug("Build Aiken File"); + + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + if (project == null) + return; + + final Module module = LangDataKeys.MODULE.getData(e.getDataContext()); + if (module == null) + return; + + FileDocumentManager.getInstance().saveAllDocuments(); + + final CardanoConsole console = CardanoConsole.getConsole(project); + console.clearAndshow(); + + //TODO -- If sdk not set, check in default location + AikenSDK localSDK = AikenConfigurationHelperService.getCompilerLocalSDK(project); + + if (localSDK == null) { + IdeaUtil.showNotification(project, "Compilation configuration", + "Aikon SDK is not done for this module.", NotificationType.ERROR, AikenConfigurationAction.ACTION_ID); + return; + } + PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); + if (!(psiFile instanceof AikenFile)) { + Messages.showErrorDialog("Not a Aiken fille", "Aiken Compilation"); + return; + } + + String moduleDir = ModuleUtil.getModuleDirPath(module); + final VirtualFile folderToRefresh = VfsUtil.findFileByIoFile(new File(moduleDir), true); + + CompilationResultListener compilationResultListener = new CompilationResultListener() { + @Override + public void attachProcess(OSProcessHandler handler) { + ApplicationManager.getApplication().invokeLater(() -> { + try { + console.getView().attachToProcess(handler); + } catch (IncorrectOperationException ex) { + //This should not happen + //ex.printStackTrace(); + console.showInfoMessage(ex.getMessage()); + console.dispose(); + console.getView().attachToProcess(handler); + } + handler.startNotify(); + }); + } + + @Override + public void error(String message) { + console.showErrorMessage(message); + } + + @Override + public void info(String message) { + console.showInfoMessage(message); + } + + @Override + public void warn(String msg) { + console.showWarningMessage(msg); + } + + @Override + public void onSuccessful(String sourceFile) { + console.showSuccessMessage("Build Successful"); + if (folderToRefresh != null) { + folderToRefresh.refresh(false, false); + } + + IdeaUtil.showNotification(project, "Aiken Compile", "Compilation was successful", NotificationType.INFORMATION, null); + } + + @Override + public void onFailure(String sourceFile, Throwable t) { + console.showErrorMessage(String.format("Compilation failed for %s", sourceFile), t); + IdeaUtil.showNotification(project, "Aiken Compile", "Compilation failed", NotificationType.ERROR, null); + } + }; + + Task.Backgroundable task = new Task.Backgroundable(project, "Aiken Compile") { + + @Override + public void run(@NotNull ProgressIndicator indicator) { + CompileService compileService = null; + if (localSDK != null) { + try { + compileService = new AikenCompileService(project); + } catch (SDKNotConfigured sdkNotConfigured) { + Messages.showErrorDialog("Aiken SDK is not set for this module.", "Aiken Compilation"); + return; + } + } + + console.showInfoMessage("Start compilation .."); + compileService.compile(moduleDir, compilationResultListener); + } + }; + + ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, new BackgroundableProcessIndicator(task)); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/action/AikenFormatAction.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/action/AikenFormatAction.java new file mode 100644 index 0000000..0e53464 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/compile/action/AikenFormatAction.java @@ -0,0 +1,162 @@ + +package com.bloxbean.intelliada.idea.aiken.compile.action; + +import com.bloxbean.intelliada.idea.aiken.compile.AikenCompileService; +import com.bloxbean.intelliada.idea.aiken.compile.CompilationResultListener; +import com.bloxbean.intelliada.idea.aiken.compile.SDKNotConfigured; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationAction; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationHelperService; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.bloxbean.intelliada.idea.aiken.lang.psi.AikenFile; +import com.bloxbean.intelliada.idea.toolwindow.CardanoConsole; +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.icons.AllIcons; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class AikenFormatAction extends AnAction { + private final static Logger LOG = Logger.getInstance(AikenFormatAction.class); + + public AikenFormatAction() { + super(AllIcons.Actions.ReformatCode); + } + + @Override + public void update(@NotNull AnActionEvent e) { + super.update(e); + + PsiFile file = e.getDataContext().getData(CommonDataKeys.PSI_FILE); + + if (file != null && file instanceof AikenFile) { + e.getPresentation().setEnabled(true); + } else { + e.getPresentation().setVisible(false); + e.getPresentation().setEnabled(false); + } + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + if (LOG.isDebugEnabled()) + LOG.debug("Format Aiken File"); + + Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); + if (project == null) + return; + + final Module module = LangDataKeys.MODULE.getData(e.getDataContext()); + if (module == null) + return; + + FileDocumentManager.getInstance().saveAllDocuments(); + + final CardanoConsole console = CardanoConsole.getConsole(project); + console.clearAndshow(); + + //TODO -- If sdk not set, check in default location + AikenSDK localSDK = AikenConfigurationHelperService.getCompilerLocalSDK(project); + + if (localSDK == null) { + IdeaUtil.showNotification(project, "Format configuration", + "Aikon SDK is not set for this module.", NotificationType.ERROR, AikenConfigurationAction.ACTION_ID); + return; + } + PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE); + if (!(psiFile instanceof AikenFile)) { + Messages.showErrorDialog("Not a Aiken fille", "Aiken Formatting"); + return; + } + + VirtualFile fileToRefresh = psiFile.getVirtualFile(); + + CompilationResultListener compilationResultListener = new CompilationResultListener() { + @Override + public void attachProcess(OSProcessHandler handler) { + ApplicationManager.getApplication().invokeLater(() -> { + try { + console.getView().attachToProcess(handler); + } catch (IncorrectOperationException ex) { + //This should not happen + console.showInfoMessage(ex.getMessage()); + console.dispose(); + console.getView().attachToProcess(handler); + } + handler.startNotify(); + }); + } + + @Override + public void error(String message) { + console.showErrorMessage(message); + } + + @Override + public void info(String message) { + console.showInfoMessage(message); + } + + @Override + public void warn(String msg) { + console.showWarningMessage(msg); + } + + @Override + public void onSuccessful(String sourceFile) { + ApplicationManager.getApplication().invokeLater(() -> { + if (fileToRefresh != null) { + fileToRefresh.refresh(false, false); + System.out.println(fileToRefresh.getCanonicalPath()); + Optional.ofNullable(FileDocumentManager.getInstance().getDocument(fileToRefresh)) + .ifPresent(document -> FileDocumentManager.getInstance().reloadFromDisk(document)); + } + }); + } + + @Override + public void onFailure(String sourceFile, Throwable t) { + console.showErrorMessage(String.format("Formatting failed for %s", sourceFile), t); + IdeaUtil.showNotification(project, "Aiken Formatting", "Formatting failed", NotificationType.ERROR, null); + } + }; + + Task.Backgroundable task = new Task.Backgroundable(project, "Aiken Formatting") { + + @Override + public void run(@NotNull ProgressIndicator indicator) { + AikenCompileService compileService = null; + if (localSDK != null) { + try { + compileService = new AikenCompileService(project); + } catch (SDKNotConfigured sdkNotConfigured) { + Messages.showErrorDialog("Aiken SDK is not set for this module.", "Aiken Formatting"); + return; + } + } + + compileService.format(fileToRefresh.getCanonicalPath(), compilationResultListener); + } + }; + + ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, new BackgroundableProcessIndicator(task)); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenConfigurationAction.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenConfigurationAction.java new file mode 100644 index 0000000..75f3093 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenConfigurationAction.java @@ -0,0 +1,43 @@ +package com.bloxbean.intelliada.idea.aiken.configuration; + +import com.bloxbean.intelliada.idea.aiken.configuration.service.AikenProjectState; +import com.bloxbean.intelliada.idea.aiken.configuration.ui.AikenProjectConfigurationDialog; +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.icons.AllIcons; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +public class AikenConfigurationAction extends AnAction { + public static final String ACTION_ID = AikenConfigurationAction.class.getName(); + + public AikenConfigurationAction() { + super(AllIcons.Ide.Notification.Gear); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + Project project = e.getProject(); + if(project == null) + return; + + AikenProjectState aikenProjectState = AikenProjectState.getInstance(project); + if(aikenProjectState == null) { + IdeaUtil.showNotification(project, "Aiken project configuration", + "Unable to configure Aiken project", NotificationType.ERROR, null); + return; + } + + AikenProjectConfigurationDialog dialog = new AikenProjectConfigurationDialog(project); + + boolean ok = dialog.showAndGet(); + if(ok) { + dialog.save(project); + } else { + + } + + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenConfigurationHelperService.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenConfigurationHelperService.java new file mode 100644 index 0000000..852322f --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenConfigurationHelperService.java @@ -0,0 +1,94 @@ +package com.bloxbean.intelliada.idea.aiken.configuration; + +import com.bloxbean.intelliada.idea.aiken.configuration.service.AikenProjectState; +import com.bloxbean.intelliada.idea.aiken.configuration.service.AikenSDKState; +import com.bloxbean.intelliada.idea.aiken.configuration.ui.AikenSDKDialog; +import com.bloxbean.intelliada.idea.aiken.messaging.AikenProjectNodeConfigChangeNotifier; +import com.bloxbean.intelliada.idea.aiken.messaging.AikenSDKChangeNotifier; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; + +import java.io.File; +import java.nio.file.Path; +import java.util.List; +import java.util.UUID; + +public class AikenConfigurationHelperService { + + public static AikenSDK getCompilerLocalSDK(Project project) { + AikenProjectState projectState = AikenProjectState.getInstance(project); + AikenProjectState.ConfigType compilerType = projectState.getState().getSdkType(); + String compilerId = projectState.getState().getSdkId(); + + if(AikenProjectState.ConfigType.local_sdk == compilerType + &&!StringUtil.isEmpty(compilerId)) { + List sdks = AikenSDKState.getInstance().getSdks(); + for(AikenSDK sdk: sdks) { + if(compilerId.equals(sdk.getId())) { + return sdk; + } + } + } + + //Check if aiken exec is there in .aiken folder + String aikenPath = System.getProperty("user.home") + File.separator + ".aiken" + File.separator + "bin"; + if (Path.of(aikenPath, getAikenCommand()).toFile().exists()) { + return new AikenSDK("some id", "some aiken name", aikenPath, "0.0"); + } + + return null; + } + + + public static AikenSDK createOrUpdateLocalSDKConfiguration(Project project, AikenSDK existingLocalSdk) { + AikenSDKState stateService = AikenSDKState.getInstance(); + AikenSDKDialog localSDKDialog = new AikenSDKDialog(project, existingLocalSdk); + boolean ok = localSDKDialog.showAndGet(); + if (ok) { + //save and return + AikenSDK sdk = new AikenSDK(); + + if (existingLocalSdk == null) { + sdk.setId(UUID.randomUUID().toString()); + } else { + sdk.setId(existingLocalSdk.getId()); + } + + sdk.setPath(localSDKDialog.getPath()); + sdk.setName(localSDKDialog.getName()); + sdk.setVersion(localSDKDialog.getVersion()); + + if (existingLocalSdk == null) { + stateService.addLocalSdk(sdk); + + AikenSDKChangeNotifier sdkChangeNotifier = ApplicationManager.getApplication().getMessageBus().syncPublisher(AikenSDKChangeNotifier.CHANGE_AIKEN_SDK_TOPIC); + sdkChangeNotifier.sdkAdded(sdk); + } else { + stateService.updateLocalSdk(sdk); + + AikenSDKChangeNotifier sdkChangeNotifier = ApplicationManager.getApplication().getMessageBus().syncPublisher(AikenSDKChangeNotifier.CHANGE_AIKEN_SDK_TOPIC); + sdkChangeNotifier.sdkUpdated(sdk); + } + + return sdk; + } else { + return null; + } + } + + public static void notifyProjectNodeConfigChange(Project project) { + AikenProjectNodeConfigChangeNotifier aikenProjectNodeConfigChangeNotifier + = ApplicationManager.getApplication().getMessageBus().syncPublisher(AikenProjectNodeConfigChangeNotifier.CHANGE_AIKEN_PROJECT_NODES_CONFIG_TOPIC); + aikenProjectNodeConfigChangeNotifier.configUpdated(project); + } + + private static String getAikenCommand() { + String aikenCmd = "aiken"; + if(SystemInfo.isWindows) + aikenCmd = "aiken.exe"; + + return aikenCmd; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenSDK.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenSDK.java new file mode 100644 index 0000000..69c6480 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/AikenSDK.java @@ -0,0 +1,66 @@ +package com.bloxbean.intelliada.idea.aiken.configuration; + +import com.intellij.openapi.util.SystemInfo; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Data +@AllArgsConstructor +public class AikenSDK { + private String id; + private String name; + private String path; + private String version; + + public AikenSDK() { + id = ""; + name = ""; + path = ""; + version = ""; + } + + public void updateValues(AikenSDK aikenSDK) { //Update everything except id + if(aikenSDK == null) return; + + this.setName(aikenSDK.getName()); + this.setPath(aikenSDK.getPath()); + this.setVersion(aikenSDK.getVersion()); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AikenSDK sdk = (AikenSDK) o; + return id.equals(sdk.id); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + public String toString() { + return name; + } + + public List getAikenCommand() { + List cmd = new ArrayList<>(); + cmd.add(getPath() + File.separator + getAikenExecutable()); + + return cmd; + } + + private String getAikenExecutable() { + String aikenCmd = "aiken"; + if(SystemInfo.isWindows) + aikenCmd = "aiken.exe"; + + return aikenCmd; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/CreateNewAikenSDKAction.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/CreateNewAikenSDKAction.java new file mode 100644 index 0000000..a60e183 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/CreateNewAikenSDKAction.java @@ -0,0 +1,23 @@ +package com.bloxbean.intelliada.idea.aiken.configuration; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +public class CreateNewAikenSDKAction extends AnAction { + public final static String ACTION_ID = CreateNewAikenSDKAction.class.getName(); + + public CreateNewAikenSDKAction() { + super("Add Aiken SDK", "Add a new Aiken SDK", AllIcons.General.AddJdk); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + Project project = e.getProject(); + + AikenConfigurationHelperService.createOrUpdateLocalSDKConfiguration(project, null); + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/service/AikenProjectState.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/service/AikenProjectState.java new file mode 100644 index 0000000..f33a9cd --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/service/AikenProjectState.java @@ -0,0 +1,60 @@ +package com.bloxbean.intelliada.idea.aiken.configuration.service; + +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; + +@State( + name = "com.bloxbean.aiken.AikenProjectState", + reloadable = true, + storages = {@Storage("aiken-project.xml")} +) +public class AikenProjectState implements PersistentStateComponent { + private static final Logger LOG = Logger.getInstance(AikenProjectState.class); + + public enum ConfigType { local_sdk, embedded_sdk} + + public static AikenProjectState getInstance(Project project) { + return ServiceManager.getService(project, AikenProjectState.class); + } + + public static class State { + private ConfigType sdkType; + private String sdkId; + + + public ConfigType getSdkType() { + return sdkType; + } + + public void setSdkType(ConfigType sdkType) { + this.sdkType = sdkType; + } + + public String getSdkId() { + return sdkId; + } + + public void setSdkId(String sdkId) { + this.sdkId = sdkId; + } + + } + + private State state = new State(); + + public State getState() { + return state; + } + + public void loadState(State state) { + this.state = state; + } + + public void setState(State state) { + this.state = state; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/service/AikenSDKState.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/service/AikenSDKState.java new file mode 100644 index 0000000..7c45ed5 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/service/AikenSDKState.java @@ -0,0 +1,95 @@ +package com.bloxbean.intelliada.idea.aiken.configuration.service; + +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +@State( + name = "com.bloxbean.aiken.AikenDKState", + storages = {@Storage("aiken-sdks.xml")} +) +public class AikenSDKState implements PersistentStateComponent { + private static final Logger LOG = Logger.getInstance(AikenSDKState.class); + + public static AikenSDKState getInstance() { + return ServiceManager.getService(AikenSDKState.class); + } + + private List sdks; + + public AikenSDKState() { + this.sdks = new ArrayList<>(); + } + + @Nullable + @Override + public Element getState() { + Element state = new Element("sdks"); + + for(AikenSDK sdk: sdks) { + Element entry = new Element("sdk"); + entry.setAttribute("id", sdk.getId()); + entry.setAttribute("name", sdk.getName()); + entry.setAttribute("path", StringUtil.notNullize(sdk.getPath())); + entry.setAttribute("version", StringUtil.notNullize(sdk.getVersion())); + + state.addContent(entry); + } + + return state; + } + + @Override + public void loadState(@NotNull Element elm) { + List list = new ArrayList<>(); + + for (Element child : elm.getChildren("localSdk")) { + String id = child.getAttributeValue("id"); + String name = child.getAttributeValue("name"); + String path = child.getAttributeValue("path"); + String version = child.getAttributeValue("version"); + + AikenSDK sdk = new AikenSDK(id, name, path,version); + + list.add(sdk); + } + + setSdks(list); + } + + public List getSdks() { + return sdks; + } + + public void addLocalSdk(AikenSDK sdk) { + sdks.add(sdk); + } + + public void updateLocalSdk(AikenSDK sdk) { + for(AikenSDK lsdk: sdks) { + if(lsdk.getId() != null && lsdk.getId().equals(sdk.getId())) { + lsdk.updateValues(sdk); + break; + } + } + } + + private void setSdks(List list) { + sdks = list; + } + + public void removeSdk(AikenSDK sdk) { + if(sdks == null || sdk == null) return; + sdks.remove(sdk); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfig.form b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfig.form new file mode 100644 index 0000000..5875ce3 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfig.form @@ -0,0 +1,78 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfig.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfig.java new file mode 100644 index 0000000..93db77a --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfig.java @@ -0,0 +1,160 @@ +package com.bloxbean.intelliada.idea.aiken.configuration.ui; + +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationHelperService; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.bloxbean.intelliada.idea.aiken.configuration.service.AikenProjectState; +import com.bloxbean.intelliada.idea.aiken.configuration.service.AikenSDKState; +import com.bloxbean.intelliada.idea.common.Tuple; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.ValidationInfo; +import com.intellij.openapi.util.text.StringUtil; + +import javax.swing.*; +import java.util.List; + +public class AikenProjectConfig { + private JPanel mainPanel; + private JComboBox localSDKCB; + private JButton newLocalSDKBtn; + private JButton localSDKDetailBtn; + + private AikenSDK emptyLocalSDK = new AikenSDK(); + private boolean configChanged; + + public AikenProjectConfig(Project project) { + initializeData(project); + attachHandlers(project); + setCurrentSelection(project); + + //Don't change this call sequence. This is needed for change notifier + //Keep it at the end to ignore initial selection + listenSelectionChange(); + } + + private void initializeData(Project project) { + populateAvailableLocalSDKs(); + } + + private void setCurrentSelection(Project project) { + AikenProjectState aikenProjectState = AikenProjectState.getInstance(project); + AikenProjectState.State state = aikenProjectState.getState(); + + //set compiler setting + if(AikenProjectState.ConfigType.local_sdk == state.getSdkType()){ + setSelectedLocalSDK(localSDKCB, state.getSdkId()); + } + } + + private void setSelectedLocalSDK(JComboBox cb, String id) { + for (int i = 0; i < cb.getItemCount(); i++) { + AikenSDK aikenSDK = (AikenSDK) cb.getItemAt(i); + if (aikenSDK == null) continue; + + if (aikenSDK.getId() != null && aikenSDK.getId().equals(id)) { + cb.setSelectedIndex(i); + break; + } + } + } + + private void populateAvailableLocalSDKs() { + AikenSDKState localSDKState = ServiceManager.getService(AikenSDKState.class); + List localSdks = localSDKState.getSdks(); + + localSDKCB.removeAllItems(); + if (localSdks != null) { + localSDKCB.addItem(emptyLocalSDK); + for (AikenSDK localSDK : localSdks) { + localSDKCB.addItem(localSDK); + } + } + } + + + private void attachHandlers(Project project) { + + newLocalSDKBtn.addActionListener(e -> { + AikenSDK localSDK = AikenConfigurationHelperService.createOrUpdateLocalSDKConfiguration(project, null); + if (localSDK != null) { + populateAvailableLocalSDKs(); + setSelectedLocalSDK(localSDKCB, localSDK.getId()); + } + }); + + localSDKDetailBtn.addActionListener(e -> { //Update if required. + AikenSDK localSDK = (AikenSDK) localSDKCB.getSelectedItem(); + if (localSDK == null || StringUtil.isEmpty(localSDK.getId())) { + Messages.showWarningDialog("Please select a Aiken SDK first to see the details", ""); + return; + } + + AikenSDK updatedSDK = AikenConfigurationHelperService.createOrUpdateLocalSDKConfiguration(project, localSDK); + if (updatedSDK != null) { + updateLocalSDKInComboBox(localSDKCB, updatedSDK); + } + }); + } + + //This is required for change notifier + private void listenSelectionChange() { + localSDKCB.addActionListener(e -> { + configChanged = true; + }); + } + + public boolean isConfigChanged() { + return configChanged; + } + + + private void updateLocalSDKInComboBox(JComboBox cb, AikenSDK updatedLocalSDK) { + int count = cb.getItemCount(); + if (count == 0) return; + + for (int i = 0; i < count; i++) { + AikenSDK lsdk = (AikenSDK) cb.getItemAt(i); + if (lsdk == null || StringUtil.isEmpty(lsdk.getId())) + continue; + if (lsdk.getId().equals(updatedLocalSDK.getId())) { + lsdk.updateValues(updatedLocalSDK); + break; + } + } + + } + + public Tuple getAikenSdkId() { + + AikenSDK aikenSDK = (AikenSDK) localSDKCB.getSelectedItem(); + if (aikenSDK != null) + return new Tuple(AikenProjectState.ConfigType.local_sdk, aikenSDK.getId()); + else + return null; + + } + + + public void updateDataToState(AikenProjectState.State state) { + //Save Compile / Build settings + Tuple compilerSetting = getAikenSdkId(); + + if (compilerSetting != null) { + state.setSdkType(compilerSetting._1()); + state.setSdkId(compilerSetting._2()); + } + } + + public JPanel getMainPanel() { + return mainPanel; + } + + private void createUIComponents() { + // TODO: place custom component creation code here + } + + public ValidationInfo doValidate() { + return null; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfigurationDialog.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfigurationDialog.java new file mode 100644 index 0000000..a8d1329 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenProjectConfigurationDialog.java @@ -0,0 +1,63 @@ +package com.bloxbean.intelliada.idea.aiken.configuration.ui; + +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationHelperService; +import com.bloxbean.intelliada.idea.aiken.configuration.service.AikenProjectState; +import com.bloxbean.intelliada.idea.common.Tuple; +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.ValidationInfo; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class AikenProjectConfigurationDialog extends DialogWrapper { + + private AikenProjectConfig aikenPrjConfig; + + public AikenProjectConfigurationDialog(@Nullable Project project) { + super(project); + aikenPrjConfig = new AikenProjectConfig(project); + init(); + setTitle("Aiken Project - Configuration"); + } + + public Tuple getCompilerSdkId() { + return aikenPrjConfig.getAikenSdkId(); + } + + public void save(Project project) { + AikenProjectState projectState = AikenProjectState.getInstance(project); + if (projectState == null) { + IdeaUtil.showNotification(project, "Aiken configuration", + "Unable to save Aiken configuration for the project", NotificationType.ERROR, null); + return; + } + + AikenProjectState.State state = projectState.getState(); + if (state != null) { + aikenPrjConfig.updateDataToState(state); + projectState.setState(state); + + if(aikenPrjConfig.isConfigChanged()) { + AikenConfigurationHelperService.notifyProjectNodeConfigChange(project); + } + } else { + IdeaUtil.showNotification(project, "Aiken project configuration", + "Unable to save Aiken configuration for the project !!!", NotificationType.ERROR, null); + } + + } + + @Override + protected @Nullable ValidationInfo doValidate() { + return aikenPrjConfig.doValidate(); + } + + @Override + protected @Nullable JComponent createCenterPanel() { + return aikenPrjConfig.getMainPanel(); + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKDialog.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKDialog.java new file mode 100644 index 0000000..9d42322 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKDialog.java @@ -0,0 +1,60 @@ +package com.bloxbean.intelliada.idea.aiken.configuration.ui; + +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.ValidationInfo; +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class AikenSDKDialog extends DialogWrapper { + + private AikenSDKPanel localSDKPanel; + + public AikenSDKDialog(Project project) { + this(project, null); + } + + public AikenSDKDialog(Project project, AikenSDK sdk) { + super(project); + localSDKPanel = new AikenSDKPanel(sdk); + init(); + setTitle("Aiken SDK"); + } + + @Override + protected @Nullable JComponent createCenterPanel() { + return localSDKPanel.getMainPanel(); + } + + public String getPath() { + return localSDKPanel.getPath(); + } + + public String getName() { + return localSDKPanel.getName(); + } + + public String getVersion() { + return localSDKPanel.getVersion(); + } + + @Override + protected @Nullable ValidationInfo doValidate() { + if(StringUtil.isEmpty(localSDKPanel.getName())) { + return new ValidationInfo("Invalid Name", localSDKPanel.getNameTf()); + } + + if(StringUtil.isEmpty(localSDKPanel.getPath())) { + return new ValidationInfo("Invalid Aiken Path", localSDKPanel.getPathTf()); + } + + if(StringUtil.isEmpty(localSDKPanel.getVersion())) { + return new ValidationInfo("Invalid Version Number or Version could not be determined", localSDKPanel.getVersionTf()); + } + + return null; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKPanel.form b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKPanel.form new file mode 100644 index 0000000..98a49da --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKPanel.form @@ -0,0 +1,109 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKPanel.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKPanel.java new file mode 100644 index 0000000..cf79754 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/configuration/ui/AikenSDKPanel.java @@ -0,0 +1,137 @@ +package com.bloxbean.intelliada.idea.aiken.configuration.ui; + +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.bloxbean.intelliada.idea.aiken.util.AikenSdkUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.text.StringUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.io.File; + +public class AikenSDKPanel { + private final static Logger LOG = Logger.getInstance(AikenSDKPanel.class); + + private JTextField versionTf; + private JPanel mainPanel; + private JTextField nameTf; + private TextFieldWithBrowseButton pathTfWithBrowserBtn; + private JLabel errorMsgLabel; + private JTextField pathTf; + + public AikenSDKPanel() { + this(null); + } + + public AikenSDKPanel(AikenSDK sdk) { + super(); + + if(sdk != null) { + nameTf.setText(sdk.getName()); + pathTf.setText(sdk.getPath()); + versionTf.setText(sdk.getVersion()); + } + + pathTf.setToolTipText("Folder where the \'aiken\' binary is available."); + + pathTf.addFocusListener(new FocusAdapter() { + @Override + public void focusLost(FocusEvent e) { + checkGoalExecutable(); + } + }); + } + + public JPanel getMainPanel() { + return mainPanel; + } + + public String getPath() { + return pathTf.getText(); + } + + public String getName() { + return nameTf.getText(); + } + + public String getVersion() { + return versionTf.getText(); + } + + private void createUIComponents() { + // TODO: place custom component creation code here + pathTf = new JTextField(); + pathTfWithBrowserBtn = new TextFieldWithBrowseButton(pathTf, e -> { + JFileChooser fc = new JFileChooser(); + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + fc.showDialog(mainPanel, "Select"); + File file = fc.getSelectedFile(); + if (file == null) { + return; + } + + pathTf.setText(file.getAbsolutePath()); + + checkGoalExecutable(); + }); + } + + private void checkGoalExecutable() { + errorMsgLabel.setText(""); //reset error msg + versionTf.setText(""); + + if(!new File(pathTf.getText() + File.separator + getAikenCommand()).exists()) { + versionTf.setText(""); + printError("\'aiken\' was not found. Please make sure \'aiken\' file is available under the selected folder."); + return; + } + + String version = null; + try { + version = AikenSdkUtil.getVersionString(pathTf.getText()); + } catch (Exception exception) { + versionTf.setText(""); + printError(exception.getMessage()); + return; + } + if(StringUtil.isEmpty(version)) { + versionTf.setText(""); + //Invalid version + printError("Invalid Aiken Binary folder. Version could not be determined. " + + "
Make sure \'aiken\' is available under the selected folder"); + return; + } else { + versionTf.setText(version); + } + } + + private void printError(String msg) { + errorMsgLabel.setText(msg); + errorMsgLabel.setForeground(Color.red); + } + + private String getAikenCommand() { + String goalCmd = "aiken"; + if(SystemInfo.isWindows) + goalCmd = "aiken.exe"; + + return goalCmd; + } + + public JTextField getVersionTf() { + return versionTf; + } + + public JTextField getNameTf() { + return nameTf; + } + + public JTextField getPathTf() { + return pathTf; + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/filetypes/AikenTomlFileType.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/filetypes/AikenTomlFileType.java new file mode 100644 index 0000000..3e0ff30 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/filetypes/AikenTomlFileType.java @@ -0,0 +1,52 @@ +package com.bloxbean.intelliada.idea.aiken.filetypes; + +import com.bloxbean.intelliada.idea.aiken.common.AikenIcons; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class AikenTomlFileType implements FileType { + public static final AikenTomlFileType INSTANCE = new AikenTomlFileType(); + + @NotNull + @Override + public String getName() { + return "Aiken Project File"; + } + + @NotNull + @Override + public String getDescription() { + return "Aiken Project File"; + } + + @NotNull + @Override + public String getDefaultExtension() { + return "toml"; + } + + @Nullable + @Override + public Icon getIcon() { + return AikenIcons.FILE; + } + + @Override + public boolean isBinary() { + return false; + } + + @Override + public boolean isReadOnly() { + return true; + } + + @Override + public @Nullable String getCharset(@NotNull VirtualFile file, @NotNull byte[] content) { + return null; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/highlight/AikenHighlighter.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/highlight/AikenHighlighter.java new file mode 100644 index 0000000..48a14e2 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/highlight/AikenHighlighter.java @@ -0,0 +1,77 @@ +package com.bloxbean.intelliada.idea.aiken.highlight; + +import com.bloxbean.intelliada.idea.aiken.lang.AikenLexerAdapter; +import com.bloxbean.intelliada.idea.aiken.color.AikenColors; +import com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +public class AikenHighlighter extends SyntaxHighlighterBase { + private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0]; + + private static final TokenSet KEYWORDS = TokenSet.create( + AikenTypes.IF, + AikenTypes.ELSE, + AikenTypes.WHEN, + AikenTypes.IS, + AikenTypes.FN, + AikenTypes.USE, + AikenTypes.LET, + AikenTypes.PUB, + AikenTypes.TYPE, + AikenTypes.OPAQUE, + AikenTypes.CONST, + AikenTypes.TODO, + AikenTypes.EXPECT, + AikenTypes.CHECK, + AikenTypes.TEST, + AikenTypes.TRACE, + AikenTypes.FAIL, + AikenTypes.VALIDATOR, + AikenTypes.AND, + AikenTypes.OR, + AikenTypes.AS, + AikenTypes.VIA, + AikenTypes.EXTERNAL, + AikenTypes.SPEND, + AikenTypes.MINT, + AikenTypes.WITHDRAW, + AikenTypes.PUBLISH, + AikenTypes.VOTE, + AikenTypes.PROPOSE + ); + + private static final Map keys = new HashMap<>(); + + static { +// fillMap(keys, OPERATIONS, TEALSyntaxColors.FUNCTION); + fillMap(keys, KEYWORDS, AikenColors.KEYWORD); + keys.put(AikenTypes.COMMENT, AikenColors.COMMENT); + keys.put(AikenTypes.DOC_COMMENT, AikenColors.DOC_COMMENT); + keys.put(AikenTypes.MODULE_COMMENT, AikenColors.MODULE_COMMENT); + keys.put(AikenTypes.STRING_CONTENT, AikenColors.STRING); + keys.put(AikenTypes.UPPER_IDENTIFIER, AikenColors.IDENTIFIER); + keys.put(AikenTypes.TYPE_IDENTIFIER, AikenColors.KEYWORD); + keys.put(AikenTypes.TYPE_NAME, AikenColors.TYPE_NAME); + keys.put(AikenTypes.CONSTRUCTOR_NAME, AikenColors.KEYWORD); + } + + @Override + public @NotNull Lexer getHighlightingLexer() { + return new AikenLexerAdapter(); + } + + @NotNull + @Override + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + TextAttributesKey tak = keys.get(tokenType); + return tak != null ? pack(keys.get(tokenType)) : EMPTY_KEYS; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/highlight/ParseErrorHighlightFilter.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/highlight/ParseErrorHighlightFilter.java new file mode 100644 index 0000000..b09f9c9 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/highlight/ParseErrorHighlightFilter.java @@ -0,0 +1,19 @@ +package com.bloxbean.intelliada.idea.aiken.highlight; + +import com.bloxbean.intelliada.idea.aiken.lang.AikenLanguage; +import com.intellij.codeInsight.highlighting.HighlightErrorFilter; +import com.intellij.lang.Language; +import com.intellij.psi.PsiErrorElement; +import org.jetbrains.annotations.NotNull; + +public class ParseErrorHighlightFilter extends HighlightErrorFilter { + + @Override + public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) { + Language language = element.getLanguage(); + if (language != AikenLanguage.INSTANCE) + return false; + else + return false; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenBundle.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenBundle.java new file mode 100644 index 0000000..9250d97 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenBundle.java @@ -0,0 +1,17 @@ +package com.bloxbean.intelliada.idea.aiken.lang; + +import com.intellij.DynamicBundle; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.PropertyKey; + +public class AikenBundle extends DynamicBundle { + private final static String BUNDLE = "messages.AikenBundle"; + + public AikenBundle(@NotNull String pathToBundle) { + super(BUNDLE); + } + +// public String message(@PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) { +// getMessage(key, params); +// } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenFileType.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenFileType.java new file mode 100644 index 0000000..57fedd2 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenFileType.java @@ -0,0 +1,42 @@ +package com.bloxbean.intelliada.idea.aiken.lang; + +import com.bloxbean.intelliada.idea.aiken.common.AikenIcons; +import com.intellij.openapi.fileTypes.LanguageFileType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class AikenFileType extends LanguageFileType { + + public static final AikenFileType INSTANCE = new AikenFileType(); + + private AikenFileType() { + super(AikenLanguage.INSTANCE); + } + + @NotNull + @Override + public String getName() { + return "Aiken File"; + } + + @NotNull + @Override + public String getDescription() { + return "Aiken language file"; + } + + @NotNull + @Override + public String getDefaultExtension() { + return "ak"; + } + + @Nullable + @Override + public Icon getIcon() { + return AikenIcons.FILE; + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenLanguage.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenLanguage.java new file mode 100644 index 0000000..b6931a8 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenLanguage.java @@ -0,0 +1,11 @@ +package com.bloxbean.intelliada.idea.aiken.lang; + +import com.intellij.lang.Language; + +public class AikenLanguage extends Language { + public static final AikenLanguage INSTANCE = new AikenLanguage(); + + protected AikenLanguage() { + super("Aiken"); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenLexerAdapter.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenLexerAdapter.java new file mode 100644 index 0000000..dcd5fe3 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenLexerAdapter.java @@ -0,0 +1,10 @@ +package com.bloxbean.intelliada.idea.aiken.lang; + +import com.intellij.lexer.FlexAdapter; + +public class AikenLexerAdapter extends FlexAdapter { + + public AikenLexerAdapter() { + super(new _AikenLexer()); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenParserDefinition.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenParserDefinition.java new file mode 100644 index 0000000..667aa2c --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/AikenParserDefinition.java @@ -0,0 +1,80 @@ +package com.bloxbean.intelliada.idea.aiken.lang; + +import com.bloxbean.intelliada.idea.aiken.lang.parser.AikenParser; +import com.bloxbean.intelliada.idea.aiken.lang.psi.AikenFile; +import com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes; +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.TokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.IFileElementType; +import com.intellij.psi.tree.TokenSet; +import org.jetbrains.annotations.NotNull; + +public class AikenParserDefinition implements ParserDefinition { + + public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE); + + public static final IElementType COMMENT = AikenTypes.COMMENT; + public static final TokenSet COMMENTS = TokenSet.create(COMMENT); + + public static final IFileElementType FILE = new IFileElementType(AikenLanguage.INSTANCE); + + @NotNull + @Override + public Lexer createLexer(Project project) { + return new AikenLexerAdapter(); + } + + @NotNull + @Override + public TokenSet getWhitespaceTokens() { + return WHITE_SPACES; + } + + @NotNull + @Override + public TokenSet getCommentTokens() { + return COMMENTS; + } + + @NotNull + @Override + public TokenSet getStringLiteralElements() { + return TokenSet.EMPTY; + } + + @NotNull + @Override + public PsiParser createParser(final Project project) { + return new AikenParser(); + } + + @Override + public IFileElementType getFileNodeType() { + return FILE; + } + + @Override + public PsiFile createFile(FileViewProvider viewProvider) { + return new AikenFile(viewProvider); + } + + @Override + public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) { + return SpaceRequirements.MAY; + } + + @NotNull + @Override + public PsiElement createElement(ASTNode node) { + return AikenTypes.Factory.createElement(node); + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/Aiken.bnf b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/Aiken.bnf new file mode 100644 index 0000000..ee66619 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/Aiken.bnf @@ -0,0 +1,151 @@ +{ + parserClass="com.bloxbean.intelliada.idea.aiken.lang.parser.AikenParser" + parserUtilClass="com.bloxbean.intelliada.idea.aiken.lang.psi.impl.AikenParserUtil" + + extends="com.intellij.extapi.psi.ASTWrapperPsiElement" + + psiClassPrefix="Aiken" + psiImplClassSuffix="Impl" + psiPackage="com.bloxbean.intelliada.idea.aiken.lang.psi" + psiImplPackage="com.bloxbean.intelliada.idea.aiken.lang.psi.impl" + + elementTypeHolderClass="com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes" + elementTypeClass="com.bloxbean.intelliada.idea.aiken.lang.psi.AikenElementType" + tokenTypeClass="com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTokenType" + + psiImplUtilClass="com.bloxbean.intelliada.idea.aiken.lang.psi.impl.AikenPsiImplUtil" + + +tokens = [ + // Keywords + IF = "if" + ELSE = "else" + WHEN = "when" + IS = "is" + FN = "fn" + USE = "use" + LET = "let" + PUB = "pub" + TYPE = "type" + OPAQUE = "opaque" + CONST = "const" + TODO = "todo" + EXPECT = "expect" + CHECK = "check" + TEST = "test" + TRACE = "trace" + FAIL = "fail" + VALIDATOR = "validator" + AND = "and" + OR = "or" + AS = "as" + VIA = "via" + + MINT = "mint" + SPEND = "spend" + WITHDRAW = "withdraw" + PUBLISH = "publish" + VOTE = "vote" + PROPOSE = "propose" + + //check if required?? + EXTERNAL = "external" + + // Regexp + IDENTIFIER = "regexp:[_a-z][_0-9a-z]*" + UPPER_IDENTIFIER = "regexp:[A-Z][_0-9a-zA-Z]*" + + COMMENT = "regexp://([^\n]*)?" + DOC_COMMENT = "regexp:///([^\n]*)?" + MODULE_COMMENT = "regexp:////([^\n]*)?" + + NUMBER = "regexp:[0-9]*" + STRING_CONTENT = "regexp:\"([^\\\\\\\"]|\\\\[^efnrt\\\"\\\\])+\"" // TODO improve matching for string content + + // Chars + LBRACE = '{' + RBRACE = '}' + LBRACK = '[' + RBRACK = ']' + LPAREN = '(' + RPAREN = ')' + + COLON = ':' + + COMMA = ',' + + EQ = '=' + EQEQ = '==' + + BANG = '!' + + PLUS = '+' + MINUS = '-' + + OR = '||' + AND = '&&' + + LT = '<' + GT = '>' + + MUL = '*' + DIV = '/' + DIVDIV = '//' + + DOT = '.' + DOTDOT = '..' + + FAT_ARROW = '=>' + ARROW = '->' + + QUOTE = '"' + + PIPE = '|>' + ] +} + +aikenFile ::= topLevelDefinition* +private topLevelDefinition ::= + importStatement + | typeStatement + | validatorStatement + | functionStatement + | COMMENT + | ([PUB] constantStatement) + +private innerDefinition ::= + COMMENT + | variableStatement + | constantStatement + | functionCall + +typeIdentifier ::= [IDENTIFIER DOT] UPPER_IDENTIFIER [LPAREN typeIdentifierInnerType [typeIdentifierInnerType*] RPAREN] +typeIdentifierInnerType ::= typeIdentifier [COMMA] + +private constructorElement ::= constructorIdentifier typeIdentifier [COMMA] +constructorIdentifier ::= IDENTIFIER COLON + +importStatement ::= USE importStatementElement +importStatementElement ::= IDENTIFIER ('/' IDENTIFIER [importStatementTypes])* +importStatementTypes ::= DOT LBRACE ((UPPER_IDENTIFIER|IDENTIFIER) [COMMA])* RBRACE + +// TODO improve type statement parsing +typeName ::= UPPER_IDENTIFIER +constructorName ::= UPPER_IDENTIFIER +typeStatement ::= [PUB] TYPE typeName ('<' IDENTIFIER '>')? LBRACE (constructorElement | (typeStatementConstructor | typeStatementConstructorNoArg)*) RBRACE +typeStatementConstructor ::= constructorName (LBRACE|LPAREN) (constructorElement | IDENTIFIER)* (RBRACE|RPAREN) +typeStatementConstructorNoArg ::= constructorName + +validatorStatement ::= VALIDATOR IDENTIFIER [LPAREN [(constructorElement)*] RPAREN] LBRACE [innerDefinition*] RBRACE + +functionStatement ::= [PUB] FN IDENTIFIER LPAREN [(constructorElement)*] RPAREN [functionStatementType] LBRACE [innerDefinition*] RBRACE +functionStatementType ::= ARROW typeIdentifier + +variableStatement ::= LET IDENTIFIER EQ variableValue +constantStatement ::= CONST IDENTIFIER EQ variableValue + +// TODO parse value inside string +variableValue ::= functionCall | UPPER_IDENTIFIER | typeIdentifier | IDENTIFIER | NUMBER | STRING_CONTENT + +functionCall ::= [IDENTIFIER DOT] IDENTIFIER LPAREN [functionCallParam*] RPAREN [PIPE functionCall] +functionCallParam ::= ((IDENTIFIER COLON variableValue) | variableValue)[COMMA] diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/_AikenLexer.flex b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/_AikenLexer.flex new file mode 100644 index 0000000..7a59415 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/grammar/_AikenLexer.flex @@ -0,0 +1,102 @@ +package com.bloxbean.intelliada.idea.aiken.lang; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.tree.IElementType; + +import static com.intellij.psi.TokenType.BAD_CHARACTER; +import static com.intellij.psi.TokenType.WHITE_SPACE; +import static com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes.*; + +%% + +%{ + public _AikenLexer() { + this((java.io.Reader)null); + } +%} + +%public +%class _AikenLexer +%implements FlexLexer +%function advance +%type IElementType +%unicode + +EOL=\R +WHITE_SPACE=\s+ + +IDENTIFIER=[_a-z][_0-9a-z]* +UPPER_IDENTIFIER=[A-Z][_0-9a-zA-Z]* +COMMENT="//"([^\n]*)? +DOC_COMMENT="///"([^\n]*)? +MODULE_COMMENT="////"([^\n]*)? +NUMBER=[0-9]* +STRING_CONTENT=\"([^\\\\\\\"]|\\\\[^efnrt\\\"\\\\])+\" + +%% + { + {WHITE_SPACE} { return WHITE_SPACE; } + + "if" { return IF; } + "else" { return ELSE; } + "when" { return WHEN; } + "is" { return IS; } + "pub" { return PUB; } + "fn" { return FN; } + "use" { return USE; } + "let" { return LET; } + "pub" { return PUB; } + "type" { return TYPE; } + "opaque" { return OPAQUE; } + "const" { return CONST; } + "todo" { return TODO; } + "expect" { return EXPECT; } + "check" { return CHECK; } + "test" { return TEST; } + "trace" { return TRACE; } + "fail" { return FAIL; } + "validator" { return VALIDATOR; } + "and" { return AND; } + "or" { return OR; } + "as" { return AS; } + "via" { return VIA; } + + + "{" { return LBRACE; } + "}" { return RBRACE; } + "[" { return LBRACK; } + "]" { return RBRACK; } + "(" { return LPAREN; } + ")" { return RPAREN; } + ":" { return COLON; } + "," { return COMMA; } + "=" { return EQ; } + "==" { return EQEQ; } + "!" { return BANG; } + "+" { return PLUS; } + "-" { return MINUS; } + "||" { return OR; } + "&&" { return AND; } + "<" { return LT; } + ">" { return GT; } + "*" { return MUL; } + "/" { return DIV; } + "//" { return DIVDIV; } + "." { return DOT; } + ".." { return DOTDOT; } + "=>" { return FAT_ARROW; } + "->" { return ARROW; } + "\"" { return QUOTE; } + "|>" { return PIPE; } + + {IDENTIFIER} { return IDENTIFIER; } + {UPPER_IDENTIFIER} { return UPPER_IDENTIFIER; } + {COMMENT} { return COMMENT; } + {DOC_COMMENT} { return DOC_COMMENT; } + {MODULE_COMMENT} { return MODULE_COMMENT; } + {NUMBER} { return NUMBER; } + {STRING_CONTENT} { return STRING_CONTENT; } + +} + +[^] { return BAD_CHARACTER; } diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenElementType.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenElementType.java new file mode 100644 index 0000000..6b087ce --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenElementType.java @@ -0,0 +1,12 @@ +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import com.bloxbean.intelliada.idea.aiken.lang.AikenLanguage; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class AikenElementType extends IElementType { + public AikenElementType(@NotNull @NonNls String debugName) { + super(debugName, AikenLanguage.INSTANCE); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFile.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFile.java new file mode 100644 index 0000000..4c31f5f --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenFile.java @@ -0,0 +1,25 @@ +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import com.bloxbean.intelliada.idea.aiken.lang.AikenFileType; +import com.bloxbean.intelliada.idea.aiken.lang.AikenLanguage; +import com.intellij.extapi.psi.PsiFileBase; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.FileViewProvider; +import org.jetbrains.annotations.NotNull; + +public class AikenFile extends PsiFileBase { + public AikenFile(@NotNull FileViewProvider viewProvider) { + super(viewProvider, AikenLanguage.INSTANCE); + } + + @NotNull + @Override + public FileType getFileType() { + return AikenFileType.INSTANCE; + } + + @Override + public String toString() { + return "Aiken File"; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTokenType.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTokenType.java new file mode 100644 index 0000000..c0a891f --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/AikenTokenType.java @@ -0,0 +1,17 @@ +package com.bloxbean.intelliada.idea.aiken.lang.psi; + +import com.bloxbean.intelliada.idea.aiken.lang.AikenLanguage; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class AikenTokenType extends IElementType { + public AikenTokenType(@NonNls @NotNull String debugName) { + super(debugName, AikenLanguage.INSTANCE); + } + + @Override + public String toString() { + return "AikenTokeType." + super.toString(); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenParserUtil.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenParserUtil.java new file mode 100644 index 0000000..f9b4f03 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenParserUtil.java @@ -0,0 +1,7 @@ +package com.bloxbean.intelliada.idea.aiken.lang.psi.impl; + +import com.intellij.lang.parser.GeneratedParserUtilBase; + +public class AikenParserUtil extends GeneratedParserUtilBase { + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenPsiImplUtil.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenPsiImplUtil.java new file mode 100644 index 0000000..dae66bd --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/lang/psi/impl/AikenPsiImplUtil.java @@ -0,0 +1,4 @@ +package com.bloxbean.intelliada.idea.aiken.lang.psi.impl; + +public class AikenPsiImplUtil { +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/messaging/AikenProjectNodeConfigChangeNotifier.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/messaging/AikenProjectNodeConfigChangeNotifier.java new file mode 100644 index 0000000..3c02e0d --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/messaging/AikenProjectNodeConfigChangeNotifier.java @@ -0,0 +1,11 @@ +package com.bloxbean.intelliada.idea.aiken.messaging; + +import com.intellij.openapi.project.Project; +import com.intellij.util.messages.Topic; + +public interface AikenProjectNodeConfigChangeNotifier { + Topic CHANGE_AIKEN_PROJECT_NODES_CONFIG_TOPIC + = Topic.create("AikenProjectNodeConfigurationTopic", AikenProjectNodeConfigChangeNotifier.class); + + void configUpdated(Project project); +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/messaging/AikenSDKChangeNotifier.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/messaging/AikenSDKChangeNotifier.java new file mode 100644 index 0000000..693b554 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/messaging/AikenSDKChangeNotifier.java @@ -0,0 +1,12 @@ +package com.bloxbean.intelliada.idea.aiken.messaging; + +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.intellij.util.messages.Topic; + +public interface AikenSDKChangeNotifier { + Topic CHANGE_AIKEN_SDK_TOPIC = Topic.create("AikenSDKTopic", AikenSDKChangeNotifier.class); + + void sdkAdded(AikenSDK sdk); + void sdkUpdated(AikenSDK sdk); + void sdkDeleted(AikenSDK sdk); +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenContractTemplates.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenContractTemplates.java new file mode 100644 index 0000000..527b8f7 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenContractTemplates.java @@ -0,0 +1,6 @@ +package com.bloxbean.intelliada.idea.aiken.module; + +public class AikenContractTemplates { + public final static String AK_HELLOWORLD_TEMPLATE = "Aiken.Hello World"; + public final static String AK_EMPTY_TMPL = "Aiken.Empty"; +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleBuilder.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleBuilder.java new file mode 100644 index 0000000..ae721ab --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleBuilder.java @@ -0,0 +1,306 @@ +package com.bloxbean.intelliada.idea.aiken.module; + +import com.bloxbean.intelliada.idea.aiken.common.AikenIcons; +import com.bloxbean.intelliada.idea.aiken.compile.AikenCompileService; +import com.bloxbean.intelliada.idea.aiken.compile.CompilationResultListener; +import com.bloxbean.intelliada.idea.aiken.compile.CompileService; +import com.bloxbean.intelliada.idea.aiken.compile.SDKNotConfigured; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenConfigurationHelperService; +import com.bloxbean.intelliada.idea.aiken.configuration.AikenSDK; +import com.bloxbean.intelliada.idea.toolwindow.CardanoConsole; +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.ide.util.projectWizard.*; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.progress.impl.BackgroundableProcessIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.NlsContexts; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.io.File; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class AikenModuleBuilder extends ModuleBuilder implements ModuleBuilderListener { + private static final Logger LOG = Logger.getInstance(AikenModuleBuilder.class); + + private List> mySourcePaths; + + private OwnerInputField ownerInputField; + + public AikenModuleBuilder() { + addListener(this); + } + + @Override + public String getBuilderId() { + return "Aiken"; + } + + @Override + public Icon getNodeIcon() { + return AikenIcons.AIKEN_ICON; + } + + @Override + public String getDescription() { + return "Aiken - A Modern Smart Contract Platform For Cardano"; + } + + @Override + public String getPresentableName() { + return "Aiken Smart Contract"; + } + + @Override + public String getGroupName() { + return "Aiken"; + } + + @Override + public ModuleWizardStep[] createWizardSteps(WizardContext wizardContext, ModulesProvider modulesProvider) { + return new ModuleWizardStep[]{}; + } + + @Override + public void moduleCreated(@NotNull Module module) { + VirtualFile[] roots = ModuleRootManager.getInstance(module).getSourceRoots(); + for (VirtualFile srcRoot: roots) { + if (srcRoot.getName().equals("validators")) { + final VirtualFile topFolder = srcRoot.getParent(); + if (topFolder != null) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + ProjectGeneratorUtil.createNewContract(module.getProject(), srcRoot, AikenContractTemplates.AK_HELLOWORLD_TEMPLATE, module.getName() + ".ak"); + + build(module); + } + }); + } + } + } + } + + private static void build(@NotNull Module module) { + var project = module.getProject(); + String moduleDir = ModuleUtil.getModuleDirPath(module); + final VirtualFile folderToRefresh = VfsUtil.findFileByIoFile(new File(moduleDir), true); + + final CardanoConsole console = CardanoConsole.getConsole(project); + console.clearAndshow(); + + CompilationResultListener compilationResultListener = new CompilationResultListener() { + @Override + public void attachProcess(OSProcessHandler handler) { + ApplicationManager.getApplication().invokeLater(() -> { + try { + console.getView().attachToProcess(handler); + } catch (IncorrectOperationException ex) { + //This should not happen + //ex.printStackTrace(); + console.showInfoMessage(ex.getMessage()); + console.dispose(); + console.getView().attachToProcess(handler); + } + handler.startNotify(); + }); + } + + @Override + public void error(String message) { + console.showErrorMessage(message); + } + + @Override + public void info(String message) { + console.showInfoMessage(message); + } + + @Override + public void warn(String msg) { + console.showWarningMessage(msg); + } + + @Override + public void onSuccessful(String sourceFile) { + console.showSuccessMessage("Build Successful"); + if (folderToRefresh != null) { + folderToRefresh.refresh(false, false); + } + IdeaUtil.showNotification(project, "Aiken Compile", "Compilation was successful", NotificationType.INFORMATION, null); + } + + @Override + public void onFailure(String sourceFile, Throwable t) { + console.showErrorMessage(String.format("Compilation failed for %s", sourceFile), t); + IdeaUtil.showNotification(project, "Aiken Compile", "Compilation failed", NotificationType.ERROR, null); + } + }; + + Task.Backgroundable task = new Task.Backgroundable(module.getProject(), "Aiken Compile") { + + @Override + public void run(@NotNull ProgressIndicator indicator) { + AikenSDK localSDK = AikenConfigurationHelperService.getCompilerLocalSDK(project); + CompileService compileService = null; + if (localSDK != null) { + try { + compileService = new AikenCompileService(project); + } catch (SDKNotConfigured sdkNotConfigured) { + Messages.showErrorDialog("Aiken SDK is not set for this module.", "Aiken Compilation"); + return; + } + } + + console.showInfoMessage("Start compilation .."); + compileService.compile(moduleDir, compilationResultListener); + } + }; + + ProgressManager.getInstance().runProcessWithProgressAsynchronously(task, new BackgroundableProcessIndicator(task)); + } + + @Override + public void setupRootModel(@NotNull ModifiableRootModel rootModel) throws ConfigurationException { + rootModel.inheritSdk(); + + String moduleName = rootModel.getModule().getName(); + + String ownerInputFieldVal= ownerInputField.getValue(); + String owner = ownerInputFieldVal != null? ownerInputFieldVal.trim(): System.getProperty("user.name"); + + Project project = rootModel.getProject(); + String basePath = project.getBasePath(); + ApplicationManager.getApplication().runWriteAction( + () -> { + var aikenSdk = AikenConfigurationHelperService.getCompilerLocalSDK(project); + + if (aikenSdk == null) { + IdeaUtil.showNotification( + "Project creation", + "Aiken executable not found. Please make sure Aiken is installed and added to the PATH", NotificationType.ERROR, null); + } + + List commands = aikenSdk.getAikenCommand(); + commands.add("new"); + commands.add(owner + "/" + moduleName); + + try { + //create a temporay directory + var tempDir = Files.createTempDirectory("aiken").toFile(); + ProcessBuilder pb = new ProcessBuilder(commands); + pb.directory(tempDir); + pb.redirectErrorStream(true); + pb.redirectOutput(ProcessBuilder.Redirect.INHERIT); + Process process = pb.start(); + process.waitFor(); + + FileUtil.copyDirContent(new File(tempDir, moduleName), new File(basePath)); + } catch (Exception e) { + IdeaUtil.showNotification(project, + "Project creation", + "Aiken executable not found. Please make sure Aiken is installed and added to the PATH", + NotificationType.ERROR, e.getMessage()); + if (LOG.isDebugEnabled()) { + LOG.error("Aiken executable not found", e); + } + } + }); + + ContentEntry contentEntry = doAddContentEntry(rootModel); + if (contentEntry != null) { + final List> sourcePaths = getSourcePaths(); + + if (sourcePaths != null) { + for (final Pair sourcePath : sourcePaths) { + String first = sourcePath.first; + new File(first).mkdirs(); + final VirtualFile sourceRoot = LocalFileSystem.getInstance() + .refreshAndFindFileByPath(FileUtil.toSystemIndependentName(first)); + if (sourceRoot != null) { + contentEntry.addSourceFolder(sourceRoot, false, sourcePath.second); + } + } + } + } + + } + + @Override + protected List> getAdditionalFields() { + if (ownerInputField == null) + ownerInputField = new OwnerInputField("owner", System.getProperty("user.name")); + return Collections.singletonList(ownerInputField); + } + + @Override + public ModuleType getModuleType() { + return new AikenModuleType(); + } + + + public List> getSourcePaths() throws ConfigurationException { + if (mySourcePaths == null) { + final List> paths = new ArrayList<>(); + @NonNls final String validatorsPath = getContentEntryPath() + File.separator + "validators"; + new File(validatorsPath).mkdirs(); + paths.add(Pair.create(validatorsPath, "")); + + @NonNls final String libPath = getContentEntryPath() + File.separator + "lib"; + new File(libPath).mkdirs(); + paths.add(Pair.create(libPath, "")); + return paths; + } + return mySourcePaths; + } + + class OwnerInputField extends WizardInputField { + private JTextField jt; + protected OwnerInputField(String id, String defaultValue) { + super(id, defaultValue); + jt = new JTextField(); + jt.setText(defaultValue); + } + + @Override + public @NlsContexts.Label String getLabel() { + return "Owner"; + } + + @Override + public JTextField getComponent() { + return jt; + } + + @Override + public String getValue() { + return jt.getText(); + } + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleConstant.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleConstant.java new file mode 100644 index 0000000..f9f3833 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleConstant.java @@ -0,0 +1,5 @@ +package com.bloxbean.intelliada.idea.aiken.module; + +public class AikenModuleConstant { + public final static String AIKEN_TOML = "aiken.toml"; +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleType.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleType.java new file mode 100644 index 0000000..e791264 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/AikenModuleType.java @@ -0,0 +1,42 @@ +package com.bloxbean.intelliada.idea.aiken.module; + +import com.bloxbean.intelliada.idea.aiken.common.AikenIcons; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.ModuleTypeManager; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +public class AikenModuleType extends ModuleType { + private static final String ID = "Aiken_Module"; + + public AikenModuleType() { + super(ID); + } + + public static AikenModuleType getInstance() { + return (AikenModuleType) ModuleTypeManager.getInstance().findByID(ID); + } + + @Override + public @NotNull AikenModuleBuilder createModuleBuilder() { + return new AikenModuleBuilder(); + } + + @Override + public @NotNull @Nls(capitalization = Nls.Capitalization.Title) String getName() { + return "Aiken Smart Contract"; + } + + @Override + public @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String getDescription() { + return "Aiken - A Modern Smart Contract Platform For Cardano"; + } + + @Override + public @NotNull Icon getNodeIcon(boolean isOpened) { + return AikenIcons.MODULE; + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ProjectGeneratorUtil.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ProjectGeneratorUtil.java new file mode 100644 index 0000000..46e9076 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ProjectGeneratorUtil.java @@ -0,0 +1,40 @@ +package com.bloxbean.intelliada.idea.aiken.module; + +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; + +public class ProjectGeneratorUtil { + private final static Logger LOG = Logger.getInstance(ProjectGeneratorUtil.class); + + public static void createNewContract(Project project, VirtualFile srcRoot, String templateName, String contractName) { + if (srcRoot == null) + return; + + try { + createFile(contractName, srcRoot, templateName); + } catch (Exception e) { + if(LOG.isDebugEnabled()) { + LOG.error(e); + } + IdeaUtil.showNotification(project, "Project create", + "Aiken smart contract file generation failed : " + e.getMessage(), NotificationType.ERROR, null); + return; + } + } + + private static boolean createFile(String file, VirtualFile folder, final String templateName) + throws Exception { + final FileTemplate template = FileTemplateManager.getDefaultInstance().getInternalTemplate(templateName); + + VirtualFile srcFile = folder.createChildData(folder, file); + VfsUtil.saveText(srcFile, template.getText()); + + return true; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenToml.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenToml.java new file mode 100644 index 0000000..45fb31c --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenToml.java @@ -0,0 +1,17 @@ +package com.bloxbean.intelliada.idea.aiken.module.pkg; + +import lombok.Data; + +import java.util.List; + +@Data +public class AikenToml { + private String name; + private String version; + private String license; + private String description; + + private Repository repository; + private List dependencies; +} + diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenTomlException.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenTomlException.java new file mode 100644 index 0000000..4150cad --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenTomlException.java @@ -0,0 +1,11 @@ +package com.bloxbean.intelliada.idea.aiken.module.pkg; + +public class AikenTomlException extends Exception { + public AikenTomlException(String message) { + super(message); + } + + public AikenTomlException(String msg, Throwable t) { + super(msg, t); + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenTomlService.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenTomlService.java new file mode 100644 index 0000000..a0a2fdf --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/AikenTomlService.java @@ -0,0 +1,136 @@ +package com.bloxbean.intelliada.idea.aiken.module.pkg; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.moandjiezana.toml.Toml; +import com.moandjiezana.toml.TomlWriter; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import static com.bloxbean.intelliada.idea.aiken.module.AikenModuleConstant.AIKEN_TOML; + +public class AikenTomlService { + private final static Logger LOG = Logger.getInstance(AikenTomlService.class); + + private Project project; + private AikenToml aikenToml; + private boolean aikenProject; + private boolean isDirty; + + public static AikenTomlService getInstance(@NotNull Project project) { + if (project == null) + return null; + + return project.getService(AikenTomlService.class); + } + + public AikenTomlService(@NotNull Project project) { + this.project = project; + + ApplicationManager.getApplication().invokeLater(() -> { + final String basePath = project.getBasePath(); + VirtualFile pkgJson = VfsUtil.findFileByIoFile(new File(basePath, AIKEN_TOML), true); + if (pkgJson != null && pkgJson.exists()) { + aikenProject = true; + attachListener(); + } + }); + } + + private void attachListener() { + } + + public boolean isAikenProject() { + return aikenProject; + } + + public AikenToml createAikenToml(String owner, String name) throws AikenTomlException { + this.aikenToml = new AikenToml(); + aikenToml.setName(owner + "/" + name); + aikenToml.setVersion("0.0.0"); + aikenToml.setLicense("Apache-2.0"); + aikenToml.setDescription("Aiken contracts"); + + aikenToml.setRepository(Repository.builder() + .user(owner) + .project(name) + .platform("github") + .build()); + + aikenToml.setDependencies(List.of( + Dependency.builder() + .name("aiken-lang/stdlib") + .version("main") + .source("github") + .build() + )); + + save(); + + return aikenToml; + } + + public void load() throws AikenTomlException { + isDirty = false; + if(project == null) return; + + String projectBasePath = project.getBasePath(); + String aikenTomlPath = projectBasePath + File.separator + AIKEN_TOML; + + if(!new File(aikenTomlPath).exists()) { + throw new AikenTomlException(AIKEN_TOML + " file doesn't exist."); + } + + try { + aikenToml = readAikenToml(aikenTomlPath); + } catch (IOException e) { + throw new AikenTomlException(String.format("Unable to read %s file at locatioin %s , Reason : %s", AIKEN_TOML, aikenTomlPath, e.getMessage()), e); + } + } + + public void save() throws AikenTomlException { + String path = getAikenTomlPath(); + if(path == null) + throw new AikenTomlException("aiken.toml path cannot be null"); + + File file = new File(path); + try { + TomlWriter tomlWriter = new TomlWriter(); + tomlWriter.write(aikenToml, file); + } catch (IOException e) { + throw new AikenTomlException(String.format("Unable to write aiken.toml file at locatioin %s", path)); + } + + try { + //Refresh + VfsUtil.findFileByIoFile(file, false).refresh(true, false); + } catch (Exception e) { + if(LOG.isDebugEnabled()) + LOG.warn(e); + } + } + + public void markDirty() { + this.isDirty = true; + } + + public boolean isDirty() { + return this.isDirty; + } + + private AikenToml readAikenToml(String path) throws IOException { + Toml toml = new Toml().read(path); + return toml.to(AikenToml.class); + } + + private String getAikenTomlPath() { + String projectBasePath = project.getBasePath(); + return projectBasePath + File.separator + AIKEN_TOML; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/Dependency.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/Dependency.java new file mode 100644 index 0000000..4624d35 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/Dependency.java @@ -0,0 +1,16 @@ +package com.bloxbean.intelliada.idea.aiken.module.pkg; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Dependency { + private String name; + private String version; + private String source; +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/Repository.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/Repository.java new file mode 100644 index 0000000..9d5c3b7 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/pkg/Repository.java @@ -0,0 +1,16 @@ +package com.bloxbean.intelliada.idea.aiken.module.pkg; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class Repository { + private String user; + private String project; + private String platform; +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/AikenDirectoryProjectGenerator.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/AikenDirectoryProjectGenerator.java new file mode 100644 index 0000000..766ae9b --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/AikenDirectoryProjectGenerator.java @@ -0,0 +1,85 @@ +package com.bloxbean.intelliada.idea.aiken.module.project; + +import com.bloxbean.intelliada.idea.aiken.common.AikenIcons; +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ModifiableModelsProvider; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.util.NlsContexts; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.platform.DirectoryProjectGeneratorBase; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.io.File; +import java.util.Arrays; +import java.util.List; + +public class AikenDirectoryProjectGenerator extends DirectoryProjectGeneratorBase { + private final static Logger LOG = Logger.getInstance(AikenDirectoryProjectGenerator.class); + + @Override + public @NlsContexts.DetailedDescription String getDescription() { + return "Aiken Smart Contract"; + } + + @Override + public @NotNull @NlsContexts.Label String getName() { + return "Aiken"; + } + + @Override + public Icon getLogo() { + return AikenIcons.MODULE; + } + + @Override + public void generateProject(@NotNull Project project, @NotNull VirtualFile baseDir, @NotNull ProjectCreateSettings settings, @NotNull Module module) { + if(project == null) { + IdeaUtil.showNotification(project, + "Project creation", + "Project creation failed. Unexpected error.", + NotificationType.ERROR, null); + return; + } + + String basePath = project.getBasePath(); + + String moduleName = module.getName(); + String owner = System.getProperty("user.name"); + + if (project != null) { + + ApplicationManager.getApplication().runWriteAction( + () -> { + List commands = Arrays.asList(System.getProperty("user.home") + File.separator + ".aiken" + File.separator + "bin" + File.separator + "aiken"); + commands.add("new"); + commands.add(owner + "/" + moduleName); + try { + ProcessBuilder pb = new ProcessBuilder(commands); + pb.directory(new File(basePath)); + pb.redirectErrorStream(true); + Process process = pb.start(); + process.waitFor(); + } catch (Exception e) { + IdeaUtil.showNotification(project, + "Project creation", + "Aiken executable not found. Please make sure Aiken is installed and added to the PATH", + NotificationType.ERROR, null); + if (LOG.isDebugEnabled()) { + LOG.error("Aiken executable not found", e); + return; + } + } + + final ModifiableRootModel modifiableModel = ModifiableModelsProvider.getInstance().getModuleModifiableModel(module); + modifiableModel.commit(); + }); + } + } + +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/AikenProjectOpenProcessor.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/AikenProjectOpenProcessor.java new file mode 100644 index 0000000..e38b6fc --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/AikenProjectOpenProcessor.java @@ -0,0 +1,83 @@ +package com.bloxbean.intelliada.idea.aiken.module.project; + +import com.bloxbean.intelliada.idea.aiken.module.AikenModuleConstant; +import com.bloxbean.intelliada.idea.util.IdeaUtil; +import com.intellij.notification.NotificationType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ContentEntry; +import com.intellij.openapi.roots.ModifiableModelsProvider; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.platform.PlatformProjectOpenProcessor; +import com.intellij.projectImport.ProjectOpenProcessor; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class AikenProjectOpenProcessor extends ProjectOpenProcessor { + @Override + public @NotNull @Nls String getName() { + return "Aiken"; + } + + @Override + public boolean canOpenProject(@NotNull VirtualFile file) { + VirtualFile aikenToml = file.findChild(AikenModuleConstant.AIKEN_TOML); + return aikenToml != null? true : false; + } + + @Override + public @Nullable Project doOpenProject(@NotNull VirtualFile virtualFile, @Nullable Project projectToClose, boolean forceOpenInNewFrame) { + if(virtualFile == null || !virtualFile.isDirectory()) + return null; + + ProjectOpenProcessor processor = PlatformProjectOpenProcessor.getInstance(); + Project project = processor.doOpenProject(virtualFile, projectToClose, forceOpenInNewFrame); + + if(project == null) + return null; + + VirtualFile pkgJson = virtualFile.findChild(AikenModuleConstant.AIKEN_TOML); + if(pkgJson == null) + return null; + + VirtualFile validatorVFile = virtualFile.findChild("validators"); + if(validatorVFile == null || !validatorVFile.isDirectory()) + return null; + + Module module = ModuleUtil.findModuleForFile(validatorVFile, project); + if(module == null) + return null; + + final ModifiableRootModel modifiableModel = ModifiableModelsProvider.getInstance().getModuleModifiableModel(module); + ContentEntry[] contentEntries = modifiableModel.getContentEntries(); + if(contentEntries != null && contentEntries.length > 0) + return null; + + String basePath = project.getBasePath(); + //No content entry defined. Add one + ApplicationManager.getApplication().runWriteAction( + () -> { + try { + final VirtualFile moduleContentRoot = + LocalFileSystem.getInstance().refreshAndFindFileByPath(basePath.replace('\\', '/')); + + ContentEntry contentEntry = modifiableModel.addContentEntry(moduleContentRoot); + contentEntry.addSourceFolder(validatorVFile, false); + + modifiableModel.commit(); + } catch (Exception e) { + IdeaUtil.showNotification(project, + "Project creation", + "Sources Root could not be created or marked properly. You can manually create and mark a folder as Sources Root", + NotificationType.WARNING, null); + } + }); + + return project; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/ProjectCreateSettings.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/ProjectCreateSettings.java new file mode 100644 index 0000000..75c449b --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/project/ProjectCreateSettings.java @@ -0,0 +1,9 @@ +package com.bloxbean.intelliada.idea.aiken.module.project; + +public class ProjectCreateSettings { + private String name; + + public ProjectCreateSettings(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModulePanel.form b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModulePanel.form new file mode 100644 index 0000000..4757e2f --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModulePanel.form @@ -0,0 +1,50 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModulePanel.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModulePanel.java new file mode 100644 index 0000000..03a19fb --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModulePanel.java @@ -0,0 +1,13 @@ +package com.bloxbean.intelliada.idea.aiken.module.ui; + +import javax.swing.*; + +public class AikenModulePanel { + private JTextField projectName; + private JTextField owner; + private JPanel mainPanel; + + public JPanel getMainPanel() { + return mainPanel; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModuleWizardStep.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModuleWizardStep.java new file mode 100644 index 0000000..fbcb836 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/module/ui/AikenModuleWizardStep.java @@ -0,0 +1,25 @@ +package com.bloxbean.intelliada.idea.aiken.module.ui; + +import com.bloxbean.intelliada.idea.aiken.module.AikenModuleBuilder; +import com.intellij.ide.util.projectWizard.ModuleWizardStep; + +import javax.swing.*; + +public class AikenModuleWizardStep extends ModuleWizardStep { + private final AikenModulePanel aikenPanel = new AikenModulePanel(); + private AikenModuleBuilder moduleBuilder; + + public AikenModuleWizardStep(AikenModuleBuilder builder) { + this.moduleBuilder = builder; + } + + @Override + public JComponent getComponent() { + return aikenPanel.getMainPanel(); + } + + @Override + public void updateDataModel() { + + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/aiken/util/AikenSdkUtil.java b/src/main/java/com/bloxbean/intelliada/idea/aiken/util/AikenSdkUtil.java new file mode 100644 index 0000000..6b16d32 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/aiken/util/AikenSdkUtil.java @@ -0,0 +1,82 @@ +package com.bloxbean.intelliada.idea.aiken.util; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.GeneralCommandLine; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; + +public class AikenSdkUtil { + private final static Logger LOG = Logger.getInstance(AikenSdkUtil.class); + + public static String getVersionString(String aikenBinFolder) throws Exception { + if (aikenBinFolder == null) return null; + + String goalCmd = "aiken"; + if(SystemInfo.isWindows) + goalCmd = "aiken.exe"; + + File file = new File(aikenBinFolder); + VirtualFile home = LocalFileSystem.getInstance().findFileByIoFile(file); + if (home != null) { + try { + String result = AikenSdkUtil.runProcessAndExit(file.getAbsolutePath() + File.separator + goalCmd, "--version"); + result.split(" "); + LOG.debug(result); + return result; + } catch (Exception e) { + if(LOG.isDebugEnabled()) { + LOG.error(e); + } + throw e; + } + } + return null; + } + + public static String runProcessAndExit(String program, String command) throws InterruptedException, ExecutionException, IOException { + GeneralCommandLine commandLine = new GeneralCommandLine(program, command); + try { + + Process process = commandLine.createProcess(); + StringBuilder output = new StringBuilder(); + + BufferedReader reader = new BufferedReader( + new InputStreamReader(process.getInputStream())); + + String line; + int lineCount = 1; + String version = null; + while ((line = reader.readLine()) != null) { + output.append(line + "\n"); + if(lineCount == 1) { + version = line.split(" ")[1]; + } + lineCount++; + } + + int exitVal = process.waitFor(); + if (exitVal == 0) { + LOG.debug("Getting Aiken SDK version. Success!"); + LOG.debug(output.toString()); + return version; + } else { + //abnormal... + } + + } catch (Exception e) { + if(LOG.isDebugEnabled()) { + LOG.error(e); + } + throw e; + } + + return null; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/common/Tuple.java b/src/main/java/com/bloxbean/intelliada/idea/common/Tuple.java new file mode 100644 index 0000000..226846b --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/common/Tuple.java @@ -0,0 +1,19 @@ +package com.bloxbean.intelliada.idea.common; + +public class Tuple { + private K _1; + private V _2; + + public Tuple(K _1, V _2) { + this._1 = _1; + this._2 = _2; + } + + public K _1() { + return _1; + } + + public V _2() { + return _2; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/CLIProviderDialog.java b/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/CLIProviderDialog.java index 5d49722..39484cb 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/CLIProviderDialog.java +++ b/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/CLIProviderDialog.java @@ -4,7 +4,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.ValidationInfo; -import com.twelvemonkeys.lang.StringUtil; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.Nullable; import javax.swing.*; diff --git a/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/CardanoNodeConfigDialog.java b/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/CardanoNodeConfigDialog.java index 3408754..60c2d73 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/CardanoNodeConfigDialog.java +++ b/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/CardanoNodeConfigDialog.java @@ -43,7 +43,7 @@ public void itemStateChanged(ItemEvent e) { if (remoteNode != null && remoteNode.getNodeType() != null) { if (remoteNode.getNodeType().equals(NodeType.KOIOS_MAINNET) || - remoteNode.getNodeType().equals(NodeType.KOIOS_TESTNET) || + remoteNode.getNodeType().equals(NodeType.KOIOS_PREPROD) || remoteNode.getNodeType().equals(NodeType.KOIOS_CUSTOM)) { nodeTypesCB.setSelectedItem(CardanoNodeType.Koios); koiosNodeConfigPanel.setNodeData(remoteNode); diff --git a/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/KoiosNodeConfigPanel.java b/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/KoiosNodeConfigPanel.java index e72a04f..2f5cf13 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/KoiosNodeConfigPanel.java +++ b/src/main/java/com/bloxbean/intelliada/idea/configuration/ui/KoiosNodeConfigPanel.java @@ -101,12 +101,12 @@ public void setNodeData(RemoteNode node) { private void handleNodeTypeSelection() { nodeTypesCB.addActionListener(e -> { - if (NodeType.KOIOS_TESTNET.equals(nodeTypesCB.getSelectedItem()) + if (NodeType.KOIOS_PREPROD.equals(nodeTypesCB.getSelectedItem()) || NodeType.KOIOS_MAINNET.equals(nodeTypesCB.getSelectedItem())) { gqlEndpointTf.setEnabled(false); - if (NodeType.KOIOS_TESTNET.equals(nodeTypesCB.getSelectedItem())) { - gqlEndpointTf.setText(Constants.KOIOS_TESTNET_URL); + if (NodeType.KOIOS_PREPROD.equals(nodeTypesCB.getSelectedItem())) { + gqlEndpointTf.setText(Constants.KOIOS_PREPROD_URL); setNetwork(Networks.testnet()); } else if (NodeType.KOIOS_MAINNET.equals(nodeTypesCB.getSelectedItem())) { gqlEndpointTf.setText(Constants.KOIOS_MAINNET_URL); @@ -302,10 +302,10 @@ private void createUIComponents() { Collection availableNodeOptions = new ArrayList(); availableNodeOptions.add(""); availableNodeOptions.add(Constants.KOIOS_MAINNET_URL); - availableNodeOptions.add(Constants.KOIOS_TESTNET_URL); + availableNodeOptions.add(Constants.KOIOS_PREPROD_URL); availableNodeOptions.add(Constants.KOIOS_GUILDNET_URL); gqlEndpointTf = TextFieldWithAutoCompletion.create(project, availableNodeOptions, true, ""); - nodeTypesCB = new ComboBox(new NodeType[]{NodeType.EMPTY, NodeType.KOIOS_TESTNET, NodeType.KOIOS_MAINNET, NodeType.KOIOS_CUSTOM}); + nodeTypesCB = new ComboBox(new NodeType[]{NodeType.EMPTY, NodeType.KOIOS_PREPROD, NodeType.KOIOS_MAINNET, NodeType.KOIOS_CUSTOM}); } } diff --git a/src/main/java/com/bloxbean/intelliada/idea/core/util/NetworkUrls.java b/src/main/java/com/bloxbean/intelliada/idea/core/util/NetworkUrls.java index e060930..5d2c0a0 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/core/util/NetworkUrls.java +++ b/src/main/java/com/bloxbean/intelliada/idea/core/util/NetworkUrls.java @@ -5,6 +5,6 @@ public class NetworkUrls { public final static String BLOCKFROST_TESTNET_BASEURL = "https://cardano-testnet.blockfrost.io/api/v0/"; public final static String BLOCKFROST_MAINNET_BASEURL = "https://cardano-mainnet.blockfrost.io/api/v0/"; - public final static String BLOCKFROST_PREPOD_BASEURL = Constants.BLOCKFROST_PREPOD_URL; + public final static String BLOCKFROST_PREPOD_BASEURL = Constants.BLOCKFROST_PREPROD_URL; public final static String BLOCKFROST_PREVIEW_BASEURL = Constants.BLOCKFROST_PREVIEW_URL; } diff --git a/src/main/java/com/bloxbean/intelliada/idea/core/util/NodeType.java b/src/main/java/com/bloxbean/intelliada/idea/core/util/NodeType.java index f3264c5..d3b7548 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/core/util/NodeType.java +++ b/src/main/java/com/bloxbean/intelliada/idea/core/util/NodeType.java @@ -13,7 +13,7 @@ public enum NodeType { BLOCKFROST_PREPOD("Blockfrost Prepod"), BLOCKFROST_PREVIEW("Blockfrost Preview"), BLOCKFROST_CUSTOM("Blockfrost Custom"), - KOIOS_TESTNET("Koios Testnet"), + KOIOS_PREPROD("Koios Preprod"), KOIOS_MAINNET("Koios Mainnet"), KOIOS_CUSTOM("Koios Custom"); diff --git a/src/main/java/com/bloxbean/intelliada/idea/folding/AikenFolderingBuilder.java b/src/main/java/com/bloxbean/intelliada/idea/folding/AikenFolderingBuilder.java new file mode 100644 index 0000000..3900588 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/folding/AikenFolderingBuilder.java @@ -0,0 +1,61 @@ +package com.bloxbean.intelliada.idea.folding; + +import com.bloxbean.intelliada.idea.aiken.lang.psi.*; +import com.intellij.lang.ASTNode; +import com.intellij.lang.folding.FoldingBuilder; +import com.intellij.lang.folding.FoldingDescriptor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class AikenFolderingBuilder implements FoldingBuilder, DumbAware { + + @NotNull + @Override + public FoldingDescriptor[] buildFoldRegions(@NotNull ASTNode node, @NotNull Document document) { + List descriptors = new ArrayList<>(); + addDescriptorsForNode(descriptors, node); + return descriptors.toArray(new FoldingDescriptor[0]); + } + + private void addDescriptorsForNode(List descriptors, ASTNode node) { + PsiElement psi = node.getPsi(); + IElementType type = psi.getNode().getElementType(); + if (type == AikenTypes.LBRACE || type == AikenTypes.RBRACE) { + PsiElement parent = psi.getParent(); + if (parent != null) { + PsiElement lBrace = parent.getFirstChild(); + PsiElement rBrace = parent.getLastChild(); + if (lBrace != null && rBrace != null && lBrace != rBrace) { + int start = lBrace.getTextRange().getStartOffset(); + int end = rBrace.getTextRange().getEndOffset(); + + descriptors.add(new FoldingDescriptor(parent.getNode(), + new TextRange(start, end))); + } + } + } + + for (ASTNode child : node.getChildren(null)) { + addDescriptorsForNode(descriptors, child); + } + } + + @Nullable + @Override + public String getPlaceholderText(@NotNull ASTNode node) { + return "{...}"; + } + + @Override + public boolean isCollapsedByDefault(@NotNull ASTNode node) { + return false; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/folding/AikenPairedBraceMatcher.java b/src/main/java/com/bloxbean/intelliada/idea/folding/AikenPairedBraceMatcher.java new file mode 100644 index 0000000..ca830d2 --- /dev/null +++ b/src/main/java/com/bloxbean/intelliada/idea/folding/AikenPairedBraceMatcher.java @@ -0,0 +1,32 @@ +package com.bloxbean.intelliada.idea.folding; + +import com.bloxbean.intelliada.idea.aiken.lang.psi.AikenTypes; +import com.intellij.lang.BracePair; +import com.intellij.lang.PairedBraceMatcher; +import com.intellij.psi.PsiFile; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + + +public class AikenPairedBraceMatcher implements PairedBraceMatcher { + private static final BracePair[] PAIRS = new BracePair[]{ + new BracePair(AikenTypes.LBRACE, AikenTypes.RBRACE, true), + new BracePair(AikenTypes.LPAREN, AikenTypes.RPAREN, true) + }; + + @Override + public BracePair[] getPairs() { + return PAIRS; + } + + @Override + public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType tokenType) { + return true; + } + + @Override + public int getCodeConstructStart(PsiFile file, int openingBraceOffset) { + return openingBraceOffset; + } +} diff --git a/src/main/java/com/bloxbean/intelliada/idea/nodeint/service/NodeServiceFactory.java b/src/main/java/com/bloxbean/intelliada/idea/nodeint/service/NodeServiceFactory.java index 80477f7..2bb7928 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/nodeint/service/NodeServiceFactory.java +++ b/src/main/java/com/bloxbean/intelliada/idea/nodeint/service/NodeServiceFactory.java @@ -49,7 +49,7 @@ public BackendService getBackendService(RemoteNode remoteNode) { LOG.debug("Backend service created for the node : " + remoteNode); } } else if (NodeType.KOIOS_MAINNET.equals(remoteNode.getNodeType()) || - NodeType.KOIOS_TESTNET.equals(remoteNode.getNodeType()) || + NodeType.KOIOS_PREPROD.equals(remoteNode.getNodeType()) || NodeType.KOIOS_CUSTOM.equals(remoteNode.getNodeType()) ) { backendService = new KoiosBackendService(remoteNode.getApiEndpoint()); diff --git a/src/main/java/com/bloxbean/intelliada/idea/scripts/util/ScriptExportUtil.java b/src/main/java/com/bloxbean/intelliada/idea/scripts/util/ScriptExportUtil.java index 4a225ea..0db3864 100644 --- a/src/main/java/com/bloxbean/intelliada/idea/scripts/util/ScriptExportUtil.java +++ b/src/main/java/com/bloxbean/intelliada/idea/scripts/util/ScriptExportUtil.java @@ -6,8 +6,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; -import com.twelvemonkeys.lang.StringUtil; import javax.swing.*; import java.io.File; diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index dc2bf0d..8ae1e99 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -10,11 +10,14 @@

Documentation ]]> - + + com.intellij.modules.platform + com.redhat.devtools.lsp4ij + com.intellij.modules.lang @@ -30,9 +33,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Aiken Language Server

+ ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/fileTemplates/internal/Aiken.Empty.ak.ft b/src/main/resources/fileTemplates/internal/Aiken.Empty.ak.ft new file mode 100644 index 0000000..8295619 --- /dev/null +++ b/src/main/resources/fileTemplates/internal/Aiken.Empty.ak.ft @@ -0,0 +1,22 @@ +use aiken/collection/list +use aiken/crypto.{VerificationKeyHash} +use cardano/transaction.{OutputReference, Transaction} + +pub type Datum { + +} + +pub type Redeemer { + +} + +validator hello_world { + spend( + datum: Option, + redeemer: Redeemer, + _own_ref: OutputReference, + self: Transaction + ) { + todo + } +} diff --git a/src/main/resources/fileTemplates/internal/Aiken.Hello World.ak.ft b/src/main/resources/fileTemplates/internal/Aiken.Hello World.ak.ft new file mode 100644 index 0000000..ef19c31 --- /dev/null +++ b/src/main/resources/fileTemplates/internal/Aiken.Hello World.ak.ft @@ -0,0 +1,28 @@ +use aiken/collection/list +use aiken/crypto.{VerificationKeyHash} +use cardano/transaction.{OutputReference, Transaction} + +pub type Datum { + owner: VerificationKeyHash, +} + +pub type Redeemer { + msg: ByteArray, +} + +validator hello_world { + spend( + datum: Option, + redeemer: Redeemer, + _own_ref: OutputReference, + self: Transaction + ) { + expect Some(Datum { owner }) = datum + + let must_say_hello = redeemer.msg == "Hello, World!" + + let must_be_signed = list.has(self.extra_signatories, owner) + + must_say_hello && must_be_signed + } +} diff --git a/src/main/resources/fileTemplates/internal/_sdk_aiken.toml.ft b/src/main/resources/fileTemplates/internal/_sdk_aiken.toml.ft new file mode 100644 index 0000000..2a87a5c --- /dev/null +++ b/src/main/resources/fileTemplates/internal/_sdk_aiken.toml.ft @@ -0,0 +1,14 @@ +name = '${OWNER}/${NAME}' +version = '0.0.0' +license = 'Apache-2.0' +description = "Aiken contracts for project '${OWNER}/${NAME}'" + +[repository] +user = '${OWNER}' +project = '${NAME}' +platform = 'github' + +[[dependencies]] +name = 'aiken-lang/stdlib' +version = 'main' +source = 'github' diff --git a/src/main/resources/icons/aiken.png b/src/main/resources/icons/aiken.png new file mode 100644 index 0000000..2aae340 Binary files /dev/null and b/src/main/resources/icons/aiken.png differ diff --git a/src/main/resources/icons/aiken_module.png b/src/main/resources/icons/aiken_module.png new file mode 100644 index 0000000..2aae340 Binary files /dev/null and b/src/main/resources/icons/aiken_module.png differ diff --git a/src/main/resources/messages/AikenBundle.properties b/src/main/resources/messages/AikenBundle.properties new file mode 100644 index 0000000..5fe164f --- /dev/null +++ b/src/main/resources/messages/AikenBundle.properties @@ -0,0 +1,8 @@ +name=Aiken Language +settings.aiken.color.scheme.title=Aiken +settings.aiken.color.comment.normal=Comment//Comment +settings.aiken.color.comment.doc=Comment//Documentation +settings.aiken.color.comment.mod_doc=Comment//Module Documentation +settings.aiken.color.keyword=Keyword +settings.aiken.color.string=String +settings.aiken.color.identifier.type=Identifier//Type