-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[CodeCompletion] Suggest synthesized declarations from macros #66821
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
[CodeCompletion] Suggest synthesized declarations from macros #66821
Conversation
@swift-ci Please smoke test |
for (auto *member : NTD->getMembers()) { | ||
if (!ctx.evaluator.hasActiveRequest(ExpandPeerMacroRequest{member})) { | ||
(void)evaluateOrDefault( | ||
ctx.evaluator, | ||
ExpandPeerMacroRequest{member}, | ||
{}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not necessary because visitAuxiliaryDecls()
calls it lazily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What calls visitAuxiliaryDecls
for members in regular type checking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's populateLookupTableEntryFromMacroExpansions
called from DirectLookupRequest::evaluate()
824439f
to
f88f181
Compare
@swift-ci Please smoke test |
f88f181
to
34c0f61
Compare
@swift-ci Please smoke test |
@@ -3827,6 +3827,10 @@ bool ValueDecl::shouldHideFromEditor() const { | |||
getBaseIdentifier().str().startswith("$__")) | |||
return true; | |||
|
|||
// Macro unique names are only intended to be used inside the expanded code. | |||
if (MacroDecl::isUniqueMacroName(getBaseName())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 👍
for (auto *member : NTD->getMembers()) { | ||
if (!ctx.evaluator.hasActiveRequest(ExpandPeerMacroRequest{member})) { | ||
(void)evaluateOrDefault( | ||
ctx.evaluator, | ||
ExpandPeerMacroRequest{member}, | ||
{}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What calls visitAuxiliaryDecls
for members in regular type checking?
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/plugins/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/../Macros/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath | ||
|
||
// RUN: %target-swift-ide-test -batch-code-completion -source-filename %s -filecheck %raw-FileCheck -completion-output-dir %t -plugin-path %t/plugins -parse-as-library | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since arbitrary
goes down fairly different paths to named, possibly worth adding tests for it as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently arbitrary
at top-level is not really supported:
If we add names: arbitrary
error: 'declaration' macros are not allowed to introduce arbitrary names at global scope
error: 'peer' macros are not allowed to introduce arbitrary names at global scope
And the macro decl becomes isInvalid()
, and the expansion is not performed.
If we omit names
from the macro decl:
error: declaration name '<name>' is not covered by macro '<macro name>'
Introduced values are found and type checked, but since it's error
, it doesn't built.
I feel like we should remove
unexpandedDecls.append(TopLevelArbitraryMacros.begin(),
TopLevelArbitraryMacros.end());
From lookupVisibleDecls()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking within a struct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For non top level cases, there is not much different code paths between arbitrary and named, but sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you 🙏🏽
if (auto *E = elem.dyn_cast<Expr *>()) { | ||
// 'MacroExpansionExpr' at code-item position may introduce value decls. | ||
// NOTE: the expression must be type checked. | ||
// FIXME: In code-completion local expressions are _not_ type checked. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we get completions from macro expansion declarations if the corresponding MacroExpansionExpr
hasn’t been type-checked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't. So we need to typecheck MacroExpansionExpr
before here, or here.
@PeerWithSuffix func localFunc() {} | ||
|
||
do { | ||
#^LOCAL?skip=FIXME^# |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this to an xfail
so we don’t forget to change it if it’s fixed?
#^LOCAL?skip=FIXME^# | |
#^LOCAL?xfail=FIXME^# |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I deliberately make this skip
for now. There's two FIXMEs here.
MacroExpansionExpr
is not type-checked.- Macro expansion in function bodies in fast-completion.
If we fix (1) but not (2) this test goes nondeterministic because it succeeds only when LOCAL
token is tested first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, OK. Makes sense.
34c0f61
to
4699899
Compare
* Don't invalidate the lookup cache in 'getOrCreateSynthesizedFile()' Adding a synthesized file itself doesn't introduce any decls. Instead, we should invalidate the right after the actual declrations are added in the file * Remove 'SourceLookupCache::invalidate()' method. It was just used right before the destruction. It was just not necessary * Include auxiliary decls in 'SourceLookupCache::lookupVisibleDecls()' Previously, global symbol completion didn't include decls synthesized by peer macros or freestanding decl macros * Include "auxiliary decls" in visible member lookup, and visible local decl lookup * Hide macro unique names rdar://110535113
4699899
to
096d8ea
Compare
@swift-ci Please smoke test |
getOrCreateSynthesizedFile()
Adding a synthesized file itself doesn't introduce any decls. Instead, we should invalidate it right after the actual declrations are added in the fileSourceLookupCache::invalidate()
method. It was just used right before the destruction. It was just not necessarySourceLookupCache::lookupVisibleDecls()
Previously, global symbol completion didn't include decls synthesized by peer macros or freestanding decl macrosrdar://110535113