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

fix: check for invalid function calls into external modules #1702

Merged
merged 4 commits into from
Jun 11, 2024

Conversation

matt2e
Copy link
Collaborator

@matt2e matt2e commented Jun 7, 2024

Closes #1640
Checks for:

  • publishing directly to an external module's exported topic
  • directly calling an external module's verb, rather than using ftl.Call(...)
    • This already fails at runtime, but it's nice to have this as a compile error

Both of these compile-time checks are not fool proof, any indirection will mean these checks don't catch it. But it is good to catch what we can.
eg:

var extTopic = external.Topic
extTopic.Publish(...) // compiler believes this is a local topic

Added a separate issue for this for pubsub as it may not be as high a priority: #1703

@matt2e matt2e requested a review from alecthomas as a code owner June 7, 2024 04:47
@matt2e matt2e requested review from a team and worstell and removed request for a team June 7, 2024 04:47
@ftl-robot ftl-robot mentioned this pull request Jun 7, 2024

if lhsType, ok := pctx.pkg.TypesInfo.TypeOf(selExpr.X).(*types.Named); ok && lhsType.Obj().Pkg().Path() == ftlPkgPath {
// Calling a function on an FTL type
if lhsType.Obj().Name() == ftlTopicHandleTypeName && selExpr.Sel.Name == "Publish" {
Copy link
Collaborator Author

@matt2e matt2e Jun 7, 2024

Choose a reason for hiding this comment

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

Checking for github.com/TBD54566975/ftl/go-runtime/ftl and TopicHandle separately because the actual full name also includes [AnEventType], which we don't care about

go-runtime/compile/schema.go Outdated Show resolved Hide resolved
// checks if the is directly:
// - calling external verbs
// - publishing to an external module's topic
func validateCallExpr(pctx *parseContext, node *ast.CallExpr) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We do want this to be recursive at some point, such that if you call a function that calls a verb, we can track that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This should already be checking this case because we aren't just checking within functions defined as verbs:

//ftl:verb
func Verb(...) (...) {
   helper()
   ...
}

func helper() {
    externalmodule.Verb() // <--- Error here
}

if lhsIsExternal && strings.HasPrefix(lhsPkgPath, "ftl/") {
if _, ok := pctx.pkg.TypesInfo.TypeOf(selExpr.Sel).(*types.Signature); ok {
// can not call functions in external modules directly
pctx.errors.add(errorf(node, "can not call verbs in other modules directly: use ftl.Call(…) instead"))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice

@matt2e matt2e force-pushed the matt2e/external-publish branch from d5ee26f to 24126bc Compare June 11, 2024 00:17
@matt2e matt2e merged commit 6b46e9b into main Jun 11, 2024
39 checks passed
@matt2e matt2e deleted the matt2e/external-publish branch June 11, 2024 00:28
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.

Handle calling Publish() on another module's topic
3 participants