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

Cleanup the runtime code #114

Merged
merged 29 commits into from
Dec 18, 2023
Merged

Conversation

lppedd
Copy link
Contributor

@lppedd lppedd commented Dec 7, 2023

Goals

  • Improving the runtime performance by avoiding unnecessary (unchecked) casts, unnecessary non-null assertions, by using the right data structures (possibly the same used in the Java runtime) and immutable types
  • Improving the development and debugging experience
  • Improving the IDE navigation experience
  • Easing the process of porting future changes

Non goals

It is a non goal to change the behavior of the code. It should possibly stay aligned with the Java runtime, line by line.

Methodology

Each commit is mapped to a runtime Kotlin package.

Each file is cleaned-up in multiple passes:

  • A first pass is done using the IDE formatter
  • A second pass is done by resolving all possible inspections
  • A third pass is done by matching the file, line by line, with the Java runtime equivalent.
    If a method is missing (e.g., StringBuilder.appendCodePoint), it is implemented.

TODO

  • Calls to toHexString should be passed a custom hex format to align to the Java implementation.

    val hexFormat = HexFormat {
     upperCase = true
     number {
       prefix = "0x"
       removeLeadingZeros = true
     }
    }
    
  • Cleanup calls to System.out.println
    The Java runtime calls .format with a terminating \n, but we don't need that \n

@lppedd
Copy link
Contributor Author

lppedd commented Dec 12, 2023

@ftomassetti I'm going to finish off the main package and then call it done.
There will be org.antlr.v4.kotlinruntime.atn still not cleaned up but I can do it in the future.

override fun isEmpty(): Boolean =
n == 0

// TODO(Edoardo): why is this one commented out?
Copy link
Member

Choose a reason for hiding this comment

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

TODO that we should look into before merging

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Answer is we already have the typed version.

override fun contains(element: T): Boolean =
  containsFast(element)

So I've simply removed it now.

"${key}:${value}"
}

// TODO: are bucket entries actually nullable?
Copy link
Member

Choose a reason for hiding this comment

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

TODO

existingBucket
} else {
// TODO(Edoardo): should be a LinkedList
val list = ArrayList<Entry<K, V>?>()
Copy link
Member

Choose a reason for hiding this comment

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

TODO

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can't do anything about it right now. Behavior is the same with ArrayList luckily.
Kotlin Multiplatform needs a common LinkedList, at that point we can switch.

* @author Sam Harwell
*/
open class IntegerList {
public open class IntegerList {
Copy link
Member

Choose a reason for hiding this comment

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

In Kotlin, ca we use lists of Ints?

Copy link
Contributor Author

@lppedd lppedd Dec 12, 2023

Choose a reason for hiding this comment

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

Let's keep the runtime a 1 to 1 match. I'd prefer using IntegerList instead of changing all the usages.

Also, using a List<Int> means dealing with objects instead of primitive ints.

@@ -9,17 +9,16 @@ package org.antlr.v4.kotlinruntime.misc
import org.antlr.v4.kotlinruntime.Vocabulary
import org.antlr.v4.kotlinruntime.atn.ATN


// TODO(Edoardo): this one requires reading files
Copy link
Member

Choose a reason for hiding this comment

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

TODO

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will implement this for the JVM only probably, but on a subsequent PR, not this one, don't want to mix too many changes.

class LogManager {

// TODO(Edoardo): uncomment once kotlinx-datetime supports date formatting
public class LogManager {
Copy link
Member

Choose a reason for hiding this comment

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

Should we move this to a ticket and delete the file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No no, let's keep the file there so we know we need to look into it.
kotlinx-datetime will get formatting support in a couple weeks I think.

@@ -10,99 +10,90 @@ package org.antlr.v4.kotlinruntime.misc
*
* @author Sam Harwell
*/
object MurmurHash {
public object MurmurHash {
Copy link
Member

Choose a reason for hiding this comment

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

What is a MurmurHash?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ftomassetti
Copy link
Member

I started taking a look at the code, but I am afraid I will not be able to do a proper review as there are too many changes. Also, I think this is code coming from the ANTLR Java runtime, so I assume that most of it will be correct. And I will rely on tests to catch blatant things

@lppedd
Copy link
Contributor Author

lppedd commented Dec 12, 2023

Definitely don't review it in details, not worth it.
The code is a 1 to 1 mapping with the Java runtime (I'm doing it by reading each source file line by line), with some Kotlin-friendly code style changes.

@lppedd
Copy link
Contributor Author

lppedd commented Dec 13, 2023

I'm almost done. Just missing a couple of big classes.

In the end I did also the atn package, as the type nullability is tied to the parser and lexer.

@lppedd
Copy link
Contributor Author

lppedd commented Dec 14, 2023

Done!

Turns out there was code not on par with ANTLR 4.13.1.
I've also re-enabled functionalities which were commented out, such as ParserInterpreter, ATNSerializer, XPath* (although we still miss a multiplatform implementation for a couple of Java methods), and many others.

I've deleted two files, which were commented out completely:

  • UnbufferedCharStream: pretty much unnecessary for us + relies on Java's Readers
  • LogManager: unnecessary for us + relies on Java's Readers

We might be able to restore them at some point, but now it doesn't make sense.

@lppedd
Copy link
Contributor Author

lppedd commented Dec 14, 2023

I'll do a couple tests (@ftomassetti you can run some tests on your grammars too if you want), update the branch with master's changes, and then mark it as ready to be merged.

Note that we now have a very strong type system, so a release with this code is not backward compatible.

Comment on lines +150 to +158
public fun isNameChar(@Suppress("UNUSED_PARAMETER") c: Int): Boolean {
TODO("Need isUnicodeIdentifierPart")
// return Character.isUnicodeIdentifierPart(c)
}

public fun isNameStartChar(@Suppress("UNUSED_PARAMETER") c: Int): Boolean {
TODO("Need isUnicodeIdentifierStart")
// return Character.isUnicodeIdentifierStart(c)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you know how to re-implement those two methods, feel free to let me know or open another PR after this one is merged.

@ftomassetti
Copy link
Member

Note that we now have a very strong type system, so a release with this code is not backward compatible.

Makes sense, I think at this stage breaking changes have to be expected

@frett
Copy link
Contributor

frett commented Dec 14, 2023

as someone using this in production multiplatform code I'm fine with the breaking changes since it's bringing it up to be more maintainable and Kotlin friendly :)

@lppedd
Copy link
Contributor Author

lppedd commented Dec 14, 2023

Cool! Hopefully there won't be changes this big anymore.

We can merge this one and publish it as another RC, so you can also test it.
I'll try to integrate more grammar tests.

@lppedd
Copy link
Contributor Author

lppedd commented Dec 14, 2023

The C++ grammar from the ANTLR4 grammars repository (which is enormous), compiles fine 🔝

The not-so-good news: the C++ generated parser (20000 LOC) crashes the Kotlin compiler lol

@lppedd
Copy link
Contributor Author

lppedd commented Dec 14, 2023

Managed to get it to run by replacing the scoped { } inline function with if (true).

C++ tests run fine and pass. I'll open a YouTrack issue once this is merged, since this is valid for K2 too.

@lppedd
Copy link
Contributor Author

lppedd commented Dec 14, 2023

I've inspected the outputted JS code and the good news is the K/JS compiler optimizes the if (true) check away.

I'll use that one in place of scoped for now, so that it works ok even if you've got an absurdly big grammar.

@ftomassetti
Copy link
Member

Great work @lppedd , should we mark the PR as ready for review and merge it?

@lppedd
Copy link
Contributor Author

lppedd commented Dec 15, 2023

Thank you! Yup, let's merge this one too, but first let's merge #115

@lppedd lppedd marked this pull request as ready for review December 15, 2023 15:40
@ftomassetti ftomassetti merged commit bc7d414 into Strumenta:master Dec 18, 2023
3 checks passed
@lppedd lppedd deleted the chore/formatting branch December 18, 2023 10:51
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.

3 participants