1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2021 Google LLC.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/private/SkSLIRNode.h"
9cb93a386Sopenharmony_ci#include "include/sksl/DSL.h"
10cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h"
11cb93a386Sopenharmony_ci#include "src/gpu/GrGpu.h"
12cb93a386Sopenharmony_ci#include "src/sksl/SkSLCompiler.h"
13cb93a386Sopenharmony_ci#include "src/sksl/SkSLThreadContext.h"
14cb93a386Sopenharmony_ci#include "src/sksl/dsl/priv/DSLWriter.h"
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci#include "tests/Test.h"
17cb93a386Sopenharmony_ci
18cb93a386Sopenharmony_ci#include <limits>
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_ciusing namespace SkSL::dsl;
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_ci#if defined(__GNUC__) || defined(__clang__)
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ciclass ExpectErrorLineNumber : public SkSL::ErrorReporter {
25cb93a386Sopenharmony_cipublic:
26cb93a386Sopenharmony_ci    ExpectErrorLineNumber(skiatest::Reporter* reporter, const char* msg, int line)
27cb93a386Sopenharmony_ci        : fMsg(msg)
28cb93a386Sopenharmony_ci        , fLine(line)
29cb93a386Sopenharmony_ci        , fReporter(reporter)
30cb93a386Sopenharmony_ci        , fOldReporter(&GetErrorReporter()) {
31cb93a386Sopenharmony_ci        SetErrorReporter(this);
32cb93a386Sopenharmony_ci    }
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ci    ~ExpectErrorLineNumber() override {
35cb93a386Sopenharmony_ci        REPORTER_ASSERT(fReporter, !fMsg);
36cb93a386Sopenharmony_ci        SetErrorReporter(fOldReporter);
37cb93a386Sopenharmony_ci    }
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ci    void handleError(skstd::string_view msg, SkSL::PositionInfo pos) override {
40cb93a386Sopenharmony_ci        REPORTER_ASSERT(fReporter, msg == fMsg,
41cb93a386Sopenharmony_ci                "Error mismatch: expected:\n%sbut received:\n%.*s", fMsg, (int)msg.length(),
42cb93a386Sopenharmony_ci                msg.data());
43cb93a386Sopenharmony_ci        REPORTER_ASSERT(fReporter, pos.line() == fLine,
44cb93a386Sopenharmony_ci                "Line number mismatch: expected %d, but received %d\n", fLine, pos.line());
45cb93a386Sopenharmony_ci        SkSL::ThreadContext::Compiler().handleError(msg, pos);
46cb93a386Sopenharmony_ci        fMsg = nullptr;
47cb93a386Sopenharmony_ci    }
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ciprivate:
50cb93a386Sopenharmony_ci    const char* fMsg;
51cb93a386Sopenharmony_ci    int fLine;
52cb93a386Sopenharmony_ci    skiatest::Reporter* fReporter;
53cb93a386Sopenharmony_ci    ErrorReporter* fOldReporter;
54cb93a386Sopenharmony_ci};
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_MOCK_CONTEXT(DSLErrorLineNumbers, r, ctxInfo) {
57cb93a386Sopenharmony_ci    Start(ctxInfo.directContext()->priv().getGpu()->shaderCompiler());
58cb93a386Sopenharmony_ci    {
59cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "type mismatch: '+' cannot operate on 'float', 'bool'",
60cb93a386Sopenharmony_ci                                    __LINE__ + 1);
61cb93a386Sopenharmony_ci        (Float(1) + true).release();
62cb93a386Sopenharmony_ci    }
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_ci    {
65cb93a386Sopenharmony_ci        Var a(kBool_Type);
66cb93a386Sopenharmony_ci        DSLWriter::MarkDeclared(a);
67cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "type mismatch: '=' cannot operate on 'bool', 'float'",
68cb93a386Sopenharmony_ci                                    __LINE__ + 1);
69cb93a386Sopenharmony_ci        (a = 5.0f).release();
70cb93a386Sopenharmony_ci    }
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci    {
73cb93a386Sopenharmony_ci        Var a(Array(kInt_Type, 5));
74cb93a386Sopenharmony_ci        DSLWriter::MarkDeclared(a);
75cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "expected 'int', but found 'bool'", __LINE__ + 1);
76cb93a386Sopenharmony_ci        (a[true]).release();
77cb93a386Sopenharmony_ci    }
78cb93a386Sopenharmony_ci
79cb93a386Sopenharmony_ci    {
80cb93a386Sopenharmony_ci        Var a(Array(kInt_Type, 5));
81cb93a386Sopenharmony_ci        DSLWriter::MarkDeclared(a);
82cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "'++' cannot operate on 'int[5]'", __LINE__ + 1);
83cb93a386Sopenharmony_ci        (++a).release();
84cb93a386Sopenharmony_ci    }
85cb93a386Sopenharmony_ci
86cb93a386Sopenharmony_ci    {
87cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "expected 'bool', but found 'int'", __LINE__ + 1);
88cb93a386Sopenharmony_ci        Do(Discard(), 5).release();
89cb93a386Sopenharmony_ci    }
90cb93a386Sopenharmony_ci
91cb93a386Sopenharmony_ci    {
92cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "expected 'bool', but found 'int'", __LINE__ + 1);
93cb93a386Sopenharmony_ci        For(DSLStatement(), 5, DSLExpression(), Block()).release();
94cb93a386Sopenharmony_ci    }
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci    {
97cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "expected 'bool', but found 'int'", __LINE__ + 1);
98cb93a386Sopenharmony_ci        If(5, Discard()).release();
99cb93a386Sopenharmony_ci    }
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ci    {
102cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "expected 'bool', but found 'int'", __LINE__ + 1);
103cb93a386Sopenharmony_ci        While(5, Discard()).release();
104cb93a386Sopenharmony_ci    }
105cb93a386Sopenharmony_ci
106cb93a386Sopenharmony_ci    {
107cb93a386Sopenharmony_ci        ExpectErrorLineNumber error(r, "no match for abs(bool)", __LINE__ + 1);
108cb93a386Sopenharmony_ci        Abs(true).release();
109cb93a386Sopenharmony_ci    }
110cb93a386Sopenharmony_ci    End();
111cb93a386Sopenharmony_ci}
112cb93a386Sopenharmony_ci
113cb93a386Sopenharmony_ci#endif // defined(__GNUC__) || defined(__clang__)
114