Add DecoratedVariable tests
This CL adds tests for decorated variable and updates the API to be
slightly nicer.
Bug: tint:11
Change-Id: I0bd5b8b6e6f682dc9d405e02e51d5dbcaeccc5f3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/16465
Commit-Queue: Sarah Mashayekhi <sarahmashay@google.com>
Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6846c12..e5f97e9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -205,6 +205,7 @@
ast/cast_expression_test.cc
ast/const_initializer_expression_test.cc
ast/continue_statement_test.cc
+ ast/decorated_variable_test.cc
ast/entry_point_test.cc
ast/import_test.cc
ast/int_literal_test.cc
diff --git a/src/ast/binding_decoration.cc b/src/ast/binding_decoration.cc
index 4278dd5..d9532fe 100644
--- a/src/ast/binding_decoration.cc
+++ b/src/ast/binding_decoration.cc
@@ -22,7 +22,7 @@
BindingDecoration::~BindingDecoration() = default;
void BindingDecoration::to_str(std::ostream& out) const {
- out << "binding " << value_;
+ out << "BindingDecoration{" << value_ << "}" << std::endl;
}
} // namespace ast
diff --git a/src/ast/builtin_decoration.cc b/src/ast/builtin_decoration.cc
index c0264af..89d116e 100644
--- a/src/ast/builtin_decoration.cc
+++ b/src/ast/builtin_decoration.cc
@@ -22,7 +22,7 @@
BuiltinDecoration::~BuiltinDecoration() = default;
void BuiltinDecoration::to_str(std::ostream& out) const {
- out << "builtin " << builtin_;
+ out << "BuiltinDecoration{" << builtin_ << "}" << std::endl;
}
} // namespace ast
diff --git a/src/ast/decorated_variable.cc b/src/ast/decorated_variable.cc
index 2a6b42e..038aaed 100644
--- a/src/ast/decorated_variable.cc
+++ b/src/ast/decorated_variable.cc
@@ -19,6 +19,9 @@
DecoratedVariable::DecoratedVariable() = default;
+DecoratedVariable::DecoratedVariable(std::unique_ptr<Variable> var)
+ : Variable(var->source(), var->name(), var->storage_class(), var->type()) {}
+
DecoratedVariable::DecoratedVariable(DecoratedVariable&&) = default;
DecoratedVariable::~DecoratedVariable() = default;
@@ -32,17 +35,17 @@
out << "DecoratedVariable{" << std::endl;
make_indent(out, indent + 2);
- out << "decorations{" << std::endl;
+ out << "Decorations{" << std::endl;
for (const auto& deco : decorations_) {
make_indent(out, indent + 4);
deco->to_str(out);
- out << std::endl;
}
make_indent(out, indent + 2);
out << "}" << std::endl;
info_to_str(out, indent + 2);
+ initializer_to_str(out, indent + 2);
make_indent(out, indent);
out << "}" << std::endl;
}
diff --git a/src/ast/decorated_variable.h b/src/ast/decorated_variable.h
index d81de81..4008a48 100644
--- a/src/ast/decorated_variable.h
+++ b/src/ast/decorated_variable.h
@@ -30,6 +30,9 @@
public:
/// Create a new empty decorated variable statement
DecoratedVariable();
+ /// Create a decorated variable from an existing variable
+ /// @param var the variable to initialize from
+ explicit DecoratedVariable(std::unique_ptr<Variable> var);
/// Move constructor
DecoratedVariable(DecoratedVariable&&);
diff --git a/src/ast/decorated_variable_test.cc b/src/ast/decorated_variable_test.cc
new file mode 100644
index 0000000..e2ed800
--- /dev/null
+++ b/src/ast/decorated_variable_test.cc
@@ -0,0 +1,97 @@
+// Copyright 2020 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/ast/decorated_variable.h"
+
+#include "gtest/gtest.h"
+#include "src/ast/binding_decoration.h"
+#include "src/ast/identifier_expression.h"
+#include "src/ast/set_decoration.h"
+#include "src/ast/type/f32_type.h"
+#include "src/ast/type/i32_type.h"
+#include "src/ast/variable.h"
+#include "src/ast/variable_decoration.h"
+
+namespace tint {
+namespace ast {
+
+using DecoratedVariableTest = testing::Test;
+
+TEST_F(DecoratedVariableTest, Creation) {
+ type::I32Type t;
+ auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+ DecoratedVariable dv(std::move(var));
+
+ EXPECT_EQ(dv.name(), "my_var");
+ EXPECT_EQ(dv.storage_class(), StorageClass::kFunction);
+ EXPECT_EQ(dv.type(), &t);
+ EXPECT_EQ(dv.line(), 0);
+ EXPECT_EQ(dv.column(), 0);
+}
+
+TEST_F(DecoratedVariableTest, CreationWithSource) {
+ Source s{27, 4};
+ type::F32Type t;
+ auto var = std::make_unique<Variable>(s, "i", StorageClass::kPrivate, &t);
+ DecoratedVariable dv(std::move(var));
+
+ EXPECT_EQ(dv.name(), "i");
+ EXPECT_EQ(dv.storage_class(), StorageClass::kPrivate);
+ EXPECT_EQ(dv.type(), &t);
+ EXPECT_EQ(dv.line(), 27);
+ EXPECT_EQ(dv.column(), 4);
+}
+
+TEST_F(DecoratedVariableTest, IsValid) {
+ type::I32Type t;
+ auto var = std::make_unique<Variable>("my_var", StorageClass::kNone, &t);
+ DecoratedVariable dv(std::move(var));
+ EXPECT_TRUE(dv.IsValid());
+}
+
+TEST_F(DecoratedVariableTest, IsDecorated) {
+ DecoratedVariable dv;
+ EXPECT_TRUE(dv.IsDecorated());
+}
+
+TEST_F(DecoratedVariableTest, to_str) {
+ type::F32Type t;
+ auto var = std::make_unique<Variable>("my_var", StorageClass::kFunction, &t);
+ DecoratedVariable dv(std::move(var));
+ dv.set_initializer(std::make_unique<IdentifierExpression>("expr"));
+
+ std::vector<std::unique_ptr<VariableDecoration>> decos;
+ decos.push_back(std::make_unique<BindingDecoration>(2));
+ decos.push_back(std::make_unique<SetDecoration>(1));
+
+ dv.set_decorations(std::move(decos));
+ std::ostringstream out;
+ dv.to_str(out, 2);
+ EXPECT_EQ(out.str(), R"( DecoratedVariable{
+ Decorations{
+ BindingDecoration{2}
+ SetDecoration{1}
+ }
+ my_var
+ function
+ __f32
+ {
+ Identifier{expr}
+ }
+ }
+)");
+}
+
+} // namespace ast
+} // namespace tint
diff --git a/src/ast/location_decoration.cc b/src/ast/location_decoration.cc
index 45bec56..9fb8d5f 100644
--- a/src/ast/location_decoration.cc
+++ b/src/ast/location_decoration.cc
@@ -22,7 +22,7 @@
LocationDecoration::~LocationDecoration() = default;
void LocationDecoration::to_str(std::ostream& out) const {
- out << "location " << value_;
+ out << "LocationDecoration{" << value_ << "}" << std::endl;
}
} // namespace ast
diff --git a/src/ast/set_decoration.cc b/src/ast/set_decoration.cc
index c27ee26..7d54d98 100644
--- a/src/ast/set_decoration.cc
+++ b/src/ast/set_decoration.cc
@@ -22,7 +22,7 @@
SetDecoration::~SetDecoration() = default;
void SetDecoration::to_str(std::ostream& out) const {
- out << "set " << value_;
+ out << "SetDecoration{" << value_ << "}" << std::endl;
}
} // namespace ast
diff --git a/src/ast/variable.cc b/src/ast/variable.cc
index 1caa64b..d9990b8 100644
--- a/src/ast/variable.cc
+++ b/src/ast/variable.cc
@@ -56,18 +56,26 @@
out << type_->type_name() << std::endl;
}
+void Variable::initializer_to_str(std::ostream& out, size_t indent) const {
+ if (initializer_ == nullptr)
+ return;
+
+ make_indent(out, indent);
+ out << "{" << std::endl;
+
+ initializer_->to_str(out, indent + 2);
+
+ make_indent(out, indent);
+ out << "}" << std::endl;
+}
+
void Variable::to_str(std::ostream& out, size_t indent) const {
- info_to_str(out, indent);
-
- if (initializer_ != nullptr) {
- make_indent(out, indent);
- out << "{" << std::endl;
-
- initializer_->to_str(out, indent + 2);
-
- make_indent(out, indent);
- out << "}" << std::endl;
- }
+ make_indent(out, indent);
+ out << "Variable{" << std::endl;
+ info_to_str(out, indent + 2);
+ initializer_to_str(out, indent + 2);
+ make_indent(out, indent);
+ out << "}" << std::endl;
}
} // namespace ast
diff --git a/src/ast/variable.h b/src/ast/variable.h
index db27ed2..3fec0d6 100644
--- a/src/ast/variable.h
+++ b/src/ast/variable.h
@@ -105,6 +105,10 @@
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void info_to_str(std::ostream& out, size_t indent) const;
+ /// Output initializer for this variable.
+ /// @param out the stream to write to
+ /// @param indent number of spaces to indent the node when writing
+ void initializer_to_str(std::ostream& out, size_t indent) const;
private:
Variable(const Variable&) = delete;
diff --git a/src/ast/variable_test.cc b/src/ast/variable_test.cc
index 0f4f59b..8156d23 100644
--- a/src/ast/variable_test.cc
+++ b/src/ast/variable_test.cc
@@ -89,10 +89,12 @@
type::F32Type t;
Variable v{"my_var", StorageClass::kFunction, &t};
std::ostringstream out;
- v.to_str(out, 0);
- EXPECT_EQ(out.str(), R"(my_var
-function
-__f32
+ v.to_str(out, 2);
+ EXPECT_EQ(out.str(), R"( Variable{
+ my_var
+ function
+ __f32
+ }
)");
}
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 58d4bf2..59d461b 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -329,11 +329,7 @@
}
if (decos.size() > 0) {
- auto dv = std::make_unique<ast::DecoratedVariable>();
- dv->set_source(var->source());
- dv->set_name(var->name());
- dv->set_type(var->type());
- dv->set_storage_class(var->storage_class());
+ auto dv = std::make_unique<ast::DecoratedVariable>(std::move(var));
dv->set_decorations(std::move(decos));
var = std::move(dv);