2 * Copyright 2016 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef SKSL_CONSTRUCTOR
9 #define SKSL_CONSTRUCTOR
11 #include "include/core/SkSpan.h"
12 #include "src/sksl/ir/SkSLExpression.h"
17 * Base class representing a constructor with unknown arguments.
19 class AnyConstructor : public Expression {
21 AnyConstructor(Position pos, Kind kind, const Type* type)
22 : INHERITED(pos, kind, type) {}
24 virtual SkSpan<std::unique_ptr<Expression>> argumentSpan() = 0;
25 virtual SkSpan<const std::unique_ptr<Expression>> argumentSpan() const = 0;
27 bool hasProperty(Property property) const override {
28 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) {
29 if (arg->hasProperty(property)) {
36 std::string description() const override {
37 std::string result = this->type().description() + "(";
38 const char* separator = "";
39 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) {
41 result += arg->description();
48 const Type& componentType() const {
49 return this->type().componentType();
52 bool isCompileTimeConstant() const override {
53 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) {
54 if (!arg->isCompileTimeConstant()) {
61 bool isConstantOrUniform() const override {
62 for (const std::unique_ptr<Expression>& arg : this->argumentSpan()) {
63 if (!arg->isConstantOrUniform()) {
70 bool supportsConstantValues() const override { return true; }
71 std::optional<double> getConstantValue(int n) const override;
73 ComparisonResult compareConstant(const Expression& other) const override;
76 using INHERITED = Expression;
80 * Base class representing a constructor that takes a single argument.
82 class SingleArgumentConstructor : public AnyConstructor {
84 SingleArgumentConstructor(Position pos, Kind kind, const Type* type,
85 std::unique_ptr<Expression> argument)
86 : INHERITED(pos, kind, type)
87 , fArgument(std::move(argument)) {}
89 std::unique_ptr<Expression>& argument() {
93 const std::unique_ptr<Expression>& argument() const {
97 SkSpan<std::unique_ptr<Expression>> argumentSpan() final {
98 return {&fArgument, 1};
101 SkSpan<const std::unique_ptr<Expression>> argumentSpan() const final {
102 return {&fArgument, 1};
106 std::unique_ptr<Expression> fArgument;
108 using INHERITED = AnyConstructor;
112 * Base class representing a constructor that takes an array of arguments.
114 class MultiArgumentConstructor : public AnyConstructor {
116 MultiArgumentConstructor(Position pos, Kind kind, const Type* type,
117 ExpressionArray arguments)
118 : INHERITED(pos, kind, type)
119 , fArguments(std::move(arguments)) {}
121 ExpressionArray& arguments() {
125 const ExpressionArray& arguments() const {
129 SkSpan<std::unique_ptr<Expression>> argumentSpan() final {
130 return {&fArguments.front(), fArguments.size()};
133 SkSpan<const std::unique_ptr<Expression>> argumentSpan() const final {
134 return {&fArguments.front(), fArguments.size()};
138 ExpressionArray fArguments;
140 using INHERITED = AnyConstructor;
144 * Converts any GLSL constructor, such as `float2(x, y)` or `mat3x3(otherMat)` or `int[2](0, i)`, to
145 * an SkSL expression.
147 * Vector constructors must always consist of either exactly 1 scalar, or a collection of vectors
148 * and scalars totaling exactly the right number of scalar components.
150 * Matrix constructors must always consist of either exactly 1 scalar, exactly 1 matrix, or a
151 * collection of vectors and scalars totaling exactly the right number of scalar components.
153 * Array constructors must always contain the proper number of array elements (matching the Type).
155 namespace Constructor {
156 // Creates, typechecks and simplifies constructor expressions. Reports errors via the
157 // ErrorReporter. This can return null on error, so be careful. There are several different
158 // Constructor expression types; this class chooses the proper one based on context, e.g.
159 // `ConstructorCompound`, `ConstructorScalarCast`, or `ConstructorMatrixResize`.
160 std::unique_ptr<Expression> Convert(const Context& context,
163 ExpressionArray args);