Skip to content

Commit b15d007

Browse files
authored
Merge pull request #15096 from slavapestov/fix-subscript-reconstruction
Fix subscript reconstruction
2 parents 55021a8 + 0e637f4 commit b15d007

File tree

2 files changed

+131
-26
lines changed

2 files changed

+131
-26
lines changed

lib/IDE/TypeReconstruction.cpp

Lines changed: 95 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,15 @@ static void VisitNodeDestructor(
951951
}
952952
}
953953

954+
static Demangle::NodePointer DropGenericSignature(
955+
Demangle::NodePointer cur_node) {
956+
if (cur_node->getKind() != Demangle::Node::Kind::DependentGenericType)
957+
return nullptr;
958+
if (cur_node->getChild(0) == nullptr)
959+
return nullptr;
960+
return cur_node->getFirstChild();
961+
}
962+
954963
static void VisitNodeDeclContext(
955964
ASTContext *ast,
956965
Demangle::NodePointer cur_node, VisitNodeResult &result) {
@@ -979,14 +988,10 @@ static void VisitNodeDeclContext(
979988
if (generics->getChild(0) == nullptr)
980989
break;
981990
generics = generics->getFirstChild();
982-
if (generics->getKind() != Demangle::Node::Kind::DependentGenericType)
991+
generics = DropGenericSignature(generics);
992+
if (generics == nullptr)
983993
break;
984-
if (generics->getChild(0) == nullptr)
985-
break;
986-
generics = generics->getFirstChild();
987-
// if (generics->getKind() !=
988-
// Demangle::Node::Kind::ArchetypeList)
989-
// break;
994+
990995
AbstractFunctionDecl *func_decl = nullptr;
991996
for (Decl *decl : found_decls._decls) {
992997
func_decl = dyn_cast<AbstractFunctionDecl>(decl);
@@ -1254,6 +1259,28 @@ static void VisitNodeFunction(
12541259
}
12551260
}
12561261

1262+
do {
1263+
if (cur_node->getKind() == Demangle::Node::Kind::Subscript) {
1264+
FindNamedDecls(ast, DeclBaseName::createSubscript(),
1265+
decl_scope_result);
1266+
if (decl_scope_result._decls.empty()) {
1267+
result._error = stringWithFormat(
1268+
"subscript identifier could not be found by name lookup");
1269+
break;
1270+
}
1271+
std::copy(decl_scope_result._decls.begin(),
1272+
decl_scope_result._decls.end(),
1273+
back_inserter(identifier_result._decls));
1274+
std::copy(decl_scope_result._types.begin(),
1275+
decl_scope_result._types.end(),
1276+
back_inserter(identifier_result._types));
1277+
identifier_result._module = decl_scope_result._module;
1278+
if (decl_scope_result._decls.size() == 1)
1279+
found_univocous = true;
1280+
break;
1281+
}
1282+
} while (0);
1283+
12571284
// if (node_kind == Demangle::Node::Kind::Allocator)
12581285
// {
12591286
// // For allocators we don't have an identifier for
@@ -1416,6 +1443,8 @@ static void VisitNodeSetterGetter(
14161443
Demangle::NodePointer cur_node, VisitNodeResult &result) {
14171444
VisitNodeResult decl_ctx_result;
14181445
std::string identifier;
1446+
std::vector<StringRef> labels;
1447+
14191448
VisitNodeResult type_result;
14201449

14211450
assert(cur_node->getNumChildren() == 1 &&
@@ -1440,9 +1469,23 @@ static void VisitNodeSetterGetter(
14401469
case Demangle::Node::Kind::Identifier:
14411470
identifier.assign((*pos)->getText());
14421471
break;
1443-
case Demangle::Node::Kind::Type:
1444-
VisitNode(ast, *pos, type_result);
1472+
case Demangle::Node::Kind::Type: {
1473+
auto type = (*pos)->getFirstChild();
1474+
if (DropGenericSignature(type))
1475+
type = type->getChild(1);
1476+
VisitNode(ast, type, type_result);
1477+
break;
1478+
}
1479+
case Demangle::Node::Kind::LabelList: {
1480+
for (const auto &label : **pos) {
1481+
if (label->getKind() == Demangle::Node::Kind::FirstElementMarker)
1482+
labels.push_back(StringRef());
1483+
else {
1484+
labels.push_back(label->getText());
1485+
}
1486+
}
14451487
break;
1488+
}
14461489
default:
14471490
result._error =
14481491
stringWithFormat("%s encountered in generic type children",
@@ -1451,6 +1494,11 @@ static void VisitNodeSetterGetter(
14511494
}
14521495
}
14531496

1497+
if (!type_result.HasSingleType()) {
1498+
result._error = "bad type";
1499+
return;
1500+
}
1501+
14541502
if (referenced_node->getKind() == Demangle::Node::Kind::Subscript) {
14551503
// Since there can be many subscripts for the same nominal type, we need to
14561504
// find the one matching the specified type.
@@ -1467,9 +1515,6 @@ static void VisitNodeSetterGetter(
14671515
const AnyFunctionType *type_func =
14681516
type_result._types.front()->getAs<AnyFunctionType>();
14691517

1470-
Type type_result_type = type_func->getResult();
1471-
Type type_input_type = type_func->getInput();
1472-
14731518
FuncDecl *identifier_func = nullptr;
14741519

14751520
for (size_t i = 0; i < num_decls; i++) {
@@ -1494,24 +1539,24 @@ static void VisitNodeSetterGetter(
14941539
break;
14951540
}
14961541

1497-
if (identifier_func && identifier_func->getInterfaceType()) {
1498-
const AnyFunctionType *identifier_func_type =
1499-
identifier_func->getInterfaceType()->getAs<AnyFunctionType>();
1500-
if (identifier_func_type) {
1542+
if (identifier_func &&
1543+
subscript_decl->getGetter() &&
1544+
subscript_decl->getGetter()->getInterfaceType()) {
1545+
auto subscript_type =
1546+
subscript_decl->getGetter()->getInterfaceType()->getAs<AnyFunctionType>();
1547+
1548+
if (subscript_type) {
15011549
// Swift function types are formally functions that take the class
15021550
// and return the method,
15031551
// we have to strip off the first level of function call to compare
15041552
// against the type
15051553
// from the demangled name.
1506-
const AnyFunctionType *identifier_uncurried_result =
1507-
identifier_func_type->getResult()->getAs<AnyFunctionType>();
1508-
if (identifier_uncurried_result) {
1509-
Type identifier_result_type =
1510-
identifier_uncurried_result->getResult();
1511-
Type identifier_input_type =
1512-
identifier_uncurried_result->getInput();
1513-
if (identifier_result_type->isEqual(type_result_type) &&
1514-
identifier_input_type->isEqual(type_input_type)) {
1554+
auto subscript_uncurried_result =
1555+
subscript_type->getResult()->getAs<AnyFunctionType>();
1556+
if (subscript_uncurried_result) {
1557+
if (CompareFunctionTypes(type_func,
1558+
subscript_uncurried_result,
1559+
labels)) {
15151560
break;
15161561
}
15171562
}
@@ -2061,6 +2106,25 @@ VisitNodeWeak(ASTContext *ast,
20612106
}
20622107
}
20632108

2109+
static void
2110+
VisitNodeGenericParam(ASTContext *ast,
2111+
Demangle::NodePointer cur_node,
2112+
VisitNodeResult &result) {
2113+
if (cur_node->getNumChildren() == 2) {
2114+
auto first = cur_node->getChild(0);
2115+
auto second = cur_node->getChild(1);
2116+
if (first->getKind() == Demangle::Node::Kind::Index &&
2117+
second->getKind() == Demangle::Node::Kind::Index) {
2118+
result._types.push_back(
2119+
GenericTypeParamType::get(first->getIndex(),
2120+
second->getIndex(), *ast));
2121+
return;
2122+
}
2123+
}
2124+
2125+
result._error = "bad generic param type";
2126+
}
2127+
20642128
static void VisitFirstChildNode(
20652129
ASTContext *ast,
20662130
Demangle::NodePointer cur_node, VisitNodeResult &result) {
@@ -2159,7 +2223,8 @@ static void VisitNode(
21592223

21602224
case Demangle::Node::Kind::Function:
21612225
case Demangle::Node::Kind::Allocator:
2162-
case Demangle::Node::Kind::Variable: // Out of order on purpose
2226+
case Demangle::Node::Kind::Variable:
2227+
case Demangle::Node::Kind::Subscript: // Out of order on purpose
21632228
VisitNodeFunction(ast, node, result);
21642229
break;
21652230

@@ -2229,6 +2294,10 @@ static void VisitNode(
22292294
VisitNodeWeak(ast, node, result);
22302295
break;
22312296

2297+
case Demangle::Node::Kind::DependentGenericParamType:
2298+
VisitNodeGenericParam(ast, node, result);
2299+
break;
2300+
22322301
case Demangle::Node::Kind::LocalDeclName:
22332302
case Demangle::Node::Kind::Identifier:
22342303
case Demangle::Node::Kind::PrivateDeclName:

test/IDE/reconstruct_type_from_mangled_name.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,39 @@ fileprivate struct VeryPrivateData {}
270270
// FIXME
271271
// CHECK: decl: FAILURE for 'privateFunction'
272272
fileprivate func privateFunction(_ d: VeryPrivateData) {}
273+
274+
struct HasSubscript {
275+
// CHECK: decl: subscript(t: Int) -> Int { get set }
276+
subscript(_ t: Int) -> Int {
277+
// CHECK: decl: get {} for '' usr=s:14swift_ide_test12HasSubscriptVyS2icig
278+
get {
279+
return t
280+
}
281+
// CHECK: decl: set {} for '' usr=s:14swift_ide_test12HasSubscriptVyS2icis
282+
set {}
283+
}
284+
}
285+
286+
// FIXME
287+
// CHECK: decl: FAILURE for 'T' usr=s:14swift_ide_test19HasGenericSubscriptV1Txmfp
288+
struct HasGenericSubscript<T> {
289+
// CHECK: subscript<U>(t: T) -> U { get set } for 'subscript' usr=s:14swift_ide_test19HasGenericSubscriptVyqd__xclui
290+
// FIXME
291+
// CHECK: decl: FAILURE for 'U'
292+
// FIXME
293+
// CHECK: decl: FAILURE for 't'
294+
subscript<U>(_ t: T) -> U {
295+
296+
// CHECK: decl: get {} for '' usr=s:14swift_ide_test19HasGenericSubscriptVyqd__xcluig
297+
// FIXME
298+
// CHECK: dref: FAILURE for 't'
299+
get {
300+
return t as! U
301+
}
302+
303+
// FIXME
304+
// CHECK: dref: FAILURE for 'U'
305+
// CHECK: decl: set {} for '' usr=s:14swift_ide_test19HasGenericSubscriptVyqd__xcluis
306+
set {}
307+
}
308+
}

0 commit comments

Comments
 (0)