Skip to content

Commit a75b64e

Browse files
committed
Add refactoring support for accessor macros
1 parent 9638062 commit a75b64e

File tree

7 files changed

+95
-11
lines changed

7 files changed

+95
-11
lines changed

include/swift/AST/TypeCheckRequests.h

+20
Original file line numberDiff line numberDiff line change
@@ -3825,6 +3825,26 @@ class ExpandMacroExpansionDeclRequest
38253825
bool isCached() const { return true; }
38263826
};
38273827

3828+
/// Expand all accessor macros attached to the given declaration.
3829+
///
3830+
/// Produces the set of macro expansion buffer IDs.
3831+
class ExpandAccessorMacros
3832+
: public SimpleRequest<ExpandAccessorMacros,
3833+
ArrayRef<unsigned>(AbstractStorageDecl *),
3834+
RequestFlags::Cached> {
3835+
public:
3836+
using SimpleRequest::SimpleRequest;
3837+
3838+
private:
3839+
friend SimpleRequest;
3840+
3841+
ArrayRef<unsigned> evaluate(
3842+
Evaluator &evaluator, AbstractStorageDecl *storage) const;
3843+
3844+
public:
3845+
bool isCached() const { return true; }
3846+
};
3847+
38283848
/// Expand all member attribute macros attached to the given
38293849
/// declaration.
38303850
///

include/swift/AST/TypeCheckerTypeIDZone.def

+3
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,9 @@ SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
434434
SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
435435
ArrayRef<unsigned>(Decl *),
436436
Cached, NoLocationInfo)
437+
SWIFT_REQUEST(TypeChecker, ExpandAccessorMacros,
438+
ArrayRef<unsigned>(AbstractStorageDecl *),
439+
Cached, NoLocationInfo)
437440
SWIFT_REQUEST(TypeChecker, ExpandSynthesizedMemberMacroRequest,
438441
ArrayRef<unsigned>(Decl *),
439442
Cached, NoLocationInfo)

lib/Refactoring/Refactoring.cpp

+15-3
Original file line numberDiff line numberDiff line change
@@ -8491,7 +8491,11 @@ getMacroExpansionBuffers(MacroDecl *macro, const CustomAttr *attr, Decl *decl) {
84918491
ASTContext &ctx = macro->getASTContext();
84928492
llvm::SmallVector<unsigned, 2> allBufferIDs;
84938493
if (roles.contains(MacroRole::Accessor)) {
8494-
// FIXME: Need to requestify.
8494+
if (auto storage = dyn_cast<AbstractStorageDecl>(decl)) {
8495+
auto bufferIDs = evaluateOrDefault(
8496+
ctx.evaluator, ExpandAccessorMacros{storage}, { });
8497+
allBufferIDs.append(bufferIDs.begin(), bufferIDs.end());
8498+
}
84958499
}
84968500

84978501
if (roles.contains(MacroRole::MemberAttribute)) {
@@ -8607,9 +8611,10 @@ bool RefactoringActionExpandMacro::performChange() {
86078611

86088612
auto originalSourceRange = generatedInfo->originalSourceRange;
86098613

8610-
// For member macros, adjust the source range from before-the-close-brace
8611-
// to after-the-open-brace.
8614+
SmallString<64> scratchBuffer;
86128615
if (generatedInfo->kind == GeneratedSourceInfo::MemberMacroExpansion) {
8616+
// For member macros, adjust the source range from before-the-close-brace
8617+
// to after-the-open-brace.
86138618
ASTNode node = ASTNode::getFromOpaqueValue(generatedInfo->astNode);
86148619
auto decl = node.dyn_cast<Decl *>();
86158620
if (!decl)
@@ -8626,6 +8631,13 @@ bool RefactoringActionExpandMacro::performChange() {
86268631

86278632
auto afterLeftBraceLoc = Lexer::getLocForEndOfToken(SM, leftBraceLoc);
86288633
originalSourceRange = CharSourceRange(afterLeftBraceLoc, 0);
8634+
} else if (generatedInfo->kind ==
8635+
GeneratedSourceInfo::AccessorMacroExpansion) {
8636+
// For accessor macros, wrap curly braces around the buffer contents.
8637+
scratchBuffer += "{\n";
8638+
scratchBuffer += rewrittenBuffer;
8639+
scratchBuffer += "\n}";
8640+
rewrittenBuffer = scratchBuffer;
86298641
}
86308642

86318643
EditConsumer.accept(SM, originalSourceRange, rewrittenBuffer);

lib/Sema/TypeCheckMacros.cpp

+25-3
Original file line numberDiff line numberDiff line change
@@ -990,8 +990,14 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
990990
Lexer::getCharSourceRangeFromSourceRange(sourceMgr, *initRange);
991991
} else {
992992
// The accessors go at the end.
993+
SourceLoc endLoc = storage->getEndLoc();
994+
if (auto var = dyn_cast<VarDecl>(storage)) {
995+
if (auto pattern = var->getParentPattern())
996+
endLoc = pattern->getEndLoc();
997+
}
998+
993999
generatedOriginalSourceRange = CharSourceRange(
994-
Lexer::getLocForEndOfToken(sourceMgr, storage->getEndLoc()), 0);
1000+
Lexer::getLocForEndOfToken(sourceMgr, endLoc), 0);
9951001
}
9961002

9971003
break;
@@ -1064,15 +1070,15 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
10641070
return macroSourceFile;
10651071
}
10661072

1067-
void swift::expandAccessors(
1073+
Optional<unsigned> swift::expandAccessors(
10681074
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
10691075
) {
10701076
// Evaluate the macro.
10711077
auto macroSourceFile = evaluateAttachedMacro(macro, storage, attr,
10721078
/*passParentContext*/false,
10731079
MacroRole::Accessor);
10741080
if (!macroSourceFile)
1075-
return;
1081+
return None;
10761082

10771083
PrettyStackTraceDecl debugStack(
10781084
"type checking expanded declaration macro", storage);
@@ -1098,6 +1104,22 @@ void swift::expandAccessors(
10981104
}
10991105
}
11001106
}
1107+
1108+
return macroSourceFile->getBufferID();
1109+
}
1110+
1111+
ArrayRef<unsigned> ExpandAccessorMacros::evaluate(
1112+
Evaluator &evaluator, AbstractStorageDecl *storage
1113+
) const {
1114+
llvm::SmallVector<unsigned, 1> bufferIDs;
1115+
storage->forEachAttachedMacro(MacroRole::Accessor,
1116+
[&](CustomAttr *customAttr, MacroDecl *macro) {
1117+
if (auto bufferID = expandAccessors(
1118+
storage, customAttr, macro))
1119+
bufferIDs.push_back(*bufferID);
1120+
});
1121+
1122+
return storage->getASTContext().AllocateCopy(bufferIDs);
11011123
}
11021124

11031125
Optional<unsigned>

lib/Sema/TypeCheckMacros.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ bool expandFreestandingDeclarationMacro(
4949

5050
/// Expand the accessors for the given storage declaration based on the
5151
/// custom attribute that references the given macro.
52-
void expandAccessors(
52+
Optional<unsigned> expandAccessors(
5353
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
5454
);
5555

lib/Sema/TypeCheckStorage.cpp

+1-4
Original file line numberDiff line numberDiff line change
@@ -3414,10 +3414,7 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
34143414
}
34153415

34163416
// Expand any attached accessor macros.
3417-
storage->forEachAttachedMacro(MacroRole::Accessor,
3418-
[&](CustomAttr *customAttr, MacroDecl *macro) {
3419-
expandAccessors(storage, customAttr, macro);
3420-
});
3417+
(void)evaluateOrDefault(evaluator, ExpandAccessorMacros{storage}, { });
34213418

34223419
bool hasWillSet = storage->getParsedAccessor(AccessorKind::WillSet);
34233420
bool hasDidSet = storage->getParsedAccessor(AccessorKind::DidSet);

test/SourceKit/Macros/macro_basic.swift

+30
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ struct S {
2424
var y: Int
2525
}
2626

27+
struct S2 {
28+
private var _storage = _Storage()
29+
30+
@accessViaStorage
31+
var x: Int
32+
33+
@accessViaStorage
34+
var y: Int = 17
35+
}
36+
2737
// FIXME: Swift parser is not enabled on Linux CI yet.
2838
// REQUIRES: OS=macosx
2939

@@ -92,3 +102,23 @@ struct S {
92102
// ATTACHED_EXPAND: 22:11-22:11 "private var _storage = _Storage()"
93103
// ATTACHED_EXPAND: source.edit.kind.active:
94104
// ATTACHED_EXPAND: 21:1-21:15 ""
105+
106+
//##-- Refactoring expanding the first accessor macro
107+
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=30:4 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=ACCESSOR1_EXPAND %s
108+
// ACCESSOR1_EXPAND: source.edit.kind.active:
109+
// ACCESSOR1_EXPAND: 31:13-31:13 "{
110+
// ACCESSOR1_EXPAND: get { _storage.x }
111+
// ACCESSOR1_EXPAND: set { _storage.x = newValue }
112+
// ACCESSOR1_EXPAND: }"
113+
// ACCESSOR1_EXPAND: source.edit.kind.active:
114+
// ACCESSOR1_EXPAND: 30:3-30:20 ""
115+
116+
//##-- Refactoring expanding the first accessor macro
117+
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=33:13 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=ACCESSOR2_EXPAND %s
118+
// ACCESSOR2_EXPAND: source.edit.kind.active:
119+
// ACCESSOR2_EXPAND: 34:14-34:18 "{
120+
// ACCESSOR2_EXPAND: get { _storage.y }
121+
// ACCESSOR2_EXPAND: set { _storage.y = newValue }
122+
// ACCESSOR2_EXPAND: }"
123+
// ACCESSOR2_EXPAND: source.edit.kind.active:
124+
// ACCESSOR2_EXPAND: 33:3-33:20 ""

0 commit comments

Comments
 (0)