Skip to content

Commit 7e84c84

Browse files
author
James Paolantonio
committed
[Const extract] Extract static function calls
1 parent ad00063 commit 7e84c84

File tree

4 files changed

+147
-4
lines changed

4 files changed

+147
-4
lines changed

include/swift/AST/ConstTypeInfo.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class CompileTimeValue {
3939
Type,
4040
KeyPath,
4141
FunctionCall,
42+
StaticFunctionCall,
4243
MemberReference,
4344
InterpolatedString,
4445
Runtime
@@ -392,6 +393,28 @@ class FunctionCallValue : public CompileTimeValue {
392393
std::optional<std::vector<FunctionParameter>> Parameters;
393394
};
394395

396+
/// A static function reference representation such as
397+
/// let foo = MyStruct.bar(item: "")
398+
/// let foo = MyStruct.bar()
399+
class StaticFunctionCallValue : public CompileTimeValue {
400+
public:
401+
StaticFunctionCallValue(swift::Type Type,
402+
std::vector<FunctionParameter> Parameters)
403+
: CompileTimeValue(ValueKind::StaticFunctionCall), Type(Type),
404+
Parameters(Parameters) {}
405+
406+
static bool classof(const CompileTimeValue *T) {
407+
return T->getKind() == ValueKind::StaticFunctionCall;
408+
}
409+
410+
swift::Type getType() const { return Type; }
411+
std::vector<FunctionParameter> getParameters() const { return Parameters; }
412+
413+
private:
414+
swift::Type Type;
415+
std::vector<FunctionParameter> Parameters;
416+
};
417+
395418
/// A member reference representation such as
396419
/// let foo = MyStruct.bar
397420
class MemberReferenceValue : public CompileTimeValue {

lib/ConstExtract/ConstExtract.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,12 +313,27 @@ static std::shared_ptr<CompileTimeValue> extractCompileTimeValue(Expr *expr) {
313313
auto fn = dotSyntaxCallExpr->getFn();
314314
if (fn->getKind() == ExprKind::DeclRef) {
315315
auto declRefExpr = cast<DeclRefExpr>(fn);
316-
auto caseName =
316+
auto baseIdentifierName =
317317
declRefExpr->getDecl()->getName().getBaseIdentifier().str().str();
318318

319319
std::vector<FunctionParameter> parameters =
320320
extractFunctionArguments(callExpr->getArgs());
321-
return std::make_shared<EnumValue>(caseName, parameters);
321+
322+
auto declRef = dotSyntaxCallExpr->getFn()->getReferencedDecl();
323+
switch (declRef.getDecl()->getKind()) {
324+
case DeclKind::EnumElement: {
325+
return std::make_shared<EnumValue>(baseIdentifierName, parameters);
326+
}
327+
328+
case DeclKind::Func: {
329+
return std::make_shared<StaticFunctionCallValue>(
330+
callExpr->getType(), parameters);
331+
}
332+
333+
default: {
334+
break;
335+
}
336+
}
322337
}
323338
}
324339

@@ -836,6 +851,26 @@ void writeValue(llvm::json::OStream &JSON,
836851
break;
837852
}
838853

854+
case CompileTimeValue::ValueKind::StaticFunctionCall: {
855+
auto staticFunctionCallValue = cast<StaticFunctionCallValue>(value);
856+
857+
JSON.attribute("valueKind", "StaticFunctionCall");
858+
JSON.attributeObject("value", [&]() {
859+
JSON.attribute("type", toFullyQualifiedTypeNameString(
860+
staticFunctionCallValue->getType()));
861+
JSON.attributeArray("arguments", [&] {
862+
for (auto FP : staticFunctionCallValue->getParameters()) {
863+
JSON.object([&] {
864+
JSON.attribute("label", FP.Label);
865+
JSON.attribute("type", toFullyQualifiedTypeNameString(FP.Type));
866+
writeValue(JSON, FP.Value);
867+
});
868+
}
869+
});
870+
});
871+
break;
872+
}
873+
839874
case CompileTimeValue::ValueKind::MemberReference: {
840875
auto memberReferenceValue = cast<MemberReferenceValue>(value);
841876
JSON.attribute("valueKind", "MemberReference");
@@ -846,6 +881,7 @@ void writeValue(llvm::json::OStream &JSON,
846881
});
847882
break;
848883
}
884+
849885
case CompileTimeValue::ValueKind::InterpolatedString: {
850886
auto interpolatedStringValue = cast<InterpolatedStringLiteralValue>(value);
851887
JSON.attribute("valueKind", "InterpolatedStringLiteral");

test/ConstExtraction/ExtractCalls.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ public struct Bat {
115115
// CHECK-NEXT: "name": "adder",
116116
// CHECK-NEXT: "arguments": [
117117
// CHECK-NEXT: {
118-
// CHECK-NEXT: "label": "",
119-
// CHECK-NEXT: "type": "Swift.Int",
118+
// CHECK-NEXT: "label": "",
119+
// CHECK-NEXT: "type": "Swift.Int",
120120
// CHECK-NEXT: "valueKind": "RawLiteral",
121121
// CHECK-NEXT: "value": "2"
122122
// CHECK-NEXT: },
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: echo "[MyProto]" > %t/protocols.json
3+
4+
// RUN: %target-swift-frontend -typecheck -emit-const-values-path %t/ExtractStaticFunctions.swiftconstvalues -const-gather-protocols-file %t/protocols.json -primary-file %s
5+
// RUN: cat %t/ExtractStaticFunctions.swiftconstvalues 2>&1 | %FileCheck %s
6+
7+
protocol MyProto {}
8+
protocol Foo {}
9+
10+
enum Bar: Foo {
11+
case one
12+
case two(item: String)
13+
}
14+
15+
struct Baz: Foo {
16+
static var one: Baz {
17+
Baz()
18+
}
19+
20+
static func two(item: String) -> Baz {
21+
return Baz()
22+
}
23+
24+
static func three() -> Baz {
25+
return Baz()
26+
}
27+
}
28+
29+
struct Statics: MyProto {
30+
var bar1 = Bar.one
31+
var bar2 = Bar.two(item: "bar")
32+
var baz1 = Baz.one
33+
var baz2 = Baz.two(item: "baz")
34+
var baz3 = Baz.three()
35+
}
36+
37+
// CHECK: "label": "bar1",
38+
// CHECK-NEXT: "type": "ExtractStaticFunctions.Bar",
39+
// CHECK: "valueKind": "Enum",
40+
// CHECK-NEXT: "value": {
41+
// CHECK-NEXT: "name": "one"
42+
// CHECK-NEXT: }
43+
// CHECK: "label": "bar2",
44+
// CHECK-NEXT: "type": "ExtractStaticFunctions.Bar",
45+
// CHECK: "valueKind": "Enum",
46+
// CHECK-NEXT: "value": {
47+
// CHECK-NEXT: "name": "two",
48+
// CHECK-NEXT: "arguments": [
49+
// CHECK-NEXT: {
50+
// CHECK-NEXT: "label": "item",
51+
// CHECK-NEXT: "type": "Swift.String",
52+
// CHECK-NEXT: "valueKind": "RawLiteral",
53+
// CHECK-NEXT: "value": "bar"
54+
// CHECK-NEXT: }
55+
// CHECK-NEXT: ]
56+
// CHECK-NEXT: }
57+
// CHECK: "label": "baz1",
58+
// CHECK-NEXT: "type": "ExtractStaticFunctions.Baz",
59+
// CHECK: "valueKind": "MemberReference"
60+
// CHECK-NEXT: "value": {
61+
// CHECK-NEXT: "baseType": "ExtractStaticFunctions.Baz",
62+
// CHECK-NEXT: "memberLabel": "one"
63+
// CHECK-NEXT: }
64+
// CHECK: "label": "baz2",
65+
// CHECK-NEXT: "type": "ExtractStaticFunctions.Baz",
66+
// CHECK: "valueKind": "StaticFunctionCall",
67+
// CHECK-NEXT: "value": {
68+
// CHECK-NEXT: "type": "ExtractStaticFunctions.Baz",
69+
// CHECK-NEXT: "arguments": [
70+
// CHECK-NEXT: {
71+
// CHECK-NEXT: "label": "item",
72+
// CHECK-NEXT: "type": "Swift.String",
73+
// CHECK-NEXT: "valueKind": "RawLiteral",
74+
// CHECK-NEXT: "value": "baz"
75+
// CHECK-NEXT: }
76+
// CHECK-NEXT: ]
77+
// CHECK-NEXT: }
78+
// CHECK: "label": "baz3",
79+
// CHECK-NEXT: "type": "ExtractStaticFunctions.Baz",
80+
// CHECK: "valueKind": "StaticFunctionCall",
81+
// CHECK-NEXT: "value": {
82+
// CHECK-NEXT: "type": "ExtractStaticFunctions.Baz",
83+
// CHECK-NEXT: "arguments": []
84+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)