parser: parse `JS.` interfaces properly (#9876)

pull/9887/head
spaceface 2021-04-26 08:58:05 +02:00 committed by GitHub
parent 8b22dbbadb
commit 7acb48df83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 4 deletions

View File

@ -264,6 +264,7 @@ pub struct InterfaceDecl {
pub:
name string
name_pos token.Position
language Language
field_names []string
is_pub bool
methods []FnDecl

View File

@ -353,14 +353,18 @@ pub fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
pub fn (mut c Checker) interface_decl(decl ast.InterfaceDecl) {
c.check_valid_pascal_case(decl.name, 'interface name', decl.pos)
for method in decl.methods {
c.check_valid_snake_case(method.name, 'method name', method.pos)
if decl.language == .v {
c.check_valid_snake_case(method.name, 'method name', method.pos)
}
c.ensure_type_exists(method.return_type, method.return_type_pos) or { return }
for param in method.params {
c.ensure_type_exists(param.typ, param.pos) or { return }
}
}
for i, field in decl.fields {
c.check_valid_snake_case(field.name, 'field name', field.pos)
if decl.language == .v {
c.check_valid_snake_case(field.name, 'field name', field.pos)
}
c.ensure_type_exists(field.typ, field.pos) or { return }
for j in 0 .. i {
if field.name == decl.fields[j].name {

View File

@ -1149,8 +1149,10 @@ pub fn (mut f Fmt) interface_decl(node ast.InterfaceDecl) {
if node.is_pub {
f.write('pub ')
}
f.write('interface ')
f.write_language_prefix(node.language)
name := node.name.after('.')
f.write('interface $name {')
f.write('$name {')
if node.fields.len > 0 || node.methods.len > 0 || node.pos.line_nr < node.pos.last_line {
f.writeln('')
}

View File

@ -440,7 +440,19 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
p.next()
}
p.next() // `interface`
language := if p.tok.lit == 'C' && p.peek_tok.kind == .dot {
ast.Language.c
} else if p.tok.lit == 'JS' && p.peek_tok.kind == .dot {
ast.Language.js
} else {
ast.Language.v
}
if language != .v {
p.next() // C || JS
p.next() // .
}
name_pos := p.tok.position()
p.check_for_impure_v(language, name_pos)
interface_name := p.prepend_mod(p.check_name()).clone()
// println('interface decl $interface_name')
p.check(.lcbr)
@ -494,7 +506,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
p.error_with_pos('duplicate method `$name`', method_start_pos)
return ast.InterfaceDecl{}
}
if util.contains_capital(name) {
if language == .v && util.contains_capital(name) {
p.error('interface methods cannot contain uppercase letters, use snake_case instead')
return ast.InterfaceDecl{}
}
@ -575,6 +587,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
pos = pos.extend_with_last_line(p.prev_tok.position(), p.prev_tok.line_nr)
return ast.InterfaceDecl{
name: interface_name
language: language
fields: fields
methods: methods
is_pub: is_pub