diff --git a/.github/workflows/idea-gradle-build-and-test.yml b/.github/workflows/idea-gradle-build-and-test.yml index d073874..41323ee 100644 --- a/.github/workflows/idea-gradle-build-and-test.yml +++ b/.github/workflows/idea-gradle-build-and-test.yml @@ -13,11 +13,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - name: Run tests and build plugin run: | cd IDEA diff --git a/IDEA/build.gradle.kts b/IDEA/build.gradle.kts index ec49037..17d584d 100644 --- a/IDEA/build.gradle.kts +++ b/IDEA/build.gradle.kts @@ -1,12 +1,13 @@ import org.jetbrains.grammarkit.tasks.GenerateLexerTask import org.jetbrains.grammarkit.tasks.GenerateParserTask import org.jetbrains.intellij.platform.gradle.TestFrameworkType +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - id("org.jetbrains.intellij.platform") version "2.0.1" - id("org.jetbrains.kotlin.jvm") version "2.0.20" - id("org.jetbrains.grammarkit") version "2022.3.2.2" + alias(libs.plugins.intellijPlattform) + alias(libs.plugins.kotlin) + alias(libs.plugins.grammarkit) } repositories { @@ -18,7 +19,7 @@ repositories { // Java target version java { - sourceCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 } sourceSets { @@ -29,33 +30,36 @@ sourceSets { kotlin { java { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + compilerOptions { + jvmTarget = JvmTarget.JVM_21 + freeCompilerArgs = listOf("-Xjvm-default=all") + } + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } } dependencies { intellijPlatform { - intellijIdeaCommunity("2024.2.1") + intellijIdeaCommunity("2025.1.1") bundledPlugins(listOf("com.intellij.java")) - instrumentationTools() testFramework(TestFrameworkType.Platform) } // From Kotlin documentation - implementation("org.jetbrains.kotlin:kotlin-stdlib:1.8.22") + implementation(libs.kotlin.stdlib) // just in case, version number specified in buildscript is used by default - implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.22") + implementation(libs.kotlin.reflect) // IntelliJ test framework needs junit 4. - testImplementation("junit:junit:4.13") - testRuntimeOnly("org.junit.vintage:junit-vintage-engine:5.7.0") + testImplementation(libs.junit4) + testRuntimeOnly(libs.junit.vintage.engine) // Use junit 5. - testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0") - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.7.0") + testImplementation(libs.junit.jupiter.api) + testRuntimeOnly(libs.junit.jupiter.engine) } // Configure Gradle IntelliJ Plugin @@ -74,39 +78,30 @@ intellijPlatform { } project(":") { - val generateLexer = task("generateMyLexer") { - sourceFile.set(file("src/main/grammar/KerboScript.flex")) - targetOutputDir.set(file("src/gen/ksp/kos/ideaplugin/parser")) -// targetClass.set("KerboScriptLexer") - purgeOldFiles.set(true) - } - - val generateParser = task("generateMyParser") { + val generateLexer = + tasks.register("generateMyLexer", fun GenerateLexerTask.() { + sourceFile.set(file("src/main/grammar/KerboScript.flex")) + targetOutputDir.set(file("src/gen/ksp/kos/ideaplugin/parser")) + purgeOldFiles.set(true) + }) + + val generateParser = tasks.register("generateMyParser", fun GenerateParserTask.() { sourceFile.set(file("src/main/grammar/KerboScript.bnf")) targetRootOutputDir.set(file("src/gen")) pathToParser.set("/ksp/kos/ideaplugin/parser/KerboScriptParser.java") pathToPsiRoot.set("/ksp/kos/ideaplugin/psi") purgeOldFiles.set(true) - } + }) tasks { withType { dependsOn(generateLexer, generateParser) } - // Set the compatibility versions to 17 + // Set the compatibility versions to 21 withType { - sourceCompatibility = "17" - targetCompatibility = "17" - } - - listOf("compileKotlin", "compileTestKotlin").forEach { - getByName(it) { - kotlinOptions { - jvmTarget = "17" - freeCompilerArgs = listOf("-Xjvm-default=all") - } - } + sourceCompatibility = "21" + targetCompatibility = "21" } publishPlugin { diff --git a/IDEA/gradle/libs.versions.toml b/IDEA/gradle/libs.versions.toml new file mode 100644 index 0000000..592b21e --- /dev/null +++ b/IDEA/gradle/libs.versions.toml @@ -0,0 +1,21 @@ +[versions] +intellij = "2.5.0" +kotlin = "2.1.20" +kotlin-std-lib = "1.8.22" +grammarkit = "2022.3.2.2" +junit4 = "4.13.1" +junit5 = "5.7.0" + +[libraries] +kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } + +junit4 = { module = "junit:junit", version.ref = "junit4" } +junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit5" } +junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit5"} +junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5"} + +[plugins] +intellijPlattform = { id = "org.jetbrains.intellij.platform", version.ref = "intellij" } +kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +grammarkit = { id = "org.jetbrains.grammarkit", version.ref = "grammarkit" } \ No newline at end of file diff --git a/IDEA/gradle/wrapper/gradle-wrapper.properties b/IDEA/gradle/wrapper/gradle-wrapper.properties index 28f5fcf..c6406bc 100644 --- a/IDEA/gradle/wrapper/gradle-wrapper.properties +++ b/IDEA/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/IDEA/src/main/grammar/KerboScript.bnf b/IDEA/src/main/grammar/KerboScript.bnf index 6ad5359..eb03e12 100644 --- a/IDEA/src/main/grammar/KerboScript.bnf +++ b/IDEA/src/main/grammar/KerboScript.bnf @@ -25,7 +25,7 @@ tokenTypeClass="ksp.kos.ideaplugin.psi.KerboScriptTokenType" extends(".*_stmt|directive|instruction_block")=instruction - extends("lazyglobal_directive")=directive + extends("lazyglobal_directive|clobberbuiltins_directive")=directive extends("function_trailer|array_trailer")=suffixterm_trailer extends("[a-z]*_expr|factor|suffix|suffixterm|atom|.*number")=expr @@ -109,13 +109,14 @@ ALL = 'regexp:(?i)all' IDENTIFIER = 'regexp:[a-zA-Z_][a-zA-Z0-9_]*' FILEIDENT = 'regexp:[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z0-9_][a-zA-Z0-9_]*)*' - INTEGER = 'regexp:[0-9]+' - DOUBLE = 'regexp:[0-9]*\.[0-9]+' + INTEGER = 'regexp:[0-9][0-9_]*' + DOUBLE = 'regexp:([0-9]+(_[0-9]*)*)?\.[0-9]+(_[0-9]*)*' STRING = 'regexp:@?"(""|[^"])*"' EOI = '.' //Compiler Directives ATSIGN = '@' LAZYGLOBAL = 'regexp:(?i)lazyglobal' + CLOBBERBUILTINS = 'regexp:(?i)clobberbuiltins' //Special //EOF = '$' //[Skip] @@ -127,7 +128,7 @@ // Rules // =================================================== -Start ::= (instruction)* +Start ::= (directive|instruction)* instruction_block ::= CURLYOPEN instruction* CURLYCLOSE instruction ::= !(CURLYCLOSE | <>) instruction_inner { pin = 1 @@ -174,7 +175,6 @@ private instruction_inner ::= empty_stmt | unset_stmt | instruction_block | identifier_led_stmt | // any statement that starts with an identifier. - directive // allow directives anywhere for now, let the compiler decide if it's in the wrong place, not the parser. // ------------ directives -------------------- lazyglobal_directive ::= LAZYGLOBAL onoff_trailer EOI diff --git a/IDEA/src/main/grammar/KerboScript.flex b/IDEA/src/main/grammar/KerboScript.flex index ac47730..ea53a83 100644 --- a/IDEA/src/main/grammar/KerboScript.flex +++ b/IDEA/src/main/grammar/KerboScript.flex @@ -98,8 +98,8 @@ ARRAYINDEX = # ALL = all IDENTIFIER = [a-zA-Z_][a-zA-Z0-9_]* FILEIDENT = [a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z0-9_][a-zA-Z0-9_]*)* -INTEGER = [0-9]+ -DOUBLE = [0-9]*\.[0-9]+ +INTEGER = [0-9][0-9_]* +DOUBLE = ([0-9]+(_[0-9]*)*)?\.[0-9]+(_[0-9]*)* STRING = @?\"(\"\"|[^\"])*\" EOI = \. //Compiler Directives diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/Magic.kt b/IDEA/src/main/java/ksp/kos/ideaplugin/Magic.kt index e0a7a05..2d6d525 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/Magic.kt +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/Magic.kt @@ -58,6 +58,7 @@ object Magic { KerboScriptTypes.UNSET, KerboScriptTypes.CHOOSE, KerboScriptTypes.ATSIGN, - KerboScriptTypes.LAZYGLOBAL + KerboScriptTypes.LAZYGLOBAL, + KerboScriptTypes.CLOBBERBUILTINS ) } \ No newline at end of file diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/actions/differentiate/DiffContext.java b/IDEA/src/main/java/ksp/kos/ideaplugin/actions/differentiate/DiffContext.java index 529c311..d400765 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/actions/differentiate/DiffContext.java +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/actions/differentiate/DiffContext.java @@ -35,8 +35,8 @@ public DiffContext(FileContext origFile, FileDuality diffFile, FileContextResolv registerFile(origFile.getName()); } - public static List> createDiffResolvers(FileContextResolver fileResolver) { - List> resolvers = FileContext.createResolvers(fileResolver); + public static List createDiffResolvers(FileContextResolver fileResolver) { + List resolvers = FileContext.createResolvers(fileResolver); resolvers.add((context, reference, createAllowed) -> { if (createAllowed && reference.getName().endsWith("_")) { String name1 = reference.getName(); diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/completion/KerboScriptKeywordProvider.kt b/IDEA/src/main/java/ksp/kos/ideaplugin/completion/KerboScriptKeywordProvider.kt index e4790a0..fe85462 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/completion/KerboScriptKeywordProvider.kt +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/completion/KerboScriptKeywordProvider.kt @@ -6,6 +6,7 @@ import com.intellij.codeInsight.completion.CompletionResultSet import com.intellij.codeInsight.lookup.LookupElementBuilder import com.intellij.util.ProcessingContext import ksp.kos.ideaplugin.Magic +import java.util.Locale class KerboScriptKeywordProvider : CompletionProvider() { override fun addCompletions(completionParameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) { @@ -15,8 +16,8 @@ class KerboScriptKeywordProvider : CompletionProvider() { // when you type in lowercase, the completion shows uppercase (which can be somewhat unreadable when // you're not used to it). listOf( - LookupElementBuilder.create(it.toString().toUpperCase()), - LookupElementBuilder.create(it.toString().toLowerCase()) + LookupElementBuilder.create(it.toString().uppercase(Locale.getDefault())), + LookupElementBuilder.create(it.toString().lowercase(Locale.getDefault())) ) }) } diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/dataflow/ContextBuilder.java b/IDEA/src/main/java/ksp/kos/ideaplugin/dataflow/ContextBuilder.java index a3a3af4..8c21bb6 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/dataflow/ContextBuilder.java +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/dataflow/ContextBuilder.java @@ -31,12 +31,14 @@ public void visit(ExpressionVisitor visitor) { } public String getText() { - String text = ""; + StringBuilder text = new StringBuilder(); for (Flow flow : getList()) { - if (!text.isEmpty()) text += "\n"; - text += flow.getText(); + if (!text.isEmpty()) { + text.append("\n"); + } + text.append(flow.getText()); } - return text; + return text.toString(); } public void differentiate(LocalContext context, ContextBuilder contextBuilder) { diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/highlighting/KerboScriptSyntaxHighlighter.java b/IDEA/src/main/java/ksp/kos/ideaplugin/highlighting/KerboScriptSyntaxHighlighter.java index 8383933..3ebb099 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/highlighting/KerboScriptSyntaxHighlighter.java +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/highlighting/KerboScriptSyntaxHighlighter.java @@ -81,7 +81,8 @@ public class KerboScriptSyntaxHighlighter extends SyntaxHighlighterBase { KerboScriptTypes.UNSET, KerboScriptTypes.CHOOSE, KerboScriptTypes.ATSIGN, - KerboScriptTypes.LAZYGLOBAL + KerboScriptTypes.LAZYGLOBAL, + KerboScriptTypes.CLOBBERBUILTINS ) ); @@ -93,7 +94,7 @@ public Lexer getHighlightingLexer() { @NotNull @Override - public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + public TextAttributesKey @NotNull [] getTokenHighlights(IElementType tokenType) { // TODO - Ideally syntax highlight based off of parser, not lexer, to handle keywords used as variables. if (tokenType.equals(KerboScriptTypes.IDENTIFIER)) { return createKeys(IDENTIFIER); diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/psi/KerboScriptNamedElement.kt b/IDEA/src/main/java/ksp/kos/ideaplugin/psi/KerboScriptNamedElement.kt index 43558ec..1122bf9 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/psi/KerboScriptNamedElement.kt +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/psi/KerboScriptNamedElement.kt @@ -1,16 +1,16 @@ package ksp.kos.ideaplugin.psi import com.intellij.openapi.util.Key +import com.intellij.psi.PsiElement import com.intellij.psi.util.CachedValue import ksp.kos.ideaplugin.dataflow.FlowParser import ksp.kos.ideaplugin.dataflow.ReferenceFlow +import ksp.kos.ideaplugin.reference.OccurrenceType import ksp.kos.ideaplugin.reference.PsiSelfResolvable import ksp.kos.ideaplugin.reference.ReferableType import ksp.kos.ideaplugin.reference.Reference import ksp.kos.ideaplugin.reference.ReferenceType import ksp.kos.ideaplugin.reference.context.LocalContext -import com.intellij.psi.PsiElement -import ksp.kos.ideaplugin.reference.* import ksp.kos.ideaplugin.reference.context.PsiDuality import java.util.function.Supplier @@ -23,7 +23,6 @@ interface KerboScriptNamedElement : KerboScriptBase, PsiSelfResolvable { var type: ReferenceType // TODO duality can be pure virtual - @JvmDefault val cachedFlow: ReferenceFlow<*> get() { var cached = getUserData(FLOW_KEY) @@ -34,20 +33,15 @@ interface KerboScriptNamedElement : KerboScriptBase, PsiSelfResolvable { return cached.value } - @JvmDefault override fun getKingdom(): LocalContext = scope.cachedScope - @JvmDefault override fun getReferableType(): ReferableType = type.type - @JvmDefault val isDeclaration: Boolean get() = type.occurrenceType.isDeclaration - @JvmDefault override fun resolve(): KerboScriptNamedElement = if (isDeclaration) this else super.resolve() - @JvmDefault override fun matches(declaration: Reference): Boolean { val declarationElement = when (declaration) { is PsiDuality -> declaration.syntax diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/FileContext.kt b/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/FileContext.kt index 7dfe5d2..2f60589 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/FileContext.kt +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/FileContext.kt @@ -20,7 +20,7 @@ import java.net.URL abstract class FileContext protected constructor( parent: LocalContext?, private val name: String, - resolvers: List>, + resolvers: List, ) : LocalContext(parent, resolvers), ReferenceFlow, FileDuality { constructor(parent: LocalContext?, name: String, fileResolver: FileContextResolver) @@ -43,7 +43,7 @@ abstract class FileContext protected constructor( } } - class FileResolver(private val fileContextResolver: FileContextResolver) : ReferenceResolver { + class FileResolver(private val fileContextResolver: FileContextResolver) : ReferenceResolver { override fun resolve(context: LocalContext, reference: Reference, createAllowed: Boolean): Duality? = if (reference.referableType == ReferableType.FILE) { fileContextResolver.resolveFile(reference.name) @@ -54,7 +54,7 @@ abstract class FileContext protected constructor( override fun getSemantics(): FileContext = this - class ImportsResolver(private val fileContextResolver: FileContextResolver) : ReferenceResolver { + class ImportsResolver(private val fileContextResolver: FileContextResolver) : ReferenceResolver { override fun resolve(context: LocalContext, reference: Reference, createAllowed: Boolean): Duality? = context.getDeclarations(ReferableType.FILE) .values @@ -66,7 +66,7 @@ abstract class FileContext protected constructor( .firstOrNull() } - class BuiltinResolver : ReferenceResolver { + class BuiltinResolver : ReferenceResolver { override fun resolve(context: LocalContext, reference: Reference, createAllowed: Boolean): Duality? { if (ksFile == null) { tryGetBuiltinKsFile() @@ -102,7 +102,7 @@ abstract class FileContext protected constructor( companion object { @JvmStatic - fun createResolvers(fileResolver: FileContextResolver): MutableList> = + fun createResolvers(fileResolver: FileContextResolver) = mutableListOf( FileResolver(fileResolver), LocalResolver(), diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/LocalContext.kt b/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/LocalContext.kt index 73a11f4..6c5b3f8 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/LocalContext.kt +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/LocalContext.kt @@ -4,7 +4,8 @@ import ksp.kos.ideaplugin.psi.KerboScriptNamedElement import ksp.kos.ideaplugin.reference.OccurrenceType import ksp.kos.ideaplugin.reference.ReferableType import ksp.kos.ideaplugin.reference.Reference -import java.util.* +import java.util.EnumMap +import java.util.Locale /** * Created on 04/10/16. @@ -13,7 +14,7 @@ import java.util.* */ open class LocalContext @JvmOverloads constructor( val parent: LocalContext?, - private val resolvers: List> = createResolvers(), + private val resolvers: List = createResolvers(), ) { private val declarations: MutableMap> = EnumMap(ksp.kos.ideaplugin.reference.ReferableType::class.java) @@ -78,12 +79,22 @@ open class LocalContext @JvmOverloads constructor( val fileContext: FileContext? get() = (this as? FileContext) ?: parent?.fileContext - class ScopeMap : LinkedHashMap() { - private fun String.normalize(): String = this.toLowerCase() + class ScopeMap( + private val delegate: MutableMap = LinkedHashMap() + ) : MutableMap by delegate { + private fun String.normalize(): String = this.lowercase(Locale.getDefault()) - override fun put(key: String, value: T): T? = super.put(key.normalize(), value) + override fun put(key: String, value: T): T? = delegate.put(key.normalize(), value) - override fun get(key: String): T? = super.get(key.normalize()) + override fun get(key: String): T? = delegate[key.normalize()] + + override fun containsKey(key: String): Boolean = delegate.containsKey(key.normalize()) + + override fun getOrDefault(key: String, defaultValue: T) = delegate.getOrDefault(key.normalize(), defaultValue) + + override fun remove(key: String): T? = delegate.remove(key.normalize()) + + override fun remove(key: String, value: T): Boolean = delegate.remove(key.normalize(), value) } /** @@ -91,7 +102,7 @@ open class LocalContext @JvmOverloads constructor( * * @author ptasha */ - class LocalResolver : ReferenceResolver { + class LocalResolver : ReferenceResolver { override fun resolve(context: LocalContext, reference: Reference, createAllowed: Boolean): Duality? = context.findLocalDeclaration(reference) } @@ -101,13 +112,13 @@ open class LocalContext @JvmOverloads constructor( * * @author ptasha */ - open class ParentResolver : ReferenceResolver { + open class ParentResolver : ReferenceResolver { override fun resolve(context: LocalContext, reference: Reference, createAllowed: Boolean): Duality? = context.parent?.resolve(reference, createAllowed) } companion object { - fun createResolvers(): List> = + fun createResolvers(): List = listOf( LocalResolver(), ParentResolver(), diff --git a/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/ReferenceResolver.java b/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/ReferenceResolver.java index 3085538..015f1a7 100644 --- a/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/ReferenceResolver.java +++ b/IDEA/src/main/java/ksp/kos/ideaplugin/reference/context/ReferenceResolver.java @@ -9,6 +9,6 @@ * * @author ptasha */ -public interface ReferenceResolver { - @Nullable Duality resolve(C context, @NotNull Reference reference, boolean createAllowed); +public interface ReferenceResolver{ + @Nullable Duality resolve(LocalContext context, @NotNull Reference reference, boolean createAllowed); } diff --git a/IDEA/src/test/kotlin/ksp/kos/ideaplugin/parsing/KerboScriptParsingTest.kt b/IDEA/src/test/kotlin/ksp/kos/ideaplugin/parsing/KerboScriptParsingTest.kt index 62141d4..cb50987 100644 --- a/IDEA/src/test/kotlin/ksp/kos/ideaplugin/parsing/KerboScriptParsingTest.kt +++ b/IDEA/src/test/kotlin/ksp/kos/ideaplugin/parsing/KerboScriptParsingTest.kt @@ -10,4 +10,5 @@ class KerboScriptParsingTest : ParsingTestCase("", "ks", KerboScriptParserDefini fun testBasic() = doTest(true) fun testErrorRecovery() = doTest(true) + fun testAnnotations() = doTest(true) } diff --git a/IDEA/src/test/testData/parsing/Annotations.ks b/IDEA/src/test/testData/parsing/Annotations.ks new file mode 100644 index 0000000..ebda004 --- /dev/null +++ b/IDEA/src/test/testData/parsing/Annotations.ks @@ -0,0 +1,5 @@ +@LAZYGLOBAL OFF. +@CLOBBERBUILTINS ON. + +local decimalsWith_ is 10_000.00. +local integerWith_ is 10_000. diff --git a/IDEA/src/test/testData/parsing/Annotations.txt b/IDEA/src/test/testData/parsing/Annotations.txt new file mode 100644 index 0000000..3a9501e --- /dev/null +++ b/IDEA/src/test/testData/parsing/Annotations.txt @@ -0,0 +1,48 @@ +FILE(0,102) + KerboScriptDirectiveImpl(DIRECTIVE)(0,16) + PsiElement(@)('@')(0,1) + KerboScriptLazyglobalDirectiveImpl(LAZYGLOBAL_DIRECTIVE)(1,16) + PsiElement(LAZYGLOBAL)('LAZYGLOBAL')(1,11) + PsiWhiteSpace(' ')(11,12) + KerboScriptOnoffTrailerImpl(ONOFF_TRAILER)(12,15) + PsiElement(OFF)('OFF')(12,15) + PsiElement(.)('.')(15,16) + PsiWhiteSpace('\n')(16,17) + KerboScriptDirectiveImpl(DIRECTIVE)(17,37) + PsiElement(@)('@')(17,18) + KerboScriptClobberbuiltinsDirectiveImpl(CLOBBERBUILTINS_DIRECTIVE)(18,37) + PsiElement(CLOBBERBUILTINS)('CLOBBERBUILTINS')(18,33) + PsiWhiteSpace(' ')(33,34) + KerboScriptOnoffTrailerImpl(ONOFF_TRAILER)(34,36) + PsiElement(ON)('ON')(34,36) + PsiElement(.)('.')(36,37) + PsiWhiteSpace('\n\n')(37,39) + KerboScriptDeclareStmtImpl(DECLARE_STMT)(39,72) + PsiElement(LOCAL)('local')(39,44) + PsiWhiteSpace(' ')(44,45) + KerboScriptDeclareIdentifierClauseImpl(DECLARE_IDENTIFIER_CLAUSE)(45,72) + KerboScriptIdentImpl(IDENT)(45,58) + PsiElement(IDENTIFIER)('decimalsWith_')(45,58) + PsiWhiteSpace(' ')(58,59) + PsiElement(IS)('is')(59,61) + PsiWhiteSpace(' ')(61,62) + KerboScriptSuffixtermImpl(SUFFIXTERM)(62,71) + KerboScriptAtomImpl(ATOM)(62,71) + KerboScriptNumberImpl(NUMBER)(62,71) + PsiElement(DOUBLE)('10_000.00')(62,71) + PsiElement(.)('.')(71,72) + PsiWhiteSpace('\n')(72,73) + KerboScriptDeclareStmtImpl(DECLARE_STMT)(73,102) + PsiElement(LOCAL)('local')(73,78) + PsiWhiteSpace(' ')(78,79) + KerboScriptDeclareIdentifierClauseImpl(DECLARE_IDENTIFIER_CLAUSE)(79,102) + KerboScriptIdentImpl(IDENT)(79,91) + PsiElement(IDENTIFIER)('integerWith_')(79,91) + PsiWhiteSpace(' ')(91,92) + PsiElement(IS)('is')(92,94) + PsiWhiteSpace(' ')(94,95) + KerboScriptSuffixtermImpl(SUFFIXTERM)(95,101) + KerboScriptAtomImpl(ATOM)(95,101) + KerboScriptNumberImpl(NUMBER)(95,101) + PsiElement(INTEGER)('10_000')(95,101) + PsiElement(.)('.')(101,102) \ No newline at end of file