1// Copyright 2021 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package noder
6
7import (
8	"fmt"
9
10	"cmd/compile/internal/syntax"
11)
12
13// typeExprEndPos returns the position that noder would leave base.Pos
14// after parsing the given type expression.
15//
16// Deprecated: This function exists to emulate position semantics from
17// Go 1.17, necessary for compatibility with the backend DWARF
18// generation logic that assigns variables to their appropriate scope.
19func typeExprEndPos(expr0 syntax.Expr) syntax.Pos {
20	for {
21		switch expr := expr0.(type) {
22		case *syntax.Name:
23			return expr.Pos()
24		case *syntax.SelectorExpr:
25			return expr.X.Pos()
26
27		case *syntax.ParenExpr:
28			expr0 = expr.X
29
30		case *syntax.Operation:
31			assert(expr.Op == syntax.Mul)
32			assert(expr.Y == nil)
33			expr0 = expr.X
34
35		case *syntax.ArrayType:
36			expr0 = expr.Elem
37		case *syntax.ChanType:
38			expr0 = expr.Elem
39		case *syntax.DotsType:
40			expr0 = expr.Elem
41		case *syntax.MapType:
42			expr0 = expr.Value
43		case *syntax.SliceType:
44			expr0 = expr.Elem
45
46		case *syntax.StructType:
47			return expr.Pos()
48
49		case *syntax.InterfaceType:
50			expr0 = lastFieldType(expr.MethodList)
51			if expr0 == nil {
52				return expr.Pos()
53			}
54
55		case *syntax.FuncType:
56			expr0 = lastFieldType(expr.ResultList)
57			if expr0 == nil {
58				expr0 = lastFieldType(expr.ParamList)
59				if expr0 == nil {
60					return expr.Pos()
61				}
62			}
63
64		case *syntax.IndexExpr: // explicit type instantiation
65			targs := syntax.UnpackListExpr(expr.Index)
66			expr0 = targs[len(targs)-1]
67
68		default:
69			panic(fmt.Sprintf("%s: unexpected type expression %v", expr.Pos(), syntax.String(expr)))
70		}
71	}
72}
73
74func lastFieldType(fields []*syntax.Field) syntax.Expr {
75	if len(fields) == 0 {
76		return nil
77	}
78	return fields[len(fields)-1].Type
79}
80