Replace `NameOfType foo = dyn_cast<NameOfType>(bar)` with DRY version `auto foo = dyn_cast<NameOfType>(bar)`.
The DRY auto version is by far the dominant form already used in the repo, so this PR merely brings the exceptional cases (redundant repetition form) in line with the dominant form (auto form).
See the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es11-use-auto-to-avoid-redundant-repetition-of-type-names) for a general discussion on why to use `auto` to avoid redundant repetition of type names.
* [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.
* Narrow allowance of 3+ components numeric literal to condition part of the
directive.
* Allow 3+ components in '#if' directive in decl list position as well.
This is a temporary stop-gap for getting round-trip parsing
off the ground. The real fix, not re-injecting declarations
into an if-config's declaration context, is a deep dive and
is still ongoing.
Add diagnostics to fix decls with consecutive identifiers. This applies to
types, properties, variables, and enum cases. The diagnostic adds a camel-cased option if it is different than the first option.
https://bugs.swift.org/browse/SR-3599
Parsing declaration list (e.g. member list of nominal decl) is very
different from comma separated list, because it's elements are separated with
new-line or semi-colon. There's no good reason to consolidate them.
Also, declaration list in 'extension' or inside of decl '#if' didn't
emit diagnostics for consecutive declarations on a line.
class C {
#if true
var value: Int = 42 func foo() {}
#endif
}
extension C {
func bar() {} subscript(i: Int) -> Int {
return 24
}
}
This change consolidates declaration list parsing for
members of nominal decls, extensions, and inside of '#if'.
In addition, removed unnecessary property 'TrailingSemiLoc' from decl.
This reverts the contents of #5778 and replaces it with a far simpler
implementation of condition resolution along with canImport. When
combined with the optimizations in #6279 we get the best of both worlds
with a performance win and a simpler implementation.
* Pack the bits for IfConfigDecls into Decl
* Don't open symbols into a module when evaluating canImport statements
The module loaders now have API to check whether a given module can be
imported without importing the referenced module. This provides a
significant speed boost to condition resolution and no longer
introduces symbols from the referenced module into the current context
without the user explicitly requesting it.
The definition of ‘canImport’ does not necessarily mean that a full
import without error is possible, merely that the path to the import is
visible to the compiler and the module is loadable in some form or
another.
Note that this means this check is insufficient to guarantee that you
are on one platform or another. For those kinds of checks, use
‘os(OSNAME)’.
Fixes SR-2757.
Variables in capture lists are treated as 'let' constants, which can
result in misleading, incorrect diagnostics. Mark them as such in order
to produce better diagnostics, by adding an extra parameter to the
VarDecl initializer.
Alternatively, these variables could be marked as implicit, but that
results in other diagnostic problems: capture list variables that are
never used produce warnings, but these warnings aren't normally emitted for
implicit variables. Other assertions in the compiler also misfire when
these variables are treated as implicit.
Another alternative would be to walk up the AST and determine whether
the `VarDecl`, but there doesn't appear to be a way to do so.
Being lazy here just means we don’t validate the entire if
configuration. We need to be able to emit diagnostics even in
condition clauses with indeterminate expressions.
Addresses SR-2605.
If you're refactoring a `guard` into an `if`, it's easy to
accidentally end up with invalid code like this in the transition:
```
if condition else {
}
```
The parser rightly complains about the `else`, but has poor recovery
afterward, interpreting the following brace as a closure, which may in
turn lead to other unhelpful errors after:
```
error: expected '{' after 'if' condition
if condition else {
^
error: braced block of statements is an unused closure
if condition else {
^
```
Improve the diagnostics to instead explicitly detect this pattern and
mark it as an error.
This completely removes Parse’s ability to make any judgement calls
about compilation conditions, instead the parser-relevant parts of
‘evaluateConditionalCompilationExpr’ have been moved into
‘classifyConditionalCompilationExpr’ where they exist to make sure only
decls that we want to parse actually parse later.
The condition-evaluation parts have been moved into NameBinding in the
form of a Walker that evaluates and collapses IfConfigs. This walker
is meant as an homage to PlaygroundLogger. It should probably be
factored out into a common walker at some point in the future.
Implemented in the naive way by way of the current ASTContext’s
‘LoadedModules’. In theory this list should be in one-to-one
correspondence with the definition of “importable” as any module that
is required for compilation is loaded *before* we start parsing the
file. This means we don’t have to load the module, just check that
it’s in the set of loaded modules.
Note that this approach will most likely fall apart if submodules are
introduced and are lazily loaded. At that point this will need to be
refactored into a format that defers the checking of conditions
sometime before or during typechecking (after namebinding).
parseBraceItems() has specific logic for pasing conditional compilation blocks.
Withoutout that, decralations in the block cannot be propagated to outside.
For instance:
FOO: #if true
func foo() {}
#endif
foo() // error: use of unresolved identifier 'foo'
The tentantive parse is used for diagnostic purposes but can cause code-completion to delay the same decl twice.
The range of CodeCompletionExpr was previously character range which invalidated invariants of the AST.
Fixes:
validation-test/IDE/crashers_fixed/084-swift-parser-consumedecl.swift
validation-test/IDE/crashers_fixed/104-swift-gettypeofcompletioncontextexpr.swift
For constructing the dummy expression for missing initializer,
use the end location of the pattern instead of the location of the
current token.
Previous behavior used to build AST like:
{ if let x [eof]
|---| Pattern range
|---| Dummy introducer range
|------------| IfStmt range
|--------| BraceStmt range
Now:
{ if let x [eof]
|---| Pattern range
| Dummy introducer range
|------| IfStmt range
|--------| BraceStmt range