1 /*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "src/sksl/SkSLContext.h"
9 #include "src/sksl/ir/SkSLChildCall.h"
10
11 namespace SkSL {
12
hasProperty(Property property) const13 bool ChildCall::hasProperty(Property property) const {
14 for (const auto& arg : this->arguments()) {
15 if (arg->hasProperty(property)) {
16 return true;
17 }
18 }
19 return false;
20 }
21
clone() const22 std::unique_ptr<Expression> ChildCall::clone() const {
23 ExpressionArray cloned;
24 cloned.reserve_back(this->arguments().size());
25 for (const std::unique_ptr<Expression>& arg : this->arguments()) {
26 cloned.push_back(arg->clone());
27 }
28 return std::make_unique<ChildCall>(fLine, &this->type(), &this->child(), std::move(cloned));
29 }
30
description() const31 String ChildCall::description() const {
32 String result = String(this->child().name()) + ".eval(";
33 String separator;
34 for (const std::unique_ptr<Expression>& arg : this->arguments()) {
35 result += separator;
36 result += arg->description();
37 separator = ", ";
38 }
39 result += ")";
40 return result;
41 }
42
call_signature_is_valid(const Context & context,const Variable & child,const ExpressionArray & arguments)43 [[maybe_unused]] static bool call_signature_is_valid(const Context& context,
44 const Variable& child,
45 const ExpressionArray& arguments) {
46 const Type* half4 = context.fTypes.fHalf4.get();
47 const Type* float2 = context.fTypes.fFloat2.get();
48
49 auto params = [&]() -> SkSTArray<2, const Type*> {
50 switch (child.type().typeKind()) {
51 case Type::TypeKind::kBlender: return { half4, half4 };
52 case Type::TypeKind::kColorFilter: return { half4 };
53 case Type::TypeKind::kShader: return { float2 };
54 default:
55 SkUNREACHABLE;
56 }
57 }();
58
59 if (params.size() != arguments.size()) {
60 return false;
61 }
62 for (size_t i = 0; i < arguments.size(); i++) {
63 if (arguments[i]->type() != *params[i]) {
64 return false;
65 }
66 }
67 return true;
68 }
69
Make(const Context & context,int line,const Type * returnType,const Variable & child,ExpressionArray arguments)70 std::unique_ptr<Expression> ChildCall::Make(const Context& context,
71 int line,
72 const Type* returnType,
73 const Variable& child,
74 ExpressionArray arguments) {
75 SkASSERT(call_signature_is_valid(context, child, arguments));
76 return std::make_unique<ChildCall>(line, returnType, &child, std::move(arguments));
77 }
78
79 } // namespace SkSL
80