diff --git a/lib/writer.js b/lib/writer.js index 653fcf61..3ee66418 100644 --- a/lib/writer.js +++ b/lib/writer.js @@ -10,6 +10,7 @@ const templates = { name: noop, reference: noop, type: noop, + generic: noop, inheritance: noop, definition: noop, extendedAttribute: noop, @@ -19,34 +20,30 @@ const templates = { export function write(ast, { templates: ts = templates } = {}) { ts = Object.assign({}, templates, ts); - /** - * @param {string[]} strings - * @param {...any} args - */ - function wrap(strings, ...args) { - return ts.wrap([].concat(...strings.map((s, i) => [s, args[i] || ""]))); - } - function reference(raw, unescaped) { return ts.reference(raw, unescaped || raw); } - function token(t, value) { - return t ? wrap`${ts.trivia(t.trivia)}${value || t.value}` : ""; + function token(t, wrapper = noop, ...args) { + if (!t) { + return ""; + } + const value = wrapper(t.value, ...args); + return ts.wrap([ts.trivia(t.trivia), value]); } function reference_token(t, unescaped) { - return t ? wrap`${ts.trivia(t.trivia)}${reference(t.value, unescaped)}` : ""; + return token(t, reference, unescaped); } function name_token(t, arg) { - return t ? wrap`${ts.trivia(t.trivia)}${ts.name(t.value, arg)}` : ""; + return token(t, ts.name, arg); } function type_body(it) { if (it.union || it.generic) { return ts.wrap([ - reference_token(it.tokens.base), + token(it.tokens.base, ts.generic), token(it.tokens.open), ...it.subtype.map(type), token(it.tokens.close) @@ -246,7 +243,10 @@ export function write(ast, { templates: ts = templates } = {}) { function enum_value(v, parent) { return ts.wrap([ ts.trivia(v.tokens.value.trivia), - ts.definition(wrap`"${ts.name(v.value, { data: v, parent })}"`, { data: v, parent }), + ts.definition( + ts.wrap(['"', ts.name(v.value, { data: v, parent }), '"']), + { data: v, parent } + ), token(v.tokens.separator) ]); } @@ -254,7 +254,7 @@ export function write(ast, { templates: ts = templates } = {}) { return ts.definition(ts.wrap([ extended_attributes(it.extAttrs), token(it.tokens.readonly), - token(it.tokens.base), + token(it.tokens.base, ts.generic), token(it.tokens.open), ts.wrap(it.idlType.map(type)), token(it.tokens.close), diff --git a/test/writer.js b/test/writer.js index d2a71abe..fcb793e1 100644 --- a/test/writer.js +++ b/test/writer.js @@ -70,7 +70,7 @@ describe("Writer template functions", () => { } const result = rewriteReference("[Exposed=Window] interface Momo : Kudamono { attribute Promise iro; };"); - expect(result).toBe("[Exposed=] interface Momo : { attribute <> iro; };"); + expect(result).toBe("[Exposed=] interface Momo : { attribute Promise<> iro; };"); const includes = rewriteReference("_A includes _B;"); expect(includes).toBe("<_A> includes <_B>;"); @@ -82,12 +82,21 @@ describe("Writer template functions", () => { } const result = rewriteReference("[Exposed=Window] interface Momo : _Kudamono { attribute Promise<_Type> iro; attribute _Type sugar; };"); - expect(result).toBe("[Exposed=] interface Momo : { attribute <> iro; attribute sugar; };"); + expect(result).toBe("[Exposed=] interface Momo : { attribute Promise<> iro; attribute sugar; };"); const includes = rewriteReference("_A includes _B;"); expect(includes).toBe(" includes ;"); }); + it("catches generics", () => { + function rewriteGeneric(text) { + return rewrite(text, { generic: bracket }); + } + + const result = rewriteGeneric("[Exposed=Window] interface Momo : Kudamono { attribute Promise iro; iterable; };"); + expect(result).toBe("[Exposed=Window] interface Momo : Kudamono { attribute iro; ; };"); + }); + it("catches types", () => { const result = rewrite("interface Momo { attribute Promise iro; };", { type: bracket