Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkSLConstructorStruct.cpp
Go to the documentation of this file.
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
9
10#include "include/core/SkSpan.h"
16#include "src/sksl/SkSLString.h"
18
19#include <string>
20
21namespace SkSL {
22
23std::unique_ptr<Expression> ConstructorStruct::Convert(const Context& context,
25 const Type& type,
27 SkASSERTF(type.isStruct() && type.fields().size() > 0, "%s", type.description().c_str());
28
29 // Check that the number of constructor arguments matches the array size.
30 if (type.fields().size() != SkToSizeT(args.size())) {
31 context.fErrors->error(pos,
32 String::printf("invalid arguments to '%s' constructor "
33 "(expected %zu elements, but found %d)",
34 type.displayName().c_str(), type.fields().size(),
35 args.size()));
36 return nullptr;
37 }
38
39 // A struct with atomic members cannot be constructed.
41 context.fErrors->error(
42 pos,
43 String::printf("construction of struct type '%s' with atomic member is not allowed",
44 type.displayName().c_str()));
45 return nullptr;
46 }
47
48 // Convert each constructor argument to the struct's field type.
49 for (int index=0; index<args.size(); ++index) {
50 std::unique_ptr<Expression>& argument = args[index];
51 const Field& field = type.fields()[index];
52
53 argument = field.fType->coerceExpression(std::move(argument), context);
54 if (!argument) {
55 return nullptr;
56 }
57 }
58
59 return ConstructorStruct::Make(context, pos, type, std::move(args));
60}
61
62[[maybe_unused]] static bool arguments_match_field_types(const ExpressionArray& args,
63 const Type& type) {
64 SkASSERT(type.fields().size() == SkToSizeT(args.size()));
65
66 for (int index = 0; index < args.size(); ++index) {
67 const std::unique_ptr<Expression>& argument = args[index];
68 const Field& field = type.fields()[index];
69 if (!argument->type().matches(*field.fType)) {
70 return false;
71 }
72 }
73
74 return true;
75}
76
77std::unique_ptr<Expression> ConstructorStruct::Make(const Context& context,
79 const Type& type,
84 return std::make_unique<ConstructorStruct>(pos, type, std::move(args));
85}
86
87} // namespace SkSL
SkPoint pos
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SkASSERTF(cond, fmt,...)
Definition SkAssert.h:117
constexpr size_t SkToSizeT(S x)
Definition SkTo.h:31
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, ExpressionArray args)
static std::unique_ptr< Expression > Convert(const Context &context, Position pos, const Type &type, ExpressionArray args)
ErrorReporter * fErrors
Definition SkSLContext.h:36
void error(Position position, std::string_view msg)
virtual const Type & type() const
bool isAllowedInES2(const Context &context) const
std::unique_ptr< Expression > coerceExpression(std::unique_ptr< Expression > expr, const Context &context) const
virtual SkSpan< const Field > fields() const
Definition SkSLType.h:469
std::string description() const override
Definition SkSLType.h:238
virtual bool isOrContainsAtomic() const
Definition SkSLType.h:586
std::string displayName() const
Definition SkSLType.h:234
virtual bool isStruct() const
Definition SkSLType.h:540
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
static bool arguments_match_field_types(const ExpressionArray &args, const Type &type)
const Type * fType
Definition SkSLType.h:88