Giter VIP home page Giter VIP logo

Comments (15)

sormuras avatar sormuras commented on July 28, 2024 1

See https://github.com/square/javapoet#parameters which refers to https://github.com/square/javapoet/blob/master/src/main/java/com/squareup/javapoet/ParameterSpec.java#L121 and following lines. Especially, all the addAnnotation[s](...) methods.

from javapoet.

JakeWharton avatar JakeWharton commented on July 28, 2024

@swankjesse and I have been bouncing the idea of making the API more aware of the content that it's generating.

So I'll counter your API suggestion with a radically different one that could be part of a 3.0 API:

Method method = Method.build("List<Activity>", "listActivity", EnumSet.of(PUBLIC))
    .annotation(Annotation.build(POST.class).value("/foo/{bar}").build())
    .parameter("String", "bar", Annotation.build(Path.class).value("bar").build())
    .parameter("ActivityRequest", "body", Annotation.of(Body.class))
    .build();

Generates:

@POST("/foo/{bar}")
public List<Activity> listActivity(@Path("bar") String bar, @Body ActivityRequest body) {
}

This isn't final and hasn't even been thought about more than about 30m in my brain. But you should hopefully get the picture of where we are headed and why.

My biggest problem with what you posted is that the signal-to-noise ratio of those method calls is starting to become really high relative to the code that is generated from them. At that level of granularity we aren't really offering much on top of just concatenating strings and some helper methods for compressing types.

I would hold off on doing any work towards this until we have had a change to discuss the direction of the library more.

from javapoet.

JakeWharton avatar JakeWharton commented on July 28, 2024

I should also note that the signal-to-noise ratio is a bit high in my example, but one cool thing is that it makes objects out of code components which can be passed around and composed like any other object. And we're not even sold that it's the right approach, just something that's bouncing around.

from javapoet.

ragunathjawahar avatar ragunathjawahar commented on July 28, 2024

The proposed API seems to be fluid and interesting. Is there a draft for the upcoming API spec or a crude timeline that you can reveal?

from javapoet.

cgruber avatar cgruber commented on July 28, 2024

It's funny, greg was toying with an idea (and I expended it a bit) of going almost the opposite way, such that instead of building up code, you have code that looks a lot like the code you're going to emit, using the block initializer jazz. Very much the way Spec/BDD frameworks do. Sort of like:

    CompliationUnit block = new CompliationUnit("com.google.whatever") {{
     add(new ClassBlock(EnumSet.of(PUBLIC, FINAL), "MyClass") {{
       add(new MethodBlock(EnumSet.of(PUBLIC, STATIC), Void.class, "main") {{
         // You can loop.
         for (Foo foo : foos) {
           // Short cut for quick-and-dirty simple statements. 
           addStatement("%s.out.println(\"Hello World\")", System.class);         
         }
         // More complex statement chains. 
         identifierFor(System.class).dot("out").dot("println").invoke(literal("Hello World!"));
       }});
     }});
    }};

It's totally a straw man, but this approach results in code that in shape/indentation/layout strongly matches the resulting emitted code, lets us do all the right things with accumulating types so we can emit shortened versions, etc. Heck, it can reflectively validate stuff along the way.

It can also be composed.

    ClassBlock[] blocks = new ClassBlock[someNumber]
    for (int i = 0; i < someNumber; i++) {
      blocks[i] = new ClassBlock(EnumSet.of(PUBLIC, FINAL), "MyClass" + i) {{
        add(new MethodBlock(EnumSet.of(PUBLIC, STATIC), Void.class, "main") {{
          identifierFor(System.class).dot("out").dot("println").invoke(literal("Hello World!"));
        }});
      }};
    }
    CompliationUnit block = new CompliationUnit("com.google.whatever") {{
     addAll(asList(blocks));
    }};

There are some down-sides, and the names suck just now, but there are some handy aspects to it. I normally really like fluent interfaces, but in this case, I think it doesn't serve the readability.

from javapoet.

cgruber avatar cgruber commented on July 28, 2024

Lots of little fixes to the above would also be needed to make it not suck on the eyes. wrapping EnumSet.of(...) with something less verbose, and maybe a little value type for parameters with terse convenience constructors, etc.

from javapoet.

cgruber avatar cgruber commented on July 28, 2024

The major downside is that you have to use "new Foo() {{ }}" and can't compress the "new Foo" bit with a static method since the whole initialization block trick only works with new. :/

from javapoet.

JakeWharton avatar JakeWharton commented on July 28, 2024

Cool stuff! The instant init block is clever.

from javapoet.

tbroyer avatar tbroyer commented on July 28, 2024

Another approach: https://github.com/WeTheInternet/xapi/tree/master/dev/source/src/main/java/xapi/dev/source, similar to Jake+Jesse's proposal.

Sample code (copied from https://groups.google.com/d/msg/google-web-toolkit-contributors/MdKEzmaMiyI/k1pIn--sVXsJ; includes GWT-specific JSNI)

MethodBuffer valueProvider = beanCls
    .createMethod("protected Object valueOf(String name, Object o)") // definition is lexed; it can be modified later if you desire
    .setUseJsni(true)
    .addAnnotation(UnsafeNativeLong.class)
    .println("switch(name) {")
    .indent()
    .println("case 'this': return o;")
    .println("case 'this.name()':")
    .indentln("return [email protected]::getClass()()[email protected]::getName()();");
SourceBuilder<Object> b = new SourceBuilder<Object>(
      "public static abstract class Test");
b.setPackage("xapi.test");
b.getClassBuffer()
  .createMethod("public <T extends java.util.Date> void Test(java.lang.String t) {")
  .indentln("System.out.println(\"Hellow World\" + new java.sql.Date());")
  .createLocalClass("class InnerClass ")
  .createMethod("void innerMethod()")
  ;
// We discard java.lang imports
Assert.assertFalse(b.toString().contains("import java.lang.String;"));
// We used java.util.Date as a fully qualified name first, so it should be imported
Assert.assertTrue(b.toString().contains("import java.util.Date;"));
Assert.assertTrue(b.toString().contains("<T extends Date>"));
// We used java.sql.Date as a fqcn after java.util.Date, so it must NOT be imported
Assert.assertFalse(b.toString().contains("import java.sql.Date;"));

from javapoet.

cgruber avatar cgruber commented on July 28, 2024

Ok - we've strayed from the actual issue... can we create an issue for Future Directions for Javawriter and we can move all of these comments there and go forth. Also, we are discussing this question internally at Google, because it turns out we generate quite a bit of code, and in a few ways. I would love to see if we can (if possible) converge. That may include converging on something that isn't javawriter if we find something, or taking that and making the best javawriter.

from javapoet.

JakeWharton avatar JakeWharton commented on July 28, 2024

I've moved discussion of future API into #51 where the comments can be used for discussion and the issue description cann be edited with any concrete decisions.

from javapoet.

JakeWharton avatar JakeWharton commented on July 28, 2024

The upcoming version 3 handles this by returning a VariableWriter type on which .annotate() can be called. Annotation itself needs augmented to allow for more than argument-free annotations, but that's another issue.

from javapoet.

eamonnmcmanus avatar eamonnmcmanus commented on July 28, 2024

Actually, VariableWriter.annotate() returns an AnnotationWriter on which you can define member values. It's not the most discoverable API, but it is in fact possible.

from javapoet.

JakeWharton avatar JakeWharton commented on July 28, 2024

Oh, nice! I definitely did not notice that.

from javapoet.

MRezaNasirloo avatar MRezaNasirloo commented on July 28, 2024

So how this is done with the latest version?
I couldn't find anything related in linked issues.

from javapoet.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.