github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/go/ast/scope.go (about)

     1  // Copyright 2009 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  
     5  // This file implements scopes and the objects they contain.
     6  
     7  package ast
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"go/token"
    13  )
    14  
    15  // A Scope maintains the set of named language entities declared
    16  // in the scope and a link to the immediately surrounding (outer)
    17  // scope.
    18  //
    19  type Scope struct {
    20  	Outer   *Scope
    21  	Objects map[string]*Object
    22  }
    23  
    24  // NewScope creates a new scope nested in the outer scope.
    25  func NewScope(outer *Scope) *Scope {
    26  	const n = 4 // initial scope capacity
    27  	return &Scope{outer, make(map[string]*Object, n)}
    28  }
    29  
    30  // Lookup returns the object with the given name if it is
    31  // found in scope s, otherwise it returns nil. Outer scopes
    32  // are ignored.
    33  //
    34  func (s *Scope) Lookup(name string) *Object {
    35  	return s.Objects[name]
    36  }
    37  
    38  // Insert attempts to insert a named object obj into the scope s.
    39  // If the scope already contains an object alt with the same name,
    40  // Insert leaves the scope unchanged and returns alt. Otherwise
    41  // it inserts obj and returns nil.
    42  //
    43  func (s *Scope) Insert(obj *Object) (alt *Object) {
    44  	if alt = s.Objects[obj.Name]; alt == nil {
    45  		s.Objects[obj.Name] = obj
    46  	}
    47  	return
    48  }
    49  
    50  // Debugging support
    51  func (s *Scope) String() string {
    52  	var buf bytes.Buffer
    53  	fmt.Fprintf(&buf, "scope %p {", s)
    54  	if s != nil && len(s.Objects) > 0 {
    55  		fmt.Fprintln(&buf)
    56  		for _, obj := range s.Objects {
    57  			fmt.Fprintf(&buf, "\t%s %s\n", obj.Kind, obj.Name)
    58  		}
    59  	}
    60  	fmt.Fprintf(&buf, "}\n")
    61  	return buf.String()
    62  }
    63  
    64  // ----------------------------------------------------------------------------
    65  // Objects
    66  
    67  // An Object describes a named language entity such as a package,
    68  // constant, type, variable, function (incl. methods), or label.
    69  //
    70  // The Data fields contains object-specific data:
    71  //
    72  //	Kind    Data type         Data value
    73  //	Pkg     *Scope            package scope
    74  //	Con     int               iota for the respective declaration
    75  //
    76  // 对象: 包,常量,类型,变量,函数,标签
    77  type Object struct {
    78  	Kind ObjKind                    // 类型
    79  	Name string      // declared name // 名称
    80  	Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil
    81  	Data interface{} // object-specific data; or nil
    82  	Type interface{} // placeholder for type information; may be nil
    83  }
    84  
    85  // NewObj creates a new object of a given kind and name.
    86  func NewObj(kind ObjKind, name string) *Object {
    87  	return &Object{Kind: kind, Name: name}
    88  }
    89  
    90  // Pos computes the source position of the declaration of an object name.
    91  // The result may be an invalid position if it cannot be computed
    92  // (obj.Decl may be nil or not correct).
    93  func (obj *Object) Pos() token.Pos { // 计算位置
    94  	name := obj.Name
    95  	switch d := obj.Decl.(type) {
    96  	case *Field:
    97  		for _, n := range d.Names {
    98  			if n.Name == name {
    99  				return n.Pos()
   100  			}
   101  		}
   102  	case *ImportSpec:
   103  		if d.Name != nil && d.Name.Name == name {
   104  			return d.Name.Pos()
   105  		}
   106  		return d.Path.Pos()
   107  	case *ValueSpec:
   108  		for _, n := range d.Names {
   109  			if n.Name == name {
   110  				return n.Pos()
   111  			}
   112  		}
   113  	case *TypeSpec:
   114  		if d.Name.Name == name {
   115  			return d.Name.Pos()
   116  		}
   117  	case *FuncDecl:
   118  		if d.Name.Name == name {
   119  			return d.Name.Pos()
   120  		}
   121  	case *LabeledStmt:
   122  		if d.Label.Name == name {
   123  			return d.Label.Pos()
   124  		}
   125  	case *AssignStmt:
   126  		for _, x := range d.Lhs {
   127  			if ident, isIdent := x.(*Ident); isIdent && ident.Name == name {
   128  				return ident.Pos()
   129  			}
   130  		}
   131  	case *Scope:
   132  		// predeclared object - nothing to do for now
   133  	}
   134  	return token.NoPos
   135  }
   136  
   137  // ObjKind describes what an object represents.
   138  // 类型
   139  type ObjKind int
   140  
   141  // The list of possible Object kinds.
   142  const (
   143  	Bad ObjKind = iota // for error handling
   144  	Pkg                // package
   145  	Con                // constant
   146  	Typ                // type
   147  	Var                // variable
   148  	Fun                // function or method
   149  	Lbl                // label
   150  )
   151  
   152  // 类型名称
   153  var objKindStrings = [...]string{
   154  	Bad: "bad",
   155  	Pkg: "package",
   156  	Con: "const",
   157  	Typ: "type",
   158  	Var: "var",
   159  	Fun: "func",
   160  	Lbl: "label",
   161  }
   162  
   163  func (kind ObjKind) String() string { return objKindStrings[kind] }