我正在努力解决一个Java +类型系统的小问题,也许你们中的一些人对如何解决该问题有很大的启发。
背景:
我正在实现一个使用领域特定语言(DLS)的Java应用程序。 DLS是生成的代码,并与主应用程序一起打包。最后,该应用程序应支持不同版本的DSL。
乍一看,这似乎不是问题,因为不同的DLS版本使用不同的程序包名称,例如*.sdtl.v2.*
和*.sdtl.v2.*.
,每个程序包都包含属于DLS的所有元素。当前版本,例如解析器和语法元素。
问题:
我现在的问题是,我想对DSL的中心元素(例如语言解析器)进行某种转换。例如,该开关应返回给定版本的正确解析器。
示例:
class Parser {
public static Object forVersion(int version) {
switch (version) {
case 1:
return new *.stdl.v1.parser.Parser();
case 2:
return new *.stdl.v2.parser.Parser();
}
}
不幸的是,似乎不可能找到该方法的有意义的类型签名。由于DLS元素(例如,解析器类)是生成的代码,并且该类的所有版本都没有公共的超类(对象除外),因此除对象之外,显然不可能找到该方法的返回类型。>
我当前的解决方法是使用通用的超类围绕生成的解析器类进行包装。这使我能够为该方法提供一个更具体的类型,但是,它只会将问题转移到下一个级别,因为解析器的返回值也是属于该版本的语法元素。
abstract class ParserWrapper {
final int version;
protected ParserWrapper(int version) {
this.version = version;
}
public abstract Object parse(String string);
}
class STDLv1Wrapper extends ParserWrapper {
public Node parse(String string) {
return new *.stdl.v1.parser.Parser().parse(string);
}
}
class STDLv1Wrapper extends ParserWrapper {
public Node parse(String string) {
return new *.stdl.v2.parser.Parser().parse(string);
}
}
class Parser {
public static ParserWrapper forVersion(int version) {
switch (version) {
case 1:
return new STDLv1Wrapper();
case 2:
return new STDLv2Wrapper();
}
}
}
有人对如何解决这种情况有更好的主意吗?