Skip to content

Commit 4a7dccd

Browse files
authored
Merge pull request swiftlang#9688 from akyrtzi/migrator-no-unnecessary-prefix-for-type
[migrator] Do proper lookup and avoid prefixing typeof(of:) if the only found name is the stdlib one.
2 parents 91e46b2 + 7cf46b0 commit 4a7dccd

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

lib/Migrator/TypeOfMigratorPass.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ using namespace swift::migrator;
2424

2525
namespace {
2626

27-
struct TypeOfMigratorPass: public ASTMigratorPass,
27+
class TypeOfMigratorPass: public ASTMigratorPass,
2828
public SourceEntityWalker {
2929

30+
std::vector<DeclContext *> ContextStack;
31+
3032
void handleTypeOf(const DynamicTypeExpr *DTE) {
3133
if (!SF->getASTContext().LangOpts.isSwiftVersion3()) {
3234
return;
@@ -39,12 +41,22 @@ struct TypeOfMigratorPass: public ASTMigratorPass,
3941

4042
UnqualifiedLookup Lookup {
4143
{ SF->getASTContext().getIdentifier("type") },
42-
SF->getModuleScopeContext(),
43-
/*TypeResolver=*/nullptr,
44+
ContextStack.empty() ? SF->getModuleScopeContext() : ContextStack.back(),
45+
/*TypeResolver=*/SF->getASTContext().getLazyResolver(),
4446
/*IsKnownPrivate=*/false,
4547
DTE->getLoc()
4648
};
47-
if (Lookup.Results.empty()) {
49+
auto isShadowing = [&]() -> bool {
50+
if (Lookup.Results.empty())
51+
return false;
52+
if (Lookup.Results.size() != 1)
53+
return true;
54+
if (auto VD = Lookup.Results.front().getValueDecl()) {
55+
return !VD->getModuleContext()->isStdlibModule();
56+
}
57+
return false;
58+
};
59+
if (!isShadowing()) {
4860
// There won't be a name shadowing here in Swift 4, so we don't need to
4961
// do anything.
5062
return;
@@ -58,6 +70,19 @@ struct TypeOfMigratorPass: public ASTMigratorPass,
5870
}
5971
return true;
6072
}
73+
74+
bool walkToDeclPre(Decl *D, CharSourceRange Range) override {
75+
if (auto DC = dyn_cast<DeclContext>(D))
76+
ContextStack.push_back(DC);
77+
return true;
78+
}
79+
80+
bool walkToDeclPost(Decl *D) override {
81+
if (isa<DeclContext>(D))
82+
ContextStack.pop_back();
83+
return true;
84+
}
85+
6186
public:
6287
TypeOfMigratorPass(EditorAdapter &Editor,
6388
SourceFile *SF,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: rm -rf %t && mkdir -p %t && %target-swift-frontend -typecheck -update-code -primary-file %s -emit-migrated-file-path %t.result
2+
// RUN: diff -u %s.expected %t.result
3+
// RUN: %target-swift-frontend -typecheck %t.result -swift-version 4
4+
5+
class HasTypeMethod {
6+
var type: Int {
7+
_ = type(of: 1)
8+
return 1
9+
}
10+
}
11+
12+
class NoTypeMethod {
13+
func meth() {
14+
_ = type(of: 1) // Don't need to add prefix
15+
}
16+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: rm -rf %t && mkdir -p %t && %target-swift-frontend -typecheck -update-code -primary-file %s -emit-migrated-file-path %t.result
2+
// RUN: diff -u %s.expected %t.result
3+
// RUN: %target-swift-frontend -typecheck %t.result -swift-version 4
4+
5+
class HasTypeMethod {
6+
var type: Int {
7+
_ = Swift.type(of: 1)
8+
return 1
9+
}
10+
}
11+
12+
class NoTypeMethod {
13+
func meth() {
14+
_ = type(of: 1) // Don't need to add prefix
15+
}
16+
}

0 commit comments

Comments
 (0)