mirror of
https://github.com/golang/go
synced 2024-11-12 05:30:21 -07:00
AST for Go programs
R=rsc,r DELTA=309 (67 added, 51 deleted, 191 changed) OCL=26611 CL=26745
This commit is contained in:
parent
21d03496e7
commit
bafd8c390a
@ -17,13 +17,6 @@ import (
|
|||||||
type Position scanner.Location
|
type Position scanner.Location
|
||||||
|
|
||||||
|
|
||||||
// TODO try to get rid of these
|
|
||||||
type (
|
|
||||||
Block struct;
|
|
||||||
Signature struct;
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Interfaces
|
// Interfaces
|
||||||
//
|
//
|
||||||
@ -43,12 +36,13 @@ type (
|
|||||||
|
|
||||||
// TODO: For comment positioning only the byte position and not
|
// TODO: For comment positioning only the byte position and not
|
||||||
// a complete Position field is needed. May be able to trim node
|
// a complete Position field is needed. May be able to trim node
|
||||||
// sizes a bit.
|
// sizes a bit. Then, embed Position field so we can get rid of
|
||||||
|
// most of the Pos() methods.
|
||||||
|
|
||||||
|
|
||||||
type (
|
type (
|
||||||
ExprVisitor interface;
|
ExprVisitor interface;
|
||||||
StatVisitor interface;
|
StmtVisitor interface;
|
||||||
DeclVisitor interface;
|
DeclVisitor interface;
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,12 +59,12 @@ type Expr interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// All statement nodes implement the Stat interface.
|
// All statement nodes implement the Stmt interface.
|
||||||
type Stat interface {
|
type Stmt interface {
|
||||||
// For a (dynamic) node type X, calling Visit with a statement
|
// For a (dynamic) node type X, calling Visit with a statement
|
||||||
// visitor v invokes the node-specific DoX function of the visitor.
|
// visitor v invokes the node-specific DoX function of the visitor.
|
||||||
//
|
//
|
||||||
Visit(v StatVisitor);
|
Visit(v StmtVisitor);
|
||||||
|
|
||||||
// Pos returns the (beginning) position of the statement.
|
// Pos returns the (beginning) position of the statement.
|
||||||
Pos() Position;
|
Pos() Position;
|
||||||
@ -109,6 +103,25 @@ type Comments []*Comment
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Expressions and types
|
// Expressions and types
|
||||||
|
|
||||||
|
// Support types.
|
||||||
|
type (
|
||||||
|
Ident struct;
|
||||||
|
StringLit struct;
|
||||||
|
FunctionType struct;
|
||||||
|
BlockStmt struct;
|
||||||
|
|
||||||
|
// A Field represents a Field declaration list in a struct type,
|
||||||
|
// a method in an interface type, or a parameter/result declaration
|
||||||
|
// in a signature.
|
||||||
|
Field struct {
|
||||||
|
Doc Comments; // associated documentation; or nil
|
||||||
|
Names []*Ident; // field/method/parameter names; nil if anonymous field
|
||||||
|
Type Expr; // field/method/parameter type
|
||||||
|
Tag []*StringLit; // field tag; nil if no tag
|
||||||
|
};
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
// An expression is represented by a tree consisting of one
|
// An expression is represented by a tree consisting of one
|
||||||
// or more of the following concrete expression nodes.
|
// or more of the following concrete expression nodes.
|
||||||
//
|
//
|
||||||
@ -127,28 +140,55 @@ type (
|
|||||||
Lit []byte; // identifier string (e.g. foobar)
|
Lit []byte; // identifier string (e.g. foobar)
|
||||||
};
|
};
|
||||||
|
|
||||||
// A BasicLit node represents a basic literal.
|
// An Ellipsis node stands for the "..." type in a
|
||||||
BasicLit struct {
|
// parameter list or the "..." length in an array type.
|
||||||
Pos_ Position; // literal string position
|
//
|
||||||
Tok int; // literal token (INT, FLOAT, CHAR, STRING)
|
Ellipsis struct {
|
||||||
Lit []byte; // literal string
|
Pos_ Position; // position of "..."
|
||||||
};
|
};
|
||||||
|
|
||||||
// A StringLit node represents a sequence of string literals.
|
// An IntLit node represents an integer literal.
|
||||||
|
IntLit struct {
|
||||||
|
Pos_ Position; // literal string position
|
||||||
|
Lit []byte; // literal string; e.g. 42 or 0x7f
|
||||||
|
};
|
||||||
|
|
||||||
|
// A FloatLit node represents a floating-point literal.
|
||||||
|
FloatLit struct {
|
||||||
|
Pos_ Position; // literal string position
|
||||||
|
Lit []byte; // literal string; e.g. 3.14 or 1e-9
|
||||||
|
};
|
||||||
|
|
||||||
|
// A CharLit node represents a character literal.
|
||||||
|
CharLit struct {
|
||||||
|
Pos_ Position; // literal string position
|
||||||
|
Lit []byte; // literal string, including quotes; e.g. 'a' or '\x7f'
|
||||||
|
};
|
||||||
|
|
||||||
|
// A StringLit node represents a string literal.
|
||||||
StringLit struct {
|
StringLit struct {
|
||||||
Strings []*BasicLit; // sequence of strings
|
Pos_ Position; // literal string position
|
||||||
|
Lit []byte; // literal string, including quotes; e.g. "foo" or `\m\n\o`
|
||||||
|
};
|
||||||
|
|
||||||
|
// A StringList node represents a sequence of adjacent string literals.
|
||||||
|
// A single string literal (common case) is represented by a StringLit
|
||||||
|
// node; StringList nodes are used only if there are two or more string
|
||||||
|
// literals in a sequence.
|
||||||
|
//
|
||||||
|
StringList struct {
|
||||||
|
Strings []*StringLit; // list of strings, len(Strings) > 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// A FunctionLit node represents a function literal.
|
// A FunctionLit node represents a function literal.
|
||||||
FunctionLit struct {
|
FunctionLit struct {
|
||||||
Func Position; // position of "func" keyword
|
Type *FunctionType; // function type
|
||||||
Typ *Signature; // function signature
|
Body *BlockStmt; // function body
|
||||||
Body *Block; // function body
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A CompositeLit node represents a composite literal.
|
// A CompositeLit node represents a composite literal.
|
||||||
CompositeLit struct {
|
CompositeLit struct {
|
||||||
Typ Expr; // literal type
|
Type Expr; // literal type
|
||||||
Lbrace Position; // position of "{"
|
Lbrace Position; // position of "{"
|
||||||
Elts []Expr; // list of composite elements
|
Elts []Expr; // list of composite elements
|
||||||
Rbrace Position; // position of "}"
|
Rbrace Position; // position of "}"
|
||||||
@ -161,33 +201,33 @@ type (
|
|||||||
Rparen Position; // position of ")"
|
Rparen Position; // position of ")"
|
||||||
};
|
};
|
||||||
|
|
||||||
// A SelectorExpr node represents a primary expression followed by a selector.
|
// A SelectorExpr node represents an expression followed by a selector.
|
||||||
SelectorExpr struct {
|
SelectorExpr struct {
|
||||||
X Expr; // primary expression
|
X Expr; // expression
|
||||||
Sel *Ident; // field selector
|
Sel *Ident; // field selector
|
||||||
};
|
};
|
||||||
|
|
||||||
// An IndexExpr node represents a primary expression followed by an index.
|
// An IndexExpr node represents an expression followed by an index.
|
||||||
IndexExpr struct {
|
IndexExpr struct {
|
||||||
X Expr; // primary expression
|
X Expr; // expression
|
||||||
Index Expr; // index expression
|
Index Expr; // index expression
|
||||||
};
|
};
|
||||||
|
|
||||||
// A SliceExpr node represents a primary expression followed by a slice.
|
// A SliceExpr node represents an expression followed by a slice.
|
||||||
SliceExpr struct {
|
SliceExpr struct {
|
||||||
X Expr; // primary expression
|
X Expr; // expression
|
||||||
Begin, End Expr; // slice range
|
Begin, End Expr; // slice range
|
||||||
};
|
};
|
||||||
|
|
||||||
// A TypeAssertExpr node represents a primary expression followed by a
|
// A TypeAssertExpr node represents an expression followed by a
|
||||||
// type assertion.
|
// type assertion.
|
||||||
//
|
//
|
||||||
TypeAssertExpr struct {
|
TypeAssertExpr struct {
|
||||||
X Expr; // primary expression
|
X Expr; // expression
|
||||||
Typ Expr; // asserted type
|
Type Expr; // asserted type
|
||||||
};
|
};
|
||||||
|
|
||||||
// A CallExpr node represents a primary expression followed by an argument list.
|
// A CallExpr node represents an expression followed by an argument list.
|
||||||
CallExpr struct {
|
CallExpr struct {
|
||||||
Fun Expr; // function expression
|
Fun Expr; // function expression
|
||||||
Lparen Position; // position of "("
|
Lparen Position; // position of "("
|
||||||
@ -236,17 +276,10 @@ const (
|
|||||||
// nodes.
|
// nodes.
|
||||||
//
|
//
|
||||||
type (
|
type (
|
||||||
// An Ellipsis node stands for the "..." type in a
|
|
||||||
// parameter list or the "..." length in an array type.
|
|
||||||
//
|
|
||||||
Ellipsis struct { // neither a type nor an expression
|
|
||||||
Pos_ Position; // position of "..."
|
|
||||||
};
|
|
||||||
|
|
||||||
// An ArrayType node represents an array type.
|
// An ArrayType node represents an array type.
|
||||||
ArrayType struct {
|
ArrayType struct {
|
||||||
Lbrack Position; // position of "["
|
Lbrack Position; // position of "["
|
||||||
Len Expr; // an Ellipsis node for [...]T array types
|
Len Expr; // possibly an Ellipsis node for [...]T array types
|
||||||
Elt Expr; // element type
|
Elt Expr; // element type
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -256,16 +289,6 @@ type (
|
|||||||
Elt Expr; // element type
|
Elt Expr; // element type
|
||||||
};
|
};
|
||||||
|
|
||||||
// A Field represents a Field declaration list in a struct type,
|
|
||||||
// a method in an interface type, or a parameter declaration in
|
|
||||||
// a signature.
|
|
||||||
Field struct {
|
|
||||||
Doc Comments; // associated documentation (struct types only)
|
|
||||||
Names []*Ident; // field/method/parameter names; nil if anonymous field
|
|
||||||
Typ Expr; // field/method/parameter type
|
|
||||||
Tag Expr; // field tag; nil if no tag
|
|
||||||
};
|
|
||||||
|
|
||||||
// A StructType node represents a struct type.
|
// A StructType node represents a struct type.
|
||||||
StructType struct {
|
StructType struct {
|
||||||
Struct, Lbrace Position; // positions of "struct" keyword, "{"
|
Struct, Lbrace Position; // positions of "struct" keyword, "{"
|
||||||
@ -273,20 +296,13 @@ type (
|
|||||||
Rbrace Position; // position of "}"
|
Rbrace Position; // position of "}"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note: pointer types are represented via StarExpr nodes.
|
// Pointer types are represented via StarExpr nodes.
|
||||||
|
|
||||||
// A signature node represents the parameter and result
|
|
||||||
// sections of a function type only.
|
|
||||||
//
|
|
||||||
Signature struct {
|
|
||||||
Params []*Field;
|
|
||||||
Result []*Field;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A FunctionType node represents a function type.
|
// A FunctionType node represents a function type.
|
||||||
FunctionType struct {
|
FunctionType struct {
|
||||||
Func Position; // position of "func" keyword
|
Func Position; // position of "func" keyword
|
||||||
Sig *Signature;
|
Params []*Field; // (incoming) parameters
|
||||||
|
Results []*Field; // (outgoing) results
|
||||||
};
|
};
|
||||||
|
|
||||||
// An InterfaceType node represents an interface type.
|
// An InterfaceType node represents an interface type.
|
||||||
@ -306,7 +322,7 @@ type (
|
|||||||
// A ChannelType node represents a channel type.
|
// A ChannelType node represents a channel type.
|
||||||
ChannelType struct {
|
ChannelType struct {
|
||||||
Pos_ Position; // position of "chan" keyword or "<-" (whichever comes first)
|
Pos_ Position; // position of "chan" keyword or "<-" (whichever comes first)
|
||||||
Dir ChanDir;
|
Dir ChanDir; // channel direction
|
||||||
Value Expr; // value type
|
Value Expr; // value type
|
||||||
};
|
};
|
||||||
)
|
)
|
||||||
@ -316,10 +332,13 @@ type (
|
|||||||
//
|
//
|
||||||
func (x *BadExpr) Pos() Position { return x.Pos_; }
|
func (x *BadExpr) Pos() Position { return x.Pos_; }
|
||||||
func (x *Ident) Pos() Position { return x.Pos_; }
|
func (x *Ident) Pos() Position { return x.Pos_; }
|
||||||
func (x *BasicLit) Pos() Position { return x.Pos_; }
|
func (x *IntLit) Pos() Position { return x.Pos_; }
|
||||||
func (x *StringLit) Pos() Position { return x.Strings[0].Pos(); }
|
func (x *FloatLit) Pos() Position { return x.Pos_; }
|
||||||
func (x *FunctionLit) Pos() Position { return x.Func; }
|
func (x *CharLit) Pos() Position { return x.Pos_; }
|
||||||
func (x *CompositeLit) Pos() Position { return x.Typ.Pos(); }
|
func (x *StringLit) Pos() Position { return x.Pos_; }
|
||||||
|
func (x *StringList) Pos() Position { return x.Strings[0].Pos(); }
|
||||||
|
func (x *FunctionLit) Pos() Position { return x.Type.Func; }
|
||||||
|
func (x *CompositeLit) Pos() Position { return x.Type.Pos(); }
|
||||||
func (x *ParenExpr) Pos() Position { return x.Lparen; }
|
func (x *ParenExpr) Pos() Position { return x.Lparen; }
|
||||||
func (x *SelectorExpr) Pos() Position { return x.X.Pos(); }
|
func (x *SelectorExpr) Pos() Position { return x.X.Pos(); }
|
||||||
func (x *IndexExpr) Pos() Position { return x.X.Pos(); }
|
func (x *IndexExpr) Pos() Position { return x.X.Pos(); }
|
||||||
@ -349,8 +368,11 @@ type ExprVisitor interface {
|
|||||||
// Expressions
|
// Expressions
|
||||||
DoBadExpr(x *BadExpr);
|
DoBadExpr(x *BadExpr);
|
||||||
DoIdent(x *Ident);
|
DoIdent(x *Ident);
|
||||||
DoBasicLit(x *BasicLit);
|
DoIntLit(x *IntLit);
|
||||||
|
DoFloatLit(x *FloatLit);
|
||||||
|
DoCharLit(x *CharLit);
|
||||||
DoStringLit(x *StringLit);
|
DoStringLit(x *StringLit);
|
||||||
|
DoStringList(x *StringList);
|
||||||
DoFunctionLit(x *FunctionLit);
|
DoFunctionLit(x *FunctionLit);
|
||||||
DoCompositeLit(x *CompositeLit);
|
DoCompositeLit(x *CompositeLit);
|
||||||
DoParenExpr(x *ParenExpr);
|
DoParenExpr(x *ParenExpr);
|
||||||
@ -379,8 +401,12 @@ type ExprVisitor interface {
|
|||||||
//
|
//
|
||||||
func (x *BadExpr) Visit(v ExprVisitor) { v.DoBadExpr(x); }
|
func (x *BadExpr) Visit(v ExprVisitor) { v.DoBadExpr(x); }
|
||||||
func (x *Ident) Visit(v ExprVisitor) { v.DoIdent(x); }
|
func (x *Ident) Visit(v ExprVisitor) { v.DoIdent(x); }
|
||||||
func (x *BasicLit) Visit(v ExprVisitor) { v.DoBasicLit(x); }
|
func (x *Ellipsis) Visit(v ExprVisitor) { v.DoEllipsis(x); }
|
||||||
|
func (x *IntLit) Visit(v ExprVisitor) { v.DoIntLit(x); }
|
||||||
|
func (x *FloatLit) Visit(v ExprVisitor) { v.DoFloatLit(x); }
|
||||||
|
func (x *CharLit) Visit(v ExprVisitor) { v.DoCharLit(x); }
|
||||||
func (x *StringLit) Visit(v ExprVisitor) { v.DoStringLit(x); }
|
func (x *StringLit) Visit(v ExprVisitor) { v.DoStringLit(x); }
|
||||||
|
func (x *StringList) Visit(v ExprVisitor) { v.DoStringList(x); }
|
||||||
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); }
|
func (x *FunctionLit) Visit(v ExprVisitor) { v.DoFunctionLit(x); }
|
||||||
func (x *CompositeLit) Visit(v ExprVisitor) { v.DoCompositeLit(x); }
|
func (x *CompositeLit) Visit(v ExprVisitor) { v.DoCompositeLit(x); }
|
||||||
func (x *ParenExpr) Visit(v ExprVisitor) { v.DoParenExpr(x); }
|
func (x *ParenExpr) Visit(v ExprVisitor) { v.DoParenExpr(x); }
|
||||||
@ -393,7 +419,6 @@ func (x *StarExpr) Visit(v ExprVisitor) { v.DoStarExpr(x); }
|
|||||||
func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
|
func (x *UnaryExpr) Visit(v ExprVisitor) { v.DoUnaryExpr(x); }
|
||||||
func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
|
func (x *BinaryExpr) Visit(v ExprVisitor) { v.DoBinaryExpr(x); }
|
||||||
|
|
||||||
func (x *Ellipsis) Visit(v ExprVisitor) { v.DoEllipsis(x); }
|
|
||||||
func (x *ArrayType) Visit(v ExprVisitor) { v.DoArrayType(x); }
|
func (x *ArrayType) Visit(v ExprVisitor) { v.DoArrayType(x); }
|
||||||
func (x *SliceType) Visit(v ExprVisitor) { v.DoSliceType(x); }
|
func (x *SliceType) Visit(v ExprVisitor) { v.DoSliceType(x); }
|
||||||
func (x *StructType) Visit(v ExprVisitor) { v.DoStructType(x); }
|
func (x *StructType) Visit(v ExprVisitor) { v.DoStructType(x); }
|
||||||
@ -403,22 +428,6 @@ func (x *MapType) Visit(v ExprVisitor) { v.DoMapType(x); }
|
|||||||
func (x *ChannelType) Visit(v ExprVisitor) { v.DoChannelType(x); }
|
func (x *ChannelType) Visit(v ExprVisitor) { v.DoChannelType(x); }
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Blocks
|
|
||||||
|
|
||||||
// A Block represents syntactic constructs of the form:
|
|
||||||
//
|
|
||||||
// "{" StatementList "}"
|
|
||||||
// ":" StatementList
|
|
||||||
//
|
|
||||||
type Block struct {
|
|
||||||
Pos_ Position;
|
|
||||||
Tok int;
|
|
||||||
List []Stat;
|
|
||||||
Rparen Position; // position of closing "}" if present
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Statements
|
// Statements
|
||||||
|
|
||||||
@ -426,236 +435,244 @@ type Block struct {
|
|||||||
// or more of the following concrete statement nodes.
|
// or more of the following concrete statement nodes.
|
||||||
//
|
//
|
||||||
type (
|
type (
|
||||||
// A BadStat node is a placeholder for statements containing
|
// A BadStmt node is a placeholder for statements containing
|
||||||
// syntax errors for which no correct statement nodes can be
|
// syntax errors for which no correct statement nodes can be
|
||||||
// created.
|
// created.
|
||||||
//
|
//
|
||||||
BadStat struct {
|
BadStmt struct {
|
||||||
Pos_ Position; // beginning position of bad statement
|
Pos_ Position; // beginning position of bad statement
|
||||||
};
|
};
|
||||||
|
|
||||||
// A DeclStat node represents a declaration in a statement list.
|
// A DeclStmt node represents a declaration in a statement list.
|
||||||
DeclStat struct {
|
DeclStmt struct {
|
||||||
Decl Decl;
|
Decl Decl;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An EmptyStat node represents an empty statement.
|
// An EmptyStmt node represents an empty statement.
|
||||||
// The "position" of the empty statement is the position
|
// The "position" of the empty statement is the position
|
||||||
// of the immediately preceeding semicolon.
|
// of the immediately preceeding semicolon.
|
||||||
//
|
//
|
||||||
EmptyStat struct {
|
EmptyStmt struct {
|
||||||
Semicolon Position; // position of preceeding ";"
|
Semicolon Position; // position of preceeding ";"
|
||||||
};
|
};
|
||||||
|
|
||||||
// A LabeledStat node represents a labeled statement.
|
// A LabeledStmt node represents a labeled statement.
|
||||||
LabeledStat struct {
|
LabeledStmt struct {
|
||||||
Label *Ident;
|
Label *Ident;
|
||||||
Stat Stat;
|
Stmt Stmt;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An ExprStat node represents a (stand-alone) expression
|
// An ExprStmt node represents a (stand-alone) expression
|
||||||
// in a statement list.
|
// in a statement list.
|
||||||
//
|
//
|
||||||
ExprStat struct {
|
ExprStmt struct {
|
||||||
X Expr; // expression
|
X Expr; // expression
|
||||||
};
|
};
|
||||||
|
|
||||||
// An IncDecStat node represents an increment or decrement statement.
|
// An IncDecStmt node represents an increment or decrement statement.
|
||||||
IncDecStat struct {
|
IncDecStmt struct {
|
||||||
X Expr;
|
X Expr;
|
||||||
Tok int; // INC or DEC
|
Tok int; // INC or DEC
|
||||||
};
|
};
|
||||||
|
|
||||||
// An AssignmentStat node represents an assignment or
|
// An AssignStmt node represents an assignment or
|
||||||
// a short variable declaration.
|
// a short variable declaration.
|
||||||
AssignmentStat struct {
|
AssignStmt struct {
|
||||||
Lhs []Expr;
|
Lhs []Expr;
|
||||||
Pos_ Position; // token position
|
Pos_ Position; // token position
|
||||||
Tok int; // assignment token, DEFINE
|
Tok int; // assignment token, DEFINE
|
||||||
Rhs []Expr;
|
Rhs []Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A GoStat node represents a go statement.
|
// A GoStmt node represents a go statement.
|
||||||
GoStat struct {
|
GoStmt struct {
|
||||||
Go Position; // position of "go" keyword
|
Go Position; // position of "go" keyword
|
||||||
Call Expr;
|
Call *CallExpr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A DeferStat node represents a defer statement.
|
// A DeferStmt node represents a defer statement.
|
||||||
DeferStat struct {
|
DeferStmt struct {
|
||||||
Defer Position; // position of "defer" keyword
|
Defer Position; // position of "defer" keyword
|
||||||
Call Expr;
|
Call *CallExpr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A ReturnStat node represents a return statement.
|
// A ReturnStmt node represents a return statement.
|
||||||
ReturnStat struct {
|
ReturnStmt struct {
|
||||||
Return Position; // position of "return" keyword
|
Return Position; // position of "return" keyword
|
||||||
Results []Expr;
|
Results []Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A ControlFlowStat node represents a break, continue, goto,
|
// A BranchStmt node represents a break, continue, goto,
|
||||||
// or fallthrough statement.
|
// or fallthrough statement.
|
||||||
//
|
//
|
||||||
ControlFlowStat struct {
|
BranchStmt struct {
|
||||||
Pos_ Position; // position of keyword
|
Pos_ Position; // position of keyword
|
||||||
Tok int; // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
|
Tok int; // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
|
||||||
Label *Ident;
|
Label *Ident;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A CompositeStat node represents a braced statement list.
|
// A BlockStmt node represents a braced statement list.
|
||||||
CompositeStat struct {
|
BlockStmt struct {
|
||||||
Body *Block;
|
Lbrace Position;
|
||||||
|
List []Stmt;
|
||||||
|
Rbrace Position;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An IfStat node represents an if statement.
|
// An IfStmt node represents an if statement.
|
||||||
IfStat struct {
|
IfStmt struct {
|
||||||
If Position; // position of "if" keyword
|
If Position; // position of "if" keyword
|
||||||
Init Stat;
|
Init Stmt;
|
||||||
Cond Expr;
|
Cond Expr;
|
||||||
Body *Block;
|
Body *BlockStmt;
|
||||||
Else Stat;
|
Else Stmt;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A CaseClause represents a case of an expression switch statement.
|
// A CaseClause represents a case of an expression switch statement.
|
||||||
CaseClause struct {
|
CaseClause struct {
|
||||||
Case Position; // position of "case" or "default" keyword
|
Case Position; // position of "case" or "default" keyword
|
||||||
Values []Expr; // nil means default case
|
Values []Expr; // nil means default case
|
||||||
Body *Block;
|
Colon Position; // position of ":"
|
||||||
|
Body []Stmt; // statement list; or nil
|
||||||
};
|
};
|
||||||
|
|
||||||
// A SwitchStat node represents an expression switch statement.
|
// A SwitchStmt node represents an expression switch statement.
|
||||||
SwitchStat struct {
|
SwitchStmt struct {
|
||||||
Switch Position; // position of "switch" keyword
|
Switch Position; // position of "switch" keyword
|
||||||
Init Stat;
|
Init Stmt;
|
||||||
Tag Expr;
|
Tag Expr;
|
||||||
Body *Block; // CaseClauses only
|
Body *BlockStmt; // CaseClauses only
|
||||||
};
|
};
|
||||||
|
|
||||||
// A TypeCaseClause represents a case of a type switch statement.
|
// A TypeCaseClause represents a case of a type switch statement.
|
||||||
TypeCaseClause struct {
|
TypeCaseClause struct {
|
||||||
Case Position; // position of "case" or "default" keyword
|
Case Position; // position of "case" or "default" keyword
|
||||||
Typ Expr; // nil means default case
|
Type Expr; // nil means default case
|
||||||
Body *Block;
|
Colon Position; // position of ":"
|
||||||
|
Body []Stmt; // statement list; or nil
|
||||||
};
|
};
|
||||||
|
|
||||||
// An TypeSwitchStat node represents a type switch statement.
|
// An TypeSwitchStmt node represents a type switch statement.
|
||||||
TypeSwitchStat struct {
|
TypeSwitchStmt struct {
|
||||||
Switch Position; // position of "switch" keyword
|
Switch Position; // position of "switch" keyword
|
||||||
Init Stat;
|
Init Stmt;
|
||||||
Assign Stat; // x := y.(type)
|
Assign Stmt; // x := y.(type)
|
||||||
Body *Block; // TypeCaseClauses only
|
Body *BlockStmt; // TypeCaseClauses only
|
||||||
};
|
};
|
||||||
|
|
||||||
// A CommClause node represents a case of a select statement.
|
// A CommClause node represents a case of a select statement.
|
||||||
CommClause struct {
|
CommClause struct {
|
||||||
Case Position; // position of "case" or "default" keyword
|
Case Position; // position of "case" or "default" keyword
|
||||||
Tok int; // ASSIGN, DEFINE (valid only if Lhs != nil)
|
Tok int; // ASSIGN or DEFINE (valid only if Lhs != nil)
|
||||||
Lhs, Rhs Expr; // Rhs == nil means default case
|
Lhs, Rhs Expr; // Rhs == nil means default case
|
||||||
Body *Block;
|
Colon Position; // position of ":"
|
||||||
|
Body []Stmt; // statement list; or nil
|
||||||
};
|
};
|
||||||
|
|
||||||
// An SelectStat node represents a select statement.
|
// An SelectStmt node represents a select statement.
|
||||||
SelectStat struct {
|
SelectStmt struct {
|
||||||
Select Position; // position of "select" keyword
|
Select Position; // position of "select" keyword
|
||||||
Body *Block; // CommClauses only
|
Body *BlockStmt; // CommClauses only
|
||||||
};
|
};
|
||||||
|
|
||||||
// A ForStat represents a for statement.
|
// A ForStmt represents a for statement.
|
||||||
ForStat struct {
|
ForStmt struct {
|
||||||
For Position; // position of "for" keyword
|
For Position; // position of "for" keyword
|
||||||
Init Stat;
|
Init Stmt;
|
||||||
Cond Expr;
|
Cond Expr;
|
||||||
Post Stat;
|
Post Stmt;
|
||||||
Body *Block;
|
Body *BlockStmt;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A RangeStat represents a for statement with a range clause.
|
// A RangeStmt represents a for statement with a range clause.
|
||||||
RangeStat struct {
|
RangeStmt struct {
|
||||||
For Position; // position of "for" keyword
|
For Position; // position of "for" keyword
|
||||||
Range Stat;
|
Key, Value Expr; // Value may be nil
|
||||||
Body *Block;
|
Pos_ Position; // token position
|
||||||
|
Tok int; // ASSIGN or DEFINE
|
||||||
|
X Expr; // value to range over
|
||||||
|
Body *BlockStmt;
|
||||||
};
|
};
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Pos() implementations for all statement nodes.
|
// Pos() implementations for all statement nodes.
|
||||||
//
|
//
|
||||||
func (s *BadStat) Pos() Position { return s.Pos_; }
|
func (s *BadStmt) Pos() Position { return s.Pos_; }
|
||||||
func (s *DeclStat) Pos() Position { return s.Decl.Pos(); }
|
func (s *DeclStmt) Pos() Position { return s.Decl.Pos(); }
|
||||||
func (s *EmptyStat) Pos() Position { return s.Semicolon; }
|
func (s *EmptyStmt) Pos() Position { return s.Semicolon; }
|
||||||
func (s *LabeledStat) Pos() Position { return s.Label.Pos(); }
|
func (s *LabeledStmt) Pos() Position { return s.Label.Pos(); }
|
||||||
func (s *ExprStat) Pos() Position { return s.X.Pos(); }
|
func (s *ExprStmt) Pos() Position { return s.X.Pos(); }
|
||||||
func (s *IncDecStat) Pos() Position { return s.X.Pos(); }
|
func (s *IncDecStmt) Pos() Position { return s.X.Pos(); }
|
||||||
func (s *AssignmentStat) Pos() Position { return s.Lhs[0].Pos(); }
|
func (s *AssignStmt) Pos() Position { return s.Lhs[0].Pos(); }
|
||||||
func (s *GoStat) Pos() Position { return s.Go; }
|
func (s *GoStmt) Pos() Position { return s.Go; }
|
||||||
func (s *DeferStat) Pos() Position { return s.Defer; }
|
func (s *DeferStmt) Pos() Position { return s.Defer; }
|
||||||
func (s *ReturnStat) Pos() Position { return s.Return; }
|
func (s *ReturnStmt) Pos() Position { return s.Return; }
|
||||||
func (s *ControlFlowStat) Pos() Position { return s.Pos_; }
|
func (s *BranchStmt) Pos() Position { return s.Pos_; }
|
||||||
func (s *CompositeStat) Pos() Position { return s.Body.Pos_; }
|
func (s *BlockStmt) Pos() Position { return s.Lbrace; }
|
||||||
func (s *IfStat) Pos() Position { return s.If; }
|
func (s *IfStmt) Pos() Position { return s.If; }
|
||||||
func (s *CaseClause) Pos() Position { return s.Case; }
|
func (s *CaseClause) Pos() Position { return s.Case; }
|
||||||
func (s *SwitchStat) Pos() Position { return s.Switch; }
|
func (s *SwitchStmt) Pos() Position { return s.Switch; }
|
||||||
func (s *TypeCaseClause) Pos() Position { return s.Case; }
|
func (s *TypeCaseClause) Pos() Position { return s.Case; }
|
||||||
func (s *TypeSwitchStat) Pos() Position { return s.Switch; }
|
func (s *TypeSwitchStmt) Pos() Position { return s.Switch; }
|
||||||
func (s *CommClause) Pos() Position { return s.Case; }
|
func (s *CommClause) Pos() Position { return s.Case; }
|
||||||
func (s *SelectStat) Pos() Position { return s.Select; }
|
func (s *SelectStmt) Pos() Position { return s.Select; }
|
||||||
func (s *ForStat) Pos() Position { return s.For; }
|
func (s *ForStmt) Pos() Position { return s.For; }
|
||||||
func (s *RangeStat) Pos() Position { return s.For; }
|
func (s *RangeStmt) Pos() Position { return s.For; }
|
||||||
|
|
||||||
|
|
||||||
// All statement nodes implement a Visit method which takes
|
// All statement nodes implement a Visit method which takes
|
||||||
// a StatVisitor as argument. For a given node x of type X, and
|
// a StmtVisitor as argument. For a given node x of type X, and
|
||||||
// an implementation v of a StatVisitor, calling x.Visit(v) will
|
// an implementation v of a StmtVisitor, calling x.Visit(v) will
|
||||||
// result in a call of v.DoX(x) (through a double-dispatch).
|
// result in a call of v.DoX(x) (through a double-dispatch).
|
||||||
//
|
//
|
||||||
type StatVisitor interface {
|
type StmtVisitor interface {
|
||||||
DoBadStat(s *BadStat);
|
DoBadStmt(s *BadStmt);
|
||||||
DoDeclStat(s *DeclStat);
|
DoDeclStmt(s *DeclStmt);
|
||||||
DoEmptyStat(s *EmptyStat);
|
DoEmptyStmt(s *EmptyStmt);
|
||||||
DoLabeledStat(s *LabeledStat);
|
DoLabeledStmt(s *LabeledStmt);
|
||||||
DoExprStat(s *ExprStat);
|
DoExprStmt(s *ExprStmt);
|
||||||
DoIncDecStat(s *IncDecStat);
|
DoIncDecStmt(s *IncDecStmt);
|
||||||
DoAssignmentStat(s *AssignmentStat);
|
DoAssignStmt(s *AssignStmt);
|
||||||
DoGoStat(s *GoStat);
|
DoGoStmt(s *GoStmt);
|
||||||
DoDeferStat(s *DeferStat);
|
DoDeferStmt(s *DeferStmt);
|
||||||
DoReturnStat(s *ReturnStat);
|
DoReturnStmt(s *ReturnStmt);
|
||||||
DoControlFlowStat(s *ControlFlowStat);
|
DoBranchStmt(s *BranchStmt);
|
||||||
DoCompositeStat(s *CompositeStat);
|
DoBlockStmt(s *BlockStmt);
|
||||||
DoIfStat(s *IfStat);
|
DoIfStmt(s *IfStmt);
|
||||||
DoCaseClause(s *CaseClause);
|
DoCaseClause(s *CaseClause);
|
||||||
DoSwitchStat(s *SwitchStat);
|
DoSwitchStmt(s *SwitchStmt);
|
||||||
DoTypeCaseClause(s *TypeCaseClause);
|
DoTypeCaseClause(s *TypeCaseClause);
|
||||||
DoTypeSwitchStat(s *TypeSwitchStat);
|
DoTypeSwitchStmt(s *TypeSwitchStmt);
|
||||||
DoCommClause(s *CommClause);
|
DoCommClause(s *CommClause);
|
||||||
DoSelectStat(s *SelectStat);
|
DoSelectStmt(s *SelectStmt);
|
||||||
DoForStat(s *ForStat);
|
DoForStmt(s *ForStmt);
|
||||||
DoRangeStat(s *RangeStat);
|
DoRangeStmt(s *RangeStmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Visit() implementations for all statement nodes.
|
// Visit() implementations for all statement nodes.
|
||||||
//
|
//
|
||||||
func (s *BadStat) Visit(v StatVisitor) { v.DoBadStat(s); }
|
func (s *BadStmt) Visit(v StmtVisitor) { v.DoBadStmt(s); }
|
||||||
func (s *DeclStat) Visit(v StatVisitor) { v.DoDeclStat(s); }
|
func (s *DeclStmt) Visit(v StmtVisitor) { v.DoDeclStmt(s); }
|
||||||
func (s *EmptyStat) Visit(v StatVisitor) { v.DoEmptyStat(s); }
|
func (s *EmptyStmt) Visit(v StmtVisitor) { v.DoEmptyStmt(s); }
|
||||||
func (s *LabeledStat) Visit(v StatVisitor) { v.DoLabeledStat(s); }
|
func (s *LabeledStmt) Visit(v StmtVisitor) { v.DoLabeledStmt(s); }
|
||||||
func (s *ExprStat) Visit(v StatVisitor) { v.DoExprStat(s); }
|
func (s *ExprStmt) Visit(v StmtVisitor) { v.DoExprStmt(s); }
|
||||||
func (s *IncDecStat) Visit(v StatVisitor) { v.DoIncDecStat(s); }
|
func (s *IncDecStmt) Visit(v StmtVisitor) { v.DoIncDecStmt(s); }
|
||||||
func (s *AssignmentStat) Visit(v StatVisitor) { v.DoAssignmentStat(s); }
|
func (s *AssignStmt) Visit(v StmtVisitor) { v.DoAssignStmt(s); }
|
||||||
func (s *GoStat) Visit(v StatVisitor) { v.DoGoStat(s); }
|
func (s *GoStmt) Visit(v StmtVisitor) { v.DoGoStmt(s); }
|
||||||
func (s *DeferStat) Visit(v StatVisitor) { v.DoDeferStat(s); }
|
func (s *DeferStmt) Visit(v StmtVisitor) { v.DoDeferStmt(s); }
|
||||||
func (s *ReturnStat) Visit(v StatVisitor) { v.DoReturnStat(s); }
|
func (s *ReturnStmt) Visit(v StmtVisitor) { v.DoReturnStmt(s); }
|
||||||
func (s *ControlFlowStat) Visit(v StatVisitor) { v.DoControlFlowStat(s); }
|
func (s *BranchStmt) Visit(v StmtVisitor) { v.DoBranchStmt(s); }
|
||||||
func (s *CompositeStat) Visit(v StatVisitor) { v.DoCompositeStat(s); }
|
func (s *BlockStmt) Visit(v StmtVisitor) { v.DoBlockStmt(s); }
|
||||||
func (s *IfStat) Visit(v StatVisitor) { v.DoIfStat(s); }
|
func (s *IfStmt) Visit(v StmtVisitor) { v.DoIfStmt(s); }
|
||||||
func (s *CaseClause) Visit(v StatVisitor) { v.DoCaseClause(s); }
|
func (s *CaseClause) Visit(v StmtVisitor) { v.DoCaseClause(s); }
|
||||||
func (s *SwitchStat) Visit(v StatVisitor) { v.DoSwitchStat(s); }
|
func (s *SwitchStmt) Visit(v StmtVisitor) { v.DoSwitchStmt(s); }
|
||||||
func (s *TypeCaseClause) Visit(v StatVisitor) { v.DoTypeCaseClause(s); }
|
func (s *TypeCaseClause) Visit(v StmtVisitor) { v.DoTypeCaseClause(s); }
|
||||||
func (s *TypeSwitchStat) Visit(v StatVisitor) { v.DoTypeSwitchStat(s); }
|
func (s *TypeSwitchStmt) Visit(v StmtVisitor) { v.DoTypeSwitchStmt(s); }
|
||||||
func (s *CommClause) Visit(v StatVisitor) { v.DoCommClause(s); }
|
func (s *CommClause) Visit(v StmtVisitor) { v.DoCommClause(s); }
|
||||||
func (s *SelectStat) Visit(v StatVisitor) { v.DoSelectStat(s); }
|
func (s *SelectStmt) Visit(v StmtVisitor) { v.DoSelectStmt(s); }
|
||||||
func (s *ForStat) Visit(v StatVisitor) { v.DoForStat(s); }
|
func (s *ForStmt) Visit(v StmtVisitor) { v.DoForStmt(s); }
|
||||||
func (s *RangeStat) Visit(v StatVisitor) { v.DoRangeStat(s); }
|
func (s *RangeStmt) Visit(v StmtVisitor) { v.DoRangeStmt(s); }
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -673,46 +690,45 @@ type (
|
|||||||
};
|
};
|
||||||
|
|
||||||
ImportDecl struct {
|
ImportDecl struct {
|
||||||
Doc Comments; // associated documentation
|
Doc Comments; // associated documentation; or nil
|
||||||
Import Position; // position of "import" keyword
|
Import Position; // position of "import" keyword
|
||||||
Name *Ident; // local package name or nil
|
Name *Ident; // local package name or nil
|
||||||
Path *StringLit; // package path
|
Path []*StringLit; // package path
|
||||||
};
|
};
|
||||||
|
|
||||||
ConstDecl struct {
|
ConstDecl struct {
|
||||||
Doc Comments; // associated documentation
|
Doc Comments; // associated documentation; or nil
|
||||||
Const Position; // position of "const" keyword
|
Const Position; // position of "const" keyword
|
||||||
Names []*Ident;
|
Names []*Ident;
|
||||||
Typ Expr; // constant type or nil
|
Type Expr; // constant type or nil
|
||||||
Values []Expr;
|
Values []Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
TypeDecl struct {
|
TypeDecl struct {
|
||||||
Doc Comments; // associated documentation
|
Doc Comments; // associated documentation; or nil
|
||||||
Type Position; // position of "type" keyword
|
Pos_ Position; // position of "type" keyword
|
||||||
Name *Ident;
|
Name *Ident;
|
||||||
Typ Expr;
|
Type Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
VarDecl struct {
|
VarDecl struct {
|
||||||
Doc Comments; // associated documentation
|
Doc Comments; // associated documentation; or nil
|
||||||
Var Position; // position of "var" keyword
|
Var Position; // position of "var" keyword
|
||||||
Names []*Ident;
|
Names []*Ident;
|
||||||
Typ Expr; // variable type or nil
|
Type Expr; // variable type or nil
|
||||||
Values []Expr;
|
Values []Expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
FuncDecl struct {
|
FuncDecl struct {
|
||||||
Doc Comments; // associated documentation
|
Doc Comments; // associated documentation; or nil
|
||||||
Func Position; // position of "func" keyword
|
|
||||||
Recv *Field; // receiver (methods) or nil (functions)
|
Recv *Field; // receiver (methods) or nil (functions)
|
||||||
Name *Ident; // function/method name
|
Name *Ident; // function/method name
|
||||||
Sig *Signature; // parameters and results
|
Type *FunctionType; // position of Func keyword, parameters and results
|
||||||
Body *Block; // function body or nil (forward declaration)
|
Body *BlockStmt; // function body or nil (forward declaration)
|
||||||
};
|
};
|
||||||
|
|
||||||
DeclList struct {
|
DeclList struct {
|
||||||
Doc Comments; // associated documentation
|
Doc Comments; // associated documentation; or nil
|
||||||
Pos_ Position; // position of token
|
Pos_ Position; // position of token
|
||||||
Tok int; // IMPORT, CONST, VAR, TYPE
|
Tok int; // IMPORT, CONST, VAR, TYPE
|
||||||
Lparen Position; // position of '('
|
Lparen Position; // position of '('
|
||||||
@ -727,9 +743,9 @@ type (
|
|||||||
func (d *BadDecl) Pos() Position { return d.Pos_; }
|
func (d *BadDecl) Pos() Position { return d.Pos_; }
|
||||||
func (d *ImportDecl) Pos() Position { return d.Import; }
|
func (d *ImportDecl) Pos() Position { return d.Import; }
|
||||||
func (d *ConstDecl) Pos() Position { return d.Const; }
|
func (d *ConstDecl) Pos() Position { return d.Const; }
|
||||||
func (d *TypeDecl) Pos() Position { return d.Type; }
|
func (d *TypeDecl) Pos() Position { return d.Pos_; }
|
||||||
func (d *VarDecl) Pos() Position { return d.Var; }
|
func (d *VarDecl) Pos() Position { return d.Var; }
|
||||||
func (d *FuncDecl) Pos() Position { return d.Func; }
|
func (d *FuncDecl) Pos() Position { return d.Type.Func; }
|
||||||
func (d *DeclList) Pos() Position { return d.Lparen; }
|
func (d *DeclList) Pos() Position { return d.Lparen; }
|
||||||
|
|
||||||
|
|
||||||
@ -765,7 +781,7 @@ func (d *DeclList) Visit(v DeclVisitor) { v.DoDeclList(d); }
|
|||||||
|
|
||||||
// A Package node represents the root node of an AST.
|
// A Package node represents the root node of an AST.
|
||||||
type Package struct {
|
type Package struct {
|
||||||
Doc Comments; // associated documentation
|
Doc Comments; // associated documentation; or nil
|
||||||
Package Position; // position of "package" keyword
|
Package Position; // position of "package" keyword
|
||||||
Name *Ident; // package name
|
Name *Ident; // package name
|
||||||
Decls []Decl; // top-level declarations
|
Decls []Decl; // top-level declarations
|
||||||
|
Loading…
Reference in New Issue
Block a user