mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-27 16:57:49 +08:00
Add simple_language and updates to simple_language_plugin
This commit is contained in:
parent
308c10991e
commit
0dd8eca961
37
simple_language/build.gradle
Normal file
37
simple_language/build.gradle
Normal file
@ -0,0 +1,37 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.jetbrains.intellij' version '0.4.15'
|
||||
}
|
||||
|
||||
group 'com.intellij.sdk'
|
||||
version '2.0.0'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
test {
|
||||
// Set idea.home.path to the absolute path to the intellij-community source
|
||||
// on your local machine.
|
||||
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 {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
}
|
||||
|
||||
// See https://github.com/JetBrains/gradle-intellij-plugin/
|
||||
intellij {
|
||||
version '2019.3.2'
|
||||
type = 'IC'
|
||||
plugins 'java'
|
||||
updateSinceUntilBuild = false
|
||||
}
|
||||
patchPluginXml {
|
||||
version = project.version
|
||||
}
|
BIN
simple_language/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
simple_language/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
simple_language/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
simple_language/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
183
simple_language/gradlew
vendored
Executable file
183
simple_language/gradlew
vendored
Executable file
@ -0,0 +1,183 @@
|
||||
#!/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
|
||||
;;
|
||||
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" "$@"
|
100
simple_language/gradlew.bat
vendored
Normal file
100
simple_language/gradlew.bat
vendored
Normal file
@ -0,0 +1,100 @@
|
||||
@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 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 init
|
||||
|
||||
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 init
|
||||
|
||||
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
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
: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 %CMD_LINE_ARGS%
|
||||
|
||||
: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
|
2
simple_language/settings.gradle
Normal file
2
simple_language/settings.gradle
Normal file
@ -0,0 +1,2 @@
|
||||
rootProject.name = 'language'
|
||||
|
@ -0,0 +1,535 @@
|
||||
/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.sdk.language.psi.SimpleTypes;
|
||||
import com.intellij.psi.TokenType;
|
||||
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package com.intellij.sdk.language.parser;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.PsiBuilder.Marker;
|
||||
import static com.intellij.sdk.language.psi.SimpleTypes.*;
|
||||
import static com.intellij.lang.parser.GeneratedParserUtilBase.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.lang.PsiParser;
|
||||
import com.intellij.lang.LightPsiParser;
|
||||
|
||||
@SuppressWarnings({"SimplifiableIfStatement", "UnusedAssignment"})
|
||||
public class 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 = consumeToken(b, COMMENT);
|
||||
if (!r) r = consumeToken(b, 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_, PROPERTY, "<property>");
|
||||
r = property_0(b, l + 1);
|
||||
if (!r) r = consumeToken(b, KEY);
|
||||
exit_section_(b, l, m, r, false, recover_property_parser_);
|
||||
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 && consumeToken(b, 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;
|
||||
consumeToken(b, KEY);
|
||||
return true;
|
||||
}
|
||||
|
||||
// VALUE?
|
||||
private static boolean property_0_2(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "property_0_2")) return false;
|
||||
consumeToken(b, 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 = consumeToken(b, KEY);
|
||||
if (!r) r = consumeToken(b, SEPARATOR);
|
||||
if (!r) r = consumeToken(b, 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;
|
||||
}
|
||||
|
||||
static final Parser recover_property_parser_ = new Parser() {
|
||||
public boolean parse(PsiBuilder b, int l) {
|
||||
return recover_property(b, l + 1);
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package com.intellij.sdk.language.psi;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
|
||||
public interface SimpleProperty extends SimpleNamedElement {
|
||||
|
||||
String getKey();
|
||||
|
||||
String getValue();
|
||||
|
||||
String getName();
|
||||
|
||||
PsiElement setName(String newName);
|
||||
|
||||
PsiElement getNameIdentifier();
|
||||
|
||||
ItemPresentation getPresentation();
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package com.intellij.sdk.language.psi;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.sdk.language.psi.impl.*;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package com.intellij.sdk.language.psi;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiElement;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package com.intellij.sdk.language.psi.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import static com.intellij.sdk.language.psi.SimpleTypes.*;
|
||||
import com.intellij.sdk.language.psi.*;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
|
||||
public class SimplePropertyImpl extends SimpleNamedElementImpl implements SimpleProperty {
|
||||
|
||||
public SimplePropertyImpl(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull SimpleVisitor visitor) {
|
||||
visitor.visitProperty(this);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
{
|
||||
parserClass="com.intellij.sdk.language.parser.SimpleParser"
|
||||
|
||||
extends="com.intellij.extapi.psi.ASTWrapperPsiElement"
|
||||
|
||||
psiClassPrefix="Simple"
|
||||
psiImplClassSuffix="Impl"
|
||||
psiPackage="com.intellij.sdk.language.psi"
|
||||
psiImplPackage="com.intellij.sdk.language.psi.impl"
|
||||
|
||||
elementTypeHolderClass="com.intellij.sdk.language.psi.SimpleTypes"
|
||||
elementTypeClass="com.intellij.sdk.language.psi.SimpleElementType"
|
||||
tokenTypeClass="com.intellij.sdk.language.psi.SimpleTokenType"
|
||||
|
||||
psiImplUtilClass="com.intellij.sdk.language.psi.impl.SimplePsiImplUtil"
|
||||
}
|
||||
|
||||
simpleFile ::= item_*
|
||||
|
||||
private item_ ::= (property|COMMENT|CRLF)
|
||||
|
||||
property ::= (KEY? SEPARATOR VALUE?) | KEY {
|
||||
pin=3
|
||||
recoverWhile="recover_property"
|
||||
mixin="com.intellij.sdk.language.psi.impl.SimpleNamedElementImpl"
|
||||
implements="com.intellij.sdk.language.psi.SimpleNamedElement"
|
||||
methods=[getKey getValue getName setName getNameIdentifier getPresentation]
|
||||
}
|
||||
|
||||
private recover_property ::= !(KEY|SEPARATOR|COMMENT)
|
@ -0,0 +1,44 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lexer.FlexLexer;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.sdk.language.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; }
|
@ -0,0 +1,59 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lang.annotation.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
|
||||
|
||||
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 key 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 );
|
||||
|
||||
// Get the list of properties from the Project
|
||||
String possibleProperties = value.substring( SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length() );
|
||||
Project project = element.getProject();
|
||||
List< SimpleProperty > properties = SimpleUtil.findProperties( project, possibleProperties );
|
||||
|
||||
// Set the annotations using the text ranges.
|
||||
Annotation keyAnnotation = holder.createInfoAnnotation( prefixRange, null );
|
||||
keyAnnotation.setTextAttributes( DefaultLanguageHighlighterColors.KEYWORD );
|
||||
Annotation separatorAnnotation = holder.createInfoAnnotation( separatorRange, null );
|
||||
separatorAnnotation.setTextAttributes( SimpleSyntaxHighlighter.SEPARATOR );
|
||||
if ( properties.isEmpty() ) {
|
||||
// No well-formed property found following the key-separator
|
||||
Annotation badProperty = holder.createErrorAnnotation( keyRange, "Unresolved property" );
|
||||
badProperty.setTextAttributes( SimpleSyntaxHighlighter.BAD_CHARACTER );
|
||||
// ** Tutorial step 18.3 - Add a quick fix for the string containing possible properties
|
||||
badProperty.registerFix(new SimpleCreatePropertyQuickFix(possibleProperties));
|
||||
} else {
|
||||
// Found at least one property
|
||||
Annotation annotation = holder.createInfoAnnotation( keyRange, null );
|
||||
annotation.setTextAttributes( SimpleSyntaxHighlighter.VALUE );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.formatting.*;
|
||||
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 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<Block>();
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.navigation.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
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<String>(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()]);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.psi.codeStyle.*;
|
||||
|
||||
public class SimpleCodeStyleSettings extends CustomCodeStyleSettings {
|
||||
public SimpleCodeStyleSettings(CodeStyleSettings settings) {
|
||||
super("SimpleCodeStyleSettings", settings);
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.application.options.*;
|
||||
import com.intellij.psi.codeStyle.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
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(SimpleLanguage.INSTANCE, currentSettings, settings);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
|
||||
import com.intellij.openapi.options.colors.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.sdk.language.SimpleLanguage.*;
|
||||
|
||||
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 SimpleIcons.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 = http://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";
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.sdk.language.psi.SimpleTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SimpleCompletionContributor extends CompletionContributor {
|
||||
public SimpleCompletionContributor() {
|
||||
// Register the completion providers
|
||||
extend( CompletionType.BASIC,
|
||||
PlatformPatterns.psiElement(SimpleTypes.VALUE).withLanguage(SimpleLanguage.INSTANCE),
|
||||
new CompletionProvider<CompletionParameters>() {
|
||||
// Define candidate completions
|
||||
public void addCompletions(@NotNull CompletionParameters parameters,
|
||||
ProcessingContext context,
|
||||
@NotNull CompletionResultSet resultSet) {
|
||||
// Create a completion independent of context for Simple language
|
||||
resultSet.addElement(LookupElementBuilder.create("Hello"));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
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 com.intellij.sdk.language.psi.SimpleElementFactory;
|
||||
import com.intellij.sdk.language.psi.SimpleFile;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
class SimpleCreatePropertyQuickFix extends BaseIntentionAction {
|
||||
private String key;
|
||||
|
||||
SimpleCreatePropertyQuickFix(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Create property";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Simple properties";
|
||||
}
|
||||
|
||||
@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(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Collection<VirtualFile> virtualFiles =
|
||||
FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project) );
|
||||
if (virtualFiles.size() == 1) {
|
||||
createProperty(project, virtualFiles.iterator().next());
|
||||
} else {
|
||||
final FileChooserDescriptor descriptor =
|
||||
FileChooserDescriptorFactory.createSingleFileDescriptor(SimpleFileType.INSTANCE);
|
||||
descriptor.setRoots(ProjectUtil.guessProjectDir(project));
|
||||
final VirtualFile file = FileChooser.chooseFile(descriptor, project, null);
|
||||
if (file != null) {
|
||||
createProperty(project, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class SimpleFileType extends LanguageFileType {
|
||||
public static final SimpleFileType INSTANCE = new SimpleFileType();
|
||||
|
||||
private SimpleFileType() {
|
||||
super(SimpleLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Simple file";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Simple language file";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getDefaultExtension() {
|
||||
return "simple";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return SimpleIcons.FILE;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
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
|
||||
*/
|
||||
public class SimpleFileTypeFactory extends FileTypeFactory {
|
||||
@Override
|
||||
public void createFileTypes(@NotNull FileTypeConsumer fileTypeConsumer) {
|
||||
fileTypeConsumer.consume(SimpleFileType.INSTANCE);
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lang.cacheBuilder.*;
|
||||
import com.intellij.lang.findUsages.FindUsagesProvider;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.sdk.language.psi.*;
|
||||
import org.jetbrains.annotations.*;
|
||||
import static com.intellij.sdk.language.SimpleAnnotator.*;
|
||||
|
||||
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() + SIMPLE_SEPARATOR_STR + ((SimpleProperty) element).getValue();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.folding.*;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.project.*;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import static com.intellij.sdk.language.SimpleAnnotator.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
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(SIMPLE_PREFIX_STR);
|
||||
// Initialize the list of folding regions
|
||||
List< FoldingDescriptor > descriptors = new ArrayList< FoldingDescriptor >();
|
||||
// Get a collection of the literal expressions in the document below root
|
||||
Collection< PsiLiteralExpression > literalExpressions =
|
||||
PsiTreeUtil.findChildrenOfType(root, PsiLiteralExpression.class);
|
||||
// Evaluate the collection, using only Simple language literalExpressions
|
||||
for ( final PsiLiteralExpression literalExpression : literalExpressions ) {
|
||||
String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null;
|
||||
if ( value != null && value.startsWith(SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR) ) {
|
||||
Project project = literalExpression.getProject();
|
||||
String key = value.substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length());
|
||||
// Get a list of properties for 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.
|
||||
* @return String corresponding to the "website" key.
|
||||
*/
|
||||
@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(SIMPLE_PREFIX_STR.length() + 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.formatting.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.sdk.language.psi.SimpleTypes;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class SimpleFormattingModelBuilder implements FormattingModelBuilder {
|
||||
@NotNull
|
||||
@Override
|
||||
public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
|
||||
return FormattingModelProvider
|
||||
.createFormattingModelForPsiFile(element.getContainingFile(),
|
||||
new SimpleBlock(element.getNode(),
|
||||
Wrap.createWrap(WrapType.NONE, false),
|
||||
Alignment.createAlignment(),
|
||||
createSpaceBuilder(settings)),
|
||||
settings);
|
||||
}
|
||||
|
||||
private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) {
|
||||
return new SpacingBuilder(settings, SimpleLanguage.INSTANCE)
|
||||
.around(SimpleTypes.SEPARATOR)
|
||||
.spaceIf(settings.getCommonSettings(SimpleLanguage.INSTANCE.getID()).SPACE_AROUND_ASSIGNMENT_OPERATORS)
|
||||
.before(SimpleTypes.PROPERTY)
|
||||
.none();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class SimpleIcons {
|
||||
public static final Icon FILE = IconLoader.getIcon("/icons/jar-gray.png");
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
|
||||
public class SimpleLanguage extends Language {
|
||||
public static final SimpleLanguage INSTANCE = new SimpleLanguage();
|
||||
|
||||
private SimpleLanguage() {
|
||||
super("Simple");
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.codeStyle.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SimpleLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider {
|
||||
@NotNull
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return SimpleLanguage.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 = http://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";
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lexer.FlexAdapter;
|
||||
|
||||
import java.io.Reader;
|
||||
|
||||
public class SimpleLexerAdapter extends FlexAdapter {
|
||||
public SimpleLexerAdapter() {
|
||||
super(new SimpleLexer((Reader) null));
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.codeInsight.daemon.*;
|
||||
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import static com.intellij.sdk.language.SimpleAnnotator.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
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( SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR ) ) return;
|
||||
|
||||
// Get the Simple language property usage
|
||||
Project project = element.getProject();
|
||||
String possibleProperties = value.substring( SIMPLE_PREFIX_STR.length()+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( SimpleIcons.FILE )
|
||||
.setTargets( properties )
|
||||
.setTooltipText( "Navigate to Simple language property" );
|
||||
result.add( builder.createLineMarkerInfo( element ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.*;
|
||||
import com.intellij.sdk.language.parser.SimpleParser;
|
||||
import com.intellij.sdk.language.psi.*;
|
||||
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(SimpleLanguage.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);
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class SimpleRefactoringSupportProvider extends RefactoringSupportProvider {
|
||||
@Override
|
||||
public boolean isMemberInplaceRenameAvailable(@NotNull PsiElement elementToRename, @Nullable PsiElement context) {
|
||||
return (elementToRename instanceof SimpleProperty);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
2020-01-10 21:59:36,392 [ 74521] WARN - name.RenamePsiElementProcessor - org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinTypeParameterProcessor overrides deprecated findReferences(..).
|
||||
Override findReferences(PsiElement, SearchScope, boolean) instead.
|
||||
*/
|
@ -0,0 +1,57 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SimpleReference extends PsiReferenceBase<PsiElement> implements PsiPolyVariantReference {
|
||||
private 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<ResolveResult>();
|
||||
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<LookupElement>();
|
||||
for (final SimpleProperty property : properties) {
|
||||
if (property.getKey() != null && property.getKey().length() > 0) {
|
||||
variants.add(LookupElementBuilder
|
||||
.create(property).withIcon(SimpleIcons.FILE)
|
||||
.withTypeText(property.getContainingFile().getName())
|
||||
);
|
||||
}
|
||||
}
|
||||
return variants.toArray();
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.sdk.language.SimpleAnnotator.*;
|
||||
|
||||
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;
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
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 com.intellij.sdk.language.psi.SimpleFile;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
import com.intellij.sdk.language.psi.impl.SimplePropertyImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleStructureViewElement implements StructureViewTreeElement, SortableTreeElement {
|
||||
private NavigatablePsiElement element;
|
||||
|
||||
public SimpleStructureViewElement(NavigatablePsiElement element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void navigate(boolean requestFocus) {
|
||||
element.navigate(requestFocus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canNavigate() {
|
||||
return element.canNavigate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canNavigateToSource() {
|
||||
return element.canNavigateToSource();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getAlphaSortKey() {
|
||||
String name = element.getName();
|
||||
return name != null ? name : "";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ItemPresentation getPresentation() {
|
||||
ItemPresentation presentation = element.getPresentation();
|
||||
return presentation != null ? presentation : new PresentationData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeElement[] getChildren() {
|
||||
if (element instanceof SimpleFile) {
|
||||
SimpleProperty[] properties = PsiTreeUtil.getChildrenOfType(element, SimpleProperty.class);
|
||||
List<TreeElement> treeElements = new ArrayList<TreeElement>(properties.length);
|
||||
for (SimpleProperty property : properties) {
|
||||
treeElements.add(new SimpleStructureViewElement((SimplePropertyImpl) property));
|
||||
}
|
||||
return treeElements.toArray(new TreeElement[treeElements.size()]);
|
||||
} else {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.ide.structureView.*;
|
||||
import com.intellij.lang.PsiStructureViewFactory;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class SimpleStructureViewFactory implements PsiStructureViewFactory {
|
||||
@Nullable
|
||||
@Override
|
||||
public StructureViewBuilder getStructureViewBuilder(final PsiFile psiFile) {
|
||||
return new TreeBasedStructureViewBuilder() {
|
||||
@NotNull
|
||||
@Override
|
||||
public StructureViewModel createStructureViewModel(@Nullable Editor editor) {
|
||||
return new SimpleStructureViewModel(psiFile);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.ide.structureView.*;
|
||||
import com.intellij.ide.util.treeView.smartTree.Sorter;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.sdk.language.psi.SimpleFile;
|
||||
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 instanceof SimpleFile;
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.editor.*;
|
||||
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 com.intellij.sdk.language.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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.openapi.fileTypes.*;
|
||||
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();
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.indexing.FileBasedIndex;
|
||||
import com.intellij.sdk.language.psi.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SimpleUtil {
|
||||
|
||||
// Searches the entire project for Simple language files with instances of the Simple property
|
||||
public static List<SimpleProperty> findProperties(Project project, String key) {
|
||||
List<SimpleProperty> result = null;
|
||||
Collection<VirtualFile> virtualFiles =
|
||||
FileTypeIndex.getFiles(SimpleFileType.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())) {
|
||||
if (result == null) {
|
||||
result = new ArrayList<SimpleProperty>();
|
||||
}
|
||||
result.add(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result != null ? result : Collections.<SimpleProperty>emptyList();
|
||||
}
|
||||
|
||||
public static List<SimpleProperty> findProperties(Project project) {
|
||||
List<SimpleProperty> result = new ArrayList<SimpleProperty>();
|
||||
Collection<VirtualFile> virtualFiles =
|
||||
FileTypeIndex.getFiles(SimpleFileType.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;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language.psi;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.sdk.language.SimpleFileType;
|
||||
|
||||
public class SimpleElementFactory {
|
||||
public static SimpleProperty createProperty(Project project, String name) {
|
||||
final SimpleFile file = createFile(project, name);
|
||||
return (SimpleProperty) file.getFirstChild();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public static SimpleFile createFile(Project project, String text) {
|
||||
String name = "dummy.simple";
|
||||
return (SimpleFile) PsiFileFactory.getInstance( project).createFileFromText(name, SimpleFileType.INSTANCE, text);
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.intellij.sdk.language.psi;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.sdk.language.SimpleLanguage;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SimpleElementType extends IElementType {
|
||||
public SimpleElementType( @NotNull @NonNls String debugName) {
|
||||
super(debugName, SimpleLanguage.INSTANCE);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.intellij.sdk.language.psi;
|
||||
|
||||
import com.intellij.extapi.psi.PsiFileBase;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.sdk.language.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class SimpleFile extends PsiFileBase {
|
||||
public SimpleFile(@NotNull FileViewProvider viewProvider) {
|
||||
super(viewProvider, SimpleLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FileType getFileType() {
|
||||
return SimpleFileType.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Simple File";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon(int flags) {
|
||||
return super.getIcon(flags);
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language.psi;
|
||||
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
|
||||
public interface SimpleNamedElement extends PsiNameIdentifierOwner {
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.intellij.sdk.language.psi;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.sdk.language.SimpleLanguage;
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class SimpleTokenType extends IElementType {
|
||||
public SimpleTokenType(@NotNull @NonNls String debugName) {
|
||||
super(debugName, SimpleLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SimpleTokenType." + super.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package com.intellij.sdk.language.psi.impl;
|
||||
|
||||
import com.intellij.extapi.psi.ASTWrapperPsiElement;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.sdk.language.psi.SimpleNamedElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class SimpleNamedElementImpl extends ASTWrapperPsiElement implements SimpleNamedElement {
|
||||
public SimpleNamedElementImpl(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.intellij.sdk.language.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.sdk.language.SimpleIcons;
|
||||
import com.intellij.sdk.language.psi.*;
|
||||
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();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Icon getIcon( boolean unused) {
|
||||
return SimpleIcons.FILE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
66
simple_language/src/main/resources/META-INF/plugin.xml
Normal file
66
simple_language/src/main/resources/META-INF/plugin.xml
Normal file
@ -0,0 +1,66 @@
|
||||
<!-- Copyright 2000-2020 JetBrains s.r.o. 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>com.intellij.sdk.simple_language</id>
|
||||
|
||||
<!-- Text to display as name on Preferences/Settings | Plugin page -->
|
||||
<name>SDK: Simple Language Sample Project</name>
|
||||
|
||||
<!-- The version of this plugin -->
|
||||
<version>2.0.0</version>
|
||||
|
||||
<!-- Compatible with the following versions of IntelliJ Platform
|
||||
At least 2019.2 is required. Otherwise, a FileTypeFactor must be registered as an extension.
|
||||
See the extensions section below. -->
|
||||
<idea-version since-build="192.2"/>
|
||||
|
||||
<!-- Product and plugin compatibility requirements -->
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
<depends>com.intellij.modules.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://www.jetbrains.org/intellij/sdk/docs/tutorials/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="Simple file" implementationClass="com.intellij.sdk.language.SimpleFileType" fieldName="INSTANCE"
|
||||
language="Simple" extensions="simple"/>
|
||||
<!-- Only required for versions of the IntelliJ Platform prior to v2019.2.
|
||||
<fileTypeFactory implementation="com.intellij.sdk.language.SimpleFileTypeFactory"/>
|
||||
-->
|
||||
<lang.parserDefinition language="Simple" implementationClass="com.intellij.sdk.language.SimpleParserDefinition"/>
|
||||
<lang.syntaxHighlighterFactory language="Simple" implementationClass="com.intellij.sdk.language.SimpleSyntaxHighlighterFactory"/>
|
||||
<colorSettingsPage implementation="com.intellij.sdk.language.SimpleColorSettingsPage"/>
|
||||
<annotator language="JAVA" implementationClass="com.intellij.sdk.language.SimpleAnnotator"/>
|
||||
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.intellij.sdk.language.SimpleLineMarkerProvider"/>
|
||||
<completion.contributor language="Simple" implementationClass="com.intellij.sdk.language.SimpleCompletionContributor"/>
|
||||
<psi.referenceContributor implementation="com.intellij.sdk.language.SimpleReferenceContributor"/>
|
||||
<lang.refactoringSupport language="Simple" implementationClass="com.intellij.sdk.language.SimpleRefactoringSupportProvider"/>
|
||||
<lang.findUsagesProvider language="Simple" implementationClass="com.intellij.sdk.language.SimpleFindUsagesProvider"/>
|
||||
<lang.foldingBuilder language="JAVA" implementationClass="com.intellij.sdk.language.SimpleFoldingBuilder"/>
|
||||
<gotoSymbolContributor implementation="com.intellij.sdk.language.SimpleChooseByNameContributor"/>
|
||||
<lang.psiStructureViewFactory language="Simple" implementationClass="com.intellij.sdk.language.SimpleStructureViewFactory"/>
|
||||
<lang.formatter language="Simple" implementationClass="com.intellij.sdk.language.SimpleFormattingModelBuilder"/>
|
||||
<codeStyleSettingsProvider implementation="com.intellij.sdk.language.SimpleCodeStyleSettingsProvider"/>
|
||||
<langCodeStyleSettingsProvider implementation="com.intellij.sdk.language.SimpleLanguageCodeStyleSettingsProvider"/>
|
||||
<lang.commenter language="Simple" implementationClass="com.intellij.sdk.language.SimpleCommenter"/>
|
||||
</extensions>
|
||||
|
||||
</idea-plugin>
|
58
simple_language/src/main/resources/META-INF/pluginIcon.svg
Normal file
58
simple_language/src/main/resources/META-INF/pluginIcon.svg
Normal file
@ -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.984 C15.376,15.872 17.296,17.096 17.296,20.024 L17.296,20.072 C17.296,23.408 14.752,25.28 11.128,25.28 Z M19.512,25.04 L19.512,8.24 L26.064,8.24 C31.344,8.24 34.992,11.864 34.992,16.592 L34.992,16.64 C34.992,21.368 31.344,25.04 26.064,25.04 L19.512,25.04 Z M26.064,11.576 L23.208,11.576 L23.208,21.704 L26.064,21.704 C29.088,21.704 31.128,19.664 31.128,16.688 L31.128,16.64 C31.128,13.664 29.088,11.576 26.064,11.576 Z M37.28,25.04 L37.28,8.24 L40.976,8.24 L40.976,15.584 L47.744,8.24 L52.28,8.24 L45.416,15.368 L52.568,25.04 L48.128,25.04 L42.92,17.888 L40.976,19.904 L40.976,25.04 L37.28,25.04 Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
BIN
simple_language/src/main/resources/icons/jar-gray.png
Normal file
BIN
simple_language/src/main/resources/icons/jar-gray.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 717 B |
@ -0,0 +1,83 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.application.options.CodeStyle;
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.generation.actions.CommentByLineCommentAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.sdk.language.psi.SimpleProperty;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleCodeInsightTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
|
||||
/**
|
||||
*
|
||||
* @return path to test data file directory relative to working directory in the run configuration for this test.
|
||||
*/
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return "src/test/testData";
|
||||
}
|
||||
|
||||
public void testCompletion() {
|
||||
myFixture.configureByFiles("CompleteTestData.java", "DefaultTestData.simple");
|
||||
myFixture.complete(CompletionType.BASIC, 1);
|
||||
List<String> strings = myFixture.getLookupElementStrings();
|
||||
assertTrue(strings.containsAll(Arrays.asList("key with spaces", "language", "message", "tab", "website")));
|
||||
assertEquals(5, strings.size());
|
||||
}
|
||||
|
||||
public void testAnnotator() {
|
||||
myFixture.configureByFiles("AnnotatorTestData.java", "DefaultTestData.simple");
|
||||
myFixture.checkHighlighting(false, false, true, true);
|
||||
}
|
||||
|
||||
public void testFormatter() {
|
||||
myFixture.configureByFiles("FormatterTestData.simple");
|
||||
CodeStyle.getLanguageSettings(myFixture.getFile()).SPACE_AROUND_ASSIGNMENT_OPERATORS = true;
|
||||
CodeStyle.getLanguageSettings(myFixture.getFile()).KEEP_BLANK_LINES_IN_CODE = 2;
|
||||
WriteCommandAction.writeCommandAction(getProject()).run(() -> {
|
||||
CodeStyleManager.getInstance(getProject()).reformatText(myFixture.getFile(),
|
||||
ContainerUtil.newArrayList(myFixture.getFile().getTextRange()));
|
||||
});
|
||||
myFixture.checkResultByFile("DefaultTestData.simple");
|
||||
}
|
||||
|
||||
public void testRename() {
|
||||
myFixture.configureByFiles("RenameTestData.java", "RenameTestData.simple");
|
||||
myFixture.renameElementAtCaret("websiteUrl");
|
||||
myFixture.checkResultByFile("RenameTestData.simple", "RenameTestDataAfter.simple", false);
|
||||
}
|
||||
|
||||
public void testFolding() {
|
||||
myFixture.configureByFiles("DefaultTestData.simple");
|
||||
myFixture.testFolding(getTestDataPath() + "/FoldingTestData.java");
|
||||
}
|
||||
|
||||
public void testFindUsages() {
|
||||
Collection<UsageInfo> usageInfos = myFixture.testFindUsages("FindUsagesTestData.simple", "FindUsagesTestData.java");
|
||||
assertEquals(1, usageInfos.size());
|
||||
}
|
||||
|
||||
public void testCommenter() {
|
||||
myFixture.configureByText(SimpleFileType.INSTANCE, "<caret>website = http://en.wikipedia.org/");
|
||||
CommentByLineCommentAction commentAction = new CommentByLineCommentAction();
|
||||
commentAction.actionPerformedImpl(getProject(), myFixture.getEditor());
|
||||
myFixture.checkResult("#website = http://en.wikipedia.org/");
|
||||
commentAction.actionPerformedImpl(getProject(), myFixture.getEditor());
|
||||
myFixture.checkResult("website = http://en.wikipedia.org/");
|
||||
}
|
||||
|
||||
public void testReference() {
|
||||
myFixture.configureByFiles("ReferenceTestData.java", "DefaultTestData.simple");
|
||||
PsiElement element = myFixture.getFile().findElementAt(myFixture.getCaretOffset()).getParent();
|
||||
assertEquals("http://en.wikipedia.org/", ((SimpleProperty) element.getReferences()[0].resolve()).getValue());
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.intellij.sdk.language;
|
||||
|
||||
import com.intellij.testFramework.ParsingTestCase;
|
||||
|
||||
public class SimpleParsingTest extends ParsingTestCase {
|
||||
public SimpleParsingTest() {
|
||||
super("", "simple", new SimpleParserDefinition());
|
||||
}
|
||||
|
||||
public void testParsingTestData() {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return path to test data file directory relative to root of this module.
|
||||
*/
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return "src/test/testData";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean skipSpaces() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean includeRanges() {
|
||||
return true;
|
||||
}
|
||||
}
|
7
simple_language/src/test/testData/AnnotatorTestData.java
Normal file
7
simple_language/src/test/testData/AnnotatorTestData.java
Normal file
@ -0,0 +1,7 @@
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("simple:website");
|
||||
System.out.println("simple:key with spaces");
|
||||
System.out.println("simple:<error descr="Unresolved property">websit</error>");
|
||||
}
|
||||
}
|
5
simple_language/src/test/testData/CompleteTestData.java
Normal file
5
simple_language/src/test/testData/CompleteTestData.java
Normal file
@ -0,0 +1,5 @@
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("simple:<caret>");
|
||||
}
|
||||
}
|
14
simple_language/src/test/testData/DefaultTestData.simple
Normal file
14
simple_language/src/test/testData/DefaultTestData.simple
Normal file
@ -0,0 +1,14 @@
|
||||
# You are reading the ".properties" entry.
|
||||
! The exclamation mark can also mark text as comments.
|
||||
website = http://en.wikipedia.org/
|
||||
|
||||
|
||||
language = English
|
||||
# The backslash below tells the application to continue reading
|
||||
# the value onto the next line.
|
||||
message = Welcome to \
|
||||
Wikipedia!
|
||||
# Add spaces to the key
|
||||
key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
|
||||
# Unicode
|
||||
tab : \u0009
|
@ -0,0 +1,5 @@
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("simple:key with spaces");
|
||||
}
|
||||
}
|
13
simple_language/src/test/testData/FindUsagesTestData.simple
Normal file
13
simple_language/src/test/testData/FindUsagesTestData.simple
Normal file
@ -0,0 +1,13 @@
|
||||
# You are reading the ".properties" entry.
|
||||
! The exclamation mark can also mark text as comments.
|
||||
website = http://en.wikipedia.org/
|
||||
|
||||
language = English
|
||||
# The backslash below tells the application to continue reading
|
||||
# the value onto the next line.
|
||||
message = Welcome to \
|
||||
Wikipedia!
|
||||
# Add spaces to the key
|
||||
<caret>key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
|
||||
# Unicode
|
||||
tab : \u0009
|
11
simple_language/src/test/testData/FoldingTestData.java
Normal file
11
simple_language/src/test/testData/FoldingTestData.java
Normal file
@ -0,0 +1,11 @@
|
||||
public class Test {
|
||||
public static void main(String[] args)<fold text=' { '> {
|
||||
</fold>System.out.println("<fold text='http://en.wikipedia.org/'>simple:website</fold>");<fold text=' }'>
|
||||
}</fold>
|
||||
public static void main1(String[] args)<fold text=' { '> {
|
||||
</fold>System.out.println("<fold text='This is the value that could be looked up with the key \"key with spaces\".'>simple:key with spaces</fold>");<fold text=' }'>
|
||||
}</fold>
|
||||
public static void main2(String[] args)<fold text=' { '> {
|
||||
</fold>System.out.println("<fold text='Welcome to \n Wikipedia!'>simple:message</fold>");<fold text=' }'>
|
||||
}</fold>
|
||||
}
|
15
simple_language/src/test/testData/FormatterTestData.simple
Normal file
15
simple_language/src/test/testData/FormatterTestData.simple
Normal file
@ -0,0 +1,15 @@
|
||||
# You are reading the ".properties" entry.
|
||||
! The exclamation mark can also mark text as comments.
|
||||
website=http://en.wikipedia.org/
|
||||
|
||||
|
||||
|
||||
language= English
|
||||
# The backslash below tells the application to continue reading
|
||||
# the value onto the next line.
|
||||
message = Welcome to \
|
||||
Wikipedia!
|
||||
# Add spaces to the key
|
||||
key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
|
||||
# Unicode
|
||||
tab :\u0009
|
17
simple_language/src/test/testData/ParsingTestData.simple
Normal file
17
simple_language/src/test/testData/ParsingTestData.simple
Normal file
@ -0,0 +1,17 @@
|
||||
# You are reading the ".properties" entry.
|
||||
! The exclamation mark can also mark text as comments.
|
||||
website = http://en.wikipedia.org/
|
||||
|
||||
language = English
|
||||
# The backslash below tells the application to continue reading
|
||||
# the value onto the next line.
|
||||
message = Welcome to \
|
||||
Wikipedia!
|
||||
# Add spaces to the key
|
||||
key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
|
||||
# Unicode
|
||||
tab : \u0009
|
||||
# test for illegal key attempt
|
||||
key\
|
||||
with\
|
||||
endofline = test
|
66
simple_language/src/test/testData/ParsingTestData.txt
Normal file
66
simple_language/src/test/testData/ParsingTestData.txt
Normal file
@ -0,0 +1,66 @@
|
||||
Simple File(0,492)
|
||||
PsiComment(SimpleTokenType.COMMENT)('# You are reading the ".properties" entry.')(0,42)
|
||||
PsiWhiteSpace('\n')(42,43)
|
||||
PsiComment(SimpleTokenType.COMMENT)('! The exclamation mark can also mark text as comments.')(43,97)
|
||||
PsiWhiteSpace('\n')(97,98)
|
||||
SimplePropertyImpl(PROPERTY)(98,132)
|
||||
PsiElement(SimpleTokenType.KEY)('website')(98,105)
|
||||
PsiWhiteSpace(' ')(105,106)
|
||||
PsiElement(SimpleTokenType.SEPARATOR)('=')(106,107)
|
||||
PsiWhiteSpace(' ')(107,108)
|
||||
PsiElement(SimpleTokenType.VALUE)('http://en.wikipedia.org/')(108,132)
|
||||
PsiWhiteSpace('\n\n')(132,134)
|
||||
SimplePropertyImpl(PROPERTY)(134,152)
|
||||
PsiElement(SimpleTokenType.KEY)('language')(134,142)
|
||||
PsiWhiteSpace(' ')(142,143)
|
||||
PsiElement(SimpleTokenType.SEPARATOR)('=')(143,144)
|
||||
PsiWhiteSpace(' ')(144,145)
|
||||
PsiElement(SimpleTokenType.VALUE)('English')(145,152)
|
||||
PsiWhiteSpace('\n')(152,153)
|
||||
PsiComment(SimpleTokenType.COMMENT)('# The backslash below tells the application to continue reading')(153,216)
|
||||
PsiWhiteSpace('\n')(216,217)
|
||||
PsiComment(SimpleTokenType.COMMENT)('# the value onto the next line.')(217,248)
|
||||
PsiWhiteSpace('\n')(248,249)
|
||||
SimplePropertyImpl(PROPERTY)(249,292)
|
||||
PsiElement(SimpleTokenType.KEY)('message')(249,256)
|
||||
PsiWhiteSpace(' ')(256,257)
|
||||
PsiElement(SimpleTokenType.SEPARATOR)('=')(257,258)
|
||||
PsiWhiteSpace(' ')(258,259)
|
||||
PsiElement(SimpleTokenType.VALUE)('Welcome to \\n Wikipedia!')(259,292)
|
||||
PsiWhiteSpace('\n')(292,293)
|
||||
PsiComment(SimpleTokenType.COMMENT)('# Add spaces to the key')(293,316)
|
||||
PsiWhiteSpace('\n')(316,317)
|
||||
SimplePropertyImpl(PROPERTY)(317,410)
|
||||
PsiElement(SimpleTokenType.KEY)('key\ with\ spaces')(317,334)
|
||||
PsiWhiteSpace(' ')(334,335)
|
||||
PsiElement(SimpleTokenType.SEPARATOR)('=')(335,336)
|
||||
PsiWhiteSpace(' ')(336,337)
|
||||
PsiElement(SimpleTokenType.VALUE)('This is the value that could be looked up with the key "key with spaces".')(337,410)
|
||||
PsiWhiteSpace('\n')(410,411)
|
||||
PsiComment(SimpleTokenType.COMMENT)('# Unicode')(411,420)
|
||||
PsiWhiteSpace('\n')(420,421)
|
||||
SimplePropertyImpl(PROPERTY)(421,433)
|
||||
PsiElement(SimpleTokenType.KEY)('tab')(421,424)
|
||||
PsiWhiteSpace(' ')(424,425)
|
||||
PsiElement(SimpleTokenType.SEPARATOR)(':')(425,426)
|
||||
PsiWhiteSpace(' ')(426,427)
|
||||
PsiElement(SimpleTokenType.VALUE)('\u0009')(427,433)
|
||||
PsiWhiteSpace('\n')(433,434)
|
||||
PsiComment(SimpleTokenType.COMMENT)('# test for illegal key attempt')(434,464)
|
||||
PsiWhiteSpace('\n')(464,465)
|
||||
SimplePropertyImpl(PROPERTY)(465,469)
|
||||
PsiElement(SimpleTokenType.KEY)('key')(465,468)
|
||||
PsiErrorElement:SimpleTokenType.SEPARATOR expected, got '\'(468,469)
|
||||
PsiElement(BAD_CHARACTER)('\')(468,469)
|
||||
PsiWhiteSpace('\n')(469,470)
|
||||
SimplePropertyImpl(PROPERTY)(470,475)
|
||||
PsiElement(SimpleTokenType.KEY)('with')(470,474)
|
||||
PsiErrorElement:SimpleTokenType.SEPARATOR expected, got '\'(474,475)
|
||||
PsiElement(BAD_CHARACTER)('\')(474,475)
|
||||
PsiWhiteSpace('\n')(475,476)
|
||||
SimplePropertyImpl(PROPERTY)(476,492)
|
||||
PsiElement(SimpleTokenType.KEY)('endofline')(476,485)
|
||||
PsiWhiteSpace(' ')(485,486)
|
||||
PsiElement(SimpleTokenType.SEPARATOR)('=')(486,487)
|
||||
PsiWhiteSpace(' ')(487,488)
|
||||
PsiElement(SimpleTokenType.VALUE)('test')(488,492)
|
5
simple_language/src/test/testData/ReferenceTestData.java
Normal file
5
simple_language/src/test/testData/ReferenceTestData.java
Normal file
@ -0,0 +1,5 @@
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("simple:website<caret>");
|
||||
}
|
||||
}
|
5
simple_language/src/test/testData/RenameTestData.java
Normal file
5
simple_language/src/test/testData/RenameTestData.java
Normal file
@ -0,0 +1,5 @@
|
||||
public class Test {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("simple:website<caret>");
|
||||
}
|
||||
}
|
13
simple_language/src/test/testData/RenameTestData.simple
Normal file
13
simple_language/src/test/testData/RenameTestData.simple
Normal file
@ -0,0 +1,13 @@
|
||||
# You are reading the ".properties" entry.
|
||||
! The exclamation mark can also mark text as comments.
|
||||
website = http://en.wikipedia.org/
|
||||
|
||||
language = English
|
||||
# The backslash below tells the application to continue reading
|
||||
# the value onto the next line.
|
||||
message = Welcome to \
|
||||
Wikipedia!
|
||||
# Add spaces to the key
|
||||
key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
|
||||
# Unicode
|
||||
tab : \u0009
|
13
simple_language/src/test/testData/RenameTestDataAfter.simple
Normal file
13
simple_language/src/test/testData/RenameTestDataAfter.simple
Normal file
@ -0,0 +1,13 @@
|
||||
# You are reading the ".properties" entry.
|
||||
! The exclamation mark can also mark text as comments.
|
||||
websiteUrl = http://en.wikipedia.org/
|
||||
|
||||
language = English
|
||||
# The backslash below tells the application to continue reading
|
||||
# the value onto the next line.
|
||||
message = Welcome to \
|
||||
Wikipedia!
|
||||
# Add spaces to the key
|
||||
key\ with\ spaces = This is the value that could be looked up with the key "key with spaces".
|
||||
# Unicode
|
||||
tab : \u0009
|
@ -3,6 +3,7 @@ package com.simpleplugin;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.folding.*;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
@ -12,7 +13,7 @@ import org.jetbrains.annotations.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SimpleFoldingBuilder extends FoldingBuilderEx {
|
||||
public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
@NotNull
|
||||
@Override
|
||||
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) {
|
||||
@ -52,7 +53,18 @@ public class SimpleFoldingBuilder extends FoldingBuilderEx {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getPlaceholderText(@NotNull ASTNode node) {
|
||||
return "...";
|
||||
String retTxt = "...";
|
||||
if ( node.getPsi() instanceof PsiLiteralExpression ) {
|
||||
PsiLiteralExpression nodeElement = (PsiLiteralExpression) node.getPsi();
|
||||
String key = ((String) nodeElement.getValue()).substring("simple:".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
|
||||
|
@ -27,19 +27,16 @@ public class SimpleParserDefinition implements ParserDefinition {
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
@ -49,19 +46,16 @@ public class SimpleParserDefinition implements ParserDefinition {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,6 @@ public class Test {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("simple:website");
|
||||
System.out.println("simple:key with spaces");
|
||||
System.out.println("simple:<error descr="Unresolved property">websit"</error>);
|
||||
System.out.println("simple:<error descr="Unresolved property">websit</error>");
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import com.intellij.codeInsight.generation.actions.CommentByLineCommentAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.simpleplugin.psi.SimpleProperty;
|
||||
@ -15,12 +15,13 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class SimpleCodeInsightTest extends LightCodeInsightFixtureTestCase {
|
||||
public class SimpleCodeInsightTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
// path to test data file directory relative to working directory in the run configuration for this test.
|
||||
@Override
|
||||
protected String getTestDataPath() { return "testData"; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user