-
Notifications
You must be signed in to change notification settings - Fork 440
[SwiftLexicalLookup] Add ASTScope related fixes and lookInMembers result kind. #2852
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
Changes from 1 commit
d83af9c
7521e4e
fae4d0e
3de7208
433f14b
0f9b2bc
baf6a2f
fc1ab88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,7 +20,7 @@ import SwiftSyntax | |
case `self`(DeclSyntaxProtocol) | ||
/// `Self` keyword representing object type. | ||
/// Could be associated with type declaration or extension. | ||
case `Self`(ProtocolDeclSyntax) | ||
case `Self`(DeclSyntaxProtocol) | ||
/// `error` value caught by a `catch` | ||
/// block that does not specify a catch pattern. | ||
case error(CatchClauseSyntax) | ||
|
@@ -147,27 +147,33 @@ import SwiftSyntax | |
case .identifier(let syntax, _): | ||
return syntax.identifier.positionAfterSkippingLeadingTrivia | ||
case .declaration(let syntax): | ||
return syntax.name.position | ||
return syntax.name.positionAfterSkippingLeadingTrivia | ||
case .implicit(let implicitName): | ||
switch implicitName { | ||
case .self(let declSyntax): | ||
switch Syntax(declSyntax).as(SyntaxEnum.self) { | ||
case .functionDecl(let functionDecl): | ||
return functionDecl.name.position | ||
return functionDecl.name.positionAfterSkippingLeadingTrivia | ||
case .initializerDecl(let initializerDecl): | ||
return initializerDecl.initKeyword.positionAfterSkippingLeadingTrivia | ||
case .subscriptDecl(let subscriptDecl): | ||
return subscriptDecl.accessorBlock?.position ?? subscriptDecl.endPosition | ||
return subscriptDecl.accessorBlock?.positionAfterSkippingLeadingTrivia | ||
?? subscriptDecl.endPositionBeforeTrailingTrivia | ||
case .variableDecl(let variableDecl): | ||
return variableDecl.bindings.first?.accessorBlock?.positionAfterSkippingLeadingTrivia | ||
?? variableDecl.endPosition | ||
default: | ||
return declSyntax.positionAfterSkippingLeadingTrivia | ||
} | ||
case .Self(let protocolDecl): | ||
return protocolDecl.name.positionAfterSkippingLeadingTrivia | ||
case .Self(let declSyntax): | ||
switch Syntax(declSyntax).as(SyntaxEnum.self) { | ||
case .protocolDecl(let protocolDecl): | ||
return protocolDecl.name.positionAfterSkippingLeadingTrivia | ||
Comment on lines
+170
to
+171
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we only need this for protocols and not other type declarations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this PR, protocol declarations are the only places we are introducing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, you’re not handling class Foo {
func bar() -> Self { fatalError() }
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interestingly, it seems to me like
Nevertheless, there certainly are more places protocol Foo {}
extension Foo {
func bar() -> Self { fatalError() }
}
|
||
default: | ||
return declSyntax.positionAfterSkippingLeadingTrivia | ||
} | ||
case .error(let catchClause): | ||
return catchClause.body.position | ||
return catchClause.body.positionAfterSkippingLeadingTrivia | ||
default: | ||
return implicitName.syntax.positionAfterSkippingLeadingTrivia | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,9 @@ | |
import SwiftSyntax | ||
|
||
protocol CanInterleaveResultsLaterScopeSyntax: ScopeSyntax { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a comment explaining what it means to interleave results later? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing this out! I added documentation comments to the definition of |
||
/// Perform lookup in this scope and later introduce results | ||
/// passed as `resultsToInterleave`. | ||
/// The exact behavior depends on a specific scope. | ||
func lookupWithInterleavedResults( | ||
_ identifier: Identifier?, | ||
at lookUpPosition: AbsolutePosition, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -498,7 +498,13 @@ import SwiftSyntax | |
with config: LookupConfig | ||
) -> [LookupResult] { | ||
if memberBlock.range.contains(lookUpPosition) { | ||
return [.lookInMembers(self)] + defaultLookupImplementation(identifier, at: lookUpPosition, with: config) | ||
let implicitSelf: [LookupName] = [.implicit(.Self(self))] | ||
.filter { name in | ||
checkIdentifier(identifier, refersTo: name, at: lookUpPosition) | ||
} | ||
|
||
return (implicitSelf.isEmpty ? [] : [.fromScope(self, withNames: implicitSelf)]) + [.lookInMembers(self)] | ||
+ defaultLookupImplementation(identifier, at: lookUpPosition, with: config) | ||
} else { | ||
return defaultLookupImplementation(identifier, at: lookUpPosition, with: config) | ||
} | ||
|
@@ -665,13 +671,16 @@ import SwiftSyntax | |
) | ||
} | ||
|
||
let lookInMembers: [LookupResult] = | ||
inheritanceClause?.range.contains(lookUpPosition) ?? false ? [] : [.lookInMembers(self)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of blacklisting the inheritance clause, wouldn’t it be better to whitelist the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good point. As for now, I couldn't find a specific case this wouldn't work and it definitely improves readability of this part of code as well. I changed it to check if lookup was started inside |
||
|
||
return results | ||
+ defaultLookupImplementation( | ||
identifier, | ||
at: lookUpPosition, | ||
with: config, | ||
propagateToParent: false | ||
) + [.lookInMembers(self)] + lookupInParent(identifier, at: lookUpPosition, with: config) | ||
) + lookInMembers + lookupInParent(identifier, at: lookUpPosition, with: config) | ||
} | ||
} | ||
|
||
|
@@ -868,12 +877,11 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe | |
at lookUpPosition: AbsolutePosition, | ||
with config: LookupConfig | ||
) -> [LookupResult] { | ||
if let parentScope, | ||
parentScope.is(MemberBlockSyntax.self), | ||
bindings.first?.accessorBlock?.range.contains(lookUpPosition) ?? false | ||
{ | ||
if bindings.first?.accessorBlock?.range.contains(lookUpPosition) ?? false { | ||
let shouldIntroduceSelf = parentScope?.is(MemberBlockSyntax.self) ?? false | ||
|
||
return defaultLookupImplementation( | ||
in: [.implicit(.self(self))], | ||
in: LookupName.getNames(from: self) + (shouldIntroduceSelf ? [.implicit(.self(self))] : []), | ||
identifier, | ||
at: lookUpPosition, | ||
with: config | ||
|
@@ -883,14 +891,16 @@ extension SubscriptDeclSyntax: WithGenericParametersScopeSyntax, CanInterleaveRe | |
} | ||
} | ||
|
||
/// If a member, introduce results passed in `resultsToInterleave` | ||
/// and then pass lookup to the parent. Otherwise, perform `lookup`. | ||
func lookupWithInterleavedResults( | ||
_ identifier: Identifier?, | ||
at lookUpPosition: AbsolutePosition, | ||
with config: LookupConfig, | ||
resultsToInterleave: [LookupResult] | ||
) -> [LookupResult] { | ||
guard parentScope?.is(MemberBlockSyntax.self) ?? false else { | ||
return lookupInParent(identifier, at: lookUpPosition, with: config) | ||
return lookup(identifier, at: lookUpPosition, with: config) | ||
} | ||
|
||
return resultsToInterleave + lookupInParent(identifier, at: lookUpPosition, with: config) | ||
|
Uh oh!
There was an error while loading. Please reload this page.