diff --git a/CHANGELOG.md b/CHANGELOG.md index aa2c12b9b..b7f59bd79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,18 +2,18 @@ ## 1.3.20 -* [X] 适用于规则文件的代码补全,也适用于插件或者规则仓库中的CWT文件 * +* [X] 适用于规则文件的代码补全,也适用于插件或者规则仓库中的CWT文件 * [X] 完善脚本文件与本地化文件的词法器与解析器,修复存在的一些问题 -* [X] 完善对本地化命令的支持 * -* [ ] 完善参数对应的规则的推断与合并的逻辑 -* [ ] 其他优化与BUG修复 +* [X] 完善对本地化命令的支持 +* [X] 完善参数对应的规则的推断与合并的逻辑 +* [X] 其他优化与BUG修复 *** * [X] Code completion for config files: also for CWT files in plugin or config repositories * [X] Optimize lexer and parser for script and localisation fixes, fix some existing problems * [X] Optimize support for localisation commands -* [ ] Optimize inference and merging logic for configs of parameters +* [X] Optimize inference and merging logic for configs of parameters * [X] Other optimizations and bug fixes ## 1.3.19 diff --git "a/notes/\350\260\203\350\257\225\347\254\224\350\256\260.md" "b/notes/\350\260\203\350\257\225\347\254\224\350\256\260.md" index 5f1f11dce..a2cfa814c 100644 --- "a/notes/\350\260\203\350\257\225\347\254\224\350\256\260.md" +++ "b/notes/\350\260\203\350\257\225\347\254\224\350\256\260.md" @@ -86,4 +86,4 @@ From.GetName&gen *** -* [ ] 需要优化参数的规则的推断与合并的逻辑 +* [X] 需要优化参数的规则的推断与合并的逻辑 diff --git a/src/main/kotlin/icu/windea/pls/ep/parameter/ParadoxParameterInferredConfigProviders.kt b/src/main/kotlin/icu/windea/pls/ep/parameter/ParadoxParameterInferredConfigProviders.kt index cf16b49b6..5c3a6f650 100644 --- a/src/main/kotlin/icu/windea/pls/ep/parameter/ParadoxParameterInferredConfigProviders.kt +++ b/src/main/kotlin/icu/windea/pls/ep/parameter/ParadoxParameterInferredConfigProviders.kt @@ -55,8 +55,9 @@ class ParadoxDefaultExpressionParameterInferredConfigProvider : ParadoxParameter */ class ParadoxBaseParameterInferredConfigProvider : ParadoxParameterInferredConfigProvider { override fun supports(parameterInfo: ParadoxParameterContextInfo.Parameter, parameterContextInfo: ParadoxParameterContextInfo): Boolean { - val expressionElement = parameterInfo.parentElement?.castOrNull() ?: return false - if(!expressionElement.value.isFullParameterized()) return false + val parentElement = parameterInfo.parentElement + if(parentElement !is ParadoxScriptStringExpressionElement) return false + if(!parentElement.value.isFullParameterized()) return false return true } @@ -70,23 +71,28 @@ class ParadoxBaseParameterInferredConfigProvider : ParadoxParameterInferredConfi private fun getContextConfigsFromExpressionContextConfigs(expressionContextConfigs: List>, parameterInfo: ParadoxParameterContextInfo.Parameter): List>? { val inlinedContextConfigs = expressionContextConfigs.map { CwtConfigManipulator.inlineSingleAlias(it) ?: it } + val parentElement = parameterInfo.parentElement + val configGroup = expressionContextConfigs.first().configGroup val passingConfig = inlinedContextConfigs.find { it.expression.type == CwtDataTypes.ParameterValue } if(passingConfig != null) { //处理参数传递的情况 if(passingConfig !is CwtValueConfig) return null - val argumentNameElement = parameterInfo.element?.parent?.castOrNull()?.propertyKey ?: return null + val argumentNameElement = parentElement?.castOrNull()?.propertyKey ?: return null val argumentNameConfig = passingConfig.propertyConfig ?: return null val passingParameterElement = ParadoxParameterSupport.resolveArgument(argumentNameElement, null, argumentNameConfig) ?: return null val passingContextConfigs = ParadoxParameterManager.getInferredContextConfigs(passingParameterElement) return passingContextConfigs } val finalConfigs = inlinedContextConfigs.map { config -> + if(parentElement is ParadoxScriptPropertyKey && config is CwtPropertyConfig) { + return@map CwtValueConfig.resolve(emptyPointer(), configGroup, config.key) + } when(config) { is CwtPropertyConfig -> config.delegated(CwtConfigManipulator.deepCopyConfigs(config), config.parentConfig) is CwtValueConfig -> config.delegated(CwtConfigManipulator.deepCopyConfigs(config), config.parentConfig) } } - val configGroup = finalConfigs.first().configGroup + if(finalConfigs.isEmpty()) return emptyList() val contextConfig = CwtConfigManipulator.inlineWithConfigs(null, finalConfigs, configGroup) return listOf(contextConfig) } @@ -102,65 +108,65 @@ class ParadoxComplexExpressionNodeParameterInferredConfigProvider : ParadoxParam //root.value:some_script_value|K|$PARAM$| -> (from parameter K) override fun supports(parameterInfo: ParadoxParameterContextInfo.Parameter, parameterContextInfo: ParadoxParameterContextInfo): Boolean { - val expressionElement = parameterInfo.parentElement?.castOrNull() ?: return false - if(expressionElement.value.isFullParameterized()) return false + val parentElement = parameterInfo.parentElement + if(parentElement !is ParadoxScriptStringExpressionElement) return false + if(parentElement.value.isFullParameterized()) return false return true } override fun getContextConfigs(parameterInfo: ParadoxParameterContextInfo.Parameter, parameterContextInfo: ParadoxParameterContextInfo): List>? { val expressionConfigs = parameterInfo.expressionConfigs if(expressionConfigs.isEmpty()) return null - val expressionElement = parameterInfo.parentElement?.castOrNull() ?: return null - val finalConfigs = expressionConfigs.mapNotNull { getConfigFromExpressionConfig(expressionElement, it, parameterInfo) } - if(finalConfigs.isEmpty()) return null - val configGroup = finalConfigs.first().configGroup - val contextConfig = CwtConfigManipulator.inlineWithConfigs(null, finalConfigs, configGroup) - return listOf(contextConfig) + val parentElement = parameterInfo.parentElement + if(parentElement !is ParadoxScriptStringExpressionElement) return null + val contextConfigs = expressionConfigs.mapNotNull { getContextConfigFromExpressionConfig(parentElement, it, parameterInfo) } + return contextConfigs } - private fun getConfigFromExpressionConfig(expressionElement: ParadoxScriptStringExpressionElement, expressionConfig: CwtMemberConfig<*>, parameterInfo: ParadoxParameterContextInfo.Parameter): CwtValueConfig? { + private fun getContextConfigFromExpressionConfig(expressionElement: ParadoxScriptStringExpressionElement, expressionConfig: CwtMemberConfig<*>, parameterInfo: ParadoxParameterContextInfo.Parameter): CwtValueConfig? { val configGroup = expressionConfig.configGroup val value = expressionElement.value val textRange = TextRange.create(0, value.length) val expression = ParadoxComplexExpression.resolveByConfig(value, textRange, configGroup, expressionConfig) ?: return null val rangeInExpressionElement = parameterInfo.element?.textRangeInParent - var result: CwtValueConfig? = null + var result: List? = null expression.processAllNodes p@{ node -> if(node.rangeInExpression == rangeInExpressionElement) { - result = getConfigFromNode(expressionElement, expressionConfig, node) - if(result != null) return@p false + result = getConfigsFromNode(expressionElement, expressionConfig, node) + if(result.isNotNullOrEmpty()) return@p false } true } - return result + if(result.isNullOrEmpty()) return null + return CwtConfigManipulator.inlineWithConfigs(null, result, configGroup) } - private fun getConfigFromNode(expressionElement: ParadoxScriptStringExpressionElement, expressionConfig: CwtMemberConfig<*>, node: ParadoxComplexExpressionNode): CwtValueConfig? { + private fun getConfigsFromNode(expressionElement: ParadoxScriptStringExpressionElement, expressionConfig: CwtMemberConfig<*>, node: ParadoxComplexExpressionNode): List { val configGroup = expressionConfig.configGroup return when { node is ParadoxDataSourceNode -> { - node.linkConfigs.firstNotNullOfOrNull { it.expression?.let { e -> CwtValueConfig.resolve(emptyPointer(), configGroup, e.expressionString) } } + node.linkConfigs.mapNotNull { it.expression?.let { e -> CwtValueConfig.resolve(emptyPointer(), configGroup, e.expressionString) } } } node is ParadoxDynamicValueNode -> { - node.configs.firstOrNull()?.let { it.expression?.let { e -> CwtValueConfig.resolve(emptyPointer(), configGroup, e.expressionString) } } + node.configs.mapNotNull { it.expression?.let { e -> CwtValueConfig.resolve(emptyPointer(), configGroup, e.expressionString) } } } node is ParadoxScriptValueNode -> { - node.config.let { it.expression?.let { e -> CwtValueConfig.resolve(emptyPointer(), configGroup, e.expressionString) } } + node.config.toSingletonList().mapNotNull { it.expression?.let { e -> CwtValueConfig.resolve(emptyPointer(), configGroup, e.expressionString) } } } node is ParadoxScopeLinkNode -> { - CwtValueConfig.resolve(emptyPointer(), configGroup, "scope_field") + CwtValueConfig.resolve(emptyPointer(), configGroup, "scope_field").toSingletonList() } node is ParadoxValueFieldNode -> { - CwtValueConfig.resolve(emptyPointer(), configGroup, "value_field") + CwtValueConfig.resolve(emptyPointer(), configGroup, "value_field").toSingletonList() } node is ParadoxScriptValueArgumentValueNode -> { - val argumentNode = node.argumentNode ?: return null - val passingParameterElement = ParadoxParameterSupport.resolveArgument(expressionElement, argumentNode.rangeInExpression, expressionConfig) ?: return null + val argumentNode = node.argumentNode ?: return emptyList() + val passingParameterElement = ParadoxParameterSupport.resolveArgument(expressionElement, argumentNode.rangeInExpression, expressionConfig) ?: return emptyList() val passingContextConfigs = ParadoxParameterManager.getInferredContextConfigs(passingParameterElement) - val passingConfig = passingContextConfigs.singleOrNull()?.castOrNull() - passingConfig + val passingConfigs = passingContextConfigs.singleOrNull()?.configs?.filterIsInstance().orEmpty() + passingConfigs } - else -> null + else -> emptyList() } } }