From 6e5ec5a1d788a4db8ba08fee17900db679c4a9c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Thu, 29 Aug 2024 10:13:12 +0100 Subject: [PATCH] internal/astinternal: print relative positions as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stringifying a token.Pos shows the filename, line, and column numbers, but it omits a crucial piece of information: the relative position. This can be important for encodings or formatting. For instance, some decoders produce token.NoPos with relative positions for the sake of ensuring good formatting, such as a node being printed following a newline or the correct amount of whitespace. We would print such missing positions with a relative position as token.Pos("-") even with DebugConfig.OmitEmpty, as the token.Pos value was not invalid nor empty. We would now print, for example, token.Pos("-").WithRel("newline"). Signed-off-by: Daniel Martí Change-Id: I444ae9915cb96d2797775937f45e44599b7deb43 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1200205 TryBot-Result: CUEcueckoo Unity-Result: CUE porcuepine Reviewed-by: Matthew Sackman --- internal/astinternal/debug.go | 7 ++ .../testdata/debugprint/comprehensions.txtar | 48 +++++------ .../testdata/debugprint/fields.txtar | 80 +++++++++---------- .../testdata/debugprint/file.txtar | 36 ++++----- .../testdata/debugprint/unify.txtar | 30 +++---- 5 files changed, 104 insertions(+), 97 deletions(-) diff --git a/internal/astinternal/debug.go b/internal/astinternal/debug.go index 06d0e30fce7..a32acf7aaf3 100644 --- a/internal/astinternal/debug.go +++ b/internal/astinternal/debug.go @@ -103,6 +103,13 @@ func (d *debugPrinter) value(dst []byte, v reflect.Value, impliedType reflect.Ty // Simple types which can stringify themselves. case typeTokenPos, typeTokenToken: dst = d.printf(dst, "%s(%q)", t, v) + // Show relative positions too, if there are any, as they affect formatting. + if t == typeTokenPos { + pos := v.Interface().(token.Pos) + if pos.HasRelPos() { + dst = d.printf(dst, ".WithRel(%q)", pos.RelPos()) + } + } return dst } diff --git a/internal/astinternal/testdata/debugprint/comprehensions.txtar b/internal/astinternal/testdata/debugprint/comprehensions.txtar index 7c8c23629df..5e69edd4b2c 100644 --- a/internal/astinternal/testdata/debugprint/comprehensions.txtar +++ b/internal/astinternal/testdata/debugprint/comprehensions.txtar @@ -12,66 +12,66 @@ for k, v in input if v > 2 { *ast.Comprehension{ Clauses: []ast.Clause{ *ast.IfClause{ - If: token.Pos("comprehensions.cue:1:1") + If: token.Pos("comprehensions.cue:1:1").WithRel("nospace") Condition: *ast.Ident{ - NamePos: token.Pos("comprehensions.cue:1:4") + NamePos: token.Pos("comprehensions.cue:1:4").WithRel("blank") Name: "condition" } } } Value: *ast.StructLit{ - Lbrace: token.Pos("comprehensions.cue:1:14") + Lbrace: token.Pos("comprehensions.cue:1:14").WithRel("blank") Elts: []ast.Decl{ *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("comprehensions.cue:2:2") + NamePos: token.Pos("comprehensions.cue:2:2").WithRel("newline") Name: "a" } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("comprehensions.cue:2:3") + TokenPos: token.Pos("comprehensions.cue:2:3").WithRel("nospace") Token: token.Token(":") Value: *ast.BasicLit{ - ValuePos: token.Pos("comprehensions.cue:2:5") + ValuePos: token.Pos("comprehensions.cue:2:5").WithRel("blank") Kind: token.Token("true") Value: "true" } Attrs: []*ast.Attribute{} } } - Rbrace: token.Pos("comprehensions.cue:3:1") + Rbrace: token.Pos("comprehensions.cue:3:1").WithRel("newline") } } *ast.Comprehension{ Clauses: []ast.Clause{ *ast.ForClause{ - For: token.Pos("comprehensions.cue:4:1") + For: token.Pos("comprehensions.cue:4:1").WithRel("newline") Key: *ast.Ident{ - NamePos: token.Pos("comprehensions.cue:4:5") + NamePos: token.Pos("comprehensions.cue:4:5").WithRel("blank") Name: "k" } - Colon: token.Pos("comprehensions.cue:4:6") + Colon: token.Pos("comprehensions.cue:4:6").WithRel("nospace") Value: *ast.Ident{ - NamePos: token.Pos("comprehensions.cue:4:8") + NamePos: token.Pos("comprehensions.cue:4:8").WithRel("blank") Name: "v" } - In: token.Pos("comprehensions.cue:4:10") + In: token.Pos("comprehensions.cue:4:10").WithRel("blank") Source: *ast.Ident{ - NamePos: token.Pos("comprehensions.cue:4:13") + NamePos: token.Pos("comprehensions.cue:4:13").WithRel("blank") Name: "input" } } *ast.IfClause{ - If: token.Pos("comprehensions.cue:4:19") + If: token.Pos("comprehensions.cue:4:19").WithRel("blank") Condition: *ast.BinaryExpr{ X: *ast.Ident{ - NamePos: token.Pos("comprehensions.cue:4:22") + NamePos: token.Pos("comprehensions.cue:4:22").WithRel("blank") Name: "v" } - OpPos: token.Pos("comprehensions.cue:4:24") + OpPos: token.Pos("comprehensions.cue:4:24").WithRel("blank") Op: token.Token(">") Y: *ast.BasicLit{ - ValuePos: token.Pos("comprehensions.cue:4:26") + ValuePos: token.Pos("comprehensions.cue:4:26").WithRel("blank") Kind: token.Token("INT") Value: "2" } @@ -79,29 +79,29 @@ for k, v in input if v > 2 { } } Value: *ast.StructLit{ - Lbrace: token.Pos("comprehensions.cue:4:28") + Lbrace: token.Pos("comprehensions.cue:4:28").WithRel("blank") Elts: []ast.Decl{ *ast.Field{ Label: *ast.ParenExpr{ - Lparen: token.Pos("comprehensions.cue:5:2") + Lparen: token.Pos("comprehensions.cue:5:2").WithRel("newline") X: *ast.Ident{ - NamePos: token.Pos("comprehensions.cue:5:3") + NamePos: token.Pos("comprehensions.cue:5:3").WithRel("nospace") Name: "k" } - Rparen: token.Pos("comprehensions.cue:5:4") + Rparen: token.Pos("comprehensions.cue:5:4").WithRel("nospace") } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("comprehensions.cue:5:5") + TokenPos: token.Pos("comprehensions.cue:5:5").WithRel("nospace") Token: token.Token(":") Value: *ast.Ident{ - NamePos: token.Pos("comprehensions.cue:5:7") + NamePos: token.Pos("comprehensions.cue:5:7").WithRel("blank") Name: "v" } Attrs: []*ast.Attribute{} } } - Rbrace: token.Pos("comprehensions.cue:6:1") + Rbrace: token.Pos("comprehensions.cue:6:1").WithRel("newline") } } } diff --git a/internal/astinternal/testdata/debugprint/fields.txtar b/internal/astinternal/testdata/debugprint/fields.txtar index e6b60b130ec..13320ec7438 100644 --- a/internal/astinternal/testdata/debugprint/fields.txtar +++ b/internal/astinternal/testdata/debugprint/fields.txtar @@ -16,73 +16,73 @@ embed: { Decls: []ast.Decl{ *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("fields.cue:1:1") + NamePos: token.Pos("fields.cue:1:1").WithRel("nospace") Name: "a" } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("fields.cue:1:2") + TokenPos: token.Pos("fields.cue:1:2").WithRel("nospace") Token: token.Token(":") Value: *ast.BasicLit{ - ValuePos: token.Pos("fields.cue:1:4") + ValuePos: token.Pos("fields.cue:1:4").WithRel("blank") Kind: token.Token("INT") Value: "1" } Attrs: []*ast.Attribute{ { - At: token.Pos("fields.cue:1:6") + At: token.Pos("fields.cue:1:6").WithRel("blank") Text: "@xml(,attr)" } } } *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("fields.cue:2:1") + NamePos: token.Pos("fields.cue:2:1").WithRel("newline") Name: "b" } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("fields.cue:2:2") + TokenPos: token.Pos("fields.cue:2:2").WithRel("nospace") Token: token.Token(":") Value: *ast.BasicLit{ - ValuePos: token.Pos("fields.cue:2:4") + ValuePos: token.Pos("fields.cue:2:4").WithRel("blank") Kind: token.Token("INT") Value: "2" } Attrs: []*ast.Attribute{ { - At: token.Pos("fields.cue:2:6") + At: token.Pos("fields.cue:2:6").WithRel("blank") Text: "@foo(a,b=4)" } { - At: token.Pos("fields.cue:2:18") + At: token.Pos("fields.cue:2:18").WithRel("blank") Text: "@go(Foo)" } } } *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("fields.cue:3:1") + NamePos: token.Pos("fields.cue:3:1").WithRel("newline") Name: "c" } - Optional: token.Pos("fields.cue:3:2") + Optional: token.Pos("fields.cue:3:2").WithRel("nospace") Constraint: token.Token("!") - TokenPos: token.Pos("fields.cue:3:3") + TokenPos: token.Pos("fields.cue:3:3").WithRel("nospace") Token: token.Token(":") Value: *ast.StructLit{ Lbrace: token.Pos("-") Elts: []ast.Decl{ *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("fields.cue:3:5") + NamePos: token.Pos("fields.cue:3:5").WithRel("blank") Name: "d" } - Optional: token.Pos("fields.cue:3:6") + Optional: token.Pos("fields.cue:3:6").WithRel("nospace") Constraint: token.Token("?") - TokenPos: token.Pos("fields.cue:3:7") + TokenPos: token.Pos("fields.cue:3:7").WithRel("nospace") Token: token.Token(":") Value: *ast.Ident{ - NamePos: token.Pos("fields.cue:3:9") + NamePos: token.Pos("fields.cue:3:9").WithRel("blank") Name: "string" } Attrs: []*ast.Attribute{} @@ -95,46 +95,46 @@ embed: { *ast.Field{ Label: *ast.Alias{ Ident: *ast.Ident{ - NamePos: token.Pos("fields.cue:4:1") + NamePos: token.Pos("fields.cue:4:1").WithRel("newline") Name: "X" } - Equal: token.Pos("fields.cue:4:2") + Equal: token.Pos("fields.cue:4:2").WithRel("nospace") Expr: *ast.Ident{ - NamePos: token.Pos("fields.cue:4:3") + NamePos: token.Pos("fields.cue:4:3").WithRel("nospace") Name: "e" } } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("fields.cue:4:4") + TokenPos: token.Pos("fields.cue:4:4").WithRel("nospace") Token: token.Token(":") Value: *ast.StructLit{ Lbrace: token.Pos("-") Elts: []ast.Decl{ *ast.Field{ Label: *ast.ListLit{ - Lbrack: token.Pos("fields.cue:4:6") + Lbrack: token.Pos("fields.cue:4:6").WithRel("blank") Elts: []ast.Expr{ *ast.Alias{ Ident: *ast.Ident{ - NamePos: token.Pos("fields.cue:4:7") + NamePos: token.Pos("fields.cue:4:7").WithRel("nospace") Name: "Y" } - Equal: token.Pos("fields.cue:4:8") + Equal: token.Pos("fields.cue:4:8").WithRel("nospace") Expr: *ast.Ident{ - NamePos: token.Pos("fields.cue:4:9") + NamePos: token.Pos("fields.cue:4:9").WithRel("nospace") Name: "string" } } } - Rbrack: token.Pos("fields.cue:4:15") + Rbrack: token.Pos("fields.cue:4:15").WithRel("nospace") } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("fields.cue:4:16") + TokenPos: token.Pos("fields.cue:4:16").WithRel("nospace") Token: token.Token(":") Value: *ast.Ident{ - NamePos: token.Pos("fields.cue:4:18") + NamePos: token.Pos("fields.cue:4:18").WithRel("blank") Name: "int" } Attrs: []*ast.Attribute{} @@ -146,60 +146,60 @@ embed: { } *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("fields.cue:5:1") + NamePos: token.Pos("fields.cue:5:1").WithRel("newline") Name: "#Schema" } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("fields.cue:5:8") + TokenPos: token.Pos("fields.cue:5:8").WithRel("nospace") Token: token.Token(":") Value: *ast.StructLit{ - Lbrace: token.Pos("fields.cue:5:10") + Lbrace: token.Pos("fields.cue:5:10").WithRel("blank") Elts: []ast.Decl{ *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("fields.cue:6:2") + NamePos: token.Pos("fields.cue:6:2").WithRel("newline") Name: "name" } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("fields.cue:6:6") + TokenPos: token.Pos("fields.cue:6:6").WithRel("nospace") Token: token.Token(":") Value: *ast.Ident{ - NamePos: token.Pos("fields.cue:6:8") + NamePos: token.Pos("fields.cue:6:8").WithRel("blank") Name: "string" } Attrs: []*ast.Attribute{} } *ast.Ellipsis{ - Ellipsis: token.Pos("fields.cue:7:2") + Ellipsis: token.Pos("fields.cue:7:2").WithRel("newline") Type: nil } } - Rbrace: token.Pos("fields.cue:8:1") + Rbrace: token.Pos("fields.cue:8:1").WithRel("newline") } Attrs: []*ast.Attribute{} } *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("fields.cue:9:1") + NamePos: token.Pos("fields.cue:9:1").WithRel("newline") Name: "embed" } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("fields.cue:9:6") + TokenPos: token.Pos("fields.cue:9:6").WithRel("nospace") Token: token.Token(":") Value: *ast.StructLit{ - Lbrace: token.Pos("fields.cue:9:8") + Lbrace: token.Pos("fields.cue:9:8").WithRel("blank") Elts: []ast.Decl{ *ast.EmbedDecl{ Expr: *ast.Ident{ - NamePos: token.Pos("fields.cue:10:2") + NamePos: token.Pos("fields.cue:10:2").WithRel("newline") Name: "#Schema" } } } - Rbrace: token.Pos("fields.cue:11:1") + Rbrace: token.Pos("fields.cue:11:1").WithRel("newline") } Attrs: []*ast.Attribute{} } diff --git a/internal/astinternal/testdata/debugprint/file.txtar b/internal/astinternal/testdata/debugprint/file.txtar index 080578f4439..f708c32e60a 100644 --- a/internal/astinternal/testdata/debugprint/file.txtar +++ b/internal/astinternal/testdata/debugprint/file.txtar @@ -24,9 +24,9 @@ import ( Filename: "package_only.cue" Decls: []ast.Decl{ *ast.Package{ - PackagePos: token.Pos("package_only.cue:1:1") + PackagePos: token.Pos("package_only.cue:1:1").WithRel("nospace") Name: *ast.Ident{ - NamePos: token.Pos("package_only.cue:1:9") + NamePos: token.Pos("package_only.cue:1:9").WithRel("blank") Name: "p" } } @@ -45,11 +45,11 @@ import ( Position: 0 List: []*ast.Comment{ { - Slash: token.Pos("comments_only.cue:1:1") + Slash: token.Pos("comments_only.cue:1:1").WithRel("newline") Text: "// some" } { - Slash: token.Pos("comments_only.cue:2:1") + Slash: token.Pos("comments_only.cue:2:1").WithRel("newline") Text: "// comment lines" } } @@ -61,20 +61,20 @@ import ( Filename: "imports.cue" Decls: []ast.Decl{ *ast.Package{ - PackagePos: token.Pos("imports.cue:1:1") + PackagePos: token.Pos("imports.cue:1:1").WithRel("nospace") Name: *ast.Ident{ - NamePos: token.Pos("imports.cue:1:9") + NamePos: token.Pos("imports.cue:1:9").WithRel("blank") Name: "p" } } *ast.ImportDecl{ - Import: token.Pos("imports.cue:3:1") + Import: token.Pos("imports.cue:3:1").WithRel("section") Lparen: token.Pos("-") Specs: []*ast.ImportSpec{ { Name: nil Path: *ast.BasicLit{ - ValuePos: token.Pos("imports.cue:3:8") + ValuePos: token.Pos("imports.cue:3:8").WithRel("blank") Kind: token.Token("STRING") Value: "\"foo\"" } @@ -84,13 +84,13 @@ import ( Rparen: token.Pos("-") } *ast.ImportDecl{ - Import: token.Pos("imports.cue:5:1") - Lparen: token.Pos("imports.cue:5:8") + Import: token.Pos("imports.cue:5:1").WithRel("section") + Lparen: token.Pos("imports.cue:5:8").WithRel("blank") Specs: []*ast.ImportSpec{ { Name: nil Path: *ast.BasicLit{ - ValuePos: token.Pos("imports.cue:6:2") + ValuePos: token.Pos("imports.cue:6:2").WithRel("newline") Kind: token.Token("STRING") Value: "\"bar\"" } @@ -98,25 +98,25 @@ import ( } { Name: *ast.Ident{ - NamePos: token.Pos("imports.cue:7:2") + NamePos: token.Pos("imports.cue:7:2").WithRel("newline") Name: "name" } Path: *ast.BasicLit{ - ValuePos: token.Pos("imports.cue:7:7") + ValuePos: token.Pos("imports.cue:7:7").WithRel("blank") Kind: token.Token("STRING") Value: "\"baz\"" } EndPos: token.Pos("-") } } - Rparen: token.Pos("imports.cue:8:1") + Rparen: token.Pos("imports.cue:8:1").WithRel("newline") } } Imports: []*ast.ImportSpec{ { Name: nil Path: *ast.BasicLit{ - ValuePos: token.Pos("imports.cue:3:8") + ValuePos: token.Pos("imports.cue:3:8").WithRel("blank") Kind: token.Token("STRING") Value: "\"foo\"" } @@ -125,7 +125,7 @@ import ( { Name: nil Path: *ast.BasicLit{ - ValuePos: token.Pos("imports.cue:6:2") + ValuePos: token.Pos("imports.cue:6:2").WithRel("newline") Kind: token.Token("STRING") Value: "\"bar\"" } @@ -133,11 +133,11 @@ import ( } { Name: *ast.Ident{ - NamePos: token.Pos("imports.cue:7:2") + NamePos: token.Pos("imports.cue:7:2").WithRel("newline") Name: "name" } Path: *ast.BasicLit{ - ValuePos: token.Pos("imports.cue:7:7") + ValuePos: token.Pos("imports.cue:7:7").WithRel("blank") Kind: token.Token("STRING") Value: "\"baz\"" } diff --git a/internal/astinternal/testdata/debugprint/unify.txtar b/internal/astinternal/testdata/debugprint/unify.txtar index b8bb50ac35b..64ab358ecda 100644 --- a/internal/astinternal/testdata/debugprint/unify.txtar +++ b/internal/astinternal/testdata/debugprint/unify.txtar @@ -7,30 +7,30 @@ disjunctoin: b | c | *d Decls: []ast.Decl{ *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("unify.txtar:1:1") + NamePos: token.Pos("unify.txtar:1:1").WithRel("nospace") Name: "unification" } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("unify.txtar:1:12") + TokenPos: token.Pos("unify.txtar:1:12").WithRel("nospace") Token: token.Token(":") Value: *ast.BinaryExpr{ X: *ast.BinaryExpr{ X: *ast.Ident{ - NamePos: token.Pos("unify.txtar:1:14") + NamePos: token.Pos("unify.txtar:1:14").WithRel("blank") Name: "b" } - OpPos: token.Pos("unify.txtar:1:16") + OpPos: token.Pos("unify.txtar:1:16").WithRel("blank") Op: token.Token("&") Y: *ast.Ident{ - NamePos: token.Pos("unify.txtar:1:18") + NamePos: token.Pos("unify.txtar:1:18").WithRel("blank") Name: "c" } } - OpPos: token.Pos("unify.txtar:1:20") + OpPos: token.Pos("unify.txtar:1:20").WithRel("blank") Op: token.Token("&") Y: *ast.Ident{ - NamePos: token.Pos("unify.txtar:1:22") + NamePos: token.Pos("unify.txtar:1:22").WithRel("blank") Name: "d" } } @@ -38,33 +38,33 @@ disjunctoin: b | c | *d } *ast.Field{ Label: *ast.Ident{ - NamePos: token.Pos("unify.txtar:2:1") + NamePos: token.Pos("unify.txtar:2:1").WithRel("newline") Name: "disjunctoin" } Optional: token.Pos("-") Constraint: token.Token("ILLEGAL") - TokenPos: token.Pos("unify.txtar:2:12") + TokenPos: token.Pos("unify.txtar:2:12").WithRel("nospace") Token: token.Token(":") Value: *ast.BinaryExpr{ X: *ast.BinaryExpr{ X: *ast.Ident{ - NamePos: token.Pos("unify.txtar:2:14") + NamePos: token.Pos("unify.txtar:2:14").WithRel("blank") Name: "b" } - OpPos: token.Pos("unify.txtar:2:16") + OpPos: token.Pos("unify.txtar:2:16").WithRel("blank") Op: token.Token("|") Y: *ast.Ident{ - NamePos: token.Pos("unify.txtar:2:18") + NamePos: token.Pos("unify.txtar:2:18").WithRel("blank") Name: "c" } } - OpPos: token.Pos("unify.txtar:2:20") + OpPos: token.Pos("unify.txtar:2:20").WithRel("blank") Op: token.Token("|") Y: *ast.UnaryExpr{ - OpPos: token.Pos("unify.txtar:2:22") + OpPos: token.Pos("unify.txtar:2:22").WithRel("blank") Op: token.Token("*") X: *ast.Ident{ - NamePos: token.Pos("unify.txtar:2:23") + NamePos: token.Pos("unify.txtar:2:23").WithRel("nospace") Name: "d" } }