Skip to content

Commit c6c8526

Browse files
author
Venkatesh Sriram
committed
[Compile Time Constant Extraction] Extract Nil Values for Optionals
1 parent f1f1051 commit c6c8526

File tree

4 files changed

+84
-6
lines changed

4 files changed

+84
-6
lines changed

include/swift/AST/ConstTypeInfo.h

+17
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class CompileTimeValue {
4343
StaticFunctionCall,
4444
MemberReference,
4545
InterpolatedString,
46+
NilLiteral,
4647
Runtime
4748
};
4849

@@ -72,6 +73,22 @@ class RawLiteralValue : public CompileTimeValue {
7273
std::string Value;
7374
};
7475

76+
/// A representation of an Optional<Wrapped> value declared as nil
77+
/// or left undeclared.
78+
///
79+
/// Nil values were previously represented as RawLiteralValue with
80+
/// value "nil". This caused ambiguous values when extracting values,
81+
/// such as an Optional<String> of value "nil".
82+
83+
class NilLiteralValue : public CompileTimeValue {
84+
public:
85+
NilLiteralValue() : CompileTimeValue(ValueKind::NilLiteral) {}
86+
87+
static bool classof(const CompileTimeValue *T) {
88+
return T->getKind() == ValueKind::NilLiteral;
89+
}
90+
};
91+
7592
struct FunctionParameter {
7693
std::string Label;
7794
swift::Type Type;

lib/ConstExtract/ConstExtract.cpp

+10-3
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@ static std::optional<std::string> extractRawLiteral(Expr *expr) {
198198
switch (expr->getKind()) {
199199
case ExprKind::BooleanLiteral:
200200
case ExprKind::FloatLiteral:
201-
case ExprKind::IntegerLiteral:
202-
case ExprKind::NilLiteral: {
201+
case ExprKind::IntegerLiteral: {
203202
std::string literalOutput;
204203
llvm::raw_string_ostream OutputStream(literalOutput);
205204
expr->printConstExprValue(&OutputStream, nullptr);
@@ -230,7 +229,6 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
230229
case ExprKind::BooleanLiteral:
231230
case ExprKind::FloatLiteral:
232231
case ExprKind::IntegerLiteral:
233-
case ExprKind::NilLiteral:
234232
case ExprKind::StringLiteral: {
235233
auto rawLiteral = extractRawLiteral(expr);
236234
if (rawLiteral.has_value()) {
@@ -240,6 +238,10 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
240238
break;
241239
}
242240

241+
case ExprKind::NilLiteral: {
242+
return std::make_shared<NilLiteralValue>();
243+
}
244+
243245
case ExprKind::Array: {
244246
auto arrayExpr = cast<ArrayExpr>(expr);
245247
std::vector<std::shared_ptr<CompileTimeValue>> elementValues;
@@ -710,6 +712,11 @@ void writeValue(llvm::json::OStream &JSON,
710712
break;
711713
}
712714

715+
case CompileTimeValue::ValueKind::NilLiteral: {
716+
JSON.attribute("valueKind", "NilLiteral");
717+
break;
718+
}
719+
713720
case CompileTimeValue::ValueKind::InitCall: {
714721
auto initCallValue = cast<InitCallValue>(value);
715722

test/ConstExtraction/ExtractFromObjcImplementationExtension.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extension ImplClass: MyProto {
2424

2525
// CHECK: "label": "defaultNilProperty",
2626
// CHECK: "type": "Swift.Optional<AnyObject>",
27-
// CHECK: "value": "nil"
27+
// CHECK: "valueKind": "NilLiteral"
2828

2929
// CHECK: "label": "notStoredProperty",
3030
// CHECK: "type": "Swift.Bool",

test/ConstExtraction/ExtractLiterals.swift

+56-2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@ public struct PropertyWrappers : MyProto {
9494
var projectedValue: (V, V?) { (self.value, self.lastValue) }
9595
}
9696

97+
public struct Optionals: MyProto {
98+
let int1: Bool? = nil
99+
let string1: String?
100+
static var float1: Float?
101+
}
102+
97103
// CHECK: [
98104
// CHECK-NEXT: {
99105
// CHECK-NEXT: "typeName": "ExtractLiterals.Bools",
@@ -131,8 +137,7 @@ public struct PropertyWrappers : MyProto {
131137
// CHECK-NEXT: "isComputed": "false",
132138
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
133139
// CHECK-NEXT: "line": 11,
134-
// CHECK-NEXT: "valueKind": "RawLiteral",
135-
// CHECK-NEXT: "value": "nil"
140+
// CHECK-NEXT: "valueKind": "NilLiteral"
136141
// CHECK-NEXT: }
137142
// CHECK-NEXT: ]
138143
// CHECK-NEXT: },
@@ -617,5 +622,54 @@ public struct PropertyWrappers : MyProto {
617622
// CHECK-NEXT: "valueKind": "Runtime"
618623
// CHECK-NEXT: }
619624
// CHECK-NEXT: ]
625+
// CHECK-NEXT: },
626+
// CHECK-NEXT: {
627+
// CHECK-NEXT: "typeName": "ExtractLiterals.Optionals",
628+
// CHECK-NEXT: "mangledTypeName": "15ExtractLiterals9OptionalsV",
629+
// CHECK-NEXT: "kind": "struct",
630+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
631+
// CHECK-NEXT: "line": 97,
632+
// CHECK-NEXT: "conformances": [
633+
// CHECK-NEXT: "ExtractLiterals.MyProto"
634+
// CHECK-NEXT: ],
635+
// CHECK-NEXT: "allConformances": [
636+
// CHECK-NEXT: {
637+
// CHECK-NEXT: "protocolName": "ExtractLiterals.MyProto",
638+
// CHECK-NEXT: "conformanceDefiningModule": "ExtractLiterals"
639+
// CHECK-NEXT: }
640+
// CHECK-NEXT: ],
641+
// CHECK-NEXT: "associatedTypeAliases": [],
642+
// CHECK-NEXT: "properties": [
643+
// CHECK-NEXT: {
644+
// CHECK-NEXT: "label": "int1",
645+
// CHECK-NEXT: "type": "Swift.Optional<Swift.Bool>",
646+
// CHECK-NEXT: "mangledTypeName": "n/a - deprecated",
647+
// CHECK-NEXT: "isStatic": "false",
648+
// CHECK-NEXT: "isComputed": "false",
649+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
650+
// CHECK-NEXT: "line": 98,
651+
// CHECK-NEXT: "valueKind": "NilLiteral"
652+
// CHECK-NEXT: },
653+
// CHECK-NEXT: {
654+
// CHECK-NEXT: "label": "string1",
655+
// CHECK-NEXT: "type": "Swift.Optional<Swift.String>",
656+
// CHECK-NEXT: "mangledTypeName": "n/a - deprecated",
657+
// CHECK-NEXT: "isStatic": "false",
658+
// CHECK-NEXT: "isComputed": "false",
659+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
660+
// CHECK-NEXT: "line": 99,
661+
// CHECK-NEXT: "valueKind": "Runtime"
662+
// CHECK-NEXT: },
663+
// CHECK-NEXT: {
664+
// CHECK-NEXT: "label": "float1",
665+
// CHECK-NEXT: "type": "Swift.Optional<Swift.Float>",
666+
// CHECK-NEXT: "mangledTypeName": "n/a - deprecated",
667+
// CHECK-NEXT: "isStatic": "true",
668+
// CHECK-NEXT: "isComputed": "false",
669+
// CHECK-NEXT: "file": "{{.*}}test{{/|\\\\}}ConstExtraction{{/|\\\\}}ExtractLiterals.swift",
670+
// CHECK-NEXT: "line": 100,
671+
// CHECK-NEXT: "valueKind": "NilLiteral"
672+
// CHECK-NEXT: }
673+
// CHECK-NEXT: ]
620674
// CHECK-NEXT: }
621675
// CHECK-NEXT:]

0 commit comments

Comments
 (0)