Let's say you want to implement TypeScript with macros:
function foo(str: string) {
return str.toUpperCase()
// ^
// want to provide completion here
}
So we define the function
macro:
macro function {
// for simplicity, only match a single param + type
case {
$name ($param : $type) { $body ... }
} => {
// (1) get the list of possible completions for the type
completions = getCompletions($type)
// (2) record in the completion service that
// each identifier $param in $name has
// those completions
setCompletions($name, $param, completions)
// expand to the appropriate code
return #{
function $name ($param) { $body ... }
}
}
}
Exactly how you implement getCompletions
and setCompletions
depends on how you want to provide the service. The basic idea though is that during expansion you have the information you need to map identifier names in their appropriate scope (the function body) to their completions. You just have to record that somewhere and feed that to the editor.