Skip to content

Commit deae449

Browse files
authored
Merge pull request #62461 from quinntaylor/const-extraction-recursion
[Compile Time Constant Extraction] Refactor to support recursion.
2 parents 309976f + 5ad4970 commit deae449

File tree

1 file changed

+43
-49
lines changed

1 file changed

+43
-49
lines changed

lib/ConstExtract/ConstExtract.cpp

Lines changed: 43 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -120,77 +120,71 @@ 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-
131-
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);
123+
static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
124+
if (expr) {
125+
switch (expr->getKind()) {
126+
case ExprKind::Array:
127+
case ExprKind::Dictionary:
128+
case ExprKind::Tuple:
129+
130+
case ExprKind::BooleanLiteral:
131+
case ExprKind::FloatLiteral:
132+
case ExprKind::IntegerLiteral:
133+
case ExprKind::NilLiteral:
134+
case ExprKind::StringLiteral: {
135+
std::string literalOutput;
136+
llvm::raw_string_ostream OutputStream(literalOutput);
137+
expr->printConstExprValue(&OutputStream, nullptr);
138138
if (!literalOutput.empty()) {
139139
return std::make_shared<RawLiteralValue>(literalOutput);
140140
}
141+
break;
142+
}
141143

142-
if (auto callExpr = dyn_cast<CallExpr>(originalInit)) {
143-
if (callExpr->getFn()->getKind() != ExprKind::ConstructorRefCall) {
144-
return std::make_shared<RuntimeValue>();
145-
}
146-
144+
case ExprKind::Call: {
145+
auto callExpr = cast<CallExpr>(expr);
146+
if (callExpr->getFn()->getKind() == ExprKind::ConstructorRefCall) {
147147
std::vector<FunctionParameter> parameters;
148148
const auto args = callExpr->getArgs();
149149
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);
150+
auto argExpr = arg.getExpr();
151+
const auto label = arg.getLabel().str().str();
152+
const auto type = argExpr->getType();
153+
if (auto defaultArgument = dyn_cast<DefaultArgumentExpr>(argExpr)) {
156154
auto *decl = defaultArgument->getParamDecl();
157-
158155
if (decl->hasDefaultExpr()) {
159-
literalOutput =
160-
extractLiteralOutput(decl->getTypeCheckedDefaultExpr());
156+
argExpr = decl->getTypeCheckedDefaultExpr();
161157
}
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)});
177158
}
159+
parameters.push_back({label, type, extractCompileTimeValue(argExpr)});
178160
}
179-
180161
auto name = toFullyQualifiedTypeNameString(callExpr->getType());
181162
return std::make_shared<InitCallValue>(name, parameters);
182163
}
164+
break;
165+
}
166+
167+
default: {
168+
break;
169+
}
170+
}
171+
}
172+
return std::make_shared<RuntimeValue>();
173+
}
174+
175+
static std::shared_ptr<CompileTimeValue>
176+
extractPropertyInitializationValue(VarDecl *propertyDecl) {
177+
if (auto binding = propertyDecl->getParentPatternBinding()) {
178+
if (auto originalInit = binding->getOriginalInit(0)) {
179+
return extractCompileTimeValue(originalInit);
183180
}
184181
}
185182

186183
if (auto accessorDecl = propertyDecl->getAccessor(AccessorKind::Get)) {
187184
auto node = accessorDecl->getTypecheckedBody()->getFirstElement();
188185
if (node.is<Stmt *>()) {
189186
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);
187+
return extractCompileTimeValue(returnStmt->getResult());
194188
}
195189
}
196190
}

0 commit comments

Comments
 (0)