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/ir/SkSLConstructorArray.h"
9
10 namespace SkSL {
11
Convert(const Context & context,int offset,const Type & type,ExpressionArray args)12 std::unique_ptr<Expression> ConstructorArray::Convert(const Context& context,
13 int offset,
14 const Type& type,
15 ExpressionArray args) {
16 SkASSERTF(type.isArray() && type.columns() > 0, "%s", type.description().c_str());
17
18 // ES2 doesn't support first-class array types.
19 if (context.fConfig->strictES2Mode()) {
20 context.fErrors.error(offset, "construction of array type '" + type.displayName() +
21 "' is not supported");
22 return nullptr;
23 }
24
25 // Check that the number of constructor arguments matches the array size.
26 if (type.columns() != args.count()) {
27 context.fErrors.error(offset, String::printf("invalid arguments to '%s' constructor "
28 "(expected %d elements, but found %d)",
29 type.displayName().c_str(), type.columns(),
30 args.count()));
31 return nullptr;
32 }
33
34 // Convert each constructor argument to the array's component type.
35 const Type& baseType = type.componentType();
36 for (std::unique_ptr<Expression>& argument : args) {
37 argument = baseType.coerceExpression(std::move(argument), context);
38 if (!argument) {
39 return nullptr;
40 }
41 }
42
43 return ConstructorArray::Make(context, offset, type, std::move(args));
44 }
45
Make(const Context & context,int offset,const Type & type,ExpressionArray args)46 std::unique_ptr<Expression> ConstructorArray::Make(const Context& context,
47 int offset,
48 const Type& type,
49 ExpressionArray args) {
50 SkASSERT(!context.fConfig->strictES2Mode());
51 SkASSERT(type.columns() == args.count());
52 SkASSERT(std::all_of(args.begin(), args.end(), [&](const std::unique_ptr<Expression>& arg) {
53 return type.componentType() == arg->type();
54 }));
55
56 return std::make_unique<ConstructorArray>(offset, type, std::move(args));
57 }
58
59 } // namespace SkSL
60