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

[swift2objc] Support optionals #1742

Merged
merged 7 commits into from
Nov 25, 2024
Merged

[swift2objc] Support optionals #1742

merged 7 commits into from
Nov 25, 2024

Conversation

liamappelbe
Copy link
Contributor

@liamappelbe liamappelbe commented Nov 21, 2024

Optionals in Swift are essentially the same as nullables in Dart. This PR adds support for them by parsing them into the new OptionalType class.

The parsing side of this is pretty complicated, because unlike classes, structs, and primitives, optional types aren't presented in the symbolgraph as a single token with a type ID. Instead we get a "?" token that comes after the type token. So now we have to write a parser.

I wrote a pretty general parser architecture, because we're also going to need it for closures, tuples, and arrays, which also appear as a sequence of tokens. I used a Pratt parser, but without any precedence, so it ends up being pretty simple and readable. The entire parser is in parse_type.dart, and the entrypoint is parseType.

One extra complexity is that sometimes some of the tokens are concatenated. For example, you'd expect foo(bar: Int?) to be tokenized as ["foo", "(", "bar", ": ", "Int", "?", ")"], but actually the "?" and ")" get merged: ["foo", "(", "bar", ": ", "Int", "?)"]. So we also need a preprocessing stage that splits up all the known cases where this happens. This is handled by the TokenList class.

Other changes

  • Had to rewrite parseInitializerParams to use the new parseType function, but it ends up being simpler and more readable.
  • Removed id and name from ReferredType, since not all types have a name or ID.
  • All the type comparisons that used to be id based have been migrated to the new sameAs method.
  • All the codegen that used to print the name now prints the swiftType.
  • Made FunctionDeclaration's returnType non-nullable. Not specifying the return type of a function just means it's Void in Swift, so there's no point making this field nullable. Making it non-null simplifies some stuff.
  • Renamed pase_function_declaration.dart to parse_function_declaration.dart
  • Removed test/unit/parse_initializer_param_input.json because it isn't actually used by the test.

Optional primitives aren't supported atm: #1743

@coveralls
Copy link

coveralls commented Nov 22, 2024

Coverage Status

coverage: 90.171% (-0.03%) from 90.198%
when pulling c34d60e on optionals
into 7afad0b on main.

@liamappelbe liamappelbe changed the title WIP: [swift2objc] Support optionals [swift2objc] Support optionals Nov 22, 2024
@liamappelbe liamappelbe marked this pull request as ready for review November 22, 2024 05:13
@@ -38,10 +40,16 @@ extension TopLevelOnly<T extends Declaration> on List<T> {
).toList();
}

/// If fragment['kind'] == kind, returns fragment['spelling']. Otherwise returns
Copy link
Member

Choose a reason for hiding this comment

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

nit: Wrap code with backticks. [] might do some linking stuff in markdown otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@liamappelbe liamappelbe merged commit 4ce4816 into main Nov 25, 2024
6 checks passed
@liamappelbe liamappelbe deleted the optionals branch November 25, 2024 22:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants