-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SR-8340]Improve fix-it for var and subscript in Protocol #19660
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
Conversation
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 definitely a nice improvement, thank you! One thing - it looks like you should use getSourceRange()
while replacing let
with var
, otherwise it would just insert var
and keep let
or rather et
I think...
One way to validate everything would be to do @swift-ci build toolchain
and verify in Xcode.
I believe |
test/decl/protocol/protocols.swift
Outdated
@@ -502,6 +502,7 @@ protocol LetThereBeCrash { | |||
let x: Int | |||
// expected-error@-1 {{immutable property requirement must be declared as 'var' with a '{ get }' specifier}} | |||
// expected-note@-2 {{declared here}} | |||
// {{13-13= { get \}}} |
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 {{ ... }}
belongs to the line 503 (2 lines above)?
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.
fixed at f0f33eb
test/decl/protocol/protocols.swift
Outdated
@@ -454,7 +454,7 @@ protocol ShouldntCrash { | |||
let fullName: String { get } // expected-error {{'let' declarations cannot be computed properties}} {{3-6=var}} | |||
|
|||
// <rdar://problem/17200672> Let in protocol causes unclear errors and crashes | |||
let fullName2: String // expected-error {{immutable property requirement must be declared as 'var' with a '{ get }' specifier}} | |||
let fullName2: String // expected-error {{immutable property requirement must be declared as 'var' with a '{ get }' specifier}} {{24-24= { get \}}} |
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 believe this diagnostics emits {{3-6=var}}
as well.
Small tip: Try adding {{none}}
without adding {{3-6=var}}
. That should fail with fixit for test-cases. e.g.
test.swift:2:57: error: expected no fix-its; actual fix-it seen: {{11-11=,}}
"foo": 1 // expected-error {{expected ',' separator}} {{none}}
^~~~~~~
{{11-11=,}}
You can paste it. (after you confirmed it's expected, of course)
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.
Wow, it's useful tip.
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.
fixed at 7d35c95
test/decl/var/properties.swift
Outdated
@@ -850,10 +850,10 @@ struct WillSetDidSetDisambiguate3 { | |||
} | |||
|
|||
protocol ProtocolGetSet1 { | |||
var a: Int // expected-error {{property in protocol must have explicit { get } or { get set } specifier}} | |||
var a: Int // expected-error {{property in protocol must have explicit { get } or { get set } specifier}} //{{13-13= { get <#set#> \}}} |
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.
Remove //
before {{13-13...
.
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.
removed at f1d830a
test/decl/var/lazy_properties.swift
Outdated
@@ -12,6 +12,7 @@ protocol SomeProtocol { | |||
lazy var x : Int // expected-error {{'lazy' isn't allowed on a protocol requirement}} {{3-8=}} | |||
// expected-error@-1 {{property in protocol must have explicit { get } or { get set } specifier}} | |||
// expected-error@-2 {{lazy properties must have an initializer}} | |||
// {{18-18= { get set \}}} |
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 fix-it belongs to line 13.
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.
lib/Sema/CodeSynthesis.cpp
Outdated
if (braces.isValid()) | ||
diag | ||
.fixItReplace(var->getParentPatternBinding()->getLoc(), "var") | ||
.fixItReplace(braces, " { get }"); |
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.
It looks like we don't have test cases for this path. Is this possible?
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.
added test case at da9a19b
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 don't think the test case added in da9a19b is actually testing this code path.
If so, the fix-it should be {{14-32= { get \}}}
instead of {{14-32={ get <#set#> \}}}
.
Currently, even if it's spelled with let
, the parser creates non-let
PatternBindingDecl if the decl has accessor block.
I think it's OK to remove if (braces.isValid())
block here.
@@ -6226,7 +6226,7 @@ Parser::parseDeclSubscript(ParseDeclOptions Flags, | |||
if (!Status.isError()) { | |||
if (Flags.contains(PD_InProtocol)) { | |||
diagnose(Tok, diag::expected_lbrace_subscript_protocol) | |||
.fixItInsertAfter(ElementTy.get()->getEndLoc(), " { get set }"); | |||
.fixItInsertAfter(ElementTy.get()->getEndLoc(), " { get <#set#> }"); |
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.
Generally, editor place holder (<#...#>
) doesn't mean it's optional. Instead, we expect developers to replace it with actual code. But I admit it's handy in Xcode. (tab navigation, return key inserts set
, single del key removes the placeholder).
@jrose-apple Any concern about this?
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 found it a little funny too, but I think it's reasonable. @nkcsgexi might also be a good person to ask.
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.
it seems reasonable to me as well. One benefit of placeholder is being easy to remove or being made solid, which i believe is @mzp 's motivation here to include set as a placeholder.
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.
Actually, the <#set#>
was my idea, and that was my motivation.
I made SR-8340.
lib/Sema/CodeSynthesis.cpp
Outdated
auto diag = TC.diagnose(var->getLoc(), diag::protocol_property_must_be_computed); | ||
|
||
if (braces.isValid()) | ||
diag.fixItReplace(braces, " { get <#set#> }"); |
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.
" {
adds extra space.
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.
striped at 7ae9eb7
@rintaro |
SourceLoc does not form a single-character SourceRange; it forms a single-token SourceRange. You're mixing up SourceRange and CharSourceRange. |
Ah, okay so it's just going to wrap the whole |
I pushed changes to fix commented code. |
@swift-ci please smoke test |
lib/Sema/CodeSynthesis.cpp
Outdated
if (braces.isValid()) | ||
diag | ||
.fixItReplace(var->getParentPatternBinding()->getLoc(), "var") | ||
.fixItReplace(braces, " { get }"); |
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 don't think the test case added in da9a19b is actually testing this code path.
If so, the fix-it should be {{14-32= { get \}}}
instead of {{14-32={ get <#set#> \}}}
.
Currently, even if it's spelled with let
, the parser creates non-let
PatternBindingDecl if the decl has accessor block.
I think it's OK to remove if (braces.isValid())
block here.
if (braces.isValid()) | ||
diag.fixItReplace(braces, "{ get <#set#> }"); | ||
else | ||
diag.fixItInsertAfter(var->getTypeLoc().getLoc(), " { get <#set#> }"); |
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.
Do we have test cases without type annotation? like:
protocol P {
let foo
var bar
}
If not, could you add them?
In these cases, ->getTypeLoc().getLoc()
is invalid, so this fix-it should be ignored.
Just in case.
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.
@swift-ci Please smoke test |
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.
Thanks!
…19660) * [Parser] Improve fix-it for subscription in protocol * [Sema] Add fix-it for property in protocol https://bugs.swift.org/browse/SR-8340
Improve fix-it for following code to resolves SR-8340.