Giter VIP home page Giter VIP logo

Comments (6)

manosbatsis avatar manosbatsis commented on May 25, 2024 1

Had a couple of issues with that approach:

  • Creating a class that has the target external classes as members to generate their DSL produces a wrapper layer that is hard to get rid of.
  • Creating a super class of the target to apply @AutoDsl there only works if the target class is open, while it doesn't produce the target type anyway. Also a bit problematic in case of data classes.
  • In either case of the above there is no way for fine grained config, e.g. DSL name or collection tweaks like AutoDslCollection)

from autodsl.

juanchosaravia avatar juanchosaravia commented on May 25, 2024

Hi @manosbatsis ! thanks for this cool idea! I didn't think about it and I like it.
In order to provide a feature like this, we will need to integrate that (in some way) into the current process of AutoDsl as imagine this scenario where you have a mix of classes with and without AutoDsl

// External module/dep
class PersonExt(val wallet: WalletExt)
class WalletExt(val money: MoneyExt)
@AutoDsl
class MoneyExt()

// internal module
@AutoDslMixin(..)
class PersonMixin

@AutoDslMixin(..)
class WalletMixin

When creating the PersonExt Builder, you will need to lookup for its dependencies not only annotated with AutoDsl but also find (in some way) that the class WalletExt (which is not annotated at all) has a corresponding AutoDslMixin. One concern here is that this lookup could make the entire process to slow down. Another problem that I see with this is that you will be creating unnecessary classes to provide a builder to another class (like the PersonMixin class)

The first idea that comes to my mind is maybe having an interface and annotate there all the external classes that you want to support:

@AutoDslExternal(
   classes = PersonExt::class, WalletExt::class, etc..
)
interface AutoDslDep

and integrate in the current AutoDsl process the lookup in that list in case you have an scenario like this:

// external module
class WalletExt

// internal module
@AutoDsl
class Person(val wallet: WalletExt)

@AutoDslExternal(
   classes = WalletExt::class
)
interface AutoDslDep

and once it finish the regular AutoDsl process, it continues with the builder creation process for the AutoDslExternal list.

But still I need to think a little more about this. I really like the idea!

from autodsl.

manosbatsis avatar manosbatsis commented on May 25, 2024

Hey @juanchosaravia, thanks for the quick reply. To give a clearer picture, my annotation processors typically treat sources and mixins equally. For example, this:

@AutoDsl(dslName = "myBox")
class Box(
    val name: String,
    @AutoDslCollection(concreteType = ArrayList::class, inline = true)
    val stamps: List<Stamp>?
)

... would produce exactly the same as:

@AutoDslMixin(dslName = "myBox", dslSource = Box::class)
class BoxMixin(
    @AutoDslCollection(concreteType = ArrayList::class, inline = true)
    val stamps: List<Stamp>?
)

For each regular or mixin/ext annotation, the processor will create an AnnotatedElementInfo and process that to create e.g. a DTO or, in our case, the DSL. The mixin above provides the AutoDslCollection info as if it where in the original code.

In other words, both the mixin annotated element and it's dslSource are TypeElements as far as the annotation processor is concerned, with the mixin only providing information that cannot be added to the original source. The annotated elements are given directly to the processor by kapt so there is no need to perform any manual scanning - it just handles both regular and mixin annotations equally.

As you can imagine, the main reason I tend to use classes VS interfaces as mixins is pure laziness: it's easier to process them using the exact same code in the processor, e.g. when looking for constructor fields. That said, it's rather trivial to use interfaces too.

About AutoDslExternal: you'll have to help me there, i really see no need for it - just seems like a redundant point for the user to maintain.

Happy to discuss as needed and/or work on a branch, this feature would be of great help in a project i have right in front of me right now ;-)

from autodsl.

juanchosaravia avatar juanchosaravia commented on May 25, 2024

So what you are saying is to make a copy of each class that you want to have AutoDsl? hmm if that's the case, not sure about that approach. Seems redundant and requires maintainability. My proposal was to avoid this class duplication. And how would you handle those the case of a mix between external class and internal?

from autodsl.

manosbatsis avatar manosbatsis commented on May 25, 2024

So what you are saying is to make a copy of each class that you want to have AutoDsl?

Oh no, not at all. The mixin class/interface will usually be totally empty, with mixin members optionally emulating the annotation of a member in the original source. To make this clearer, this:

@AutoDsl(dslName = "myBox")
class Box(
    val field1: String,
    val field2: String,
    val field3: String,
    val field4: String,
    @AutoDslCollection(concreteType = ArrayList::class, inline = true)
    val field5: List<Stamp>?
)

... would produce exactly the same as:

@AutoDslMixin(dslName = "myBox", dslSource = Box::class)
class BoxMixin(
    @AutoDslCollection(concreteType = ArrayList::class, inline = true)
    val field5: List<Stamp>?
)

from autodsl.

juanchosaravia avatar juanchosaravia commented on May 25, 2024

I'm concern of the need to create new classes to generate builders for other classes. Seems to be a lot of code just to provide support to external class that should not really be exposed in a DSL. You could easily create a class to encapsulate the internal classes that you use or any class from any library. In that case you will not need to expose that class with your DSL and then no need to apply AutoDsl to that internal class.

from autodsl.

Related Issues (10)

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.