From c434075a6c6a1db73c1bff66f8836a65f25c8446 Mon Sep 17 00:00:00 2001 From: Quinn Taylor Date: Thu, 8 Dec 2022 12:17:03 -0500 Subject: [PATCH 1/2] [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`. --- lib/ConstExtract/ConstExtract.cpp | 110 +++++++++++++++--------------- 1 file changed, 54 insertions(+), 56 deletions(-) diff --git a/lib/ConstExtract/ConstExtract.cpp b/lib/ConstExtract/ConstExtract.cpp index 269d8da9ef509..d22a1e2ec5bcd 100644 --- a/lib/ConstExtract/ConstExtract.cpp +++ b/lib/ConstExtract/ConstExtract.cpp @@ -120,77 +120,75 @@ parseProtocolListFromFile(StringRef protocolListFilePath, return true; } -static std::string extractLiteralOutput(Expr *expr) { - std::string LiteralOutput; - llvm::raw_string_ostream OutputStream(LiteralOutput); - expr->printConstExprValue(&OutputStream, nullptr); - - return LiteralOutput; -} - static std::shared_ptr -extractPropertyInitializationValue(VarDecl *propertyDecl) { - auto binding = propertyDecl->getParentPatternBinding(); - if (binding) { - auto originalInit = binding->getOriginalInit(0); - if (originalInit) { - auto literalOutput = extractLiteralOutput(originalInit); - if (!literalOutput.empty()) { - return std::make_shared(literalOutput); - } - - if (auto callExpr = dyn_cast(originalInit)) { - if (callExpr->getFn()->getKind() != ExprKind::ConstructorRefCall) { - return std::make_shared(); +extractCompileTimeValue(Expr *expr) { + if (expr) { + switch (expr->getKind()) { + case ExprKind::Array: + case ExprKind::Dictionary: + case ExprKind::Tuple: + + case ExprKind::BooleanLiteral: + case ExprKind::FloatLiteral: + case ExprKind::IntegerLiteral: + case ExprKind::NilLiteral: + case ExprKind::StringLiteral: + { + std::string literalOutput; + llvm::raw_string_ostream OutputStream(literalOutput); + expr->printConstExprValue(&OutputStream, nullptr); + if (!literalOutput.empty()) { + return std::make_shared(literalOutput); } + break; + } - std::vector parameters; - const auto args = callExpr->getArgs(); - for (auto arg : *args) { - auto label = arg.getLabel().str().str(); - auto expr = arg.getExpr(); - - switch (expr->getKind()) { - case ExprKind::DefaultArgument: { - auto defaultArgument = cast(expr); - auto *decl = defaultArgument->getParamDecl(); - - if (decl->hasDefaultExpr()) { - literalOutput = - extractLiteralOutput(decl->getTypeCheckedDefaultExpr()); + case ExprKind::Call: + { + auto callExpr = cast(expr); + if (callExpr->getFn()->getKind() == ExprKind::ConstructorRefCall) { + std::vector parameters; + const auto args = callExpr->getArgs(); + for (auto arg : *args) { + auto argExpr = arg.getExpr(); + const auto label = arg.getLabel().str().str(); + const auto type = argExpr->getType(); + if (auto defaultArgument = dyn_cast(argExpr)) { + auto *decl = defaultArgument->getParamDecl(); + if (decl->hasDefaultExpr()) { + argExpr = decl->getTypeCheckedDefaultExpr(); + } } - - break; - } - default: - literalOutput = extractLiteralOutput(expr); - break; - } - - if (literalOutput.empty()) { - parameters.push_back( - {label, expr->getType(), std::make_shared()}); - } else { - parameters.push_back( - {label, expr->getType(), - std::make_shared(literalOutput)}); + parameters.push_back({label, type, extractCompileTimeValue(argExpr)}); } + auto name = toFullyQualifiedTypeNameString(callExpr->getType()); + return std::make_shared(name, parameters); } + break; + } - auto name = toFullyQualifiedTypeNameString(callExpr->getType()); - return std::make_shared(name, parameters); + default: + { + break; } } } + return std::make_shared(); +} + +static std::shared_ptr +extractPropertyInitializationValue(VarDecl *propertyDecl) { + if (auto binding = propertyDecl->getParentPatternBinding()) { + if (auto originalInit = binding->getOriginalInit(0)) { + return extractCompileTimeValue(originalInit); + } + } if (auto accessorDecl = propertyDecl->getAccessor(AccessorKind::Get)) { auto node = accessorDecl->getTypecheckedBody()->getFirstElement(); if (node.is()) { if (auto returnStmt = dyn_cast(node.get())) { - auto expr = returnStmt->getResult(); - std::string LiteralOutput = extractLiteralOutput(expr); - if (!LiteralOutput.empty()) - return std::make_shared(LiteralOutput); + return extractCompileTimeValue(returnStmt->getResult()); } } } From 5ad497047af0bd07881612e5fb01de771d0cbcbd Mon Sep 17 00:00:00 2001 From: Quinn Taylor Date: Thu, 8 Dec 2022 13:07:29 -0500 Subject: [PATCH 2/2] Updated formatting using `clang-format`. --- lib/ConstExtract/ConstExtract.cpp | 80 +++++++++++++++---------------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/lib/ConstExtract/ConstExtract.cpp b/lib/ConstExtract/ConstExtract.cpp index d22a1e2ec5bcd..c7dc31f182964 100644 --- a/lib/ConstExtract/ConstExtract.cpp +++ b/lib/ConstExtract/ConstExtract.cpp @@ -120,57 +120,53 @@ parseProtocolListFromFile(StringRef protocolListFilePath, return true; } -static std::shared_ptr -extractCompileTimeValue(Expr *expr) { +static std::shared_ptr extractCompileTimeValue(Expr *expr) { if (expr) { switch (expr->getKind()) { - case ExprKind::Array: - case ExprKind::Dictionary: - case ExprKind::Tuple: - - case ExprKind::BooleanLiteral: - case ExprKind::FloatLiteral: - case ExprKind::IntegerLiteral: - case ExprKind::NilLiteral: - case ExprKind::StringLiteral: - { - std::string literalOutput; - llvm::raw_string_ostream OutputStream(literalOutput); - expr->printConstExprValue(&OutputStream, nullptr); - if (!literalOutput.empty()) { - return std::make_shared(literalOutput); - } - break; + case ExprKind::Array: + case ExprKind::Dictionary: + case ExprKind::Tuple: + + case ExprKind::BooleanLiteral: + case ExprKind::FloatLiteral: + case ExprKind::IntegerLiteral: + case ExprKind::NilLiteral: + case ExprKind::StringLiteral: { + std::string literalOutput; + llvm::raw_string_ostream OutputStream(literalOutput); + expr->printConstExprValue(&OutputStream, nullptr); + if (!literalOutput.empty()) { + return std::make_shared(literalOutput); } + break; + } - case ExprKind::Call: - { - auto callExpr = cast(expr); - if (callExpr->getFn()->getKind() == ExprKind::ConstructorRefCall) { - std::vector parameters; - const auto args = callExpr->getArgs(); - for (auto arg : *args) { - auto argExpr = arg.getExpr(); - const auto label = arg.getLabel().str().str(); - const auto type = argExpr->getType(); - if (auto defaultArgument = dyn_cast(argExpr)) { - auto *decl = defaultArgument->getParamDecl(); - if (decl->hasDefaultExpr()) { - argExpr = decl->getTypeCheckedDefaultExpr(); - } + case ExprKind::Call: { + auto callExpr = cast(expr); + if (callExpr->getFn()->getKind() == ExprKind::ConstructorRefCall) { + std::vector parameters; + const auto args = callExpr->getArgs(); + for (auto arg : *args) { + auto argExpr = arg.getExpr(); + const auto label = arg.getLabel().str().str(); + const auto type = argExpr->getType(); + if (auto defaultArgument = dyn_cast(argExpr)) { + auto *decl = defaultArgument->getParamDecl(); + if (decl->hasDefaultExpr()) { + argExpr = decl->getTypeCheckedDefaultExpr(); } - parameters.push_back({label, type, extractCompileTimeValue(argExpr)}); } - auto name = toFullyQualifiedTypeNameString(callExpr->getType()); - return std::make_shared(name, parameters); + parameters.push_back({label, type, extractCompileTimeValue(argExpr)}); } - break; + auto name = toFullyQualifiedTypeNameString(callExpr->getType()); + return std::make_shared(name, parameters); } + break; + } - default: - { - break; - } + default: { + break; + } } } return std::make_shared();