diff --git a/gradle.properties b/gradle.properties index 4ee453f2e..e29bb3685 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,4 @@ javaVersion=17 gradleVersion=7.6 org.gradle.jvmargs=-Xmx4096m lcaacGroup=ch.kleis.lcaac -lcaacVersion=1.7.12 +lcaacVersion=1.8.0 diff --git a/plugin/CHANGELOG.md b/plugin/CHANGELOG.md index 899608459..176290877 100644 --- a/plugin/CHANGELOG.md +++ b/plugin/CHANGELOG.md @@ -4,6 +4,11 @@ ## [Unreleased] +## [1.8.0] + +- Updated dependency LCAAC core +- Support for annotation @cached + ## [1.7.12] - Adapt to latest idea build `251.*` diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 7103b3c35..1b60cf320 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -47,7 +47,7 @@ sourceSets { } dependencies { - implementation("ch.kleis.lcaac:core:1.7.11") + implementation("ch.kleis.lcaac:core:1.8.0") implementation(files(layout.buildDirectory.dir("stdlib/ef3.1")) { builtBy("generateEmissionFactors31") diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/ActionHelper.kt b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/ActionHelper.kt index f352f6089..2f3b5c6cc 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/ActionHelper.kt +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/ActionHelper.kt @@ -3,10 +3,9 @@ package ch.kleis.lcaac.plugin.actions import ch.kleis.lcaac.core.datasource.ConnectorFactory import ch.kleis.lcaac.core.datasource.DefaultDataSourceOperations import ch.kleis.lcaac.core.datasource.csv.CsvConnectorBuilder -import ch.kleis.lcaac.core.datasource.resilio_db.ResilioDbConnectorBuilder import ch.kleis.lcaac.core.lang.evaluator.EvaluationTrace import ch.kleis.lcaac.core.lang.evaluator.Evaluator -import ch.kleis.lcaac.core.math.QuantityOperations +import ch.kleis.lcaac.core.math.Operations import ch.kleis.lcaac.plugin.ide.config.LcaacConfigExtensions import ch.kleis.lcaac.plugin.language.loader.LcaFileCollector import ch.kleis.lcaac.plugin.language.loader.LcaLoader @@ -14,12 +13,12 @@ import ch.kleis.lcaac.plugin.language.psi.LcaFile import com.intellij.openapi.application.runReadAction import com.intellij.openapi.progress.ProgressIndicator -fun traceSystemWithIndicator( +fun traceSystemWithIndicator( indicator: ProgressIndicator, file: LcaFile, processName: String, matchLabels: Map, - ops: QuantityOperations, + ops: Operations, ): EvaluationTrace { indicator.isIndeterminate = true @@ -42,7 +41,6 @@ fun traceSystemWithIndicator( symbolTable, listOf( CsvConnectorBuilder(), - ResilioDbConnectorBuilder(), ) ) val sourceOps = DefaultDataSourceOperations(ops, config, factory.buildConnectors()) diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/csv/CsvProcessor.kt b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/csv/CsvProcessor.kt index 50667ffb8..ed56c92cf 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/csv/CsvProcessor.kt +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/csv/CsvProcessor.kt @@ -5,7 +5,6 @@ import ch.kleis.lcaac.core.config.LcaacConfig import ch.kleis.lcaac.core.datasource.ConnectorFactory import ch.kleis.lcaac.core.datasource.DefaultDataSourceOperations import ch.kleis.lcaac.core.datasource.csv.CsvConnectorBuilder -import ch.kleis.lcaac.core.datasource.resilio_db.ResilioDbConnectorBuilder import ch.kleis.lcaac.core.lang.SymbolTable import ch.kleis.lcaac.core.lang.evaluator.Evaluator import ch.kleis.lcaac.core.lang.evaluator.EvaluatorException @@ -30,7 +29,6 @@ class CsvProcessor( symbolTable, listOf( CsvConnectorBuilder(), - ResilioDbConnectorBuilder(), ) ) private val sourceOps = DefaultDataSourceOperations(ops, config, factory.buildConnectors()) diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/tasks/SensitivityAnalysisTask.kt b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/tasks/SensitivityAnalysisTask.kt index 9ef3154e8..db39883b4 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/tasks/SensitivityAnalysisTask.kt +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/actions/tasks/SensitivityAnalysisTask.kt @@ -8,7 +8,6 @@ import ch.kleis.lcaac.core.datasource.ConnectorFactory import ch.kleis.lcaac.core.datasource.DataSourceOperations import ch.kleis.lcaac.core.datasource.DefaultDataSourceOperations import ch.kleis.lcaac.core.datasource.csv.CsvConnectorBuilder -import ch.kleis.lcaac.core.datasource.resilio_db.ResilioDbConnectorBuilder import ch.kleis.lcaac.core.lang.SymbolTable import ch.kleis.lcaac.core.lang.evaluator.Evaluator import ch.kleis.lcaac.core.lang.evaluator.ToValue @@ -99,7 +98,6 @@ class SensitivityAnalysisTask( symbolTable, listOf( CsvConnectorBuilder(), - ResilioDbConnectorBuilder(), ) ) val sourceOps = DefaultDataSourceOperations(ops, config, factory.buildConnectors()) diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/ide/template/ErrorHelper.kt b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/ide/template/ErrorHelper.kt index a1e57f4b6..5be208f28 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/ide/template/ErrorHelper.kt +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/ide/template/ErrorHelper.kt @@ -1,6 +1,5 @@ package ch.kleis.lcaac.plugin.ide.template -import ch.kleis.lcaac.plugin.psi.LcaTypes import com.intellij.psi.PsiElement import com.intellij.psi.PsiErrorElement @@ -13,8 +12,8 @@ class ErrorHelper { containsAllErrors(parent, "process", "substance") } - fun containsAllErrors(elt: PsiErrorElement, vararg strings: String): Boolean { - return strings.all { elt.errorDescription.contains("LcaTokenType.${it}") } + private fun containsAllErrors(elt: PsiErrorElement, vararg strings: String): Boolean { + return strings.all { elt.errorDescription.contains(it) } } } diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/Lca.bnf b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/Lca.bnf index 50fab39f4..96e5ff771 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/Lca.bnf +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/Lca.bnf @@ -83,6 +83,8 @@ HAT = "^" EQUAL = "=" DOUBLE_QUOTE = '"' + + ANNOTATION_CACHED_KEYWORD = '@cached' ] } @@ -218,7 +220,7 @@ aliasForField ::= "alias_for" "=" dataExpression Process */ -process ::= "process" processRef +process ::= annotation* "process" processRef "{" ( params | labels @@ -237,6 +239,8 @@ process ::= "process" processRef stubClass = "ch.kleis.lcaac.plugin.language.psi.stub.process.ProcessStub" } +annotation ::= "@cached" + labels ::= "labels" "{" labelAssignment* "}" labelAssignment ::= labelRef "=" STRING_LITERAL { implements=["ch.kleis.lcaac.plugin.language.psi.type.PsiLabelAssignment"] diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/Lca.flex b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/Lca.flex index 9c54d7e1d..b26110467 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/Lca.flex +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/Lca.flex @@ -98,6 +98,8 @@ CommentContent = .* "between" { return LcaTypes.BETWEEN_KEYWORD; } "and" { return LcaTypes.AND_KEYWORD; } + "@cached" { return LcaTypes.ANNOTATION_CACHED_KEYWORD; } + "datasource" { return LcaTypes.DATASOURCE_KEYWORD; } "location" { return LcaTypes.LOCATION_KEYWORD; } "schema" { return LcaTypes.SCHEMA_KEYWORD; } diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LanguageCompletion.kt b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LanguageCompletion.kt index 751f2eb1d..4a1221885 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LanguageCompletion.kt +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LanguageCompletion.kt @@ -11,8 +11,6 @@ class LanguageCompletion : CompletionContributor() { override fun fillCompletionVariants(parameters: CompletionParameters, result: CompletionResultSet) { - super.fillCompletionVariants(parameters, result) - if (parameters.position.parent is PsiErrorElement) { val parent = parameters.position.parent as PsiErrorElement result.addElements(*extractKeyWordFromError(parent).toTypedArray()) @@ -21,22 +19,21 @@ class LanguageCompletion : CompletionContributor() { private fun extractKeyWordFromError(elt: PsiErrorElement): List { - val grp = listOfKeywordPattern.find(elt.errorDescription)?.groupValues - return if (grp?.size == 2) { - val errors = grp[1] - keywordsPattern.findAll(errors) - .map { it.groupValues } - .filter { it.size >= 2 } - .map { it[1] } - .filter { it in keywordWhiteList } - .toList() - } else { - listOf() - } + val description = elt.errorDescription + val matchingSuggestions = keys.filter { + description.contains(it) + }.mapNotNull { suggestions[it] }.flatten() + val suggestionsToRemove = matchingSuggestions + .map { + matchingSuggestions.filter { suggestion -> + it != suggestion && it.contains(suggestion) } + }.flatten().toSet() + return matchingSuggestions.minus(suggestionsToRemove) } - private val keywordWhiteList = - hashSetOf( + + private val keys = + listOf( "meta", // All Blocks "unit", "process", "substance", "import", "package", "variables", // Root "name", "type", "compartment", "sub_compartment", "reference_unit", "impacts", // Substance block @@ -50,8 +47,11 @@ class LanguageCompletion : CompletionContributor() { "for_each", // For each "sum", "lookup", "default_record" // Primitives ) - private val listOfKeywordPattern = Regex("(LcaTokenType.*) expected, got") - private val keywordsPattern = Regex("LcaTokenType\\.([^ ,]*)(, | or |)") + private val suggestions: Map> = + keys.associateWith { listOf(it) } + .plus( + "process" to listOf("process", "@cached") + ) private fun CompletionResultSet.addElements(vararg strings: String) { strings.forEach { this.addElement(LookupElementBuilder.create(it)) } diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LcaSyntaxHighlighter.kt b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LcaSyntaxHighlighter.kt index 007d2e009..ffdcec685 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LcaSyntaxHighlighter.kt +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LcaSyntaxHighlighter.kt @@ -22,6 +22,7 @@ class LcaSyntaxHighlighter : SyntaxHighlighterBase() { DefaultLanguageHighlighterColors.IDENTIFIER ) ) + val ANNOTATION_KEYS = arrayOf(createTextAttributesKey("LCA_ANNOTATION", DefaultLanguageHighlighterColors.DOC_COMMENT_TAG_VALUE)) val EMPTY_KEYS = emptyArray() val BAD_CHARACTER_KEYS = arrayOf(createTextAttributesKey("SIMPLE_BAD_CHARACTER", BAD_CHARACTER)) val STRING_LITERAL_KEYS = @@ -64,6 +65,8 @@ class LcaSyntaxHighlighter : SyntaxHighlighterBase() { COMMENT_BLOCK_START, COMMENT_BLOCK_END, COMMENT_LINE, COMMENT_CONTENT -> BLOCK_COMMENT_KEYS + ANNOTATION_CACHED_KEYWORD -> ANNOTATION_KEYS + else -> EMPTY_KEYS } } diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/loader/LcaMapper.kt b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/loader/LcaMapper.kt index 6cec2ef8f..3dd7b349b 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/loader/LcaMapper.kt +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/language/loader/LcaMapper.kt @@ -66,13 +66,24 @@ class LcaMapper( biosphere = biosphere, impacts = impacts, ) + val annotations = annotations(psiProcess.annotationList) return EProcessTemplate( params, locals, body, + annotations, ) } + private fun annotations(psiAnnotationList: List): Set { + return psiAnnotationList.mapNotNull { + when (it.text) { + "@cached" -> ProcessAnnotation.CACHED + else -> null + } + }.toSet() + } + private fun generateTechnoProductExchanges( psiProcess: PsiProcess, symbolTable: SymbolTable, diff --git a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/testing/LcaTestRunner.kt b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/testing/LcaTestRunner.kt index e568f3576..c3989da0e 100644 --- a/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/testing/LcaTestRunner.kt +++ b/plugin/src/main/kotlin/ch/kleis/lcaac/plugin/testing/LcaTestRunner.kt @@ -4,7 +4,6 @@ import ch.kleis.lcaac.core.assessment.ContributionAnalysisProgram import ch.kleis.lcaac.core.datasource.ConnectorFactory import ch.kleis.lcaac.core.datasource.DefaultDataSourceOperations import ch.kleis.lcaac.core.datasource.csv.CsvConnectorBuilder -import ch.kleis.lcaac.core.datasource.resilio_db.ResilioDbConnectorBuilder import ch.kleis.lcaac.core.lang.SymbolTable import ch.kleis.lcaac.core.lang.evaluator.Evaluator import ch.kleis.lcaac.core.lang.evaluator.EvaluatorException @@ -66,7 +65,6 @@ class LcaTestRunner( symbolTable, listOf( CsvConnectorBuilder(), - ResilioDbConnectorBuilder(), ) ) val sourceOps = DefaultDataSourceOperations(ops, config, factory.buildConnectors()) diff --git a/plugin/src/test/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LanguageCompletionTest.kt b/plugin/src/test/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LanguageCompletionTest.kt index 154cc45fc..7f08ed7c4 100644 --- a/plugin/src/test/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LanguageCompletionTest.kt +++ b/plugin/src/test/kotlin/ch/kleis/lcaac/plugin/language/ide/syntax/LanguageCompletionTest.kt @@ -28,7 +28,8 @@ class LanguageCompletionTest : LcaCompletionTestCase() { "unit", "variables", "test", - "datasource" + "datasource", + "@cached" ) } diff --git a/plugin/src/test/kotlin/ch/kleis/lcaac/plugin/language/loader/LcaLoaderTest.kt b/plugin/src/test/kotlin/ch/kleis/lcaac/plugin/language/loader/LcaLoaderTest.kt index 6b0e0ef57..dc7df1cd8 100644 --- a/plugin/src/test/kotlin/ch/kleis/lcaac/plugin/language/loader/LcaLoaderTest.kt +++ b/plugin/src/test/kotlin/ch/kleis/lcaac/plugin/language/loader/LcaLoaderTest.kt @@ -61,6 +61,31 @@ class LcaLoaderTest : ParsingTestCase("", "lca", LcaParserDefinition()) { assertEquals(expected, actual) } + @Test + fun test_annotationCached() { + // given + val file = parseFile( + "hello", """ + @cached + process p { + } + """.trimIndent() + ) as LcaFile + val parser = LcaLoader( + sequenceOf(file), + ops, + ) + + // when + val actual = parser.load().getTemplate("p")!!.annotations + + // then + val expected = setOf( + ProcessAnnotation.CACHED + ) + assertEquals(expected, actual) + } + @Test fun test_impactBlockForEach() { // given