• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Tint Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/ast/struct_block_decoration.h"
16 #include "src/resolver/resolver.h"
17 #include "src/resolver/resolver_test_helper.h"
18 
19 #include "gmock/gmock.h"
20 
21 namespace tint {
22 namespace resolver {
23 namespace {
24 
25 // Helpers and typedefs
26 template <typename T>
27 using DataType = builder::DataType<T>;
28 template <typename T>
29 using vec2 = builder::vec2<T>;
30 template <typename T>
31 using vec3 = builder::vec3<T>;
32 template <typename T>
33 using vec4 = builder::vec4<T>;
34 template <typename T>
35 using mat2x2 = builder::mat2x2<T>;
36 template <typename T>
37 using mat3x3 = builder::mat3x3<T>;
38 template <typename T>
39 using mat4x4 = builder::mat4x4<T>;
40 template <typename T>
41 using alias = builder::alias<T>;
42 using f32 = builder::f32;
43 using i32 = builder::i32;
44 using u32 = builder::u32;
45 
46 struct ResolverInferredTypeTest : public resolver::TestHelper,
47                                   public testing::Test {};
48 
49 struct Params {
50   builder::ast_expr_func_ptr create_value;
51   builder::sem_type_func_ptr create_expected_type;
52 };
53 
54 template <typename T>
ParamsFor()55 constexpr Params ParamsFor() {
56   return Params{DataType<T>::Expr, DataType<T>::Sem};
57 }
58 
59 Params all_cases[] = {
60     ParamsFor<bool>(),                //
61     ParamsFor<u32>(),                 //
62     ParamsFor<i32>(),                 //
63     ParamsFor<f32>(),                 //
64     ParamsFor<vec3<bool>>(),          //
65     ParamsFor<vec3<i32>>(),           //
66     ParamsFor<vec3<u32>>(),           //
67     ParamsFor<vec3<f32>>(),           //
68     ParamsFor<mat3x3<f32>>(),         //
69     ParamsFor<alias<bool>>(),         //
70     ParamsFor<alias<u32>>(),          //
71     ParamsFor<alias<i32>>(),          //
72     ParamsFor<alias<f32>>(),          //
73     ParamsFor<alias<vec3<bool>>>(),   //
74     ParamsFor<alias<vec3<i32>>>(),    //
75     ParamsFor<alias<vec3<u32>>>(),    //
76     ParamsFor<alias<vec3<f32>>>(),    //
77     ParamsFor<alias<mat3x3<f32>>>(),  //
78 };
79 
80 using ResolverInferredTypeParamTest = ResolverTestWithParam<Params>;
81 
TEST_P(ResolverInferredTypeParamTest,GlobalLet_Pass)82 TEST_P(ResolverInferredTypeParamTest, GlobalLet_Pass) {
83   auto& params = GetParam();
84 
85   auto* expected_type = params.create_expected_type(*this);
86 
87   // let a = <type constructor>;
88   auto* ctor_expr = params.create_value(*this, 0);
89   auto* var = GlobalConst("a", nullptr, ctor_expr);
90   WrapInFunction();
91 
92   EXPECT_TRUE(r()->Resolve()) << r()->error();
93   EXPECT_EQ(TypeOf(var), expected_type);
94 }
95 
TEST_P(ResolverInferredTypeParamTest,GlobalVar_Fail)96 TEST_P(ResolverInferredTypeParamTest, GlobalVar_Fail) {
97   auto& params = GetParam();
98 
99   // var a = <type constructor>;
100   auto* ctor_expr = params.create_value(*this, 0);
101   Global(Source{{12, 34}}, "a", nullptr, ast::StorageClass::kPrivate,
102          ctor_expr);
103   WrapInFunction();
104 
105   EXPECT_FALSE(r()->Resolve());
106   EXPECT_EQ(r()->error(),
107             "12:34 error: global var declaration must specify a type");
108 }
109 
TEST_P(ResolverInferredTypeParamTest,LocalLet_Pass)110 TEST_P(ResolverInferredTypeParamTest, LocalLet_Pass) {
111   auto& params = GetParam();
112 
113   auto* expected_type = params.create_expected_type(*this);
114 
115   // let a = <type constructor>;
116   auto* ctor_expr = params.create_value(*this, 0);
117   auto* var = Const("a", nullptr, ctor_expr);
118   WrapInFunction(var);
119 
120   EXPECT_TRUE(r()->Resolve()) << r()->error();
121   EXPECT_EQ(TypeOf(var), expected_type);
122 }
123 
TEST_P(ResolverInferredTypeParamTest,LocalVar_Pass)124 TEST_P(ResolverInferredTypeParamTest, LocalVar_Pass) {
125   auto& params = GetParam();
126 
127   auto* expected_type = params.create_expected_type(*this);
128 
129   // var a = <type constructor>;
130   auto* ctor_expr = params.create_value(*this, 0);
131   auto* var = Var("a", nullptr, ast::StorageClass::kFunction, ctor_expr);
132   WrapInFunction(var);
133 
134   EXPECT_TRUE(r()->Resolve()) << r()->error();
135   EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
136 }
137 
138 INSTANTIATE_TEST_SUITE_P(ResolverTest,
139                          ResolverInferredTypeParamTest,
140                          testing::ValuesIn(all_cases));
141 
TEST_F(ResolverInferredTypeTest,InferArray_Pass)142 TEST_F(ResolverInferredTypeTest, InferArray_Pass) {
143   auto* type = ty.array(ty.u32(), 10);
144   auto* expected_type =
145       create<sem::Array>(create<sem::U32>(), 10, 4, 4 * 10, 4, 4);
146 
147   auto* ctor_expr = Construct(type);
148   auto* var = Var("a", nullptr, ast::StorageClass::kFunction, ctor_expr);
149   WrapInFunction(var);
150 
151   EXPECT_TRUE(r()->Resolve()) << r()->error();
152   EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
153 }
154 
TEST_F(ResolverInferredTypeTest,InferStruct_Pass)155 TEST_F(ResolverInferredTypeTest, InferStruct_Pass) {
156   auto* member = Member("x", ty.i32());
157   auto* str = Structure("S", {member}, {create<ast::StructBlockDecoration>()});
158 
159   auto* expected_type = create<sem::Struct>(
160       str, str->name,
161       sem::StructMemberList{create<sem::StructMember>(
162           member, member->symbol, create<sem::I32>(), 0, 0, 0, 4)},
163       0, 4, 4);
164 
165   auto* ctor_expr = Construct(ty.Of(str));
166 
167   auto* var = Var("a", nullptr, ast::StorageClass::kFunction, ctor_expr);
168   WrapInFunction(var);
169 
170   EXPECT_TRUE(r()->Resolve()) << r()->error();
171   EXPECT_EQ(TypeOf(var)->UnwrapRef(), expected_type);
172 }
173 
174 }  // namespace
175 }  // namespace resolver
176 }  // namespace tint
177