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

Make the kotlinpoet module multi-platform and add source set configuration for the JS and wasmJs platforms #1959

Open
wants to merge 38 commits into
base: main
Choose a base branch
from

Conversation

ForteScarlet
Copy link

#304

Hi! This PR attempts to change the kotlinpoet module into a true multi-platform module: adding source code sets for platforms other than the JVM platform: JS and WasmJs. No native platforms have been added yet.

There should be no change in behaviour on the JVM platform after the change, and the unit tests all pass locally.

There are some limitations and issues with JS and wasmJs.

  • The kotlin-reflect in JS and WasmJs is very limited, so it's almost impossible to get valid results with KClass.asXxx.
  • The IDENTIFIER_REGEX in the Util.kt cannot be initialised, and you get the error: PatternSyntaxException: No such character class. (I'm not very good at regular expressions, I don't understand the problem with them.)
  • CodePoint related implementations are temporary on JS and WasmJS, not sure if that's correct.
  • isJavaIdentifierStart and isJavaIdentifierPart are not implemented on JS and WasmJs at the moment and only return default values temporarily.
  • formatNumericValue is not implemented on JS and WasmJs at the moment and currently returns toString itself directly, unformatted.

I have tried not to change the logic and ensure API compatibility, but I have to say it's still a lot of changes. I wonder if such a change would be allowed or accepted? I think this might simply advance #304 ?

Please review these changes and let me know whether you will be accepted or not, thanks!

@Egorand
Copy link
Collaborator

Egorand commented Aug 8, 2024

This PR is gigantic and due to that it's virtually unreviewable. Please split it up into multiple incremental commits, each of which has a clear commit message that describes what it's doing. Also, please try to avoid noisy changes such as moving function or property annotations from the same line to the previous line.

To be honest I'm also not completely sure there's value in getting the library to work in a non-Java environment, given the limitations. I'll let other contributors voice their opinions, probably worth waiting until then before you start cleaning it up and splitting into commits.

@ForteScarlet
Copy link
Author

Thank you for your reply! I think running in a non-Java environment can make browser-based code generation or mobile code generation in non-Java environments easier. However, let's wait for the results of your discussion and look forward to the follow-up~

@JakeWharton
Copy link
Collaborator

I agree that JS is valuable.

I also agree that we need to do this piece by piece.

The TypeName hierarchy seems like a good candidate.

…ontents of commonMain and commonTest to the JVM source set.
@ForteScarlet ForteScarlet marked this pull request as draft August 10, 2024 08:10
…n that works with it (there are unspecified implementations on JS and WasmJs)
… Annotatable, AnnotationSpec, CodeBlock to common

There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
Extracts several pieces of logic involving JVM platform types into expected functions.

There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.

Migrate ParameterSpec to common.

There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
Restored some of the functions in Util.kt that needed to wait for CodeBlock migration before they could be used.

Migrate several internal factory functions in TypeVariableName companion objects to the platform (TypeVariableName.jvm.kt).

There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
Migrate several public functions with platform types in FunSpec companion objects to the platform (FunSpec.jvm.kt)

There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
Restore a couple of internal functions in Util.kt that need to wait for KModifier to migrate.

There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
Migrate some APIs involved in operating platform types to the platform (FileSpec.jvm.kt)

There are some related but unmigrated types (such as CodeWriter), and this commit cannot be compiled at the moment.
Change the logic for initializing NO_PACKAGE to what is expected by the platform, since you can't use String's constructor directly in wasmJs.
Add ClassName type properties (OptionalExpectationAnnotations.kt) to the relevant optional platform annotation (e.g., JvmName) instead of using `::class` directly.
@ForteScarlet ForteScarlet marked this pull request as ready for review August 10, 2024 14:38
@ForteScarlet
Copy link
Author

Hey! A while ago, I split and re-pushed the commit message as much as possible (I think I forgot to mention it here, sorry). The current changes should have the vast majority implemented via KMP, and the behavior on the JVM platform should be no different than before.

Some of the content that may be problematic in the platform implementation, ambiguous, or I'm not quite sure how to implement it in the platform, I've marked with a TODO.

Feel free to review them and let me know if there's anything I can do, thanks!

@Egorand
Copy link
Collaborator

Egorand commented Aug 27, 2024

Thanks! Will start the review today.

Copy link
Collaborator

@Egorand Egorand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(reviewed first 5 commits so far)

kotlinpoet/build.gradle.kts Show resolved Hide resolved
}
}
binaries.library()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: delete empty line.

kotlinpoet/build.gradle.kts Show resolved Hide resolved
wasmJsMain {
dependsOn(nonJvmMain)
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove empty line.

kotlinpoet/gradle.properties Show resolved Hide resolved
}

/*
* A character may be part of a Java identifier if any of the following conditions are true:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: fix indentation.

* - it is a non-spacing mark
* isIdentifierIgnorable returns true for the character
*/

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove empty line.

}

internal fun Char.isIdentifierIgnorable(): Boolean {
/*
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: non-documentation comments don't need the /** */ syntax, can just use //.

Comment on lines 43 to 54
browser {
testTask {
useKarma {
useChromeHeadless()
}
}
}
nodejs {
testTask {
useMocha()
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to run the tests in both the browser and on Node. Just Node is fine.

Comment on lines 251 to 256
/** Returns the class name for `element`. */
@DelicateKotlinPoetApi(
message = "Element APIs don't give complete information on Kotlin types. Consider using" +
" the kotlinpoet-metadata APIs instead."
)
public expect fun JvmTypeElement.asClassName(): ClassName
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Things that are JVM-specific should not be in common. Moreover, kotlinpoet-metadata is JVM-only due to kotlin-metadata being JVM-only.

*/
package com.squareup.kotlinpoet

public expect interface Closeable : AutoCloseable
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use AutoCloseable on all platforms and only add the JVM's Closeable where needed. We don't want to put a type in our public API for just doing this, though.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't realize that the types that implement Closeable are internal types, you're right, it doesn't seem necessary to define an additional Closeable

@ForteScarlet
Copy link
Author

Changes have been made to the needed adjustments mentioned above. Feel free to let me know of any other reviews after that~

@egorikftp
Copy link

@JakeWharton @Egorand Could you please take a look the PR?
I'm developing plugin for converting xml/svg into Compose ImageVector and I want to make a WASM version, but kotlinpoet not works on wasm target yet 🙂

ComposeGears/Valkyrie#180

@JakeWharton
Copy link
Collaborator

I don't think this PR is reviewable. We need to start with something smaller in scope like the TypeName hierarchy by itself. There's way too much API surface here to do at once.

@ForteScarlet
Copy link
Author

@JakeWharton I think I may have misunderstood a bit before. I thought I needed to split the content of this PR into more defined commits based on the changes, but now it seems I need to submit the PRs for each "small part" of the changes step-by-step, right? 😂

@Egorand
Copy link
Collaborator

Egorand commented Oct 3, 2024

Yeah, that was the original suggestion, but it seems it'll be really hard to review it all as a single PR even broken down into individual commits. Agree we should try to merge as many bits as possible independently.

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

Successfully merging this pull request may close these issues.

4 participants