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

CodeLiteral #484

Open
swankjesse opened this issue Sep 28, 2018 · 8 comments
Open

CodeLiteral #484

swankjesse opened this issue Sep 28, 2018 · 8 comments
Milestone

Comments

@swankjesse
Copy link
Member

swankjesse commented Sep 28, 2018

Idea: an interface CodeLiteral that is used whenever we have %L to let the value itself convert to source code.

interface CodeLiteral {
  fun toCodeBlock(): CodeBlock
}

Here’s how we might define a function to convert a Float to a CodeLiteral:

private val Float.literal: CodeLiteral
  get() {
    val v = this
    return object : CodeLiteral {
      override fun toCodeBlock() = CodeBlock.of("%Lf", v)
    }
  }

And here’s how we might use it:

@Test fun testLiterals() {
    val taco = TypeSpec.classBuilder("Taco")
        .addFunction(FunSpec.builder("getPrice")
            .addModifiers(KModifier.PUBLIC, KModifier.FINAL, KModifier.OVERRIDE)
            .returns(Float::class)
            .addStatement("return %L", 1.99f.literal)
            .build())
        .build()
}
@alex2069
Copy link
Contributor

Though a little nicer, this still doesn't solve the original problem - if you don't know the type (such as when reading from a generic annotation AnnotationValue.value which returns Object) - you can't can't call .literal on it.
The types that can be used in an annotation are well defined and restricted to primitives, arrays, enums, and classes. That you have to go out of your way to correctly emit these standard types is just bizarre and frustrating.

@swankjesse
Copy link
Member Author

@alex2069 presumably you could write a function that takes Any and does it. Could you give me a concrete example? In the code I've generated I rarely need to emit literals of unknown types.

@ZacSweers
Copy link
Collaborator

I like the idea of this, but the float impl doesn't always quite work I think

1.00000001f.literal comes out to 1.0f

@JakeWharton
Copy link
Member

JakeWharton commented Sep 4, 2019 via email

@ZacSweers
Copy link
Collaborator

huh, TIL

ZacSweers added a commit to ZacSweers/kotlinpoet that referenced this issue Sep 4, 2019
Resolves square#484

Unclear if KotlinPoet should ship with some pre-builts, but this is a good starting point at least
@ZacSweers
Copy link
Collaborator

#775

@JakeWharton
Copy link
Member

JakeWharton commented Sep 4, 2019 via email

@ZacSweers
Copy link
Collaborator

Another good use-case for this - we have "constantValue" CodeBlocks in the new element handler APIs that would make more sense as a CodeLiteral

@Egorand Egorand modified the milestones: Backlog, Icebox Aug 31, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants