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#ifndef SKSL_METHODREFERENCE
9#define SKSL_METHODREFERENCE
10
11#include "src/sksl/SkSLContext.h"
12#include "src/sksl/ir/SkSLExpression.h"
13
14namespace SkSL {
15
16class FunctionDeclaration;
17
18/**
19 * An identifier referring to a method name, along with an instance for the call.
20 * This is an intermediate value: MethodReferences are always eventually replaced by FunctionCalls
21 * in valid programs.
22 *
23 * Method calls are only supported on effect-child types, and they all resolve to intrinsics
24 * prefixed with '$', and taking the 'self' object as the last parameter. For example:
25 *
26 *   uniform shader child;
27 *   ...
28 *   child.eval(xy)  -->  $eval(xy, child)
29 */
30class MethodReference final : public Expression {
31public:
32    inline static constexpr Kind kExpressionKind = Kind::kMethodReference;
33
34    MethodReference(const Context& context,
35                    int line,
36                    std::unique_ptr<Expression> self,
37                    std::vector<const FunctionDeclaration*> functions)
38            : INHERITED(line, kExpressionKind, context.fTypes.fInvalid.get())
39            , fSelf(std::move(self))
40            , fFunctions(std::move(functions)) {}
41
42    std::unique_ptr<Expression>& self() { return fSelf; }
43    const std::unique_ptr<Expression>& self() const { return fSelf; }
44
45    const std::vector<const FunctionDeclaration*>& functions() const { return fFunctions; }
46
47    bool hasProperty(Property property) const override { return false; }
48
49    std::unique_ptr<Expression> clone() const override {
50        return std::unique_ptr<Expression>(new MethodReference(
51                fLine, this->self()->clone(), this->functions(), &this->type()));
52    }
53
54    String description() const override {
55        return String("<method>");
56    }
57
58private:
59    MethodReference(int line,
60                    std::unique_ptr<Expression> self,
61                    std::vector<const FunctionDeclaration*> functions,
62                    const Type* type)
63            : INHERITED(line, kExpressionKind, type)
64            , fSelf(std::move(self))
65            , fFunctions(std::move(functions)) {}
66
67    std::unique_ptr<Expression> fSelf;
68    std::vector<const FunctionDeclaration*> fFunctions;
69
70    using INHERITED = Expression;
71};
72
73}  // namespace SkSL
74
75#endif
76