-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
Support raw identifiers (backtick-delimited identifiers containing non-identifier characters). #76636
base: main
Are you sure you want to change the base?
Conversation
/// Returns true if this identifier contains non-identifier characters and | ||
/// must always be escaped with backticks, even in contexts were other | ||
/// escaped identifiers could omit backticks (like keywords as argument | ||
/// labels). | ||
bool mustAlwaysBeEscaped() const; |
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.
Could you add some test cases for code completion checking mustAlwaysBeEscaped()
items are actually escaped in code completion suggestions?
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! Those did need to be fixed.
163c6f9
to
cd7ed4e
Compare
This PR is ready except for the issue mentioned in the description of specialized C++ templates getting escaped by backticks (and now since the backticks are added to the mangling, it changes their mangled names as well). After the holidays I'll take another look at how to handle these. |
d392874
to
aac1fdb
Compare
The issues with imported C++ template specializations have been fixed. |
@swift-ci please test |
@swift-ci please test |
@swift-ci please test |
Is there a named feature I can test for with |
Looks like |
@swift-ci please test |
f5ee709
to
7e6f8ba
Compare
@swift-ci please test |
1 similar comment
@swift-ci please test |
@swift-ci please test macOS platform |
1 similar comment
@swift-ci please test macOS platform |
d31b241
to
82eb01b
Compare
@DougGregor @jckarter Can you review please, or forward along to someone who can? Thanks! |
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.
Parser and Index related changes looks good to me.
Deferring to others for other areas.
lib/IDE/CompletionLookup.cpp
Outdated
if (Name.mustAlwaysBeEscaped()) { | ||
// Names that are raw identifiers must always be escaped regardless of | ||
// their position. | ||
shouldEscapeKeywords = true; |
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 calls Lexer:: identifierMustAlwaysBeEscaped(StringRef)
twice, in Name.mustAlwaysBeEscaped()
and Builder.escapeKeyword()
which is a waste. Can we avoid that? I'm fine with just manually wrapping it with back-ticks here, or you could factor out the escaping logic from Builder.escapeKeyword
.
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.
Done. I've factored out a escapeWithBackticks
method in the builder so it can be called directly.
lib/IDE/CompletionLookup.cpp
Outdated
Identifier Name) { | ||
if (Name.mustAlwaysBeEscaped()) { | ||
SmallString<16> buffer; | ||
Builder.addBaseName(Builder.escapeKeyword(Name.str(), true, buffer)); |
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.
Ditto
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.
Done.
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.
Could you use swift-ide-test
in test/IDE
for testing these? Our primary place for testing code completion results is test/IDE/complete_*.swift
.
test/SourceKit/CodeComplete
is for SourceKit specific functionalities, like response format, ordering or such.
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.
Moved the tests to test/IDE
and updated them to use %batch-code-completion
.
Raw identifiers are backtick-delimited identifiers that can contain any non-identifier character other than the backtick itself, CR, LF, or other non-printable ASCII code units, and which are also not composed entirely of operator characters.
This requires no additional work beyond just parsing the identifier because Clang module maps already support such names in quotes.
The original module names themselves must still be valid unescaped identifiers; most of the serialization logic in the compiler depends on the name of a module matching its name on the file system, and it would be very complex to turn escaped identifiers into file-safe names.
… JSON file. For build systems that already generate these files, it makes sense to include the aliases so that the map file serves as a comprehensive index of how the module inputs are referenced.
`#fileID` never accounted for the possibility that someone one have a module alias _itself_, so it always generated the module's real (physical) name. This _technically_ changes the behavior of `#fileID` for self-aliased modules, but since nobody would have ever had a reason to do that before raw identifiers, it's unlikely that this change would affect anyone in practice.
If a decl is exported to Objective-C (explicitly or implicitly), it must be given an explicit name that is a valid Objective-C identifier.
Imported C++ template specializations receive identifiers that contain their type signature; e.g., `X<Y, Z>`. Since this means the identifier contains non-identifier characters, the new behavior was trying to escape them with backticks in ASTPrinter, ASTMangler, and the runtime metadata. This pulls that back to preserve the current behavior for specifically those types.
This lets clients test `#if hasFeature(RawIdentifiers)` to determine compiler support.
82eb01b
to
c25931e
Compare
Implementation of SE-0451.