【问题标题】:XText Chained Dependencies in Type Inference类型推断中的 XText 链式依赖
【发布时间】:2013-05-14 13:25:59
【问题描述】:

在我的实验中,当存在跨多个 XExpression 块的依赖链时,XText 似乎无法解析变量类型。

一个最小的例子来说明。我有一个语法:

grammar eg.types.inference.TypeInferenceExample with org.eclipse.xtext.xbase.Xbase 

generate typeInferenceExample "example.org/types/inference/TypeInferenceExample"

Model:
    blocks += Block*
;

Block:
    '{'
        'name' ':' name=QualifiedName
        'from' ':' ('none' | from=[Block|QualifiedName])
        'block' ':' expression=XBlockExpression
    '}'
; 

一个接口:

package eg.lib;

public interface IModelBlock {
    public void push(org.eclipse.xtext.xbase.lib.Pair<String, ?> toPush);
}

还有一个 JvmModelInferrer:

package eg.types.inference.jvmmodel

import com.google.inject.Inject
import eg.lib.IModelBlock
import eg.types.inference.typeInferenceExample.Block
import eg.types.inference.typeInferenceExample.Model
import org.eclipse.xtext.xbase.XBinaryOperation
import org.eclipse.xtext.xbase.XExpression
import org.eclipse.xtext.xbase.XFeatureCall
import org.eclipse.xtext.xbase.XStringLiteral
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder

class TypeInferenceExampleJvmModelInferrer extends AbstractModelInferrer {

    @Inject extension JvmTypesBuilder

    def dispatch void infer(Model model, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
        model.blocks.forEach [block |
            acceptor.accept(block.toClass(block.name)).initializeLater [
                superTypes += block.newTypeRef(typeof(IModelBlock))
                members += block.toMethod("invoke", newTypeRef(Void::TYPE)) [
                    if (block.from != null) {
                        block.from.pushType.forEach [p |
                            parameters += block.toParameter(p.key, p.value)
                        ]
                    }
                    body = block.expression
                ]
            ]
        ]
    }

    def private pushType(Block block) {
        return block.eAllContents.filter[ // List of push calls in this Block
            it instanceof XFeatureCall && (it as XFeatureCall).concreteSyntaxFeatureName.equals("push")
        ].map [ 
            val call = it as XFeatureCall
            // Add entry for push call as an OutputDeclaration
            return call.featureCallArguments.map[
                if (!(it instanceof XBinaryOperation)) {
                    throw new RuntimeException("Must push using -> operator")
                }
                val key = (it as XBinaryOperation).leftOperand
                val value = (it as XBinaryOperation).rightOperand
                return key.name -> value.inferredType
            ]
        ].head
    }

    def private String name(XExpression literal) {
        if (!(literal instanceof XStringLiteral)) {
            throw new UnsupportedOperationException("Literal was not a string literal")
        }
        return (literal as XStringLiteral).value
    }

}

当我为这个 DSL 创建一个简单的例子时,例如:

{
    name : BlockOne
    from : none
    block : {
        val i = 42 * 3.6
        push("index" -> i)
    }
}

{
    name : BlockTwo
    from : BlockOne
    block : {
        val res = "Another Value from " + index
        push("result" -> res)
    }
}

代码生成得很好(类型推断在生成输出 Java 时成功计算出 indexres 的类型)。我在BlockOne 上使用对push 的调用中的对来推断BlockTwo 的调用方法上的接口。这个push 方法来自上面的IModelBlock 接口。如果我在此示例中添加第三个 Block,则:

{
    name : BlockThree
    from : BlockTwo
    block : {
        val out = "This one came from: " + result
        push("out" -> out)
    }
}

推理失败,UnsupportedOperationException: TODO: import a functional handle on the type resolution that delegates to the best available (current, but evolving) result(来自OnChangeEvictingCache.execWithoutCacheClearCachingBatchTypeResolver.resolveTypes)。

我应该使用其他一些技术来派生在 XText 中具有像这样的链式依赖关系的变量类型吗?

感谢您的帮助!

【问题讨论】:

    标签: types dsl type-inference xtext


    【解决方案1】:

    这似乎是您使用的版本中的一个错误。试试最新的。

    【讨论】:

    • 我刚刚尝试使用 XText 2.5.0(根据文档为 R201312110906),它抛出了同样的异常。我是否缺少更新站点?
    猜你喜欢
    • 2021-09-08
    • 2021-04-15
    • 2019-09-10
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多