dawn_node: Add template files
Templates used to generate the NodeJS interop classes for the WebGPU IDL. Also includes a stub `Browser.idl` file that provides stub definitions for browser IDL declarations referenced by the WebGPU IDL. Bug: dawn:1123 Change-Id: I4067cb186f63436a502c3516a879ed1c5cd30731 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/64902 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
6d8a03e707
commit
897cdeeb61
|
@ -0,0 +1,84 @@
|
|||
// Copyright 2021 The Dawn 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.
|
||||
|
||||
// An IDL file that provides stub definitions for dictionaries and interfaces
|
||||
// used by the webgpu.idl file
|
||||
|
||||
dictionary EventInit {
|
||||
boolean bubbles = false;
|
||||
boolean cancelable = false;
|
||||
boolean composed = false;
|
||||
};
|
||||
|
||||
interface Navigator {
|
||||
readonly attribute DOMString vendorSub;
|
||||
readonly attribute DOMString productSub;
|
||||
readonly attribute DOMString vendor;
|
||||
};
|
||||
|
||||
interface Event {
|
||||
readonly attribute boolean bubbles;
|
||||
readonly attribute boolean cancelable;
|
||||
attribute boolean returnValue;
|
||||
};
|
||||
|
||||
interface WorkerNavigator{};
|
||||
|
||||
interface EventListener {
|
||||
undefined handleEvent(Event event);
|
||||
};
|
||||
|
||||
interface EventTarget {
|
||||
undefined addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options);
|
||||
undefined removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
|
||||
boolean dispatchEvent(Event event);
|
||||
};
|
||||
|
||||
dictionary EventListenerOptions { boolean capture = false; };
|
||||
|
||||
dictionary AddEventListenerOptions : EventListenerOptions {
|
||||
boolean passive = false;
|
||||
boolean once = false;
|
||||
};
|
||||
|
||||
interface HTMLVideoElement {
|
||||
attribute unsigned long width;
|
||||
attribute unsigned long height;
|
||||
readonly attribute unsigned long videoWidth;
|
||||
readonly attribute unsigned long videoHeight;
|
||||
attribute DOMString poster;
|
||||
};
|
||||
|
||||
typedef(Int8Array or Int16Array or Int32Array or Uint8Array or Uint16Array or
|
||||
Uint32Array or Float32Array or Float64Array or
|
||||
DataView) ArrayBufferView;
|
||||
|
||||
typedef(ArrayBufferView or ArrayBuffer) BufferSource;
|
||||
|
||||
interface ImageBitmap {
|
||||
readonly attribute unsigned long width;
|
||||
readonly attribute unsigned long height;
|
||||
};
|
||||
|
||||
interface HTMLCanvasElement {
|
||||
attribute unsigned long width;
|
||||
attribute unsigned long height;
|
||||
};
|
||||
|
||||
interface OffscreenCanvas {
|
||||
attribute unsigned long width;
|
||||
attribute unsigned long height;
|
||||
};
|
||||
|
||||
interface EventHandler{};
|
|
@ -0,0 +1,341 @@
|
|||
{{/*
|
||||
Copyright 2021 The Dawn 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.
|
||||
*/}}
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
Template file for use with src/dawn_node/tools/cmd/idlgen/main.go to generate
|
||||
the WebGPU.cpp source file.
|
||||
|
||||
See:
|
||||
* https://github.com/ben-clayton/webidlparser/blob/main/ast/ast.go for the AST
|
||||
types used by this template
|
||||
* src/dawn_node/tools/cmd/idlgen/main.go for additional structures and functions
|
||||
used by this template
|
||||
* https://golang.org/pkg/text/template/ for documentation on the template syntax
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
|
||||
{{- Include "WebGPUCommon.tmpl" -}}
|
||||
|
||||
#include "src/dawn_node/interop/WebGPU.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "src/dawn_node/utils/Debug.h"
|
||||
|
||||
namespace wgpu {
|
||||
namespace interop {
|
||||
|
||||
namespace {
|
||||
|
||||
{{template "Wrappers" $}}
|
||||
|
||||
} // namespace
|
||||
|
||||
{{ range $ := .Declarations}}
|
||||
{{- if IsDictionary $}}{{template "Dictionary" $}}
|
||||
{{- else if IsInterface $}}{{template "Interface" $}}
|
||||
{{- else if IsEnum $}}{{template "Enum" $}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
|
||||
void Initialize(Napi::Env env) {
|
||||
auto* wrapper = Wrappers::Init(env);
|
||||
auto global = env.Global();
|
||||
{{ range $ := .Declarations}}
|
||||
{{- if IsInterfaceOrNamespace $}}
|
||||
global.Set(Napi::String::New(env, "{{$.Name}}"), wrapper->{{$.Name}}_ctor.Value());
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
} // namespace interop
|
||||
} // namespace wgpu
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Wrappers emits the C++ 'Wrappers' class, which holds all the interface and
|
||||
-- namespace interop wrapper classes.
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Wrappers"}}
|
||||
// Wrappers holds all the Napi class constructors, and Napi::ObjectWrap type
|
||||
// declarations, for each of the WebIDL interface and namespace types.
|
||||
class Wrappers {
|
||||
Wrappers(Napi::Env env) {
|
||||
{{- range $ := .Declarations}}
|
||||
{{- if IsInterfaceOrNamespace $}}
|
||||
{{$.Name}}_ctor = Napi::Persistent(W{{$.Name}}::Class(env));
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
}
|
||||
|
||||
static Wrappers* instance;
|
||||
|
||||
public:
|
||||
{{- range $ := .Declarations}}
|
||||
{{- if IsInterfaceOrNamespace $}}{{template "Wrapper" $}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
// Allocates and constructs the Wrappers instance
|
||||
static Wrappers* Init(Napi::Env env) {
|
||||
instance = new Wrappers(env);
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Destructs and frees the Wrappers instance
|
||||
static void Term(Napi::Env env) {
|
||||
delete instance;
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
static Wrappers* For(Napi::Env env) {
|
||||
// Currently Napi only actually supports a single Env, so there's no point
|
||||
// maintaining a map of Env to Wrapper. Note: This might not always be true.
|
||||
return instance;
|
||||
}
|
||||
|
||||
{{ range $ := .Declarations}}
|
||||
{{- if IsInterfaceOrNamespace $}}
|
||||
Napi::FunctionReference {{$.Name}}_ctor;
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
};
|
||||
|
||||
Wrappers* Wrappers::instance = nullptr;
|
||||
{{- end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Wrapper emits the C++ wrapper class for the given ast.Interface or
|
||||
-- ast.Namespace.
|
||||
-- This wrapper class inherits from Napi::ObjectWrap, which binds the lifetime
|
||||
-- of the JavaScript object to the lifetime of the wrapper class instance.
|
||||
-- If the wrapper is for an interface, the wrapper object holds a unique_ptr to
|
||||
-- the interface implementation, and delegates all exposed method calls on to
|
||||
-- the implementation.
|
||||
-- See: https://github.com/nodejs/node-addon-api/blob/main/doc/object_wrap.md
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Wrapper"}}
|
||||
struct W{{$.Name}} : public Napi::ObjectWrap<W{{$.Name}}> {
|
||||
{{- if IsInterface $}}
|
||||
std::unique_ptr<{{$.Name}}> impl;
|
||||
{{- end}}
|
||||
static Napi::Function Class(Napi::Env env) {
|
||||
return DefineClass(env, "{{$.Name}}", {
|
||||
{{- range $m := MethodsOf $}}
|
||||
InstanceMethod("{{$m.Name}}", &W{{$.Name}}::{{$m.Name}}),
|
||||
{{- end}}
|
||||
{{- range $a := AttributesOf $}}
|
||||
InstanceAccessor("{{$a.Name}}", &W{{$.Name}}::get{{Title $a.Name}},
|
||||
{{- if $a.Readonly}} nullptr{{else}} &W{{$.Name}}::set{{Title $a.Name}}{{end -}}
|
||||
),
|
||||
{{- end}}
|
||||
{{- range $c := ConstantsOf $}}
|
||||
StaticValue("{{$c.Name}}", ToJS(env, {{$.Name}}::{{$c.Name}})),
|
||||
{{- end}}
|
||||
});
|
||||
}
|
||||
|
||||
W{{$.Name}}(const Napi::CallbackInfo& info) : ObjectWrap(info) {}
|
||||
{{- range $m := MethodsOf $}}
|
||||
Napi::Value {{$m.Name}}(const Napi::CallbackInfo& info) {
|
||||
{{- range $overload_idx, $o := $m.Overloads}}
|
||||
{ // Overload {{$overload_idx}}
|
||||
std::tuple<
|
||||
{{- range $i, $p := $o.Parameters}}
|
||||
{{- if $i}}, {{end}}
|
||||
{{- if $p.Optional}}std::optional<{{template "Type" $p.Type}}>
|
||||
{{- else }}{{template "Type" $p.Type}}
|
||||
{{- end}}
|
||||
{{- end}}> args;
|
||||
if (FromJS(info, args)) {
|
||||
{{/* indent */}}INTEROP_LOG(
|
||||
{{- range $i, $p := $o.Parameters}}
|
||||
{{- if $i}}, ", {{$p.Name}}: "{{else}}"{{$p.Name}}: "{{end}}, std::get<{{$i}}>(args)
|
||||
{{- end}});
|
||||
{{/* indent */}}
|
||||
{{- if not (IsUndefinedType $o.Type) }}auto result = {{end -}}
|
||||
impl->{{$o.Name}}(info.Env(){{range $i, $_ := $o.Parameters}}, std::get<{{$i}}>(args){{end}});
|
||||
{{/* indent */ -}}
|
||||
{{- if IsUndefinedType $o.Type}}return info.Env().Null();
|
||||
{{- else }}return ToJS(info.Env(), result);
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
{{- end}}
|
||||
Napi::Error::New(info.Env(), "invalid arguments to {{$m.Name}}").ThrowAsJavaScriptException();
|
||||
return {};
|
||||
}
|
||||
{{- end}}
|
||||
|
||||
{{- range $a := AttributesOf $}}
|
||||
Napi::Value get{{Title $a.Name}}(const Napi::CallbackInfo& info) {
|
||||
return ToJS(info.Env(), impl->get{{Title $a.Name}}(info.Env()));
|
||||
}
|
||||
{{- if not $a.Readonly}}
|
||||
void set{{Title $a.Name}}(const Napi::CallbackInfo& info, const Napi::Value& value) {
|
||||
{{template "Type" $a.Type}} v{};
|
||||
if (FromJS(info.Env(), value, v)) {
|
||||
impl->set{{Title $a.Name}}(info.Env(), std::move(v));
|
||||
} else {
|
||||
Napi::Error::New(info.Env(), "invalid value to {{$a.Name}}").ThrowAsJavaScriptException();
|
||||
}
|
||||
}
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
};
|
||||
{{end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Dictionary emits the C++ method implementations and associated functions of
|
||||
-- the interop type that defines the given ast.Dictionary
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Dictionary"}}
|
||||
bool Converter<{{$.Name}}>::FromJS(Napi::Env env, Napi::Value value, {{$.Name}}& out) {
|
||||
auto object = value.ToObject();
|
||||
return true{{template "DictionaryMembersFromJS" $}};
|
||||
}
|
||||
|
||||
Napi::Value Converter<{{$.Name}}>::ToJS(Napi::Env env, {{$.Name}} value) {
|
||||
auto object = Napi::Object::New(env);
|
||||
{{- template "DictionaryMembersToJS" $}}
|
||||
return object;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const {{$.Name}}& dict) {
|
||||
o << "{{$.Name}} {";
|
||||
{{- range $i, $m := $.Members}}
|
||||
o << {{if $i}}", "{{else}}" "{{end}} << "{{$m.Name}}: ";
|
||||
utils::Write(o, dict.{{$m.Name}});
|
||||
{{- end }}
|
||||
o << "}" << std::endl;
|
||||
return o;
|
||||
}
|
||||
{{ end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- DictionaryMembersFromJS emits the C++ logic to convert each of the
|
||||
-- dictionary ast.Member fields from JavaScript to C++. Each call to FromJS() is
|
||||
-- prefixed with '&&' so that the combined expression is true iff all members
|
||||
-- are converted succesfully
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "DictionaryMembersFromJS"}}
|
||||
{{- if $.Inherits}}{{template "DictionaryMembersFromJS" (Lookup $.Inherits)}}{{end}}
|
||||
{{- range $i, $m := $.Members}} &&
|
||||
{{/* indent */}}
|
||||
{{- if $m.Init }}interop::FromJSOptional(env, object.Get("{{$m.Name}}"), out.{{$m.Name}})
|
||||
{{- else }}interop::FromJS(env, object.Get("{{$m.Name}}"), out.{{$m.Name}})
|
||||
{{- end }}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- DictionaryMembersToJS emits the C++ logic to convert each of the
|
||||
-- dictionary ast.Member fields to JavaScript from C++. Each call to ToJS() is
|
||||
-- emitted as a separate statement
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "DictionaryMembersToJS"}}
|
||||
{{- if $.Inherits}}{{template "DictionaryMembersToJS" (Lookup $.Inherits)}}{{end}}
|
||||
{{- range $m := $.Members}}
|
||||
object.Set(Napi::String::New(env, "{{$m.Name}}"), interop::ToJS(env, value.{{$m.Name}}));
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Interface emits the C++ method implementations that define the given
|
||||
-- ast.Interface.
|
||||
-- Note: Most of the actual binding logic lives in the interface wrapper class.
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Interface"}}
|
||||
{{$.Name}}::{{$.Name}}() = default;
|
||||
|
||||
{{$.Name}}* {{$.Name}}::Unwrap(Napi::Object object) {
|
||||
auto* wrappers = Wrappers::For(object.Env());
|
||||
if (!object.InstanceOf(wrappers->{{$.Name}}_ctor.Value())) {
|
||||
return nullptr;
|
||||
}
|
||||
return Wrappers::W{{$.Name}}::Unwrap(object)->impl.get();
|
||||
}
|
||||
|
||||
Interface<{{$.Name}}> {{$.Name}}::Bind(Napi::Env env, std::unique_ptr<{{$.Name}}>&& impl) {
|
||||
auto* wrappers = Wrappers::For(env);
|
||||
auto object = wrappers->{{$.Name}}_ctor.New({});
|
||||
auto* wrapper = Wrappers::W{{$.Name}}::Unwrap(object);
|
||||
wrapper->impl = std::move(impl);
|
||||
return Interface<{{$.Name}}>(object);
|
||||
}
|
||||
|
||||
{{$.Name}}::~{{$.Name}}() = default;
|
||||
{{ end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Enum emits the C++ associated functions of the interop type that defines the
|
||||
-- given ast.Enum
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Enum"}}
|
||||
bool Converter<{{$.Name}}>::FromJS(Napi::Env env, Napi::Value value, {{$.Name}}& out) {
|
||||
std::string str = value.ToString();
|
||||
{{- range $e := $.Values}}
|
||||
if (str == {{$e.Value}}) {
|
||||
out = {{$.Name}}::{{EnumEntryName $e.Value}};
|
||||
return true;
|
||||
}
|
||||
{{- end}}
|
||||
return false;
|
||||
}
|
||||
Napi::Value Converter<{{$.Name}}>::ToJS(Napi::Env env, {{$.Name}} value) {
|
||||
switch (value) {
|
||||
{{- range $e := $.Values}}
|
||||
case {{$.Name}}::{{EnumEntryName $e.Value}}:
|
||||
return Napi::String::New(env, {{$e.Value}});
|
||||
break;
|
||||
{{- end}}
|
||||
}
|
||||
return env.Undefined();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, {{$.Name}} value) {
|
||||
switch (value) {
|
||||
{{- range $e := $.Values}}
|
||||
case {{$.Name}}::{{EnumEntryName $e.Value}}:
|
||||
return o << {{$e.Value}};
|
||||
{{- end}}
|
||||
}
|
||||
return o << "undefined<{{$.Name}}>";
|
||||
}
|
||||
|
||||
{{end}}
|
|
@ -0,0 +1,263 @@
|
|||
{{/*
|
||||
Copyright 2021 The Dawn 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.
|
||||
*/}}
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
Template file for use with src/dawn_node/tools/cmd/idlgen/main.go to generate
|
||||
the WebGPU.h header file.
|
||||
|
||||
See:
|
||||
* https://github.com/ben-clayton/webidlparser/blob/main/ast/ast.go for the AST
|
||||
types used by this template
|
||||
* src/dawn_node/tools/cmd/idlgen/main.go for additional structures and functions
|
||||
used by this template
|
||||
* https://golang.org/pkg/text/template/ for documentation on the template syntax
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
|
||||
{{- Include "WebGPUCommon.tmpl" -}}
|
||||
|
||||
#ifndef DAWN_NODE_GEN_INTEROP_WEBGPU_H_
|
||||
#define DAWN_NODE_GEN_INTEROP_WEBGPU_H_
|
||||
|
||||
#include "src/dawn_node/interop/Core.h"
|
||||
|
||||
namespace wgpu {
|
||||
namespace interop {
|
||||
|
||||
// Initialize() registers the WebGPU types with the Napi environment.
|
||||
void Initialize(Napi::Env env);
|
||||
|
||||
{{ range $ := .Declarations}}
|
||||
{{- if IsDictionary $}}{{template "Dictionary" $}}
|
||||
{{- else if IsNamespace $}}{{template "Namespace" $}}
|
||||
{{- else if IsInterface $}}{{template "Interface" $}}
|
||||
{{- else if IsEnum $}}{{template "Enum" $}}
|
||||
{{- else if IsTypedef $}}{{template "Typedef" $}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
|
||||
} // namespace interop
|
||||
} // namespace wgpu
|
||||
|
||||
#endif // DAWN_NODE_GEN_INTEROP_WEBGPU_H_
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Dictionary emits the C++ header declaration that defines the interop type for
|
||||
-- the given ast.Dictionary
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Dictionary"}}
|
||||
// dictionary {{$.Name}}
|
||||
class {{$.Name}} {{- if $.Inherits }} : public {{$.Inherits}}{{end}} {
|
||||
public:
|
||||
{{ range $m := $.Members}}
|
||||
{{- if IsConstructor $m}} {{$.Name}}();
|
||||
{{ else if IsMember $m}} {{template "DictionaryMember" $m}}
|
||||
{{ end}}
|
||||
{{- end -}}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Converter<{{$.Name}}> {
|
||||
public:
|
||||
static bool FromJS(Napi::Env, Napi::Value, {{$.Name}}&);
|
||||
static Napi::Value ToJS(Napi::Env, {{$.Name}});
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const {{$.Name}}& desc);
|
||||
{{end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Namespace emits the C++ header declaration that defines the interop type for
|
||||
-- the given ast.Namespace
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Namespace"}}
|
||||
// namespace {{$.Name}}
|
||||
class {{$.Name}} {
|
||||
public:
|
||||
virtual ~{{$.Name}}();
|
||||
{{$.Name}}();
|
||||
{{- range $c := ConstantsOf $}}
|
||||
{{- template "Constant" $c}}
|
||||
{{- end}}
|
||||
};
|
||||
{{end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Interface emits the C++ header declaration that defines the interop type for
|
||||
-- the given ast.Interface
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Interface"}}
|
||||
// interface {{$.Name}}
|
||||
class {{$.Name}} {{- if $.Inherits }} : public {{$.Inherits}}{{end}} {
|
||||
public:
|
||||
static Interface<{{$.Name}}> Bind(Napi::Env, std::unique_ptr<{{$.Name}}>&&);
|
||||
static {{$.Name}}* Unwrap(Napi::Object);
|
||||
|
||||
template<typename T, typename ... ARGS>
|
||||
static inline Interface<{{$.Name}}> Create(Napi::Env env, ARGS&& ... args) {
|
||||
return Bind(env, std::make_unique<T>(std::forward<ARGS>(args)...));
|
||||
}
|
||||
|
||||
virtual ~{{$.Name}}();
|
||||
{{$.Name}}();
|
||||
{{- range $m := MethodsOf $}}
|
||||
{{- template "InterfaceMethod" $m}}
|
||||
{{- end}}
|
||||
{{- range $a := AttributesOf $}}
|
||||
{{- template "InterfaceAttribute" $a}}
|
||||
{{- end}}
|
||||
{{- range $c := ConstantsOf $}}
|
||||
{{- template "Constant" $c}}
|
||||
{{- end}}
|
||||
};
|
||||
{{end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Typedef emits the C++ header declaration that defines the interop type for
|
||||
-- the given ast.Interface
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Typedef"}}
|
||||
using {{$.Name}} = {{template "Type" $.Type}};
|
||||
{{end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Enum emits the C++ header declaration that defines the interop type for
|
||||
-- the given ast.Enum
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Enum"}}
|
||||
enum class {{$.Name}} {
|
||||
{{- range $ := $.Values}}
|
||||
{{EnumEntryName $.Value}},
|
||||
{{- end}}
|
||||
};
|
||||
|
||||
template<>
|
||||
class Converter<{{$.Name}}> {
|
||||
public:
|
||||
static bool FromJS(Napi::Env, Napi::Value, {{$.Name}}&);
|
||||
static Napi::Value ToJS(Napi::Env, {{$.Name}});
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, {{$.Name}});
|
||||
{{end}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- DictionaryMember emits the C++ declaration for a single dictionary ast.Member
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "DictionaryMember"}}
|
||||
{{- if $.Attribute}}{{template "AttributeType" $}} {{$.Name}}
|
||||
{{- if $.Init}} = {{Eval "Literal" "Value" $.Init "Type" $.Type}}{{end}};
|
||||
{{- else }}{{template "Type" $.Type}} {{$.Name}}({{template "Parameters" $.Parameters}});
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- InterfaceMethod emits the C++ declaration for a single interface ast.Member
|
||||
-- method
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "InterfaceMethod"}}
|
||||
{{- range $o := $.Overloads}}
|
||||
virtual {{template "Type" $o.Type}} {{$.Name}}(Napi::Env{{template "ParametersWithLeadingComma" $o.Parameters}}) = 0;
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- InterfaceAttribute emits the C++ declaration for a single interface
|
||||
-- ast.Member attribute
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "InterfaceAttribute"}}
|
||||
virtual {{template "Type" $.Type}} get{{Title $.Name}}(Napi::Env) = 0;
|
||||
{{- if not $.Readonly}}
|
||||
virtual void set{{Title $.Name}}(Napi::Env, {{template "Type" $.Type}} value) = 0;
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Constant emits the C++ declaration for a single ast.Member constant
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Constant"}}
|
||||
static constexpr {{template "Type" $.Type}} {{$.Name}} = {{Eval "Literal" "Value" $.Init "Type" $.Type}};
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Parameters emits the C++ comma separated list of parameter declarations for
|
||||
-- the given []ast.Parameter
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Parameters"}}
|
||||
{{- range $i, $param := $ }}
|
||||
{{- if $i }}, {{end}}
|
||||
{{- template "Parameter" $param}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- ParametersWithLeadingComma emits the C++ comma separated list of parameter
|
||||
-- declarations for the given []ast.Parameter, starting with a leading comma
|
||||
-- for the first parameter
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "ParametersWithLeadingComma"}}
|
||||
{{- range $i, $param := $ }}, {{/* */}}
|
||||
{{- template "Parameter" $param}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Parameter emits the C++ parameter type and name for the given ast.Parameter
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Parameter" -}}
|
||||
{{- if $.Optional -}}
|
||||
std::optional<{{template "Type" $.Type}}> {{$.Name}}
|
||||
{{- else}}
|
||||
{{- template "Type" $.Type}} {{$.Name}}
|
||||
{{- end}}
|
||||
{{- end}}
|
|
@ -0,0 +1,126 @@
|
|||
{{/*
|
||||
Copyright 2021 The Dawn 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.
|
||||
*/}}
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
Template file for use with src/dawn_node/tools/cmd/idlgen/main.go.
|
||||
This file provides common template definitions and is included by WebGPU.h.tmpl
|
||||
and WebGPU.cpp.tmpl.
|
||||
|
||||
See:
|
||||
* https://github.com/ben-clayton/webidlparser/blob/main/ast/ast.go for the AST
|
||||
types used by this template
|
||||
* src/dawn_node/tools/cmd/idlgen/main.go for additional structures and functions
|
||||
used by this template
|
||||
* https://golang.org/pkg/text/template/ for documentation on the template syntax
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Type generates the C++ type for the given ast.Type
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Type" -}}
|
||||
{{- if IsUndefinedType $}}void
|
||||
{{- else if IsTypeName $}}
|
||||
{{- if eq $.Name "boolean" }}bool
|
||||
{{- else if eq $.Name "long" }}int32_t
|
||||
{{- else if eq $.Name "unsigned long" }}uint32_t
|
||||
{{- else if eq $.Name "long long" }}int64_t
|
||||
{{- else if eq $.Name "unsigned long long" }}uint64_t
|
||||
{{- else if eq $.Name "object" }}Object
|
||||
{{- else if eq $.Name "DOMString" }}std::string
|
||||
{{- else if eq $.Name "USVString" }}std::string
|
||||
{{- else if eq $.Name "ArrayBuffer" }}ArrayBuffer
|
||||
{{- else if IsInterface (Lookup $.Name) }}Interface<{{$.Name}}>
|
||||
{{- else }}{{$.Name}}
|
||||
{{- end }}
|
||||
{{- else if IsParametrizedType $}}{{$.Name}}<{{template "TypeList" $.Elems}}>
|
||||
{{- else if IsNullableType $}}std::optional<{{template "Type" $.Type}}>
|
||||
{{- else if IsUnionType $}}std::variant<{{template "VariantTypeList" $.Types}}>
|
||||
{{- else if IsSequenceType $}}std::vector<{{template "Type" $.Elem}}>
|
||||
{{- else if IsRecordType $}}std::unordered_map<{{template "Type" $.Key}}, {{template "Type" $.Elem}}>
|
||||
{{- else }} /* Unhandled Type {{printf "%T" $}} */
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- AttributeType generates the C++ type for the given ast.Member
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "AttributeType" -}}
|
||||
{{- if $.Required }}{{template "Type" $.Type}}
|
||||
{{- else if $.Init }}{{template "Type" $.Type}}
|
||||
{{- else }}std::optional<{{template "Type" $.Type}}>
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- Literal generates a C++ literal value using the following arguments:
|
||||
-- Value - the ast.Literal
|
||||
-- Type - the ast.Type of the literal
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "Literal" -}}
|
||||
{{- if IsDefaultDictionaryLiteral $.Value}}{{template "Type" $.Type}}{}
|
||||
{{- else if IsTypeName $.Type }}
|
||||
{{- $ty := Lookup $.Type.Name}}
|
||||
{{- if IsEnum $ty }}{{$.Type.Name}}::{{EnumEntryName $.Value.Value}}
|
||||
{{- else if IsBasicLiteral $.Value }}{{$.Value.Value}}
|
||||
{{- else }}/* Unhandled Type {{printf "ty: %v $.Type.Name: %T $.Value: %T" $ty $.Type.Name $.Value}} */
|
||||
{{- end }}
|
||||
{{- else if IsSequenceType $.Type }}{{template "Type" $.Type}}{} {{- /* TODO: Assumes the initialiser is empty */}}
|
||||
{{- else if IsBasicLiteral $.Value }}{{$.Value.Value}}
|
||||
{{- else }} /* Unhandled Type {{printf "%T %T" $.Type $.Value}} */
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- TypeList generates a C++ comma separated list of types from the given
|
||||
-- []ast.Type
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "TypeList" -}}
|
||||
{{- range $i, $ty := $}}
|
||||
{{- if $i }}, {{end}}
|
||||
{{- template "Type" $ty}}
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{- /*
|
||||
--------------------------------------------------------------------------------
|
||||
-- VariantTypeList generates a C++ comma separated list of types from the given
|
||||
-- []ast.Type, skipping any 'undefined' types
|
||||
--------------------------------------------------------------------------------
|
||||
*/ -}}
|
||||
{{- define "VariantTypeList" -}}
|
||||
{{- range $i, $ty := $}}
|
||||
{{- if not (IsUndefinedType $ty)}}
|
||||
{{- if $i }}, {{end}}
|
||||
{{- template "Type" $ty}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
{{- end }}
|
||||
|
Loading…
Reference in New Issue