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