mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
ModulePrinting: Merge synthesized extensions' bodies if they have the common constraints.
This commit is contained in:
@@ -31,6 +31,7 @@ class Type;
|
|||||||
enum DeclAttrKind : unsigned;
|
enum DeclAttrKind : unsigned;
|
||||||
class PrinterArchetypeTransformer;
|
class PrinterArchetypeTransformer;
|
||||||
class SynthesizedExtensionAnalyzer;
|
class SynthesizedExtensionAnalyzer;
|
||||||
|
struct PrintOptions;
|
||||||
|
|
||||||
/// Necessary information for archetype transformation during printing.
|
/// Necessary information for archetype transformation during printing.
|
||||||
struct ArchetypeTransformContext {
|
struct ArchetypeTransformContext {
|
||||||
@@ -47,29 +48,30 @@ struct ArchetypeTransformContext {
|
|||||||
SynthesizedExtensionAnalyzer *Analyzer);
|
SynthesizedExtensionAnalyzer *Analyzer);
|
||||||
Type transform(Type Input);
|
Type transform(Type Input);
|
||||||
StringRef transform(StringRef Input);
|
StringRef transform(StringRef Input);
|
||||||
|
|
||||||
bool shouldPrintRequirement(ExtensionDecl *ED, StringRef Req);
|
bool shouldPrintRequirement(ExtensionDecl *ED, StringRef Req);
|
||||||
|
bool shouldOpenExtension;
|
||||||
|
bool shouldCloseExtension;
|
||||||
|
|
||||||
~ArchetypeTransformContext();
|
~ArchetypeTransformContext();
|
||||||
private:
|
private:
|
||||||
struct Implementation;
|
struct Implementation;
|
||||||
Implementation &Impl;
|
Implementation &Impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SynthesizedExtensionInfo {
|
|
||||||
ExtensionDecl *Ext = nullptr;
|
|
||||||
std::vector<StringRef> KnownSatisfiedRequirements;
|
|
||||||
operator bool() const { return Ext; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class SynthesizedExtensionAnalyzer {
|
class SynthesizedExtensionAnalyzer {
|
||||||
struct Implementation;
|
struct Implementation;
|
||||||
Implementation &Impl;
|
Implementation &Impl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SynthesizedExtensionAnalyzer(NominalTypeDecl *Target,
|
SynthesizedExtensionAnalyzer(NominalTypeDecl *Target,
|
||||||
|
PrintOptions Options,
|
||||||
bool IncludeUnconditional = true);
|
bool IncludeUnconditional = true);
|
||||||
~SynthesizedExtensionAnalyzer();
|
~SynthesizedExtensionAnalyzer();
|
||||||
void forEachSynthesizedExtension(
|
void forEachSynthesizedExtension(
|
||||||
llvm::function_ref<void(ExtensionDecl*)> Fn);
|
llvm::function_ref<void(ExtensionDecl*)> Fn);
|
||||||
|
void forEachSynthesizedExtensionMergeGroup(
|
||||||
|
llvm::function_ref<void(ArrayRef<ExtensionDecl*>)> Fn);
|
||||||
bool isInSynthesizedExtension(const ValueDecl *VD);
|
bool isInSynthesizedExtension(const ValueDecl *VD);
|
||||||
bool shouldPrintRequirement(ExtensionDecl *ED, StringRef Req);
|
bool shouldPrintRequirement(ExtensionDecl *ED, StringRef Req);
|
||||||
};
|
};
|
||||||
@@ -259,7 +261,7 @@ struct PrintOptions {
|
|||||||
/// \brief Print dependent types as references into this generic parameter
|
/// \brief Print dependent types as references into this generic parameter
|
||||||
/// list.
|
/// list.
|
||||||
GenericParamList *ContextGenericParams = nullptr;
|
GenericParamList *ContextGenericParams = nullptr;
|
||||||
|
|
||||||
/// \brief Print types with alternative names from their canonical names.
|
/// \brief Print types with alternative names from their canonical names.
|
||||||
llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr;
|
llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -98,14 +98,14 @@ public:
|
|||||||
return Ty.transform([&](Type Ty) -> Type {
|
return Ty.transform([&](Type Ty) -> Type {
|
||||||
if (Ty->getKind() != TypeKind::Archetype)
|
if (Ty->getKind() != TypeKind::Archetype)
|
||||||
return Ty;
|
return Ty;
|
||||||
|
|
||||||
// First, we try to find the map from cache.
|
// First, we try to find the map from cache.
|
||||||
if (Cache.count(Ty.getPointer()) > 0) {
|
if (Cache.count(Ty.getPointer()) > 0) {
|
||||||
return Cache[Ty.getPointer()];
|
return Cache[Ty.getPointer()];
|
||||||
}
|
}
|
||||||
auto Id = cast<ArchetypeType>(Ty.getPointer())->getName().str();
|
auto Id = cast<ArchetypeType>(Ty.getPointer())->getName().str();
|
||||||
auto Result = Ty;
|
auto Result = Ty;
|
||||||
|
|
||||||
// Iterate the IdMap to find the argument type of the given param name.
|
// Iterate the IdMap to find the argument type of the given param name.
|
||||||
for (auto It = IdMap->begin(); It != IdMap->end(); ++ It) {
|
for (auto It = IdMap->begin(); It != IdMap->end(); ++ It) {
|
||||||
if (Id == It->getFirst()) {
|
if (Id == It->getFirst()) {
|
||||||
@@ -113,7 +113,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put the result into cache.
|
// Put the result into cache.
|
||||||
Cache[Ty.getPointer()] = Result;
|
Cache[Ty.getPointer()] = Result;
|
||||||
return Result;
|
return Result;
|
||||||
@@ -206,20 +206,30 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SynthesizedExtensionAnalyzer::Implementation {
|
struct SynthesizedExtensionAnalyzer::Implementation {
|
||||||
|
struct SynthesizedExtensionInfo {
|
||||||
|
ExtensionDecl *Ext = nullptr;
|
||||||
|
std::vector<StringRef> KnownSatisfiedRequirements;
|
||||||
|
unsigned MergeGroup;
|
||||||
|
operator bool() const { return Ext; }
|
||||||
|
};
|
||||||
|
|
||||||
typedef llvm::MapVector<ExtensionDecl*, SynthesizedExtensionInfo> ExtMap;
|
typedef llvm::MapVector<ExtensionDecl*, SynthesizedExtensionInfo> ExtMap;
|
||||||
NominalTypeDecl *Target;
|
NominalTypeDecl *Target;
|
||||||
Type BaseType;
|
Type BaseType;
|
||||||
DeclContext *DC;
|
DeclContext *DC;
|
||||||
std::unique_ptr<ArchetypeSelfTransformer> pTransform;
|
std::unique_ptr<ArchetypeSelfTransformer> pTransform;
|
||||||
bool IncludeUnconditional;
|
bool IncludeUnconditional;
|
||||||
|
PrintOptions Options;
|
||||||
std::unique_ptr<ExtMap> Results;
|
std::unique_ptr<ExtMap> Results;
|
||||||
|
|
||||||
Implementation(NominalTypeDecl *Target, bool IncludeUnconditional):
|
Implementation(NominalTypeDecl *Target, bool IncludeUnconditional,
|
||||||
|
PrintOptions Options):
|
||||||
Target(Target),
|
Target(Target),
|
||||||
BaseType(Target->getDeclaredTypeInContext()),
|
BaseType(Target->getDeclaredTypeInContext()),
|
||||||
DC(Target),
|
DC(Target),
|
||||||
pTransform(new ArchetypeSelfTransformer(Target)),
|
pTransform(new ArchetypeSelfTransformer(Target)),
|
||||||
IncludeUnconditional(IncludeUnconditional),
|
IncludeUnconditional(IncludeUnconditional),
|
||||||
|
Options(Options),
|
||||||
Results(collectSynthesizedExtensionInfo()) {}
|
Results(collectSynthesizedExtensionInfo()) {}
|
||||||
|
|
||||||
Type checkElementType(StringRef Text) {
|
Type checkElementType(StringRef Text) {
|
||||||
@@ -284,12 +294,46 @@ struct SynthesizedExtensionAnalyzer::Implementation {
|
|||||||
return MType->getAs<AnyMetatypeType>()->getInstanceType();
|
return MType->getAs<AnyMetatypeType>()->getInstanceType();
|
||||||
}
|
}
|
||||||
|
|
||||||
SynthesizedExtensionInfo isApplicable(ExtensionDecl *Ext) {
|
struct ExtensionMergeInfo {
|
||||||
|
struct Requirement {
|
||||||
|
Type First;
|
||||||
|
Type Second;
|
||||||
|
RequirementReprKind Kind;
|
||||||
|
bool operator< (const Requirement& Rhs) const {
|
||||||
|
if (Kind != Rhs.Kind)
|
||||||
|
return Kind < Rhs.Kind;
|
||||||
|
else if (First.getPointer() != Rhs.First.getPointer())
|
||||||
|
return First.getPointer() < Rhs.First.getPointer();
|
||||||
|
else
|
||||||
|
return Second.getPointer() < Rhs.Second.getPointer();
|
||||||
|
}
|
||||||
|
bool operator== (const Requirement& Rhs) const {
|
||||||
|
return (!(*this < Rhs)) && (!(Rhs < *this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool HasDocComment;
|
||||||
|
std::set<Requirement> Requirements;
|
||||||
|
void addRequirement(Type First, Type Second, RequirementReprKind Kind) {
|
||||||
|
Requirements.insert({First, Second, Kind});
|
||||||
|
}
|
||||||
|
bool operator== (const ExtensionMergeInfo& Another) const {
|
||||||
|
// Trivially unmergable.
|
||||||
|
if (HasDocComment || Another.HasDocComment)
|
||||||
|
return false;
|
||||||
|
return Requirements == Another.Requirements;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::pair<SynthesizedExtensionInfo, std::unique_ptr<ExtensionMergeInfo>>
|
||||||
|
isApplicable(ExtensionDecl *Ext) {
|
||||||
SynthesizedExtensionInfo Result;
|
SynthesizedExtensionInfo Result;
|
||||||
|
std::unique_ptr<ExtensionMergeInfo> MergeInfo(new ExtensionMergeInfo());
|
||||||
|
MergeInfo->HasDocComment = false;
|
||||||
if (!Ext->isConstrainedExtension()) {
|
if (!Ext->isConstrainedExtension()) {
|
||||||
if (IncludeUnconditional)
|
if (IncludeUnconditional)
|
||||||
Result.Ext = Ext;
|
Result.Ext = Ext;
|
||||||
return Result;
|
return {Result, std::move(MergeInfo)};
|
||||||
}
|
}
|
||||||
assert(Ext->getGenericParams() && "No generic params.");
|
assert(Ext->getGenericParams() && "No generic params.");
|
||||||
for (auto Req : Ext->getGenericParams()->getRequirements()){
|
for (auto Req : Ext->getGenericParams()->getRequirements()){
|
||||||
@@ -308,30 +352,61 @@ struct SynthesizedExtensionAnalyzer::Implementation {
|
|||||||
if (First && Second) {
|
if (First && Second) {
|
||||||
First = First->getDesugaredType();
|
First = First->getDesugaredType();
|
||||||
Second = Second->getDesugaredType();
|
Second = Second->getDesugaredType();
|
||||||
|
auto Written = Req.getAsWrittenString();
|
||||||
switch (Kind) {
|
switch (Kind) {
|
||||||
case RequirementReprKind::TypeConstraint:
|
case RequirementReprKind::TypeConstraint:
|
||||||
if(!canPossiblyConvertTo(First, Second, *DC))
|
if(!canPossiblyConvertTo(First, Second, *DC))
|
||||||
return Result;
|
return {Result, std::move(MergeInfo)};
|
||||||
else if (isConvertibleTo(First, Second, *DC))
|
else if (isConvertibleTo(First, Second, *DC))
|
||||||
Result.KnownSatisfiedRequirements.push_back(Req.getAsWrittenString());
|
Result.KnownSatisfiedRequirements.push_back(Written);
|
||||||
|
else
|
||||||
|
MergeInfo->addRequirement(First, Second, Kind);
|
||||||
break;
|
break;
|
||||||
case RequirementReprKind::SameType:
|
case RequirementReprKind::SameType:
|
||||||
if (!canPossiblyEqual(First, Second, *DC))
|
if (!canPossiblyEqual(First, Second, *DC))
|
||||||
return Result;
|
return {Result, std::move(MergeInfo)};
|
||||||
else if (isEqual(First, Second, *DC))
|
else if (isEqual(First, Second, *DC))
|
||||||
Result.KnownSatisfiedRequirements.push_back(Req.getAsWrittenString());
|
Result.KnownSatisfiedRequirements.push_back(Written);
|
||||||
|
else
|
||||||
|
MergeInfo->addRequirement(First, Second, Kind);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Result.Ext = Ext;
|
Result.Ext = Ext;
|
||||||
return Result;
|
return {Result, std::move(MergeInfo)};
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef llvm::MapVector<ExtensionDecl*, std::unique_ptr<ExtensionMergeInfo>>
|
||||||
|
ExtensionMergeInfoMap;
|
||||||
|
|
||||||
|
typedef llvm::MapVector<ExtensionDecl*, unsigned> ExtensionMergeGroupMap;
|
||||||
|
|
||||||
|
void calculateMergeGroup(ExtensionMergeInfoMap &MergeInfoMap,
|
||||||
|
ExtensionMergeGroupMap &MergeGroupMap) {
|
||||||
|
std::vector<std::pair<ExtensionMergeInfo*, unsigned>> KnownGroups;
|
||||||
|
unsigned NewGroupNum = 0;
|
||||||
|
for (auto &Pair : MergeInfoMap) {
|
||||||
|
auto Key = Pair.first;
|
||||||
|
auto Found = std::find_if(KnownGroups.begin(), KnownGroups.end(),
|
||||||
|
[&](std::pair<ExtensionMergeInfo*, unsigned> LHS) {
|
||||||
|
return (*LHS.first) == (*Pair.second);
|
||||||
|
});
|
||||||
|
if (Found != KnownGroups.end()) {
|
||||||
|
MergeGroupMap[Key] = (*Found).second;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MergeGroupMap[Key] = NewGroupNum;
|
||||||
|
KnownGroups.push_back({Pair.second.get(), NewGroupNum});
|
||||||
|
NewGroupNum ++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ExtMap> collectSynthesizedExtensionInfo() {
|
std::unique_ptr<ExtMap> collectSynthesizedExtensionInfo() {
|
||||||
std::unique_ptr<ExtMap> pMap(new ExtMap());
|
std::unique_ptr<ExtMap> pMap(new ExtMap());
|
||||||
if (Target->getKind() == DeclKind::Protocol)
|
if (Target->getKind() == DeclKind::Protocol)
|
||||||
return pMap;
|
return pMap;
|
||||||
|
ExtensionMergeInfoMap MergeInfoMap;
|
||||||
std::vector<NominalTypeDecl*> Unhandled;
|
std::vector<NominalTypeDecl*> Unhandled;
|
||||||
auto addTypeLocNominal = [&](TypeLoc TL){
|
auto addTypeLocNominal = [&](TypeLoc TL){
|
||||||
if (TL.getType()) {
|
if (TL.getType()) {
|
||||||
@@ -347,21 +422,32 @@ struct SynthesizedExtensionAnalyzer::Implementation {
|
|||||||
NominalTypeDecl* Back = Unhandled.back();
|
NominalTypeDecl* Back = Unhandled.back();
|
||||||
Unhandled.pop_back();
|
Unhandled.pop_back();
|
||||||
for (ExtensionDecl *E : Back->getExtensions()) {
|
for (ExtensionDecl *E : Back->getExtensions()) {
|
||||||
if (auto Info = isApplicable(E))
|
if (!shouldPrint(E, Options))
|
||||||
(*pMap)[E] = Info;
|
continue;
|
||||||
|
auto Pair = isApplicable(E);
|
||||||
|
if (Pair.first) {
|
||||||
|
(*pMap)[E] = Pair.first;
|
||||||
|
MergeInfoMap[E] = std::move(Pair.second);
|
||||||
|
}
|
||||||
for (auto TL : Back->getInherited()) {
|
for (auto TL : Back->getInherited()) {
|
||||||
addTypeLocNominal(TL);
|
addTypeLocNominal(TL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ExtensionMergeGroupMap GroupMap;
|
||||||
|
calculateMergeGroup(MergeInfoMap, GroupMap);
|
||||||
|
for(auto It : *pMap) {
|
||||||
|
(*pMap)[It.first].MergeGroup = GroupMap[It.first];
|
||||||
|
}
|
||||||
return pMap;
|
return pMap;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SynthesizedExtensionAnalyzer::
|
SynthesizedExtensionAnalyzer::
|
||||||
SynthesizedExtensionAnalyzer(NominalTypeDecl *Target,
|
SynthesizedExtensionAnalyzer(NominalTypeDecl *Target,
|
||||||
|
PrintOptions Options,
|
||||||
bool IncludeUnconditional):
|
bool IncludeUnconditional):
|
||||||
Impl(*(new Implementation(Target, IncludeUnconditional))) {}
|
Impl(*(new Implementation(Target, IncludeUnconditional, Options))) {}
|
||||||
|
|
||||||
SynthesizedExtensionAnalyzer::~SynthesizedExtensionAnalyzer() {delete &Impl;}
|
SynthesizedExtensionAnalyzer::~SynthesizedExtensionAnalyzer() {delete &Impl;}
|
||||||
|
|
||||||
@@ -381,6 +467,21 @@ forEachSynthesizedExtension(llvm::function_ref<void(ExtensionDecl*)> Fn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SynthesizedExtensionAnalyzer::
|
||||||
|
forEachSynthesizedExtensionMergeGroup(
|
||||||
|
llvm::function_ref<void(ArrayRef<ExtensionDecl*>)> Fn) {
|
||||||
|
llvm::DenseMap<unsigned, std::vector<ExtensionDecl*>> GroupBags;
|
||||||
|
for (auto It : *Impl.Results) {
|
||||||
|
unsigned Group = It.second.MergeGroup;
|
||||||
|
if (GroupBags.find(Group) == GroupBags.end())
|
||||||
|
GroupBags[Group] = std::vector<ExtensionDecl*>();
|
||||||
|
GroupBags[Group].push_back(It.first);
|
||||||
|
}
|
||||||
|
for (auto It : GroupBags) {
|
||||||
|
Fn(llvm::makeArrayRef(It.second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SynthesizedExtensionAnalyzer::
|
bool SynthesizedExtensionAnalyzer::
|
||||||
shouldPrintRequirement(ExtensionDecl *ED, StringRef Req) {
|
shouldPrintRequirement(ExtensionDecl *ED, StringRef Req) {
|
||||||
auto Found = Impl.Results->find(ED);
|
auto Found = Impl.Results->find(ED);
|
||||||
@@ -547,7 +648,7 @@ void ASTPrinter::printIndent() {
|
|||||||
llvm::SmallString<16> Str;
|
llvm::SmallString<16> Str;
|
||||||
for (unsigned i = 0; i != CurrentIndentation; ++i)
|
for (unsigned i = 0; i != CurrentIndentation; ++i)
|
||||||
Str += ' ';
|
Str += ' ';
|
||||||
|
|
||||||
printText(Str);
|
printText(Str);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -865,8 +966,10 @@ private:
|
|||||||
bool shouldPrintPattern(const Pattern *P);
|
bool shouldPrintPattern(const Pattern *P);
|
||||||
void printPatternType(const Pattern *P);
|
void printPatternType(const Pattern *P);
|
||||||
void printAccessors(AbstractStorageDecl *ASD);
|
void printAccessors(AbstractStorageDecl *ASD);
|
||||||
void printMembersOfDecl(Decl * NTD, bool needComma = false);
|
void printMembersOfDecl(Decl * NTD, bool needComma = false,
|
||||||
void printMembers(ArrayRef<Decl *> members, bool needComma = false);
|
bool openBracket = true, bool closeBracket = true);
|
||||||
|
void printMembers(ArrayRef<Decl *> members, bool needComma = false,
|
||||||
|
bool openBracket = true, bool closeBracket = true);
|
||||||
void printNominalDeclGenericParams(NominalTypeDecl *decl);
|
void printNominalDeclGenericParams(NominalTypeDecl *decl);
|
||||||
void printInherited(const Decl *decl,
|
void printInherited(const Decl *decl,
|
||||||
ArrayRef<TypeLoc> inherited,
|
ArrayRef<TypeLoc> inherited,
|
||||||
@@ -1020,7 +1123,7 @@ void PrintAST::printPattern(const Pattern *pattern) {
|
|||||||
const auto &Elt = Fields[i];
|
const auto &Elt = Fields[i];
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
Printer << ", ";
|
Printer << ", ";
|
||||||
|
|
||||||
printPattern(Elt.getPattern());
|
printPattern(Elt.getPattern());
|
||||||
}
|
}
|
||||||
Printer << ")";
|
Printer << ")";
|
||||||
@@ -1485,7 +1588,7 @@ void PrintAST::printAccessors(AbstractStorageDecl *ASD) {
|
|||||||
switch (storageKind) {
|
switch (storageKind) {
|
||||||
case AbstractStorageDecl::Stored:
|
case AbstractStorageDecl::Stored:
|
||||||
llvm_unreachable("filtered out above!");
|
llvm_unreachable("filtered out above!");
|
||||||
|
|
||||||
case AbstractStorageDecl::StoredWithTrivialAccessors:
|
case AbstractStorageDecl::StoredWithTrivialAccessors:
|
||||||
case AbstractStorageDecl::Computed:
|
case AbstractStorageDecl::Computed:
|
||||||
PrintAccessor(ASD->getGetter(), "get");
|
PrintAccessor(ASD->getGetter(), "get");
|
||||||
@@ -1522,7 +1625,9 @@ void PrintAST::printAccessors(AbstractStorageDecl *ASD) {
|
|||||||
Printer << "}";
|
Printer << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintAST::printMembersOfDecl(Decl *D, bool needComma) {
|
void PrintAST::printMembersOfDecl(Decl *D, bool needComma,
|
||||||
|
bool openBracket,
|
||||||
|
bool closeBracket) {
|
||||||
llvm::SmallVector<Decl *, 3> Members;
|
llvm::SmallVector<Decl *, 3> Members;
|
||||||
auto AddDeclFunc = [&](DeclRange Range) {
|
auto AddDeclFunc = [&](DeclRange Range) {
|
||||||
for (auto RD : Range)
|
for (auto RD : Range)
|
||||||
@@ -1538,11 +1643,13 @@ void PrintAST::printMembersOfDecl(Decl *D, bool needComma) {
|
|||||||
AddDeclFunc(Ext->getMembers());
|
AddDeclFunc(Ext->getMembers());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printMembers(Members, needComma);
|
printMembers(Members, needComma, openBracket, closeBracket);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintAST::printMembers(ArrayRef<Decl *> members, bool needComma) {
|
void PrintAST::printMembers(ArrayRef<Decl *> members, bool needComma,
|
||||||
Printer << " {";
|
bool openBracket, bool closeBracket) {
|
||||||
|
if (openBracket)
|
||||||
|
Printer << " {";
|
||||||
Printer.printNewline();
|
Printer.printNewline();
|
||||||
{
|
{
|
||||||
IndentRAII indentMore(*this);
|
IndentRAII indentMore(*this);
|
||||||
@@ -1565,7 +1672,8 @@ void PrintAST::printMembers(ArrayRef<Decl *> members, bool needComma) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
indent();
|
indent();
|
||||||
Printer << "}";
|
if (closeBracket)
|
||||||
|
Printer << "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintAST::printNominalDeclGenericParams(NominalTypeDecl *decl) {
|
void PrintAST::printNominalDeclGenericParams(NominalTypeDecl *decl) {
|
||||||
@@ -1795,27 +1903,30 @@ static void printExtendedTypeName(Type ExtendedType, ASTPrinter &Printer,
|
|||||||
|
|
||||||
void PrintAST::
|
void PrintAST::
|
||||||
printSynthesizedExtension(NominalTypeDecl* Decl, ExtensionDecl *ExtDecl) {
|
printSynthesizedExtension(NominalTypeDecl* Decl, ExtensionDecl *ExtDecl) {
|
||||||
Printer << "/// Synthesized extension from " <<
|
if (Options.TransformContext->shouldOpenExtension) {
|
||||||
|
Printer << "/// Synthesized extension from " <<
|
||||||
ExtDecl->getExtendedType()->getAnyNominal()->getName().str() << "\n";
|
ExtDecl->getExtendedType()->getAnyNominal()->getName().str() << "\n";
|
||||||
printDocumentationComment(ExtDecl);
|
printDocumentationComment(ExtDecl);
|
||||||
printAttributes(ExtDecl);
|
printAttributes(ExtDecl);
|
||||||
Printer << tok::kw_extension << " ";
|
Printer << tok::kw_extension << " ";
|
||||||
|
|
||||||
printExtendedTypeName(Decl->getDeclaredType(), Printer, Options);
|
printExtendedTypeName(Decl->getDeclaredType(), Printer, Options);
|
||||||
printInherited(ExtDecl);
|
printInherited(ExtDecl);
|
||||||
|
|
||||||
if (auto *GPs = ExtDecl->getGenericParams()) {
|
if (auto *GPs = ExtDecl->getGenericParams()) {
|
||||||
std::vector<RequirementRepr> ReqsToPrint;
|
std::vector<RequirementRepr> ReqsToPrint;
|
||||||
for (auto Req : GPs->getRequirements()) {
|
for (auto Req : GPs->getRequirements()) {
|
||||||
if (Options.TransformContext->shouldPrintRequirement(ExtDecl,
|
if (Options.TransformContext->shouldPrintRequirement(ExtDecl,
|
||||||
Req.getAsWrittenString()))
|
Req.getAsWrittenString()))
|
||||||
ReqsToPrint.push_back(Req);
|
ReqsToPrint.push_back(Req);
|
||||||
|
}
|
||||||
|
printWhereClause(ReqsToPrint);
|
||||||
}
|
}
|
||||||
printWhereClause(ReqsToPrint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Options.TypeDefinitions) {
|
if (Options.TypeDefinitions) {
|
||||||
printMembersOfDecl(ExtDecl);
|
printMembersOfDecl(ExtDecl, false,
|
||||||
|
Options.TransformContext->shouldOpenExtension,
|
||||||
|
Options.TransformContext->shouldCloseExtension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1879,7 +1990,7 @@ void PrintAST::visitPatternBindingDecl(PatternBindingDecl *decl) {
|
|||||||
} else {
|
} else {
|
||||||
Printer << "let ";
|
Printer << "let ";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
for (auto entry : decl->getPatternList()) {
|
for (auto entry : decl->getPatternList()) {
|
||||||
if (!shouldPrintPattern(entry.getPattern()))
|
if (!shouldPrintPattern(entry.getPattern()))
|
||||||
@@ -1888,7 +1999,7 @@ void PrintAST::visitPatternBindingDecl(PatternBindingDecl *decl) {
|
|||||||
isFirst = false;
|
isFirst = false;
|
||||||
else
|
else
|
||||||
Printer << ", ";
|
Printer << ", ";
|
||||||
|
|
||||||
printPattern(entry.getPattern());
|
printPattern(entry.getPattern());
|
||||||
|
|
||||||
// We also try to print type for named patterns, e.g. var Field = 10;
|
// We also try to print type for named patterns, e.g. var Field = 10;
|
||||||
@@ -2198,17 +2309,17 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
|
|||||||
Options.ExcludeAttrList.push_back(DAK_NoEscape);
|
Options.ExcludeAttrList.push_back(DAK_NoEscape);
|
||||||
if (!hasAutoClosure)
|
if (!hasAutoClosure)
|
||||||
Options.ExcludeAttrList.push_back(DAK_AutoClosure);
|
Options.ExcludeAttrList.push_back(DAK_AutoClosure);
|
||||||
|
|
||||||
|
|
||||||
// If the parameter is variadic, we will print the "..." after it, but we have
|
// If the parameter is variadic, we will print the "..." after it, but we have
|
||||||
// to strip off the added array type.
|
// to strip off the added array type.
|
||||||
if (param->isVariadic() && TheTypeLoc.getType()) {
|
if (param->isVariadic() && TheTypeLoc.getType()) {
|
||||||
if (auto *BGT = TheTypeLoc.getType()->getAs<BoundGenericType>())
|
if (auto *BGT = TheTypeLoc.getType()->getAs<BoundGenericType>())
|
||||||
TheTypeLoc.setType(BGT->getGenericArgs()[0]);
|
TheTypeLoc.setType(BGT->getGenericArgs()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printTypeLoc(TheTypeLoc);
|
printTypeLoc(TheTypeLoc);
|
||||||
|
|
||||||
if (param->isVariadic())
|
if (param->isVariadic())
|
||||||
Printer << "...";
|
Printer << "...";
|
||||||
|
|
||||||
@@ -2217,8 +2328,8 @@ void PrintAST::printOneParameter(const ParamDecl *param, bool Curried,
|
|||||||
RemoveFunc(DAK_NoEscape);
|
RemoveFunc(DAK_NoEscape);
|
||||||
if (!hasAutoClosure)
|
if (!hasAutoClosure)
|
||||||
RemoveFunc(DAK_AutoClosure);
|
RemoveFunc(DAK_AutoClosure);
|
||||||
|
|
||||||
|
|
||||||
if (Options.PrintDefaultParameterPlaceholder &&
|
if (Options.PrintDefaultParameterPlaceholder &&
|
||||||
param->isDefaultArgument()) {
|
param->isDefaultArgument()) {
|
||||||
Printer << " = ";
|
Printer << " = ";
|
||||||
@@ -2237,7 +2348,7 @@ void PrintAST::printParameterList(ParameterList *PL, bool isCurried,
|
|||||||
for (unsigned i = 0, e = PL->size(); i != e; ++i) {
|
for (unsigned i = 0, e = PL->size(); i != e; ++i) {
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
Printer << ", ";
|
Printer << ", ";
|
||||||
|
|
||||||
printOneParameter(PL->get(i), isCurried, isAPINameByDefault(i));
|
printOneParameter(PL->get(i), isCurried, isAPINameByDefault(i));
|
||||||
}
|
}
|
||||||
Printer << ")";
|
Printer << ")";
|
||||||
@@ -2503,7 +2614,7 @@ void PrintAST::visitConstructorDecl(ConstructorDecl *decl) {
|
|||||||
} else if (decl->getInitKind() == CtorInitializerKind::Factory) {
|
} else if (decl->getInitKind() == CtorInitializerKind::Factory) {
|
||||||
Printer << "/*not inherited*/ ";
|
Printer << "/*not inherited*/ ";
|
||||||
}
|
}
|
||||||
|
|
||||||
recordDeclLoc(decl,
|
recordDeclLoc(decl,
|
||||||
[&]{
|
[&]{
|
||||||
Printer << "init";
|
Printer << "init";
|
||||||
@@ -2511,7 +2622,7 @@ void PrintAST::visitConstructorDecl(ConstructorDecl *decl) {
|
|||||||
switch (decl->getFailability()) {
|
switch (decl->getFailability()) {
|
||||||
case OTK_None:
|
case OTK_None:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OTK_Optional:
|
case OTK_Optional:
|
||||||
Printer << "?";
|
Printer << "?";
|
||||||
break;
|
break;
|
||||||
@@ -2526,7 +2637,7 @@ void PrintAST::visitConstructorDecl(ConstructorDecl *decl) {
|
|||||||
|
|
||||||
printFunctionParameters(decl);
|
printFunctionParameters(decl);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!Options.FunctionDefinitions || !decl->getBody()) {
|
if (!Options.FunctionDefinitions || !decl->getBody()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2877,7 +2988,7 @@ void Pattern::print(llvm::raw_ostream &OS, const PrintOptions &Options) const {
|
|||||||
namespace {
|
namespace {
|
||||||
class TypePrinter : public TypeVisitor<TypePrinter> {
|
class TypePrinter : public TypeVisitor<TypePrinter> {
|
||||||
using super = TypeVisitor;
|
using super = TypeVisitor;
|
||||||
|
|
||||||
ASTPrinter &Printer;
|
ASTPrinter &Printer;
|
||||||
const PrintOptions &Options;
|
const PrintOptions &Options;
|
||||||
Optional<std::vector<GenericParamList *>> UnwrappedGenericParams;
|
Optional<std::vector<GenericParamList *>> UnwrappedGenericParams;
|
||||||
@@ -2917,7 +3028,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
|
|||||||
case DeclContextKind::AbstractFunctionDecl:
|
case DeclContextKind::AbstractFunctionDecl:
|
||||||
visit(cast<AbstractFunctionDecl>(DC)->getType());
|
visit(cast<AbstractFunctionDecl>(DC)->getType());
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case DeclContextKind::SubscriptDecl:
|
case DeclContextKind::SubscriptDecl:
|
||||||
visit(cast<SubscriptDecl>(DC)->getType());
|
visit(cast<SubscriptDecl>(DC)->getType());
|
||||||
return;
|
return;
|
||||||
@@ -3040,7 +3151,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
|
|||||||
public:
|
public:
|
||||||
TypePrinter(ASTPrinter &Printer, const PrintOptions &PO)
|
TypePrinter(ASTPrinter &Printer, const PrintOptions &PO)
|
||||||
: Printer(Printer), Options(PO) {}
|
: Printer(Printer), Options(PO) {}
|
||||||
|
|
||||||
void visit(Type T) {
|
void visit(Type T) {
|
||||||
Printer.printTypePre(TypeLoc::withoutLoc(T));
|
Printer.printTypePre(TypeLoc::withoutLoc(T));
|
||||||
defer { Printer.printTypePost(TypeLoc::withoutLoc(T)); };
|
defer { Printer.printTypePost(TypeLoc::withoutLoc(T)); };
|
||||||
@@ -3082,7 +3193,7 @@ public:
|
|||||||
void visitBuiltinBridgeObjectType(BuiltinBridgeObjectType *T) {
|
void visitBuiltinBridgeObjectType(BuiltinBridgeObjectType *T) {
|
||||||
Printer << "Builtin.BridgeObject";
|
Printer << "Builtin.BridgeObject";
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitBuiltinUnsafeValueBufferType(BuiltinUnsafeValueBufferType *T) {
|
void visitBuiltinUnsafeValueBufferType(BuiltinUnsafeValueBufferType *T) {
|
||||||
Printer << "Builtin.UnsafeValueBuffer";
|
Printer << "Builtin.UnsafeValueBuffer";
|
||||||
}
|
}
|
||||||
@@ -3303,7 +3414,7 @@ public:
|
|||||||
else if (info.isNoEscape() && !IsAttrExcluded(DAK_NoEscape))
|
else if (info.isNoEscape() && !IsAttrExcluded(DAK_NoEscape))
|
||||||
// autoclosure implies noescape.
|
// autoclosure implies noescape.
|
||||||
Printer << "@noescape ";
|
Printer << "@noescape ";
|
||||||
|
|
||||||
if (Options.PrintFunctionRepresentationAttrs) {
|
if (Options.PrintFunctionRepresentationAttrs) {
|
||||||
// TODO: coalesce into a single convention attribute.
|
// TODO: coalesce into a single convention attribute.
|
||||||
switch (info.getSILRepresentation()) {
|
switch (info.getSILRepresentation()) {
|
||||||
@@ -3374,10 +3485,10 @@ public:
|
|||||||
|
|
||||||
printFunctionExtInfo(T->getExtInfo());
|
printFunctionExtInfo(T->getExtInfo());
|
||||||
printWithParensIfNotSimple(T->getInput());
|
printWithParensIfNotSimple(T->getInput());
|
||||||
|
|
||||||
if (T->throws())
|
if (T->throws())
|
||||||
Printer << " " << tok::kw_throws;
|
Printer << " " << tok::kw_throws;
|
||||||
|
|
||||||
Printer << " -> ";
|
Printer << " -> ";
|
||||||
|
|
||||||
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
|
Printer.callPrintStructurePre(PrintStructureKind::FunctionReturnType);
|
||||||
@@ -3435,7 +3546,7 @@ public:
|
|||||||
// Return the max valid depth of firstType and secondType.
|
// Return the max valid depth of firstType and secondType.
|
||||||
unsigned firstDepth = getDepthOfType(req.getFirstType());
|
unsigned firstDepth = getDepthOfType(req.getFirstType());
|
||||||
unsigned secondDepth = getDepthOfType(req.getSecondType());
|
unsigned secondDepth = getDepthOfType(req.getSecondType());
|
||||||
|
|
||||||
unsigned maxDepth;
|
unsigned maxDepth;
|
||||||
if (firstDepth == ErrorDepth && secondDepth != ErrorDepth)
|
if (firstDepth == ErrorDepth && secondDepth != ErrorDepth)
|
||||||
maxDepth = secondDepth;
|
maxDepth = secondDepth;
|
||||||
@@ -3443,7 +3554,7 @@ public:
|
|||||||
maxDepth = firstDepth;
|
maxDepth = firstDepth;
|
||||||
else
|
else
|
||||||
maxDepth = std::max(firstDepth, secondDepth);
|
maxDepth = std::max(firstDepth, secondDepth);
|
||||||
|
|
||||||
return maxDepth;
|
return maxDepth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3473,7 +3584,7 @@ public:
|
|||||||
// Collect requirements for this level.
|
// Collect requirements for this level.
|
||||||
// Because of same-type requirements, these aren't well-ordered.
|
// Because of same-type requirements, these aren't well-ordered.
|
||||||
SmallVector<Requirement, 2> requirementsAtDepth;
|
SmallVector<Requirement, 2> requirementsAtDepth;
|
||||||
|
|
||||||
for (auto reqt : requirements) {
|
for (auto reqt : requirements) {
|
||||||
unsigned currentDepth = getDepthOfRequirement(reqt);
|
unsigned currentDepth = getDepthOfRequirement(reqt);
|
||||||
// Collect requirements at the current depth.
|
// Collect requirements at the current depth.
|
||||||
@@ -3487,7 +3598,7 @@ public:
|
|||||||
printSingleDepthOfGenericSignature(
|
printSingleDepthOfGenericSignature(
|
||||||
genericParams.slice(paramIdx, lastParamIdx - paramIdx),
|
genericParams.slice(paramIdx, lastParamIdx - paramIdx),
|
||||||
requirementsAtDepth);
|
requirementsAtDepth);
|
||||||
|
|
||||||
paramIdx = lastParamIdx;
|
paramIdx = lastParamIdx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3616,7 +3727,7 @@ public:
|
|||||||
|
|
||||||
if (totalResults != 1) Printer << ")";
|
if (totalResults != 1) Printer << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitSILBlockStorageType(SILBlockStorageType *T) {
|
void visitSILBlockStorageType(SILBlockStorageType *T) {
|
||||||
Printer << "@block_storage ";
|
Printer << "@block_storage ";
|
||||||
printWithParensIfNotSimple(T->getCaptureType());
|
printWithParensIfNotSimple(T->getCaptureType());
|
||||||
@@ -3774,7 +3885,7 @@ public:
|
|||||||
Printer << "$T" << T->getID();
|
Printer << "$T" << T->getID();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Printer << "_";
|
Printer << "_";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -3928,10 +4039,10 @@ void ProtocolConformance::printName(llvm::raw_ostream &os,
|
|||||||
os << ' ';
|
os << ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getType()->print(os, PO);
|
getType()->print(os, PO);
|
||||||
os << ": ";
|
os << ": ";
|
||||||
|
|
||||||
switch (getKind()) {
|
switch (getKind()) {
|
||||||
case ProtocolConformanceKind::Normal: {
|
case ProtocolConformanceKind::Normal: {
|
||||||
auto normal = cast<NormalProtocolConformance>(this);
|
auto normal = cast<NormalProtocolConformance>(this);
|
||||||
|
|||||||
@@ -479,15 +479,22 @@ void swift::ide::printSubmoduleInterface(
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Print synthesized extensions.
|
// Print synthesized extensions.
|
||||||
SynthesizedExtensionAnalyzer Analyzer(NTD);
|
SynthesizedExtensionAnalyzer Analyzer(NTD, AdjustedOptions);
|
||||||
AdjustedOptions.initArchetypeTransformerForSynthesizedExtensions(NTD,
|
AdjustedOptions.initArchetypeTransformerForSynthesizedExtensions(NTD,
|
||||||
&Analyzer);
|
&Analyzer);
|
||||||
Analyzer.forEachSynthesizedExtension([&](ExtensionDecl *ET){
|
Analyzer.forEachSynthesizedExtensionMergeGroup(
|
||||||
if (!shouldPrint(ET, AdjustedOptions))
|
[&](ArrayRef<ExtensionDecl*> Decls){
|
||||||
return;
|
for (auto ET : Decls) {
|
||||||
Printer << "\n";
|
AdjustedOptions.TransformContext->shouldOpenExtension =
|
||||||
ET->print(Printer, AdjustedOptions);
|
Decls.front() == ET;
|
||||||
Printer << "\n";
|
AdjustedOptions.TransformContext->shouldCloseExtension =
|
||||||
|
Decls.back() == ET;
|
||||||
|
if (AdjustedOptions.TransformContext->shouldOpenExtension)
|
||||||
|
Printer << "\n";
|
||||||
|
ET->print(Printer, AdjustedOptions);
|
||||||
|
if (AdjustedOptions.TransformContext->shouldCloseExtension)
|
||||||
|
Printer << "\n";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
AdjustedOptions.clearArchetypeTransformerForSynthesizedExtensions();
|
AdjustedOptions.clearArchetypeTransformerForSynthesizedExtensions();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,68 +123,53 @@ public struct S10 : P1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P2
|
// CHECK: <synthesized>/// Synthesized extension from P2
|
||||||
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T : P2 {
|
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>p2member()</loc></decl>
|
|
||||||
// CHECK-NEXT: }</synthesized>
|
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
|
||||||
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T == Int {
|
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>p1IntFunc(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
|
||||||
// CHECK-NEXT: }</synthesized>
|
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
|
||||||
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T : P3 {
|
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
|
||||||
// CHECK-NEXT: }</synthesized>
|
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
|
||||||
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T : P2 {
|
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T : P2 {
|
||||||
|
// CHECK-NEXT: <decl:Func>public func <loc>p2member()</loc></decl></synthesized>
|
||||||
|
// CHECK-NEXT: <synthesized>
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>ef1(<decl:Param>t: T</decl>)</loc></decl>
|
// CHECK-NEXT: <decl:Func>public func <loc>ef1(<decl:Param>t: T</decl>)</loc></decl>
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>ef2(<decl:Param>t: <ref:Struct>S2</ref></decl>)</loc></decl>
|
// CHECK-NEXT: <decl:Func>public func <loc>ef2(<decl:Param>t: <ref:Struct>S2</ref></decl>)</loc></decl>
|
||||||
// CHECK-NEXT: }</synthesized>
|
// CHECK-NEXT: }</synthesized>
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
// CHECK: <synthesized>/// Synthesized extension from P1
|
||||||
|
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T : P3 {
|
||||||
|
// CHECK-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
||||||
|
// CHECK-NEXT: }</synthesized>
|
||||||
|
|
||||||
|
// CHECK: <synthesized>/// Synthesized extension from P1
|
||||||
|
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T == Int {
|
||||||
|
// CHECK-NEXT: <decl:Func>public func <loc>p1IntFunc(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
||||||
|
// CHECK-NEXT: }</synthesized>
|
||||||
|
|
||||||
|
// CHECK: <synthesized>/// Synthesized extension from P1
|
||||||
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T == S9<Int> {
|
// CHECK-NEXT: extension <ref:Struct>S1</ref> where T == S9<Int> {
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>S9IntFunc()</loc></decl>
|
// CHECK-NEXT: <decl:Func>public func <loc>S9IntFunc()</loc></decl>
|
||||||
// CHECK-NEXT: }</synthesized>
|
// CHECK-NEXT: }</synthesized>
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
// CHECK: <synthesized>/// Synthesized extension from P1
|
||||||
// CHECK-NEXT: extension <ref:Struct>S10</ref> {
|
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
|
||||||
// CHECK-NEXT: }</synthesized>
|
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
|
||||||
// CHECK-NEXT: extension <ref:Struct>S10</ref> {
|
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>ef5(<decl:Param>t: <ref:Struct>S9</ref><<ref:Struct>Int</ref>></decl>)</loc></decl>
|
|
||||||
// CHECK-NEXT: }</synthesized>
|
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
|
||||||
// CHECK-NEXT: extension <ref:Struct>S10</ref> {
|
// CHECK-NEXT: extension <ref:Struct>S10</ref> {
|
||||||
|
// CHECK-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl></synthesized>
|
||||||
|
// CHECK-NEXT: <synthesized>
|
||||||
|
// CHECK-NEXT: <decl:Func>public func <loc>ef5(<decl:Param>t: <ref:Struct>S9</ref><<ref:Struct>Int</ref>></decl>)</loc></decl></synthesized>
|
||||||
|
// CHECK-NEXT: <synthesized>
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>S9IntFunc()</loc></decl>
|
// CHECK-NEXT: <decl:Func>public func <loc>S9IntFunc()</loc></decl>
|
||||||
// CHECK-NEXT: }</synthesized>
|
// CHECK-NEXT: }</synthesized>
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
// CHECK: <synthesized>/// Synthesized extension from P1
|
||||||
// CHECK-NEXT: extension <ref:Struct>S4</ref> {
|
// CHECK-NEXT: extension <ref:Struct>S4</ref> {
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>p1IntFunc(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
// CHECK-NEXT: <decl:Func>public func <loc>p1IntFunc(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
||||||
// CHECK-NEXT: }</synthesized>
|
// CHECK-NEXT: }</synthesized>
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
// CHECK: <synthesized>/// Synthesized extension from P1
|
||||||
// CHECK-NEXT: extension <ref:Struct>S6</ref> {
|
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
|
||||||
// CHECK-NEXT: }</synthesized>
|
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
|
||||||
// CHECK-NEXT: extension <ref:Struct>S6</ref> {
|
// CHECK-NEXT: extension <ref:Struct>S6</ref> {
|
||||||
|
// CHECK-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl></synthesized>
|
||||||
|
// CHECK-NEXT: <synthesized>
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>ef5(<decl:Param>t: <ref:Struct>S5</ref></decl>)</loc></decl>
|
// CHECK-NEXT: <decl:Func>public func <loc>ef5(<decl:Param>t: <ref:Struct>S5</ref></decl>)</loc></decl>
|
||||||
// CHECK-NEXT: }</synthesized>
|
// CHECK-NEXT: }</synthesized>
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
// CHECK: <synthesized>/// Synthesized extension from P1
|
||||||
// CHECK-NEXT: extension <ref:module>print_synthesized_extensions</ref>.<ref:Struct>S7</ref>.<ref:Struct>S8</ref> {
|
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl>
|
|
||||||
// CHECK-NEXT: }</synthesized>
|
|
||||||
|
|
||||||
// CHECK: <synthesized>/// Synthesized extension from P1
|
|
||||||
// CHECK-NEXT: extension <ref:module>print_synthesized_extensions</ref>.<ref:Struct>S7</ref>.<ref:Struct>S8</ref> {
|
// CHECK-NEXT: extension <ref:module>print_synthesized_extensions</ref>.<ref:Struct>S7</ref>.<ref:Struct>S8</ref> {
|
||||||
|
// CHECK-NEXT: <decl:Func>public func <loc>p3Func(<decl:Param>i: <ref:Struct>Int</ref></decl>)</loc> -> <ref:Struct>Int</ref></decl></synthesized>
|
||||||
|
// CHECK-NEXT: <synthesized>
|
||||||
// CHECK-NEXT: <decl:Func>public func <loc>ef5(<decl:Param>t: <ref:Struct>S5</ref></decl>)</loc></decl>
|
// CHECK-NEXT: <decl:Func>public func <loc>ef5(<decl:Param>t: <ref:Struct>S5</ref></decl>)</loc></decl>
|
||||||
// CHECK-NEXT: }</synthesized>
|
// CHECK-NEXT: }</synthesized>
|
||||||
|
|||||||
@@ -594,7 +594,8 @@ static bool passCursorInfoForDecl(const ValueDecl *VD,
|
|||||||
bool InSynthesizedExtension = false;
|
bool InSynthesizedExtension = false;
|
||||||
if (BaseType) {
|
if (BaseType) {
|
||||||
if(auto Target = BaseType->getAnyNominal()) {
|
if(auto Target = BaseType->getAnyNominal()) {
|
||||||
SynthesizedExtensionAnalyzer Analyzer(Target);
|
SynthesizedExtensionAnalyzer Analyzer(Target,
|
||||||
|
PrintOptions::printInterface());
|
||||||
InSynthesizedExtension = Analyzer.isInSynthesizedExtension(VD);
|
InSynthesizedExtension = Analyzer.isInSynthesizedExtension(VD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user