From d96f7c22eda7cae816cfdf0252b94771fa487286 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Mon, 24 Oct 2022 22:59:44 +0000 Subject: [PATCH] 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 Kokoro: Kokoro Reviewed-by: Austin Eng Commit-Queue: Ben Clayton --- src/dawn/node/interop/WebGPU.cpp.tmpl | 15 ++++--- src/dawn/node/tools/src/cmd/idlgen/main.go | 52 ++++++++++++++++++++++ 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/dawn/node/interop/WebGPU.cpp.tmpl b/src/dawn/node/interop/WebGPU.cpp.tmpl index f711b1ecfa..a8f8bc8404 100644 --- a/src/dawn/node/interop/WebGPU.cpp.tmpl +++ b/src/dawn/node/interop/WebGPU.cpp.tmpl @@ -138,6 +138,9 @@ Wrappers* Wrappers::instance = nullptr; */ -}} {{- define "Wrapper"}} struct W{{$.Name}} : public Napi::ObjectWrap { +{{- $attributes := FlattenedAttributesOf $ }} +{{- $constants := FlattenedConstantsOf $ }} +{{- $methods := FlattenedMethodsOf $ }} {{- if IsInterface $}} std::unique_ptr<{{$.Name}}> impl; {{- end}} @@ -147,17 +150,17 @@ Wrappers* Wrappers::instance = nullptr; InstanceMethod("has", &W{{$.Name}}::has), InstanceMethod("keys", &W{{$.Name}}::keys), {{- end}} -{{- range $m := MethodsOf $}} +{{- range $m := $methods}} InstanceMethod("{{$m.Name}}", &W{{$.Name}}::{{$m.Name}}), {{- end}} -{{- range $a := AttributesOf $}} +{{- range $a := $attributes}} {{- if not (HasAnnotation $a "SameObject")}} InstanceAccessor("{{$a.Name}}", &W{{$.Name}}::get{{Title $a.Name}}, {{- if $a.Readonly}} nullptr{{else}} &W{{$.Name}}::set{{Title $a.Name}}{{end -}} ), {{- end}} {{- end}} -{{- range $c := ConstantsOf $}} +{{- range $c := $constants}} StaticValue("{{$c.Name}}", ToJS(env, {{$.Name}}::{{$c.Name}}), napi_default_jsproperty), {{- end}} }); @@ -165,7 +168,7 @@ Wrappers* Wrappers::instance = nullptr; W{{$.Name}}(const Napi::CallbackInfo& info) : ObjectWrap(info) {} -{{ if $s := SetlikeOf $}} +{{- if $s := SetlikeOf $}} Napi::Value has(const Napi::CallbackInfo& info) { std::tuple<{{template "Type" $s.Elem}}> args; auto res = FromJS(info, args); @@ -179,7 +182,7 @@ Wrappers* Wrappers::instance = nullptr; return ToJS(info.Env(), impl->keys(info.Env())); } {{- end}} -{{- range $m := MethodsOf $}} +{{- range $m := $methods}} Napi::Value {{$m.Name}}(const Napi::CallbackInfo& info) { std::string error; {{- range $overload_idx, $o := $m.Overloads}} @@ -222,7 +225,7 @@ Wrappers* Wrappers::instance = nullptr; } {{- end}} -{{- range $a := AttributesOf $}} +{{- range $a := $attributes}} {{- if not (HasAnnotation $a "SameObject")}} Napi::Value get{{Title $a.Name}}(const Napi::CallbackInfo& info) { return ToJS(info.Env(), impl->get{{Title $a.Name}}(info.Env())); diff --git a/src/dawn/node/tools/src/cmd/idlgen/main.go b/src/dawn/node/tools/src/cmd/idlgen/main.go index a465591e80..4fd6cbf9fe 100644 --- a/src/dawn/node/tools/src/cmd/idlgen/main.go +++ b/src/dawn/node/tools/src/cmd/idlgen/main.go @@ -113,6 +113,9 @@ func run() error { "EnumEntryName": enumEntryName, "Eval": g.eval, "HasAnnotation": hasAnnotation, + "FlattenedAttributesOf": g.flattenedAttributesOf, + "FlattenedConstantsOf": g.flattenedConstantsOf, + "FlattenedMethodsOf": g.flattenedMethodsOf, "Include": g.include, "IsBasicLiteral": is(ast.BasicLiteral{}), "IsInitializer": isInitializer, @@ -571,6 +574,22 @@ func methodsOf(obj interface{}) []*Method { 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 // namespace. func attributesOf(obj interface{}) []*ast.Member { @@ -580,6 +599,7 @@ func attributesOf(obj interface{}) []*ast.Member { out = append(out, m) } } + switch obj := obj.(type) { case *ast.Interface: for _, m := range obj.Members { @@ -595,6 +615,22 @@ func attributesOf(obj interface{}) []*ast.Member { 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 // namespace. func constantsOf(obj interface{}) []*ast.Member { @@ -619,6 +655,22 @@ func constantsOf(obj interface{}) []*ast.Member { 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. func setlikeOf(obj interface{}) *ast.Pattern { iface, ok := obj.(*ast.Interface)