Skip to content

Commit

Permalink
Code simplification and bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
pkernevez committed Aug 22, 2023
1 parent c016195 commit 3388328
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 32 deletions.
6 changes: 3 additions & 3 deletions src/main/kotlin/ch/kleis/lcaplugin/language/Lca.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
TYPE_RESOURCE_KEYWORD = 'Resource'
TYPE_LAND_USE_KEYWORD = 'Land_use'
COMPARTMENT_KEYWORD = 'compartment'
SUB_COMPARTMENT_KEYWORD = 'sub-compartment'
SUB_COMPARTMENT_KEYWORD = 'sub_compartment'
IMPACTS_KEYWORD = 'impacts'
META_KEYWORD = "meta"
FROM_KEYWORD = "from"
Expand All @@ -31,12 +31,12 @@
INDICATOR_KEYWORD = 'indicator'
VARIABLES_KEYWORD = 'variables'
UNIT_KEYWORD = 'unit'
REFERENCE_UNIT_KEYWORD = 'reference-unit'
REFERENCE_UNIT_KEYWORD = 'reference_unit'
ALIAS_FOR_KEYWORD = 'alias_for'
ALLOCATE_KEYWORD = 'allocate'
NAME_KEYWORD = 'name'
DIMENSION_KEYWORD = 'dimension'
PARAMETERS_KEYWORD = 'parameters'
PARAMETERS_KEYWORD = 'params'
INPUTS_KEYWORD = 'inputs'
EMISSIONS_KEYWORD = 'emissions'
RESOURCES_KEYWORD = 'resources'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,54 @@
package ch.kleis.lcaplugin.language.ide.syntax

import ch.kleis.lcaplugin.ide.template.ErrorHelper.Companion.containsAllErrors
import ch.kleis.lcaplugin.ide.template.ErrorHelper.Companion.isInErrorInRootBlock
import ch.kleis.lcaplugin.ide.template.ErrorHelper.Companion.isInErrorInSubBlock
import com.intellij.codeInsight.completion.CompletionContributor
import com.intellij.codeInsight.completion.CompletionParameters
import com.intellij.codeInsight.completion.CompletionResultSet
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.psi.PsiErrorElement


private val ALL_MANDATORY_SUB_BLOCK_KEYWORD = listOf(
"name", "type", "compartment", "sub_compartment", "reference_unit", // Substance
"symbol" // Unit
)

class LanguageCompletion : CompletionContributor() {


override fun fillCompletionVariants(parameters: CompletionParameters, result: CompletionResultSet) {
super.fillCompletionVariants(parameters, result)

if (isInErrorInRootBlock(parameters.position)) { // Root Block
result.addElements("package", "import", "process", "variables", "substance", "unit")
} else if (isInErrorInSubBlock(parameters.position)) { // Substance or Unit block
if (parameters.position.parent is PsiErrorElement) {
val parent = parameters.position.parent as PsiErrorElement
val expected = findExpectedToken(parent)
if (expected != null && expected in ALL_MANDATORY_SUB_BLOCK_KEYWORD) {
result.addElements(expected)
} else if (containsAllErrors(parent, "impacts", "meta")) { // Substance optional blocks
result.addElements("impacts", "meta")
} else if (containsAllErrors(parent, "Emission", "Resource", "Land_use")) { // Substance.type
result.addElements("Emission", "Resource", "Land_use")
} else if (containsAllErrors(parent, "dimension", "alias_for")) { // Unit exclusive alternatives
result.addElements("dimension", "alias_for")
} else {
// Nothing to complete
}
} else {
// Nothing to complete
result.addElements(*extractKeyWordFromError(parent).toTypedArray())
}
}

private val expectedPattern = Regex("LcaTokenType\\.(.*) expected, got")

private fun findExpectedToken(elt: PsiErrorElement): String? {
val grp = expectedPattern.find(elt.errorDescription)?.groupValues
return if (grp?.size == 2) grp[1] else null
private fun extractKeyWordFromError(elt: PsiErrorElement): List<String> {
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()
}
}

private val keywordWhiteList =
hashSetOf(
"meta", // All Blocks
"unit", "process", "substance", "import", "package", "variables", // Root
"name", "type", "compartment", "sub_compartment", "reference_unit", "impacts", // Substance block
"Emission", "Resource", "Land_use", // Substance types
"description", "author", "other", // Meta default keys
"reference_unit", "symbol", "dimension", "alias_for", // Unit block
"variables", "params", "labels", // Process Block
"products", "inputs", "resources", "emissions", "land_use", "impacts" // Process SubBlocks
)
private val listOfKeywordPattern = Regex("(LcaTokenType.*) expected, got")
private val keywordsPattern = Regex("LcaTokenType\\.([^ ,]*)(, | or |)")

private fun CompletionResultSet.addElements(vararg strings: String) {
strings.forEach { this.addElement(LookupElementBuilder.create(it)) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,30 @@ substance mySubstance {
}

@Test
fun lookup_ShouldReturnMetaAndSubstance_ForSubstanceMetaBlock() {
// Given
fixture.configureByText(
"sampleShouldReturnEmpty_ForSubstanceMetaBlock.lca", """
substance mySubstance {
name = "mySubstanceName"
type = Emission
compartment = "water"
sub_compartment = "sea water"
reference_unit = kg
<caret>
}
"""
)
fixture.complete(CompletionType.BASIC)

// When
val lookupElementStrings = fixture.lookupElementStrings

// Then
assertNotNull(lookupElementStrings)
assertSameElements(lookupElementStrings!!, "meta", "impacts")
}

fun lookup_ShouldReturnEmpty_ForSubstanceMetaBlock() {
// Given
fixture.configureByText(
Expand Down Expand Up @@ -220,6 +244,29 @@ substance mySubstance {
assertSameElements(lookupElementStrings!!, "Emission", "Resource", "Land_use")
}

@Test
fun lookup_ShouldReturnSubstanceSubCompartment_ForSubstance() {
// Given
fixture.configureByText(
"sampleShouldReturnEmpty_ForSubstanceMetaBlock.lca", """
substance mySubstance {
name = "myname"
type = Emission
compartment = "water"
<caret>
}
"""
)
fixture.complete(CompletionType.BASIC)

// When
val lookupElementStrings = fixture.lookupElementStrings

// Then
assertNotNull(lookupElementStrings)
assertSameElements(lookupElementStrings!!, "reference_unit", "sub_compartment")
}

@Test
fun lookup_ShouldReturnEmpty_ForSubstanceImpactBlock() {
// Given
Expand All @@ -243,4 +290,32 @@ substance name {
assertSameElements(lookupElementStrings!!)
}

@Test
fun lookup_ShouldReturnProcess_ForProcess() {
// Given
fixture.configureByText(
"sampleShouldReturnEmpty_ForSubstanceImpactBlock.lca", """
process p3 {
<caret>
}
"""
)
fixture.complete(CompletionType.BASIC)

// When
val lookupElementStrings = fixture.lookupElementStrings

// Then
assertNotNull(lookupElementStrings)
assertSameElements(
lookupElementStrings!!,
"emissions", "impacts", "inputs", "labels", "land_use", "meta", "params",
"products", "resources", "variables",

)
}


}

0 comments on commit 3388328

Please sign in to comment.