This is an automated email from the ASF dual-hosted git repository. sergeykamov pushed a commit to branch NLPCRAFT-392 in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
commit f30a15f11edcb943fe71a5ea7dde541677362314 Author: Sergey Kamov <[email protected]> AuthorDate: Fri Aug 20 15:05:48 2021 +0300 WIP. --- nlpcraft-idl-idea-plugin/.gitignore | 3 + nlpcraft-idl-idea-plugin/build.gradle | 47 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59536 bytes .../gradle/wrapper/gradle-wrapper.properties | 5 + nlpcraft-idl-idea-plugin/gradlew | 185 +++++++ nlpcraft-idl-idea-plugin/gradlew.bat | 89 ++++ nlpcraft-idl-idea-plugin/settings.gradle | 3 + .../nlpcraft/idl/idea/plugin/SimpleLexer.java | 536 +++++++++++++++++++++ .../idl/idea/plugin/parser/SimpleParser.java | 123 +++++ .../idl/idea/plugin/psi/SimpleProperty.java | 21 + .../nlpcraft/idl/idea/plugin/psi/SimpleTypes.java | 28 ++ .../idl/idea/plugin/psi/SimpleVisitor.java | 22 + .../idea/plugin/psi/impl/SimplePropertyImpl.java | 58 +++ .../org/apache/nlpcraft/idl/idea/plugin/NCIdl.bnf | 31 ++ .../org/apache/nlpcraft/idl/idea/plugin/NCIdl.flex | 44 ++ .../nlpcraft/idl/idea/plugin/NCIdlFileType.java | 43 ++ .../nlpcraft/idl/idea/plugin/NCIdlLanguage.java | 14 + .../nlpcraft/idl/idea/plugin/NCPluginIcons.java | 13 + .../nlpcraft/idl/idea/plugin/SimpleAnnotator.java | 69 +++ .../nlpcraft/idl/idea/plugin/SimpleBlock.java | 62 +++ .../idea/plugin/SimpleChooseByNameContributor.java | 37 ++ .../idl/idea/plugin/SimpleCodeStyleSettings.java | 14 + .../plugin/SimpleCodeStyleSettingsProvider.java | 46 ++ .../idl/idea/plugin/SimpleColorSettingsPage.java | 78 +++ .../nlpcraft/idl/idea/plugin/SimpleCommenter.java | 40 ++ .../idea/plugin/SimpleCompletionContributor.java | 30 ++ .../idea/plugin/SimpleCreatePropertyQuickFix.java | 91 ++++ .../idea/plugin/SimpleDocumentationProvider.java | 96 ++++ .../idl/idea/plugin/SimpleFileTypeFactory.java | 21 + .../idl/idea/plugin/SimpleFindUsagesProvider.java | 68 +++ .../idl/idea/plugin/SimpleFoldingBuilder.java | 89 ++++ .../idea/plugin/SimpleFormattingModelBuilder.java | 39 ++ .../SimpleLanguageCodeStyleSettingsProvider.java | 45 ++ .../idl/idea/plugin/SimpleLexerAdapter.java | 13 + .../idl/idea/plugin/SimpleLineMarkerProvider.java | 52 ++ .../idl/idea/plugin/SimpleParserDefinition.java | 79 +++ .../plugin/SimpleRefactoringSupportProvider.java | 18 + .../nlpcraft/idl/idea/plugin/SimpleReference.java | 66 +++ .../idea/plugin/SimpleReferenceContributor.java | 42 ++ .../idea/plugin/SimpleStructureViewElement.java | 76 +++ .../idea/plugin/SimpleStructureViewFactory.java | 28 ++ .../idl/idea/plugin/SimpleStructureViewModel.java | 36 ++ .../idl/idea/plugin/SimpleSyntaxHighlighter.java | 62 +++ .../plugin/SimpleSyntaxHighlighterFactory.java | 19 + .../nlpcraft/idl/idea/plugin/SimpleUtil.java | 87 ++++ .../idl/idea/plugin/psi/SimpleElementFactory.java | 32 ++ .../idl/idea/plugin/psi/SimpleElementType.java | 16 + .../nlpcraft/idl/idea/plugin/psi/SimpleFile.java | 29 ++ .../idl/idea/plugin/psi/SimpleNamedElement.java | 9 + .../idl/idea/plugin/psi/SimpleTokenType.java | 21 + .../plugin/psi/impl/SimpleNamedElementImpl.java | 16 + .../idea/plugin/psi/impl/SimplePsiImplUtil.java | 83 ++++ .../src/main/resources/META-INF/plugin.xml | 74 +++ .../src/main/resources/META-INF/pluginIcon.svg | 58 +++ .../src/main/resources/icons/icon.png | Bin 0 -> 3905 bytes .../nlpcraft-idea-plugin/META-INF/plugin.xml | 45 ++ production/nlpcraft-idea-plugin/icons/icon.png | Bin 0 -> 2868 bytes .../plugin/SimpleCompletionContributor$1.class | Bin 0 -> 2392 bytes .../plugin/SimpleCompletionContributor$2.class | Bin 0 -> 2394 bytes .../idea/plugin/SimpleCompletionContributor.class | Bin 0 -> 2511 bytes .../nlpcraft/idea/plugin/SimpleFileType.class | Bin 0 -> 1249 bytes .../apache/nlpcraft/idea/plugin/SimpleIcons.class | Bin 0 -> 568 bytes .../nlpcraft/idea/plugin/SimpleLanguage.class | Bin 0 -> 487 bytes .../org/apache/nlpcraft/idea/plugin/nlpcraft.bnf | 21 + .../idea/plugin/parser/SimpleParserUtil.class | Bin 0 -> 383 bytes .../idea/plugin/psi/NlpCraftProperty.class | Bin 0 -> 184 bytes .../nlpcraft/idea/plugin/psi/NlpCraftVisitor.class | Bin 0 -> 1405 bytes .../idea/plugin/psi/SimpleElementType.class | Bin 0 -> 1121 bytes .../nlpcraft/idea/plugin/psi/SimpleTokenType.class | Bin 0 -> 1688 bytes .../idea/plugin/psi/SimpleTypes$Factory.class | Bin 0 -> 1562 bytes .../nlpcraft/idea/plugin/psi/SimpleTypes.class | Bin 0 -> 821 bytes .../plugin/psi/impl/NlpCraftPropertyImpl.class | Bin 0 -> 1839 bytes .../idea/plugin/psi/parser/SimpleParser.class | Bin 0 -> 4618 bytes 73 files changed, 3072 insertions(+) diff --git a/nlpcraft-idl-idea-plugin/.gitignore b/nlpcraft-idl-idea-plugin/.gitignore new file mode 100644 index 0000000..b6f374b --- /dev/null +++ b/nlpcraft-idl-idea-plugin/.gitignore @@ -0,0 +1,3 @@ +logs +.gradle +build \ No newline at end of file diff --git a/nlpcraft-idl-idea-plugin/build.gradle b/nlpcraft-idl-idea-plugin/build.gradle new file mode 100644 index 0000000..1244c33 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/build.gradle @@ -0,0 +1,47 @@ +// Copyright 2000-2021 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +plugins { + id 'java' + id 'org.jetbrains.intellij' version '1.1.4' +} + +group 'org.intellij.sdk' +version '2.0.0' + +sourceCompatibility = 11 + +repositories { + mavenCentral() +} + +test { + // This path value is machine-specific placeholder text. + // Set idea.home.path to the absolute path to the intellij-community source + // on your local machine. + // Use variants described in https://docs.gradle.org/current/userguide/build_environment.html + // for real world projects. + systemProperty "idea.home.path", "/Users/jhake/Documents/source/comm" +} + +// Include the generated files in the source set +sourceSets.main.java.srcDirs 'src/main/gen' + +dependencies { + testImplementation group: 'junit', name: 'junit', version: '4.13.2' +} + +// See https://github.com/JetBrains/gradle-intellij-plugin/ +intellij { + version = '2020.3.4' + plugins = ['com.intellij.java'] +} + +buildSearchableOptions { + enabled = false +} + +patchPluginXml { + version = project.version + sinceBuild = '203' + untilBuild = '212.*' +} \ No newline at end of file diff --git a/nlpcraft-idl-idea-plugin/gradle/wrapper/gradle-wrapper.jar b/nlpcraft-idl-idea-plugin/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..7454180 Binary files /dev/null and b/nlpcraft-idl-idea-plugin/gradle/wrapper/gradle-wrapper.jar differ diff --git a/nlpcraft-idl-idea-plugin/gradle/wrapper/gradle-wrapper.properties b/nlpcraft-idl-idea-plugin/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..a0f7639 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/nlpcraft-idl-idea-plugin/gradlew b/nlpcraft-idl-idea-plugin/gradlew new file mode 100755 index 0000000..744e882 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MSYS* | MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/nlpcraft-idl-idea-plugin/gradlew.bat b/nlpcraft-idl-idea-plugin/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/nlpcraft-idl-idea-plugin/settings.gradle b/nlpcraft-idl-idea-plugin/settings.gradle new file mode 100644 index 0000000..7b87523 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/settings.gradle @@ -0,0 +1,3 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +rootProject.name = 'nlpcraft-idl-idea-plugin' diff --git a/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/SimpleLexer.java b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/SimpleLexer.java new file mode 100644 index 0000000..a6b7cb8 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/SimpleLexer.java @@ -0,0 +1,536 @@ +/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */ + +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; + + +/** + * This class is a scanner generated by + * <a href="https://www.jflex.de/">JFlex</a> 1.7.0 + * from the specification file <tt>Simple.flex</tt> + */ +class SimpleLexer 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; + public static final int WAITING_VALUE = 2; + + /** + * 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, 1, 1 + }; + + /** + * Translates characters to character classes + * Chosen bits are [9, 6, 6] + * Total runtime size is 1568 bytes + */ + public static int ZZ_CMAP(int ch) { + return ZZ_CMAP_A[(ZZ_CMAP_Y[ZZ_CMAP_Z[ch>>12]|((ch>>6)&0x3f)]<<6)|(ch&0x3f)]; + } + + /* The ZZ_CMAP_Z table has 272 entries */ + static final char ZZ_CMAP_Z[] = zzUnpackCMap( + "\1\0\1\100\1\200\u010d\100"); + + /* The ZZ_CMAP_Y table has 192 entries */ + static final char ZZ_CMAP_Y[] = zzUnpackCMap( + "\1\0\1\1\1\2\175\3\1\4\77\3"); + + /* The ZZ_CMAP_A table has 320 entries */ + static final char ZZ_CMAP_A[] = zzUnpackCMap( + "\11\0\1\4\1\2\1\1\1\5\1\3\22\0\1\7\1\10\1\0\1\10\26\0\1\11\2\0\1\11\36\0\1"+ + "\6\50\0\1\1\242\0\2\1\26\0"); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\2\0\2\1\1\2\1\3\1\4\1\5\2\6\2\7"+ + "\1\3\1\7\1\0\2\4\1\0\1\2\2\6"; + + private static int [] zzUnpackAction() { + int [] result = new int[21]; + 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\12\0\24\0\36\0\50\0\62\0\74\0\106"+ + "\0\120\0\132\0\50\0\144\0\156\0\170\0\62\0\202"+ + "\0\214\0\156\0\132\0\226\0\240"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[21]; + 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\3\1\4\1\5\1\4\2\5\1\6\1\5\1\7"+ + "\1\10\1\11\1\12\1\13\1\12\1\14\1\13\1\15"+ + "\1\16\2\11\2\3\1\0\1\3\2\0\1\17\1\0"+ + "\1\3\1\0\1\3\1\4\1\5\1\4\2\5\1\17"+ + "\1\5\1\3\2\0\5\5\1\0\1\5\11\0\1\3"+ + "\2\0\2\7\1\0\1\3\2\20\1\21\1\20\1\7"+ + "\1\20\12\0\2\11\1\0\2\11\1\0\1\22\4\11"+ + "\1\23\1\5\2\23\1\5\1\22\1\23\3\11\1\24"+ + "\1\16\1\24\1\14\1\16\1\22\1\14\5\11\1\25"+ + "\6\11\1\0\1\5\1\16\1\5\2\16\1\0\1\16"+ + "\2\0\2\20\2\0\10\20\2\0\3\20\1\7\2\20"+ + "\1\11\1\24\1\5\2\24\1\5\1\22\1\24\7\11"+ + "\1\0\1\22\3\11"; + + private static int [] zzUnpackTrans() { + int [] result = new int[170]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String[] ZZ_ERROR_MSG = { + "Unknown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state <code>aState</code> + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\2\0\5\1\1\11\6\1\1\0\2\1\1\0\3\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[21]; + 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; + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + SimpleLexer(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 {@code false}, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + return true; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final CharSequence yytext() { + return zzBuffer.subSequence(zzStartRead, zzMarkedPos); + } + + + /** + * Returns the character at position {@code pos} from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer.charAt(zzStartRead+pos); + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occurred while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() { + if (!zzEOFDone) { + zzEOFDone = true; + + } + } + + + /** + * 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; + zzDoEOF(); + return null; + } + else { + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { yybegin(YYINITIAL); return SimpleTypes.KEY; + } + // fall through + case 8: break; + case 2: + { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; + } + // fall through + case 9: break; + case 3: + { return TokenType.BAD_CHARACTER; + } + // fall through + case 10: break; + case 4: + { yybegin(YYINITIAL); return SimpleTypes.COMMENT; + } + // fall through + case 11: break; + case 5: + { yybegin(WAITING_VALUE); return SimpleTypes.SEPARATOR; + } + // fall through + case 12: break; + case 6: + { yybegin(YYINITIAL); return SimpleTypes.VALUE; + } + // fall through + case 13: break; + case 7: + { yybegin(WAITING_VALUE); return TokenType.WHITE_SPACE; + } + // fall through + case 14: break; + default: + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/parser/SimpleParser.java b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/parser/SimpleParser.java new file mode 100644 index 0000000..18a8efd --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/parser/SimpleParser.java @@ -0,0 +1,123 @@ +// This is a generated file. Not intended for manual editing. +package org.apache.nlpcraft.idl.idea.plugin.parser; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.LightPsiParser; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiBuilder.Marker; +import com.intellij.lang.PsiParser; +import com.intellij.lang.parser.GeneratedParserUtilBase; +import com.intellij.psi.tree.IElementType; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; + +import static com.intellij.lang.parser.GeneratedParserUtilBase.*; + +@SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"}) +public class SimpleParser 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 simpleFile(b, l + 1); + } + + /* ********************************************************** */ + // property|COMMENT|CRLF + static boolean item_(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "item_")) return false; + boolean r; + Marker m = enter_section_(b); + r = property(b, l + 1); + if (!r) r = GeneratedParserUtilBase.consumeToken(b, SimpleTypes.COMMENT); + if (!r) r = GeneratedParserUtilBase.consumeToken(b, SimpleTypes.CRLF); + exit_section_(b, m, null, r); + return r; + } + + /* ********************************************************** */ + // (KEY? SEPARATOR VALUE?) | KEY + public static boolean property(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, SimpleTypes.PROPERTY, "<property>"); + r = property_0(b, l + 1); + if (!r) r = GeneratedParserUtilBase.consumeToken(b, SimpleTypes.KEY); + exit_section_(b, l, m, r, false, SimpleParser::recover_property); + return r; + } + + // KEY? SEPARATOR VALUE? + private static boolean property_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_0")) return false; + boolean r; + Marker m = enter_section_(b); + r = property_0_0(b, l + 1); + r = r && GeneratedParserUtilBase.consumeToken(b, SimpleTypes.SEPARATOR); + r = r && property_0_2(b, l + 1); + exit_section_(b, m, null, r); + return r; + } + + // KEY? + private static boolean property_0_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_0_0")) return false; + GeneratedParserUtilBase.consumeToken(b, SimpleTypes.KEY); + return true; + } + + // VALUE? + private static boolean property_0_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "property_0_2")) return false; + GeneratedParserUtilBase.consumeToken(b, SimpleTypes.VALUE); + return true; + } + + /* ********************************************************** */ + // !(KEY|SEPARATOR|COMMENT) + static boolean recover_property(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "recover_property")) return false; + boolean r; + Marker m = enter_section_(b, l, _NOT_); + r = !recover_property_0(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + // KEY|SEPARATOR|COMMENT + private static boolean recover_property_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "recover_property_0")) return false; + boolean r; + r = GeneratedParserUtilBase.consumeToken(b, SimpleTypes.KEY); + if (!r) r = GeneratedParserUtilBase.consumeToken(b, SimpleTypes.SEPARATOR); + if (!r) r = GeneratedParserUtilBase.consumeToken(b, SimpleTypes.COMMENT); + return r; + } + + /* ********************************************************** */ + // item_* + static boolean simpleFile(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "simpleFile")) return false; + while (true) { + int c = current_position_(b); + if (!item_(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "simpleFile", c)) break; + } + return true; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleProperty.java b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleProperty.java new file mode 100644 index 0000000..92b8291 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleProperty.java @@ -0,0 +1,21 @@ +// This is a generated file. Not intended for manual editing. +package org.apache.nlpcraft.idl.idea.plugin.psi; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.PsiElement; + +public interface SimpleProperty extends SimpleNamedElement { + + String getKey(); + + String getValue(); + + String getName(); + + PsiElement setName(String newName); + + PsiElement getNameIdentifier(); + + ItemPresentation getPresentation(); + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleTypes.java b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleTypes.java new file mode 100644 index 0000000..a1ee9ae --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleTypes.java @@ -0,0 +1,28 @@ +// This is a generated file. Not intended for manual editing. +package org.apache.nlpcraft.idl.idea.plugin.psi; + +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.IElementType; +import org.apache.nlpcraft.idl.idea.plugin.psi.impl.SimplePropertyImpl; + +public interface SimpleTypes { + + IElementType PROPERTY = new SimpleElementType("PROPERTY"); + + IElementType COMMENT = new SimpleTokenType("COMMENT"); + IElementType CRLF = new SimpleTokenType("CRLF"); + IElementType KEY = new SimpleTokenType("KEY"); + IElementType SEPARATOR = new SimpleTokenType("SEPARATOR"); + IElementType VALUE = new SimpleTokenType("VALUE"); + + class Factory { + public static PsiElement createElement(ASTNode node) { + IElementType type = node.getElementType(); + if (type == PROPERTY) { + return new SimplePropertyImpl(node); + } + throw new AssertionError("Unknown element type: " + type); + } + } +} diff --git a/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleVisitor.java b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleVisitor.java new file mode 100644 index 0000000..a6b30a3 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleVisitor.java @@ -0,0 +1,22 @@ +// This is a generated file. Not intended for manual editing. +package org.apache.nlpcraft.idl.idea.plugin.psi; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import org.jetbrains.annotations.NotNull; + +public class SimpleVisitor extends PsiElementVisitor { + + public void visitProperty(@NotNull SimpleProperty o) { + visitNamedElement(o); + } + + public void visitNamedElement(@NotNull SimpleNamedElement o) { + visitPsiElement(o); + } + + public void visitPsiElement(@NotNull PsiElement o) { + visitElement(o); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimplePropertyImpl.java b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimplePropertyImpl.java new file mode 100644 index 0000000..5ad1cd6 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/gen/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimplePropertyImpl.java @@ -0,0 +1,58 @@ +// This is a generated file. Not intended for manual editing. +package org.apache.nlpcraft.idl.idea.plugin.psi.impl; + +import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleVisitor; +import org.jetbrains.annotations.NotNull; + +public class SimplePropertyImpl extends SimpleNamedElementImpl implements SimpleProperty { + + public SimplePropertyImpl(@NotNull ASTNode node) { + super(node); + } + + public void accept(@NotNull SimpleVisitor visitor) { + visitor.visitProperty(this); + } + + @Override + public void accept(@NotNull PsiElementVisitor visitor) { + if (visitor instanceof SimpleVisitor) accept((SimpleVisitor)visitor); + else super.accept(visitor); + } + + @Override + public String getKey() { + return SimplePsiImplUtil.getKey(this); + } + + @Override + public String getValue() { + return SimplePsiImplUtil.getValue(this); + } + + @Override + public String getName() { + return SimplePsiImplUtil.getName(this); + } + + @Override + public PsiElement setName(String newName) { + return SimplePsiImplUtil.setName(this, newName); + } + + @Override + public PsiElement getNameIdentifier() { + return SimplePsiImplUtil.getNameIdentifier(this); + } + + @Override + public ItemPresentation getPresentation() { + return SimplePsiImplUtil.getPresentation(this); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdl.bnf b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdl.bnf new file mode 100644 index 0000000..661239d --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdl.bnf @@ -0,0 +1,31 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +{ + parserClass="org.apache.nlpcraft.idl.idea.plugin.parser.SimpleParser" + + extends="com.intellij.extapi.psi.ASTWrapperPsiElement" + + psiClassPrefix="Simple" + psiImplClassSuffix="Impl" + psiPackage="org.intellij.sdk.language.psi" + psiImplPackage="org.intellij.sdk.language.psi.impl" + + elementTypeHolderClass="org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes" + elementTypeClass="org.apache.nlpcraft.idl.idea.plugin.psi.SimpleElementType" + tokenTypeClass="org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTokenType" + + psiImplUtilClass="org.apache.nlpcraft.idl.idea.plugin.psi.impl.SimplePsiImplUtil" +} + +simpleFile ::= item_* + +private item_ ::= (property|COMMENT|CRLF) + +property ::= (KEY? SEPARATOR VALUE?) | KEY { + pin=3 + recoverWhile="recover_property" + mixin="org.apache.nlpcraft.idl.idea.plugin.psi.impl.SimpleNamedElementImpl" + implements="org.apache.nlpcraft.idl.idea.plugin.psi.SimpleNamedElement" + methods=[getKey getValue getName setName getNameIdentifier getPresentation] +} + +private recover_property ::= !(KEY|SEPARATOR|COMMENT) \ No newline at end of file diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdl.flex b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdl.flex new file mode 100644 index 0000000..18fd08b --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdl.flex @@ -0,0 +1,44 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.intellij.sdk.language; + +import com.intellij.psi.tree.IElementType; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; +import com.intellij.psi.TokenType; + +%% + +%class SimpleLexer +%implements FlexLexer +%unicode +%function advance +%type IElementType +%eof{ return; +%eof} + +CRLF=\R +WHITE_SPACE=[\ \n\t\f] +FIRST_VALUE_CHARACTER=[^ \n\f\\] | "\\"{CRLF} | "\\". +VALUE_CHARACTER=[^\n\f\\] | "\\"{CRLF} | "\\". +END_OF_LINE_COMMENT=("#"|"!")[^\r\n]* +SEPARATOR=[:=] +KEY_CHARACTER=[^:=\ \n\t\f\\] | "\\ " + +%state WAITING_VALUE + +%% + +<YYINITIAL> {END_OF_LINE_COMMENT} { yybegin(YYINITIAL); return SimpleTypes.COMMENT; } + +<YYINITIAL> {KEY_CHARACTER}+ { yybegin(YYINITIAL); return SimpleTypes.KEY; } + +<YYINITIAL> {SEPARATOR} { yybegin(WAITING_VALUE); return SimpleTypes.SEPARATOR; } + +<WAITING_VALUE> {CRLF}({CRLF}|{WHITE_SPACE})+ { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; } + +<WAITING_VALUE> {WHITE_SPACE}+ { yybegin(WAITING_VALUE); return TokenType.WHITE_SPACE; } + +<WAITING_VALUE> {FIRST_VALUE_CHARACTER}{VALUE_CHARACTER}* { yybegin(YYINITIAL); return SimpleTypes.VALUE; } + +({CRLF}|{WHITE_SPACE})+ { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; } + +[^] { return TokenType.BAD_CHARACTER; } diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdlFileType.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdlFileType.java new file mode 100644 index 0000000..450096d --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdlFileType.java @@ -0,0 +1,43 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.openapi.fileTypes.LanguageFileType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class NCIdlFileType extends LanguageFileType { + + public static final NCIdlFileType INSTANCE = new NCIdlFileType(); + + private NCIdlFileType() { + super(NCIdlLanguage.INSTANCE); + } + + @NotNull + @Override + public String getName() { + return "NlpCraft IDL"; + } + + @NotNull + @Override + public String getDescription() { + return "NlpCraft IDL"; + } + + @NotNull + @Override + public String getDefaultExtension() { + return "idl"; + } + + @Nullable + @Override + public Icon getIcon() { + return NCPluginIcons.FILE; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdlLanguage.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdlLanguage.java new file mode 100644 index 0000000..5877888 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCIdlLanguage.java @@ -0,0 +1,14 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lang.Language; + +public class NCIdlLanguage extends Language { + + public static final NCIdlLanguage INSTANCE = new NCIdlLanguage(); + + private NCIdlLanguage() { + super("NlpCraftIdl"); + } +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCPluginIcons.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCPluginIcons.java new file mode 100644 index 0000000..e15a0da --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/NCPluginIcons.java @@ -0,0 +1,13 @@ +// Copyright 2000-2021 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +public class NCPluginIcons { + + public static final Icon FILE = IconLoader.getIcon("/icons/icon.png", NCPluginIcons.class); + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleAnnotator.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleAnnotator.java new file mode 100644 index 0000000..e50d8a2 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleAnnotator.java @@ -0,0 +1,69 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLiteralExpression; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class SimpleAnnotator implements Annotator { + + // Define strings for the Simple language prefix - used for annotations, line markers, etc. + public static final String SIMPLE_PREFIX_STR = "simple"; + public static final String SIMPLE_SEPARATOR_STR = ":"; + + @Override + public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { + // Ensure the Psi Element is an expression + if (!(element instanceof PsiLiteralExpression)) { + return; + } + + // Ensure the Psi element contains a string that starts with the prefix and separator + PsiLiteralExpression literalExpression = (PsiLiteralExpression) element; + String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; + if ((value == null) || !value.startsWith(SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR)) { + return; + } + + // Define the text ranges (start is inclusive, end is exclusive) + // "simple:key" + // 01234567890 + TextRange prefixRange = TextRange.from(element.getTextRange().getStartOffset(), SIMPLE_PREFIX_STR.length() + 1); + TextRange separatorRange = TextRange.from(prefixRange.getEndOffset(), SIMPLE_SEPARATOR_STR.length()); + TextRange keyRange = new TextRange(separatorRange.getEndOffset(), element.getTextRange().getEndOffset() - 1); + + // highlight "simple" prefix and ":" separator + holder.newSilentAnnotation(HighlightSeverity.INFORMATION) + .range(prefixRange).textAttributes(DefaultLanguageHighlighterColors.KEYWORD).create(); + holder.newSilentAnnotation(HighlightSeverity.INFORMATION) + .range(separatorRange).textAttributes(SimpleSyntaxHighlighter.SEPARATOR).create(); + + + // Get the list of properties for given key + String key = value.substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length()); + List<SimpleProperty> properties = SimpleUtil.findProperties(element.getProject(), key); + if (properties.isEmpty()) { + holder.newAnnotation(HighlightSeverity.ERROR, "Unresolved property") + .range(keyRange) + .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL) + // ** Tutorial step 18.3 - Add a quick fix for the string containing possible properties + .withFix(new SimpleCreatePropertyQuickFix(key)) + .create(); + } else { + // Found at least one property, force the text attributes to Simple syntax value character + holder.newSilentAnnotation(HighlightSeverity.INFORMATION) + .range(keyRange).textAttributes(SimpleSyntaxHighlighter.VALUE).create(); + } + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleBlock.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleBlock.java new file mode 100644 index 0000000..95c3fa3 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleBlock.java @@ -0,0 +1,62 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.formatting.Alignment; +import com.intellij.formatting.Block; +import com.intellij.formatting.Indent; +import com.intellij.formatting.Spacing; +import com.intellij.formatting.SpacingBuilder; +import com.intellij.formatting.Wrap; +import com.intellij.formatting.WrapType; +import com.intellij.lang.ASTNode; +import com.intellij.psi.TokenType; +import com.intellij.psi.formatter.common.AbstractBlock; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class SimpleBlock extends AbstractBlock { + + private final SpacingBuilder spacingBuilder; + + protected SimpleBlock(@NotNull ASTNode node, @Nullable Wrap wrap, @Nullable Alignment alignment, + SpacingBuilder spacingBuilder) { + super(node, wrap, alignment); + this.spacingBuilder = spacingBuilder; + } + + @Override + protected List<Block> buildChildren() { + List<Block> blocks = new ArrayList<>(); + ASTNode child = myNode.getFirstChildNode(); + while (child != null) { + if (child.getElementType() != TokenType.WHITE_SPACE) { + Block block = new SimpleBlock(child, Wrap.createWrap(WrapType.NONE, false), Alignment.createAlignment(), + spacingBuilder); + blocks.add(block); + } + child = child.getTreeNext(); + } + return blocks; + } + + @Override + public Indent getIndent() { + return Indent.getNoneIndent(); + } + + @Nullable + @Override + public Spacing getSpacing(@Nullable Block child1, @NotNull Block child2) { + return spacingBuilder.getSpacing(this, child1, child2); + } + + @Override + public boolean isLeaf() { + return myNode.getFirstChildNode() == null; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleChooseByNameContributor.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleChooseByNameContributor.java new file mode 100644 index 0000000..d7ebcaf --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleChooseByNameContributor.java @@ -0,0 +1,37 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.navigation.ChooseByNameContributor; +import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.project.Project; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class SimpleChooseByNameContributor implements ChooseByNameContributor { + + @NotNull + @Override + public String[] getNames(Project project, boolean includeNonProjectItems) { + List<SimpleProperty> properties = SimpleUtil.findProperties(project); + List<String> names = new ArrayList<>(properties.size()); + for (SimpleProperty property : properties) { + if (property.getKey() != null && property.getKey().length() > 0) { + names.add(property.getKey()); + } + } + return names.toArray(new String[names.size()]); + } + + @NotNull + @Override + public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) { + // TODO: include non project items + List<SimpleProperty> properties = SimpleUtil.findProperties(project, name); + return properties.toArray(new NavigationItem[properties.size()]); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCodeStyleSettings.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCodeStyleSettings.java new file mode 100644 index 0000000..59feb63 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCodeStyleSettings.java @@ -0,0 +1,14 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; + +public class SimpleCodeStyleSettings extends CustomCodeStyleSettings { + + public SimpleCodeStyleSettings(CodeStyleSettings settings) { + super("SimpleCodeStyleSettings", settings); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCodeStyleSettingsProvider.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCodeStyleSettingsProvider.java new file mode 100644 index 0000000..e1fc362 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCodeStyleSettingsProvider.java @@ -0,0 +1,46 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.application.options.CodeStyleAbstractConfigurable; +import com.intellij.application.options.CodeStyleAbstractPanel; +import com.intellij.application.options.TabbedLanguageCodeStylePanel; +import com.intellij.psi.codeStyle.CodeStyleConfigurable; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsProvider; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SimpleCodeStyleSettingsProvider extends CodeStyleSettingsProvider { + + @Override + public CustomCodeStyleSettings createCustomSettings(CodeStyleSettings settings) { + return new SimpleCodeStyleSettings(settings); + } + + @Nullable + @Override + public String getConfigurableDisplayName() { + return "Simple"; + } + + @NotNull + public CodeStyleConfigurable createConfigurable(@NotNull CodeStyleSettings settings, @NotNull CodeStyleSettings modelSettings) { + return new CodeStyleAbstractConfigurable(settings, modelSettings, this.getConfigurableDisplayName()) { + @Override + protected CodeStyleAbstractPanel createPanel(CodeStyleSettings settings) { + return new SimpleCodeStyleMainPanel(getCurrentSettings(), settings); + } + }; + } + + private static class SimpleCodeStyleMainPanel extends TabbedLanguageCodeStylePanel { + + public SimpleCodeStyleMainPanel(CodeStyleSettings currentSettings, CodeStyleSettings settings) { + super(NCIdlLanguage.INSTANCE, currentSettings, settings); + } + + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleColorSettingsPage.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleColorSettingsPage.java new file mode 100644 index 0000000..ce2aef0 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleColorSettingsPage.java @@ -0,0 +1,78 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.ColorDescriptor; +import com.intellij.openapi.options.colors.ColorSettingsPage; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Map; + +public class SimpleColorSettingsPage implements ColorSettingsPage { + + private static final AttributesDescriptor[] DESCRIPTORS = new AttributesDescriptor[]{ + new AttributesDescriptor("Key", SimpleSyntaxHighlighter.KEY), + new AttributesDescriptor("Separator", SimpleSyntaxHighlighter.SEPARATOR), + new AttributesDescriptor("Value", SimpleSyntaxHighlighter.VALUE), + new AttributesDescriptor("Bad Value", SimpleSyntaxHighlighter.BAD_CHARACTER) + }; + + @Nullable + @Override + public Icon getIcon() { + return NCPluginIcons.FILE; + } + + @NotNull + @Override + public SyntaxHighlighter getHighlighter() { + return new SimpleSyntaxHighlighter(); + } + + @NotNull + @Override + public String getDemoText() { + return "# You are reading the \".properties\" entry.\n" + + "! The exclamation mark can also mark text as comments.\n" + + "website = https://en.wikipedia.org/\n" + + "language = English\n" + + "# The backslash below tells the application to continue reading\n" + + "# the value onto the next line.\n" + + "message = Welcome to \\\n" + + " Wikipedia!\n" + + "# Add spaces to the key\n" + + "key\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n" + + "# Unicode\n" + + "tab : \\u0009"; + } + + @Nullable + @Override + public Map<String, TextAttributesKey> getAdditionalHighlightingTagToDescriptorMap() { + return null; + } + + @NotNull + @Override + public AttributesDescriptor[] getAttributeDescriptors() { + return DESCRIPTORS; + } + + @NotNull + @Override + public ColorDescriptor[] getColorDescriptors() { + return ColorDescriptor.EMPTY_ARRAY; + } + + @NotNull + @Override + public String getDisplayName() { + return "Simple"; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCommenter.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCommenter.java new file mode 100644 index 0000000..cb14f45 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCommenter.java @@ -0,0 +1,40 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lang.Commenter; +import org.jetbrains.annotations.Nullable; + +public class SimpleCommenter implements Commenter { + + @Nullable + @Override + public String getLineCommentPrefix() { + return "#"; + } + + @Nullable + @Override + public String getBlockCommentPrefix() { + return ""; + } + + @Nullable + @Override + public String getBlockCommentSuffix() { + return null; + } + + @Nullable + @Override + public String getCommentedBlockCommentPrefix() { + return null; + } + + @Nullable + @Override + public String getCommentedBlockCommentSuffix() { + return null; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCompletionContributor.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCompletionContributor.java new file mode 100644 index 0000000..eec5082 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCompletionContributor.java @@ -0,0 +1,30 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.codeInsight.completion.CompletionContributor; +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionProvider; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.completion.CompletionType; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.util.ProcessingContext; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; +import org.jetbrains.annotations.NotNull; + +public class SimpleCompletionContributor extends CompletionContributor { + + public SimpleCompletionContributor() { + extend(CompletionType.BASIC, PlatformPatterns.psiElement(SimpleTypes.VALUE), + new CompletionProvider<CompletionParameters>() { + public void addCompletions(@NotNull CompletionParameters parameters, + @NotNull ProcessingContext context, + @NotNull CompletionResultSet resultSet) { + resultSet.addElement(LookupElementBuilder.create("Hello")); + } + } + ); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCreatePropertyQuickFix.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCreatePropertyQuickFix.java new file mode 100644 index 0000000..63e9fcd --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleCreatePropertyQuickFix.java @@ -0,0 +1,91 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.codeInsight.intention.impl.BaseIntentionAction; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileChooser.FileChooser; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.search.FileTypeIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.IncorrectOperationException; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleElementFactory; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleFile; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +class SimpleCreatePropertyQuickFix extends BaseIntentionAction { + + private final String key; + + SimpleCreatePropertyQuickFix(String key) { + this.key = key; + } + + @NotNull + @Override + public String getText() { + return "Create property '" + key + "'"; + } + + @NotNull + @Override + public String getFamilyName() { + return "Create property"; + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return true; + } + + @Override + public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws + IncorrectOperationException { + ApplicationManager.getApplication().invokeLater(() -> { + Collection<VirtualFile> virtualFiles = + FileTypeIndex.getFiles(NCIdlFileType.INSTANCE, GlobalSearchScope.allScope(project)); + if (virtualFiles.size() == 1) { + createProperty(project, virtualFiles.iterator().next()); + } else { + final FileChooserDescriptor descriptor = + FileChooserDescriptorFactory.createSingleFileDescriptor(NCIdlFileType.INSTANCE); + descriptor.setRoots(ProjectUtil.guessProjectDir(project)); + final VirtualFile file1 = FileChooser.chooseFile(descriptor, project, null); + if (file1 != null) { + createProperty(project, file1); + } + } + }); + } + + private void createProperty(final Project project, final VirtualFile file) { + WriteCommandAction.writeCommandAction(project).run(() -> { + SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(file); + ASTNode lastChildNode = simpleFile.getNode().getLastChildNode(); + // TODO: Add another check for CRLF + if (lastChildNode != null/* && !lastChildNode.getElementType().equals(SimpleTypes.CRLF)*/) { + simpleFile.getNode().addChild(SimpleElementFactory.createCRLF(project).getNode()); + } + // IMPORTANT: change spaces to escaped spaces or the new node will only have the first word for the key + SimpleProperty property = SimpleElementFactory.createProperty(project, key.replaceAll(" ", "\\\\ "), ""); + simpleFile.getNode().addChild(property.getNode()); + ((Navigatable) property.getLastChild().getNavigationElement()).navigate(true); + FileEditorManager.getInstance(project).getSelectedTextEditor().getCaretModel().moveCaretRelatively(2, 0, false, false, false); + }); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleDocumentationProvider.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleDocumentationProvider.java new file mode 100644 index 0000000..25f514a --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleDocumentationProvider.java @@ -0,0 +1,96 @@ +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lang.documentation.AbstractDocumentationProvider; +import com.intellij.lang.documentation.DocumentationMarkup; +import com.intellij.psi.PsiElement; +import com.intellij.psi.presentation.java.SymbolPresentationUtil; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class SimpleDocumentationProvider extends AbstractDocumentationProvider { + + /** + * For the Simple Language, we don't have online documentation. However, if your language provides + * references pages online, URLs for the element can be returned here. + */ + @Override + public @Nullable List<String> getUrlFor(PsiElement element, PsiElement originalElement) { + return null; + } + + /** + * Extracts the key, value, file and documentation comment of a Simple key/value entry and returns + * a formatted representation of the information. + */ + @Override + public @Nullable String generateDoc(PsiElement element, @Nullable PsiElement originalElement) { + if (element instanceof SimpleProperty) { + final String key = ((SimpleProperty) element).getKey(); + final String value = ((SimpleProperty) element).getValue(); + final String file = SymbolPresentationUtil.getFilePathPresentation(element.getContainingFile()); + final String docComment = SimpleUtil.findDocumentationComment((SimpleProperty) element); + + return renderFullDoc(key, value, file, docComment); + } + return null; + } + + /** + * Provides the information in which file the Simple language key/value is defined. + */ + @Override + public @Nullable String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) { + if (element instanceof SimpleProperty) { + final String key = ((SimpleProperty) element).getKey(); + final String file = SymbolPresentationUtil.getFilePathPresentation(element.getContainingFile()); + return "\"" + key + "\" in " + file; + } + return null; + } + + /** + * Provides documentation when a Simple Language element is hovered with the mouse. + */ + @Override + public @Nullable String generateHoverDoc(@NotNull PsiElement element, @Nullable PsiElement originalElement) { + return generateDoc(element, originalElement); + } + + /** + * Creates a key/value row for the rendered documentation. + */ + private void addKeyValueSection(String key, String value, StringBuilder sb) { + sb.append(DocumentationMarkup.SECTION_HEADER_START); + sb.append(key); + sb.append(DocumentationMarkup.SECTION_SEPARATOR); + sb.append("<p>"); + sb.append(value); + sb.append(DocumentationMarkup.SECTION_END); + } + + /** + * Creates the formatted documentation using {@link DocumentationMarkup}. See the Java doc of + * {@link com.intellij.lang.documentation.DocumentationProvider#generateDoc(PsiElement, PsiElement)} for more + * information about building the layout. + */ + private String renderFullDoc(String key, String value, String file, String docComment) { + StringBuilder sb = new StringBuilder(); + sb.append(DocumentationMarkup.DEFINITION_START); + sb.append("Simple Property"); + sb.append(DocumentationMarkup.DEFINITION_END); + sb.append(DocumentationMarkup.CONTENT_START); + sb.append(value); + sb.append(DocumentationMarkup.CONTENT_END); + sb.append(DocumentationMarkup.SECTIONS_START); + addKeyValueSection("Key:", key, sb); + addKeyValueSection("Value:", value, sb); + addKeyValueSection("File:", file, sb); + addKeyValueSection("Comment:", docComment, sb); + sb.append(DocumentationMarkup.SECTIONS_END); + return sb.toString(); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFileTypeFactory.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFileTypeFactory.java new file mode 100644 index 0000000..d9d6487 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFileTypeFactory.java @@ -0,0 +1,21 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.openapi.fileTypes.FileTypeConsumer; +import com.intellij.openapi.fileTypes.FileTypeFactory; +import org.jetbrains.annotations.NotNull; + +/** + * Note: This class is only used with the fileTypeFactory extension point + * for versions of the IntelliJ Platform prior to v2019.2. + */ +@SuppressWarnings("deprecation") +public class SimpleFileTypeFactory extends FileTypeFactory { + + @Override + public void createFileTypes(@NotNull FileTypeConsumer fileTypeConsumer) { + fileTypeConsumer.consume(NCIdlFileType.INSTANCE); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFindUsagesProvider.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFindUsagesProvider.java new file mode 100644 index 0000000..788be22 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFindUsagesProvider.java @@ -0,0 +1,68 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lang.cacheBuilder.DefaultWordsScanner; +import com.intellij.lang.cacheBuilder.WordsScanner; +import com.intellij.lang.findUsages.FindUsagesProvider; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; +import com.intellij.psi.tree.TokenSet; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SimpleFindUsagesProvider implements FindUsagesProvider { + + @Nullable + @Override + public WordsScanner getWordsScanner() { + return new DefaultWordsScanner(new SimpleLexerAdapter(), + TokenSet.create(SimpleTypes.KEY), + TokenSet.create(SimpleTypes.COMMENT), + TokenSet.EMPTY); + } + + @Override + public boolean canFindUsagesFor(@NotNull PsiElement psiElement) { + return psiElement instanceof PsiNamedElement; + } + + @Nullable + @Override + public String getHelpId(@NotNull PsiElement psiElement) { + return null; + } + + @NotNull + @Override + public String getType(@NotNull PsiElement element) { + if (element instanceof SimpleProperty) { + return "simple property"; + } else { + return ""; + } + } + + @NotNull + @Override + public String getDescriptiveName(@NotNull PsiElement element) { + if (element instanceof SimpleProperty) { + return ((SimpleProperty) element).getKey(); + } else { + return ""; + } + } + + @NotNull + @Override + public String getNodeText(@NotNull PsiElement element, boolean useFullName) { + if (element instanceof SimpleProperty) { + return ((SimpleProperty) element).getKey() + SimpleAnnotator.SIMPLE_SEPARATOR_STR + ((SimpleProperty) element).getValue(); + } else { + return ""; + } + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFoldingBuilder.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFoldingBuilder.java new file mode 100644 index 0000000..bbe86d9 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFoldingBuilder.java @@ -0,0 +1,89 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.folding.FoldingBuilderEx; +import com.intellij.lang.folding.FoldingDescriptor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.FoldingGroup; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLiteralExpression; +import com.intellij.psi.util.PsiTreeUtil; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware { + + @NotNull + @Override + public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { + // Initialize the group of folding regions that will expand/collapse together. + FoldingGroup group = FoldingGroup.newGroup(SimpleAnnotator.SIMPLE_PREFIX_STR); + // Initialize the list of folding regions + List<FoldingDescriptor> descriptors = new ArrayList<>(); + // Get a collection of the literal expressions in the document below root + Collection<PsiLiteralExpression> literalExpressions = + PsiTreeUtil.findChildrenOfType(root, PsiLiteralExpression.class); + // Evaluate the collection + for (final PsiLiteralExpression literalExpression : literalExpressions) { + String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; + if (value != null && value.startsWith(SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR)) { + Project project = literalExpression.getProject(); + String key = value.substring( + SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() + ); + // Get a list of all properties for a given key in the project + final List<SimpleProperty> properties = SimpleUtil.findProperties(project, key); + if (properties.size() == 1) { + // Add a folding descriptor for the literal expression at this node. + descriptors.add(new FoldingDescriptor(literalExpression.getNode(), + new TextRange(literalExpression.getTextRange().getStartOffset() + 1, + literalExpression.getTextRange().getEndOffset() - 1), + group)); + } + } + } + return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); + } + + /** + * Gets the Simple Language 'value' string corresponding to the 'key' + * + * @param node Node corresponding to PsiLiteralExpression containing a string in the format + * SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR + Key, where Key is + * defined by the Simple language file. + */ + @Nullable + @Override + public String getPlaceholderText(@NotNull ASTNode node) { + String retTxt = "..."; + if (node.getPsi() instanceof PsiLiteralExpression) { + PsiLiteralExpression nodeElement = (PsiLiteralExpression) node.getPsi(); + String key = ((String) nodeElement.getValue()).substring( + SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() + ); + final List<SimpleProperty> properties = SimpleUtil.findProperties(nodeElement.getProject(), key); + String place = properties.get(0).getValue(); + // IMPORTANT: keys can come with no values, so a test for null is needed + // IMPORTANT: Convert embedded \n to backslash n, so that the string will look + // like it has LF embedded in it and embedded " to escaped " + return place == null ? retTxt : place.replaceAll("\n", "\\n").replaceAll("\"", "\\\\\""); + } + return retTxt; + } + + @Override + public boolean isCollapsedByDefault(@NotNull ASTNode node) { + return true; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFormattingModelBuilder.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFormattingModelBuilder.java new file mode 100644 index 0000000..81152de --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleFormattingModelBuilder.java @@ -0,0 +1,39 @@ +// Copyright 2000-2021 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.formatting.Alignment; +import com.intellij.formatting.FormattingContext; +import com.intellij.formatting.FormattingModel; +import com.intellij.formatting.FormattingModelBuilder; +import com.intellij.formatting.FormattingModelProvider; +import com.intellij.formatting.SpacingBuilder; +import com.intellij.formatting.Wrap; +import com.intellij.formatting.WrapType; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; +import org.jetbrains.annotations.NotNull; + +public class SimpleFormattingModelBuilder implements FormattingModelBuilder { + + private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) { + return new SpacingBuilder(settings, NCIdlLanguage.INSTANCE) + .around(SimpleTypes.SEPARATOR) + .spaceIf(settings.getCommonSettings(NCIdlLanguage.INSTANCE.getID()).SPACE_AROUND_ASSIGNMENT_OPERATORS) + .before(SimpleTypes.PROPERTY) + .none(); + } + + @Override + public @NotNull FormattingModel createModel(@NotNull FormattingContext formattingContext) { + final CodeStyleSettings codeStyleSettings = formattingContext.getCodeStyleSettings(); + return FormattingModelProvider + .createFormattingModelForPsiFile(formattingContext.getContainingFile(), + new SimpleBlock(formattingContext.getNode(), + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + createSpaceBuilder(codeStyleSettings)), + codeStyleSettings); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLanguageCodeStyleSettingsProvider.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLanguageCodeStyleSettingsProvider.java new file mode 100644 index 0000000..5986b50 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLanguageCodeStyleSettingsProvider.java @@ -0,0 +1,45 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lang.Language; +import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable; +import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider; +import org.jetbrains.annotations.NotNull; + +public class SimpleLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider { + + @NotNull + @Override + public Language getLanguage() { + return NCIdlLanguage.INSTANCE; + } + + @Override + public void customizeSettings(@NotNull CodeStyleSettingsCustomizable consumer, @NotNull SettingsType settingsType) { + if (settingsType == SettingsType.SPACING_SETTINGS) { + consumer.showStandardOptions("SPACE_AROUND_ASSIGNMENT_OPERATORS"); + consumer.renameStandardOption("SPACE_AROUND_ASSIGNMENT_OPERATORS", "Separator"); + } else if (settingsType == SettingsType.BLANK_LINES_SETTINGS) { + consumer.showStandardOptions("KEEP_BLANK_LINES_IN_CODE"); + } + } + + @Override + public String getCodeSample(@NotNull SettingsType settingsType) { + return "# You are reading the \".properties\" entry.\n" + + "! The exclamation mark can also mark text as comments.\n" + + "website = https://en.wikipedia.org/\n" + + "\n" + + "language = English\n" + + "# The backslash below tells the application to continue reading\n" + + "# the value onto the next line.\n" + + "message = Welcome to \\\n" + + " Wikipedia!\n" + + "# Add spaces to the key\n" + + "key\\ with\\ spaces = This is the value that could be looked up with the key \"key with spaces\".\n" + + "# Unicode\n" + + "tab : \\u0009"; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLexerAdapter.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLexerAdapter.java new file mode 100644 index 0000000..7775af5 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLexerAdapter.java @@ -0,0 +1,13 @@ +// Copyright 2000-2021 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lexer.FlexAdapter; + +public class SimpleLexerAdapter extends FlexAdapter { + + public SimpleLexerAdapter() { + super(new SimpleLexer(null)); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLineMarkerProvider.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLineMarkerProvider.java new file mode 100644 index 0000000..9005811 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleLineMarkerProvider.java @@ -0,0 +1,52 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.codeInsight.daemon.RelatedItemLineMarkerInfo; +import com.intellij.codeInsight.daemon.RelatedItemLineMarkerProvider; +import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLiteralExpression; +import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.List; + +public class SimpleLineMarkerProvider extends RelatedItemLineMarkerProvider { + + @Override + protected void collectNavigationMarkers(@NotNull PsiElement element, + @NotNull Collection<? super RelatedItemLineMarkerInfo<?>> result) { + // This must be an element with a literal expression as a parent + if (!(element instanceof PsiJavaTokenImpl) || !(element.getParent() instanceof PsiLiteralExpression)) { + return; + } + + // The literal expression must start with the Simple language literal expression + PsiLiteralExpression literalExpression = (PsiLiteralExpression) element.getParent(); + String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null; + if ((value == null) || + !value.startsWith(SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR)) { + return; + } + + // Get the Simple language property usage + Project project = element.getProject(); + String possibleProperties = value.substring( + SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() + ); + final List<SimpleProperty> properties = SimpleUtil.findProperties(project, possibleProperties); + if (properties.size() > 0) { + // Add the property to a collection of line marker info + NavigationGutterIconBuilder<PsiElement> builder = + NavigationGutterIconBuilder.create(NCPluginIcons.FILE) + .setTargets(properties) + .setTooltipText("Navigate to Simple language property"); + result.add(builder.createLineMarkerInfo(element)); + } + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleParserDefinition.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleParserDefinition.java new file mode 100644 index 0000000..d5666b7 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleParserDefinition.java @@ -0,0 +1,79 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +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.IFileElementType; +import com.intellij.psi.tree.TokenSet; +import org.apache.nlpcraft.idl.idea.plugin.parser.SimpleParser; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleFile; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; +import org.jetbrains.annotations.NotNull; + +public class SimpleParserDefinition implements ParserDefinition { + + public static final TokenSet WHITE_SPACES = TokenSet.create(TokenType.WHITE_SPACE); + public static final TokenSet COMMENTS = TokenSet.create(SimpleTypes.COMMENT); + + public static final IFileElementType FILE = new IFileElementType(NCIdlLanguage.INSTANCE); + + @NotNull + @Override + public Lexer createLexer(Project project) { + return new SimpleLexerAdapter(); + } + + @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 SimpleParser(); + } + + @Override + public IFileElementType getFileNodeType() { + return FILE; + } + + @Override + public PsiFile createFile(FileViewProvider viewProvider) { + return new SimpleFile(viewProvider); + } + + @Override + public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) { + return SpaceRequirements.MAY; + } + + @NotNull + @Override + public PsiElement createElement(ASTNode node) { + return SimpleTypes.Factory.createElement(node); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleRefactoringSupportProvider.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleRefactoringSupportProvider.java new file mode 100644 index 0000000..297b307 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleRefactoringSupportProvider.java @@ -0,0 +1,18 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lang.refactoring.RefactoringSupportProvider; +import com.intellij.psi.PsiElement; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SimpleRefactoringSupportProvider extends RefactoringSupportProvider { + + @Override + public boolean isMemberInplaceRenameAvailable(@NotNull PsiElement elementToRename, @Nullable PsiElement context) { + return (elementToRename instanceof SimpleProperty); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleReference.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleReference.java new file mode 100644 index 0000000..7e7ca74 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleReference.java @@ -0,0 +1,66 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementResolveResult; +import com.intellij.psi.PsiPolyVariantReference; +import com.intellij.psi.PsiReferenceBase; +import com.intellij.psi.ResolveResult; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class SimpleReference extends PsiReferenceBase<PsiElement> implements PsiPolyVariantReference { + + private final String key; + + public SimpleReference(@NotNull PsiElement element, TextRange textRange) { + super(element, textRange); + key = element.getText().substring(textRange.getStartOffset(), textRange.getEndOffset()); + } + + @NotNull + @Override + public ResolveResult[] multiResolve(boolean incompleteCode) { + Project project = myElement.getProject(); + final List<SimpleProperty> properties = SimpleUtil.findProperties(project, key); + List<ResolveResult> results = new ArrayList<>(); + for (SimpleProperty property : properties) { + results.add(new PsiElementResolveResult(property)); + } + return results.toArray(new ResolveResult[results.size()]); + } + + @Nullable + @Override + public PsiElement resolve() { + ResolveResult[] resolveResults = multiResolve(false); + return resolveResults.length == 1 ? resolveResults[0].getElement() : null; + } + + @NotNull + @Override + public Object[] getVariants() { + Project project = myElement.getProject(); + List<SimpleProperty> properties = SimpleUtil.findProperties(project); + List<LookupElement> variants = new ArrayList<>(); + for (final SimpleProperty property : properties) { + if (property.getKey() != null && property.getKey().length() > 0) { + variants.add(LookupElementBuilder + .create(property).withIcon(NCPluginIcons.FILE) + .withTypeText(property.getContainingFile().getName()) + ); + } + } + return variants.toArray(); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleReferenceContributor.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleReferenceContributor.java new file mode 100644 index 0000000..a6c92e6 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleReferenceContributor.java @@ -0,0 +1,42 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.openapi.util.TextRange; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiLiteralExpression; +import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceContributor; +import com.intellij.psi.PsiReferenceProvider; +import com.intellij.psi.PsiReferenceRegistrar; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +import static org.apache.nlpcraft.idl.idea.plugin.SimpleAnnotator.SIMPLE_PREFIX_STR; +import static org.apache.nlpcraft.idl.idea.plugin.SimpleAnnotator.SIMPLE_SEPARATOR_STR; + +public class SimpleReferenceContributor extends PsiReferenceContributor { + + @Override + public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) { + registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression.class), + new PsiReferenceProvider() { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, + @NotNull ProcessingContext context) { + PsiLiteralExpression literalExpression = (PsiLiteralExpression) element; + String value = literalExpression.getValue() instanceof String ? + (String) literalExpression.getValue() : null; + if ((value != null && value.startsWith(SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR))) { + TextRange property = new TextRange(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length() + 1, + value.length() + 1); + return new PsiReference[]{new SimpleReference(element, property)}; + } + return PsiReference.EMPTY_ARRAY; + } + }); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewElement.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewElement.java new file mode 100644 index 0000000..9083312 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewElement.java @@ -0,0 +1,76 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.ide.projectView.PresentationData; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.util.treeView.smartTree.SortableTreeElement; +import com.intellij.ide.util.treeView.smartTree.TreeElement; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleFile; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.apache.nlpcraft.idl.idea.plugin.psi.impl.SimplePropertyImpl; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public class SimpleStructureViewElement implements StructureViewTreeElement, SortableTreeElement { + + private final NavigatablePsiElement myElement; + + public SimpleStructureViewElement(NavigatablePsiElement element) { + this.myElement = element; + } + + @Override + public Object getValue() { + return myElement; + } + + @Override + public void navigate(boolean requestFocus) { + myElement.navigate(requestFocus); + } + + @Override + public boolean canNavigate() { + return myElement.canNavigate(); + } + + @Override + public boolean canNavigateToSource() { + return myElement.canNavigateToSource(); + } + + @NotNull + @Override + public String getAlphaSortKey() { + String name = myElement.getName(); + return name != null ? name : ""; + } + + @NotNull + @Override + public ItemPresentation getPresentation() { + ItemPresentation presentation = myElement.getPresentation(); + return presentation != null ? presentation : new PresentationData(); + } + + @NotNull + @Override + public TreeElement[] getChildren() { + if (myElement instanceof SimpleFile) { + List<SimpleProperty> properties = PsiTreeUtil.getChildrenOfTypeAsList(myElement, SimpleProperty.class); + List<TreeElement> treeElements = new ArrayList<>(properties.size()); + for (SimpleProperty property : properties) { + treeElements.add(new SimpleStructureViewElement((SimplePropertyImpl) property)); + } + return treeElements.toArray(new TreeElement[0]); + } + return EMPTY_ARRAY; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewFactory.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewFactory.java new file mode 100644 index 0000000..2f572eb --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewFactory.java @@ -0,0 +1,28 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.ide.structureView.StructureViewBuilder; +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.TreeBasedStructureViewBuilder; +import com.intellij.lang.PsiStructureViewFactory; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class SimpleStructureViewFactory implements PsiStructureViewFactory { + + @Nullable + @Override + public StructureViewBuilder getStructureViewBuilder(@NotNull final PsiFile psiFile) { + return new TreeBasedStructureViewBuilder() { + @NotNull + @Override + public StructureViewModel createStructureViewModel(@Nullable Editor editor) { + return new SimpleStructureViewModel(psiFile); + } + }; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewModel.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewModel.java new file mode 100644 index 0000000..ac2d0e5 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleStructureViewModel.java @@ -0,0 +1,36 @@ +// Copyright 2000-2021 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.ide.structureView.StructureViewModel; +import com.intellij.ide.structureView.StructureViewModelBase; +import com.intellij.ide.structureView.StructureViewTreeElement; +import com.intellij.ide.util.treeView.smartTree.Sorter; +import com.intellij.psi.PsiFile; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; + +public class SimpleStructureViewModel extends StructureViewModelBase implements + StructureViewModel.ElementInfoProvider { + + public SimpleStructureViewModel(PsiFile psiFile) { + super(psiFile, new SimpleStructureViewElement(psiFile)); + } + + @NotNull + public Sorter[] getSorters() { + return new Sorter[]{Sorter.ALPHA_SORTER}; + } + + + @Override + public boolean isAlwaysShowsPlus(StructureViewTreeElement element) { + return false; + } + + @Override + public boolean isAlwaysLeaf(StructureViewTreeElement element) { + return element.getValue() instanceof SimpleProperty; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleSyntaxHighlighter.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleSyntaxHighlighter.java new file mode 100644 index 0000000..c897989 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleSyntaxHighlighter.java @@ -0,0 +1,62 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; +import org.jetbrains.annotations.NotNull; + +import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey; + +public class SimpleSyntaxHighlighter extends SyntaxHighlighterBase { + + public static final TextAttributesKey SEPARATOR = + createTextAttributesKey("SIMPLE_SEPARATOR", DefaultLanguageHighlighterColors.OPERATION_SIGN); + public static final TextAttributesKey KEY = + createTextAttributesKey("SIMPLE_KEY", DefaultLanguageHighlighterColors.KEYWORD); + public static final TextAttributesKey VALUE = + createTextAttributesKey("SIMPLE_VALUE", DefaultLanguageHighlighterColors.STRING); + public static final TextAttributesKey COMMENT = + createTextAttributesKey("SIMPLE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT); + public static final TextAttributesKey BAD_CHARACTER = + createTextAttributesKey("SIMPLE_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER); + + + private static final TextAttributesKey[] BAD_CHAR_KEYS = new TextAttributesKey[]{BAD_CHARACTER}; + private static final TextAttributesKey[] SEPARATOR_KEYS = new TextAttributesKey[]{SEPARATOR}; + private static final TextAttributesKey[] KEY_KEYS = new TextAttributesKey[]{KEY}; + private static final TextAttributesKey[] VALUE_KEYS = new TextAttributesKey[]{VALUE}; + private static final TextAttributesKey[] COMMENT_KEYS = new TextAttributesKey[]{COMMENT}; + private static final TextAttributesKey[] EMPTY_KEYS = new TextAttributesKey[0]; + + @NotNull + @Override + public Lexer getHighlightingLexer() { + return new SimpleLexerAdapter(); + } + + @NotNull + @Override + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + if (tokenType.equals(SimpleTypes.SEPARATOR)) { + return SEPARATOR_KEYS; + } else if (tokenType.equals(SimpleTypes.KEY)) { + return KEY_KEYS; + } else if (tokenType.equals(SimpleTypes.VALUE)) { + return VALUE_KEYS; + } else if (tokenType.equals(SimpleTypes.COMMENT)) { + return COMMENT_KEYS; + } else if (tokenType.equals(TokenType.BAD_CHARACTER)) { + return BAD_CHAR_KEYS; + } else { + return EMPTY_KEYS; + } + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleSyntaxHighlighterFactory.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleSyntaxHighlighterFactory.java new file mode 100644 index 0000000..7e66eaa --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleSyntaxHighlighterFactory.java @@ -0,0 +1,19 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +public class SimpleSyntaxHighlighterFactory extends SyntaxHighlighterFactory { + + @NotNull + @Override + public SyntaxHighlighter getSyntaxHighlighter(Project project, VirtualFile virtualFile) { + return new SimpleSyntaxHighlighter(); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleUtil.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleUtil.java new file mode 100644 index 0000000..1635d33 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/SimpleUtil.java @@ -0,0 +1,87 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin; + +import com.google.common.collect.Lists; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.search.FileTypeIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleFile; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +public class SimpleUtil { + + /** + * Searches the entire project for Simple language files with instances of the Simple property with the given key. + * + * @param project current project + * @param key to check + * @return matching properties + */ + public static List<SimpleProperty> findProperties(Project project, String key) { + List<SimpleProperty> result = new ArrayList<>(); + Collection<VirtualFile> virtualFiles = + FileTypeIndex.getFiles(NCIdlFileType.INSTANCE, GlobalSearchScope.allScope(project)); + for (VirtualFile virtualFile : virtualFiles) { + SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(virtualFile); + if (simpleFile != null) { + SimpleProperty[] properties = PsiTreeUtil.getChildrenOfType(simpleFile, SimpleProperty.class); + if (properties != null) { + for (SimpleProperty property : properties) { + if (key.equals(property.getKey())) { + result.add(property); + } + } + } + } + } + return result; + } + + public static List<SimpleProperty> findProperties(Project project) { + List<SimpleProperty> result = new ArrayList<>(); + Collection<VirtualFile> virtualFiles = + FileTypeIndex.getFiles(NCIdlFileType.INSTANCE, GlobalSearchScope.allScope(project)); + for (VirtualFile virtualFile : virtualFiles) { + SimpleFile simpleFile = (SimpleFile) PsiManager.getInstance(project).findFile(virtualFile); + if (simpleFile != null) { + SimpleProperty[] properties = PsiTreeUtil.getChildrenOfType(simpleFile, SimpleProperty.class); + if (properties != null) { + Collections.addAll(result, properties); + } + } + } + return result; + } + + /** + * Attempts to collect any comment elements above the Simple key/value pair. + */ + public static @NotNull String findDocumentationComment(SimpleProperty property) { + List<String> result = new LinkedList<>(); + PsiElement element = property.getPrevSibling(); + while (element instanceof PsiComment || element instanceof PsiWhiteSpace) { + if (element instanceof PsiComment) { + String commentText = element.getText().replaceFirst("[!# ]+", ""); + result.add(commentText); + } + element = element.getPrevSibling(); + } + return StringUtil.join(Lists.reverse(result),"\n "); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleElementFactory.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleElementFactory.java new file mode 100644 index 0000000..f309191 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleElementFactory.java @@ -0,0 +1,32 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin.psi; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFileFactory; +import org.apache.nlpcraft.idl.idea.plugin.NCIdlFileType; + +public class SimpleElementFactory { + + public static SimpleProperty createProperty(Project project, String name) { + final SimpleFile file = createFile(project, name); + return (SimpleProperty) file.getFirstChild(); + } + + public static SimpleFile createFile(Project project, String text) { + String name = "dummy.simple"; + return (SimpleFile) PsiFileFactory.getInstance(project).createFileFromText(name, NCIdlFileType.INSTANCE, text); + } + + public static SimpleProperty createProperty(Project project, String name, String value) { + final SimpleFile file = createFile(project, name + " = " + value); + return (SimpleProperty) file.getFirstChild(); + } + + public static PsiElement createCRLF(Project project) { + final SimpleFile file = createFile(project, "\n"); + return file.getFirstChild(); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleElementType.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleElementType.java new file mode 100644 index 0000000..12c7bd4 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleElementType.java @@ -0,0 +1,16 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin.psi; + +import com.intellij.psi.tree.IElementType; +import org.apache.nlpcraft.idl.idea.plugin.NCIdlLanguage; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class SimpleElementType extends IElementType { + + public SimpleElementType(@NotNull @NonNls String debugName) { + super(debugName, NCIdlLanguage.INSTANCE); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleFile.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleFile.java new file mode 100644 index 0000000..3bce514 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleFile.java @@ -0,0 +1,29 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin.psi; + +import com.intellij.extapi.psi.PsiFileBase; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.FileViewProvider; +import org.apache.nlpcraft.idl.idea.plugin.NCIdlFileType; +import org.apache.nlpcraft.idl.idea.plugin.NCIdlLanguage; +import org.jetbrains.annotations.NotNull; + +public class SimpleFile extends PsiFileBase { + + public SimpleFile(@NotNull FileViewProvider viewProvider) { + super(viewProvider, NCIdlLanguage.INSTANCE); + } + + @NotNull + @Override + public FileType getFileType() { + return NCIdlFileType.INSTANCE; + } + + @Override + public String toString() { + return "Simple File"; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleNamedElement.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleNamedElement.java new file mode 100644 index 0000000..80f9510 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleNamedElement.java @@ -0,0 +1,9 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin.psi; + +import com.intellij.psi.PsiNameIdentifierOwner; + +public interface SimpleNamedElement extends PsiNameIdentifierOwner { + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleTokenType.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleTokenType.java new file mode 100644 index 0000000..6e4b68e --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/SimpleTokenType.java @@ -0,0 +1,21 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin.psi; + +import com.intellij.psi.tree.IElementType; +import org.apache.nlpcraft.idl.idea.plugin.NCIdlLanguage; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class SimpleTokenType extends IElementType { + + public SimpleTokenType(@NotNull @NonNls String debugName) { + super(debugName, NCIdlLanguage.INSTANCE); + } + + @Override + public String toString() { + return "SimpleTokenType." + super.toString(); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimpleNamedElementImpl.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimpleNamedElementImpl.java new file mode 100644 index 0000000..570eaf4 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimpleNamedElementImpl.java @@ -0,0 +1,16 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin.psi.impl; + +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.intellij.lang.ASTNode; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleNamedElement; +import org.jetbrains.annotations.NotNull; + +public abstract class SimpleNamedElementImpl extends ASTWrapperPsiElement implements SimpleNamedElement { + + public SimpleNamedElementImpl(@NotNull ASTNode node) { + super(node); + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimplePsiImplUtil.java b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimplePsiImplUtil.java new file mode 100644 index 0000000..7ef29a0 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/java/org/apache/nlpcraft/idl/idea/plugin/psi/impl/SimplePsiImplUtil.java @@ -0,0 +1,83 @@ +// Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.apache.nlpcraft.idl.idea.plugin.psi.impl; + +import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import org.apache.nlpcraft.idl.idea.plugin.NCPluginIcons; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleElementFactory; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleProperty; +import org.apache.nlpcraft.idl.idea.plugin.psi.SimpleTypes; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +public class SimplePsiImplUtil { + + public static String getKey(SimpleProperty element) { + ASTNode keyNode = element.getNode().findChildByType(SimpleTypes.KEY); + if (keyNode != null) { + // IMPORTANT: Convert embedded escaped spaces to simple spaces + return keyNode.getText().replaceAll("\\\\ ", " "); + } else { + return null; + } + } + + public static String getValue(SimpleProperty element) { + ASTNode valueNode = element.getNode().findChildByType(SimpleTypes.VALUE); + if (valueNode != null) { + return valueNode.getText(); + } else { + return null; + } + } + + public static String getName(SimpleProperty element) { + return getKey(element); + } + + public static PsiElement setName(SimpleProperty element, String newName) { + ASTNode keyNode = element.getNode().findChildByType(SimpleTypes.KEY); + if (keyNode != null) { + SimpleProperty property = SimpleElementFactory.createProperty(element.getProject(), newName); + ASTNode newKeyNode = property.getFirstChild().getNode(); + element.getNode().replaceChild(keyNode, newKeyNode); + } + return element; + } + + public static PsiElement getNameIdentifier(SimpleProperty element) { + ASTNode keyNode = element.getNode().findChildByType(SimpleTypes.KEY); + if (keyNode != null) { + return keyNode.getPsi(); + } else { + return null; + } + } + + public static ItemPresentation getPresentation(final SimpleProperty element) { + return new ItemPresentation() { + @Nullable + @Override + public String getPresentableText() { + return element.getKey(); + } + + @Nullable + @Override + public String getLocationString() { + PsiFile containingFile = element.getContainingFile(); + return containingFile == null ? null : containingFile.getName(); + } + + @Override + public Icon getIcon(boolean unused) { + return NCPluginIcons.FILE; + } + }; + } + +} diff --git a/nlpcraft-idl-idea-plugin/src/main/resources/META-INF/plugin.xml b/nlpcraft-idl-idea-plugin/src/main/resources/META-INF/plugin.xml new file mode 100644 index 0000000..0f6b4b5 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -0,0 +1,74 @@ +<!-- Copyright 2000-2020 JetBrains s.r.o. and other contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. --> + +<idea-plugin> + + <!-- Unique id for this plugin. Must stay constant for the life of the plugin. --> + <id>org.apache.nlpcraft.idl.idea.plugin</id> + + <!-- Text to display as name on Preferences/Settings | Plugin page --> + <name>NlpCraft IDL</name> + + <!-- Product and plugin compatibility requirements --> + <depends>com.intellij.modules.platform</depends> + <depends>com.intellij.java</depends> + + <!-- Text to display as description on Preferences/Settings | Plugin page --> + <description> + <![CDATA[ + Demonstrates how to add custom language support to an IntelliJ Platform-based IDE. <br>Defines a new language, + <i>Simple language</i> with support for syntax highlighting, annotations, code completion, and other features. + <br> + See the + <a href="https://plugins.jetbrains.com/docs/intellij/custom-language-support-tutorial.html">Custom + Language Tutorial</a> for more information. + ]]> + </description> + <change-notes> + <![CDATA[ + <ul> + <li><b>2.0.0</b> Convert to Gradle-based plugin.</li> + <li><b>1.0.0</b> Release 2018.3 and earlier.</li> + </ul> + ]]> + </change-notes> + + <!-- Text to display as company information on Preferences/Settings | Plugin page --> + <vendor url="https://plugins.jetbrains.com">IntelliJ Platform SDK</vendor> + + <extensions defaultExtensionNs="com.intellij"> + <fileType name="NlpCraft IDL file" + implementationClass="org.apache.nlpcraft.idl.idea.plugin.NCIdlFileType" + fieldName="INSTANCE" + language="NlpCraftIdl" extensions="idl"/> + <!-- + Only required for versions of the IntelliJ Platform prior to v2019.2. + Use 'com.intellij.fileTypeFactory' extension point INSTEAD of above 'com.intellij.fileType'. + <fileTypeFactory implementation="org.intellij.sdk.language.SimpleFileTypeFactory"/> + --> + <lang.parserDefinition language="NlpCraftIdl" implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleParserDefinition"/> + <lang.syntaxHighlighterFactory language="NlpCraftIdl" + implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleSyntaxHighlighterFactory"/> + <colorSettingsPage implementation="org.apache.nlpcraft.idl.idea.plugin.SimpleColorSettingsPage"/> + <annotator language="JAVA" implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleAnnotator"/> + <codeInsight.lineMarkerProvider language="JAVA" + implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleLineMarkerProvider"/> + <completion.contributor language="NlpCraftIdl" + implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleCompletionContributor"/> + <psi.referenceContributor language="JAVA" + implementation="org.apache.nlpcraft.idl.idea.plugin.SimpleReferenceContributor"/> + <lang.refactoringSupport language="NlpCraftIdl" + implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleRefactoringSupportProvider"/> + <lang.findUsagesProvider language="NlpCraftIdl" + implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleFindUsagesProvider"/> + <lang.foldingBuilder language="JAVA" implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleFoldingBuilder"/> + <gotoSymbolContributor implementation="org.apache.nlpcraft.idl.idea.plugin.SimpleChooseByNameContributor"/> + <lang.psiStructureViewFactory language="NlpCraftIdl" + implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleStructureViewFactory"/> + <lang.formatter language="NlpCraftIdl" implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleFormattingModelBuilder"/> + <codeStyleSettingsProvider implementation="org.apache.nlpcraft.idl.idea.plugin.SimpleCodeStyleSettingsProvider"/> + <langCodeStyleSettingsProvider implementation="org.apache.nlpcraft.idl.idea.plugin.SimpleLanguageCodeStyleSettingsProvider"/> + <lang.commenter language="NlpCraftIdl" implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleCommenter"/> + <lang.documentationProvider language="NlpCraftIdl" implementationClass="org.apache.nlpcraft.idl.idea.plugin.SimpleDocumentationProvider"/> + </extensions> + +</idea-plugin> diff --git a/nlpcraft-idl-idea-plugin/src/main/resources/META-INF/pluginIcon.svg b/nlpcraft-idl-idea-plugin/src/main/resources/META-INF/pluginIcon.svg new file mode 100644 index 0000000..6132908 --- /dev/null +++ b/nlpcraft-idl-idea-plugin/src/main/resources/META-INF/pluginIcon.svg @@ -0,0 +1,58 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="81" height="80" viewBox="0 0 81 80"> + <defs> + <linearGradient id="pluginsdk_80-a" x1="-.031%" x2="100.053%" y1="49.963%" y2="49.963%"> + <stop offset="25.81%" stop-color="#F97A12"/> + <stop offset="45.91%" stop-color="#B07B58"/> + <stop offset="72.41%" stop-color="#577BAE"/> + <stop offset="91.05%" stop-color="#1E7CE5"/> + <stop offset="100%" stop-color="#087CFA"/> + </linearGradient> + <linearGradient id="pluginsdk_80-b" x1="27.55%" x2="82.223%" y1="34.514%" y2="77.605%"> + <stop offset="0%" stop-color="#F97A12"/> + <stop offset="7.18%" stop-color="#CB7A3E"/> + <stop offset="15.41%" stop-color="#9E7B6A"/> + <stop offset="24.2%" stop-color="#757B91"/> + <stop offset="33.44%" stop-color="#537BB1"/> + <stop offset="43.24%" stop-color="#387CCC"/> + <stop offset="53.81%" stop-color="#237CE0"/> + <stop offset="65.52%" stop-color="#147CEF"/> + <stop offset="79.25%" stop-color="#0B7CF7"/> + <stop offset="100%" stop-color="#087CFA"/> + </linearGradient> + <linearGradient id="pluginsdk_80-c" x1="63.121%" x2="40.793%" y1="97.699%" y2="-6.587%"> + <stop offset="0%" stop-color="#FE315D"/> + <stop offset="7.84%" stop-color="#CB417E"/> + <stop offset="16.01%" stop-color="#9E4E9B"/> + <stop offset="24.74%" stop-color="#755BB4"/> + <stop offset="33.92%" stop-color="#5365CA"/> + <stop offset="43.65%" stop-color="#386DDB"/> + <stop offset="54.14%" stop-color="#2374E9"/> + <stop offset="65.76%" stop-color="#1478F3"/> + <stop offset="79.4%" stop-color="#0B7BF8"/> + <stop offset="100%" stop-color="#087CFA"/> + </linearGradient> + <linearGradient id="pluginsdk_80-d" x1="25.331%" x2="93.854%" y1="24.119%" y2="132.621%"> + <stop offset="0%" stop-color="#FE315D"/> + <stop offset="4.023%" stop-color="#F63462"/> + <stop offset="10.37%" stop-color="#DF3A71"/> + <stop offset="16.67%" stop-color="#C24383"/> + <stop offset="29.12%" stop-color="#AD4A91"/> + <stop offset="54.98%" stop-color="#755BB4"/> + <stop offset="91.75%" stop-color="#1D76ED"/> + <stop offset="100%" stop-color="#087CFA"/> + </linearGradient> + </defs> + <g fill="none" fill-rule="evenodd"> + <g fill-rule="nonzero" transform="translate(8 8)"> + <path fill="url(#pluginsdk_80-a)" d="M6.08754566,64 L2.66453526e-15,59.1000946 L0,26.7918961 L30,38.6703369 L10.1403967,64 L6.08754566,64 Z"/> + <path fill="url(#pluginsdk_80-b)" d="M20.9524706,64 L52.2740919,31.9159091 L37.6708832,0.460194805 L38.0580944,1.33226763e-15 L64,0 L64,64 L20.9524706,64 Z"/> + <path fill="url(#pluginsdk_80-c)" d="M34.4123783,0 L64,0 L64,28.0366227 L49.0078336,44 L34,0.44696173 L34.4123783,0 Z"/> + <path fill="url(#pluginsdk_80-d)" d="M30.3358775,64 L0,64 L0,49.9709549 L6.23437817,29.2830519 L0,27.1596093 L0,0 L39.4697238,0 L58,21.3844805 L30.5381317,63.9259091 L30.3358775,64 Z"/> + </g> + <g fill-rule="nonzero" transform="translate(12 12)"> + <rect width="56" height="56" fill="#000"/> + <rect width="22" height="4" x="4" y="46" fill="#FFFEFE"/> + <path fill="#FFFEFE" d="M11.128,25.28 C8.584,25.28 6.016,24.392 4,22.592 L6.184,19.976 C7.696,21.224 9.28,22.016 11.2,22.016 C12.712,22.016 13.624,21.416 13.624,20.432 L13.624,20.384 C13.624,19.448 13.048,18.968 10.24,18.248 C6.856,17.384 4.672,16.448 4.672,13.112 L4.672,13.064 C4.672,10.016 7.12,8 10.552,8 C13,8 15.088,8.768 16.792,10.136 L14.872,12.92 C13.384,11.888 11.92,11.264 10.504,11.264 C9.088,11.264 8.344,11.912 8.344,12.728 L8.344,12.776 C8.344,13.88 9.064,14.24 11.968,14 [...] + </g> + </g> +</svg> diff --git a/nlpcraft-idl-idea-plugin/src/main/resources/icons/icon.png b/nlpcraft-idl-idea-plugin/src/main/resources/icons/icon.png new file mode 100644 index 0000000..37bbad3 Binary files /dev/null and b/nlpcraft-idl-idea-plugin/src/main/resources/icons/icon.png differ diff --git a/production/nlpcraft-idea-plugin/META-INF/plugin.xml b/production/nlpcraft-idea-plugin/META-INF/plugin.xml new file mode 100644 index 0000000..1a0348c --- /dev/null +++ b/production/nlpcraft-idea-plugin/META-INF/plugin.xml @@ -0,0 +1,45 @@ +<idea-plugin> + <id>nlpcraft.idl.plugin.id</id> + <name>Nlpcraft.Idl</name> + <version>1.0</version> + <vendor email="[email protected]" url="https://nlpcraft.apache.org/">Nlpcraft</vendor> + + <description><![CDATA[ + Enter short description for your plugin here.<br> + <em>most HTML tags may be used</em> + ]]></description> + + <change-notes><![CDATA[ + Add change notes here.<br> + <em>most HTML tags may be used</em> + ]]> + </change-notes> + + <!-- please see https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html for description --> + <idea-version since-build="173.0"/> + + <!-- please see https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html + on how to target different products --> + <depends>com.intellij.modules.platform</depends> + + <extensions defaultExtensionNs="com.intellij"> + <!-- Add your extensions here --> + + <fileType name="nlpcraftIdl" + implementationClass="org.apache.nlpcraft.idea.plugin.SimpleFileType" + fieldName="INSTANCE" + language="nlpcraftIdl" + extensions="idl1" + id="nlpcraftIdl" + /> + + <completion.contributor language="nlpcraftIdl" order="first" + implementationClass="org.apache.nlpcraft.idea.plugin.SimpleCompletionContributor" + /> + </extensions> + + <actions> + <!-- Add your actions here --> + </actions> + +</idea-plugin> \ No newline at end of file diff --git a/production/nlpcraft-idea-plugin/icons/icon.png b/production/nlpcraft-idea-plugin/icons/icon.png new file mode 100644 index 0000000..499fae7 Binary files /dev/null and b/production/nlpcraft-idea-plugin/icons/icon.png differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor$1.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor$1.class new file mode 100644 index 0000000..c3d760f Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor$1.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor$2.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor$2.class new file mode 100644 index 0000000..1cc08da Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor$2.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor.class new file mode 100644 index 0000000..bac18cf Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleCompletionContributor.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleFileType.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleFileType.class new file mode 100644 index 0000000..876d326 Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleFileType.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleIcons.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleIcons.class new file mode 100644 index 0000000..6e568a9 Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleIcons.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleLanguage.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleLanguage.class new file mode 100644 index 0000000..f80758f Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/SimpleLanguage.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/nlpcraft.bnf b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/nlpcraft.bnf new file mode 100644 index 0000000..8c6c67f --- /dev/null +++ b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/nlpcraft.bnf @@ -0,0 +1,21 @@ +{ + parserClass="org.apache.nlpcraft.idea.plugin.parser.SimpleParser" + parserUtilClass="org.apache.nlpcraft.idea.plugin.parser.SimpleParserUtil" + + extends="com.intellij.extapi.psi.ASTWrapperPsiElement" + + psiClassPrefix="NlpCraft" + psiImplClassSuffix="Impl" + psiPackage="org.apache.nlpcraft.idea.plugin.psi" + psiImplPackage="org.apache.nlpcraft.idea.plugin.psi.impl" + + elementTypeHolderClass="org.apache.nlpcraft.idea.plugin.psi.SimpleTypes" + elementTypeClass="org.apache.nlpcraft.idea.plugin.psi.SimpleElementType" + tokenTypeClass="org.apache.nlpcraft.idea.plugin.psi.SimpleTokenType" +} + +simpleFile ::= item_* + +private item_ ::= (property|COMMENT|CRLF) + +property ::= (KEY? SEPARATOR VALUE?) | KEY \ No newline at end of file diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/parser/SimpleParserUtil.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/parser/SimpleParserUtil.class new file mode 100644 index 0000000..b129da4 Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/parser/SimpleParserUtil.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/NlpCraftProperty.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/NlpCraftProperty.class new file mode 100644 index 0000000..15f7781 Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/NlpCraftProperty.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/NlpCraftVisitor.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/NlpCraftVisitor.class new file mode 100644 index 0000000..47d8e58 Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/NlpCraftVisitor.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleElementType.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleElementType.class new file mode 100644 index 0000000..9690d5e Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleElementType.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTokenType.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTokenType.class new file mode 100644 index 0000000..50a50eb Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTokenType.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTypes$Factory.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTypes$Factory.class new file mode 100644 index 0000000..07c5a3d Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTypes$Factory.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTypes.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTypes.class new file mode 100644 index 0000000..1f027a8 Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/SimpleTypes.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/impl/NlpCraftPropertyImpl.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/impl/NlpCraftPropertyImpl.class new file mode 100644 index 0000000..1967ff1 Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/impl/NlpCraftPropertyImpl.class differ diff --git a/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/parser/SimpleParser.class b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/parser/SimpleParser.class new file mode 100644 index 0000000..f013e2c Binary files /dev/null and b/production/nlpcraft-idea-plugin/org/apache/nlpcraft/idea/plugin/psi/parser/SimpleParser.class differ
