/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SKSL_METHODREFERENCE #define SKSL_METHODREFERENCE #include "src/sksl/SkSLBuiltinTypes.h" #include "src/sksl/SkSLContext.h" #include "src/sksl/ir/SkSLExpression.h" namespace SkSL { class FunctionDeclaration; /** * An identifier referring to a method name, along with an instance for the call. * This is an intermediate value: MethodReferences are always eventually replaced by FunctionCalls * in valid programs. * * Method calls are only supported on effect-child types, and they all resolve to intrinsics * prefixed with '$', and taking the 'self' object as the last parameter. For example: * * uniform shader child; * ... * child.eval(xy) --> $eval(xy, child) */ class MethodReference final : public Expression { public: inline static constexpr Kind kIRNodeKind = Kind::kMethodReference; MethodReference(const Context& context, Position pos, std::unique_ptr self, const FunctionDeclaration* overloadChain) : INHERITED(pos, kIRNodeKind, context.fTypes.fInvalid.get()) , fSelf(std::move(self)) , fOverloadChain(overloadChain) {} std::unique_ptr& self() { return fSelf; } const std::unique_ptr& self() const { return fSelf; } const FunctionDeclaration* overloadChain() const { return fOverloadChain; } std::unique_ptr clone(Position pos) const override { return std::unique_ptr(new MethodReference( pos, this->self()->clone(), this->overloadChain(), &this->type())); } std::string description(OperatorPrecedence) const override { return ""; } private: MethodReference(Position pos, std::unique_ptr self, const FunctionDeclaration* overloadChain, const Type* type) : INHERITED(pos, kIRNodeKind, type) , fSelf(std::move(self)) , fOverloadChain(overloadChain) {} std::unique_ptr fSelf; const FunctionDeclaration* fOverloadChain; using INHERITED = Expression; }; } // namespace SkSL #endif