dawn/node: Fix missing validation errors

Derived interfaces were not exposing their base interface's attributes / methods / constants.

By fixing this, we now correctly expose the `message` property on interfaces deriving from `GPUError`.

Change-Id: I2f8cb4145b589a7b148495ad36f1ae00e388a99e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/106881
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2022-10-24 22:59:44 +00:00 committed by Dawn LUCI CQ
parent 20500b8e3a
commit d96f7c22ed
2 changed files with 61 additions and 6 deletions

View File

@ -138,6 +138,9 @@ Wrappers* Wrappers::instance = nullptr;
*/ -}} */ -}}
{{- define "Wrapper"}} {{- define "Wrapper"}}
struct W{{$.Name}} : public Napi::ObjectWrap<W{{$.Name}}> { struct W{{$.Name}} : public Napi::ObjectWrap<W{{$.Name}}> {
{{- $attributes := FlattenedAttributesOf $ }}
{{- $constants := FlattenedConstantsOf $ }}
{{- $methods := FlattenedMethodsOf $ }}
{{- if IsInterface $}} {{- if IsInterface $}}
std::unique_ptr<{{$.Name}}> impl; std::unique_ptr<{{$.Name}}> impl;
{{- end}} {{- end}}
@ -147,17 +150,17 @@ Wrappers* Wrappers::instance = nullptr;
InstanceMethod("has", &W{{$.Name}}::has), InstanceMethod("has", &W{{$.Name}}::has),
InstanceMethod("keys", &W{{$.Name}}::keys), InstanceMethod("keys", &W{{$.Name}}::keys),
{{- end}} {{- end}}
{{- range $m := MethodsOf $}} {{- range $m := $methods}}
InstanceMethod("{{$m.Name}}", &W{{$.Name}}::{{$m.Name}}), InstanceMethod("{{$m.Name}}", &W{{$.Name}}::{{$m.Name}}),
{{- end}} {{- end}}
{{- range $a := AttributesOf $}} {{- range $a := $attributes}}
{{- if not (HasAnnotation $a "SameObject")}} {{- if not (HasAnnotation $a "SameObject")}}
InstanceAccessor("{{$a.Name}}", &W{{$.Name}}::get{{Title $a.Name}}, InstanceAccessor("{{$a.Name}}", &W{{$.Name}}::get{{Title $a.Name}},
{{- if $a.Readonly}} nullptr{{else}} &W{{$.Name}}::set{{Title $a.Name}}{{end -}} {{- if $a.Readonly}} nullptr{{else}} &W{{$.Name}}::set{{Title $a.Name}}{{end -}}
), ),
{{- end}} {{- end}}
{{- end}} {{- end}}
{{- range $c := ConstantsOf $}} {{- range $c := $constants}}
StaticValue("{{$c.Name}}", ToJS(env, {{$.Name}}::{{$c.Name}}), napi_default_jsproperty), StaticValue("{{$c.Name}}", ToJS(env, {{$.Name}}::{{$c.Name}}), napi_default_jsproperty),
{{- end}} {{- end}}
}); });
@ -165,7 +168,7 @@ Wrappers* Wrappers::instance = nullptr;
W{{$.Name}}(const Napi::CallbackInfo& info) : ObjectWrap(info) {} W{{$.Name}}(const Napi::CallbackInfo& info) : ObjectWrap(info) {}
{{ if $s := SetlikeOf $}} {{- if $s := SetlikeOf $}}
Napi::Value has(const Napi::CallbackInfo& info) { Napi::Value has(const Napi::CallbackInfo& info) {
std::tuple<{{template "Type" $s.Elem}}> args; std::tuple<{{template "Type" $s.Elem}}> args;
auto res = FromJS(info, args); auto res = FromJS(info, args);
@ -179,7 +182,7 @@ Wrappers* Wrappers::instance = nullptr;
return ToJS(info.Env(), impl->keys(info.Env())); return ToJS(info.Env(), impl->keys(info.Env()));
} }
{{- end}} {{- end}}
{{- range $m := MethodsOf $}} {{- range $m := $methods}}
Napi::Value {{$m.Name}}(const Napi::CallbackInfo& info) { Napi::Value {{$m.Name}}(const Napi::CallbackInfo& info) {
std::string error; std::string error;
{{- range $overload_idx, $o := $m.Overloads}} {{- range $overload_idx, $o := $m.Overloads}}
@ -222,7 +225,7 @@ Wrappers* Wrappers::instance = nullptr;
} }
{{- end}} {{- end}}
{{- range $a := AttributesOf $}} {{- range $a := $attributes}}
{{- if not (HasAnnotation $a "SameObject")}} {{- if not (HasAnnotation $a "SameObject")}}
Napi::Value get{{Title $a.Name}}(const Napi::CallbackInfo& info) { Napi::Value get{{Title $a.Name}}(const Napi::CallbackInfo& info) {
return ToJS(info.Env(), impl->get{{Title $a.Name}}(info.Env())); return ToJS(info.Env(), impl->get{{Title $a.Name}}(info.Env()));

View File

@ -113,6 +113,9 @@ func run() error {
"EnumEntryName": enumEntryName, "EnumEntryName": enumEntryName,
"Eval": g.eval, "Eval": g.eval,
"HasAnnotation": hasAnnotation, "HasAnnotation": hasAnnotation,
"FlattenedAttributesOf": g.flattenedAttributesOf,
"FlattenedConstantsOf": g.flattenedConstantsOf,
"FlattenedMethodsOf": g.flattenedMethodsOf,
"Include": g.include, "Include": g.include,
"IsBasicLiteral": is(ast.BasicLiteral{}), "IsBasicLiteral": is(ast.BasicLiteral{}),
"IsInitializer": isInitializer, "IsInitializer": isInitializer,
@ -571,6 +574,22 @@ func methodsOf(obj interface{}) []*Method {
return out return out
} }
// flattenedMethodsOf returns all the methods of the given WebIDL
// interface or namespace, as well as all the methods of the full inheritance
// chain
func (g *generator) flattenedMethodsOf(obj interface{}) []*Method {
switch obj := obj.(type) {
case *ast.Interface:
out := methodsOf(obj)
if base := g.lookup(obj.Inherits); base != nil {
out = append(out, g.flattenedMethodsOf(base)...)
}
return out
default:
return methodsOf(obj)
}
}
// attributesOf returns all the attributes of the given WebIDL interface or // attributesOf returns all the attributes of the given WebIDL interface or
// namespace. // namespace.
func attributesOf(obj interface{}) []*ast.Member { func attributesOf(obj interface{}) []*ast.Member {
@ -580,6 +599,7 @@ func attributesOf(obj interface{}) []*ast.Member {
out = append(out, m) out = append(out, m)
} }
} }
switch obj := obj.(type) { switch obj := obj.(type) {
case *ast.Interface: case *ast.Interface:
for _, m := range obj.Members { for _, m := range obj.Members {
@ -595,6 +615,22 @@ func attributesOf(obj interface{}) []*ast.Member {
return out return out
} }
// flattenedAttributesOf returns all the attributes of the given WebIDL
// interface or namespace, as well as all the attributes of the full inheritance
// chain
func (g *generator) flattenedAttributesOf(obj interface{}) []*ast.Member {
switch obj := obj.(type) {
case *ast.Interface:
out := attributesOf(obj)
if base := g.lookup(obj.Inherits); base != nil {
out = append(out, g.flattenedAttributesOf(base)...)
}
return out
default:
return attributesOf(obj)
}
}
// constantsOf returns all the constant values of the given WebIDL interface or // constantsOf returns all the constant values of the given WebIDL interface or
// namespace. // namespace.
func constantsOf(obj interface{}) []*ast.Member { func constantsOf(obj interface{}) []*ast.Member {
@ -619,6 +655,22 @@ func constantsOf(obj interface{}) []*ast.Member {
return out return out
} }
// flattenedConstantsOf returns all the constants of the given WebIDL
// interface or namespace, as well as all the constants of the full inheritance
// chain
func (g *generator) flattenedConstantsOf(obj interface{}) []*ast.Member {
switch obj := obj.(type) {
case *ast.Interface:
out := constantsOf(obj)
if base := g.lookup(obj.Inherits); base != nil {
out = append(out, g.flattenedConstantsOf(base)...)
}
return out
default:
return constantsOf(obj)
}
}
// setlikeOf returns the setlike ast.Pattern, if obj is a setlike interface. // setlikeOf returns the setlike ast.Pattern, if obj is a setlike interface.
func setlikeOf(obj interface{}) *ast.Pattern { func setlikeOf(obj interface{}) *ast.Pattern {
iface, ok := obj.(*ast.Interface) iface, ok := obj.(*ast.Interface)