使用JET生成代码:缩进代码 [英] Using JET to generate code: Indenting code

查看:104
本文介绍了使用JET生成代码:缩进代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试执行以下操作:

I'm trying to do the following:


编写一个接收Class类型为
的对象的JET模板论点。该对象应代表Java接口。模板
生成一个实现接口的类,即为它定义的所有方法签名提供方法
。生成的
类的名称应该是XImplementation,其中X是参数
interface的名称。生成的类中的方法不执行任何操作或仅返回
返回常量值:0表示int和double,false表示布尔值,
null表示引用类型。您不需要考虑任何其他返回
类型。例如。对于以下接口A,类AImplementation将生成

Write a JET template that receives an object of type Class as argument. The object should represent a Java interface. The template generates a class that implements the interface, i.e. provides methods for all the method signatures it defines. The name of the generated class should be XImplementation where X is the name of the argument interface. The methods in the generated class do nothing or only return constant values: 0 for int and double, false for boolean, and null for reference types. You do not need to consider any other return types. E.g. for the following interface A, class AImplementation would be generated:

interface A {  
    void m1(int x, int y);  
    int m2(Object a);  
    Object m3();  
}  

class AImplementation implements A {  
    public void m1(int p1, int p2) { }  
    public int m2(Object p1) { return 0; }  
    public Object m3() { return null; }  
}  

提示:
类型的非限定(简单)名称可以通过在
对应的Class对象上使用getSimpleName()方法获取。

Hint: the unqualified (simple) name of a type can be acquired by using the getSimpleName() method on the corresponding Class object.

我已阅读有关JET的教程在eclipse.org上找到,但我仍然无法理解我需要做什么。

I have read the tutorials about JET found on eclipse.org but I am still having trouble understanding what I need to do.

当我要翻译.txtjet文件时,我是否想要翻译它所以.txtjet文件的实现用 generate 方法中生成的代码写了一个巨大的字符串?这是正确的概念吗?

When I make the .txtjet file to be translated, am I trying to make it so the implementation of the .txtjet file writes a huge String with the code that I want to generate in the generate method? Is that the right concept?

如果是这种情况我就遇到了一个特殊方面的问题。这是我到目前为止提出的JET模板:

If that is the case I'm having trouble with one particular aspect. This is the JET template that I have come up with so far:

<%@ jet imports="java.lang.reflect.*" class="Q2Generator" %>
<%Object o = (Object) argument;%>
<%Class c = o.getClass();%>

public class <%=c.getName()%>Implementation implements <%=c.getName()%> {
<%for (Method m : c.getDeclaredMethods()) {%>
<%  Class type = m.getReturnType();%>
<%  if (!type.isPrimitive()) {%>
public <%=type.getSimpleName()%> <%=m.getName()%> { return null; } // this line is the problem
<%  }%>
<%}%>       
}

此模板导致生成以下代码方法:

  public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;
  protected final String TEXT_1 = NL + "public class ";
  protected final String TEXT_2 = "Implementation implements ";
  protected final String TEXT_3 = " {";
  protected final String TEXT_4 = NL + "public ";
  protected final String TEXT_5 = " ";
  protected final String TEXT_6 = " { return null; }";
  protected final String TEXT_7 = NL + "\t\t" + NL + "}";
  protected final String TEXT_8 = NL;

  public String generate(Object argument)
  {
    final StringBuffer stringBuffer = new StringBuffer();
    Object o = (Object) argument;
    Class c = o.getClass();
    stringBuffer.append(TEXT_1);
    stringBuffer.append(c.getName());
    stringBuffer.append(TEXT_2);
    stringBuffer.append(c.getName());
    stringBuffer.append(TEXT_3);
    for (Method m : c.getDeclaredMethods()) {
        Class type = m.getReturnType();
        if (!type.isPrimitive()) {
    stringBuffer.append(TEXT_4);
    stringBuffer.append(type.getSimpleName());
    stringBuffer.append(TEXT_5);
    stringBuffer.append(m.getName());
    stringBuffer.append(TEXT_6);
        }
    }
    stringBuffer.append(TEXT_7);
    stringBuffer.append(TEXT_8);
    return stringBuffer.toString();
  }

有没有办法缩进 stringBuffer.append () if语句中的行?并且String是正确的方式来完成这项任务吗?

Is there a way to indent the stringBuffer.append() lines in the if statement? And is the String way the right way of going about this task?

谢谢。

推荐答案

我使用较新的JET2语法。您应该能够使用New - > Other创建一个新的JET转换。

I'd use the newer JET2 syntax. You should be able to create a new JET transform with New -> Other.

至于高级别发生的事情,您将拥有一个名为main.jet的模板。这将充当控制者。它本身不会创建任何文本内容,但会管理项目,文件夹和文件的生成。

As for what's happening at a high level, you'll have a template called main.jet which will act as the controller. It doesn't create any text content itself but it will manage the generation of projects, folders and files.

我知道你想使用类对象作为输入,但我建议您构建模板以使用XML文件作为输入。这样的事情:

I understand that you want to use a class object as input, but I recommend you build out your templates to use an XML file as input. Something like this:

<root>
    <object name="A">
        <method name="m1" returns="void">
            <arg name="x" type="int" />
            <arg name="y" type="int" />
        </method>
        <method name="m2" returns="int">
            <arg name="a" type="Object" />
        </method>
        <method name="m3" returns="Object">
        </method>
    </object>
</root>

您可以看到,给定一个类,我们可以轻松创建这样的XML文档。

You can see that given a class we can "easily" create such an XML document.

所以main.jet看起来像这样:

So the main.jet would look something like this:

<%@taglib prefix="ws" id="org.eclipse.jet.workspaceTags" %>

<c:iterate select="/root/object" var="object"

    <c:set select="$object" name="impl" ><c:get select="$object/@name"/>Implementation</c:set>
    <c:set select="$object" name="interface" ><c:get select="$object/@name"/></c:set>

</c:iterate>


<c:iterate select="/root/object" var="object">

    <ws:file path="my project/src/a/b/c/{$object/@interface}.java" template="interface.jet" />
    <ws:file path="my project/src/a/b/c/{$object/@impl}.java" template="impl.jet" />

</c:iterate>

基本上你在迭代每个对象(你可以根据需要定义多个)和你'重新构建实现和接口名称并将这些名称存储回模型。

完成所有命名约定后,迭代对象元素并使用ws:file将模板应用于模型标签。标签告诉我们使用哪个模板,然后使用生成结果指定要创建的文件名。

Basically you're iterating over each object (you can define as many as you want) and you're building the implementation and interface names and storing those names back into the model.
Once you've done all the naming conventions, you iterate over the object elements and apply templates to the model using the ws:file tag. The tag tells which template to use and then specifies the file name to create with the generation results.

interface.jet文件可能如下所示:

the interface.jet file might look something like this:

package a.b.c;

interface <c:get select="$object/@interface"/> { 
<c:iterate select="$object/method" var="method" > 
    <c:get select="$method/@returns"/> <c:get select="$method/@name"/>(int x, int y);  
</c:iterate>
}  

请注意,我已将软件包硬编码为a.b.c.您可以通过向XML文件添加属性来创建该变量,可能是对象元素,并使用c:get标记将其插入到源中。我还将args保留为硬编码,但您可以使用另一个迭代标记来迭代模型中的嵌套元素以写出方法签名。

Note that I've hard-coded the package to be a.b.c. You can make that variable by adding an attribute to the XML file, probably to the object element and using the c:get tag to insert it into the source. I've also left the args hard-coded, but you can use another iterate tag to iterate over the nested elements in the model to write out the method signature.

所以我会在那里看看你是否正在寻找这个。您可能想在评论中提出更多问题或发布更多问题。

So I'll stop there to see if this is what you were looking for. You may want to ask more in comments or post more questions.

这篇关于使用JET生成代码:缩进代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆