parser: allow JS methods with more than 1 dot
parent
04744a5390
commit
7c9bb44784
|
@ -231,8 +231,8 @@ pub fn (g mut JsGen) new_tmp_var() string {
|
|||
}
|
||||
|
||||
[inline]
|
||||
fn js_name(name_ string) string {
|
||||
name := name_.replace('.', '__')
|
||||
fn js_name(name string) string {
|
||||
// name := name_.replace('.', '__')
|
||||
if name in js_reserved {
|
||||
return 'v_$name'
|
||||
}
|
||||
|
@ -358,12 +358,13 @@ fn (g mut JsGen) expr(node ast.Expr) {
|
|||
g.write("'$it.val'")
|
||||
}
|
||||
ast.CallExpr {
|
||||
name := if it.name.starts_with('JS.') { it.name[3..] } else { it.name }
|
||||
g.expr(it.left)
|
||||
if it.is_method {
|
||||
// example: foo.bar.baz()
|
||||
g.write('.')
|
||||
}
|
||||
g.write('${js_name(it.name)}(')
|
||||
g.write('${js_name(name)}(')
|
||||
for i, arg in it.args {
|
||||
g.expr(arg.expr)
|
||||
if i != it.args.len - 1 {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// V_COMMIT_HASH d60233b
|
||||
// V_CURRENT_COMMIT_HASH fc520d9
|
||||
// V_COMMIT_HASH 04744a5
|
||||
// V_CURRENT_COMMIT_HASH 04744a5
|
||||
|
||||
// Generated by the V compiler
|
||||
"use strict";
|
||||
|
@ -13,6 +13,8 @@ const CONSTANTS = Object.freeze({
|
|||
|
||||
/* namespace: main */
|
||||
const main = (function () {
|
||||
|
||||
|
||||
class Companies {
|
||||
/**
|
||||
* @param {{google: number, amazon: boolean, yahoo: string}} values - values for this class fields
|
||||
|
@ -61,6 +63,7 @@ class Companies {
|
|||
|
||||
/* program entry point */
|
||||
(async function() {
|
||||
console.log("Hello from V.js!");
|
||||
/** @type {string} - v */
|
||||
const v = "done";
|
||||
{
|
||||
|
@ -76,6 +79,7 @@ class Companies {
|
|||
const v_await = CONSTANTS.v_super + v_debugger;
|
||||
/** @type {string} - v_finally */
|
||||
let v_finally = "implemented";
|
||||
console.log(v_await, v_finally);
|
||||
/** @type {number} - dun */
|
||||
const dun = CONSTANTS.i_am_a_const * 20;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
fn JS.alert(arg string)
|
||||
fn JS.console.log(arg string)
|
||||
|
||||
const (
|
||||
i_am_a_const = 21214
|
||||
|
@ -21,6 +23,8 @@ fn class(extends string, instanceof int) {
|
|||
|
||||
|
||||
fn main() {
|
||||
JS.console.log('Hello from V.js!')
|
||||
|
||||
v := "done"
|
||||
{
|
||||
_ := "block"
|
||||
|
@ -33,6 +37,8 @@ fn main() {
|
|||
await := super + debugger
|
||||
mut finally := 'implemented'
|
||||
|
||||
JS.console.log(await, finally)
|
||||
|
||||
dun := i_am_a_const * 20
|
||||
|
||||
for i := 0; i < 10; i++ {}
|
||||
|
|
|
@ -10,16 +10,16 @@ import v.util
|
|||
|
||||
pub fn (mut p Parser) call_expr(is_c, is_js bool, mod string) ast.CallExpr {
|
||||
first_pos := p.tok.position()
|
||||
name := p.check_name()
|
||||
fn_name := if is_c {
|
||||
'C.$name'
|
||||
'C.${p.check_name()}'
|
||||
} else if is_js {
|
||||
'JS.$name'
|
||||
'JS.${p.check_js_name()}'
|
||||
} else if mod.len > 0 {
|
||||
'${mod}.$name'
|
||||
'${mod}.${p.check_name()}'
|
||||
} else {
|
||||
name
|
||||
p.check_name()
|
||||
}
|
||||
|
||||
mut is_or_block_used := false
|
||||
if fn_name == 'json.decode' {
|
||||
p.expecting_type = true // Makes name_expr() parse the type (`User` in `json.decode(User, txt)`)`
|
||||
|
@ -156,7 +156,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
|||
mut name := ''
|
||||
if p.tok.kind == .name {
|
||||
// TODO high order fn
|
||||
name = p.check_name()
|
||||
name = if is_js { p.check_js_name() } else { p.check_name() }
|
||||
if !is_js && !is_c && !p.pref.translated && util.contains_capital(name) {
|
||||
p.error('function names cannot contain uppercase letters, use snake_case instead')
|
||||
}
|
||||
|
|
|
@ -285,6 +285,22 @@ fn (mut p Parser) check(expected token.Kind) {
|
|||
p.next()
|
||||
}
|
||||
|
||||
// JS functions can have multiple dots in their name:
|
||||
// JS.foo.bar.and.a.lot.more.dots()
|
||||
fn (mut p Parser) check_js_name() string {
|
||||
mut name := ''
|
||||
for p.peek_tok.kind == .dot {
|
||||
name += '${p.tok.lit}.'
|
||||
p.next() // .name
|
||||
p.next() // .dot
|
||||
}
|
||||
// last .name
|
||||
name += p.tok.lit
|
||||
p.next()
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
fn (mut p Parser) check_name() string {
|
||||
name := p.tok.lit
|
||||
if p.peek_tok.kind == .dot && name in p.imports {
|
||||
|
@ -754,8 +770,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
|||
} else {
|
||||
// fn call
|
||||
// println('calling $p.tok.lit')
|
||||
x := p.call_expr(is_c, is_js, mod) // TODO `node,typ :=` should work
|
||||
node = x
|
||||
node = p.call_expr(is_c, is_js, mod)
|
||||
}
|
||||
} else if p.peek_tok.kind == .lcbr && !p.inside_match && !p.inside_match_case && !p.inside_if &&
|
||||
!p.inside_for {
|
||||
|
@ -782,6 +797,9 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
|||
} else if p.peek_tok.kind == .colon && p.prev_tok.kind != .str_dollar {
|
||||
// `foo(key:val, key2:val2)`
|
||||
return p.struct_init(true) // short_syntax:true
|
||||
// JS. function call with more than 1 dot
|
||||
} else if is_js && p.peek_tok.kind == .dot && p.peek_tok2.kind == .name {
|
||||
node = p.call_expr(is_c, is_js, mod)
|
||||
} else {
|
||||
node = p.parse_ident(is_c, is_js)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue