Skip to content

Commit 10b9daf

Browse files
committed
[Refactoring] Split ConvertToComputedProperty to its own file
1 parent 00eaf74 commit 10b9daf

File tree

3 files changed

+110
-91
lines changed

3 files changed

+110
-91
lines changed

lib/Refactoring/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ add_swift_host_library(swiftRefactoring STATIC
33
AddExplicitCodableImplementation.cpp
44
CollapseNestedIfStmt.cpp
55
ConvertStringConcatenationToInterpolation.cpp
6+
ConvertToComputedProperty.cpp
67
ConvertGuardExprToIfLetExpr.cpp
78
ConvertIfLetExprToGuardExpr.cpp
89
ConvertToDoCatch.cpp
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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+
#include "swift/AST/TypeRepr.h"
15+
16+
using namespace swift::refactoring;
17+
18+
bool RefactoringActionConvertToComputedProperty::isApplicable(
19+
const ResolvedRangeInfo &Info, DiagnosticEngine &Diag) {
20+
if (Info.Kind != RangeKind::SingleDecl) {
21+
return false;
22+
}
23+
24+
if (Info.ContainedNodes.size() != 1) {
25+
return false;
26+
}
27+
28+
auto D = Info.ContainedNodes[0].dyn_cast<Decl *>();
29+
if (!D) {
30+
return false;
31+
}
32+
33+
auto Binding = dyn_cast<PatternBindingDecl>(D);
34+
if (!Binding) {
35+
return false;
36+
}
37+
38+
auto SV = Binding->getSingleVar();
39+
if (!SV) {
40+
return false;
41+
}
42+
43+
// willSet, didSet cannot be provided together with a getter
44+
for (auto AD : SV->getAllAccessors()) {
45+
if (AD->isObservingAccessor()) {
46+
return false;
47+
}
48+
}
49+
50+
// 'lazy' must not be used on a computed property
51+
// NSCopying and IBOutlet attribute requires property to be mutable
52+
auto Attributies = SV->getAttrs();
53+
if (Attributies.hasAttribute<LazyAttr>() ||
54+
Attributies.hasAttribute<NSCopyingAttr>() ||
55+
Attributies.hasAttribute<IBOutletAttr>()) {
56+
return false;
57+
}
58+
59+
// Property wrapper cannot be applied to a computed property
60+
if (SV->hasAttachedPropertyWrapper()) {
61+
return false;
62+
}
63+
64+
// has an initializer
65+
return Binding->hasInitStringRepresentation(0);
66+
}
67+
68+
bool RefactoringActionConvertToComputedProperty::performChange() {
69+
// Get an initialization
70+
auto D = RangeInfo.ContainedNodes[0].dyn_cast<Decl *>();
71+
auto Binding = dyn_cast<PatternBindingDecl>(D);
72+
SmallString<128> scratch;
73+
auto Init = Binding->getInitStringRepresentation(0, scratch);
74+
75+
// Get type
76+
auto SV = Binding->getSingleVar();
77+
auto SVType = SV->getTypeInContext();
78+
auto TR = SV->getTypeReprOrParentPatternTypeRepr();
79+
80+
SmallString<64> DeclBuffer;
81+
llvm::raw_svector_ostream OS(DeclBuffer);
82+
StringRef Space = " ";
83+
StringRef NewLine = "\n";
84+
85+
OS << tok::kw_var << Space;
86+
// Add var name
87+
OS << SV->getNameStr().str() << ":" << Space;
88+
// For computed property must write a type of var
89+
if (TR) {
90+
OS << Lexer::getCharSourceRangeFromSourceRange(SM, TR->getSourceRange())
91+
.str();
92+
} else {
93+
SVType.print(OS);
94+
}
95+
96+
OS << Space << tok::l_brace << NewLine;
97+
// Add an initialization
98+
OS << tok::kw_return << Space << Init.str() << NewLine;
99+
OS << tok::r_brace;
100+
101+
// Replace initializer to computed property
102+
auto ReplaceStartLoc = Binding->getLoc();
103+
auto ReplaceEndLoc = Binding->getSourceRange().End;
104+
auto ReplaceRange = SourceRange(ReplaceStartLoc, ReplaceEndLoc);
105+
auto ReplaceCharSourceRange =
106+
Lexer::getCharSourceRangeFromSourceRange(SM, ReplaceRange);
107+
EditConsumer.accept(SM, ReplaceCharSourceRange, DeclBuffer.str());
108+
return false; // success
109+
}

lib/Refactoring/Refactoring.cpp

Lines changed: 0 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -579,97 +579,6 @@ static bool collectRangeStartRefactorings(const ResolvedRangeInfo &Info) {
579579
return false;
580580
}
581581
}
582-
583-
bool RefactoringActionConvertToComputedProperty::
584-
isApplicable(const ResolvedRangeInfo &Info, DiagnosticEngine &Diag) {
585-
if (Info.Kind != RangeKind::SingleDecl) {
586-
return false;
587-
}
588-
589-
if (Info.ContainedNodes.size() != 1) {
590-
return false;
591-
}
592-
593-
auto D = Info.ContainedNodes[0].dyn_cast<Decl*>();
594-
if (!D) {
595-
return false;
596-
}
597-
598-
auto Binding = dyn_cast<PatternBindingDecl>(D);
599-
if (!Binding) {
600-
return false;
601-
}
602-
603-
auto SV = Binding->getSingleVar();
604-
if (!SV) {
605-
return false;
606-
}
607-
608-
// willSet, didSet cannot be provided together with a getter
609-
for (auto AD : SV->getAllAccessors()) {
610-
if (AD->isObservingAccessor()) {
611-
return false;
612-
}
613-
}
614-
615-
// 'lazy' must not be used on a computed property
616-
// NSCopying and IBOutlet attribute requires property to be mutable
617-
auto Attributies = SV->getAttrs();
618-
if (Attributies.hasAttribute<LazyAttr>() ||
619-
Attributies.hasAttribute<NSCopyingAttr>() ||
620-
Attributies.hasAttribute<IBOutletAttr>()) {
621-
return false;
622-
}
623-
624-
// Property wrapper cannot be applied to a computed property
625-
if (SV->hasAttachedPropertyWrapper()) {
626-
return false;
627-
}
628-
629-
// has an initializer
630-
return Binding->hasInitStringRepresentation(0);
631-
}
632-
633-
bool RefactoringActionConvertToComputedProperty::performChange() {
634-
// Get an initialization
635-
auto D = RangeInfo.ContainedNodes[0].dyn_cast<Decl*>();
636-
auto Binding = dyn_cast<PatternBindingDecl>(D);
637-
SmallString<128> scratch;
638-
auto Init = Binding->getInitStringRepresentation(0, scratch);
639-
640-
// Get type
641-
auto SV = Binding->getSingleVar();
642-
auto SVType = SV->getTypeInContext();
643-
auto TR = SV->getTypeReprOrParentPatternTypeRepr();
644-
645-
SmallString<64> DeclBuffer;
646-
llvm::raw_svector_ostream OS(DeclBuffer);
647-
StringRef Space = " ";
648-
StringRef NewLine = "\n";
649-
650-
OS << tok::kw_var << Space;
651-
// Add var name
652-
OS << SV->getNameStr().str() << ":" << Space;
653-
// For computed property must write a type of var
654-
if (TR) {
655-
OS << Lexer::getCharSourceRangeFromSourceRange(SM, TR->getSourceRange()).str();
656-
} else {
657-
SVType.print(OS);
658-
}
659-
660-
OS << Space << tok::l_brace << NewLine;
661-
// Add an initialization
662-
OS << tok::kw_return << Space << Init.str() << NewLine;
663-
OS << tok::r_brace;
664-
665-
// Replace initializer to computed property
666-
auto ReplaceStartLoc = Binding->getLoc();
667-
auto ReplaceEndLoc = Binding->getSourceRange().End;
668-
auto ReplaceRange = SourceRange(ReplaceStartLoc, ReplaceEndLoc);
669-
auto ReplaceCharSourceRange = Lexer::getCharSourceRangeFromSourceRange(SM, ReplaceRange);
670-
EditConsumer.accept(SM, ReplaceCharSourceRange, DeclBuffer.str());
671-
return false; // success
672-
}
673582

674583
namespace asyncrefactorings {
675584

0 commit comments

Comments
 (0)