mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[SR-4231] Add diagnostic (& fix-it) for mixed syntax availability attribute (#9122)
* [Parse] Add diagnostic for mixed syntax availability attribute When parsing a list of availablity specifications in the shorthand syntax, check to see that the next specification is also in shorthand syntax. If the next specification looks like an explicit “deprecated” (or similad) attribute, then emit a specific diagnostic about it to help the developer understand the problem. https://bugs.swift.org/browse/SR-4231 * [Parse] Add fix-it for single mixed availability syntax For the scenario that’s described in SR-4231, when there is one shorthard syntax followed by ‘deprecated’ (or similar), then we can guess that the intention was to treat the shorthand as ‘introduced’ so that the two of them work together. This guess is only made if there is one platform version constrain, that is followed by ‘deprecated’, ‘renamed’, etc. but not ‘introduced’. https://bugs.swift.org/browse/SR-4231 * Automatic formatting using git-clang-format * Fix typos in test code and language in comment Also, consistently names test functions as “deprecated” and "introduced" * [Parse] Add note to explain the mixed availability syntax fix-it insertion This change also moves the fix-it from the error to the note.
This commit is contained in:
committed by
Robert Widmann
parent
21d040b863
commit
f45196d022
@@ -1103,7 +1103,54 @@ Parser::parseAvailabilitySpecList(SmallVectorImpl<AvailabilitySpec *> &Specs) {
|
||||
consumeToken();
|
||||
Status.setIsParseError();
|
||||
} else if (consumeIf(tok::comma)) {
|
||||
// keep going.
|
||||
// There is more to parse in this list.
|
||||
|
||||
// Before continuing to parse the next specification, we check that it's
|
||||
// also in the shorthand syntax and provide a more specific diagnostic if
|
||||
// that's not the case.
|
||||
if (Tok.isIdentifierOrUnderscore() &&
|
||||
!peekToken().isAny(tok::integer_literal, tok::floating_literal)) {
|
||||
auto Text = Tok.getText();
|
||||
if (Text == "deprecated" || Text == "renamed" || Text == "introduced" ||
|
||||
Text == "message" || Text == "obsoleted" || Text == "unavailable") {
|
||||
auto *Previous = Specs.back();
|
||||
auto &SourceManager = Context.SourceMgr;
|
||||
auto PreviousSpecText =
|
||||
SourceManager.extractText(L->getCharSourceRangeFromSourceRange(
|
||||
SourceManager, Previous->getSourceRange()));
|
||||
|
||||
diagnose(Tok,
|
||||
diag::avail_query_argument_and_shorthand_mix_not_allowed,
|
||||
Text, PreviousSpecText);
|
||||
|
||||
// If this was preceded by a single platform version constraint, we
|
||||
// can guess that the intention was to treat it as 'introduced' and
|
||||
// suggest a fix-it to combine them.
|
||||
if (Specs.size() == 1 &&
|
||||
PlatformVersionConstraintAvailabilitySpec::classof(Previous) &&
|
||||
Text != "introduced") {
|
||||
auto *PlatformSpec =
|
||||
cast<PlatformVersionConstraintAvailabilitySpec>(Previous);
|
||||
|
||||
auto PlatformName = platformString(PlatformSpec->getPlatform());
|
||||
auto PlatformNameEndLoc =
|
||||
PlatformSpec->getPlatformLoc().getAdvancedLoc(
|
||||
PlatformName.size());
|
||||
|
||||
StringRef VersionName = PlatformSpec->getVersion().getAsString();
|
||||
|
||||
diagnose(PlatformSpec->getPlatformLoc(),
|
||||
diag::avail_query_meant_introduced, PlatformName,
|
||||
VersionName)
|
||||
.fixItInsert(PlatformNameEndLoc, ", introduced:");
|
||||
}
|
||||
|
||||
Status.setIsParseError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, keep going.
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user