diff --git a/idl/position.go b/ast/position.go similarity index 79% rename from idl/position.go rename to ast/position.go index 6d246680..40b90f64 100644 --- a/idl/position.go +++ b/ast/position.go @@ -18,9 +18,18 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -package idl +package ast // Position represents a position in the parsed document. type Position struct { Line int } + +// Pos attempts to return the position of a Node in the parsed document. +// For most use cases, prefer to use idl.Info to access positional information. +func Pos(n Node) (Position, bool) { + if nl, ok := n.(nodeWithLine); ok { + return Position{Line: nl.lineNumber()}, true + } + return Position{}, false +} diff --git a/idl/config_test.go b/idl/config_test.go index 2b3e1720..9b0ddf43 100644 --- a/idl/config_test.go +++ b/idl/config_test.go @@ -39,8 +39,8 @@ func TestParse(t *testing.T) { func TestInfoPos(t *testing.T) { c := &Config{Info: &Info{}} prog, err := c.Parse([]byte(`const string a = 'a';`)) - if assert.NoError(t, err, "%v", err) { - assert.Equal(t, Position{Line: 0}, c.Info.Pos(prog)) - assert.Equal(t, Position{Line: 1}, c.Info.Pos(prog.Definitions[0])) + if assert.NoError(t, err) { + assert.Equal(t, ast.Position{Line: 0}, c.Info.Pos(prog)) + assert.Equal(t, ast.Position{Line: 1}, c.Info.Pos(prog.Definitions[0])) } } diff --git a/idl/error.go b/idl/error.go index 7c1a083e..59ec1823 100644 --- a/idl/error.go +++ b/idl/error.go @@ -24,6 +24,7 @@ import ( "bytes" "fmt" + "go.uber.org/thriftrw/ast" "go.uber.org/thriftrw/idl/internal" ) @@ -33,7 +34,7 @@ type ParseError struct{ Errors []Error } // Error holds an error and the position that caused it. type Error struct { - Pos Position + Pos ast.Position Err error } @@ -44,7 +45,7 @@ func newParseError(errors []internal.ParseError) error { errs := make([]Error, len(errors)) for i, err := range errors { errs[i] = Error{ - Pos: Position{Line: err.Pos.Line}, + Pos: ast.Position{Line: err.Pos.Line}, Err: err.Err, } } diff --git a/idl/info.go b/idl/info.go index 97cc7917..57fe9799 100644 --- a/idl/info.go +++ b/idl/info.go @@ -30,11 +30,11 @@ type Info struct { nodePositions internal.NodePositions } -// Pos returns a node's position in the parsed document. -func (i *Info) Pos(n ast.Node) Position { - if line := ast.LineNumber(n); line != 0 { - return Position{Line: line} +// Pos returns a Node's position in the parsed document. +func (i *Info) Pos(n ast.Node) ast.Position { + if pos, ok := ast.Pos(n); ok { + return pos } pos := i.nodePositions[n] - return Position{Line: pos.Line} + return ast.Position{Line: pos.Line} } diff --git a/idl/info_test.go b/idl/info_test.go index f915de59..164256ed 100644 --- a/idl/info_test.go +++ b/idl/info_test.go @@ -32,20 +32,20 @@ func TestPos(t *testing.T) { tests := []struct { node ast.Node pos *internal.Position - want Position + want ast.Position }{ { node: &ast.Struct{Line: 10}, - want: Position{Line: 10}, + want: ast.Position{Line: 10}, }, { node: ast.ConstantString("s"), - want: Position{Line: 0}, + want: ast.Position{Line: 0}, }, { node: ast.ConstantString("s"), pos: &internal.Position{Line: 1}, - want: Position{Line: 1}, + want: ast.Position{Line: 1}, }, }