Skip to content

Commit 2b85835

Browse files
authored
Merge pull request #29664 from hamishknight/inout-decls
Create a new module and SourceFile for REPL completion
2 parents 02a676b + 9208f5b commit 2b85835

15 files changed

+69
-69
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,17 +1959,15 @@ class DynamicallyReplacedDeclRequest
19591959

19601960
class TypeCheckSourceFileRequest :
19611961
public SimpleRequest<TypeCheckSourceFileRequest,
1962-
bool (SourceFile *, unsigned),
1963-
CacheKind::SeparatelyCached> {
1962+
bool (SourceFile *), CacheKind::SeparatelyCached> {
19641963
public:
19651964
using SimpleRequest::SimpleRequest;
19661965

19671966
private:
19681967
friend SimpleRequest;
19691968

19701969
// Evaluation.
1971-
llvm::Expected<bool> evaluate(Evaluator &evaluator,
1972-
SourceFile *SF, unsigned StartElem) const;
1970+
llvm::Expected<bool> evaluate(Evaluator &evaluator, SourceFile *SF) const;
19731971

19741972
public:
19751973
// Separate caching.

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ SWIFT_REQUEST(TypeChecker, HasDefaultInitRequest,
211211
SWIFT_REQUEST(TypeChecker, SynthesizeDefaultInitRequest,
212212
ConstructorDecl *(NominalTypeDecl *), Cached, NoLocationInfo)
213213
SWIFT_REQUEST(TypeChecker, TypeCheckSourceFileRequest,
214-
bool(SouceFile *, unsigned), SeparatelyCached, NoLocationInfo)
214+
bool(SouceFile *), SeparatelyCached, NoLocationInfo)
215215
SWIFT_REQUEST(TypeChecker, TypeWitnessRequest,
216216
TypeWitnessAndDecl(NormalProtocolConformance *,
217217
AssociatedTypeDecl *),

include/swift/Frontend/Frontend.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,6 @@ class CompilerInstance {
653653
};
654654

655655
private:
656-
void createREPLFile(const ImplicitImports &implicitImports);
657-
658656
void addMainFileToModule(const ImplicitImports &implicitImports);
659657

660658
void performSemaUpTo(SourceFile::ASTStage_t LimitStage);

include/swift/Subsystems.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,7 @@ namespace swift {
137137

138138
/// Once parsing is complete, this walks the AST to resolve imports, record
139139
/// operators, and do other top-level validation.
140-
///
141-
/// \param StartElem Where to start for incremental name binding in the main
142-
/// source file.
143-
void performNameBinding(SourceFile &SF, unsigned StartElem = 0);
140+
void performNameBinding(SourceFile &SF);
144141

145142
/// Once type-checking is complete, this instruments code with calls to an
146143
/// intrinsic that record the expected values of local variables so they can
@@ -171,10 +168,7 @@ namespace swift {
171168

172169
/// Once parsing and name-binding are complete, this walks the AST to resolve
173170
/// types and diagnose problems therein.
174-
///
175-
/// \param StartElem Where to start for incremental type-checking in the main
176-
/// source file.
177-
void performTypeChecking(SourceFile &SF, unsigned StartElem = 0);
171+
void performTypeChecking(SourceFile &SF);
178172

179173
/// Now that we have type-checked an entire module, perform any type
180174
/// checking that requires the full module, e.g., Objective-C method

lib/Frontend/Frontend.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,15 @@ void CompilerInstance::performSemaUpTo(SourceFile::ASTStage_t LimitStage) {
727727
const ImplicitImports implicitImports(*this);
728728

729729
if (Invocation.getInputKind() == InputFileKind::SwiftREPL) {
730-
createREPLFile(implicitImports);
730+
// Create the initial empty REPL file. This only exists to feed in the
731+
// implicit imports such as the standard library.
732+
auto *replFile = createSourceFileForMainModule(
733+
SourceFileKind::REPL, implicitImports.kind, /*BufferID*/ None);
734+
addAdditionalInitialImportsTo(replFile, implicitImports);
735+
736+
// Given this file is empty, we can go ahead and just mark it as having been
737+
// type checked.
738+
replFile->ASTStage = SourceFile::TypeChecked;
731739
return;
732740
}
733741

@@ -824,12 +832,6 @@ void CompilerInstance::getImplicitlyImportedModules(
824832
}
825833
}
826834

827-
void CompilerInstance::createREPLFile(const ImplicitImports &implicitImports) {
828-
auto *SingleInputFile = createSourceFileForMainModule(
829-
Invocation.getSourceFileKind(), implicitImports.kind, None);
830-
addAdditionalInitialImportsTo(SingleInputFile, implicitImports);
831-
}
832-
833835
void CompilerInstance::addMainFileToModule(
834836
const ImplicitImports &implicitImports) {
835837
auto *MainFile = createSourceFileForMainModule(

lib/IDE/REPLCodeCompletion.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -204,19 +204,40 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID,
204204

205205
Ctx.SourceMgr.setCodeCompletionPoint(*BufferID, CodeCompletionOffset);
206206

207-
// Parse, typecheck and temporarily insert the incomplete code into the AST.
208-
const unsigned OriginalDeclCount = SF.getTopLevelDecls().size();
207+
// Create a new module and file for the code completion buffer, similar to how
208+
// we handle new lines of REPL input.
209+
auto *newModule =
210+
ModuleDecl::create(Ctx.getIdentifier("REPL_Code_Completion"), Ctx);
211+
auto &newSF =
212+
*new (Ctx) SourceFile(*newModule, SourceFileKind::REPL, *BufferID,
213+
SourceFile::ImplicitModuleImportKind::None);
214+
newModule->addFile(newSF);
215+
216+
// Import the last module.
217+
auto *lastModule = SF.getParentModule();
218+
ModuleDecl::ImportedModule importOfLastModule{/*AccessPath*/ {}, lastModule};
219+
newSF.addImports(SourceFile::ImportedModuleDesc(importOfLastModule,
220+
SourceFile::ImportOptions()));
221+
222+
// Carry over the private imports from the last module.
223+
SmallVector<ModuleDecl::ImportedModule, 8> imports;
224+
lastModule->getImportedModules(imports,
225+
ModuleDecl::ImportFilterKind::Private);
226+
if (!imports.empty()) {
227+
SmallVector<SourceFile::ImportedModuleDesc, 8> importsWithOptions;
228+
for (auto &import : imports) {
229+
importsWithOptions.emplace_back(
230+
SourceFile::ImportedModuleDesc(import, SourceFile::ImportOptions()));
231+
}
232+
newSF.addImports(importsWithOptions);
233+
}
209234

210235
PersistentParserState PersistentState;
211-
parseIntoSourceFile(SF, *BufferID, &PersistentState);
212-
performTypeChecking(SF, OriginalDeclCount);
236+
parseIntoSourceFile(newSF, *BufferID, &PersistentState);
237+
performTypeChecking(newSF);
213238

214239
performCodeCompletionSecondPass(PersistentState, *CompletionCallbacksFactory);
215240

216-
// Now we are done with code completion. Remove the declarations we
217-
// temporarily inserted.
218-
SF.truncateTopLevelDecls(OriginalDeclCount);
219-
220241
// Reset the error state because it's only relevant to the code that we just
221242
// processed, which now gets thrown away.
222243
Ctx.Diags.resetHadAnyError();

lib/Immediate/REPL.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -997,10 +997,6 @@ class REPLEnvironment {
997997
IRGenOpts.DebugInfoLevel = IRGenDebugInfoLevel::None;
998998
IRGenOpts.DebugInfoFormat = IRGenDebugInfoFormat::None;
999999

1000-
// The very first module is a dummy.
1001-
CI.getMainModule()->getMainSourceFile(SourceFileKind::REPL).ASTStage =
1002-
SourceFile::TypeChecked;
1003-
10041000
if (!ParseStdlib) {
10051001
// Force standard library to be loaded immediately. This forces any
10061002
// errors to appear upfront, and helps eliminate some nasty lag after the

lib/Sema/NameBinding.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ static void insertPrecedenceGroupDecl(NameBinder &binder, SourceFile &SF,
397397
/// UnresolvedDeclRefExpr nodes for unresolved value names, and we may have
398398
/// unresolved type names as well. This handles import directives and forward
399399
/// references.
400-
void swift::performNameBinding(SourceFile &SF, unsigned StartElem) {
400+
void swift::performNameBinding(SourceFile &SF) {
401401
FrontendStatsTracer tracer(SF.getASTContext().Stats, "Name binding");
402402

403403
// Make sure we skip adding the standard library imports if the
@@ -417,7 +417,7 @@ void swift::performNameBinding(SourceFile &SF, unsigned StartElem) {
417417

418418
// Do a prepass over the declarations to find and load the imported modules
419419
// and map operator decls.
420-
for (auto D : SF.getTopLevelDecls().slice(StartElem)) {
420+
for (auto D : SF.getTopLevelDecls()) {
421421
if (auto *ID = dyn_cast<ImportDecl>(D)) {
422422
Binder.addImport(ImportedModules, ID);
423423
} else if (auto *OD = dyn_cast<PrefixOperatorDecl>(D)) {

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -614,14 +614,8 @@ class TypeRefinementContextBuilder : private ASTWalker {
614614

615615
} // end anonymous namespace
616616

617-
void TypeChecker::buildTypeRefinementContextHierarchy(SourceFile &SF,
618-
unsigned StartElem) {
617+
void TypeChecker::buildTypeRefinementContextHierarchy(SourceFile &SF) {
619618
TypeRefinementContext *RootTRC = SF.getTypeRefinementContext();
620-
621-
// If we are not starting at the beginning of the source file, we had better
622-
// already have a root type refinement context.
623-
assert(StartElem == 0 || RootTRC);
624-
625619
ASTContext &Context = SF.getASTContext();
626620

627621
if (!RootTRC) {
@@ -636,7 +630,7 @@ void TypeChecker::buildTypeRefinementContextHierarchy(SourceFile &SF,
636630
// Build refinement contexts, if necessary, for all declarations starting
637631
// with StartElem.
638632
TypeRefinementContextBuilder Builder(RootTRC, Context);
639-
for (auto D : SF.getTopLevelDecls().slice(StartElem)) {
633+
for (auto D : SF.getTopLevelDecls()) {
640634
Builder.build(D);
641635
}
642636
}
@@ -645,7 +639,7 @@ TypeRefinementContext *
645639
TypeChecker::getOrBuildTypeRefinementContext(SourceFile *SF) {
646640
TypeRefinementContext *TRC = SF->getTypeRefinementContext();
647641
if (!TRC) {
648-
buildTypeRefinementContextHierarchy(*SF, 0);
642+
buildTypeRefinementContextHierarchy(*SF);
649643
TRC = SF->getTypeRefinementContext();
650644
}
651645

lib/Sema/TypeCheckREPL.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -462,17 +462,17 @@ Identifier REPLChecker::getNextResponseVariableName(DeclContext *DC) {
462462
/// processREPLTopLevel - This is called after we've parsed and typechecked some
463463
/// new decls at the top level. We inject code to print out expressions and
464464
/// pattern bindings the are evaluated.
465-
void TypeChecker::processREPLTopLevel(SourceFile &SF, unsigned FirstDecl) {
465+
void TypeChecker::processREPLTopLevel(SourceFile &SF) {
466466
// Walk over all decls in the file to find the next available closure
467467
// discriminator.
468468
DiscriminatorFinder DF;
469469
for (Decl *D : SF.getTopLevelDecls())
470470
D->walk(DF);
471471

472-
// Move new declarations out.
473-
std::vector<Decl *> NewDecls(SF.getTopLevelDecls().begin()+FirstDecl,
472+
// Move the new declarations out of the source file.
473+
std::vector<Decl *> NewDecls(SF.getTopLevelDecls().begin(),
474474
SF.getTopLevelDecls().end());
475-
SF.truncateTopLevelDecls(FirstDecl);
475+
SF.truncateTopLevelDecls(0);
476476

477477
REPLChecker RC(SF, DF);
478478

0 commit comments

Comments
 (0)