Skip to content

Commit c434075

Browse files
author
Quinn Taylor
committed
[Compile Time Constant Extraction] Refactor to support recursion.
Extract `extractCompileTimeValue()` function to recursively handle `CompileTimeValue` hierarchies. Inline `extractLiteralOutput()` to only be used from the one remaining call site. Refactor `ExprKind::Call` handling to reduce branching for args with a `DefaultArgumentExpr`.
1 parent f650682 commit c434075

File tree

1 file changed

+54
-56
lines changed

1 file changed

+54
-56
lines changed

lib/ConstExtract/ConstExtract.cpp

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -120,77 +120,75 @@ parseProtocolListFromFile(StringRef protocolListFilePath,
120120
return true;
121121
}
122122

123-
static std::string extractLiteralOutput(Expr *expr) {
124-
std::string LiteralOutput;
125-
llvm::raw_string_ostream OutputStream(LiteralOutput);
126-
expr->printConstExprValue(&OutputStream, nullptr);
127-
128-
return LiteralOutput;
129-
}
130-
131123
static std::shared_ptr<CompileTimeValue>
132-
extractPropertyInitializationValue(VarDecl *propertyDecl) {
133-
auto binding = propertyDecl->getParentPatternBinding();
134-
if (binding) {
135-
auto originalInit = binding->getOriginalInit(0);
136-
if (originalInit) {
137-
auto literalOutput = extractLiteralOutput(originalInit);
138-
if (!literalOutput.empty()) {
139-
return std::make_shared<RawLiteralValue>(literalOutput);
140-
}
141-
142-
if (auto callExpr = dyn_cast<CallExpr>(originalInit)) {
143-
if (callExpr->getFn()->getKind() != ExprKind::ConstructorRefCall) {
144-
return std::make_shared<RuntimeValue>();
124+
extractCompileTimeValue(Expr *expr) {
125+
if (expr) {
126+
switch (expr->getKind()) {
127+
case ExprKind::Array:
128+
case ExprKind::Dictionary:
129+
case ExprKind::Tuple:
130+
131+
case ExprKind::BooleanLiteral:
132+
case ExprKind::FloatLiteral:
133+
case ExprKind::IntegerLiteral:
134+
case ExprKind::NilLiteral:
135+
case ExprKind::StringLiteral:
136+
{
137+
std::string literalOutput;
138+
llvm::raw_string_ostream OutputStream(literalOutput);
139+
expr->printConstExprValue(&OutputStream, nullptr);
140+
if (!literalOutput.empty()) {
141+
return std::make_shared<RawLiteralValue>(literalOutput);
145142
}
143+
break;
144+
}
146145

147-
std::vector<FunctionParameter> parameters;
148-
const auto args = callExpr->getArgs();
149-
for (auto arg : *args) {
150-
auto label = arg.getLabel().str().str();
151-
auto expr = arg.getExpr();
152-
153-
switch (expr->getKind()) {
154-
case ExprKind::DefaultArgument: {
155-
auto defaultArgument = cast<DefaultArgumentExpr>(expr);
156-
auto *decl = defaultArgument->getParamDecl();
157-
158-
if (decl->hasDefaultExpr()) {
159-
literalOutput =
160-
extractLiteralOutput(decl->getTypeCheckedDefaultExpr());
146+
case ExprKind::Call:
147+
{
148+
auto callExpr = cast<CallExpr>(expr);
149+
if (callExpr->getFn()->getKind() == ExprKind::ConstructorRefCall) {
150+
std::vector<FunctionParameter> parameters;
151+
const auto args = callExpr->getArgs();
152+
for (auto arg : *args) {
153+
auto argExpr = arg.getExpr();
154+
const auto label = arg.getLabel().str().str();
155+
const auto type = argExpr->getType();
156+
if (auto defaultArgument = dyn_cast<DefaultArgumentExpr>(argExpr)) {
157+
auto *decl = defaultArgument->getParamDecl();
158+
if (decl->hasDefaultExpr()) {
159+
argExpr = decl->getTypeCheckedDefaultExpr();
160+
}
161161
}
162-
163-
break;
164-
}
165-
default:
166-
literalOutput = extractLiteralOutput(expr);
167-
break;
168-
}
169-
170-
if (literalOutput.empty()) {
171-
parameters.push_back(
172-
{label, expr->getType(), std::make_shared<RuntimeValue>()});
173-
} else {
174-
parameters.push_back(
175-
{label, expr->getType(),
176-
std::make_shared<RawLiteralValue>(literalOutput)});
162+
parameters.push_back({label, type, extractCompileTimeValue(argExpr)});
177163
}
164+
auto name = toFullyQualifiedTypeNameString(callExpr->getType());
165+
return std::make_shared<InitCallValue>(name, parameters);
178166
}
167+
break;
168+
}
179169

180-
auto name = toFullyQualifiedTypeNameString(callExpr->getType());
181-
return std::make_shared<InitCallValue>(name, parameters);
170+
default:
171+
{
172+
break;
182173
}
183174
}
184175
}
176+
return std::make_shared<RuntimeValue>();
177+
}
178+
179+
static std::shared_ptr<CompileTimeValue>
180+
extractPropertyInitializationValue(VarDecl *propertyDecl) {
181+
if (auto binding = propertyDecl->getParentPatternBinding()) {
182+
if (auto originalInit = binding->getOriginalInit(0)) {
183+
return extractCompileTimeValue(originalInit);
184+
}
185+
}
185186

186187
if (auto accessorDecl = propertyDecl->getAccessor(AccessorKind::Get)) {
187188
auto node = accessorDecl->getTypecheckedBody()->getFirstElement();
188189
if (node.is<Stmt *>()) {
189190
if (auto returnStmt = dyn_cast<ReturnStmt>(node.get<Stmt *>())) {
190-
auto expr = returnStmt->getResult();
191-
std::string LiteralOutput = extractLiteralOutput(expr);
192-
if (!LiteralOutput.empty())
193-
return std::make_shared<RawLiteralValue>(LiteralOutput);
191+
return extractCompileTimeValue(returnStmt->getResult());
194192
}
195193
}
196194
}

0 commit comments

Comments
 (0)