Skip to content

Commit bb45b2a

Browse files
committed
[CodeCompletion] Lazily populate 'BasicSourceFileInfo'
1 parent 34223bc commit bb45b2a

File tree

6 files changed

+83
-41
lines changed

6 files changed

+83
-41
lines changed

include/swift/AST/RawComment.h

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,51 @@ struct BasicDeclLocs {
9696
LineColumn EndLoc;
9797
};
9898

99-
struct BasicSourceFileInfo {
99+
class BasicSourceFileInfo {
100+
/// If this is non-null, fields other than 'FilePath' hasn't been populated.
101+
/// The 'getInt()' part indicates this instance is constructed with a
102+
/// SourceFile.
103+
llvm::PointerIntPair<const SourceFile *, 1, bool> SFAndIsFromSF;
104+
100105
StringRef FilePath;
101-
Fingerprint InterfaceHash = Fingerprint::ZERO();
106+
Fingerprint InterfaceHashIncludingTypeMembers = Fingerprint::ZERO();
102107
llvm::sys::TimePoint<> LastModified = {};
103108
uint64_t FileSize = 0;
104109

105-
BasicSourceFileInfo() {}
110+
// Populate the from 'SF' member if exist. 'SF' will be cleared.
111+
void populateWithSourceFileIfNeeded();
112+
113+
public:
114+
BasicSourceFileInfo(StringRef FilePath,
115+
Fingerprint InterfaceHashIncludingTypeMembers,
116+
llvm::sys::TimePoint<> LastModified, uint64_t FileSize)
117+
: FilePath(FilePath),
118+
InterfaceHashIncludingTypeMembers(InterfaceHashIncludingTypeMembers),
119+
LastModified(LastModified), FileSize(FileSize) {}
120+
121+
/// Construct with a 'SourceFile'. 'getInterfaceHashIncludingTypeMembers()',
122+
/// 'getLastModified()' and 'getFileSize()' are laizily pupulated when
123+
/// accessed.
124+
BasicSourceFileInfo(const SourceFile *SF);
125+
126+
bool isFromSourceFile() const;
127+
128+
StringRef getFilePath() const { return FilePath; }
106129

107-
bool populate(const SourceFile *SF);
130+
Fingerprint getInterfaceHashIncludingTypeMembers() const {
131+
const_cast<BasicSourceFileInfo *>(this)->populateWithSourceFileIfNeeded();
132+
return InterfaceHashIncludingTypeMembers;
133+
}
134+
135+
llvm::sys::TimePoint<> getLastModified() const {
136+
const_cast<BasicSourceFileInfo *>(this)->populateWithSourceFileIfNeeded();
137+
return LastModified;
138+
}
139+
140+
uint64_t getFileSize() const {
141+
const_cast<BasicSourceFileInfo *>(this)->populateWithSourceFileIfNeeded();
142+
return FileSize;
143+
}
108144
};
109145

110146
} // namespace swift

lib/AST/Module.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,10 +1539,7 @@ void ModuleDecl::collectBasicSourceFileInfo(
15391539
llvm::function_ref<void(const BasicSourceFileInfo &)> callback) const {
15401540
for (const FileUnit *fileUnit : getFiles()) {
15411541
if (const auto *SF = dyn_cast<SourceFile>(fileUnit)) {
1542-
BasicSourceFileInfo info;
1543-
if (info.populate(SF))
1544-
continue;
1545-
callback(info);
1542+
callback(BasicSourceFileInfo(SF));
15461543
} else if (auto *serialized = dyn_cast<LoadedFile>(fileUnit)) {
15471544
serialized->collectBasicSourceFileInfo(callback);
15481545
}
@@ -1553,7 +1550,7 @@ Fingerprint ModuleDecl::getFingerprint() const {
15531550
StableHasher hasher = StableHasher::defaultHasher();
15541551
SmallVector<Fingerprint, 16> FPs;
15551552
collectBasicSourceFileInfo([&](const BasicSourceFileInfo &bsfi) {
1556-
FPs.emplace_back(bsfi.InterfaceHash);
1553+
FPs.emplace_back(bsfi.getInterfaceHashIncludingTypeMembers());
15571554
});
15581555

15591556
// Sort the fingerprints lexicographically so we have a stable hash despite

lib/AST/RawComment.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/PrettyStackTrace.h"
2525
#include "swift/AST/SourceFile.h"
2626
#include "swift/AST/Types.h"
27+
#include "swift/Basic/Defer.h"
2728
#include "swift/Basic/PrimitiveParsing.h"
2829
#include "swift/Basic/SourceManager.h"
2930
#include "swift/Markup/Markup.h"
@@ -247,26 +248,40 @@ CharSourceRange RawComment::getCharSourceRange() {
247248
return CharSourceRange(Start, Length);
248249
}
249250

250-
bool BasicSourceFileInfo::populate(const SourceFile *SF) {
251+
BasicSourceFileInfo::BasicSourceFileInfo(const SourceFile *SF)
252+
: SFAndIsFromSF(SF, true) {
253+
FilePath = SF->getFilename();
254+
}
255+
256+
bool BasicSourceFileInfo::isFromSourceFile() const {
257+
return SFAndIsFromSF.getInt();
258+
}
259+
260+
void BasicSourceFileInfo::populateWithSourceFileIfNeeded() {
261+
const auto *SF = SFAndIsFromSF.getPointer();
262+
if (!SF)
263+
return;
264+
SWIFT_DEFER {
265+
SFAndIsFromSF.setPointer(nullptr);
266+
};
267+
251268
SourceManager &SM = SF->getASTContext().SourceMgr;
252269

253-
auto filename = SF->getFilename();
254-
if (filename.empty())
255-
return true;
256-
auto stat = SM.getFileSystem()->status(filename);
270+
if (FilePath.empty())
271+
return;
272+
auto stat = SM.getFileSystem()->status(FilePath);
257273
if (!stat)
258-
return true;
274+
return;
259275

260-
FilePath = filename;
261276
LastModified = stat->getLastModificationTime();
262277
FileSize = stat->getSize();
263278

264279
if (SF->hasInterfaceHash()) {
265-
InterfaceHash = SF->getInterfaceHashIncludingTypeMembers();
280+
InterfaceHashIncludingTypeMembers = SF->getInterfaceHashIncludingTypeMembers();
266281
} else {
267282
// FIXME: Parse the file with EnableInterfaceHash option.
268-
InterfaceHash = Fingerprint::ZERO();
283+
InterfaceHashIncludingTypeMembers = Fingerprint::ZERO();
269284
}
270285

271-
return false;
286+
return;
272287
}

lib/Serialization/ModuleFile.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -992,18 +992,13 @@ void ModuleFile::collectBasicSourceFileInfo(
992992
size_t terminatorOffset = filePath.find('\0');
993993
filePath = filePath.slice(0, terminatorOffset);
994994

995-
BasicSourceFileInfo info;
996-
info.FilePath = filePath;
997-
if (auto fingerprint = Fingerprint::fromString(fpStr))
998-
info.InterfaceHash = fingerprint.getValue();
999-
else {
995+
auto fingerprint = Fingerprint::fromString(fpStr);
996+
if (!fingerprint) {
1000997
llvm::errs() << "Unconvertable fingerprint '" << fpStr << "'\n";
1001998
abort();
1002999
}
1003-
info.LastModified =
1004-
llvm::sys::TimePoint<>(std::chrono::nanoseconds(timestamp));
1005-
info.FileSize = fileSize;
1006-
callback(info);
1000+
1001+
callback(BasicSourceFileInfo(filePath, fingerprint.getValue(), llvm::sys::TimePoint<>(std::chrono::nanoseconds(timestamp)), fileSize));
10071002
}
10081003
}
10091004

lib/Serialization/SerializeDoc.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -794,18 +794,20 @@ static void emitFileListRecord(llvm::BitstreamWriter &Out,
794794
llvm::StringSet<> seenFilenames;
795795

796796
void emitSourceFileInfo(const BasicSourceFileInfo &info) {
797+
if (info.getFilePath().empty())
798+
return;
797799
// Make 'FilePath' absolute for serialization;
798-
SmallString<128> absolutePath = info.FilePath;
800+
SmallString<128> absolutePath = info.getFilePath();
799801
llvm::sys::fs::make_absolute(absolutePath);
800802

801803
// Don't emit duplicated files.
802-
if (!seenFilenames.insert(info.FilePath).second)
804+
if (!seenFilenames.insert(absolutePath).second)
803805
return;
804806

805807
auto fileID = FWriter.getTextOffset(absolutePath);
806-
auto fingerprintStr = info.InterfaceHash.getRawValue();
808+
auto fingerprintStr = info.getInterfaceHashIncludingTypeMembers().getRawValue();
807809
auto timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(
808-
info.LastModified.time_since_epoch())
810+
info.getLastModified().time_since_epoch())
809811
.count();
810812

811813
llvm::raw_svector_ostream out(Buffer);
@@ -818,7 +820,7 @@ static void emitFileListRecord(llvm::BitstreamWriter &Out,
818820
// LastModified (nanoseconds since epoch).
819821
writer.write<uint64_t>(timestamp);
820822
// FileSize (num of bytes).
821-
writer.write<uint64_t>(info.FileSize);
823+
writer.write<uint64_t>(info.getFileSize());
822824
}
823825

824826
SourceFileListWriter(StringWriter &FWriter) : FWriter(FWriter) {
@@ -827,10 +829,7 @@ static void emitFileListRecord(llvm::BitstreamWriter &Out,
827829
} writer(FWriter);
828830

829831
if (SourceFile *SF = MSF.dyn_cast<SourceFile *>()) {
830-
BasicSourceFileInfo info;
831-
if (info.populate(SF))
832-
return;
833-
writer.emitSourceFileInfo(info);
832+
writer.emitSourceFileInfo(BasicSourceFileInfo(SF));
834833
} else {
835834
auto *M = MSF.get<ModuleDecl *>();
836835
M->collectBasicSourceFileInfo([&](const BasicSourceFileInfo &info) {

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2517,10 +2517,10 @@ static void printModuleMetadata(ModuleDecl *MD) {
25172517
<< ", force load: " << (lib.shouldForceLoad() ? "true" : "false") << "\n";
25182518
});
25192519
MD->collectBasicSourceFileInfo([&](const BasicSourceFileInfo &info) {
2520-
OS << "filepath=" << info.FilePath << "; ";
2521-
OS << "hash=" << info.InterfaceHash.getRawValue() << "; ";
2522-
OS << "mtime=" << info.LastModified << "; ";
2523-
OS << "size=" << info.FileSize;
2520+
OS << "filepath=" << info.getFilePath() << "; ";
2521+
OS << "hash=" << info.getInterfaceHashIncludingTypeMembers().getRawValue() << "; ";
2522+
OS << "mtime=" << info.getLastModified() << "; ";
2523+
OS << "size=" << info.getFileSize();
25242524
OS << "\n";
25252525
});
25262526
}

0 commit comments

Comments
 (0)