-
Notifications
You must be signed in to change notification settings - Fork 566
XGo AST Design: Static Members
This document describes the AST representation of static constants, static variables, and static methods/functions in XGo, covering both normal XGo files and classfiles.
XGo introduces static members — static constants, static variables, and static methods — as type-scoped declarations. The AST must distinguish these from global declarations and instance members. Two existing node types carry this information:
-
FuncDecl— for functions and methods (static or not) -
ValueSpec— forconstandvardeclarations (static or not)
type FuncDecl struct {
Doc *CommentGroup // associated documentation; or nil
Recv *FieldList // receiver (methods); or nil (functions)
Name *Ident // function/method name
Type *FuncType // function signature: parameters, results, and position of "func" keyword
Body *BlockStmt // function body; or nil for external (non-Go) function
Operator bool // is operator or not
Shadow bool // is a shadow entry
IsClass bool // recv set by class
Static bool // recv is static (class method)
}-
Static bool: set totruewhen the declaration is a static method (eitherT.Methodor.Methodform). -
Recv *FieldList: carries the receiver typeTfor theT.Methodform; non-nil but withlen(Recv.List) == 0for the.Methodshorthand form in classfiles. -
Name *Ident: always holds the bare method name (without theT.or.prefix).
| Context | Syntax | Static |
Recv |
Name |
|---|---|---|---|---|
| Normal XGo | func name(...) |
false |
nil |
"name" |
| Normal XGo | func T.Method(...) |
true |
FieldList{List: [T]} |
"Method" |
| Classfile | func name(...) |
false |
non-nil, set by class (IsClass=true) |
"name" |
| Classfile | func T.Method(...) |
true |
FieldList{List: [T]} |
"Method" |
| Classfile | func .Method(...) |
true |
FieldList{List: nil} (empty list) |
"Method" |
- For normal XGo, a bare
func name(...)is a global function:Static=false,Recv=nil. - For classfiles, a bare
func name(...)is an instance method:Static=false,Recvis non-nil and set by the class mechanism (IsClass=true). -
func T.Method(...)is unambiguously a static method in both contexts.RecvholdsTas a regular field entry. -
func .Method(...)is the classfile shorthand for a static method on the owning class.Recvis non-nil butlen(Recv.List) == 0, indicating "static on the implicit class type."
type ValueSpec struct {
Doc *CommentGroup // associated documentation; or nil
Names []*Ident // value names (len >= 1)
Type Expr // value type; or nil
Tag *BasicLit // classfile field tag; or nil
Values []Expr // initial values; or nil
Comment *CommentGroup // line comments; or nil
HasStatic bool // true if any name is in ".name" or "T.name" form
}-
HasStatic bool: set totruewhen at least one name inNamesuses theT.nameor.namestatic form. Whenfalse, all names are bare identifiers (global or instance members). -
Names []*Ident: eachIdentin the slice carries its parsed name. For a static name inT.nameform the identifier encodes the qualifier; for.nameform the identifier encodes the shorthand.
Note: A single
ValueSpecmay mix static and non-static names (e.g.,const T.A, B = 1, 2).HasStaticsignals that at least one name requires special handling; consumers must inspect eachIdentindividually to determine which names are static.
| Context | Syntax | HasStatic |
Names entries |
Semantics |
|---|---|---|---|---|
| Normal XGo | const name = ... |
false |
["name"] |
Global constant |
| Normal XGo | const T.name = ... |
true |
["T.name"] |
Static constant |
| Classfile | const name = ... |
false |
["name"] |
Global constant |
| Classfile | const T.name = ... |
true |
["T.name"] |
Static constant |
| Classfile | const .name = ... |
true |
[".name"] |
Static constant |
| Context | Syntax | HasStatic |
Names entries |
Semantics |
|---|---|---|---|---|
| Normal XGo | var name V = ... |
false |
["name"] |
Global variable |
| Normal XGo | var T.name V = ... |
true |
["T.name"] |
Static variable |
| Classfile | var name V = ... |
false |
["name"] |
Class (instance) member † |
| Classfile | var T.name V = ... |
true |
["T.name"] |
Static variable |
| Classfile | var .name V = ... |
true |
[".name"] |
Static variable |
† In classfiles, bare var name declares a class (instance) member. At most one top-level var block with bare names is permitted per classfile; a second such block is a compile-time error.
| Kind | Context | Form |
Static / HasStatic
|
Semantics |
|---|---|---|---|---|
func |
Normal XGo | name |
Static=false |
Global function |
func |
Normal XGo | T.Method |
Static=true |
Static method |
func |
Classfile | name |
Static=false |
Instance method |
func |
Classfile | T.Method |
Static=true |
Static method |
func |
Classfile | .Method |
Static=true |
Static method (shorthand) |
const |
Normal XGo | name |
HasStatic=false |
Global constant |
const |
Normal XGo | T.name |
HasStatic=true |
Static constant |
const |
Classfile | name |
HasStatic=false |
Global constant |
const |
Classfile | T.name |
HasStatic=true |
Static constant |
const |
Classfile | .name |
HasStatic=true |
Static constant (shorthand) |
var |
Normal XGo | name |
HasStatic=false |
Global variable |
var |
Normal XGo | T.name |
HasStatic=true |
Static variable |
var |
Classfile | name |
HasStatic=false |
Class (instance) member |
var |
Classfile | T.name |
HasStatic=true |
Static variable |
var |
Classfile | .name |
HasStatic=true |
Static variable (shorthand) |
When walking the AST, consumers can classify any declaration using the following rules:
if Static == false && Recv == nil → global function (normal XGo)
if Static == false && Recv != nil → instance method (classfile, IsClass=true)
if Static == true && len(Recv.List) > 0 → static method with explicit type T
if Static == true && len(Recv.List) == 0 → static method via classfile shorthand (.Method)
if HasStatic == false → all names are global constants (both contexts)
if HasStatic == true → at least one name is a static constant;
inspect each Ident for "T.name" or ".name" form
if HasStatic == false, in normal XGo → all names are global variables
if HasStatic == false, in classfile → all names are class (instance) members
if HasStatic == true → at least one name is a static variable;
inspect each Ident for "T.name" or ".name" form
-
Classfile
varblock limit: A classfile may contain at most one top-levelvarblock whose names are bare (non-static) identifiers. Parsing a second such block is a compile-time error. -
typedeclarations:typedeclarations are always global in both contexts. There is noT.Nameor.Namesyntax for types, and no static flag is needed on type nodes. -
Mixed
ValueSpec: A singleValueSpecmay contain both static and non-static names.HasStatic=truedoes not imply that all names are static — only that at least one is. Semantic analysis must inspect individualIdentnodes.