jsgen: prefix JS keywords with 'v_'

pull/4908/head
spaceface777 2020-05-15 15:55:49 +02:00 committed by GitHub
parent 8500c8885c
commit 8de6da01d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 179 additions and 138 deletions

View File

@ -8,8 +8,12 @@ import term
import v.util import v.util
const ( const (
//TODO // https://ecma-international.org/ecma-262/#sec-reserved-words
js_reserved = ['delete', 'const', 'let', 'var', 'function', 'continue', 'break', 'switch', 'for', 'in', 'of', 'instanceof', 'typeof', 'do'] js_reserved = ['await', 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 'finally', 'for', 'function',
'if', 'implements', 'import', 'in', 'instanceof', 'interface', 'let', 'new', 'package', 'private',
'protected', 'public', 'return', 'static', 'super', 'switch', 'this', 'throw', 'try', 'typeof',
'var', 'void', 'while', 'with', 'yield']
tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t'] tabs = ['', '\t', '\t\t', '\t\t\t', '\t\t\t\t', '\t\t\t\t\t', '\t\t\t\t\t\t', '\t\t\t\t\t\t\t', '\t\t\t\t\t\t\t\t']
) )
@ -95,7 +99,6 @@ pub fn (g mut JsGen) enter_namespace(n string) {
g.indents[g.namespace] = 0 g.indents[g.namespace] = 0
g.out.writeln('const $n = (function () {') g.out.writeln('const $n = (function () {')
} }
//
else { else {
g.out = g.namespaces[g.namespace] g.out = g.namespaces[g.namespace]
} }
@ -107,10 +110,7 @@ pub fn (g mut JsGen) escape_namespace() {
} }
pub fn (g mut JsGen) push_pub_var(s string) { pub fn (g mut JsGen) push_pub_var(s string) {
// Workaround until `m[key]<<val` works. g.namespaces_pub[g.namespace] << s
mut arr := g.namespaces_pub[g.namespace]
arr << s
g.namespaces_pub[g.namespace] = arr
} }
pub fn (g mut JsGen) find_class_methods(stmts []ast.Stmt) { pub fn (g mut JsGen) find_class_methods(stmts []ast.Stmt) {
@ -207,11 +207,11 @@ pub fn (g mut JsGen) gen_indent() {
} }
pub fn (g mut JsGen) inc_indent() { pub fn (g mut JsGen) inc_indent() {
g.indents[g.namespace] = g.indents[g.namespace] + 1 g.indents[g.namespace]++
} }
pub fn (g mut JsGen) dec_indent() { pub fn (g mut JsGen) dec_indent() {
g.indents[g.namespace] = g.indents[g.namespace] - 1 g.indents[g.namespace]--
} }
pub fn (g mut JsGen) write(s string) { pub fn (g mut JsGen) write(s string) {
@ -227,7 +227,16 @@ pub fn (g mut JsGen) writeln(s string) {
pub fn (g mut JsGen) new_tmp_var() string { pub fn (g mut JsGen) new_tmp_var() string {
g.tmp_count++ g.tmp_count++
return 'tmp$g.tmp_count' return '_tmp$g.tmp_count'
}
[inline]
fn js_name(name_ string) string {
name := name_.replace('.', '__')
if name in js_reserved {
return 'v_$name'
}
return name
} }
fn (g mut JsGen) stmts(stmts []ast.Stmt) { fn (g mut JsGen) stmts(stmts []ast.Stmt) {
@ -299,7 +308,7 @@ fn (g mut JsGen) stmt(node ast.Stmt) {
g.writeln('') g.writeln('')
} }
ast.GotoLabel { ast.GotoLabel {
g.writeln('$it.name:') g.writeln('${js_name(it.name)}:')
} }
ast.GotoStmt { ast.GotoStmt {
// skip: JS has no goto // skip: JS has no goto
@ -354,7 +363,7 @@ fn (g mut JsGen) expr(node ast.Expr) {
// example: foo.bar.baz() // example: foo.bar.baz()
g.write('.') g.write('.')
} }
g.write('${it.name}(') g.write('${js_name(it.name)}(')
for i, arg in it.args { for i, arg in it.args {
g.expr(arg.expr) g.expr(arg.expr)
if i != it.args.len - 1 { if i != it.args.len - 1 {
@ -421,7 +430,7 @@ fn (g mut JsGen) expr(node ast.Expr) {
g.gen_selector_expr(it) g.gen_selector_expr(it)
} }
else { else {
println(term.red('jsgen.expr(): bad node')) println(term.red('jsgen.expr(): bad node "${typeof(node)}"'))
} }
} }
} }
@ -522,7 +531,7 @@ fn (g mut JsGen) gen_assign_stmt(it ast.AssignStmt) {
styp := g.typ(ident_var_info.typ) styp := g.typ(ident_var_info.typ)
jsdoc.write(styp) jsdoc.write(styp)
stmt.write('$ident.name') stmt.write(js_name(ident.name))
if i < it.left.len - 1 { if i < it.left.len - 1 {
jsdoc.write(', ') jsdoc.write(', ')
@ -564,7 +573,7 @@ fn (g mut JsGen) gen_assign_stmt(it ast.AssignStmt) {
g.write('const ') g.write('const ')
} }
g.write('$ident.name = ') g.write('${js_name(ident.name)} = ')
g.expr(val) g.expr(val)
if g.inside_loop { if g.inside_loop {
@ -604,7 +613,7 @@ fn (g mut JsGen) gen_const_decl(it ast.ConstDecl) {
g.constants.write('\t') g.constants.write('\t')
g.constants.writeln(g.doc.gen_typ(typ, field.name)) g.constants.writeln(g.doc.gen_typ(typ, field.name))
g.constants.write('\t') g.constants.write('\t')
g.constants.write('$field.name: $val') g.constants.write('${js_name(field.name)}: $val')
if i < it.fields.len - 1 { if i < it.fields.len - 1 {
g.constants.writeln(',') g.constants.writeln(',')
} }
@ -621,7 +630,7 @@ fn (g mut JsGen) gen_defer_stmts() {
} }
fn (g mut JsGen) gen_enum_decl(it ast.EnumDecl) { fn (g mut JsGen) gen_enum_decl(it ast.EnumDecl) {
g.writeln('const $it.name = Object.freeze({') g.writeln('const ${js_name(it.name)} = Object.freeze({')
g.inc_indent() g.inc_indent()
for i, field in it.fields { for i, field in it.fields {
g.write('$field.name: ') g.write('$field.name: ')
@ -682,7 +691,7 @@ fn (g mut JsGen) gen_method_decl(it ast.FnDecl) {
} }
g.write('function(') g.write('function(')
} else { } else {
mut name := it.name mut name := js_name(it.name)
c := name[0] c := name[0]
if c in [`+`, `-`, `*`, `/`] { if c in [`+`, `-`, `*`, `/`] {
name = util.replace_op(name) name = util.replace_op(name)
@ -818,11 +827,12 @@ fn (g mut JsGen) gen_for_stmt(it ast.ForStmt) {
fn (g mut JsGen) fn_args(args []table.Arg, is_variadic bool) { fn (g mut JsGen) fn_args(args []table.Arg, is_variadic bool) {
// no_names := args.len > 0 && args[0].name == 'arg_1' // no_names := args.len > 0 && args[0].name == 'arg_1'
for i, arg in args { for i, arg in args {
name := js_name(arg.name)
is_varg := i == args.len - 1 && is_variadic is_varg := i == args.len - 1 && is_variadic
if is_varg { if is_varg {
g.write('...$arg.name') g.write('...$name')
} else { } else {
g.write(arg.name) g.write(name)
} }
// if its not the last argument // if its not the last argument
if i < args.len - 1 { if i < args.len - 1 {
@ -911,7 +921,6 @@ fn (g mut JsGen) gen_return_stmt(it ast.Return) {
g.writeln(';') g.writeln(';')
} }
fn (g mut JsGen) enum_expr(node ast.Expr) { fn (g mut JsGen) enum_expr(node ast.Expr) {
match node { match node {
ast.EnumVal { ast.EnumVal {
@ -924,7 +933,7 @@ fn (g mut JsGen) enum_expr(node ast.Expr) {
} }
fn (g mut JsGen) gen_struct_decl(node ast.StructDecl) { fn (g mut JsGen) gen_struct_decl(node ast.StructDecl) {
g.writeln('class $node.name {') g.writeln('class ${js_name(node.name)} {')
g.inc_indent() g.inc_indent()
g.writeln(g.doc.gen_ctor(node.fields)) g.writeln(g.doc.gen_ctor(node.fields))
g.writeln('constructor(values) {') g.writeln('constructor(values) {')
@ -980,7 +989,7 @@ fn (g mut JsGen) gen_ident(node ast.Ident) {
} }
// TODO js_name // TODO js_name
name := node.name name := js_name(node.name)
// TODO `is` // TODO `is`
// TODO handle optionals // TODO handle optionals
g.write(name) g.write(name)

View File

@ -45,7 +45,7 @@ fn (mut d JsDoc) gen_typ(typ, name string) string {
d.write('/**') d.write('/**')
d.write(' @type {$typ}') d.write(' @type {$typ}')
if name.len > 0 { if name.len > 0 {
d.write(' - $name') d.write(' - ${js_name(name)}')
} }
d.write(' */') d.write(' */')
return d.out.str() return d.out.str()
@ -77,10 +77,11 @@ fn (mut d JsDoc) gen_fn(it ast.FnDecl) string {
} }
arg_type_name := d.gen.typ(arg.typ) arg_type_name := d.gen.typ(arg.typ)
is_varg := i == it.args.len - 1 && it.is_variadic is_varg := i == it.args.len - 1 && it.is_variadic
name := js_name(arg.name)
if is_varg { if is_varg {
d.writeln('* @param {...$arg_type_name} $arg.name') d.writeln('* @param {...$arg_type_name} $name')
} else { } else {
d.writeln('* @param {$arg_type_name} $arg.name') d.writeln('* @param {$arg_type_name} $name')
} }
} }
d.writeln('* @return {$type_name}') d.writeln('* @return {$type_name}')

View File

@ -1,14 +1,18 @@
// V_COMMIT_HASH 83289d7 // V_COMMIT_HASH d60233b
// V_CURRENT_COMMIT_HASH fc7e64b // V_CURRENT_COMMIT_HASH fc520d9
// Generated by the V compiler // Generated by the V compiler
"use strict"; "use strict";
const CONSTANTS = Object.freeze({ const CONSTANTS = Object.freeze({
/** @type {number} - i_am_a_const */ /** @type {number} - i_am_a_const */
i_am_a_const: 21214 i_am_a_const: 21214,
/** @type {string} - v_super */
v_super: "amazing keyword"
}); });
/* namespace: main */
const main = (function () {
class Companies { class Companies {
/** /**
* @param {{google: number, amazon: boolean, yahoo: string}} values - values for this class fields * @param {{google: number, amazon: boolean, yahoo: string}} values - values for this class fields
@ -39,13 +43,22 @@ class Companies {
return 0; return 0;
} }
} }
const POSITION = Object.freeze({ const POSITION = Object.freeze({
GO_BACK: 0, go_back: 0,
DONT_GO_BACK: 1, dont_go_back: 1,
}); });
/**
* @param {string} v_extends
* @param {number} v_instanceof
* @return {void}
*/
function v_class(v_extends, v_instanceof) {
/** @type {number} - v_delete */
const v_delete = v_instanceof;
}
/* program entry point */ /* program entry point */
(async function() { (async function() {
/** @type {string} - v */ /** @type {string} - v */
@ -56,7 +69,13 @@ const POSITION = Object.freeze({
} }
/** @type {number} - pos */ /** @type {number} - pos */
const pos = POSITION.GO_BACK; const pos = POSITION.go_back;
/** @type {string} - v_debugger */
const v_debugger = "JS keyword";
/** @type {string} - v_await */
const v_await = CONSTANTS.v_super + v_debugger;
/** @type {string} - v_finally */
let v_finally = "implemented";
/** @type {number} - dun */ /** @type {number} - dun */
const dun = CONSTANTS.i_am_a_const * 20; const dun = CONSTANTS.i_am_a_const * 20;
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
@ -71,8 +90,8 @@ const POSITION = Object.freeze({
/** @type {number[]} - arr */ /** @type {number[]} - arr */
const arr = [1, 2, 3, 4, 5]; const arr = [1, 2, 3, 4, 5];
for (let tmp1 = 0; tmp1 < arr.length; ++tmp1) { for (let _tmp1 = 0; _tmp1 < arr.length; ++_tmp1) {
let a = arr[tmp1]; let a = arr[_tmp1];
} }
/** @type {Map<string, string>} - ma */ /** @type {Map<string, string>} - ma */
@ -92,7 +111,6 @@ const POSITION = Object.freeze({
})(); })();
/** /**
* @param {number} num * @param {number} num
* @param {string} def * @param {string} def
@ -101,7 +119,6 @@ const POSITION = Object.freeze({
function async(num, def) { function async(num, def) {
} }
/* [inline] */ /* [inline] */
/** /**
* @param {number} game_on * @param {number} game_on
@ -109,19 +126,22 @@ function async(num, def) {
* @return {multi_return_int_int} * @return {multi_return_int_int}
*/ */
function hello(game_on, ...dummy) { function hello(game_on, ...dummy) {
for (let tmp2 = 0; tmp2 < dummy.length; ++tmp2) { for (let _tmp2 = 0; _tmp2 < dummy.length; ++_tmp2) {
let dd = dummy[tmp2]; let dd = dummy[_tmp2];
/** @type {string} - l */ /** @type {string} - l */
const l = dd; const l = dd;
} }
(function defer() { (function defer() {
/** @type {string} - do */ /** @type {string} - v_do */
const do = "not"; const v_do = "not";
})(); })();
return [game_on + 2, 221]; return [game_on + 2, 221];
} }
/* module exports */
return {
};
})();

View File

@ -1,6 +1,7 @@
const ( const (
i_am_a_const = 21214 i_am_a_const = 21214
super = 'amazing keyword'
) )
struct Companies { struct Companies {
@ -10,17 +11,27 @@ struct Companies {
} }
enum POSITION { enum POSITION {
GO_BACK go_back
DONT_GO_BACK dont_go_back
} }
fn class(extends string, instanceof int) {
delete := instanceof
}
fn main() { fn main() {
v := "done" v := "done"
{ {
_ := "block" _ := "block"
} }
pos := POSITION.GO_BACK pos := POSITION.go_back
debugger := 'JS keyword'
// TODO: Implement interpolation
await := super + debugger
mut finally := 'implemented'
dun := i_am_a_const * 20 dun := i_am_a_const * 20