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