resolver: Remove error codes
We've decided that these will be omitted for now. Move the check-spec-examples script into the tools/src directory, and update the go modules. Add a bash script to build and run this. Change-Id: I852f8ddb1b9b987410a2a49cf6d14e54c3cf3f0e Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/56381 Auto-Submit: Ben Clayton <bclayton@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
91622e3853
commit
5a88ec8822
|
@ -42,8 +42,7 @@ TEST_F(ResolverCallValidationTest, Recursive_Invalid) {
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0004: recursion is not permitted. 'main' attempted "
|
"12:34 error: recursion is not permitted. 'main' attempted to call "
|
||||||
"to call "
|
|
||||||
"itself.");
|
"itself.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +69,7 @@ TEST_F(ResolverCallValidationTest, Undeclared_Invalid) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(), "12:34 error: unable to find called function: func");
|
||||||
"12:34 error: v-0006: unable to find called function: func");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverCallValidationTest, TooFewArgs) {
|
TEST_F(ResolverCallValidationTest, TooFewArgs) {
|
||||||
|
|
|
@ -45,8 +45,8 @@ TEST_F(ResolverControlBlockValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0025: switch statement selector expression must be "
|
"12:34 error: switch statement selector expression must be of a "
|
||||||
"of a scalar integer type");
|
"scalar integer type");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverControlBlockValidationTest, SwitchWithoutDefault_Fail) {
|
TEST_F(ResolverControlBlockValidationTest, SwitchWithoutDefault_Fail) {
|
||||||
|
@ -106,8 +106,7 @@ TEST_F(ResolverControlBlockValidationTest, SwitchWithTwoDefault_Fail) {
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
r()->error(),
|
r()->error(),
|
||||||
"12:34 error v-0008: switch statement must have exactly one default "
|
"12:34 error: switch statement must have exactly one default clause");
|
||||||
"clause");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverControlBlockValidationTest, UnreachableCode_continue) {
|
TEST_F(ResolverControlBlockValidationTest, UnreachableCode_continue) {
|
||||||
|
@ -164,8 +163,8 @@ TEST_F(ResolverControlBlockValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0026: the case selector values must have the same "
|
"12:34 error: the case selector values must have the same type as "
|
||||||
"type as the selector expression.");
|
"the selector expression.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverControlBlockValidationTest,
|
TEST_F(ResolverControlBlockValidationTest,
|
||||||
|
@ -193,8 +192,8 @@ TEST_F(ResolverControlBlockValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0026: the case selector values must have the same "
|
"12:34 error: the case selector values must have the same type as "
|
||||||
"type as the selector expression.");
|
"the selector expression.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverControlBlockValidationTest,
|
TEST_F(ResolverControlBlockValidationTest,
|
||||||
|
@ -228,8 +227,8 @@ TEST_F(ResolverControlBlockValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0027: a literal value must not appear more than "
|
"12:34 error: a literal value must not appear more than once in "
|
||||||
"once in the case selectors for a switch statement: '2u'");
|
"the case selectors for a switch statement: '2u'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverControlBlockValidationTest,
|
TEST_F(ResolverControlBlockValidationTest,
|
||||||
|
@ -264,10 +263,9 @@ TEST_F(ResolverControlBlockValidationTest,
|
||||||
WrapInFunction(block);
|
WrapInFunction(block);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(r()->error(),
|
||||||
r()->error(),
|
"12:34 error: a literal value must not appear more than once in "
|
||||||
"12:34 error v-0027: a literal value must not appear more than once in "
|
"the case selectors for a switch statement: '10'");
|
||||||
"the case selectors for a switch statement: '10'");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverControlBlockValidationTest,
|
TEST_F(ResolverControlBlockValidationTest,
|
||||||
|
@ -288,10 +286,9 @@ TEST_F(ResolverControlBlockValidationTest,
|
||||||
WrapInFunction(block);
|
WrapInFunction(block);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(r()->error(),
|
||||||
r()->error(),
|
"12:34 error: a fallthrough statement must not appear as the last "
|
||||||
"12:34 error v-0028: a fallthrough statement must not appear as the "
|
"statement in last clause of a switch");
|
||||||
"last statement in last clause of a switch");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverControlBlockValidationTest, SwitchCase_Pass) {
|
TEST_F(ResolverControlBlockValidationTest, SwitchCase_Pass) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ TEST_F(ResolverFunctionValidationTest, FunctionNamesMustBeUnique_fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
R"(12:34 error v-0016: duplicate function named 'func'
|
R"(12:34 error: duplicate function named 'func'
|
||||||
note: first function declared here)");
|
note: first function declared here)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,8 +74,8 @@ TEST_F(ResolverFunctionValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-2000: duplicate declaration 'foo'\n56:78 note: "
|
"12:34 error: duplicate declaration 'foo'\n56:78 note: 'foo' first "
|
||||||
"'foo' first declared here:");
|
"declared here:");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest,
|
TEST_F(ResolverFunctionValidationTest,
|
||||||
|
@ -91,8 +91,8 @@ TEST_F(ResolverFunctionValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"error v-2000: duplicate declaration 'foo'\n12:34 note: 'foo' "
|
"error: duplicate declaration 'foo'\n12:34 note: 'foo' first "
|
||||||
"first declared here:");
|
"declared here:");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest, FunctionUsingSameVariableName_Pass) {
|
TEST_F(ResolverFunctionValidationTest, FunctionUsingSameVariableName_Pass) {
|
||||||
|
@ -163,9 +163,8 @@ TEST_F(ResolverFunctionValidationTest, FunctionEndWithoutReturnStatement_Fail) {
|
||||||
ast::DecorationList{});
|
ast::DecorationList{});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(r()->error(),
|
||||||
r()->error(),
|
"12:34 error: non-void function must end with a return statement");
|
||||||
"12:34 error v-0002: non-void function must end with a return statement");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest,
|
TEST_F(ResolverFunctionValidationTest,
|
||||||
|
@ -186,9 +185,8 @@ TEST_F(ResolverFunctionValidationTest,
|
||||||
ast::StatementList{}, ast::DecorationList{});
|
ast::StatementList{}, ast::DecorationList{});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(r()->error(),
|
||||||
r()->error(),
|
"12:34 error: non-void function must end with a return statement");
|
||||||
"12:34 error v-0002: non-void function must end with a return statement");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest,
|
TEST_F(ResolverFunctionValidationTest,
|
||||||
|
@ -214,8 +212,8 @@ TEST_F(ResolverFunctionValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-000y: return statement type must match its function "
|
"12:34 error: return statement type must match its function return "
|
||||||
"return type, returned 'i32', expected 'void'");
|
"type, returned 'i32', expected 'void'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest,
|
TEST_F(ResolverFunctionValidationTest,
|
||||||
|
@ -229,8 +227,8 @@ TEST_F(ResolverFunctionValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-000y: return statement type must match its function "
|
"12:34 error: return statement type must match its function return "
|
||||||
"return type, returned 'void', expected 'f32'");
|
"type, returned 'void', expected 'f32'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest,
|
TEST_F(ResolverFunctionValidationTest,
|
||||||
|
@ -256,8 +254,8 @@ TEST_F(ResolverFunctionValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-000y: return statement type must match its function "
|
"12:34 error: return statement type must match its function return "
|
||||||
"return type, returned 'i32', expected 'f32'");
|
"type, returned 'i32', expected 'f32'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest,
|
TEST_F(ResolverFunctionValidationTest,
|
||||||
|
@ -287,8 +285,8 @@ TEST_F(ResolverFunctionValidationTest,
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-000y: return statement type must match its function "
|
"12:34 error: return statement type must match its function return "
|
||||||
"return type, returned 'u32', expected 'myf32'");
|
"type, returned 'u32', expected 'myf32'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverFunctionValidationTest, PipelineStage_MustBeUnique_Fail) {
|
TEST_F(ResolverFunctionValidationTest, PipelineStage_MustBeUnique_Fail) {
|
||||||
|
|
|
@ -616,8 +616,7 @@ bool Resolver::ValidateVariableConstructor(const ast::Variable* var,
|
||||||
|
|
||||||
bool Resolver::GlobalVariable(ast::Variable* var) {
|
bool Resolver::GlobalVariable(ast::Variable* var) {
|
||||||
if (variable_stack_.has(var->symbol())) {
|
if (variable_stack_.has(var->symbol())) {
|
||||||
AddError("v-0011",
|
AddError("redeclared global identifier '" +
|
||||||
"redeclared global identifier '" +
|
|
||||||
builder_->Symbols().NameFor(var->symbol()) + "'",
|
builder_->Symbols().NameFor(var->symbol()) + "'",
|
||||||
var->source());
|
var->source());
|
||||||
return false;
|
return false;
|
||||||
|
@ -630,13 +629,11 @@ bool Resolver::GlobalVariable(ast::Variable* var) {
|
||||||
variable_stack_.set_global(var->symbol(), info);
|
variable_stack_.set_global(var->symbol(), info);
|
||||||
|
|
||||||
if (!var->is_const() && info->storage_class == ast::StorageClass::kNone) {
|
if (!var->is_const() && info->storage_class == ast::StorageClass::kNone) {
|
||||||
AddError("v-0022", "global variables must have a storage class",
|
AddError("global variables must have a storage class", var->source());
|
||||||
var->source());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (var->is_const() && !(info->storage_class == ast::StorageClass::kNone)) {
|
if (var->is_const() && !(info->storage_class == ast::StorageClass::kNone)) {
|
||||||
AddError("v-global01", "global constants shouldn't have a storage class",
|
AddError("global constants shouldn't have a storage class", var->source());
|
||||||
var->source());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,8 +675,7 @@ bool Resolver::GlobalVariable(ast::Variable* var) {
|
||||||
bool Resolver::ValidateGlobalVariable(const VariableInfo* info) {
|
bool Resolver::ValidateGlobalVariable(const VariableInfo* info) {
|
||||||
auto duplicate_func = symbol_to_function_.find(info->declaration->symbol());
|
auto duplicate_func = symbol_to_function_.find(info->declaration->symbol());
|
||||||
if (duplicate_func != symbol_to_function_.end()) {
|
if (duplicate_func != symbol_to_function_.end()) {
|
||||||
AddError("v-2000",
|
AddError("duplicate declaration '" +
|
||||||
"duplicate declaration '" +
|
|
||||||
builder_->Symbols().NameFor(info->declaration->symbol()) + "'",
|
builder_->Symbols().NameFor(info->declaration->symbol()) + "'",
|
||||||
info->declaration->source());
|
info->declaration->source());
|
||||||
AddNote("'" + builder_->Symbols().NameFor(info->declaration->symbol()) +
|
AddNote("'" + builder_->Symbols().NameFor(info->declaration->symbol()) +
|
||||||
|
@ -866,8 +862,7 @@ bool Resolver::ValidateVariable(const VariableInfo* info) {
|
||||||
|
|
||||||
if (auto* r = storage_type->As<sem::Array>()) {
|
if (auto* r = storage_type->As<sem::Array>()) {
|
||||||
if (r->IsRuntimeSized()) {
|
if (r->IsRuntimeSized()) {
|
||||||
AddError("v-0015",
|
AddError("runtime arrays may only appear as the last member of a struct",
|
||||||
"runtime arrays may only appear as the last member of a struct",
|
|
||||||
var->source());
|
var->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1040,8 +1035,7 @@ bool Resolver::ValidateFunction(const ast::Function* func,
|
||||||
const FunctionInfo* info) {
|
const FunctionInfo* info) {
|
||||||
auto func_it = symbol_to_function_.find(func->symbol());
|
auto func_it = symbol_to_function_.find(func->symbol());
|
||||||
if (func_it != symbol_to_function_.end()) {
|
if (func_it != symbol_to_function_.end()) {
|
||||||
AddError("v-0016",
|
AddError("duplicate function named '" +
|
||||||
"duplicate function named '" +
|
|
||||||
builder_->Symbols().NameFor(func->symbol()) + "'",
|
builder_->Symbols().NameFor(func->symbol()) + "'",
|
||||||
func->source());
|
func->source());
|
||||||
AddNote("first function declared here",
|
AddNote("first function declared here",
|
||||||
|
@ -1053,8 +1047,7 @@ bool Resolver::ValidateFunction(const ast::Function* func,
|
||||||
VariableInfo* var;
|
VariableInfo* var;
|
||||||
if (variable_stack_.get(func->symbol(), &var, &is_global)) {
|
if (variable_stack_.get(func->symbol(), &var, &is_global)) {
|
||||||
if (is_global) {
|
if (is_global) {
|
||||||
AddError("v-2000",
|
AddError("duplicate declaration '" +
|
||||||
"duplicate declaration '" +
|
|
||||||
builder_->Symbols().NameFor(func->symbol()) + "'",
|
builder_->Symbols().NameFor(func->symbol()) + "'",
|
||||||
func->source());
|
func->source());
|
||||||
AddNote("'" + builder_->Symbols().NameFor(func->symbol()) +
|
AddNote("'" + builder_->Symbols().NameFor(func->symbol()) +
|
||||||
|
@ -1099,7 +1092,7 @@ bool Resolver::ValidateFunction(const ast::Function* func,
|
||||||
if (func->body()) {
|
if (func->body()) {
|
||||||
if (!func->get_last_statement() ||
|
if (!func->get_last_statement() ||
|
||||||
!func->get_last_statement()->Is<ast::ReturnStatement>()) {
|
!func->get_last_statement()->Is<ast::ReturnStatement>()) {
|
||||||
AddError("v-0002", "non-void function must end with a return statement",
|
AddError("non-void function must end with a return statement",
|
||||||
func->source());
|
func->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2038,13 +2031,11 @@ bool Resolver::FunctionCall(const ast::CallExpression* call) {
|
||||||
if (callee_func_it == symbol_to_function_.end()) {
|
if (callee_func_it == symbol_to_function_.end()) {
|
||||||
if (current_function_ &&
|
if (current_function_ &&
|
||||||
current_function_->declaration->symbol() == ident->symbol()) {
|
current_function_->declaration->symbol() == ident->symbol()) {
|
||||||
AddError("v-0004",
|
AddError("recursion is not permitted. '" + name +
|
||||||
"recursion is not permitted. '" + name +
|
|
||||||
"' attempted to call itself.",
|
"' attempted to call itself.",
|
||||||
call->source());
|
call->source());
|
||||||
} else {
|
} else {
|
||||||
AddError("v-0006: unable to find called function: " + name,
|
AddError("unable to find called function: " + name, call->source());
|
||||||
call->source());
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2400,8 +2391,7 @@ bool Resolver::Identifier(ast::IdentifierExpression* expr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddError("v-0006: identifier must be declared before use: " + name,
|
AddError("identifier must be declared before use: " + name, expr->source());
|
||||||
expr->source());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2829,9 +2819,7 @@ bool Resolver::VariableDeclStatement(const ast::VariableDeclStatement* stmt) {
|
||||||
|
|
||||||
bool is_global = false;
|
bool is_global = false;
|
||||||
if (variable_stack_.get(var->symbol(), nullptr, &is_global)) {
|
if (variable_stack_.get(var->symbol(), nullptr, &is_global)) {
|
||||||
const char* error_code = is_global ? "v-0013" : "v-0014";
|
AddError("redeclared identifier '" +
|
||||||
AddError(error_code,
|
|
||||||
"redeclared identifier '" +
|
|
||||||
builder_->Symbols().NameFor(var->symbol()) + "'",
|
builder_->Symbols().NameFor(var->symbol()) + "'",
|
||||||
var->source());
|
var->source());
|
||||||
return false;
|
return false;
|
||||||
|
@ -3370,18 +3358,16 @@ bool Resolver::ValidateStructure(const sem::Struct* str) {
|
||||||
if (r->IsRuntimeSized()) {
|
if (r->IsRuntimeSized()) {
|
||||||
if (member != str->Members().back()) {
|
if (member != str->Members().back()) {
|
||||||
AddError(
|
AddError(
|
||||||
"v-0015",
|
|
||||||
"runtime arrays may only appear as the last member of a struct",
|
"runtime arrays may only appear as the last member of a struct",
|
||||||
member->Declaration()->source());
|
member->Declaration()->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!str->IsBlockDecorated()) {
|
if (!str->IsBlockDecorated()) {
|
||||||
AddError("v-0015",
|
AddError(
|
||||||
"a struct containing a runtime-sized array "
|
"a struct containing a runtime-sized array "
|
||||||
"requires the [[block]] attribute: '" +
|
"requires the [[block]] attribute: '" +
|
||||||
builder_->Symbols().NameFor(str->Declaration()->name()) +
|
builder_->Symbols().NameFor(str->Declaration()->name()) + "'",
|
||||||
"'",
|
member->Declaration()->source());
|
||||||
member->Declaration()->source());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3568,12 +3554,12 @@ bool Resolver::ValidateReturn(const ast::ReturnStatement* ret) {
|
||||||
: builder_->create<sem::Void>();
|
: builder_->create<sem::Void>();
|
||||||
|
|
||||||
if (func_type->UnwrapRef() != ret_type) {
|
if (func_type->UnwrapRef() != ret_type) {
|
||||||
AddError("v-000y",
|
AddError(
|
||||||
"return statement type must match its function "
|
"return statement type must match its function "
|
||||||
"return type, returned '" +
|
"return type, returned '" +
|
||||||
ret_type->FriendlyName(builder_->Symbols()) + "', expected '" +
|
ret_type->FriendlyName(builder_->Symbols()) + "', expected '" +
|
||||||
current_function_->return_type_name + "'",
|
current_function_->return_type_name + "'",
|
||||||
ret->source());
|
ret->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3598,10 +3584,10 @@ bool Resolver::Return(ast::ReturnStatement* ret) {
|
||||||
bool Resolver::ValidateSwitch(const ast::SwitchStatement* s) {
|
bool Resolver::ValidateSwitch(const ast::SwitchStatement* s) {
|
||||||
auto* cond_type = TypeOf(s->condition())->UnwrapRef();
|
auto* cond_type = TypeOf(s->condition())->UnwrapRef();
|
||||||
if (!cond_type->is_integer_scalar()) {
|
if (!cond_type->is_integer_scalar()) {
|
||||||
AddError("v-0025",
|
AddError(
|
||||||
"switch statement selector expression must be of a "
|
"switch statement selector expression must be of a "
|
||||||
"scalar integer type",
|
"scalar integer type",
|
||||||
s->condition()->source());
|
s->condition()->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3612,8 +3598,7 @@ bool Resolver::ValidateSwitch(const ast::SwitchStatement* s) {
|
||||||
if (case_stmt->IsDefault()) {
|
if (case_stmt->IsDefault()) {
|
||||||
if (has_default) {
|
if (has_default) {
|
||||||
// More than one default clause
|
// More than one default clause
|
||||||
AddError("v-0008",
|
AddError("switch statement must have exactly one default clause",
|
||||||
"switch statement must have exactly one default clause",
|
|
||||||
case_stmt->source());
|
case_stmt->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -3622,20 +3607,20 @@ bool Resolver::ValidateSwitch(const ast::SwitchStatement* s) {
|
||||||
|
|
||||||
for (auto* selector : case_stmt->selectors()) {
|
for (auto* selector : case_stmt->selectors()) {
|
||||||
if (cond_type != TypeOf(selector)) {
|
if (cond_type != TypeOf(selector)) {
|
||||||
AddError("v-0026",
|
AddError(
|
||||||
"the case selector values must have the same "
|
"the case selector values must have the same "
|
||||||
"type as the selector expression.",
|
"type as the selector expression.",
|
||||||
case_stmt->source());
|
case_stmt->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto v = selector->value_as_u32();
|
auto v = selector->value_as_u32();
|
||||||
if (selector_set.find(v) != selector_set.end()) {
|
if (selector_set.find(v) != selector_set.end()) {
|
||||||
AddError("v-0027",
|
AddError(
|
||||||
"a literal value must not appear more than once in "
|
"a literal value must not appear more than once in "
|
||||||
"the case selectors for a switch statement: '" +
|
"the case selectors for a switch statement: '" +
|
||||||
builder_->str(selector) + "'",
|
builder_->str(selector) + "'",
|
||||||
case_stmt->source());
|
case_stmt->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
selector_set.emplace(v);
|
selector_set.emplace(v);
|
||||||
|
@ -3652,10 +3637,10 @@ bool Resolver::ValidateSwitch(const ast::SwitchStatement* s) {
|
||||||
auto* last_clause = s->body().back()->As<ast::CaseStatement>();
|
auto* last_clause = s->body().back()->As<ast::CaseStatement>();
|
||||||
auto* last_stmt = last_clause->body()->last();
|
auto* last_stmt = last_clause->body()->last();
|
||||||
if (last_stmt && last_stmt->Is<ast::FallthroughStatement>()) {
|
if (last_stmt && last_stmt->Is<ast::FallthroughStatement>()) {
|
||||||
AddError("v-0028",
|
AddError(
|
||||||
"a fallthrough statement must not appear as "
|
"a fallthrough statement must not appear as "
|
||||||
"the last statement in last clause of a switch",
|
"the last statement in last clause of a switch",
|
||||||
last_stmt->source());
|
last_stmt->source());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3875,12 +3860,6 @@ void Resolver::Mark(const ast::Node* node) {
|
||||||
<< "Pointer: " << node;
|
<< "Pointer: " << node;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resolver::AddError(const char* code,
|
|
||||||
const std::string& msg,
|
|
||||||
const Source& source) const {
|
|
||||||
diagnostics_.add_error(diag::System::Resolver, code, msg, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Resolver::AddError(const std::string& msg, const Source& source) const {
|
void Resolver::AddError(const std::string& msg, const Source& source) const {
|
||||||
diagnostics_.add_error(diag::System::Resolver, msg, source);
|
diagnostics_.add_error(diag::System::Resolver, msg, source);
|
||||||
}
|
}
|
||||||
|
|
|
@ -411,12 +411,6 @@ class Resolver {
|
||||||
/// @param node the AST node.
|
/// @param node the AST node.
|
||||||
void Mark(const ast::Node* node);
|
void Mark(const ast::Node* node);
|
||||||
|
|
||||||
/// Adds the given error message to the diagnostics
|
|
||||||
/// [DEPRECATED] Remove all codes
|
|
||||||
void AddError(const char* code,
|
|
||||||
const std::string& msg,
|
|
||||||
const Source& source) const;
|
|
||||||
|
|
||||||
/// Adds the given error message to the diagnostics
|
/// Adds the given error message to the diagnostics
|
||||||
void AddError(const std::string& msg, const Source& source) const;
|
void AddError(const std::string& msg, const Source& source) const;
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ TEST_F(ResolverStorageClassValidationTest, GlobalVariableNoStorageClass_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0022: global variables must have a storage class");
|
"12:34 error: global variables must have a storage class");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
|
TEST_F(ResolverStorageClassValidationTest, StorageBufferBool) {
|
||||||
|
|
|
@ -100,8 +100,7 @@ TEST_F(ResolverTypeValidationTest, GlobalConstantWithStorageClass_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-global01: global constants shouldn't have a storage "
|
"12:34 error: global constants shouldn't have a storage class");
|
||||||
"class");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTypeValidationTest, GlobalConstNoStorageClass_Pass) {
|
TEST_F(ResolverTypeValidationTest, GlobalConstNoStorageClass_Pass) {
|
||||||
|
@ -216,10 +215,9 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayInFunction_Fail) {
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(r()->error(),
|
||||||
r()->error(),
|
"12:34 error: runtime arrays may only appear as the last member of "
|
||||||
"12:34 error v-0015: runtime arrays may only appear as the last member "
|
"a struct");
|
||||||
"of a struct");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTypeValidationTest, RuntimeArrayIsLast_Pass) {
|
TEST_F(ResolverTypeValidationTest, RuntimeArrayIsLast_Pass) {
|
||||||
|
@ -256,8 +254,8 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayIsLastNoBlock_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0015: a struct containing a runtime-sized array "
|
"12:34 error: a struct containing a runtime-sized array requires "
|
||||||
"requires the [[block]] attribute: 'Foo'");
|
"the [[block]] attribute: 'Foo'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTypeValidationTest, RuntimeArrayIsNotLast_Fail) {
|
TEST_F(ResolverTypeValidationTest, RuntimeArrayIsNotLast_Fail) {
|
||||||
|
@ -279,7 +277,7 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayIsNotLast_Fail) {
|
||||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
r()->error(),
|
r()->error(),
|
||||||
R"(12:34 error v-0015: runtime arrays may only appear as the last member of a struct)");
|
R"(12:34 error: runtime arrays may only appear as the last member of a struct)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsGlobalVariable) {
|
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsGlobalVariable) {
|
||||||
|
@ -289,7 +287,7 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayAsGlobalVariable) {
|
||||||
|
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
r()->error(),
|
r()->error(),
|
||||||
R"(56:78 error v-0015: runtime arrays may only appear as the last member of a struct)");
|
R"(56:78 error: runtime arrays may only appear as the last member of a struct)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsLocalVariable) {
|
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsLocalVariable) {
|
||||||
|
@ -300,7 +298,7 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayAsLocalVariable) {
|
||||||
|
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
r()->error(),
|
r()->error(),
|
||||||
R"(56:78 error v-0015: runtime arrays may only appear as the last member of a struct)");
|
R"(56:78 error: runtime arrays may only appear as the last member of a struct)");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsParameter_Fail) {
|
TEST_F(ResolverTypeValidationTest, RuntimeArrayAsParameter_Fail) {
|
||||||
|
@ -324,10 +322,9 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayAsParameter_Fail) {
|
||||||
});
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(r()->error(),
|
||||||
r()->error(),
|
"12:34 error: runtime arrays may only appear as the last member of "
|
||||||
"12:34 error v-0015: runtime arrays may only appear as the last member "
|
"a struct");
|
||||||
"of a struct");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsNotLast_Fail) {
|
TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsNotLast_Fail) {
|
||||||
|
@ -349,10 +346,9 @@ TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsNotLast_Fail) {
|
||||||
WrapInFunction();
|
WrapInFunction();
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(r()->error(),
|
||||||
r()->error(),
|
"12:34 error: runtime arrays may only appear as the last member of "
|
||||||
"12:34 error v-0015: runtime arrays may only appear as the last member "
|
"a struct");
|
||||||
"of a struct");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsLast_Pass) {
|
TEST_F(ResolverTypeValidationTest, AliasRuntimeArrayIsLast_Pass) {
|
||||||
|
|
|
@ -213,7 +213,7 @@ TEST_F(ResolverValidationTest, UsingUndefinedVariable_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: v-0006: identifier must be declared before use: b");
|
"12:34 error: identifier must be declared before use: b");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverValidationTest, UsingUndefinedVariableInBlockStatement_Fail) {
|
TEST_F(ResolverValidationTest, UsingUndefinedVariableInBlockStatement_Fail) {
|
||||||
|
@ -229,7 +229,7 @@ TEST_F(ResolverValidationTest, UsingUndefinedVariableInBlockStatement_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: v-0006: identifier must be declared before use: b");
|
"12:34 error: identifier must be declared before use: b");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariableAfter_Fail) {
|
TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariableAfter_Fail) {
|
||||||
|
@ -251,8 +251,7 @@ TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariableAfter_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: v-0006: identifier must be declared before use: "
|
"12:34 error: identifier must be declared before use: global_var");
|
||||||
"global_var");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariable_Pass) {
|
TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariable_Pass) {
|
||||||
|
@ -295,7 +294,7 @@ TEST_F(ResolverValidationTest, UsingUndefinedVariableInnerScope_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: v-0006: identifier must be declared before use: a");
|
"12:34 error: identifier must be declared before use: a");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverValidationTest, UsingUndefinedVariableOuterScope_Pass) {
|
TEST_F(ResolverValidationTest, UsingUndefinedVariableOuterScope_Pass) {
|
||||||
|
@ -338,7 +337,7 @@ TEST_F(ResolverValidationTest, UsingUndefinedVariableDifferentScope_Fail) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: v-0006: identifier must be declared before use: a");
|
"12:34 error: identifier must be declared before use: a");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverValidationTest, StorageClass_FunctionVariableWorkgroupClass) {
|
TEST_F(ResolverValidationTest, StorageClass_FunctionVariableWorkgroupClass) {
|
||||||
|
|
|
@ -124,7 +124,7 @@ TEST_F(ResolverVarLetValidationTest, LocalVarRedeclared) {
|
||||||
WrapInFunction(v1, v2);
|
WrapInFunction(v1, v2);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error v-0014: redeclared identifier 'v'");
|
EXPECT_EQ(r()->error(), "12:34 error: redeclared identifier 'v'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverVarLetValidationTest, LocalLetRedeclared) {
|
TEST_F(ResolverVarLetValidationTest, LocalLetRedeclared) {
|
||||||
|
@ -135,7 +135,7 @@ TEST_F(ResolverVarLetValidationTest, LocalLetRedeclared) {
|
||||||
WrapInFunction(l1, l2);
|
WrapInFunction(l1, l2);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error v-0014: redeclared identifier 'l'");
|
EXPECT_EQ(r()->error(), "12:34 error: redeclared identifier 'l'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverVarLetValidationTest, GlobalVarRedeclared) {
|
TEST_F(ResolverVarLetValidationTest, GlobalVarRedeclared) {
|
||||||
|
@ -146,7 +146,7 @@ TEST_F(ResolverVarLetValidationTest, GlobalVarRedeclared) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0011: redeclared global identifier 'v'");
|
"12:34 error: redeclared global identifier 'v'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverVarLetValidationTest, GlobalLetRedeclared) {
|
TEST_F(ResolverVarLetValidationTest, GlobalLetRedeclared) {
|
||||||
|
@ -157,7 +157,7 @@ TEST_F(ResolverVarLetValidationTest, GlobalLetRedeclared) {
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error v-0011: redeclared global identifier 'l'");
|
"12:34 error: redeclared global identifier 'l'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverVarLetValidationTest, GlobalVarRedeclaredAsLocal) {
|
TEST_F(ResolverVarLetValidationTest, GlobalVarRedeclaredAsLocal) {
|
||||||
|
@ -173,7 +173,7 @@ TEST_F(ResolverVarLetValidationTest, GlobalVarRedeclaredAsLocal) {
|
||||||
Expr(2.0f)));
|
Expr(2.0f)));
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||||
EXPECT_EQ(r()->error(), "12:34 error v-0013: redeclared identifier 'v'");
|
EXPECT_EQ(r()->error(), "12:34 error: redeclared identifier 'v'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverVarLetValidationTest, VarRedeclaredInInnerBlock) {
|
TEST_F(ResolverVarLetValidationTest, VarRedeclaredInInnerBlock) {
|
||||||
|
@ -190,7 +190,7 @@ TEST_F(ResolverVarLetValidationTest, VarRedeclaredInInnerBlock) {
|
||||||
WrapInFunction(outer_body);
|
WrapInFunction(outer_body);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error v-0014: redeclared identifier 'v'");
|
EXPECT_EQ(r()->error(), "12:34 error: redeclared identifier 'v'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverVarLetValidationTest, VarRedeclaredInIfBlock) {
|
TEST_F(ResolverVarLetValidationTest, VarRedeclaredInIfBlock) {
|
||||||
|
@ -213,7 +213,7 @@ TEST_F(ResolverVarLetValidationTest, VarRedeclaredInIfBlock) {
|
||||||
WrapInFunction(outer_body);
|
WrapInFunction(outer_body);
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error v-0014: redeclared identifier 'v'");
|
EXPECT_EQ(r()->error(), "12:34 error: redeclared identifier 'v'");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverVarLetValidationTest, InferredPtrStorageAccessMismatch) {
|
TEST_F(ResolverVarLetValidationTest, InferredPtrStorageAccessMismatch) {
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Copyright 2021 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.
|
||||||
|
|
||||||
|
set -e # Fail on any error.
|
||||||
|
|
||||||
|
if [ ! -x "$(which go)" ] ; then
|
||||||
|
echo "error: go needs to be on \$PATH to use $0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd )"
|
||||||
|
ROOT_DIR="$( cd "${SCRIPT_DIR}/.." >/dev/null 2>&1 && pwd )"
|
||||||
|
BINARY="${SCRIPT_DIR}/bin/check-spec-examples"
|
||||||
|
|
||||||
|
# Rebuild the binary.
|
||||||
|
# Note, go caches build artifacts, so this is quick for repeat calls
|
||||||
|
pushd "${SCRIPT_DIR}/src/cmd/check-spec-examples" > /dev/null
|
||||||
|
go build -o "${BINARY}" main.go
|
||||||
|
popd > /dev/null
|
||||||
|
|
||||||
|
"${BINARY}" "$@"
|
|
@ -42,7 +42,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
toolName = "check-spec-examples"
|
toolName = "check-spec-examples"
|
||||||
defaultSpecPath = "https://gpuweb.github.io/gpuweb/wgsl.html"
|
defaultSpecPath = "https://gpuweb.github.io/gpuweb/wgsl/"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -152,6 +152,10 @@ func run() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(examples) == 0 {
|
||||||
|
return fmt.Errorf("no examples found")
|
||||||
|
}
|
||||||
|
|
||||||
// Create a temporary directory to hold the examples as separate files
|
// Create a temporary directory to hold the examples as separate files
|
||||||
tmpDir, err := ioutil.TempDir("", "wgsl-spec-examples")
|
tmpDir, err := ioutil.TempDir("", "wgsl-spec-examples")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -193,9 +197,8 @@ type example struct {
|
||||||
// tryCompile attempts to compile the example e in the directory wd, using the
|
// tryCompile attempts to compile the example e in the directory wd, using the
|
||||||
// compiler at the given path. If the example is annotated with 'function-scope'
|
// compiler at the given path. If the example is annotated with 'function-scope'
|
||||||
// then the code is wrapped with a basic vertex-stage-entry function.
|
// then the code is wrapped with a basic vertex-stage-entry function.
|
||||||
// If the first compile fails with an error message containing 'error v-0003',
|
// If the first compile fails then a dummy vertex-state-entry function is
|
||||||
// then a dummy vertex-state-entry function is appended to the source, and
|
// appended to the source, and another attempt to compile the shader is made.
|
||||||
// another attempt to compile the shader is made.
|
|
||||||
func tryCompile(compiler, wd string, e example) error {
|
func tryCompile(compiler, wd string, e example) error {
|
||||||
code := e.code
|
code := e.code
|
||||||
if e.functionScope {
|
if e.functionScope {
|
||||||
|
@ -209,9 +212,7 @@ func tryCompile(compiler, wd string, e example) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !addedStubFunction && strings.Contains(err.Error(), "error v-0003") {
|
if !addedStubFunction {
|
||||||
// error v-0003: At least one of vertex, fragment or compute shader
|
|
||||||
// must be present. Add a stub entry point to satisfy the compiler.
|
|
||||||
code += "\n[[stage(vertex)]] fn main() {}\n"
|
code += "\n[[stage(vertex)]] fn main() {}\n"
|
||||||
addedStubFunction = true
|
addedStubFunction = true
|
||||||
continue
|
continue
|
|
@ -5,4 +5,5 @@ go 1.16
|
||||||
require (
|
require (
|
||||||
github.com/fatih/color v1.10.0
|
github.com/fatih/color v1.10.0
|
||||||
github.com/sergi/go-diff v1.2.0
|
github.com/sergi/go-diff v1.2.0
|
||||||
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,9 +17,16 @@ github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q=
|
||||||
|
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
|
||||||
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
Loading…
Reference in New Issue