The diagnosticc engine is keeping track of state which might modify parsing/typechecking behaviour. In the added test case the `fatalErrorOccurred` flag was during the first completion. The flag was still `true` for the second completion, causing parsing/typechecking to behave slightly differently. Because of this, the ExprRewriter failed when applying a constraint system solution, not properly cleaning up its `ExprStack`.
This PR tackles both issues:
1) Reset the `hadError` flags in the diagnostics engine
2) Clean up the `ExprRewriter`’s `ExprStack` when rewriting a target fails.
Either of these changes fixes the crash in the test case but I think both could manifest through different code paths in different scenarios.
Fixes rdar://76051976 [SR-14430]
Introduce a new compiler flag `-module-abi-name <name>` that uses the
given name as the ABI name for the module (rather than the module's
name in source code). The ABI name impacts name mangling and metadata.
Take type body fingerprints into account for inteface hash checking.
Since `SourceFile.getInterfacehash()` doesn't digest the type body
fingerprints in the file, enabling type body fingerprints regressed
fast-completion.
rdar://problem/69890297
Also perform the plumbing necessary to convince the rest of the compiler that they're just ordinary external dependencies. In particular, we will still emit these depenencies into .d files, and code completion will still index them.
We need ClangImporterOptions to be persistent for several scenarios: (1)
when creating a sub-ASTContext to build Swift modules from interfaces; and
(2) when creating a new Clang instance to invoke Clang dependencies scanner.
This change is NFC.
This was not needed. The list of depenencies should not be changed
during fast-completion sessions.
This was also harmful because it calls stat(2) for all the dependency
files.
rdar://problem/67773257
* Re-create `ASTScope` for each completion
* Add generic params and where clause scope even without missing body
* Use `getOriginalBodySourceRange()` for `AbstractFunctionBodyScope`
* Source range translations for replaced ranges when finding scopes
* Bypass source range checks when the completion happens in the replaced
range
* Be lenient with ASTScope / DeclContext mismatch in code completion
Fast completion replaces the body ('BraceStmt') of function decls with
other bodies parsed from different source buffers from the original
source buffer. That means the source range of the body and the location
of the function declaration itself might be in different buffers.
Previously, FuncDecl::getSourceRange() used to use the 'func' keyword decl
as the start loc and 'getBodySourceRange().End' as the end loc. This
breaks a SourceRange invariant where the start and end loc must be
in the same buffer.
This patch add a new function 'getOriginalBodySourceRange()' which
always return the source range of the original body of the function. And
use that from 'getSourceRange()' functions.
The orignal body source range is stored in a side table in ASTContext so
that normal compilation doesn't consume space for that extra info.
'SM.getCodeCompletionBufferID()' returns the buffer ID of the previous
code completion. 'CI.getCodeCompletionFile()->getBufferID()' always
returns the original source buffer ID of the current file in the main
module. The latter is needed for excluding buffer ID for dependency checking.
rdar://problem/66301353
Expand the FrontendOptions to allow the enabling
of the dependency tracker for non-system
dependencies, and switch the previous clients of
`createDependencyTracker` over to using this
option. This ensures that the dependency tracker
is now set only during `CompilerInstance::setup`.
Sink the `BuildSyntaxTree` and
`CollectParsedTokens` bits into
`SourceFile::ParsingFlags`, with a static method
to get the parsing options from the lang opts.
Also add a parsing flag for enabling the interface
hash, which can be used instead of calling
`enableInterfaceHash`.
Rather than replacing the code completion file
on the `CompilerInstance` whenever we do a cached
top-level completion, let's set a new main module
instead.
This allows us to properly update the
`LoadedModules` map, and allows the retrieval of
the code completion file to be turned into a
request.
Rather than trying to continue the compilation
with an empty main module, let's bail out early if
we expect an implicit stdlib import and fail to
load in the stdlib.
There's no need to walk all imports of all source files, and bind the
extensions defined therein. The only time that a non-main module
contains source files is when using -enable-source-import, and we
can just explicitly call bindExtensions() in the right place.
Check if dependencies are modified since the last checking.
Dependencies:
- Other source files in the current module
- Dependent files collected by the dependency tracker
When:
- If the last dependency check was over N (defaults to 5) seconds ago
Invalidate if:
- The dependency file is missing
- The modification time of the dependecy is greater than the last check
- If the modification time is zero, compare the content using the file
system from the previous completion and the current completion
rdar://problem/62336432
Add ModuleImplicitImportsRequest, which computes
the modules that should be implicitly imported by
each file of a given module. Use this request in
import resolution to add all the necessary
implicit imports.
The request computes the implicit imports by
consulting the ImplicitImportInfo, which ModuleDecl
can now be created with. This allows us to remove
uses of `SourceFile::addImports` in favor of
adding modules needed to be implicitly imported to
the ImplicitImportInfo.
Move the global PersistentParserState from
the CompilerInstance to the source file that code
completion is operating on, only hooking up the
state when it's needed. This will help make it
easier to requestify source file parsing.
e.g. Playground.
A single file script is like a single function body; the interface of
the file does not affect any other files.
So when a completion happens in a single file script, re-parse the whole
file. But we are still be able to reuse imported modules.
rdar://problem/58378157
Instead of interleaving typechecking and parsing
for SIL files, first parse the file for Swift
decls by skipping over any intermixed SIL decls.
Then we can perform type checking, and finally SIL
parsing where we now skip over Swift decls.
This is an intermediate step to requestifying the
parsing of a source file for its Swift decls.
TypeChecker sometimes (e.g. property wrappers) inserts implicit decls
(e.g. 'PatternBindingDecl's and 'VarDecl's) between decls in the AST.
This used to confuse 'getEquivalentDeclContextFromSourceFile()'. It
canceled fast-completion, caused crashes, or completed in a wrong
context.
Ignore implicit decls in the AST so that we can find the correct decl
context.
rdar://problem/58665268
For example, if stdlib is not found, CompilerInstance simply returns
before creating PersistentParserState. In such cases, completion should
just return empty result.
Previously, it caused SourceKit crash.
rdar://problem/58663066
'getEquivalentDeclContextFromSourceFile()' didn't work for accessors
because DeclContext hierarchy and AST hierarhy are not the same.
AST hierarchy:
(TypeDecl or SourceFile) > AbstractStorageDecl > AccessorDecl
DeclContext hierarchy:
(TypeDecl or SourceFile) > AccessorDecl
Handle them specially.
rdar://problem/58632889