Java 定义xtext语法时导入packageDefinition“.”接口定义

Java 定义xtext语法时导入packageDefinition“.”接口定义,java,antlr,grammar,xtext,Java,Antlr,Grammar,Xtext,我正在尝试使用xText创建一个简单的语法。语法应该只为Java接口定义语言,目前我正忙于导入声明。我希望能够引用我使用FQN定义的其他包中的其他接口。我的语法是这样的: DomainModel: elements=AbstractElement; AbstractElement: 'package' packageDeclaration=PackageDeclaration 'import'? importDeclarations+=ImportDeclaratio

我正在尝试使用xText创建一个简单的语法。语法应该只为Java接口定义语言,目前我正忙于导入声明。我希望能够引用我使用FQN定义的其他包中的其他接口。我的语法是这样的:

DomainModel:
    elements=AbstractElement;

AbstractElement:
    'package' packageDeclaration=PackageDeclaration 
    'import'? importDeclarations+=ImportDeclaration*
    typeDeclaration=TypeDeclaration;

PackageDeclaration:
    name=QualifiedName ';';

ImportDeclaration:
    importedNamespace=[ReferncedType|QualifiedName] ('.*')? ';';

ReferncedType:
    PackageDeclaration |InterfaceDeclaration; //need to combine both?? separated by '.'

TypeDeclaration:
    'interface' interfaceDeclaration=InterfaceDeclaration;

TypeList:
    Type ( ',' type+=Type)*;

Type:
    typeDefinition=[ReferncedType|ValidID];

InterfaceDeclaration:
    name=ValidID ('extends' superType=TypeList)? body=InterfaceBody;

InterfaceBody:
    '{' (declarations+=InterfaceBodyDeclaration)+ '}';

InterfaceBodyDeclaration:
    interfaceMemberDelcaration+=InterfaceMemberDeclaration ';';

InterfaceMemberDeclaration:
    InterfaceMethodDeclaration;
InterfaceMethodDeclaration:
    (Type | 'void') name+=ValidID '(' (formalParameters+=FormalParameters)* ')' ('throws'
    ....)?;
我已经定义了两个文件:

package org.first.sample;

interface Demo {
   void getA();
}

你有什么想法吗?

当我读语法时:

ImportDeclaration:
    importedNamespace=[ReferncedType|QualifiedName] ('.*')? ';';

ReferncedType:
    PackageDeclaration |InterfaceDeclaration; //need to combine both?? separated by '.'

PackageDeclaration:
    name=QualifiedName ';';
因此,import后面可以跟一个PackageDeclaration=QualifiedName,后面跟一个;然后,回到规则导入声明,另一个;必须遵循

另外,我不明白为什么referencedType也可以扩展到InterfaceDeclaration,这就是全部

后来

因此,也许应该将导入定义为

AbstractElement:
    'package' packageDeclaration=PackageDeclaration 
    importDeclarations+=ImportDeclaration*
    ...

ImportDeclaration
   'import' importedNamespace=QualifiedName ('.*')? ';';

它不允许静态导入,必须做一些事情来跟踪。*如果发生这种情况。

您可以绑定一个自定义的QualifiedNameProvider来覆盖接口导出的名称。 类似这样的东西应该可以使导入引用正常:import org.first.sample.Demo

public class CustomQualifiedNameProvider extends DefaultDeclarativeQualifiedNameProvider {
    @Override
    public QualifiedName getFullyQualifiedName(EObject obj) {
        if (obj instanceof InterfaceDeclaration && obj.eContainer().eContainer() instanceof AbstractElement) {
            QualifiedName packageQualifiedName = getFullyQualifiedName(((AbstractElement)obj.eContainer().eContainer()).getPackageDeclaration());
            return packageQualifiedName.append(((InterfaceDeclaration) obj).getName());
        }
        return super.getFullyQualifiedName(obj);
    }
}

此外,您可以按Ctrl+Shift+F3查看导出对象的名称。

实际上@laune是正确的。Xtext支持这种开箱即用的方式。只要模型中引用的类型具有名为“name”的功能,类型的完全限定名就是现成的。我注意到Xtext语法定义中的错误是包应该包含接口,这样当一个完全限定名形成时,Xtext通过将接口的“名称”与包或其父包的“名称”相结合来构造它。 @如果xtext语法规则不包含“name”特性,那么您的答案是正确的。这是构建FQN的一种自定义方法,例如,我们使用以下方法:

Package:
 'package' name=ID ';' imports=Import ';' interface=Interface ';'
;

Interface:
 qualifier=Qualifier !id=ID (instead of name=ID)
;
然后我们应该显式地构造fqn,因为内置支持只查找“name”特性

因此,在我的情况下,正确的使用方法是:

 Package:
 'package' name=ID; imports=Import typeDefinition=TypeDefinition;

Import:
 'import' importedNamespace=[TypeDefinition|QualifiedName] ';'
;

TypeDefinition:
  InterfaceDefinition | EnumDefinition ...
;

InterfaceDefinition:
 qualifier=Qualifier !name=ID
;

嗯,我不确定ReferencedType规则应该包含什么。我只需要能够像在Java import com.somepackage中那样导入类型。TypeName或com.sompackage.*请参阅我稍后添加的内容。谢谢,但如果导入的包无效,则不会引发编译错误。它将使用任何有效的限定名进行编译。我只需要引用现有的类型。这应该像Java编译器那样工作吗?如果是这样,则使用限定名访问类文件,或者,如果所有类文件都参与编译,则限定名最终必须引用在别处声明的接口。但是接口不会在导入中显示为完全的。不,演示类已编译。谢谢!这很有帮助。
 Package:
 'package' name=ID; imports=Import typeDefinition=TypeDefinition;

Import:
 'import' importedNamespace=[TypeDefinition|QualifiedName] ';'
;

TypeDefinition:
  InterfaceDefinition | EnumDefinition ...
;

InterfaceDefinition:
 qualifier=Qualifier !name=ID
;