1
0
mirror of https://github.com/golang/go synced 2024-09-24 09:20:15 -06:00

cmd/compile/internal/types2: review of pos.go and move into syntax package

This moves the two helper functions startPos and endPos into
the syntax package where they belong. Export the functions and
adjust dependent code.

Change-Id: I8170faeadd7cfa8f53009f81fcffd50ec0fc6a98
Reviewed-on: https://go-review.googlesource.com/c/go/+/305578
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2021-03-29 15:15:56 -07:00
parent d57189e92b
commit 93466cc1b6
9 changed files with 128 additions and 132 deletions

View File

@ -1,16 +1,13 @@
// UNREVIEWED
// Copyright 2012 The Go Authors. All rights reserved.
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file implements helper functions for scope position computations.
package types2
package syntax
import "cmd/compile/internal/syntax"
// startPos returns the start position of n.
func startPos(n syntax.Node) syntax.Pos {
// StartPos returns the start position of n.
func StartPos(n Node) Pos {
// Cases for nodes which don't need a correction are commented out.
for m := n; ; {
switch n := m.(type) {
@ -18,95 +15,95 @@ func startPos(n syntax.Node) syntax.Pos {
panic("internal error: nil")
// packages
case *syntax.File:
case *File:
// file block starts at the beginning of the file
return syntax.MakePos(n.Pos().Base(), 1, 1)
return MakePos(n.Pos().Base(), 1, 1)
// declarations
// case *syntax.ImportDecl:
// case *syntax.ConstDecl:
// case *syntax.TypeDecl:
// case *syntax.VarDecl:
// case *syntax.FuncDecl:
// case *ImportDecl:
// case *ConstDecl:
// case *TypeDecl:
// case *VarDecl:
// case *FuncDecl:
// expressions
// case *syntax.BadExpr:
// case *syntax.Name:
// case *syntax.BasicLit:
case *syntax.CompositeLit:
// case *BadExpr:
// case *Name:
// case *BasicLit:
case *CompositeLit:
if n.Type != nil {
m = n.Type
continue
}
return n.Pos()
// case *syntax.KeyValueExpr:
// case *syntax.FuncLit:
// case *syntax.ParenExpr:
case *syntax.SelectorExpr:
// case *KeyValueExpr:
// case *FuncLit:
// case *ParenExpr:
case *SelectorExpr:
m = n.X
case *syntax.IndexExpr:
case *IndexExpr:
m = n.X
// case *syntax.SliceExpr:
case *syntax.AssertExpr:
// case *SliceExpr:
case *AssertExpr:
m = n.X
case *syntax.TypeSwitchGuard:
case *TypeSwitchGuard:
if n.Lhs != nil {
m = n.Lhs
continue
}
m = n.X
case *syntax.Operation:
case *Operation:
if n.Y != nil {
m = n.X
continue
}
return n.Pos()
case *syntax.CallExpr:
case *CallExpr:
m = n.Fun
case *syntax.ListExpr:
case *ListExpr:
if len(n.ElemList) > 0 {
m = n.ElemList[0]
continue
}
return n.Pos()
// types
// case *syntax.ArrayType:
// case *syntax.SliceType:
// case *syntax.DotsType:
// case *syntax.StructType:
// case *syntax.Field:
// case *syntax.InterfaceType:
// case *syntax.FuncType:
// case *syntax.MapType:
// case *syntax.ChanType:
// case *ArrayType:
// case *SliceType:
// case *DotsType:
// case *StructType:
// case *Field:
// case *InterfaceType:
// case *FuncType:
// case *MapType:
// case *ChanType:
// statements
// case *syntax.EmptyStmt:
// case *syntax.LabeledStmt:
// case *syntax.BlockStmt:
// case *syntax.ExprStmt:
case *syntax.SendStmt:
// case *EmptyStmt:
// case *LabeledStmt:
// case *BlockStmt:
// case *ExprStmt:
case *SendStmt:
m = n.Chan
// case *syntax.DeclStmt:
case *syntax.AssignStmt:
// case *DeclStmt:
case *AssignStmt:
m = n.Lhs
// case *syntax.BranchStmt:
// case *syntax.CallStmt:
// case *syntax.ReturnStmt:
// case *syntax.IfStmt:
// case *syntax.ForStmt:
// case *syntax.SwitchStmt:
// case *syntax.SelectStmt:
// case *BranchStmt:
// case *CallStmt:
// case *ReturnStmt:
// case *IfStmt:
// case *ForStmt:
// case *SwitchStmt:
// case *SelectStmt:
// helper nodes
case *syntax.RangeClause:
case *RangeClause:
if n.Lhs != nil {
m = n.Lhs
continue
}
m = n.X
// case *syntax.CaseClause:
// case *syntax.CommClause:
// case *CaseClause:
// case *CommClause:
default:
return n.Pos()
@ -114,30 +111,29 @@ func startPos(n syntax.Node) syntax.Pos {
}
}
// endPos returns the approximate end position of n in the source.
// For some nodes (*syntax.Name, *syntax.BasicLit) it returns
// the position immediately following the node; for others
// (*syntax.BlockStmt, *syntax.SwitchStmt, etc.) it returns
// the position of the closing '}'; and for some (*syntax.ParenExpr)
// EndPos returns the approximate end position of n in the source.
// For some nodes (*Name, *BasicLit) it returns the position immediately
// following the node; for others (*BlockStmt, *SwitchStmt, etc.) it
// returns the position of the closing '}'; and for some (*ParenExpr)
// the returned position is the end position of the last enclosed
// expression.
// Thus, endPos should not be used for exact demarcation of the
// Thus, EndPos should not be used for exact demarcation of the
// end of a node in the source; it is mostly useful to determine
// scope ranges where there is some leeway.
func endPos(n syntax.Node) syntax.Pos {
func EndPos(n Node) Pos {
for m := n; ; {
switch n := m.(type) {
case nil:
panic("internal error: nil")
// packages
case *syntax.File:
case *File:
return n.EOF
// declarations
case *syntax.ImportDecl:
case *ImportDecl:
m = n.Path
case *syntax.ConstDecl:
case *ConstDecl:
if n.Values != nil {
m = n.Values
continue
@ -151,9 +147,9 @@ func endPos(n syntax.Node) syntax.Pos {
continue
}
return n.Pos()
case *syntax.TypeDecl:
case *TypeDecl:
m = n.Type
case *syntax.VarDecl:
case *VarDecl:
if n.Values != nil {
m = n.Values
continue
@ -167,7 +163,7 @@ func endPos(n syntax.Node) syntax.Pos {
continue
}
return n.Pos()
case *syntax.FuncDecl:
case *FuncDecl:
if n.Body != nil {
m = n.Body
continue
@ -175,27 +171,27 @@ func endPos(n syntax.Node) syntax.Pos {
m = n.Type
// expressions
case *syntax.BadExpr:
case *BadExpr:
return n.Pos()
case *syntax.Name:
case *Name:
p := n.Pos()
return syntax.MakePos(p.Base(), p.Line(), p.Col()+uint(len(n.Value)))
case *syntax.BasicLit:
return MakePos(p.Base(), p.Line(), p.Col()+uint(len(n.Value)))
case *BasicLit:
p := n.Pos()
return syntax.MakePos(p.Base(), p.Line(), p.Col()+uint(len(n.Value)))
case *syntax.CompositeLit:
return MakePos(p.Base(), p.Line(), p.Col()+uint(len(n.Value)))
case *CompositeLit:
return n.Rbrace
case *syntax.KeyValueExpr:
case *KeyValueExpr:
m = n.Value
case *syntax.FuncLit:
case *FuncLit:
m = n.Body
case *syntax.ParenExpr:
case *ParenExpr:
m = n.X
case *syntax.SelectorExpr:
case *SelectorExpr:
m = n.Sel
case *syntax.IndexExpr:
case *IndexExpr:
m = n.Index
case *syntax.SliceExpr:
case *SliceExpr:
for i := len(n.Index) - 1; i >= 0; i-- {
if x := n.Index[i]; x != nil {
m = x
@ -203,23 +199,23 @@ func endPos(n syntax.Node) syntax.Pos {
}
}
m = n.X
case *syntax.AssertExpr:
case *AssertExpr:
m = n.Type
case *syntax.TypeSwitchGuard:
case *TypeSwitchGuard:
m = n.X
case *syntax.Operation:
case *Operation:
if n.Y != nil {
m = n.Y
continue
}
m = n.X
case *syntax.CallExpr:
case *CallExpr:
if l := lastExpr(n.ArgList); l != nil {
m = l
continue
}
m = n.Fun
case *syntax.ListExpr:
case *ListExpr:
if l := lastExpr(n.ElemList); l != nil {
m = l
continue
@ -227,32 +223,32 @@ func endPos(n syntax.Node) syntax.Pos {
return n.Pos()
// types
case *syntax.ArrayType:
case *ArrayType:
m = n.Elem
case *syntax.SliceType:
case *SliceType:
m = n.Elem
case *syntax.DotsType:
case *DotsType:
m = n.Elem
case *syntax.StructType:
case *StructType:
if l := lastField(n.FieldList); l != nil {
m = l
continue
}
return n.Pos()
// TODO(gri) need to take TagList into account
case *syntax.Field:
case *Field:
if n.Type != nil {
m = n.Type
continue
}
m = n.Name
case *syntax.InterfaceType:
case *InterfaceType:
if l := lastField(n.MethodList); l != nil {
m = l
continue
}
return n.Pos()
case *syntax.FuncType:
case *FuncType:
if l := lastField(n.ResultList); l != nil {
m = l
continue
@ -262,71 +258,71 @@ func endPos(n syntax.Node) syntax.Pos {
continue
}
return n.Pos()
case *syntax.MapType:
case *MapType:
m = n.Value
case *syntax.ChanType:
case *ChanType:
m = n.Elem
// statements
case *syntax.EmptyStmt:
case *EmptyStmt:
return n.Pos()
case *syntax.LabeledStmt:
case *LabeledStmt:
m = n.Stmt
case *syntax.BlockStmt:
case *BlockStmt:
return n.Rbrace
case *syntax.ExprStmt:
case *ExprStmt:
m = n.X
case *syntax.SendStmt:
case *SendStmt:
m = n.Value
case *syntax.DeclStmt:
case *DeclStmt:
if l := lastDecl(n.DeclList); l != nil {
m = l
continue
}
return n.Pos()
case *syntax.AssignStmt:
case *AssignStmt:
m = n.Rhs
if m == nil {
p := endPos(n.Lhs)
return syntax.MakePos(p.Base(), p.Line(), p.Col()+2)
p := EndPos(n.Lhs)
return MakePos(p.Base(), p.Line(), p.Col()+2)
}
case *syntax.BranchStmt:
case *BranchStmt:
if n.Label != nil {
m = n.Label
continue
}
return n.Pos()
case *syntax.CallStmt:
case *CallStmt:
m = n.Call
case *syntax.ReturnStmt:
case *ReturnStmt:
if n.Results != nil {
m = n.Results
continue
}
return n.Pos()
case *syntax.IfStmt:
case *IfStmt:
if n.Else != nil {
m = n.Else
continue
}
m = n.Then
case *syntax.ForStmt:
case *ForStmt:
m = n.Body
case *syntax.SwitchStmt:
case *SwitchStmt:
return n.Rbrace
case *syntax.SelectStmt:
case *SelectStmt:
return n.Rbrace
// helper nodes
case *syntax.RangeClause:
case *RangeClause:
m = n.X
case *syntax.CaseClause:
case *CaseClause:
if l := lastStmt(n.Body); l != nil {
m = l
continue
}
return n.Colon
case *syntax.CommClause:
case *CommClause:
if l := lastStmt(n.Body); l != nil {
m = l
continue
@ -339,28 +335,28 @@ func endPos(n syntax.Node) syntax.Pos {
}
}
func lastDecl(list []syntax.Decl) syntax.Decl {
func lastDecl(list []Decl) Decl {
if l := len(list); l > 0 {
return list[l-1]
}
return nil
}
func lastExpr(list []syntax.Expr) syntax.Expr {
func lastExpr(list []Expr) Expr {
if l := len(list); l > 0 {
return list[l-1]
}
return nil
}
func lastStmt(list []syntax.Stmt) syntax.Stmt {
func lastStmt(list []Stmt) Stmt {
if l := len(list); l > 0 {
return list[l-1]
}
return nil
}
func lastField(list []*syntax.Field) *syntax.Field {
func lastField(list []*Field) *Field {
if l := len(list); l > 0 {
return list[l-1]
}

View File

@ -377,7 +377,7 @@ func (check *Checker) shortVarDecl(pos syntax.Pos, lhs, rhs []syntax.Expr) {
// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
// for short variable declarations) and ends at the end of the innermost
// containing block."
scopePos := endPos(rhs[len(rhs)-1])
scopePos := syntax.EndPos(rhs[len(rhs)-1])
for _, obj := range newVars {
check.declare(scope, nil, obj, scopePos) // recordObject already called
}

View File

@ -901,7 +901,7 @@ func (check *Checker) declStmt(list []syntax.Decl) {
// inside a function begins at the end of the ConstSpec or VarSpec
// (ShortVarDecl for short variable declarations) and ends at the
// end of the innermost containing block."
scopePos := endPos(s)
scopePos := syntax.EndPos(s)
for i, name := range s.NameList {
check.declare(check.scope, name, lhs[i], scopePos)
}
@ -958,7 +958,7 @@ func (check *Checker) declStmt(list []syntax.Decl) {
// declare all variables
// (only at this point are the variable scopes (parents) set)
scopePos := endPos(s) // see constant declarations
scopePos := syntax.EndPos(s) // see constant declarations
for i, name := range s.NameList {
// see constant declarations
check.declare(check.scope, name, lhs0[i], scopePos)

View File

@ -207,10 +207,10 @@ func posFor(at poser) syntax.Pos {
switch x := at.(type) {
case *operand:
if x.expr != nil {
return startPos(x.expr)
return syntax.StartPos(x.expr)
}
case syntax.Node:
return startPos(x)
return syntax.StartPos(x)
}
return at.Pos()
}

View File

@ -96,7 +96,7 @@ func (check *Checker) overflow(x *operand) {
// If the corresponding expression is an operation, use the
// operator position rather than the start of the expression
// as error position.
pos := startPos(x.expr)
pos := syntax.StartPos(x.expr)
what := "" // operator description, if any
if op, _ := x.expr.(*syntax.Operation); op != nil {
pos = op.Pos()

View File

@ -11,7 +11,7 @@ import (
// labels checks correct label use in body.
func (check *Checker) labels(body *syntax.BlockStmt) {
// set of all labels in this body
all := NewScope(nil, body.Pos(), endPos(body), "label")
all := NewScope(nil, body.Pos(), syntax.EndPos(body), "label")
fwdJumps := check.blockBranches(all, nil, nil, body.List)

View File

@ -216,7 +216,7 @@ func (check *Checker) collectObjects() {
// but there is no corresponding package object.
check.recordDef(file.PkgName, nil)
fileScope := NewScope(check.pkg.scope, startPos(file), endPos(file), check.filename(fileNo))
fileScope := NewScope(check.pkg.scope, syntax.StartPos(file), syntax.EndPos(file), check.filename(fileNo))
fileScopes = append(fileScopes, fileScope)
check.recordScope(file, fileScope)

View File

@ -16,13 +16,13 @@ func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body
if check.conf.Trace {
check.trace(body.Pos(), "--- %s: %s", name, sig)
defer func() {
check.trace(endPos(body), "--- <end>")
check.trace(syntax.EndPos(body), "--- <end>")
}()
}
// set function scope extent
sig.scope.pos = body.Pos()
sig.scope.end = endPos(body)
sig.scope.end = syntax.EndPos(body)
// save/restore current context and setup function context
// (and use 0 indentation at function start)
@ -154,7 +154,7 @@ func (check *Checker) multipleSelectDefaults(list []*syntax.CommClause) {
}
func (check *Checker) openScope(node syntax.Node, comment string) {
check.openScopeUntil(node, endPos(node), comment)
check.openScopeUntil(node, syntax.EndPos(node), comment)
}
func (check *Checker) openScopeUntil(node syntax.Node, end syntax.Pos, comment string) {
@ -723,7 +723,7 @@ func (check *Checker) typeSwitchStmt(inner stmtContext, s *syntax.SwitchStmt, gu
// "at the end of the TypeSwitchCase" in #16794 instead?
scopePos := clause.Pos() // for default clause (len(List) == 0)
if n := len(cases); n > 0 {
scopePos = endPos(cases[n-1])
scopePos = syntax.EndPos(cases[n-1])
}
check.declare(check.scope, nil, obj, scopePos)
check.recordImplicit(clause, obj)
@ -840,7 +840,7 @@ func (check *Checker) rangeStmt(inner stmtContext, s *syntax.ForStmt, rclause *s
// declare variables
if len(vars) > 0 {
scopePos := endPos(rclause.X) // TODO(gri) should this just be s.Body.Pos (spec clarification)?
scopePos := syntax.EndPos(rclause.X) // TODO(gri) should this just be s.Body.Pos (spec clarification)?
for _, obj := range vars {
// spec: "The scope of a constant or variable identifier declared inside
// a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl

View File

@ -131,7 +131,7 @@ func (check *Checker) typ(e syntax.Expr) Type {
// (see ordinaryType).
func (check *Checker) varType(e syntax.Expr) Type {
typ := check.definedType(e, nil)
check.ordinaryType(startPos(e), typ)
check.ordinaryType(syntax.StartPos(e), typ)
return typ
}
@ -1154,7 +1154,7 @@ func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
// spec: "An embedded type must be specified as a type name T or as a
// pointer to a non-interface type name *T, and T itself may not be a
// pointer type."
pos := startPos(f.Type)
pos := syntax.StartPos(f.Type)
name := embeddedFieldIdent(f.Type)
if name == nil {
check.errorf(pos, "invalid embedded field type %s", f.Type)