mirror of
https://github.com/google/go-jsonnet.git
synced 2025-08-10 00:07:13 +02:00
memory align structs (#635)
feat: align most structs and add lint rule to enforce struct alignment
This commit is contained in:
parent
8abb4aa639
commit
2655afd2bd
@ -5,11 +5,24 @@ linters:
|
|||||||
- stylecheck
|
- stylecheck
|
||||||
- gochecknoinits
|
- gochecknoinits
|
||||||
- golint
|
- golint
|
||||||
|
- govet
|
||||||
issues:
|
issues:
|
||||||
exclude-use-default: false
|
exclude-use-default: false
|
||||||
exclude:
|
exclude:
|
||||||
- "should have a package comment, unless it's in another file for this package"
|
- "should have a package comment, unless it's in another file for this package"
|
||||||
- "the surrounding loop is unconditionally terminated"
|
- "the surrounding loop is unconditionally terminated"
|
||||||
|
exclude-rules:
|
||||||
|
# ignore govet on non-critical files
|
||||||
|
- path: 'linter/*'
|
||||||
|
linters:
|
||||||
|
- govet
|
||||||
|
- path: '(.+)_test\.go'
|
||||||
|
linters:
|
||||||
|
- govet
|
||||||
linters-settings:
|
linters-settings:
|
||||||
golint:
|
golint:
|
||||||
min-confidence: 0
|
min-confidence: 0
|
||||||
|
govet:
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
- shadow
|
||||||
|
177
ast/ast.go
177
ast/ast.go
@ -22,7 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Identifier represents a variable / parameter / field name.
|
// Identifier represents a variable / parameter / field name.
|
||||||
//+gen set
|
// +gen set
|
||||||
type Identifier string
|
type Identifier string
|
||||||
|
|
||||||
// Identifiers represents an Identifier slice.
|
// Identifiers represents an Identifier slice.
|
||||||
@ -59,13 +59,13 @@ type Nodes []Node
|
|||||||
|
|
||||||
// NodeBase holds fields common to all node types.
|
// NodeBase holds fields common to all node types.
|
||||||
type NodeBase struct {
|
type NodeBase struct {
|
||||||
LocRange LocationRange
|
|
||||||
// This is the fodder that precedes the first token of the node.
|
// This is the fodder that precedes the first token of the node.
|
||||||
// If the node is left-recursive, i.e. the first token is actually
|
// If the node is left-recursive, i.e. the first token is actually
|
||||||
// a token of a sub-expression, then Fodder is nil.
|
// a token of a sub-expression, then Fodder is nil.
|
||||||
Fodder Fodder
|
Fodder Fodder
|
||||||
Ctx Context
|
Ctx Context
|
||||||
FreeVars Identifiers
|
FreeVars Identifiers
|
||||||
|
LocRange LocationRange
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNodeBase creates a new NodeBase from initial LocationRange and
|
// NewNodeBase creates a new NodeBase from initial LocationRange and
|
||||||
@ -117,8 +117,8 @@ func (n *NodeBase) SetContext(context Context) {
|
|||||||
|
|
||||||
// IfSpec represents an if-specification in a comprehension.
|
// IfSpec represents an if-specification in a comprehension.
|
||||||
type IfSpec struct {
|
type IfSpec struct {
|
||||||
IfFodder Fodder
|
|
||||||
Expr Node
|
Expr Node
|
||||||
|
IfFodder Fodder
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForSpec represents a for-specification in a comprehension.
|
// ForSpec represents a for-specification in a comprehension.
|
||||||
@ -135,34 +135,35 @@ type IfSpec struct {
|
|||||||
// The if is attached to the y forspec.
|
// The if is attached to the y forspec.
|
||||||
//
|
//
|
||||||
// It desugares to:
|
// It desugares to:
|
||||||
// flatMap(\x ->
|
//
|
||||||
// flatMap(\y ->
|
// flatMap(\x ->
|
||||||
// flatMap(\z -> [expr], arr3)
|
// flatMap(\y ->
|
||||||
// arr2)
|
// flatMap(\z -> [expr], arr3)
|
||||||
// arr3)
|
// arr2)
|
||||||
|
// arr3)
|
||||||
type ForSpec struct {
|
type ForSpec struct {
|
||||||
ForFodder Fodder
|
ForFodder Fodder
|
||||||
VarFodder Fodder
|
VarFodder Fodder
|
||||||
VarName Identifier
|
|
||||||
InFodder Fodder
|
|
||||||
Expr Node
|
|
||||||
Conditions []IfSpec
|
Conditions []IfSpec
|
||||||
Outer *ForSpec
|
Outer *ForSpec
|
||||||
|
Expr Node
|
||||||
|
VarName Identifier
|
||||||
|
InFodder Fodder
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Apply represents a function call
|
// Apply represents a function call
|
||||||
type Apply struct {
|
type Apply struct {
|
||||||
NodeBase
|
Target Node
|
||||||
Target Node
|
FodderLeft Fodder
|
||||||
FodderLeft Fodder
|
Arguments Arguments
|
||||||
Arguments Arguments
|
|
||||||
// Always false if there were no arguments.
|
|
||||||
TrailingComma bool
|
|
||||||
TailStrict bool
|
|
||||||
FodderRight Fodder
|
FodderRight Fodder
|
||||||
TailStrictFodder Fodder
|
TailStrictFodder Fodder
|
||||||
|
NodeBase
|
||||||
|
// Always false if there were no arguments.
|
||||||
|
TrailingComma bool
|
||||||
|
TailStrict bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NamedArgument represents a named argument to function call x=1.
|
// NamedArgument represents a named argument to function call x=1.
|
||||||
@ -193,20 +194,20 @@ type Arguments struct {
|
|||||||
|
|
||||||
// ApplyBrace represents e { }. Desugared to e + { }.
|
// ApplyBrace represents e { }. Desugared to e + { }.
|
||||||
type ApplyBrace struct {
|
type ApplyBrace struct {
|
||||||
NodeBase
|
|
||||||
Left Node
|
Left Node
|
||||||
Right Node
|
Right Node
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Array represents array constructors [1, 2, 3].
|
// Array represents array constructors [1, 2, 3].
|
||||||
type Array struct {
|
type Array struct {
|
||||||
|
Elements []CommaSeparatedExpr
|
||||||
|
CloseFodder Fodder
|
||||||
NodeBase
|
NodeBase
|
||||||
Elements []CommaSeparatedExpr
|
|
||||||
// Always false if there were no elements.
|
// Always false if there were no elements.
|
||||||
TrailingComma bool
|
TrailingComma bool
|
||||||
CloseFodder Fodder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -214,12 +215,12 @@ type Array struct {
|
|||||||
// ArrayComp represents array comprehensions (which are like Python list
|
// ArrayComp represents array comprehensions (which are like Python list
|
||||||
// comprehensions)
|
// comprehensions)
|
||||||
type ArrayComp struct {
|
type ArrayComp struct {
|
||||||
NodeBase
|
|
||||||
Body Node
|
Body Node
|
||||||
TrailingComma bool
|
|
||||||
TrailingCommaFodder Fodder
|
TrailingCommaFodder Fodder
|
||||||
Spec ForSpec
|
Spec ForSpec
|
||||||
CloseFodder Fodder
|
CloseFodder Fodder
|
||||||
|
NodeBase
|
||||||
|
TrailingComma bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -229,12 +230,12 @@ type ArrayComp struct {
|
|||||||
// After parsing, message can be nil indicating that no message was
|
// After parsing, message can be nil indicating that no message was
|
||||||
// specified. This AST is elimiated by desugaring.
|
// specified. This AST is elimiated by desugaring.
|
||||||
type Assert struct {
|
type Assert struct {
|
||||||
NodeBase
|
|
||||||
Cond Node
|
Cond Node
|
||||||
ColonFodder Fodder
|
|
||||||
Message Node
|
Message Node
|
||||||
SemicolonFodder Fodder
|
|
||||||
Rest Node
|
Rest Node
|
||||||
|
ColonFodder Fodder
|
||||||
|
SemicolonFodder Fodder
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -337,11 +338,11 @@ func (b BinaryOp) String() string {
|
|||||||
|
|
||||||
// Binary represents binary operators.
|
// Binary represents binary operators.
|
||||||
type Binary struct {
|
type Binary struct {
|
||||||
NodeBase
|
Right Node
|
||||||
Left Node
|
Left Node
|
||||||
OpFodder Fodder
|
OpFodder Fodder
|
||||||
Op BinaryOp
|
NodeBase
|
||||||
Right Node
|
Op BinaryOp
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -351,12 +352,12 @@ type Binary struct {
|
|||||||
// After parsing, branchFalse can be nil indicating that no else branch
|
// After parsing, branchFalse can be nil indicating that no else branch
|
||||||
// was specified. The desugarer fills this in with a LiteralNull
|
// was specified. The desugarer fills this in with a LiteralNull
|
||||||
type Conditional struct {
|
type Conditional struct {
|
||||||
NodeBase
|
|
||||||
Cond Node
|
Cond Node
|
||||||
ThenFodder Fodder
|
|
||||||
BranchTrue Node
|
BranchTrue Node
|
||||||
ElseFodder Fodder
|
|
||||||
BranchFalse Node
|
BranchFalse Node
|
||||||
|
ThenFodder Fodder
|
||||||
|
ElseFodder Fodder
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -368,21 +369,21 @@ type Dollar struct{ NodeBase }
|
|||||||
|
|
||||||
// Error represents the error e.
|
// Error represents the error e.
|
||||||
type Error struct {
|
type Error struct {
|
||||||
NodeBase
|
|
||||||
Expr Node
|
Expr Node
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Function represents a function definition
|
// Function represents a function definition
|
||||||
type Function struct {
|
type Function struct {
|
||||||
NodeBase
|
ParenLeftFodder Fodder
|
||||||
ParenLeftFodder Fodder
|
|
||||||
Parameters []Parameter
|
|
||||||
// Always false if there were no parameters.
|
|
||||||
TrailingComma bool
|
|
||||||
ParenRightFodder Fodder
|
ParenRightFodder Fodder
|
||||||
Body Node
|
Body Node
|
||||||
|
Parameters []Parameter
|
||||||
|
NodeBase
|
||||||
|
// Always false if there were no parameters.
|
||||||
|
TrailingComma bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameter represents a parameter of function.
|
// Parameter represents a parameter of function.
|
||||||
@ -391,9 +392,9 @@ type Function struct {
|
|||||||
type Parameter struct {
|
type Parameter struct {
|
||||||
NameFodder Fodder
|
NameFodder Fodder
|
||||||
Name Identifier
|
Name Identifier
|
||||||
|
CommaFodder Fodder
|
||||||
EqFodder Fodder
|
EqFodder Fodder
|
||||||
DefaultArg Node
|
DefaultArg Node
|
||||||
CommaFodder Fodder
|
|
||||||
LocRange LocationRange
|
LocRange LocationRange
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,24 +410,24 @@ type CommaSeparatedID struct {
|
|||||||
|
|
||||||
// Import represents import "file".
|
// Import represents import "file".
|
||||||
type Import struct {
|
type Import struct {
|
||||||
NodeBase
|
|
||||||
File *LiteralString
|
File *LiteralString
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// ImportStr represents importstr "file".
|
// ImportStr represents importstr "file".
|
||||||
type ImportStr struct {
|
type ImportStr struct {
|
||||||
NodeBase
|
|
||||||
File *LiteralString
|
File *LiteralString
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// ImportBin represents importbin "file".
|
// ImportBin represents importbin "file".
|
||||||
type ImportBin struct {
|
type ImportBin struct {
|
||||||
NodeBase
|
|
||||||
File *LiteralString
|
File *LiteralString
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -436,24 +437,22 @@ type ImportBin struct {
|
|||||||
// One of index and id will be nil before desugaring. After desugaring id
|
// One of index and id will be nil before desugaring. After desugaring id
|
||||||
// will be nil.
|
// will be nil.
|
||||||
type Index struct {
|
type Index struct {
|
||||||
NodeBase
|
|
||||||
Target Node
|
Target Node
|
||||||
// When Index is being used, this is the fodder before the '['.
|
Index Node
|
||||||
// When Id is being used, this is the fodder before the '.'.
|
|
||||||
LeftBracketFodder Fodder
|
|
||||||
Index Node
|
|
||||||
// When Index is being used, this is the fodder before the ']'.
|
// When Index is being used, this is the fodder before the ']'.
|
||||||
// When Id is being used, this is the fodder before the id.
|
// When Id is being used, this is the fodder before the id.
|
||||||
RightBracketFodder Fodder
|
RightBracketFodder Fodder
|
||||||
|
// When Index is being used, this is the fodder before the '['.
|
||||||
|
// When Id is being used, this is the fodder before the '.'.
|
||||||
|
LeftBracketFodder Fodder
|
||||||
//nolint: golint,stylecheck // keeping Id instead of ID for now to avoid breaking 3rd parties
|
//nolint: golint,stylecheck // keeping Id instead of ID for now to avoid breaking 3rd parties
|
||||||
Id *Identifier
|
Id *Identifier
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slice represents an array slice a[begin:end:step].
|
// Slice represents an array slice a[begin:end:step].
|
||||||
type Slice struct {
|
type Slice struct {
|
||||||
NodeBase
|
Target Node
|
||||||
Target Node
|
|
||||||
|
|
||||||
LeftBracketFodder Fodder
|
LeftBracketFodder Fodder
|
||||||
// Each of these can be nil
|
// Each of these can be nil
|
||||||
BeginIndex Node
|
BeginIndex Node
|
||||||
@ -462,6 +461,7 @@ type Slice struct {
|
|||||||
StepColonFodder Fodder
|
StepColonFodder Fodder
|
||||||
Step Node
|
Step Node
|
||||||
RightBracketFodder Fodder
|
RightBracketFodder Fodder
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -469,15 +469,14 @@ type Slice struct {
|
|||||||
// LocalBind is a helper struct for astLocal
|
// LocalBind is a helper struct for astLocal
|
||||||
type LocalBind struct {
|
type LocalBind struct {
|
||||||
VarFodder Fodder
|
VarFodder Fodder
|
||||||
Variable Identifier
|
|
||||||
EqFodder Fodder
|
|
||||||
// If Fun is set then its body == Body.
|
// If Fun is set then its body == Body.
|
||||||
Body Node
|
Body Node
|
||||||
// There is no base fodder in Fun because there was no `function` keyword.
|
EqFodder Fodder
|
||||||
Fun *Function
|
Variable Identifier
|
||||||
// The fodder before the closing ',' or ';' (whichever it is)
|
// The fodder before the closing ',' or ';' (whichever it is)
|
||||||
CloseFodder Fodder
|
CloseFodder Fodder
|
||||||
|
// There is no base fodder in Fun because there was no `function` keyword.
|
||||||
|
Fun *Function
|
||||||
LocRange LocationRange
|
LocRange LocationRange
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,9 +485,9 @@ type LocalBinds []LocalBind
|
|||||||
|
|
||||||
// Local represents local x = e; e. After desugaring, functionSugar is false.
|
// Local represents local x = e; e. After desugaring, functionSugar is false.
|
||||||
type Local struct {
|
type Local struct {
|
||||||
NodeBase
|
|
||||||
Binds LocalBinds
|
Binds LocalBinds
|
||||||
Body Node
|
Body Node
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -508,8 +507,8 @@ type LiteralNull struct{ NodeBase }
|
|||||||
|
|
||||||
// LiteralNumber represents a JSON number
|
// LiteralNumber represents a JSON number
|
||||||
type LiteralNumber struct {
|
type LiteralNumber struct {
|
||||||
NodeBase
|
|
||||||
OriginalString string
|
OriginalString string
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -540,11 +539,11 @@ func (k LiteralStringKind) FullyEscaped() bool {
|
|||||||
|
|
||||||
// LiteralString represents a JSON string
|
// LiteralString represents a JSON string
|
||||||
type LiteralString struct {
|
type LiteralString struct {
|
||||||
NodeBase
|
|
||||||
Value string
|
Value string
|
||||||
Kind LiteralStringKind
|
|
||||||
BlockIndent string
|
BlockIndent string
|
||||||
BlockTermIndent string
|
BlockTermIndent string
|
||||||
|
NodeBase
|
||||||
|
Kind LiteralStringKind
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -588,24 +587,23 @@ const (
|
|||||||
// ObjectField represents a field of an object or object comprehension.
|
// ObjectField represents a field of an object or object comprehension.
|
||||||
// TODO(sbarzowski) consider having separate types for various kinds
|
// TODO(sbarzowski) consider having separate types for various kinds
|
||||||
type ObjectField struct {
|
type ObjectField struct {
|
||||||
Kind ObjectFieldKind
|
|
||||||
Hide ObjectFieldHide // (ignore if kind != astObjectFieldID/Expr/Str)
|
|
||||||
SuperSugar bool // +: (ignore if kind != astObjectFieldID/Expr/Str)
|
|
||||||
|
|
||||||
// f(x, y, z): ... (ignore if kind == astObjectAssert)
|
// f(x, y, z): ... (ignore if kind == astObjectAssert)
|
||||||
// If Method is set then Expr2 == Method.Body.
|
// If Method is set then Expr2 == Method.Body.
|
||||||
// There is no base fodder in Method because there was no `function`
|
// There is no base fodder in Method because there was no `function`
|
||||||
// keyword.
|
// keyword.
|
||||||
Method *Function
|
Method *Function
|
||||||
Fodder1 Fodder
|
|
||||||
Expr1 Node // Not in scope of the object
|
|
||||||
//nolint: golint,stylecheck // keeping Id instead of ID for now to avoid breaking 3rd parties
|
//nolint: golint,stylecheck // keeping Id instead of ID for now to avoid breaking 3rd parties
|
||||||
Id *Identifier
|
Id *Identifier
|
||||||
Fodder2 Fodder
|
Fodder2 Fodder
|
||||||
|
Fodder1 Fodder
|
||||||
OpFodder Fodder
|
OpFodder Fodder
|
||||||
Expr2, Expr3 Node // In scope of the object (can see self).
|
|
||||||
CommaFodder Fodder
|
CommaFodder Fodder
|
||||||
|
Expr1 Node // Not in scope of the object
|
||||||
|
Expr2, Expr3 Node // In scope of the object (can see self).
|
||||||
LocRange LocationRange
|
LocRange LocationRange
|
||||||
|
Kind ObjectFieldKind
|
||||||
|
Hide ObjectFieldHide // (ignore if kind != astObjectFieldID/Expr/Str)
|
||||||
|
SuperSugar bool // +: (ignore if kind != astObjectFieldID/Expr/Str)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectFieldLocalNoMethod creates a non-method local object field.
|
// ObjectFieldLocalNoMethod creates a non-method local object field.
|
||||||
@ -627,22 +625,21 @@ type ObjectFields []ObjectField
|
|||||||
// The trailing comma is only allowed if len(fields) > 0. Converted to
|
// The trailing comma is only allowed if len(fields) > 0. Converted to
|
||||||
// DesugaredObject during desugaring.
|
// DesugaredObject during desugaring.
|
||||||
type Object struct {
|
type Object struct {
|
||||||
|
Fields ObjectFields
|
||||||
|
CloseFodder Fodder
|
||||||
NodeBase
|
NodeBase
|
||||||
Fields ObjectFields
|
|
||||||
TrailingComma bool
|
TrailingComma bool
|
||||||
CloseFodder Fodder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// DesugaredObjectField represents a desugared object field.
|
// DesugaredObjectField represents a desugared object field.
|
||||||
type DesugaredObjectField struct {
|
type DesugaredObjectField struct {
|
||||||
Hide ObjectFieldHide
|
|
||||||
Name Node
|
Name Node
|
||||||
Body Node
|
Body Node
|
||||||
|
LocRange LocationRange
|
||||||
|
Hide ObjectFieldHide
|
||||||
PlusSuper bool
|
PlusSuper bool
|
||||||
|
|
||||||
LocRange LocationRange
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DesugaredObjectFields represents a DesugaredObjectField slice.
|
// DesugaredObjectFields represents a DesugaredObjectField slice.
|
||||||
@ -653,33 +650,35 @@ type DesugaredObjectFields []DesugaredObjectField
|
|||||||
//
|
//
|
||||||
// The assertions either return true or raise an error.
|
// The assertions either return true or raise an error.
|
||||||
type DesugaredObject struct {
|
type DesugaredObject struct {
|
||||||
NodeBase
|
|
||||||
Asserts Nodes
|
Asserts Nodes
|
||||||
Fields DesugaredObjectFields
|
Fields DesugaredObjectFields
|
||||||
Locals LocalBinds
|
Locals LocalBinds
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// ObjectComp represents object comprehension
|
// ObjectComp represents object comprehension
|
||||||
// { [e]: e for x in e for.. if... }.
|
//
|
||||||
|
// { [e]: e for x in e for.. if... }.
|
||||||
type ObjectComp struct {
|
type ObjectComp struct {
|
||||||
NodeBase
|
|
||||||
Fields ObjectFields
|
Fields ObjectFields
|
||||||
TrailingCommaFodder Fodder
|
TrailingCommaFodder Fodder
|
||||||
TrailingComma bool
|
|
||||||
Spec ForSpec
|
|
||||||
CloseFodder Fodder
|
CloseFodder Fodder
|
||||||
|
Spec ForSpec
|
||||||
|
NodeBase
|
||||||
|
TrailingComma bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Parens represents parentheses
|
// Parens represents parentheses
|
||||||
// ( e )
|
//
|
||||||
|
// ( e )
|
||||||
type Parens struct {
|
type Parens struct {
|
||||||
NodeBase
|
|
||||||
Inner Node
|
Inner Node
|
||||||
CloseFodder Fodder
|
CloseFodder Fodder
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -694,24 +693,24 @@ type Self struct{ NodeBase }
|
|||||||
// Either index or identifier will be set before desugaring. After desugaring, id will be
|
// Either index or identifier will be set before desugaring. After desugaring, id will be
|
||||||
// nil.
|
// nil.
|
||||||
type SuperIndex struct {
|
type SuperIndex struct {
|
||||||
NodeBase
|
|
||||||
// If super.f, the fodder before the '.'
|
|
||||||
// If super[e], the fodder before the '['.
|
|
||||||
DotFodder Fodder
|
|
||||||
Index Node
|
|
||||||
// If super.f, the fodder before the 'f'
|
// If super.f, the fodder before the 'f'
|
||||||
// If super[e], the fodder before the ']'.
|
// If super[e], the fodder before the ']'.
|
||||||
IDFodder Fodder
|
IDFodder Fodder
|
||||||
|
Index Node
|
||||||
|
// If super.f, the fodder before the '.'
|
||||||
|
// If super[e], the fodder before the '['.
|
||||||
|
DotFodder Fodder
|
||||||
//nolint: golint,stylecheck // keeping Id instead of ID for now to avoid breaking 3rd parties
|
//nolint: golint,stylecheck // keeping Id instead of ID for now to avoid breaking 3rd parties
|
||||||
Id *Identifier
|
Id *Identifier
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// InSuper represents the e in super construct.
|
// InSuper represents the e in super construct.
|
||||||
type InSuper struct {
|
type InSuper struct {
|
||||||
NodeBase
|
|
||||||
Index Node
|
Index Node
|
||||||
InFodder Fodder
|
InFodder Fodder
|
||||||
SuperFodder Fodder
|
SuperFodder Fodder
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@ -751,18 +750,18 @@ func (u UnaryOp) String() string {
|
|||||||
|
|
||||||
// Unary represents unary operators.
|
// Unary represents unary operators.
|
||||||
type Unary struct {
|
type Unary struct {
|
||||||
NodeBase
|
|
||||||
Op UnaryOp
|
|
||||||
Expr Node
|
Expr Node
|
||||||
|
NodeBase
|
||||||
|
Op UnaryOp
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Var represents variables.
|
// Var represents variables.
|
||||||
type Var struct {
|
type Var struct {
|
||||||
NodeBase
|
|
||||||
//nolint: golint,stylecheck // keeping Id instead of ID for now to avoid breaking 3rd parties
|
//nolint: golint,stylecheck // keeping Id instead of ID for now to avoid breaking 3rd parties
|
||||||
Id Identifier
|
Id Identifier
|
||||||
|
NodeBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -66,10 +66,10 @@ const (
|
|||||||
|
|
||||||
// FodderElement is a single piece of fodder.
|
// FodderElement is a single piece of fodder.
|
||||||
type FodderElement struct {
|
type FodderElement struct {
|
||||||
|
Comment []string
|
||||||
Kind FodderKind
|
Kind FodderKind
|
||||||
Blanks int
|
Blanks int
|
||||||
Indent int
|
Indent int
|
||||||
Comment []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeFodderElement is a helper function that checks some preconditions.
|
// MakeFodderElement is a helper function that checks some preconditions.
|
||||||
|
@ -28,10 +28,10 @@ type DiagnosticFileName string
|
|||||||
|
|
||||||
// Source represents a source file.
|
// Source represents a source file.
|
||||||
type Source struct {
|
type Source struct {
|
||||||
Lines []string
|
|
||||||
// DiagnosticFileName is the imported path or a special string
|
// DiagnosticFileName is the imported path or a special string
|
||||||
// for indicating stdin, extvars and other non-imported sources.
|
// for indicating stdin, extvars and other non-imported sources.
|
||||||
DiagnosticFileName DiagnosticFileName
|
DiagnosticFileName DiagnosticFileName
|
||||||
|
Lines []string
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -68,11 +68,11 @@ func LocationBefore(a Location, b Location) bool {
|
|||||||
|
|
||||||
// LocationRange represents a range of a source file.
|
// LocationRange represents a range of a source file.
|
||||||
type LocationRange struct {
|
type LocationRange struct {
|
||||||
|
File *Source
|
||||||
// FileName should be the imported path or "" for snippets etc.
|
// FileName should be the imported path or "" for snippets etc.
|
||||||
FileName string
|
FileName string
|
||||||
Begin Location
|
Begin Location
|
||||||
End Location // TODO(sbarzowski) inclusive? exclusive? a gap?
|
End Location // TODO(sbarzowski) inclusive? exclusive? a gap?
|
||||||
File *Source
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LocationRangeBetween returns a LocationRange containing both a and b.
|
// LocationRangeBetween returns a LocationRange containing both a and b.
|
||||||
@ -164,7 +164,7 @@ func BuildSource(dFilename DiagnosticFileName, s string) *Source {
|
|||||||
rest := lineBuf.String()
|
rest := lineBuf.String()
|
||||||
// Stuff after last end-of-line (EOF or some more code)
|
// Stuff after last end-of-line (EOF or some more code)
|
||||||
result = append(result, rest+"\n")
|
result = append(result, rest+"\n")
|
||||||
return &Source{result, dFilename}
|
return &Source{dFilename, result}
|
||||||
}
|
}
|
||||||
|
|
||||||
func trimToLine(loc LocationRange, line int) LocationRange {
|
func trimToLine(loc LocationRange, line int) LocationRange {
|
||||||
@ -187,11 +187,12 @@ func trimToLine(loc LocationRange, line int) LocationRange {
|
|||||||
|
|
||||||
// LineBeginning returns the part of a line directly before LocationRange
|
// LineBeginning returns the part of a line directly before LocationRange
|
||||||
// for example:
|
// for example:
|
||||||
// local x = foo()
|
//
|
||||||
// ^^^^^ <- LocationRange loc
|
// local x = foo()
|
||||||
// then
|
// ^^^^^ <- LocationRange loc
|
||||||
// local x = foo()
|
// then
|
||||||
// ^^^^^^^^^^ <- lineBeginning(loc)
|
// local x = foo()
|
||||||
|
// ^^^^^^^^^^ <- lineBeginning(loc)
|
||||||
func LineBeginning(loc *LocationRange) LocationRange {
|
func LineBeginning(loc *LocationRange) LocationRange {
|
||||||
return LocationRange{
|
return LocationRange{
|
||||||
Begin: Location{Line: loc.Begin.Line, Column: 1},
|
Begin: Location{Line: loc.Begin.Line, Column: 1},
|
||||||
@ -203,11 +204,12 @@ func LineBeginning(loc *LocationRange) LocationRange {
|
|||||||
|
|
||||||
// LineEnding returns the part of a line directly after LocationRange
|
// LineEnding returns the part of a line directly after LocationRange
|
||||||
// for example:
|
// for example:
|
||||||
// local x = foo() + test
|
//
|
||||||
// ^^^^^ <- LocationRange loc
|
// local x = foo() + test
|
||||||
// then
|
// ^^^^^ <- LocationRange loc
|
||||||
// local x = foo() + test
|
// then
|
||||||
// ^^^^^^^ <- lineEnding(loc)
|
// local x = foo() + test
|
||||||
|
// ^^^^^^^ <- lineEnding(loc)
|
||||||
func LineEnding(loc *LocationRange) LocationRange {
|
func LineEnding(loc *LocationRange) LocationRange {
|
||||||
return LocationRange{
|
return LocationRange{
|
||||||
Begin: loc.End,
|
Begin: loc.End,
|
||||||
|
10
builtins.go
10
builtins.go
@ -260,9 +260,9 @@ func builtinTrace(i *interpreter, x value, y value) (value, error) {
|
|||||||
// time. It is equivalent to `local i = 42; func(i)`. It therefore has no
|
// time. It is equivalent to `local i = 42; func(i)`. It therefore has no
|
||||||
// free variables and needs only an empty environment to execute.
|
// free variables and needs only an empty environment to execute.
|
||||||
type astMakeArrayElement struct {
|
type astMakeArrayElement struct {
|
||||||
ast.NodeBase
|
|
||||||
function *valueFunction
|
function *valueFunction
|
||||||
index int
|
ast.NodeBase
|
||||||
|
index int
|
||||||
}
|
}
|
||||||
|
|
||||||
func builtinMakeArray(i *interpreter, szv, funcv value) (value, error) {
|
func builtinMakeArray(i *interpreter, szv, funcv value) (value, error) {
|
||||||
@ -506,10 +506,10 @@ func builtinFilter(i *interpreter, funcv, arrv value) (value, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type sortData struct {
|
type sortData struct {
|
||||||
|
err error
|
||||||
i *interpreter
|
i *interpreter
|
||||||
thunks []*cachedThunk
|
thunks []*cachedThunk
|
||||||
keys []value
|
keys []value
|
||||||
err error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *sortData) Len() int {
|
func (d *sortData) Len() int {
|
||||||
@ -1917,10 +1917,10 @@ func (b *ternaryBuiltin) Name() ast.Identifier {
|
|||||||
type generalBuiltinFunc func(*interpreter, []value) (value, error)
|
type generalBuiltinFunc func(*interpreter, []value) (value, error)
|
||||||
|
|
||||||
type generalBuiltinParameter struct {
|
type generalBuiltinParameter struct {
|
||||||
name ast.Identifier
|
|
||||||
// Note that the defaults are passed as values rather than AST nodes like in Parameters.
|
// Note that the defaults are passed as values rather than AST nodes like in Parameters.
|
||||||
// This spares us unnecessary evaluation.
|
// This spares us unnecessary evaluation.
|
||||||
defaultValue value
|
defaultValue value
|
||||||
|
name ast.Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// generalBuiltin covers cases that other builtin structures do not,
|
// generalBuiltin covers cases that other builtin structures do not,
|
||||||
@ -1929,8 +1929,8 @@ type generalBuiltinParameter struct {
|
|||||||
// at the same index.
|
// at the same index.
|
||||||
type generalBuiltin struct {
|
type generalBuiltin struct {
|
||||||
name ast.Identifier
|
name ast.Identifier
|
||||||
params []generalBuiltinParameter
|
|
||||||
function generalBuiltinFunc
|
function generalBuiltinFunc
|
||||||
|
params []generalBuiltinParameter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *generalBuiltin) parameters() []namedParameter {
|
func (b *generalBuiltin) parameters() []namedParameter {
|
||||||
|
@ -16,8 +16,8 @@ import (
|
|||||||
|
|
||||||
// handlesTable is the set of active, valid Jsonnet allocated handles
|
// handlesTable is the set of active, valid Jsonnet allocated handles
|
||||||
type handlesTable struct {
|
type handlesTable struct {
|
||||||
mu sync.Mutex
|
|
||||||
handles map[uintptr]*handle
|
handles map[uintptr]*handle
|
||||||
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type handle struct {
|
type handle struct {
|
||||||
|
@ -93,15 +93,14 @@ func usage(o io.Writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
inputFiles []string
|
outputFile string
|
||||||
outputFile string
|
evalMultiOutputDir string
|
||||||
filenameIsCode bool
|
inputFiles []string
|
||||||
|
evalJpath []string
|
||||||
|
filenameIsCode bool
|
||||||
evalMulti bool
|
evalMulti bool
|
||||||
evalStream bool
|
evalStream bool
|
||||||
evalMultiOutputDir string
|
|
||||||
evalCreateOutputDirs bool
|
evalCreateOutputDirs bool
|
||||||
evalJpath []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeConfig() config {
|
func makeConfig() config {
|
||||||
|
@ -71,13 +71,13 @@ func usage(o io.Writer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
|
outputFile string
|
||||||
|
inputFiles []string
|
||||||
evalCreateOutputDirs bool
|
evalCreateOutputDirs bool
|
||||||
filenameIsCode bool
|
filenameIsCode bool
|
||||||
inPlace bool
|
inPlace bool
|
||||||
inputFiles []string
|
|
||||||
options formatter.Options
|
|
||||||
outputFile string
|
|
||||||
test bool
|
test bool
|
||||||
|
options formatter.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeConfig() config {
|
func makeConfig() config {
|
||||||
|
@ -43,17 +43,15 @@ type ColorFormatter func(w io.Writer, f string, a ...interface{}) (n int, err er
|
|||||||
var _ ErrorFormatter = &termErrorFormatter{}
|
var _ ErrorFormatter = &termErrorFormatter{}
|
||||||
|
|
||||||
type termErrorFormatter struct {
|
type termErrorFormatter struct {
|
||||||
// maxStackTraceSize is the maximum length of stack trace before cropping
|
|
||||||
maxStackTraceSize int
|
|
||||||
|
|
||||||
// Examples of current state of the art.
|
// Examples of current state of the art.
|
||||||
// http://elm-lang.org/blog/compiler-errors-for-humans
|
// http://elm-lang.org/blog/compiler-errors-for-humans
|
||||||
// https://clang.llvm.org/diagnostics.html
|
// https://clang.llvm.org/diagnostics.html
|
||||||
color ColorFormatter
|
color ColorFormatter
|
||||||
pretty bool
|
|
||||||
|
|
||||||
// sp is currently never set, but is used to format locations.
|
// sp is currently never set, but is used to format locations.
|
||||||
sp *ast.SourceProvider
|
sp *ast.SourceProvider
|
||||||
|
// maxStackTraceSize is the maximum length of stack trace before cropping
|
||||||
|
maxStackTraceSize int
|
||||||
|
pretty bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ef *termErrorFormatter) SetMaxStackTraceSize(size int) {
|
func (ef *termErrorFormatter) SetMaxStackTraceSize(size int) {
|
||||||
|
@ -70,6 +70,7 @@ func (c Contents) String() string {
|
|||||||
return *(*string)(unsafe.Pointer(c.data))
|
return *(*string)(unsafe.Pointer(c.data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data returns content bytes
|
||||||
func (c Contents) Data() []byte {
|
func (c Contents) Data() []byte {
|
||||||
return *c.data
|
return *c.data
|
||||||
}
|
}
|
||||||
@ -217,13 +218,13 @@ func (cache *importCache) importCode(importedFrom, importedPath string, i *inter
|
|||||||
|
|
||||||
// FileImporter imports data from the filesystem.
|
// FileImporter imports data from the filesystem.
|
||||||
type FileImporter struct {
|
type FileImporter struct {
|
||||||
JPaths []string
|
|
||||||
fsCache map[string]*fsCacheEntry
|
fsCache map[string]*fsCacheEntry
|
||||||
|
JPaths []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type fsCacheEntry struct {
|
type fsCacheEntry struct {
|
||||||
exists bool
|
|
||||||
contents Contents
|
contents Contents
|
||||||
|
exists bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (importer *FileImporter) tryPath(dir, importedPath string) (found bool, contents Contents, foundHere string, err error) {
|
func (importer *FileImporter) tryPath(dir, importedPath string) (found bool, contents Contents, foundHere string, err error) {
|
||||||
|
@ -33,11 +33,11 @@ var packageNameStripperRegexp = regexp.MustCompile(`\b[a-zA-Z_]+[a-zA-Z_0-9]+\.`
|
|||||||
|
|
||||||
// Options represents configuration option
|
// Options represents configuration option
|
||||||
type Options struct {
|
type Options struct {
|
||||||
StripPackageNames bool
|
|
||||||
HidePrivateFields bool
|
|
||||||
HomePackage string
|
HomePackage string
|
||||||
VariableName string
|
VariableName string
|
||||||
VariableDescription string
|
VariableDescription string
|
||||||
|
StripPackageNames bool
|
||||||
|
HidePrivateFields bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config is the default config used when calling Dump
|
// Config is the default config used when calling Dump
|
||||||
@ -48,7 +48,7 @@ var Config = Options{
|
|||||||
VariableDescription: "",
|
VariableDescription: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
type dumpState struct {
|
type dumpState struct { // nolint:govet
|
||||||
w io.Writer
|
w io.Writer
|
||||||
depth int
|
depth int
|
||||||
config *Options
|
config *Options
|
||||||
|
@ -38,8 +38,8 @@ type StaticError interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type staticError struct {
|
type staticError struct {
|
||||||
loc ast.LocationRange
|
|
||||||
msg string
|
msg string
|
||||||
|
loc ast.LocationRange
|
||||||
}
|
}
|
||||||
|
|
||||||
func (err staticError) WithContext(context string) StaticError {
|
func (err staticError) WithContext(context string) StaticError {
|
||||||
|
@ -23,8 +23,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type importElem struct {
|
type importElem struct {
|
||||||
key string
|
|
||||||
adjacentFodder ast.Fodder
|
adjacentFodder ast.Fodder
|
||||||
|
key string
|
||||||
bind ast.LocalBind
|
bind ast.LocalBind
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ func extractImportElems(binds ast.LocalBinds, after ast.Fodder) []importElem {
|
|||||||
newBind.VarFodder = before
|
newBind.VarFodder = before
|
||||||
theImport := bind.Body.(*ast.Import)
|
theImport := bind.Body.(*ast.Import)
|
||||||
result = append(result,
|
result = append(result,
|
||||||
importElem{theImport.File.Value, adjacent, newBind})
|
importElem{key: theImport.File.Value, adjacentFodder: adjacent, bind: newBind})
|
||||||
before = beforeNext
|
before = beforeNext
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
@ -144,7 +144,8 @@ func DirectChildren(node ast.Node) []ast.Node {
|
|||||||
// It supports ASTs before and after desugaring.
|
// It supports ASTs before and after desugaring.
|
||||||
//
|
//
|
||||||
// TODO(sbarzowski) Make sure it works well with boundary cases like tailstrict arguments,
|
// TODO(sbarzowski) Make sure it works well with boundary cases like tailstrict arguments,
|
||||||
// make it more precise.
|
// make it more precise.
|
||||||
|
//
|
||||||
// Rules:
|
// Rules:
|
||||||
// * (same-environment) They must be evaluated in the same environment as their parent
|
// * (same-environment) They must be evaluated in the same environment as their parent
|
||||||
// * (not-direct) If they can be direct children, they should (and cannot be thunked).
|
// * (not-direct) If they can be direct children, they should (and cannot be thunked).
|
||||||
|
@ -147,15 +147,13 @@ func (tk tokenKind) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type token struct {
|
type token struct {
|
||||||
kind tokenKind // The type of the token
|
|
||||||
fodder ast.Fodder // Any fodder that occurs before this token
|
fodder ast.Fodder // Any fodder that occurs before this token
|
||||||
data string // Content of the token if it is not a keyword
|
data string // Content of the token if it is not a keyword
|
||||||
|
|
||||||
// Extra info for when kind == tokenStringBlock
|
// Extra info for when kind == tokenStringBlock
|
||||||
stringBlockIndent string // The sequence of whitespace that indented the block.
|
stringBlockIndent string // The sequence of whitespace that indented the block.
|
||||||
stringBlockTermIndent string // This is always fewer whitespace characters than in stringBlockIndent.
|
stringBlockTermIndent string // This is always fewer whitespace characters than in stringBlockIndent.
|
||||||
|
loc ast.LocationRange
|
||||||
loc ast.LocationRange
|
kind tokenKind // The type of the token
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tokens is a slice of token structs.
|
// Tokens is a slice of token structs.
|
||||||
@ -283,8 +281,6 @@ type lexer struct {
|
|||||||
input string // The input string
|
input string // The input string
|
||||||
source *ast.Source
|
source *ast.Source
|
||||||
|
|
||||||
pos position // Current position in input
|
|
||||||
|
|
||||||
tokens Tokens // The tokens that we've generated so far
|
tokens Tokens // The tokens that we've generated so far
|
||||||
|
|
||||||
// Information about the token we are working on right now
|
// Information about the token we are working on right now
|
||||||
@ -294,6 +290,8 @@ type lexer struct {
|
|||||||
|
|
||||||
// Was the last rune the first rune on a line (ignoring initial whitespace).
|
// Was the last rune the first rune on a line (ignoring initial whitespace).
|
||||||
freshLine bool
|
freshLine bool
|
||||||
|
|
||||||
|
pos position // Current position in input
|
||||||
}
|
}
|
||||||
|
|
||||||
const lexEOF = -1
|
const lexEOF = -1
|
||||||
|
@ -32,15 +32,14 @@ import (
|
|||||||
// TODO(sbarzowski) use it as a pointer in most places b/c it can sometimes be shared
|
// TODO(sbarzowski) use it as a pointer in most places b/c it can sometimes be shared
|
||||||
// for example it can be shared between array elements and function arguments
|
// for example it can be shared between array elements and function arguments
|
||||||
type environment struct {
|
type environment struct {
|
||||||
selfBinding selfBinding
|
|
||||||
|
|
||||||
// Bindings introduced in this frame. The way previous bindings are treated
|
// Bindings introduced in this frame. The way previous bindings are treated
|
||||||
// depends on the type of a frame.
|
// depends on the type of a frame.
|
||||||
// If cleanEnv == true then previous bindings are ignored (it's a clean
|
// If cleanEnv == true then previous bindings are ignored (it's a clean
|
||||||
// environment with just the variables we have here).
|
// environment with just the variables we have here).
|
||||||
// If cleanEnv == false then if this frame doesn't contain a binding
|
// If cleanEnv == false then if this frame doesn't contain a binding
|
||||||
// previous bindings will be used.
|
// previous bindings will be used.
|
||||||
upValues bindingFrame
|
upValues bindingFrame
|
||||||
|
selfBinding selfBinding
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeEnvironment(upValues bindingFrame, sb selfBinding) environment {
|
func makeEnvironment(upValues bindingFrame, sb selfBinding) environment {
|
||||||
@ -64,20 +63,20 @@ func (i *interpreter) getCurrentStackTrace() []traceFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type callFrame struct {
|
type callFrame struct {
|
||||||
|
// Tracing information about the place where it was called from.
|
||||||
|
trace traceElement
|
||||||
|
|
||||||
|
env environment
|
||||||
|
|
||||||
// True if it switches to a clean environment (function call or array element)
|
// True if it switches to a clean environment (function call or array element)
|
||||||
// False otherwise, e.g. for local
|
// False otherwise, e.g. for local
|
||||||
cleanEnv bool
|
cleanEnv bool
|
||||||
|
|
||||||
// Tracing information about the place where it was called from.
|
|
||||||
trace traceElement
|
|
||||||
|
|
||||||
// Whether this frame can be removed from the stack when it doesn't affect
|
// Whether this frame can be removed from the stack when it doesn't affect
|
||||||
// the evaluation result, but in case of an error, it won't appear on the
|
// the evaluation result, but in case of an error, it won't appear on the
|
||||||
// stack trace.
|
// stack trace.
|
||||||
// It's used for tail call optimization.
|
// It's used for tail call optimization.
|
||||||
trimmable bool
|
trimmable bool
|
||||||
|
|
||||||
env environment
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpCallFrame(c *callFrame) string {
|
func dumpCallFrame(c *callFrame) string {
|
||||||
@ -95,10 +94,10 @@ func dumpCallFrame(c *callFrame) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type callStack struct {
|
type callStack struct {
|
||||||
|
currentTrace traceElement
|
||||||
|
stack []*callFrame
|
||||||
calls int
|
calls int
|
||||||
limit int
|
limit int
|
||||||
stack []*callFrame
|
|
||||||
currentTrace traceElement
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpCallStack(c *callStack) string {
|
func dumpCallStack(c *callStack) string {
|
||||||
@ -242,10 +241,8 @@ func makeCallStack(limit int) callStack {
|
|||||||
|
|
||||||
// Keeps current execution context and evaluates things
|
// Keeps current execution context and evaluates things
|
||||||
type interpreter struct {
|
type interpreter struct {
|
||||||
// Current stack. It is used for:
|
// Output stream for trace() for
|
||||||
// 1) Keeping environment (object we're in, variables)
|
traceOut io.Writer
|
||||||
// 2) Diagnostic information in case of failure
|
|
||||||
stack callStack
|
|
||||||
|
|
||||||
// External variables
|
// External variables
|
||||||
extVars map[string]*cachedThunk
|
extVars map[string]*cachedThunk
|
||||||
@ -259,8 +256,10 @@ type interpreter struct {
|
|||||||
// Keeps imports
|
// Keeps imports
|
||||||
importCache *importCache
|
importCache *importCache
|
||||||
|
|
||||||
// Output stream for trace() for
|
// Current stack. It is used for:
|
||||||
traceOut io.Writer
|
// 1) Keeping environment (object we're in, variables)
|
||||||
|
// 2) Diagnostic information in case of failure
|
||||||
|
stack callStack
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map union, b takes precedence when keys collide.
|
// Map union, b takes precedence when keys collide.
|
||||||
@ -414,7 +413,7 @@ func (i *interpreter) evaluate(a ast.Node, tc tailCallStatus) (value, error) {
|
|||||||
if field.PlusSuper {
|
if field.PlusSuper {
|
||||||
f = &plusSuperUnboundField{f}
|
f = &plusSuperUnboundField{f}
|
||||||
}
|
}
|
||||||
fields[fieldName] = simpleObjectField{field.Hide, f}
|
fields[fieldName] = simpleObjectField{f, field.Hide}
|
||||||
}
|
}
|
||||||
var asserts []unboundField
|
var asserts []unboundField
|
||||||
for _, assert := range node.Asserts {
|
for _, assert := range node.Asserts {
|
||||||
@ -1181,7 +1180,7 @@ func buildStdObject(i *interpreter) (*valueObject, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for name, value := range builtinFields {
|
for name, value := range builtinFields {
|
||||||
obj.fields[name] = simpleObjectField{ast.ObjectFieldHidden, value}
|
obj.fields[name] = simpleObjectField{value, ast.ObjectFieldHidden}
|
||||||
}
|
}
|
||||||
return objVal.(*valueObject), nil
|
return objVal.(*valueObject), nil
|
||||||
}
|
}
|
||||||
@ -1231,7 +1230,7 @@ func prepareExtVars(i *interpreter, ext vmExtMap, kind string) map[string]*cache
|
|||||||
func buildObject(hide ast.ObjectFieldHide, fields map[string]value) *valueObject {
|
func buildObject(hide ast.ObjectFieldHide, fields map[string]value) *valueObject {
|
||||||
fieldMap := simpleObjectFieldMap{}
|
fieldMap := simpleObjectFieldMap{}
|
||||||
for name, v := range fields {
|
for name, v := range fields {
|
||||||
fieldMap[name] = simpleObjectField{hide, &readyValue{v}}
|
fieldMap[name] = simpleObjectField{&readyValue{v}, hide}
|
||||||
}
|
}
|
||||||
return makeValueSimpleObject(bindingFrame{}, fieldMap, nil, nil)
|
return makeValueSimpleObject(bindingFrame{}, fieldMap, nil, nil)
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ import "github.com/google/go-jsonnet/ast"
|
|||||||
|
|
||||||
// RuntimeError is an error discovered during evaluation of the program
|
// RuntimeError is an error discovered during evaluation of the program
|
||||||
type RuntimeError struct {
|
type RuntimeError struct {
|
||||||
StackTrace []traceFrame
|
|
||||||
Msg string
|
Msg string
|
||||||
|
StackTrace []traceFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeRuntimeError(msg string, stackTrace []traceFrame) RuntimeError {
|
func makeRuntimeError(msg string, stackTrace []traceFrame) RuntimeError {
|
||||||
@ -40,8 +40,8 @@ func (err RuntimeError) Error() string {
|
|||||||
// traceFrame is tracing information about a single frame of the call stack.
|
// traceFrame is tracing information about a single frame of the call stack.
|
||||||
// TODO(sbarzowski) the difference from traceElement. Do we even need this?
|
// TODO(sbarzowski) the difference from traceElement. Do we even need this?
|
||||||
type traceFrame struct {
|
type traceFrame struct {
|
||||||
Loc ast.LocationRange
|
|
||||||
Name string
|
Name string
|
||||||
|
Loc ast.LocationRange
|
||||||
}
|
}
|
||||||
|
|
||||||
func traceElementToTraceFrame(trace traceElement) traceFrame {
|
func traceElementToTraceFrame(trace traceElement) traceFrame {
|
||||||
|
@ -18,6 +18,7 @@ package jsonnet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/google/go-jsonnet/ast"
|
"github.com/google/go-jsonnet/ast"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -254,9 +255,9 @@ func makeClosure(env environment, function *ast.Function) *closure {
|
|||||||
|
|
||||||
// NativeFunction represents a function implemented in Go.
|
// NativeFunction represents a function implemented in Go.
|
||||||
type NativeFunction struct {
|
type NativeFunction struct {
|
||||||
|
Name string
|
||||||
Func func([]interface{}) (interface{}, error)
|
Func func([]interface{}) (interface{}, error)
|
||||||
Params ast.Identifiers
|
Params ast.Identifiers
|
||||||
Name string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// evalCall evaluates a call to a NativeFunction and returns the result.
|
// evalCall evaluates a call to a NativeFunction and returns the result.
|
||||||
|
19
value.go
19
value.go
@ -397,8 +397,8 @@ func (f *valueFunction) getType() *valueType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type namedParameter struct {
|
type namedParameter struct {
|
||||||
name ast.Identifier
|
|
||||||
defaultArg ast.Node
|
defaultArg ast.Node
|
||||||
|
name ast.Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
type callArguments struct {
|
type callArguments struct {
|
||||||
@ -408,8 +408,8 @@ type callArguments struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type namedCallArgument struct {
|
type namedCallArgument struct {
|
||||||
name ast.Identifier
|
|
||||||
pv *cachedThunk
|
pv *cachedThunk
|
||||||
|
name ast.Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
func args(xs ...*cachedThunk) callArguments {
|
func args(xs ...*cachedThunk) callArguments {
|
||||||
@ -525,9 +525,9 @@ type uncachedObject interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type objectLocal struct {
|
type objectLocal struct {
|
||||||
name ast.Identifier
|
|
||||||
// Locals may depend on self and super so they are unbound fields and not simply thunks
|
// Locals may depend on self and super so they are unbound fields and not simply thunks
|
||||||
node ast.Node
|
node ast.Node
|
||||||
|
name ast.Identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// simpleObject represents a flat object (no inheritance).
|
// simpleObject represents a flat object (no inheritance).
|
||||||
@ -605,8 +605,8 @@ func makeValueSimpleObject(b bindingFrame, fields simpleObjectFieldMap, asserts
|
|||||||
type simpleObjectFieldMap map[string]simpleObjectField
|
type simpleObjectFieldMap map[string]simpleObjectField
|
||||||
|
|
||||||
type simpleObjectField struct {
|
type simpleObjectField struct {
|
||||||
hide ast.ObjectFieldHide
|
|
||||||
field unboundField
|
field unboundField
|
||||||
|
hide ast.ObjectFieldHide
|
||||||
}
|
}
|
||||||
|
|
||||||
// unboundField is a field that doesn't know yet in which object it is.
|
// unboundField is a field that doesn't know yet in which object it is.
|
||||||
@ -620,11 +620,11 @@ type unboundField interface {
|
|||||||
// Example:
|
// Example:
|
||||||
// (A + B) + C
|
// (A + B) + C
|
||||||
//
|
//
|
||||||
// +
|
// +
|
||||||
// / \
|
// / \
|
||||||
// + C
|
// + C
|
||||||
// / \
|
// / \
|
||||||
// A B
|
// A B
|
||||||
//
|
//
|
||||||
// It is possible to create an arbitrary binary tree.
|
// It is possible to create an arbitrary binary tree.
|
||||||
// Note however, that because + is associative the only thing that matters
|
// Note however, that because + is associative the only thing that matters
|
||||||
@ -632,7 +632,6 @@ type unboundField interface {
|
|||||||
//
|
//
|
||||||
// This represenation allows us to implement "+" in O(1),
|
// This represenation allows us to implement "+" in O(1),
|
||||||
// but requires going through the tree and trying subsequent leafs for field access.
|
// but requires going through the tree and trying subsequent leafs for field access.
|
||||||
//
|
|
||||||
type extendedObject struct {
|
type extendedObject struct {
|
||||||
left, right uncachedObject
|
left, right uncachedObject
|
||||||
totalInheritanceSize int
|
totalInheritanceSize int
|
||||||
|
10
vm.go
10
vm.go
@ -36,7 +36,7 @@ import (
|
|||||||
|
|
||||||
// VM is the core interpreter and is the touchpoint used to parse and execute
|
// VM is the core interpreter and is the touchpoint used to parse and execute
|
||||||
// Jsonnet.
|
// Jsonnet.
|
||||||
type VM struct {
|
type VM struct { //nolint:govet
|
||||||
MaxStack int
|
MaxStack int
|
||||||
ext vmExtMap
|
ext vmExtMap
|
||||||
tla vmExtMap
|
tla vmExtMap
|
||||||
@ -59,12 +59,12 @@ const (
|
|||||||
|
|
||||||
// External variable or top level argument provided before execution
|
// External variable or top level argument provided before execution
|
||||||
type vmExt struct {
|
type vmExt struct {
|
||||||
// the kind of external variable that is specified.
|
|
||||||
kind extKind
|
|
||||||
// jsonnet code to evaluate (kind=extKindCode) or string to pass (kind=extKindVar)
|
|
||||||
value string
|
|
||||||
// the specified node for kind=extKindNode
|
// the specified node for kind=extKindNode
|
||||||
node ast.Node
|
node ast.Node
|
||||||
|
// jsonnet code to evaluate (kind=extKindCode) or string to pass (kind=extKindVar)
|
||||||
|
value string
|
||||||
|
// the kind of external variable that is specified.
|
||||||
|
kind extKind
|
||||||
}
|
}
|
||||||
|
|
||||||
type vmExtMap map[string]vmExt
|
type vmExtMap map[string]vmExt
|
||||||
|
Loading…
Reference in New Issue
Block a user