Merge pull request #78511 from venkatesh5789/null-value-optional-extraction

[Compile Time Constant Extraction] Extract Nil Values for Optionals
This commit is contained in:
Venkatesh Sriram
2025-01-16 18:43:07 +05:30
committed by GitHub
4 changed files with 84 additions and 6 deletions

View File

@@ -43,6 +43,7 @@ public:
StaticFunctionCall,
MemberReference,
InterpolatedString,
NilLiteral,
Runtime
};
@@ -72,6 +73,22 @@ private:
std::string Value;
};
/// A representation of an Optional<Wrapped> value declared as nil
/// or left undeclared.
///
/// Nil values were previously represented as RawLiteralValue with
/// value "nil". This caused ambiguous values when extracting values,
/// such as an Optional<String> of value "nil".
class NilLiteralValue : public CompileTimeValue {
public:
NilLiteralValue() : CompileTimeValue(ValueKind::NilLiteral) {}
static bool classof(const CompileTimeValue *T) {
return T->getKind() == ValueKind::NilLiteral;
}
};
struct FunctionParameter {
std::string Label;
swift::Type Type;

View File

@@ -198,8 +198,7 @@ static std::optional<std::string> extractRawLiteral(Expr *expr) {
switch (expr->getKind()) {
case ExprKind::BooleanLiteral:
case ExprKind::FloatLiteral:
case ExprKind::IntegerLiteral:
case ExprKind::NilLiteral: {
case ExprKind::IntegerLiteral: {
std::string literalOutput;
llvm::raw_string_ostream OutputStream(literalOutput);
expr->printConstExprValue(&OutputStream, nullptr);
@@ -230,7 +229,6 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
case ExprKind::BooleanLiteral:
case ExprKind::FloatLiteral:
case ExprKind::IntegerLiteral:
case ExprKind::NilLiteral:
case ExprKind::StringLiteral: {
auto rawLiteral = extractRawLiteral(expr);
if (rawLiteral.has_value()) {
@@ -240,6 +238,10 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
break;
}
case ExprKind::NilLiteral: {
return std::make_shared<NilLiteralValue>();
}
case ExprKind::Array: {
auto arrayExpr = cast<ArrayExpr>(expr);
std::vector<std::shared_ptr<CompileTimeValue>> elementValues;
@@ -715,6 +717,11 @@ void writeValue(llvm::json::OStream &JSON,
break;
}
case CompileTimeValue::ValueKind::NilLiteral: {
JSON.attribute("valueKind", "NilLiteral");
break;
}
case CompileTimeValue::ValueKind::InitCall: {
auto initCallValue = cast<InitCallValue>(value);

View File

@@ -24,7 +24,7 @@ extension ImplClass: MyProto {
// CHECK: "label": "defaultNilProperty",
// CHECK: "type": "Swift.Optional<AnyObject>",
// CHECK: "value": "nil"
// CHECK: "valueKind": "NilLiteral"
// CHECK: "label": "notStoredProperty",
// CHECK: "type": "Swift.Bool",

View File

@@ -94,6 +94,12 @@ public struct PropertyWrappers : MyProto {
var projectedValue: (V, V?) { (self.value, self.lastValue) }
}
public struct Optionals: MyProto {
let int1: Bool? = nil
let string1: String?
static var float1: Float?
}
// CHECK: [
// CHECK-NEXT: {
// CHECK-NEXT: "typeName": "ExtractLiterals.Bools",
@@ -131,8 +137,7 @@ public struct PropertyWrappers : MyProto {
// CHECK-NEXT: "isComputed": "false",
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
// CHECK-NEXT: "line": 11,
// CHECK-NEXT: "valueKind": "RawLiteral",
// CHECK-NEXT: "value": "nil"
// CHECK-NEXT: "valueKind": "NilLiteral"
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: },
@@ -617,5 +622,54 @@ public struct PropertyWrappers : MyProto {
// CHECK-NEXT: "valueKind": "Runtime"
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "typeName": "ExtractLiterals.Optionals",
// CHECK-NEXT: "mangledTypeName": "15ExtractLiterals9OptionalsV",
// CHECK-NEXT: "kind": "struct",
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
// CHECK-NEXT: "line": 97,
// CHECK-NEXT: "conformances": [
// CHECK-NEXT: "ExtractLiterals.MyProto"
// CHECK-NEXT: ],
// CHECK-NEXT: "allConformances": [
// CHECK-NEXT: {
// CHECK-NEXT: "protocolName": "ExtractLiterals.MyProto",
// CHECK-NEXT: "conformanceDefiningModule": "ExtractLiterals"
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "associatedTypeAliases": [],
// CHECK-NEXT: "properties": [
// CHECK-NEXT: {
// CHECK-NEXT: "label": "int1",
// CHECK-NEXT: "type": "Swift.Optional<Swift.Bool>",
// CHECK-NEXT: "mangledTypeName": "n/a - deprecated",
// CHECK-NEXT: "isStatic": "false",
// CHECK-NEXT: "isComputed": "false",
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
// CHECK-NEXT: "line": 98,
// CHECK-NEXT: "valueKind": "NilLiteral"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "label": "string1",
// CHECK-NEXT: "type": "Swift.Optional<Swift.String>",
// CHECK-NEXT: "mangledTypeName": "n/a - deprecated",
// CHECK-NEXT: "isStatic": "false",
// CHECK-NEXT: "isComputed": "false",
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
// CHECK-NEXT: "line": 99,
// CHECK-NEXT: "valueKind": "Runtime"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "label": "float1",
// CHECK-NEXT: "type": "Swift.Optional<Swift.Float>",
// CHECK-NEXT: "mangledTypeName": "n/a - deprecated",
// CHECK-NEXT: "isStatic": "true",
// CHECK-NEXT: "isComputed": "false",
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
// CHECK-NEXT: "line": 100,
// CHECK-NEXT: "valueKind": "NilLiteral"
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT:]