مترجمة واجهة برمجة تطبيقات جافا لإنشاء ملفات مصدر Java




كتب جافا مترجمة (12)

أنا أبحث عن إطار لإنشاء ملفات مصدر جافا.

شيء مثل واجهة برمجة التطبيقات التالية:

X clazz = Something.createClass("package name", "class name");
clazz.addSuperInterface("interface name");
clazz.addMethod("method name", returnType, argumentTypes, ...);

File targetDir = ...;
clazz.generate(targetDir);

بعد ذلك ، يجب العثور على ملف مصدر جافا في دليل فرعي للدليل الهدف.

هل يعرف أحد مثل هذا الإطار؟

تحرير :

  1. أنا حقا بحاجة إلى الملفات المصدر.
  2. أود أيضًا ملء شفرة الطرق.
  3. أنا أبحث عن التجريد على مستوى عال ، وليس التلاعب المباشر bytecode / جيل.
  4. أنا أيضا بحاجة إلى "هيكل الطبقة" في شجرة الأشياء.
  5. مجال المشكلة عام: لتوليد كمية كبيرة من الطبقات المختلفة ، بدون "بنية مشتركة".

محاليل
لقد نشرت 2 إجابات في إجاباتك ... مع CodeModel ومع Eclipse JDT .

لقد استخدمت CodeModel في الحل الخاص بي ، :-)



حل وجد مع CodeModel
شكرا ، .

على سبيل المثال ، مع هذا الرمز:

JCodeModel cm = new JCodeModel();
JDefinedClass dc = cm._class("foo.Bar");
JMethod m = dc.method(0, int.class, "foo");
m.body()._return(JExpr.lit(5));

File file = new File("./target/classes");
file.mkdirs();
cm.build(file);

يمكنني الحصول على هذا الإخراج:

package foo;
public class Bar {
    int foo() {
        return  5;
    }
}

تم العثور على حل مع AST Eclipse JDT
شكرا Giles .

على سبيل المثال ، مع هذا الرمز:

AST ast = AST.newAST(AST.JLS3);
CompilationUnit cu = ast.newCompilationUnit();

PackageDeclaration p1 = ast.newPackageDeclaration();
p1.setName(ast.newSimpleName("foo"));
cu.setPackage(p1);

ImportDeclaration id = ast.newImportDeclaration();
id.setName(ast.newName(new String[] { "java", "util", "Set" }));
cu.imports().add(id);

TypeDeclaration td = ast.newTypeDeclaration();
td.setName(ast.newSimpleName("Foo"));
TypeParameter tp = ast.newTypeParameter();
tp.setName(ast.newSimpleName("X"));
td.typeParameters().add(tp);
cu.types().add(td);

MethodDeclaration md = ast.newMethodDeclaration();
td.bodyDeclarations().add(md);

Block block = ast.newBlock();
md.setBody(block);

MethodInvocation mi = ast.newMethodInvocation();
mi.setName(ast.newSimpleName("x"));

ExpressionStatement e = ast.newExpressionStatement(mi);
block.statements().add(e);

System.out.println(cu);

يمكنني الحصول على هذا الإخراج:

package foo;
import java.util.Set;
class Foo<X> {
  void MISSING(){
    x();
  }
}

هناك مشروع جديد write-it-once . مولد رمز يستند إلى قالب. تكتب قالبًا مخصصًا باستخدام Groovy ، وتولد الملف بناءً على انعكاسات جافا. إنها أبسط طريقة لإنشاء أي ملف. يمكنك جعل getters / settest / toString من خلال إنشاء ملفات AspectJ ، SQL استنادًا إلى التعليقات التوضيحية لـ JPA ، والإدخالات / التحديثات المستندة إلى التعدادات وما إلى ذلك.

مثال على القالب:

package ${cls.package.name};

public class ${cls.shortName}Builder {

    public static ${cls.name}Builder builder() {
        return new ${cls.name}Builder();
    }
<% for(field in cls.fields) {%>
    private ${field.type.name} ${field.name};
<% } %>
<% for(field in cls.fields) {%>
    public ${cls.name}Builder ${field.name}(${field.type.name} ${field.name}) {
        this.${field.name} = ${field.name};
        return this;
    }
<% } %>
    public ${cls.name} build() {
        final ${cls.name} data = new ${cls.name}();
<% for(field in cls.fields) {%>
        data.${field.setter.name}(this.${field.name});
<% } %>
        return data;
    }
}

لقد قمت ببناء شيء يشبه إلى حد كبير برنامج DSL النظري الخاص بك ، والمسمى "sourcegen" ، ولكن من الناحية الفنية بدلاً من مشروع الاستخدام الخاص بـ ORM كتبت. يبدو DSL:

@Test
public void testTwoMethods() {
    GClass gc = new GClass("foo.bar.Foo");

    GMethod hello = gc.getMethod("hello");
    hello.arguments("String foo");
    hello.setBody("return 'Hi' + foo;");

    GMethod goodbye = gc.getMethod("goodbye");
    goodbye.arguments("String foo");
    goodbye.setBody("return 'Bye' + foo;");

    Assert.assertEquals(
    Join.lines(new Object[] {
        "package foo.bar;",
        "",
        "public class Foo {",
        "",
        "    public void hello(String foo) {",
        "        return \"Hi\" + foo;",
        "    }",
        "",
        "    public void goodbye(String foo) {",
        "        return \"Bye\" + foo;",
        "    }",
        "",
        "}",
        "" }),
    gc.toCode());
}

https://github.com/stephenh/joist/blob/master/util/src/test/java/joist/sourcegen/GClassTest.java

كما يقوم أيضًا بأشياء أنيقة مثل "التنظيم التلقائي للواردات" أي FQCN في أنواع المعلمات / الإرجاع ، تشذيب أي ملفات قديمة لم يتم لمسها في تشغيل codegen هذا ، وضع المسافات الداخلية للطبقات الداخلية بشكل صحيح ، إلخ.

والفكرة هي أن الشفرة التي تم إنشاؤها يجب أن تكون جميلة للنظر إليها ، دون تحذيرات (استيراد غير مستخدم ، وما إلى ذلك) ، تمامًا مثل بقية الشفرة. الكثير من الشفرة المولَّدة قبيحة للقراءة ... إنه أمر فظيع.

على أي حال ، ليس هناك الكثير من المستندات ، لكنني أعتقد أن واجهة برمجة التطبيقات بسيطة جدًا / بديهية. ريبو Maven here إذا كان أي شخص مهتم.


توفر Sun واجهة برمجة تطبيقات تسمى CodeModel لتوليد ملفات مصدر Java باستخدام API. ليس من الأسهل الحصول على المعلومات ، ولكنها موجودة وتعمل بشكل جيد للغاية.

أسهل طريقة للحصول عليه هي كجزء من JAXB 2 RI - يستخدم مولد XJC المكوّن من جافا إلى CodeModel لتوليد مصدر جافا الخاص به ، وهو جزء من جرار XJC. يمكنك استخدامه فقط من أجل CodeModel.

الاستيلاء عليها من CodeModel


بديل آخر هو AST Eclipse JDT وهو أمر جيد إذا كنت بحاجة إلى إعادة كتابة كود جافا جافا التعسفي بدلا من مجرد توليد شفرة المصدر. (وأعتقد أنه يمكن استخدامها بشكل مستقل من الكسوف).


يمكنك استخدام المحمصة ( https://github.com/forge/roaster ) للقيام بتوليد التعليمات البرمجية.

هنا مثال:

JavaClassSource source = Roaster.create(JavaClassSource.class);
source.setName("MyClass").setPublic();
source.addMethod().setName("testMethod").setPrivate().setBody("return null;")
           .setReturnType(String.class).addAnnotation(MyAnnotation.class);
System.out.println(source);

سيعرض الإخراج التالي:

public class MyClass {
   private String testMethod() {
       return null;
   }
}

كنت أفعل ذلك بنفسي لأداة مولد وهمية. إنها مهمة بسيطة جدًا ، حتى إذا كنت بحاجة إلى اتباع إرشادات تنسيق Sun. أراهن أنك ستنتهي من الشفرة بشكل أسرع ، فوجدت شيئًا يناسب هدفك على الإنترنت.

لقد حددت بشكل أساسي واجهة برمجة التطبيقات بنفسك. فقط املأها بالرمز الفعلي الآن!


لا تعرف مكتبة ، ولكن قد يكون محرك قالب عام هو كل ما تحتاج إليه. هناك حفنة منهم ، وأنا شخصيا قد كان تجربة جيدة مع FreeMarker


إنه يعتمد على ما تحاول القيام به. توليد التعليمات البرمجية هو موضوع في حد ذاته. بدون حالة استخدام محددة ، أقترح النظر إلى مكتبة توليد / قالب رمز السرعة. أيضا ، إذا كنت تقوم بتوليد الكود دون اتصال ، فإنني أقترح استخدام شيء مثل ArgoUML للانتقال من المخططات UML / Object إلى Java البرمجية.


إذا كنت حقا بحاجة إلى المصدر ، لا أعرف أي شيء يولد المصدر. ومع ذلك ، يمكنك استخدام ASM أو CGLIB لإنشاء ملفات .class مباشرة.

قد تكون قادرًا على إنشاء مصدر من هذه ، ولكني استخدمتها فقط لإنشاء كود البايت.





code-generation