Skip to content

Commit c7120f4

Browse files
committed
[Refactoring] Move SimplifyNumberLiteral to its own file
1 parent 5dc7a79 commit c7120f4

File tree

3 files changed

+119
-105
lines changed

3 files changed

+119
-105
lines changed

lib/Refactoring/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_swift_host_library(swiftRefactoring STATIC
2121
Refactoring.cpp
2222
Renamer.cpp
2323
ReplaceBodiesWithFatalError.cpp
24+
SimplifyNumberLiteral.cpp
2425
Utils.cpp
2526
)
2627

lib/Refactoring/Refactoring.cpp

Lines changed: 0 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -566,111 +566,6 @@ collectRefactoringsAtCursor(SourceFile *SF, unsigned Line, unsigned Column,
566566
return collectRefactorings(Tok, /*ExcludeRename=*/false);
567567
}
568568

569-
/// Given a cursor position, this function tries to collect a number literal
570-
/// expression immediately following the cursor.
571-
static NumberLiteralExpr *getTrailingNumberLiteral(ResolvedCursorInfoPtr Tok) {
572-
// This cursor must point to the start of an expression.
573-
auto ExprStartInfo = dyn_cast<ResolvedExprStartCursorInfo>(Tok);
574-
if (!ExprStartInfo)
575-
return nullptr;
576-
577-
// For every sub-expression, try to find the literal expression that matches
578-
// our criteria.
579-
class FindLiteralNumber : public ASTWalker {
580-
Expr * const parent;
581-
582-
public:
583-
NumberLiteralExpr *found = nullptr;
584-
585-
explicit FindLiteralNumber(Expr *parent) : parent(parent) { }
586-
587-
MacroWalking getMacroWalkingBehavior() const override {
588-
return MacroWalking::Arguments;
589-
}
590-
591-
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
592-
if (auto *literal = dyn_cast<NumberLiteralExpr>(expr)) {
593-
// The sub-expression must have the same start loc with the outermost
594-
// expression, i.e. the cursor position.
595-
if (!found &&
596-
parent->getStartLoc().getOpaquePointerValue() ==
597-
expr->getStartLoc().getOpaquePointerValue()) {
598-
found = literal;
599-
}
600-
}
601-
return Action::SkipChildrenIf(found, expr);
602-
}
603-
};
604-
605-
auto parent = ExprStartInfo->getTrailingExpr();
606-
FindLiteralNumber finder(parent);
607-
parent->walk(finder);
608-
return finder.found;
609-
}
610-
611-
static std::string insertUnderscore(StringRef Text) {
612-
SmallString<64> Buffer;
613-
llvm::raw_svector_ostream OS(Buffer);
614-
for (auto It = Text.begin(); It != Text.end(); ++It) {
615-
unsigned Distance = It - Text.begin();
616-
if (Distance && !(Distance % 3)) {
617-
OS << '_';
618-
}
619-
OS << *It;
620-
}
621-
return OS.str().str();
622-
}
623-
624-
void insertUnderscoreInDigits(StringRef Digits,
625-
raw_ostream &OS) {
626-
StringRef BeforePointRef, AfterPointRef;
627-
std::tie(BeforePointRef, AfterPointRef) = Digits.split('.');
628-
629-
std::string BeforePoint(BeforePointRef);
630-
std::string AfterPoint(AfterPointRef);
631-
632-
// Insert '_' for the part before the decimal point.
633-
std::reverse(BeforePoint.begin(), BeforePoint.end());
634-
BeforePoint = insertUnderscore(BeforePoint);
635-
std::reverse(BeforePoint.begin(), BeforePoint.end());
636-
OS << BeforePoint;
637-
638-
// Insert '_' for the part after the decimal point, if necessary.
639-
if (!AfterPoint.empty()) {
640-
OS << '.';
641-
OS << insertUnderscore(AfterPoint);
642-
}
643-
}
644-
645-
bool RefactoringActionSimplifyNumberLiteral::isApplicable(
646-
ResolvedCursorInfoPtr Tok, DiagnosticEngine &Diag) {
647-
if (auto *Literal = getTrailingNumberLiteral(Tok)) {
648-
SmallString<64> Buffer;
649-
llvm::raw_svector_ostream OS(Buffer);
650-
StringRef Digits = Literal->getDigitsText();
651-
insertUnderscoreInDigits(Digits, OS);
652-
653-
// If inserting '_' results in a different digit sequence, this refactoring
654-
// is applicable.
655-
return OS.str() != Digits;
656-
}
657-
return false;
658-
}
659-
660-
bool RefactoringActionSimplifyNumberLiteral::performChange() {
661-
if (auto *Literal = getTrailingNumberLiteral(CursorInfo)) {
662-
663-
EditorConsumerInsertStream OS(EditConsumer, SM,
664-
CharSourceRange(SM, Literal->getDigitsLoc(),
665-
Lexer::getLocForEndOfToken(SM,
666-
Literal->getEndLoc())));
667-
StringRef Digits = Literal->getDigitsText();
668-
insertUnderscoreInDigits(Digits, OS);
669-
return false;
670-
}
671-
return true;
672-
}
673-
674569
static CallExpr *findTrailingClosureTarget(SourceManager &SM,
675570
ResolvedCursorInfoPtr CursorInfo) {
676571
if (CursorInfo->getKind() == CursorInfoKind::StmtStart)
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "RefactoringActions.h"
14+
15+
using namespace swift::refactoring;
16+
17+
/// Given a cursor position, this function tries to collect a number literal
18+
/// expression immediately following the cursor.
19+
static NumberLiteralExpr *getTrailingNumberLiteral(ResolvedCursorInfoPtr Tok) {
20+
// This cursor must point to the start of an expression.
21+
auto ExprStartInfo = dyn_cast<ResolvedExprStartCursorInfo>(Tok);
22+
if (!ExprStartInfo)
23+
return nullptr;
24+
25+
// For every sub-expression, try to find the literal expression that matches
26+
// our criteria.
27+
class FindLiteralNumber : public ASTWalker {
28+
Expr *const parent;
29+
30+
public:
31+
NumberLiteralExpr *found = nullptr;
32+
33+
explicit FindLiteralNumber(Expr *parent) : parent(parent) {}
34+
35+
MacroWalking getMacroWalkingBehavior() const override {
36+
return MacroWalking::Arguments;
37+
}
38+
39+
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
40+
if (auto *literal = dyn_cast<NumberLiteralExpr>(expr)) {
41+
// The sub-expression must have the same start loc with the outermost
42+
// expression, i.e. the cursor position.
43+
if (!found && parent->getStartLoc().getOpaquePointerValue() ==
44+
expr->getStartLoc().getOpaquePointerValue()) {
45+
found = literal;
46+
}
47+
}
48+
return Action::SkipChildrenIf(found, expr);
49+
}
50+
};
51+
52+
auto parent = ExprStartInfo->getTrailingExpr();
53+
FindLiteralNumber finder(parent);
54+
parent->walk(finder);
55+
return finder.found;
56+
}
57+
58+
static std::string insertUnderscore(StringRef Text) {
59+
SmallString<64> Buffer;
60+
llvm::raw_svector_ostream OS(Buffer);
61+
for (auto It = Text.begin(); It != Text.end(); ++It) {
62+
unsigned Distance = It - Text.begin();
63+
if (Distance && !(Distance % 3)) {
64+
OS << '_';
65+
}
66+
OS << *It;
67+
}
68+
return OS.str().str();
69+
}
70+
71+
void insertUnderscoreInDigits(StringRef Digits, raw_ostream &OS) {
72+
StringRef BeforePointRef, AfterPointRef;
73+
std::tie(BeforePointRef, AfterPointRef) = Digits.split('.');
74+
75+
std::string BeforePoint(BeforePointRef);
76+
std::string AfterPoint(AfterPointRef);
77+
78+
// Insert '_' for the part before the decimal point.
79+
std::reverse(BeforePoint.begin(), BeforePoint.end());
80+
BeforePoint = insertUnderscore(BeforePoint);
81+
std::reverse(BeforePoint.begin(), BeforePoint.end());
82+
OS << BeforePoint;
83+
84+
// Insert '_' for the part after the decimal point, if necessary.
85+
if (!AfterPoint.empty()) {
86+
OS << '.';
87+
OS << insertUnderscore(AfterPoint);
88+
}
89+
}
90+
91+
bool RefactoringActionSimplifyNumberLiteral::isApplicable(
92+
ResolvedCursorInfoPtr Tok, DiagnosticEngine &Diag) {
93+
if (auto *Literal = getTrailingNumberLiteral(Tok)) {
94+
SmallString<64> Buffer;
95+
llvm::raw_svector_ostream OS(Buffer);
96+
StringRef Digits = Literal->getDigitsText();
97+
insertUnderscoreInDigits(Digits, OS);
98+
99+
// If inserting '_' results in a different digit sequence, this refactoring
100+
// is applicable.
101+
return OS.str() != Digits;
102+
}
103+
return false;
104+
}
105+
106+
bool RefactoringActionSimplifyNumberLiteral::performChange() {
107+
if (auto *Literal = getTrailingNumberLiteral(CursorInfo)) {
108+
109+
EditorConsumerInsertStream OS(
110+
EditConsumer, SM,
111+
CharSourceRange(SM, Literal->getDigitsLoc(),
112+
Lexer::getLocForEndOfToken(SM, Literal->getEndLoc())));
113+
StringRef Digits = Literal->getDigitsText();
114+
insertUnderscoreInDigits(Digits, OS);
115+
return false;
116+
}
117+
return true;
118+
}

0 commit comments

Comments
 (0)