mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Exclude private decls from interface token hash.
After parsing a private decl, reset the token hash state to what it was before the decl was parsed. This way, adding a private decl or editing its type or name will not trigger a rebuild of downstream files. <rdar://problem/22239821> Modifying private APIs shouldn't cause dependents to recompile Swift SVN r31358
This commit is contained in:
@@ -1083,6 +1083,9 @@ public:
|
||||
InterfaceHash.update(a);
|
||||
}
|
||||
|
||||
const llvm::MD5 &getInterfaceHashState() { return InterfaceHash; }
|
||||
void setInterfaceHashState(const llvm::MD5 &state) { InterfaceHash = state; }
|
||||
|
||||
void getInterfaceHash(llvm::SmallString<32> &str) {
|
||||
llvm::MD5::MD5Result result;
|
||||
InterfaceHash.final(result);
|
||||
|
||||
@@ -174,6 +174,36 @@ namespace {
|
||||
P.markWasHandled(D);
|
||||
}
|
||||
};
|
||||
|
||||
/// An RAII type to exclude tokens contributing to private decls from the
|
||||
/// interface hash of the source file. On destruct, it checks if the set of
|
||||
/// attributes includes the "private" attribute; if so, it resets the MD5
|
||||
/// hash of the source file to what it was when the IgnorePrivateDeclTokens
|
||||
/// instance was created, thus excluding from the interface hash all tokens
|
||||
/// parsed in the meantime.
|
||||
struct IgnorePrivateDeclTokens {
|
||||
Parser &TheParser;
|
||||
DeclAttributes &Attributes;
|
||||
Optional<llvm::MD5> SavedHashState;
|
||||
|
||||
IgnorePrivateDeclTokens(Parser &P, DeclAttributes &Attrs)
|
||||
: TheParser(P), Attributes(Attrs) {
|
||||
if (TheParser.IsParsingInterfaceTokens) {
|
||||
SavedHashState = TheParser.SF.getInterfaceHashState();
|
||||
}
|
||||
}
|
||||
|
||||
~IgnorePrivateDeclTokens() {
|
||||
if (!SavedHashState)
|
||||
return;
|
||||
|
||||
if (auto *attr = Attributes.getAttribute<AbstractAccessibilityAttr>()) {
|
||||
if (attr->getAccess() == Accessibility::Private) {
|
||||
TheParser.SF.setInterfaceHashState(*SavedHashState);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// \brief Main entrypoint for the parser.
|
||||
@@ -1711,6 +1741,7 @@ void Parser::delayParseFromBeginningToHere(ParserPosition BeginParserPosition,
|
||||
BeginParserPosition.PreviousLoc);
|
||||
skipUntil(tok::eof);
|
||||
}
|
||||
|
||||
/// \brief Parse a single syntactic declaration and return a list of decl
|
||||
/// ASTs. This can return multiple results for var decls that bind to multiple
|
||||
/// values, structs that define a struct decl and a constructor, etc.
|
||||
@@ -1742,6 +1773,7 @@ ParserStatus Parser::parseDecl(SmallVectorImpl<Decl*> &Entries,
|
||||
StructureMarkerKind::Declaration);
|
||||
|
||||
DeclAttributes Attributes;
|
||||
IgnorePrivateDeclTokens IgnoreTokens(*this, Attributes);
|
||||
if (Tok.hasComment())
|
||||
Attributes.add(new (Context) RawDocCommentAttr(Tok.getCommentRange()));
|
||||
bool FoundCCTokenInAttr;
|
||||
|
||||
23
test/InterfaceHash/added_private_method.swift
Normal file
23
test/InterfaceHash/added_private_method.swift
Normal file
@@ -0,0 +1,23 @@
|
||||
// RUN: mkdir -p %t
|
||||
// RUN: %S/../../utils/split_file.py -o %t %s
|
||||
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
|
||||
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
|
||||
// RUN: cmp %t/a.hash %t/b.hash
|
||||
|
||||
// BEGIN a.swift
|
||||
class C {
|
||||
func f2() -> Int {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
// BEGIN b.swift
|
||||
class C {
|
||||
func f2() -> Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
private func f3() -> Int {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
11
test/InterfaceHash/changed_private_var_type.swift
Normal file
11
test/InterfaceHash/changed_private_var_type.swift
Normal file
@@ -0,0 +1,11 @@
|
||||
// RUN: mkdir -p %t
|
||||
// RUN: %S/../../utils/split_file.py -o %t %s
|
||||
// RUN: %target-swift-frontend -dump-interface-hash %t/a.swift 2> %t/a.hash
|
||||
// RUN: %target-swift-frontend -dump-interface-hash %t/b.swift 2> %t/b.hash
|
||||
// RUN: cmp %t/a.hash %t/b.hash
|
||||
|
||||
// BEGIN a.swift
|
||||
private var x: Int
|
||||
|
||||
// BEGIN b.swift
|
||||
private var x: Float
|
||||
Reference in New Issue
Block a user