- Notifications
You must be signed in to change notification settings - Fork 10.6k
[Observation]: fix @Observable macro producing invalid code with certain comments #84833
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
base: main
Are you sure you want to change the base?
Changes from all commits
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 |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// REQUIRES: swift_swift_parser, asserts | ||
// | ||
// UNSUPPORTED: back_deploy_concurrency | ||
// REQUIRES: concurrency | ||
// REQUIRES: observation | ||
// | ||
// RUN: %empty-directory(%t) | ||
// RUN: %empty-directory(%t-scratch) | ||
| ||
// RUN: %target-swift-frontend -typecheck -target %target-swift-5.7-abi-triple -plugin-path %swift-plugin-dir -I %t -dump-macro-expansions %s 2>&1 | %FileCheck %s --color | ||
Comment on lines +1 to +10 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. if anyone has suggestions about the right preamble to use here i'd be glad to learn more. i basically just randomly copied things from other tests that included the | ||
| ||
import Observation | ||
| ||
// Test cases for comment handling with Observable macro | ||
| ||
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) | ||
@Observable | ||
final class CommentOnLineBeforeOtherAnnotation { | ||
@MainActor // Innocent comment | ||
internal var it = 0 | ||
} | ||
| ||
// CHECK-LABEL: {{.*}}CommentOnLineBeforeOtherAnnotation{{.*}}ObservationTracked{{.*}}.swift | ||
// CHECK: @MainActor // Innocent comment | ||
// CHECK-NEXT: @ObservationIgnored | ||
// CHECK-NEXT: private var _it = 0 | ||
| ||
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) | ||
@Observable | ||
final class CommentOnSameLineAsOtherAnnotation { | ||
@MainActor /* Innocent comment */ public var it = 0 | ||
} | ||
| ||
// CHECK-LABEL: {{.*}}CommentOnSameLineAsOtherAnnotation{{.*}}ObservationTracked{{.*}}.swift | ||
// CHECK: @MainActor /* Innocent comment */ | ||
// CHECK-NEXT: @ObservationIgnored | ||
// CHECK-NEXT: private var _it = 0 | ||
| ||
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) | ||
@Observable | ||
final class CommentOnSameLineNoAnnotation { | ||
/* Innocent comment */ public /*1*/ final /*2*/ var /*3*/ it /*4*/ = 0 | ||
} | ||
| ||
// Note: seems there's some weirdness with the existing macro eating/duplicating trivia in some | ||
// cases but we'll just test for the current behavior since it doesn't seem to be covered elsewhere: | ||
| ||
// CHECK-LABEL: {{.*}}CommentOnSameLineNoAnnotation{{.*}}ObservationTracked{{.*}}.swift | ||
// CHECK: /* Innocent comment */ | ||
// CHECK-NEXT: @ObservationIgnored | ||
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 'reality' the dump macro expansion output had some leading whitespace here, but i guess that is ignored in this form of filecheck expectation. is there a way to test for that? i.e. the 'true' output looked something like:
edit: also, note how the whitespace between the comments also appears to be slightly different from the dumped output and what we're testing against (2 spaces in the actual output b/w the '/4/' comments vs only 1 in the tests)... anyone know why that is (and why the test works in this case)? | ||
// CHECK-NEXT: private final /*2*/ var _it /*4*/ /*4*/ = 0 |
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 removes any existing leading trivia, as does the
leadingTrivia:...
in thebindingSpecifier
below. I'm not sure that's a bad thing though.IMO in an ideal world we'd just strip all trivia for the added var, then let BasicFormat handle adding the appropriate whitespace on the resulting var. Any opinions @hamishknight / @rintaro / @phausler?
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.
IIUC in this particular case, we'd be stripping the leading trivia from the
addingAttribute
parameter, which is currently only everObservableMacro.ignoredAttribute
(AFAICT). an alternative i played with was just making theignoredAttribute
(and its sibling) automatically be surrounded by newline trivia to 'break them off' to an extent from wherever they get inserted. ultimately went with this strategy first per your earlier suggestions. theleadingTrivia:
passed to the new binding specifier token syntax should still basically have the same behavior as before just with different whitespace, right?