Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support diagramming of any function #35

Open
bnorm opened this issue Feb 13, 2021 · 3 comments
Open

Support diagramming of any function #35

bnorm opened this issue Feb 13, 2021 · 3 comments

Comments

@bnorm
Copy link
Owner

bnorm commented Feb 13, 2021

Right now this compiler plugin supports diagramming a function if it can be called with parameters of either the following 2 forms:

  • function(Boolean, String)
  • function(Boolean, () -> String)

The plugin also supports diagramming of a function of the form function(Boolean) as long as it has an overload of one of the above forms.

The reason for this is because the plugin transforms the function call to include the diagrammed source code in the supplied String parameter. Something like the following...

assert(actual == expected, "Message")

...is transformed into something like...

assert(actual == expected, "Message:\nassert(actual == expected, \"Message\")\n       |         |\n       |         $expected\n       $actual")

The Boolean parameter of the function is not very significant; only the parameter which takes the function diagram is important. For example, a function of the form function(Any, Any, String) could be diagrammed if the compiler plugin understood that the function diagram can be appended to the String parameter. However, the placement of this String parameter could differ from function to function which makes support of any function more challenging.

Because of this, to support diagramming of any function, a syntax will need to be created to describe to the compiler plugin a supported function and which parameter the function diagram should be appended. For example, an pattern might be something like the following:

org.junit.jupiter.api.Assertions.assertEquals # assumed that last parameter will be diagram parameter
org.junit.Assert.assertEquals(*,1,2)          # asterisks indicates diagram parameter 
org.junit.Assert.assertEquals(1,2)->(*,1,2)   # how to transform overloads

Open questions about possible syntax:

  • How to handle functions with many overloads and/or parameters? (Should avoid lots of definitions when possible)
  • Is parameter type important when it comes to overloads? (Should support explicitness when needed)
  • Can parameter order change for overloads?
  • Can a function be transformed to a different function?
  • Should the syntax try to maintain some backwards compatibility? (Current syntax is just the fully-qualified name of the function)

And one final question: Should the name of this compiler plugin be changed if/when support for diagramming any function lands?

@vlsi
Copy link

vlsi commented Feb 27, 2023

However, the placement of this String parameter could differ from function to function which makes support of any function more challenging

@bnorm , have you explored the possibility of annotation-based configuration?
I've released https://github.com/vlsi/kotlin-argument-expression#motivation which supplies caller argument expression via specially-annotated parameters.

That enables designing APIs that are usable with and without the compiler plugin.

org.junit.Assert.assertEquals(1,2)->(*,1,2) # how to transform overloads

It might go as an annotation on top of Assert.assertEquals, so the library author can design and support the diagrams.

For instance:

class Assert {
    @ReplaceWith(target="assertEqualsWithDiagram")
    void assertEquals(Object a, Object b) { ... }

    void assertEqualsWithDiagram(
        Object a,
        Object b,
        @CallDiagram
        String diagram
    ) { ... }

Of course, having text-like configuration when library author does not use annotations might be helpful, however, it would be nice to come up with a way that could be integrated into the libraries.


Should the name of this compiler plugin be changed if/when support for diagramming any function lands?

You probably need several plugins:

  • -base plugin that adds only extensions, and makes no default configurations
  • the other plugins that add -base first, and then configure defaults

It is fine to have several Gradle plugins within a single Jar, however, shipping several plugins would make it easier for the users to opt-out of the plugin settings.

@vlsi
Copy link

vlsi commented Feb 27, 2023

I've filed a request to see what JUnit folks think of adding annotations to support diagram-like cases: junit-team/junit5#3176

WDYT of creating an umbrella organization like https://github.com/argument-expression-4j-team (or whatever name) to house projects like the spec for annotations (e.g. @CallerArgumentExpression, @WrapWith, @ReplaceWith), java-power-assert, kotlin-power-assert?

@bnorm
Copy link
Owner Author

bnorm commented Mar 1, 2023

[...] have you explored the possibility of annotation-based configuration?

Yes, actually! This idea was suggested to me and I think is probably the best way to go. I'd still like to support specifying functions via the Gradle configuration - for simple cases at least - as that will be important if you use a library which can't or doesn't natively integrate with the kotlin-power-assert support library (Kotlin assert, JUnit, etc). But I'm hoping to start work on this soon as it is yet another part of #45.

WDYT of creating an umbrella organization [...]

I'm happy to consume something like that but doubt I have the time to sufficiently support and start such an initiative. I'll watch those tickets though to stay up-to-date with the conversation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants