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

Port TypeScript code generator to Kotlin. #431

Merged
merged 18 commits into from Jul 26, 2021
Merged

Port TypeScript code generator to Kotlin. #431

merged 18 commits into from Jul 26, 2021

Conversation

hokeun
Copy link
Member

@hokeun hokeun commented Jul 26, 2021

No description provided.

Copy link
Member

@lhstrh lhstrh left a comment

Choose a reason for hiding this comment

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

Great progress!

org.lflang/src/org/lflang/generator/LFGenerator.java Outdated Show resolved Hide resolved
org.lflang/src/org/lflang/generator/LFGenerator.java Outdated Show resolved Hide resolved
org.lflang/src/org/lflang/generator/ts/TsFileConfig.kt Outdated Show resolved Hide resolved
org.lflang/src/org/lflang/generator/ts/TsFileConfig.kt Outdated Show resolved Hide resolved
org.lflang/src/org/lflang/generator/ts/TsGenerator.kt Outdated Show resolved Hide resolved
org.lflang/src/org/lflang/generator/ts/TsGenerator.kt Outdated Show resolved Hide resolved
org.lflang/src/org/lflang/generator/ts/TsGenerator.kt Outdated Show resolved Hide resolved
for (federate in federates) {
var tsFileName = fileConfig.name
if (isFederated) {
tsFileName += '_' + federate.name
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a FedFileConfig class that might be useful here. Here is an example of its use in the C target. The behavior in C target is to put each federate into its own folder.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. I believe the federated execution is not supported yet in TypeScript and I'm planning to fix that later. I added a TODO to follow up. Would this be ok with you for now?

@hokeun hokeun self-assigned this Jul 26, 2021
1) Merge create methods for FileConfigs and Generators
2) Fix comment formatting
3) Add TODOs for the comments to be followed up.
String classNamePrefix;
String targetName;
switch (target) {
case CPP: {
Copy link
Member

Choose a reason for hiding this comment

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

If I'm not mistaken this info can be read straight from the Target enum. If not, it probably makes sense to store it there.

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed targetName, which is for the error messages.

I could toLowerCase and some string operations for package name and class name prefix; however, I think explicitly assigning the values makes the code more readable, and I'm afraid that for other languages, the relationship between enum and these names can be arbitrary.

Would this make sense to you?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's better to have fewer strings floating around and strive for uniformity. For the package name, toLower of the name() sounds appropriate. When it comes to the class name prefix, I guess the toString() could work? We have both TypeScript and TS floating around in the code base, and the Kotlin classes now use Ts; this is a perfect example of lack of uniformity that we can solve by adopting some conventions; the Target enum is the place to encode them.

Copy link
Member Author

Choose a reason for hiding this comment

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

Got it. I did that. Thanks for the explanation.

@hokeun hokeun changed the title Ts kotlin Port TypeScript code generator to Kotlin. Jul 26, 2021
@hokeun
Copy link
Member Author

hokeun commented Jul 26, 2021

Thanks, Marten and Soroush, for reviewing my pull request! I'll be merging this pull request to master as it seems that your comments are all either addressed or marked to be followed up. Let me know if you still have comments. I'll be happy to address them soon!

@hokeun hokeun closed this Jul 26, 2021
@hokeun hokeun reopened this Jul 26, 2021
@hokeun hokeun merged commit a5da2a4 into master Jul 26, 2021
Copy link
Collaborator

@oowekyala oowekyala left a comment

Choose a reason for hiding this comment

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

Just a few minor comments about Kotlin code style and idioms. Most of my comments can be fixed automatically in Intellij, for instance:

Capture d’écran de 2021-07-27 14-47-08

This is why I think it's cheap to fix them to have a more idiomatic code style.

// Next handle timers.
for (timer in reactor.timers) {
var timerPeriod: String
if (timer.period === null) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a weird way to put it. You don't need a var. You could initialize the variable like so:

            val timerPeriod: String =
                if (timer.period == null) "0" 
                else getTargetValue(timer.period)

or equivalently

                val timerPeriod = timer.period?.let { getTargetValue(it) } ?: "0"

Same for the other vars.

private fun pr(builder: StringBuilder, text: Any) = tsGenerator.prw(builder, text)
private fun pr(text: Any) = tsGenerator.prw(code, text)

private fun getTargetValue(v: Value): String = tsGenerator.getTargetValueW(v)
Copy link
Collaborator

@oowekyala oowekyala Jul 27, 2021

Choose a reason for hiding this comment

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

It would be more idiomatic to use extensions for those methods. You can write

 private fun Value.getTargetValue(): String = tsGenerator.getTargetValueW(this) 

With this style, in my above comment,

                val timerPeriod = timer.period?.let { getTargetValue(it) } ?: "0"

can be rewritten to

                val timerPeriod = timer.period?.getTargetValue() ?: "0"

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried as you commented, but it doesn't compile. Maybe I'm missing something?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Look at the edit to my comment. If that doesn't work please post the compiler error

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, done in #444

@oowekyala
Copy link
Collaborator

I think since this PR, the old TypeScriptGenerator.xtend has never been deleted. @hokeun can we delete it or is it still used somewhere?

https://github.com/lf-lang/lingua-franca/blob/master/org.lflang/src/org/lflang/generator/TypeScriptGenerator.xtend

@hokeun
Copy link
Member Author

hokeun commented Oct 12, 2021

I think since this PR, the old TypeScriptGenerator.xtend has never been deleted. @hokeun can we delete it or is it still used somewhere?

https://github.com/lf-lang/lingua-franca/blob/master/org.lflang/src/org/lflang/generator/TypeScriptGenerator.xtend

Thanks, Clément. I postponed the deletion for a bit until we feel confident that we don't really need it anymore. I think it's a good time to actually delete this. I'll create a PR for deleting these.

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.

None yet

4 participants