handle php doc comments

This commit is contained in:
vadim 2018-01-02 13:53:55 +02:00
parent 30187b1db1
commit 2051e3a23d
13 changed files with 4494 additions and 4497 deletions

View File

@ -7,19 +7,20 @@ import (
type Closure struct { type Closure struct {
name string name string
attributes map[string]interface{} attributes map[string]interface{}
position *node.Position position *node.Position
params []node.Node params []node.Node
uses []node.Node uses []node.Node
returnType node.Node returnType node.Node
stmts []node.Node stmts []node.Node
} }
func NewClosure(params []node.Node, uses []node.Node, returnType node.Node, stmts []node.Node, isStatic bool, isReturnRef bool) node.Node { func NewClosure(params []node.Node, uses []node.Node, returnType node.Node, stmts []node.Node, isStatic bool, isReturnRef bool, phpDocComment string) node.Node {
return Closure{ return Closure{
"Closure", "Closure",
map[string]interface{}{ map[string]interface{}{
"isReturnRef": isReturnRef, "isReturnRef": isReturnRef,
"isStatic": isStatic, "isStatic": isStatic,
"phpDocComment": phpDocComment,
}, },
nil, nil,
params, params,

View File

@ -7,7 +7,7 @@ import (
type Class struct { type Class struct {
name string name string
attributes map[string]interface{} attributes map[string]interface{}
position *node.Position position *node.Position
className node.Node className node.Node
modifiers []node.Node modifiers []node.Node
args []node.Node args []node.Node
@ -16,10 +16,12 @@ type Class struct {
stmts []node.Node stmts []node.Node
} }
func NewClass(className node.Node, modifiers []node.Node, args []node.Node, extends node.Node, implements []node.Node, stmts []node.Node) node.Node { func NewClass(className node.Node, modifiers []node.Node, args []node.Node, extends node.Node, implements []node.Node, stmts []node.Node, phpDocComment string) node.Node {
return Class{ return Class{
"Class", "Class",
map[string]interface{}{}, map[string]interface{}{
"phpDocComment": phpDocComment,
},
nil, nil,
className, className,
modifiers, modifiers,

View File

@ -7,7 +7,7 @@ import (
type ClassMethod struct { type ClassMethod struct {
name string name string
attributes map[string]interface{} attributes map[string]interface{}
position *node.Position position *node.Position
methodName node.Node methodName node.Node
modifiers []node.Node modifiers []node.Node
params []node.Node params []node.Node
@ -15,11 +15,12 @@ type ClassMethod struct {
stmts []node.Node stmts []node.Node
} }
func NewClassMethod(methodName node.Node, modifiers []node.Node, returnsRef bool, params []node.Node, returnType node.Node, stmts []node.Node) node.Node { func NewClassMethod(methodName node.Node, modifiers []node.Node, returnsRef bool, params []node.Node, returnType node.Node, stmts []node.Node, phpDocComment string) node.Node {
return ClassMethod{ return ClassMethod{
"ClassMethod", "ClassMethod",
map[string]interface{}{ map[string]interface{}{
"returnsRef": returnsRef, "returnsRef": returnsRef,
"phpDocComment": phpDocComment,
}, },
nil, nil,
methodName, methodName,

View File

@ -7,15 +7,17 @@ import (
type Constant struct { type Constant struct {
name string name string
attributes map[string]interface{} attributes map[string]interface{}
position *node.Position position *node.Position
constantName node.Node constantName node.Node
expr node.Node expr node.Node
} }
func NewConstant(constantName node.Node, expr node.Node) node.Node { func NewConstant(constantName node.Node, expr node.Node, phpDocComment string) node.Node {
return Constant{ return Constant{
"Constant", "Constant",
map[string]interface{}{}, map[string]interface{}{
"phpDocComment": phpDocComment,
},
nil, nil,
constantName, constantName,
expr, expr,

View File

@ -7,18 +7,19 @@ import (
type Function struct { type Function struct {
name string name string
attributes map[string]interface{} attributes map[string]interface{}
position *node.Position position *node.Position
functionName node.Node functionName node.Node
params []node.Node params []node.Node
returnType node.Node returnType node.Node
stmts []node.Node stmts []node.Node
} }
func NewFunction(functionName node.Node, returnsRef bool, params []node.Node, returnType node.Node, stmts []node.Node) node.Node { func NewFunction(functionName node.Node, returnsRef bool, params []node.Node, returnType node.Node, stmts []node.Node, phpDocComment string) node.Node {
return Function{ return Function{
"Function", "Function",
map[string]interface{}{ map[string]interface{}{
"returnsRef": returnsRef, "returnsRef": returnsRef,
"phpDocComment": phpDocComment,
}, },
nil, nil,
functionName, functionName,

View File

@ -7,16 +7,18 @@ import (
type Interface struct { type Interface struct {
name string name string
attributes map[string]interface{} attributes map[string]interface{}
position *node.Position position *node.Position
interfaceName node.Node interfaceName node.Node
extends []node.Node extends []node.Node
stmts []node.Node stmts []node.Node
} }
func NewInterface(interfaceName node.Node, extends []node.Node, stmts []node.Node) node.Node { func NewInterface(interfaceName node.Node, extends []node.Node, stmts []node.Node, phpDocComment string) node.Node {
return Interface{ return Interface{
"Interface", "Interface",
map[string]interface{}{}, map[string]interface{}{
"phpDocComment": phpDocComment,
},
nil, nil,
interfaceName, interfaceName,
extends, extends,

View File

@ -7,15 +7,17 @@ import (
type Property struct { type Property struct {
name string name string
attributes map[string]interface{} attributes map[string]interface{}
position *node.Position position *node.Position
variable node.Node variable node.Node
expr node.Node expr node.Node
} }
func NewProperty(variable node.Node, expr node.Node) node.Node { func NewProperty(variable node.Node, expr node.Node, phpDocComment string) node.Node {
return Property{ return Property{
"Property", "Property",
map[string]interface{}{}, map[string]interface{}{
"phpDocComment": phpDocComment,
},
nil, nil,
variable, variable,
expr, expr,

View File

@ -7,15 +7,17 @@ import (
type Trait struct { type Trait struct {
name string name string
attributes map[string]interface{} attributes map[string]interface{}
position *node.Position position *node.Position
traitName node.Node traitName node.Node
stmts []node.Node stmts []node.Node
} }
func NewTrait(traitName node.Node, stmts []node.Node) node.Node { func NewTrait(traitName node.Node, stmts []node.Node, phpDocComment string) node.Node {
return Trait{ return Trait{
"Trait", "Trait",
map[string]interface{}{}, map[string]interface{}{
"phpDocComment": phpDocComment,
},
nil, nil,
traitName, traitName,
stmts, stmts,

View File

@ -18,8 +18,9 @@ const (
type lexer struct { type lexer struct {
*lex.Lexer *lex.Lexer
stateStack []int stateStack []int
lineNumber int lineNumber int
phpDocComment string
} }
func rune2Class(r rune) int { func rune2Class(r rune) int {
@ -42,7 +43,7 @@ func newLexer(src io.Reader, fName string) *lexer {
if err != nil { if err != nil {
panic(err) panic(err)
} }
return &lexer{lx, []int{0}, 1} return &lexer{lx, []int{0}, 1, ""}
} }
func (l *lexer) ungetN(n int) []byte { func (l *lexer) ungetN(n int) []byte {

File diff suppressed because it is too large Load Diff

View File

@ -50,6 +50,7 @@ type boolWithToken struct {
list []node.Node list []node.Node
foreachVariable foreachVariable foreachVariable foreachVariable
nodesWithEndToken *nodesWithEndToken nodesWithEndToken *nodesWithEndToken
str string
} }
%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE %left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
@ -264,6 +265,8 @@ type boolWithToken struct {
%type <list> interface_extends_list implements_list method_modifiers variable_modifiers %type <list> interface_extends_list implements_list method_modifiers variable_modifiers
%type <list> non_empty_member_modifiers name_list class_modifiers %type <list> non_empty_member_modifiers name_list class_modifiers
%type <str> backup_doc_comment
%% %%
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
@ -483,11 +486,11 @@ unset_variable:
; ;
function_declaration_statement: function_declaration_statement:
T_FUNCTION returns_ref T_STRING '(' parameter_list ')' return_type '{' inner_statement_list '}' T_FUNCTION returns_ref T_STRING backup_doc_comment '(' parameter_list ')' return_type '{' inner_statement_list '}'
{ {
name := node.NewIdentifier($3).SetPosition(NewTokenPosition($3)) name := node.NewIdentifier($3).SetPosition(NewTokenPosition($3))
$$ = stmt.NewFunction(name, $2.value, $5, $7, $9). $$ = stmt.NewFunction(name, $2.value, $6, $8, $10, $4).
SetPosition(NewTokensPosition($1, $10)) SetPosition(NewTokensPosition($1, $11))
} }
; ;
@ -502,17 +505,17 @@ is_variadic:
; ;
class_declaration_statement: class_declaration_statement:
class_modifiers T_CLASS T_STRING extends_from implements_list '{' class_statement_list '}' class_modifiers T_CLASS T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
{ {
name := node.NewIdentifier($3).SetPosition(NewTokenPosition($3)) name := node.NewIdentifier($3).SetPosition(NewTokenPosition($3))
$$ = stmt.NewClass(name, $1, nil, $4, $5, $7). $$ = stmt.NewClass(name, $1, nil, $4, $5, $8, $6).
SetPosition(NewOptionalListTokensPosition($1, $2, $8)) SetPosition(NewOptionalListTokensPosition($1, $2, $9))
} }
| T_CLASS T_STRING extends_from implements_list '{' class_statement_list '}' | T_CLASS T_STRING extends_from implements_list backup_doc_comment '{' class_statement_list '}'
{ {
name := node.NewIdentifier($2).SetPosition(NewTokenPosition($2)) name := node.NewIdentifier($2).SetPosition(NewTokenPosition($2))
$$ = stmt.NewClass(name, nil, nil, $3, $4, $6). $$ = stmt.NewClass(name, nil, nil, $3, $4, $7, $5).
SetPosition(NewTokensPosition($1, $7)) SetPosition(NewTokensPosition($1, $8))
} }
; ;
@ -527,15 +530,20 @@ class_modifier:
; ;
trait_declaration_statement: trait_declaration_statement:
T_TRAIT T_STRING '{' class_statement_list '}' { $$ = stmt.NewTrait(node.NewIdentifier($2).SetPosition(NewTokenPosition($2)), $4).SetPosition(NewTokensPosition($1, $5)) } T_TRAIT T_STRING backup_doc_comment '{' class_statement_list '}'
{
name := node.NewIdentifier($2).SetPosition(NewTokenPosition($2))
$$ = stmt.NewTrait(name, $5, $3).
SetPosition(NewTokensPosition($1, $6))
}
; ;
interface_declaration_statement: interface_declaration_statement:
T_INTERFACE T_STRING interface_extends_list '{' class_statement_list '}' T_INTERFACE T_STRING interface_extends_list backup_doc_comment '{' class_statement_list '}'
{ {
name := node.NewIdentifier($2).SetPosition(NewTokenPosition($2)) name := node.NewIdentifier($2).SetPosition(NewTokenPosition($2))
$$ = stmt.NewInterface(name, $3, $5). $$ = stmt.NewInterface(name, $3, $6, $4).
SetPosition(NewTokensPosition($1, $6)) SetPosition(NewTokensPosition($1, $7))
} }
; ;
@ -759,10 +767,11 @@ class_statement:
variable_modifiers property_list ';' { $$ = stmt.NewPropertyList($1, $2).SetPosition(NewNodeListTokenPosition($1, $3)) } variable_modifiers property_list ';' { $$ = stmt.NewPropertyList($1, $2).SetPosition(NewNodeListTokenPosition($1, $3)) }
| method_modifiers T_CONST class_const_list ';' { $$ = stmt.NewClassConstList($1, $3).SetPosition(NewOptionalListTokensPosition($1, $2, $4)) } | method_modifiers T_CONST class_const_list ';' { $$ = stmt.NewClassConstList($1, $3).SetPosition(NewOptionalListTokensPosition($1, $2, $4)) }
| T_USE name_list trait_adaptations { $$ = stmt.NewTraitUse($2, $3.nodes).SetPosition(NewTokensPosition($1, $3.endToken)) } | T_USE name_list trait_adaptations { $$ = stmt.NewTraitUse($2, $3.nodes).SetPosition(NewTokensPosition($1, $3.endToken)) }
| method_modifiers T_FUNCTION returns_ref identifier '(' parameter_list ')' return_type method_body | method_modifiers T_FUNCTION returns_ref identifier backup_doc_comment '(' parameter_list ')' return_type method_body
{ {
$$ = stmt.NewClassMethod(node.NewIdentifier($4).SetPosition(NewTokenPosition($4)), $1, $3.value, $6, $8, $9.nodes). name := node.NewIdentifier($4).SetPosition(NewTokenPosition($4))
SetPosition(NewOptionalListTokensPosition($1, $2, $9.endToken)) $$ = stmt.NewClassMethod(name, $1, $3.value, $7, $9, $10.nodes, $5).
SetPosition(NewOptionalListTokensPosition($1, $2, $10.endToken))
} }
; ;
@ -848,17 +857,17 @@ property_list:
; ;
property: property:
T_VARIABLE T_VARIABLE backup_doc_comment
{ {
identifier := node.NewIdentifier($1).SetPosition(NewTokenPosition($1)) identifier := node.NewIdentifier($1).SetPosition(NewTokenPosition($1))
variable := expr.NewVariable(identifier).SetPosition(NewTokenPosition($1)) variable := expr.NewVariable(identifier).SetPosition(NewTokenPosition($1))
$$ = stmt.NewProperty(variable, nil).SetPosition(NewTokenPosition($1)) $$ = stmt.NewProperty(variable, nil, $2).SetPosition(NewTokenPosition($1))
} }
| T_VARIABLE '=' expr | T_VARIABLE '=' expr backup_doc_comment
{ {
identifier := node.NewIdentifier($1).SetPosition(NewTokenPosition($1)) identifier := node.NewIdentifier($1).SetPosition(NewTokenPosition($1))
variable := expr.NewVariable(identifier).SetPosition(NewTokenPosition($1)) variable := expr.NewVariable(identifier).SetPosition(NewTokenPosition($1))
$$ = stmt.NewProperty(variable, $3).SetPosition(NewTokenNodePosition($1, $3)) $$ = stmt.NewProperty(variable, $3, $4).SetPosition(NewTokenNodePosition($1, $3))
} }
; ;
@ -868,11 +877,19 @@ class_const_list:
; ;
class_const_decl: class_const_decl:
identifier '=' expr { $$ = stmt.NewConstant(node.NewIdentifier($1).SetPosition(NewTokenPosition($1)), $3).SetPosition(NewTokenNodePosition($1, $3)) } identifier '=' expr backup_doc_comment
{
name := node.NewIdentifier($1).SetPosition(NewTokenPosition($1))
$$ = stmt.NewConstant(name, $3, $4).SetPosition(NewTokenNodePosition($1, $3))
}
; ;
const_decl: const_decl:
T_STRING '=' expr { $$ = stmt.NewConstant(node.NewIdentifier($1).SetPosition(NewTokenPosition($1)), $3).SetPosition(NewTokenNodePosition($1, $3)) } T_STRING '=' expr backup_doc_comment
{
name := node.NewIdentifier($1).SetPosition(NewTokenPosition($1))
$$ = stmt.NewConstant(name, $3, $4).SetPosition(NewTokenNodePosition($1, $3))
}
; ;
echo_expr_list: echo_expr_list:
@ -894,12 +911,12 @@ non_empty_for_exprs:
; ;
anonymous_class: anonymous_class:
T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' T_CLASS ctor_arguments extends_from implements_list backup_doc_comment '{' class_statement_list '}'
{ {
if $2 != nil { if $2 != nil {
$$ = stmt.NewClass(nil, nil, $2.nodes, $3, $4, $6).SetPosition(NewTokensPosition($1, $7)) $$ = stmt.NewClass(nil, nil, $2.nodes, $3, $4, $7, $5).SetPosition(NewTokensPosition($1, $8))
} else { } else {
$$ = stmt.NewClass(nil, nil, nil, $3, $4, $6).SetPosition(NewTokensPosition($1, $7)) $$ = stmt.NewClass(nil, nil, nil, $3, $4, $7, $5).SetPosition(NewTokensPosition($1, $8))
} }
} }
; ;
@ -999,16 +1016,20 @@ expr_without_variable:
| T_YIELD expr { $$ = expr.NewYield(nil, $2).SetPosition(NewTokenNodePosition($1, $2)) } | T_YIELD expr { $$ = expr.NewYield(nil, $2).SetPosition(NewTokenNodePosition($1, $2)) }
| T_YIELD expr T_DOUBLE_ARROW expr { $$ = expr.NewYield($2, $4).SetPosition(NewTokenNodePosition($1, $4)) } | T_YIELD expr T_DOUBLE_ARROW expr { $$ = expr.NewYield($2, $4).SetPosition(NewTokenNodePosition($1, $4)) }
| T_YIELD_FROM expr { $$ = expr.NewYieldFrom($2).SetPosition(NewTokenNodePosition($1, $2)) } | T_YIELD_FROM expr { $$ = expr.NewYieldFrom($2).SetPosition(NewTokenNodePosition($1, $2)) }
| T_FUNCTION returns_ref '(' parameter_list ')' lexical_vars return_type '{' inner_statement_list '}' | T_FUNCTION returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type '{' inner_statement_list '}'
{ {
$$ = expr.NewClosure($4, $6, $7, $9, false, $2.value). $$ = expr.NewClosure($5, $7, $8, $10, false, $2.value, $3).
SetPosition(NewTokensPosition($1, $10))
}
| T_STATIC T_FUNCTION returns_ref '(' parameter_list ')' lexical_vars return_type '{' inner_statement_list '}'
{
$$ = expr.NewClosure($5, $7, $8, $10, true, $3.value).
SetPosition(NewTokensPosition($1, $11)) SetPosition(NewTokensPosition($1, $11))
} }
| T_STATIC T_FUNCTION returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type '{' inner_statement_list '}'
{
$$ = expr.NewClosure($6, $8, $9, $11, true, $3.value, $4).
SetPosition(NewTokensPosition($1, $12))
}
;
backup_doc_comment:
/* empty */ { $$ = yylex.(*lexer).phpDocComment; yylex.(*lexer).phpDocComment = "" }
; ;
returns_ref: returns_ref:

File diff suppressed because it is too large Load Diff

View File

@ -246,12 +246,40 @@ NEW_LINE (\r|\n|\r\n)
<PHP>\>\> lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_SR <PHP>\>\> lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_SR
<PHP>\?\? lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_COALESCE <PHP>\?\? lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_COALESCE
<PHP>(#|[/][/]).*{NEW_LINE} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_COMMENT; // TODO: handle ?> <PHP>(#|[/][/]).*{NEW_LINE} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_COMMENT; // TODO: handle ?>
<PHP>[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_COMMENT; // TODO: handle ?> <PHP>([/][*])|([/][*][*])
<PHP>[/][*][*][^*]*[*]+([^*/][^*]*[*]+)*[/] lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)));// return T_DOC_COMMENT; // TODO: handle ?> tb := l.TokenBytes(nil)
is_doc_comment := false
if len(tb) > 2 {
is_doc_comment = true
l.phpDocComment = ""
}
for {
if c == -1 {
break; // TODO: Unterminated comment starting line %d
}
p := c
c = l.Next()
if rune(p) == '*' && rune(c) == '/' {
c = l.Next()
break;
}
}
lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil)))
if is_doc_comment {
l.phpDocComment = string(l.TokenBytes(nil))
// return T_DOC_COMMENT
} else {
// return T_COMMENT
}
<PHP>{OPERATORS} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0])) <PHP>{OPERATORS} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0]))
<PHP>\{ l.pushState(PHP); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0])) <PHP>\{ l.pushState(PHP); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0]))
<PHP>\} l.popState(); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0])) <PHP>\} l.popState(); lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return rune2Class(rune(l.TokenBytes(nil)[0])); l.phpDocComment = ""
<PHP>\${VAR_NAME} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_VARIABLE <PHP>\${VAR_NAME} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_VARIABLE
<PHP>{VAR_NAME} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_STRING <PHP>{VAR_NAME} lval.token = token.NewToken(l.handleNewLine(l.TokenBytes(nil))); return T_STRING