mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add refactoring support for accessor macros
This commit is contained in:
@@ -3825,6 +3825,26 @@ public:
|
|||||||
bool isCached() const { return true; }
|
bool isCached() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Expand all accessor macros attached to the given declaration.
|
||||||
|
///
|
||||||
|
/// Produces the set of macro expansion buffer IDs.
|
||||||
|
class ExpandAccessorMacros
|
||||||
|
: public SimpleRequest<ExpandAccessorMacros,
|
||||||
|
ArrayRef<unsigned>(AbstractStorageDecl *),
|
||||||
|
RequestFlags::Cached> {
|
||||||
|
public:
|
||||||
|
using SimpleRequest::SimpleRequest;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend SimpleRequest;
|
||||||
|
|
||||||
|
ArrayRef<unsigned> evaluate(
|
||||||
|
Evaluator &evaluator, AbstractStorageDecl *storage) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool isCached() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
/// Expand all member attribute macros attached to the given
|
/// Expand all member attribute macros attached to the given
|
||||||
/// declaration.
|
/// declaration.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -434,6 +434,9 @@ SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
|
|||||||
SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
|
SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
|
||||||
ArrayRef<unsigned>(Decl *),
|
ArrayRef<unsigned>(Decl *),
|
||||||
Cached, NoLocationInfo)
|
Cached, NoLocationInfo)
|
||||||
|
SWIFT_REQUEST(TypeChecker, ExpandAccessorMacros,
|
||||||
|
ArrayRef<unsigned>(AbstractStorageDecl *),
|
||||||
|
Cached, NoLocationInfo)
|
||||||
SWIFT_REQUEST(TypeChecker, ExpandSynthesizedMemberMacroRequest,
|
SWIFT_REQUEST(TypeChecker, ExpandSynthesizedMemberMacroRequest,
|
||||||
ArrayRef<unsigned>(Decl *),
|
ArrayRef<unsigned>(Decl *),
|
||||||
Cached, NoLocationInfo)
|
Cached, NoLocationInfo)
|
||||||
|
|||||||
@@ -8491,7 +8491,11 @@ getMacroExpansionBuffers(MacroDecl *macro, const CustomAttr *attr, Decl *decl) {
|
|||||||
ASTContext &ctx = macro->getASTContext();
|
ASTContext &ctx = macro->getASTContext();
|
||||||
llvm::SmallVector<unsigned, 2> allBufferIDs;
|
llvm::SmallVector<unsigned, 2> allBufferIDs;
|
||||||
if (roles.contains(MacroRole::Accessor)) {
|
if (roles.contains(MacroRole::Accessor)) {
|
||||||
// FIXME: Need to requestify.
|
if (auto storage = dyn_cast<AbstractStorageDecl>(decl)) {
|
||||||
|
auto bufferIDs = evaluateOrDefault(
|
||||||
|
ctx.evaluator, ExpandAccessorMacros{storage}, { });
|
||||||
|
allBufferIDs.append(bufferIDs.begin(), bufferIDs.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roles.contains(MacroRole::MemberAttribute)) {
|
if (roles.contains(MacroRole::MemberAttribute)) {
|
||||||
@@ -8607,9 +8611,10 @@ bool RefactoringActionExpandMacro::performChange() {
|
|||||||
|
|
||||||
auto originalSourceRange = generatedInfo->originalSourceRange;
|
auto originalSourceRange = generatedInfo->originalSourceRange;
|
||||||
|
|
||||||
// For member macros, adjust the source range from before-the-close-brace
|
SmallString<64> scratchBuffer;
|
||||||
// to after-the-open-brace.
|
|
||||||
if (generatedInfo->kind == GeneratedSourceInfo::MemberMacroExpansion) {
|
if (generatedInfo->kind == GeneratedSourceInfo::MemberMacroExpansion) {
|
||||||
|
// For member macros, adjust the source range from before-the-close-brace
|
||||||
|
// to after-the-open-brace.
|
||||||
ASTNode node = ASTNode::getFromOpaqueValue(generatedInfo->astNode);
|
ASTNode node = ASTNode::getFromOpaqueValue(generatedInfo->astNode);
|
||||||
auto decl = node.dyn_cast<Decl *>();
|
auto decl = node.dyn_cast<Decl *>();
|
||||||
if (!decl)
|
if (!decl)
|
||||||
@@ -8626,6 +8631,13 @@ bool RefactoringActionExpandMacro::performChange() {
|
|||||||
|
|
||||||
auto afterLeftBraceLoc = Lexer::getLocForEndOfToken(SM, leftBraceLoc);
|
auto afterLeftBraceLoc = Lexer::getLocForEndOfToken(SM, leftBraceLoc);
|
||||||
originalSourceRange = CharSourceRange(afterLeftBraceLoc, 0);
|
originalSourceRange = CharSourceRange(afterLeftBraceLoc, 0);
|
||||||
|
} else if (generatedInfo->kind ==
|
||||||
|
GeneratedSourceInfo::AccessorMacroExpansion) {
|
||||||
|
// For accessor macros, wrap curly braces around the buffer contents.
|
||||||
|
scratchBuffer += "{\n";
|
||||||
|
scratchBuffer += rewrittenBuffer;
|
||||||
|
scratchBuffer += "\n}";
|
||||||
|
rewrittenBuffer = scratchBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditConsumer.accept(SM, originalSourceRange, rewrittenBuffer);
|
EditConsumer.accept(SM, originalSourceRange, rewrittenBuffer);
|
||||||
|
|||||||
@@ -990,8 +990,14 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
|
|||||||
Lexer::getCharSourceRangeFromSourceRange(sourceMgr, *initRange);
|
Lexer::getCharSourceRangeFromSourceRange(sourceMgr, *initRange);
|
||||||
} else {
|
} else {
|
||||||
// The accessors go at the end.
|
// The accessors go at the end.
|
||||||
|
SourceLoc endLoc = storage->getEndLoc();
|
||||||
|
if (auto var = dyn_cast<VarDecl>(storage)) {
|
||||||
|
if (auto pattern = var->getParentPattern())
|
||||||
|
endLoc = pattern->getEndLoc();
|
||||||
|
}
|
||||||
|
|
||||||
generatedOriginalSourceRange = CharSourceRange(
|
generatedOriginalSourceRange = CharSourceRange(
|
||||||
Lexer::getLocForEndOfToken(sourceMgr, storage->getEndLoc()), 0);
|
Lexer::getLocForEndOfToken(sourceMgr, endLoc), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1064,7 +1070,7 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
|
|||||||
return macroSourceFile;
|
return macroSourceFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swift::expandAccessors(
|
Optional<unsigned> swift::expandAccessors(
|
||||||
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
|
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
|
||||||
) {
|
) {
|
||||||
// Evaluate the macro.
|
// Evaluate the macro.
|
||||||
@@ -1072,7 +1078,7 @@ void swift::expandAccessors(
|
|||||||
/*passParentContext*/false,
|
/*passParentContext*/false,
|
||||||
MacroRole::Accessor);
|
MacroRole::Accessor);
|
||||||
if (!macroSourceFile)
|
if (!macroSourceFile)
|
||||||
return;
|
return None;
|
||||||
|
|
||||||
PrettyStackTraceDecl debugStack(
|
PrettyStackTraceDecl debugStack(
|
||||||
"type checking expanded declaration macro", storage);
|
"type checking expanded declaration macro", storage);
|
||||||
@@ -1098,6 +1104,22 @@ void swift::expandAccessors(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return macroSourceFile->getBufferID();
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayRef<unsigned> ExpandAccessorMacros::evaluate(
|
||||||
|
Evaluator &evaluator, AbstractStorageDecl *storage
|
||||||
|
) const {
|
||||||
|
llvm::SmallVector<unsigned, 1> bufferIDs;
|
||||||
|
storage->forEachAttachedMacro(MacroRole::Accessor,
|
||||||
|
[&](CustomAttr *customAttr, MacroDecl *macro) {
|
||||||
|
if (auto bufferID = expandAccessors(
|
||||||
|
storage, customAttr, macro))
|
||||||
|
bufferIDs.push_back(*bufferID);
|
||||||
|
});
|
||||||
|
|
||||||
|
return storage->getASTContext().AllocateCopy(bufferIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<unsigned>
|
Optional<unsigned>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ bool expandFreestandingDeclarationMacro(
|
|||||||
|
|
||||||
/// Expand the accessors for the given storage declaration based on the
|
/// Expand the accessors for the given storage declaration based on the
|
||||||
/// custom attribute that references the given macro.
|
/// custom attribute that references the given macro.
|
||||||
void expandAccessors(
|
Optional<unsigned> expandAccessors(
|
||||||
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
|
AbstractStorageDecl *storage, CustomAttr *attr, MacroDecl *macro
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -3414,10 +3414,7 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Expand any attached accessor macros.
|
// Expand any attached accessor macros.
|
||||||
storage->forEachAttachedMacro(MacroRole::Accessor,
|
(void)evaluateOrDefault(evaluator, ExpandAccessorMacros{storage}, { });
|
||||||
[&](CustomAttr *customAttr, MacroDecl *macro) {
|
|
||||||
expandAccessors(storage, customAttr, macro);
|
|
||||||
});
|
|
||||||
|
|
||||||
bool hasWillSet = storage->getParsedAccessor(AccessorKind::WillSet);
|
bool hasWillSet = storage->getParsedAccessor(AccessorKind::WillSet);
|
||||||
bool hasDidSet = storage->getParsedAccessor(AccessorKind::DidSet);
|
bool hasDidSet = storage->getParsedAccessor(AccessorKind::DidSet);
|
||||||
|
|||||||
@@ -24,6 +24,16 @@ struct S {
|
|||||||
var y: Int
|
var y: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct S2 {
|
||||||
|
private var _storage = _Storage()
|
||||||
|
|
||||||
|
@accessViaStorage
|
||||||
|
var x: Int
|
||||||
|
|
||||||
|
@accessViaStorage
|
||||||
|
var y: Int = 17
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Swift parser is not enabled on Linux CI yet.
|
// FIXME: Swift parser is not enabled on Linux CI yet.
|
||||||
// REQUIRES: OS=macosx
|
// REQUIRES: OS=macosx
|
||||||
|
|
||||||
@@ -92,3 +102,23 @@ struct S {
|
|||||||
// ATTACHED_EXPAND: 22:11-22:11 "private var _storage = _Storage()"
|
// ATTACHED_EXPAND: 22:11-22:11 "private var _storage = _Storage()"
|
||||||
// ATTACHED_EXPAND: source.edit.kind.active:
|
// ATTACHED_EXPAND: source.edit.kind.active:
|
||||||
// ATTACHED_EXPAND: 21:1-21:15 ""
|
// ATTACHED_EXPAND: 21:1-21:15 ""
|
||||||
|
|
||||||
|
//##-- Refactoring expanding the first accessor macro
|
||||||
|
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=30:4 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=ACCESSOR1_EXPAND %s
|
||||||
|
// ACCESSOR1_EXPAND: source.edit.kind.active:
|
||||||
|
// ACCESSOR1_EXPAND: 31:13-31:13 "{
|
||||||
|
// ACCESSOR1_EXPAND: get { _storage.x }
|
||||||
|
// ACCESSOR1_EXPAND: set { _storage.x = newValue }
|
||||||
|
// ACCESSOR1_EXPAND: }"
|
||||||
|
// ACCESSOR1_EXPAND: source.edit.kind.active:
|
||||||
|
// ACCESSOR1_EXPAND: 30:3-30:20 ""
|
||||||
|
|
||||||
|
//##-- Refactoring expanding the first accessor macro
|
||||||
|
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=33:13 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=ACCESSOR2_EXPAND %s
|
||||||
|
// ACCESSOR2_EXPAND: source.edit.kind.active:
|
||||||
|
// ACCESSOR2_EXPAND: 34:14-34:18 "{
|
||||||
|
// ACCESSOR2_EXPAND: get { _storage.y }
|
||||||
|
// ACCESSOR2_EXPAND: set { _storage.y = newValue }
|
||||||
|
// ACCESSOR2_EXPAND: }"
|
||||||
|
// ACCESSOR2_EXPAND: source.edit.kind.active:
|
||||||
|
// ACCESSOR2_EXPAND: 33:3-33:20 ""
|
||||||
|
|||||||
Reference in New Issue
Block a user