Merge pull request #74491 from venkatesh5789/interpolated-string-extraction

[Compile Time Constant Extraction] Extract Interpolated String Literals
This commit is contained in:
Venkatesh Sriram
2024-06-26 10:34:42 -07:00
committed by GitHub
5 changed files with 352 additions and 18 deletions

View File

@@ -287,13 +287,25 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
case ExprKind::Call: {
auto callExpr = cast<CallExpr>(expr);
if (callExpr->getFn()->getKind() == ExprKind::ConstructorRefCall) {
auto functionKind = callExpr->getFn()->getKind();
if (functionKind == ExprKind::DeclRef) {
auto declRefExpr = cast<DeclRefExpr>(callExpr->getFn());
auto caseName =
declRefExpr->getDecl()->getName().getBaseIdentifier().str().str();
std::vector<FunctionParameter> parameters =
extractFunctionArguments(callExpr->getArgs());
return std::make_shared<FunctionCallValue>(caseName, parameters);
}
if (functionKind == ExprKind::ConstructorRefCall) {
std::vector<FunctionParameter> parameters =
extractFunctionArguments(callExpr->getArgs());
return std::make_shared<InitCallValue>(callExpr->getType(), parameters);
}
if (callExpr->getFn()->getKind() == ExprKind::DotSyntaxCall) {
if (functionKind == ExprKind::DotSyntaxCall) {
auto dotSyntaxCallExpr = cast<DotSyntaxCallExpr>(callExpr->getFn());
auto fn = dotSyntaxCallExpr->getFn();
if (fn->getKind() == ExprKind::DeclRef) {
@@ -409,6 +421,38 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
return extractCompileTimeValue(injectIntoOptionalExpr->getSubExpr());
}
case ExprKind::Load: {
auto loadExpr = cast<LoadExpr>(expr);
return extractCompileTimeValue(loadExpr->getSubExpr());
}
case ExprKind::MemberRef: {
auto memberExpr = cast<MemberRefExpr>(expr);
if (isa<TypeExpr>(memberExpr->getBase())) {
auto baseTypeExpr = cast<TypeExpr>(memberExpr->getBase());
auto label = memberExpr->getDecl().getDecl()->getBaseIdentifier().str();
return std::make_shared<MemberReferenceValue>(
baseTypeExpr->getInstanceType(), label.str());
}
break;
}
case ExprKind::InterpolatedStringLiteral: {
auto interpolatedStringExpr = cast<InterpolatedStringLiteralExpr>(expr);
auto tapExpr = interpolatedStringExpr->getAppendingExpr();
auto &Ctx = tapExpr->getVar()->getASTContext();
std::vector<std::shared_ptr<CompileTimeValue>> segments;
interpolatedStringExpr->forEachSegment(
Ctx, [&](bool isInterpolation, CallExpr *segment) -> void {
auto arg = segment->getArgs()->get(0);
auto expr = arg.getExpr();
segments.push_back(extractCompileTimeValue(expr));
});
return std::make_shared<InterpolatedStringLiteralValue>(segments);
}
default: {
break;
}
@@ -733,23 +777,69 @@ void writeValue(llvm::json::OStream &JSON,
break;
}
case CompileTimeValue::KeyPath: {
auto keyPathValue = cast<KeyPathValue>(value);
JSON.attribute("valueKind", "KeyPath");
JSON.attributeObject("value", [&]() {
JSON.attribute("path", keyPathValue->getPath());
JSON.attribute("rootType", toFullyQualifiedTypeNameString(keyPathValue->getRootType()));
JSON.attributeArray("components", [&] {
auto components = keyPathValue->getComponents();
for (auto c : components) {
case CompileTimeValue::ValueKind::KeyPath: {
auto keyPathValue = cast<KeyPathValue>(value);
JSON.attribute("valueKind", "KeyPath");
JSON.attributeObject("value", [&]() {
JSON.attribute("path", keyPathValue->getPath());
JSON.attribute("rootType", toFullyQualifiedTypeNameString(
keyPathValue->getRootType()));
JSON.attributeArray("components", [&] {
auto components = keyPathValue->getComponents();
for (auto c : components) {
JSON.object([&] {
JSON.attribute("label", c.Label);
JSON.attribute("type", toFullyQualifiedTypeNameString(c.Type));
});
}
});
});
break;
}
case CompileTimeValue::ValueKind::FunctionCall: {
auto functionCallValue = cast<FunctionCallValue>(value);
JSON.attribute("valueKind", "FunctionCall");
JSON.attributeObject("value", [&]() {
JSON.attribute("name", functionCallValue->getIdentifier());
if (functionCallValue->getParameters().has_value()) {
auto params = functionCallValue->getParameters().value();
JSON.attributeArray("arguments", [&] {
for (auto FP : params) {
JSON.object([&] {
JSON.attribute("label", c.Label);
JSON.attribute("type", toFullyQualifiedTypeNameString(c.Type));
JSON.attribute("label", FP.Label);
JSON.attribute("type", toFullyQualifiedTypeNameString(FP.Type));
writeValue(JSON, FP.Value);
});
}
});
}
});
break;
}
case CompileTimeValue::ValueKind::MemberReference: {
auto memberReferenceValue = cast<MemberReferenceValue>(value);
JSON.attribute("valueKind", "MemberReference");
JSON.attributeObject("value", [&]() {
JSON.attribute("baseType", toFullyQualifiedTypeNameString(
memberReferenceValue->getBaseType()));
JSON.attribute("memberLabel", memberReferenceValue->getMemberLabel());
});
break;
}
case CompileTimeValue::ValueKind::InterpolatedString: {
auto interpolatedStringValue = cast<InterpolatedStringLiteralValue>(value);
JSON.attribute("valueKind", "InterpolatedStringLiteral");
JSON.attributeObject("value", [&]() {
JSON.attributeArray("segments", [&] {
auto segments = interpolatedStringValue->getSegments();
for (auto s : segments) {
JSON.object([&] { writeValue(JSON, s); });
}
});
break;
});
break;
}
case CompileTimeValue::ValueKind::Runtime: {