diff --git a/lib/ConstExtract/ConstExtract.cpp b/lib/ConstExtract/ConstExtract.cpp index 269d8da9ef509..c7dc31f182964 100644 --- a/lib/ConstExtract/ConstExtract.cpp +++ b/lib/ConstExtract/ConstExtract.cpp @@ -120,66 +120,63 @@ 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); +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; + } - if (auto callExpr = dyn_cast(originalInit)) { - if (callExpr->getFn()->getKind() != ExprKind::ConstructorRefCall) { - return std::make_shared(); - } - + 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 label = arg.getLabel().str().str(); - auto expr = arg.getExpr(); - - switch (expr->getKind()) { - case ExprKind::DefaultArgument: { - auto defaultArgument = cast(expr); + 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()) { - literalOutput = - extractLiteralOutput(decl->getTypeCheckedDefaultExpr()); + 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; + } + + 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); } } @@ -187,10 +184,7 @@ extractPropertyInitializationValue(VarDecl *propertyDecl) { 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()); } } }