mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Property delegates] Fix printing of memberwise initializer default arguments
This commit is contained in:
@@ -126,6 +126,10 @@ void simple_display(
|
|||||||
llvm::raw_ostream &out,
|
llvm::raw_ostream &out,
|
||||||
const PropertyDelegateBackingPropertyInfo &backingInfo);
|
const PropertyDelegateBackingPropertyInfo &backingInfo);
|
||||||
|
|
||||||
|
/// Given the initializer for the given property with an attached property
|
||||||
|
/// delegate, dig out the original initialization expression.
|
||||||
|
Expr *findOriginalPropertyDelegateInitialValue(VarDecl *var, Expr *init);
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|
||||||
#endif // SWIFT_AST_PROPERTY_DELEGATES_H
|
#endif // SWIFT_AST_PROPERTY_DELEGATES_H
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include "swift/AST/TypeCheckRequests.h"
|
#include "swift/AST/TypeCheckRequests.h"
|
||||||
#include "swift/AST/TypeLoc.h"
|
#include "swift/AST/TypeLoc.h"
|
||||||
#include "swift/AST/SwiftNameTranslation.h"
|
#include "swift/AST/SwiftNameTranslation.h"
|
||||||
|
#include "swift/Parse/Lexer.h"
|
||||||
#include "clang/Lex/MacroInfo.h"
|
#include "clang/Lex/MacroInfo.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/SmallPtrSet.h"
|
#include "llvm/ADT/SmallPtrSet.h"
|
||||||
@@ -5522,6 +5523,31 @@ void ParamDecl::setDefaultArgumentInitContext(Initializer *initContext) {
|
|||||||
DefaultValueAndFlags.getPointer()->InitContext = initContext;
|
DefaultValueAndFlags.getPointer()->InitContext = initContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expr *swift::findOriginalPropertyDelegateInitialValue(VarDecl *var,
|
||||||
|
Expr *init) {
|
||||||
|
auto attr = var->getAttachedPropertyDelegate();
|
||||||
|
assert(attr && "No attached property delegate?");
|
||||||
|
|
||||||
|
// Direct initialization implies no original initial value.
|
||||||
|
if (attr->getArg())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
// Look through any expressions wrapping the initializer.
|
||||||
|
init = init->getSemanticsProvidingExpr();
|
||||||
|
auto initCall = dyn_cast<CallExpr>(init);
|
||||||
|
if (!initCall)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
auto initArg = cast<TupleExpr>(initCall->getArg())->getElement(0);
|
||||||
|
initArg = initArg->getSemanticsProvidingExpr();
|
||||||
|
if (auto autoclosure = dyn_cast<AutoClosureExpr>(initArg)) {
|
||||||
|
initArg =
|
||||||
|
autoclosure->getSingleExpressionBody()->getSemanticsProvidingExpr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return initArg;
|
||||||
|
}
|
||||||
|
|
||||||
StringRef
|
StringRef
|
||||||
ParamDecl::getDefaultValueStringRepresentation(
|
ParamDecl::getDefaultValueStringRepresentation(
|
||||||
SmallVectorImpl<char> &scratch) const {
|
SmallVectorImpl<char> &scratch) const {
|
||||||
@@ -5552,6 +5578,23 @@ ParamDecl::getDefaultValueStringRepresentation(
|
|||||||
if (!existing.empty())
|
if (!existing.empty())
|
||||||
return existing;
|
return existing;
|
||||||
auto var = getStoredProperty();
|
auto var = getStoredProperty();
|
||||||
|
|
||||||
|
if (auto original = var->getOriginalDelegatedProperty()) {
|
||||||
|
if (auto attr = original->getAttachedPropertyDelegate()) {
|
||||||
|
if (auto arg = attr->getArg()) {
|
||||||
|
SourceRange fullRange(attr->getTypeLoc().getSourceRange().Start,
|
||||||
|
arg->getEndLoc());
|
||||||
|
auto charRange = Lexer::getCharSourceRangeFromSourceRange(
|
||||||
|
getASTContext().SourceMgr, fullRange);
|
||||||
|
return getASTContext().SourceMgr.extractText(charRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto init = findOriginalPropertyDelegateInitialValue(
|
||||||
|
original, original->getParentInitializer());
|
||||||
|
return extractInlinableText(getASTContext().SourceMgr, init, scratch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return extractInlinableText(getASTContext().SourceMgr,
|
return extractInlinableText(getASTContext().SourceMgr,
|
||||||
var->getParentInitializer(),
|
var->getParentInitializer(),
|
||||||
scratch);
|
scratch);
|
||||||
|
|||||||
@@ -1455,33 +1455,6 @@ void swift::completeLazyVarImplementation(VarDecl *VD) {
|
|||||||
Storage->overwriteSetterAccess(AccessLevel::Private);
|
Storage->overwriteSetterAccess(AccessLevel::Private);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the initializer for the given property with an attached property
|
|
||||||
/// delegate, dig out the original initialization expression.
|
|
||||||
static Expr *findOriginalPropertyDelegateInitialValue(VarDecl *var,
|
|
||||||
Expr *init) {
|
|
||||||
auto attr = var->getAttachedPropertyDelegate();
|
|
||||||
assert(attr && "No attached property delegate?");
|
|
||||||
|
|
||||||
// Direct initialization implies no original initial value.
|
|
||||||
if (attr->getArg())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// Look through any expressions wrapping the initializer.
|
|
||||||
init = init->getSemanticsProvidingExpr();
|
|
||||||
auto initCall = dyn_cast<CallExpr>(init);
|
|
||||||
if (!initCall)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto initArg = cast<TupleExpr>(initCall->getArg())->getElement(0);
|
|
||||||
initArg = initArg->getSemanticsProvidingExpr();
|
|
||||||
if (auto autoclosure = dyn_cast<AutoClosureExpr>(initArg)) {
|
|
||||||
initArg =
|
|
||||||
autoclosure->getSingleExpressionBody()->getSemanticsProvidingExpr();
|
|
||||||
}
|
|
||||||
|
|
||||||
return initArg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Synthesize a computed property `$foo` for a property with an attached
|
/// Synthesize a computed property `$foo` for a property with an attached
|
||||||
/// delegate that has a `delegateValue` property.
|
/// delegate that has a `delegateValue` property.
|
||||||
static VarDecl *synthesizePropertyDelegateStorageDelegateProperty(
|
static VarDecl *synthesizePropertyDelegateStorageDelegateProperty(
|
||||||
@@ -1604,7 +1577,7 @@ PropertyDelegateBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
|
|||||||
// Take the initializer from the original property.
|
// Take the initializer from the original property.
|
||||||
auto parentPBD = var->getParentPatternBinding();
|
auto parentPBD = var->getParentPatternBinding();
|
||||||
unsigned patternNumber = parentPBD->getPatternEntryIndexForVarDecl(var);
|
unsigned patternNumber = parentPBD->getPatternEntryIndexForVarDecl(var);
|
||||||
if (parentPBD->getInit(patternNumber) &&
|
if (parentPBD->isInitialized(patternNumber) &&
|
||||||
!parentPBD->isInitializerChecked(patternNumber)) {
|
!parentPBD->isInitializerChecked(patternNumber)) {
|
||||||
auto &tc = *static_cast<TypeChecker *>(ctx.getLazyResolver());
|
auto &tc = *static_cast<TypeChecker *>(ctx.getLazyResolver());
|
||||||
tc.typeCheckPatternBinding(parentPBD, patternNumber);
|
tc.typeCheckPatternBinding(parentPBD, patternNumber);
|
||||||
|
|||||||
38
test/IDE/print_property_delegates.swift
Normal file
38
test/IDE/print_property_delegates.swift
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// RUN: %empty-directory(%t)
|
||||||
|
|
||||||
|
// Directly printing the type-checked AST
|
||||||
|
// RUN: %target-swift-ide-test -print-ast-typechecked -source-filename %s | %FileCheck %s
|
||||||
|
|
||||||
|
@propertyDelegate
|
||||||
|
struct Delegate<Value> {
|
||||||
|
var value: Value
|
||||||
|
|
||||||
|
init(initialValue: Value) {
|
||||||
|
self.value = initialValue
|
||||||
|
}
|
||||||
|
|
||||||
|
init(closure: () -> Value) {
|
||||||
|
self.value = closure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func foo() -> Int { return 17 }
|
||||||
|
|
||||||
|
// CHECK: struct HasDelegates {
|
||||||
|
struct HasDelegates {
|
||||||
|
// CHECK: @Delegate var x: Int {
|
||||||
|
// CHECK-NEXT: get
|
||||||
|
// CHECK: var $x: Delegate<Int>
|
||||||
|
@Delegate(closure: foo)
|
||||||
|
var x: Int
|
||||||
|
|
||||||
|
@Delegate
|
||||||
|
var y = true
|
||||||
|
|
||||||
|
// Memberwise initializer.
|
||||||
|
// CHECK: init(x: Delegate<Int> = Delegate(closure: foo), y: Bool = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func trigger() {
|
||||||
|
_ = HasDelegates(y: false)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user