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

feat: add type aliases, refactor go schema parsing #1493

Merged
merged 13 commits into from
May 16, 2024
Merged

Conversation

matt2e
Copy link
Contributor

@matt2e matt2e commented May 15, 2024

#1238
Adds the ability to declare type aliases in modules

//ftl:typealias
type UserId string

There is a lot of overlap between typealiases and enums. They both redefine an existing type as a new type, and therefore need to make sure our schema parsing does not skip this defined type by looking at the underlying type.
There were also issues if implicit exports, enum cases (and more?) were encountered in the ast tree before we found the typealias or enum definition.
This PR solves that by doing an initial pass just to find all typealias and enum declarations for the module and then doing the normal pass.

Previously typealiases were allowed without any declaration but they would just fall back to the underlying type.
This PR makes this an error as we do not know if this type should be an enum or a type alias. We may want to discuss this more.

fixes #1475 #1476 #1477 #1492 #1449

@matt2e
Copy link
Contributor Author

matt2e commented May 15, 2024

making this a draft because its failing tests and I'm done for the night

@matt2e matt2e force-pushed the matt2e/type-alias branch 2 times, most recently from 5336209 to af9a4b1 Compare May 15, 2024 10:47
@matt2e
Copy link
Contributor Author

matt2e commented May 15, 2024

Actually tests are succeeding, now just lint failing (sumtypes). Will submit and fix that tomorroq

@matt2e matt2e marked this pull request as ready for review May 15, 2024 10:51
Copy link
Member

@wesbillman wesbillman left a comment

Choose a reason for hiding this comment

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

Looks good! Love all the tests :)

Comment on lines +282 to +286
mdecl := scopes.Resolve(*n)
if mdecl == nil && n.Module == "" {
merr = append(merr, errorf(n, "unknown reference %q", n))
}
if mdecl := scopes.Resolve(*n); mdecl != nil {
if mdecl != nil {
Copy link
Member

Choose a reason for hiding this comment

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

oh nice! :)

`117:1-26: parent enum "ExportedTypeEnum" is exported, but directive "ftl:data" on "PrivateData" is not: all variants of exported enums that have a directive must be explicitly exported as well`,
`121:21-60: config and secret names must be valid identifiers`,
`127:1-26: only one directive expected for type alias`,
`133:2-2: type is not declared as an ftl type alias or enum: NonFTLAlias`,
Copy link
Member

Choose a reason for hiding this comment

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

I was a bit confused by this error message at first. I wonder if shuffling it around would make it more clear 🤔

type "NonFTLAlias" is not declared as an ftl type alias or enum 

Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed, but also in general I tend to leave out the typename iff the error is pointing directly at it already, as it's redundant information (not sure if that is the case here).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched it to:

type is not declared as an ftl enum or type alias

@@ -117,3 +119,16 @@ type PrivateData struct{}
func (PrivateData) exportedTypeEnum() {}

var invalidConfig = ftl.Config[string]("not an identifier")

// There can be only one
Copy link
Member

Choose a reason for hiding this comment

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

Gif

@alecthomas alecthomas requested a review from worstell May 15, 2024 19:28
@alecthomas
Copy link
Collaborator

Added @worstell as she's been touching this code a lot recently!

Copy link
Collaborator

@alecthomas alecthomas left a comment

Choose a reason for hiding this comment

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

Huge!

Who knew typealias support would be such a PITA?!

backend/schema/enum.go Outdated Show resolved Hide resolved
backend/schema/module.go Show resolved Hide resolved
@@ -15,59 +15,71 @@ type TypeEnum interface {
tag()
}

type Bool bool
//ftl:typealias
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not for this PR but I'm wondering if we should move these tests into go-runtime

if maybeVisitTypeEnumVariant(pctx, node, directives) {
return
}
maybeVisitTypeEnumVariant(pctx, node, directives)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This allowed this case: #1492
Updating it now to collect errors for subsequent type enums it conforms to

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually no. This is there because even though something is a variant we still need to continue to process it's declaration. eg: a type alias that conforms to am enum.

go-runtime/compile/schema.go Outdated Show resolved Hide resolved
`117:1-26: parent enum "ExportedTypeEnum" is exported, but directive "ftl:data" on "PrivateData" is not: all variants of exported enums that have a directive must be explicitly exported as well`,
`121:21-60: config and secret names must be valid identifiers`,
`127:1-26: only one directive expected for type alias`,
`133:2-2: type is not declared as an ftl type alias or enum: NonFTLAlias`,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Agreed, but also in general I tend to leave out the typename iff the error is pointing directly at it already, as it's redundant information (not sure if that is the case here).

@matt2e matt2e force-pushed the matt2e/type-alias branch 3 times, most recently from f5c8aed to 9612b84 Compare May 16, 2024 05:03
@matt2e matt2e changed the title feat: Add type aliases, refactor go schema parsing feat: add type aliases, refactor go schema parsing May 16, 2024
# Conflicts:
#	backend/protos/xyz/block/ftl/v1/schema/schema.pb.go
#	go-runtime/compile/schema.go

# Conflicts:
#	backend/protos/xyz/block/ftl/v1/schema/schema.pb.go
# Conflicts:
#	buildengine/testdata/type_registry_main.go

# Conflicts:
#	backend/protos/xyz/block/ftl/v1/schema/schema.pb.go
#	go-runtime/compile/external-module-template/_ftl/go/modules/{{ range .NonMainModules }}{{ push .Name . }}{{ end }}/external_module.go
@matt2e matt2e merged commit a44e99b into main May 16, 2024
23 checks passed
@matt2e matt2e deleted the matt2e/type-alias branch May 16, 2024 05:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants