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