Code Monkey home page Code Monkey logo

kotlinpoetdsl's People

Contributors

tieskedh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

kotlinpoetdsl's Issues

Consider exposing parameters, variables and fields as property accessors

For instance:

func("func", "bool" of Boolean::class) {
If("bool") {
statement("println(true)")
}.end()
}

The sad thing is "bool" is duplicated. For instance, when If("bool") is created in another method, it won't even fail if the parameter with that name does not exist.

What if func scope provided property that could be used to declare, and retrieve parameters and locals?

For instance:

createFun{
    func("func") {
        // Below adds a parameter to the function. It knows data type, it knows the name
        val flag by parameters.creating<Boolean>()
        If(flag) {
...
createFun{
    func("func") {
        // Below adds a parameter to the function. It knows data type, it knows the name
        val flag by parameters.creating<Boolean> {
            // configure initializers, varargs or whatever (it will go to the function parameter declaration)
        }
        If(flag) {
...
createFun{
    func("func", "flag" of Boolean::class) {
        val flag by parameters.existing // throw if parameter named "flag" does not exist
        If(flag) {
...

documentation

  • ConstructorSpec
  • Variable
  • inline property
  • if, repeat, switch

buildConstructor should accept FunSpec

buildConstructor {
    constructor(FunSpec.constructorBuilder().build())
}

does not compile, but should

correct way to do it:

FunSpec.construcorBuilder().build().toPrimaryConstructor()
FunSpec.construcorBuilder().build().toPrimaryConstructor()

FunSpec.toPrimaryConstructor improvements

FunSpec.toPrimaryConstructor should alllow:

create an enum in Variable.Companion:

enum class Mutability{
    MUTABLE, IMMUTABLE, NONE
}
  • vararg variables,
  • vararg Pair<String, Mutability>

add control-flow in a DSL-like way to CodeBlockBuilder

Code-block-Builder needs to have a DSL-like Constrol-flow.
lambda's with bodys needs to have control-flow access:

myType.someFunc(arg1){ it ->
    //plpl
}
val t =  someOtherFunction{
    //inside the lambda
}.andAlsoMyFunc{
    //hey
}

the code above can never be built in, so not allowing accessto the contrrol-flow is simply not feasible.

getter/setter check parametertype?

At the moment, the parametertypes of the getter / setter aren't checked.
#34 adds the possibility to add a returnType.

With those values, it should be possible to check if the type match the property...
Should this be added?

attachTo and attach

Merging the modifiers is strange.
Therefor, drop all the functions that accept a Spec, (except from accept).

Add instead extension-function attach and attachTo.
attachTo will have 2 parameters, a mendatory Acceptor, where the spec will be attached to and a builder-function, to modify the spec.
attach will be the same, but it replaces the mendatory acceptor with the Acceptor.

buildClazz{
    clazz("Hi"){
        someFunSpec.attach()
        someOtherFunSpec.attach{
            replaceModifiers(KModifier.OPEN, KModifier.OPEN)            
        }
    }
}

This will give the user themselves the choice to add the function with Spec and how to implement them.
Functions like that should be documented as well.

(attachTo could be added later, when KotlinPoetDSL tries to be more composable)

Change constructorSpec

ConstructorSpec hides properties completely at the moment, when it is a secondary.
The better way would be to make the field public as allProperties and add a field activeProperties.
(in that way it's also easier to explain why two constructors that do the same when added are in fact different)

Licenses

I don't know a lot about licenses. It would be great if anyone can help...

Returns nested for

Functions can be added to functions.
That means the infix fun is accessible inside func.

This means it's also callable on this.
When you use the not-returning function together with the returning function, the method will be added twice.

builders without body

At the moment, a function that starts a build without body returns itself.
This means that functions to complete this build are added to the builder.
Some of these functions should however not be called from inside the bodies.
Therefor, the classes should not return themselves, but a view of them.

improve interoperability constructor-parameters

constructor and primary.constructor should accept ParameterSpec as parameter.

to discuss:
PropertySpec can be aded as parameter as well, but in three ways:

  • add to all: var/val keyword will be ignored automatically, untill changed to primary, but it can bring confusion.
  • only add to secondary construcor
  • don't add at all, to ignore all confusion

Consider using dsl function names closer to their generated counterparts

There is already If for generating if statements (avoiding the keyword). There could similarly be When for when statements instead of switch, and Do/While instead of doRepeat/repeatWhile, etc.

This would make it more obvious and easier to remember what dsl function corresponds to what output.

Other possibilities to consider:

  • Class/Interface
  • Val, Var, Fun
  • For instead of foreach
  • ElseIf/Else instead of 'orElseIf' and 'orElse'
  • get/set instead of getter/setter (get and set are soft keywords)
  • etc.

(primary) constructor

There should come a primaryConstructor and constructor builder:

The accept of PrimaryConstructorAcceptor should have two accept-methods: funSpec and PropertySpec.
example:

file(""', "TestFile"){
    open.clazz("clazz1"){
        private.primaryConstructor("test" valOf<String>("def".S()){
            switch("true"){
                Else("println(1)"
            }
        }
        protected.constructor("test".valOf<Int>()) thiz("test.toString()"){
            switch("false"){
                Else("println(2)")
            }
        }
    }
    clazz("Clazz") extends String::class{
        protected.constructor("test" of Int::class).zuper("a".S()){
            switch("1"){
                Else("println(0)")
            }
        }
    }
}

constructor(ConstructorSpec)

buildClazz{
     clazz("hi"){
         constructor(/*constructorSpec here*/)
    }
}

Add the moment, it works with the isPrimary of the constructorSpec: primary is treated as other accessors.

But it can be explained the other way around: constructor is not primary, so it should not have primary added.

options:

  • change primary.constructor in primaryConstructor
  • remove constructor() -> accept remains and is easy to explain
  • leave: primary looks like accessor and should be treated as one

todo: find better solution for repeat

At the moment, the repeat is not satisfying.
I have three solutions, which I don't like very much.

the first is using a lambda, as not final parameter:

"index".repeat({10 until 20 step 2}){
    statement("println(\"hi\")"
}

//without index
repeat({10 until 20 step 2}){
    statement("println(\"hi\")"
}

The second solution is to not have the until and step etc. remapping inside a lambda in a parameter, but in the surrounding context. The problem with it is that if you want to write code unrelated to kotlinpoetdsl in the surrounding context, it doesn't do what you expect.

The third solution is to introduce a new language: replace until, downto and step with other names, but if you start going that direction....

Replace internals of variable.

The internals of Variable should be changed to FlyWeight.
The constructor should than set the fields inside main and the Specs specific variables in the side-class.

Also add a constructor accepting 2 specs, where the common fields need to be the same.

functionBody must accept code that's broader than CodeBlockBuilder

buildFunc{
    func("ho"){
        // this should be broader than CodeBlockBuilder
    }
}

Therefor, make an interface with all the interfaces of CodeBlockBuilder.
let CodeBlockBuilder implement that interface.
Make a class FunctionBlockBuilder and let it delegate the interface to a CodeBlockBuilder stored inside.

add more switch-invocations.

add:

  • else - lazyComponent
  • else - codeblock
  • else - string + varar Any?
  • case - codeblock
  • case - string + vararg Any?
  • then - codeblock

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.