kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/indexer/emit.go (about)

     1  /*
     2   * Copyright 2016 The Kythe Authors. All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *   http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package indexer
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"go/ast"
    23  	"go/doc/comment"
    24  	"go/token"
    25  	"go/types"
    26  	"net/url"
    27  	"path"
    28  	"regexp"
    29  	"strconv"
    30  	"strings"
    31  
    32  	"kythe.io/kythe/go/extractors/govname"
    33  	"kythe.io/kythe/go/util/kytheuri"
    34  	"kythe.io/kythe/go/util/log"
    35  	"kythe.io/kythe/go/util/metadata"
    36  	"kythe.io/kythe/go/util/schema/edges"
    37  	"kythe.io/kythe/go/util/schema/facts"
    38  	"kythe.io/kythe/go/util/schema/nodes"
    39  
    40  	"github.com/golang/protobuf/proto"
    41  	"golang.org/x/tools/go/types/typeutil"
    42  
    43  	cpb "kythe.io/kythe/proto/common_go_proto"
    44  	gopb "kythe.io/kythe/proto/go_go_proto"
    45  	spb "kythe.io/kythe/proto/storage_go_proto"
    46  )
    47  
    48  // EmitOptions control the behaviour of the Emit function. A nil options
    49  // pointer provides default values.
    50  type EmitOptions struct {
    51  	// If true, emit nodes for standard library packages when they are first
    52  	// encountered. This is helpful if you want to index a package in isolation
    53  	// where data for the standard library are not available.
    54  	EmitStandardLibs bool
    55  
    56  	// If true, emit code facts containing MarkedSource messages.
    57  	EmitMarkedSource bool
    58  
    59  	// If true, emit linkages specified by metadata rules.
    60  	EmitLinkages bool
    61  
    62  	// If true, emit childof edges for an anchor's semantic scope.
    63  	EmitAnchorScopes bool
    64  
    65  	// If true, use the enclosing file for top-level callsite scopes.
    66  	UseFileAsTopLevelScope bool
    67  
    68  	// If set, use this as the base URL for links to godoc.  The import path is
    69  	// appended to the path of this URL to obtain the target URL to link to.
    70  	DocBase *url.URL
    71  
    72  	// If true, the doc/uri fact is only emitted for go std library packages.
    73  	OnlyEmitDocURIsForStandardLibs bool
    74  
    75  	// If enabled, all VNames emitted by the indexer are assigned the
    76  	// compilation unit's corpus.
    77  	UseCompilationCorpusForAll bool
    78  
    79  	// If set, all stdlib nodes are assigned this corpus. This takes precedence
    80  	// over UseCompilationCorpusForAll for stdlib nodes.
    81  	OverrideStdlibCorpus string
    82  
    83  	// EmitRefCallOverIdentifier determines whether ref/call anchors are emitted
    84  	// over function identifiers (or the legacy behavior of over the entire
    85  	// callsite).
    86  	EmitRefCallOverIdentifier bool
    87  
    88  	// FlagConstructors is a set of known flag constructor functions.
    89  	FlagConstructors *gopb.FlagConstructors
    90  
    91  	// Verbose determines whether verbose logging is enabled.
    92  	Verbose bool
    93  }
    94  
    95  func (e *EmitOptions) emitMarkedSource() bool {
    96  	if e == nil {
    97  		return false
    98  	}
    99  	return e.EmitMarkedSource
   100  }
   101  
   102  func (e *EmitOptions) emitAnchorScopes() bool {
   103  	if e == nil {
   104  		return false
   105  	}
   106  	return e.EmitAnchorScopes
   107  }
   108  
   109  func (e *EmitOptions) emitRefCallOverIdentifier() bool {
   110  	if e == nil {
   111  		return false
   112  	}
   113  	return e.EmitRefCallOverIdentifier
   114  }
   115  
   116  func (e *EmitOptions) emitFlagNodes() bool {
   117  	if e == nil {
   118  		return false
   119  	}
   120  	return e.FlagConstructors != nil
   121  }
   122  
   123  func (e *EmitOptions) useFileAsTopLevelScope() bool {
   124  	if e == nil {
   125  		return false
   126  	}
   127  	return e.UseFileAsTopLevelScope
   128  }
   129  
   130  // shouldEmit reports whether the indexer should emit a node for the given
   131  // vname.  Presently this is true if vname denotes a standard library and the
   132  // corresponding option is enabled.
   133  func (e *EmitOptions) shouldEmit(vname *spb.VName) bool {
   134  	return e != nil && e.EmitStandardLibs && govname.IsStandardLibrary(vname)
   135  }
   136  
   137  func (e *EmitOptions) docBase() string {
   138  	if e == nil || e.DocBase == nil {
   139  		return ""
   140  	}
   141  	return e.DocBase.String()
   142  }
   143  
   144  // docURL returns a documentation URL for the specified package, if one is
   145  // specified by the options, or "" if not.
   146  func (e *EmitOptions) docURL(pi *PackageInfo) string {
   147  	if e == nil || e.DocBase == nil {
   148  		return ""
   149  	}
   150  	if e.OnlyEmitDocURIsForStandardLibs && !govname.IsStandardLibrary(pi.VName) {
   151  		return ""
   152  	}
   153  
   154  	u := *e.DocBase
   155  	u.Path = path.Join(u.Path, pi.ImportPath)
   156  	return u.String()
   157  }
   158  
   159  func (e *EmitOptions) verbose() bool {
   160  	if e == nil {
   161  		return false
   162  	}
   163  	return e.Verbose
   164  }
   165  
   166  // An impl records that a type A implements an interface B.
   167  type impl struct{ A, B types.Object }
   168  
   169  // Emit generates Kythe facts and edges to represent pi, and writes them to
   170  // sink. In case of errors, processing continues as far as possible before the
   171  // first error encountered is reported.
   172  func (pi *PackageInfo) Emit(ctx context.Context, sink Sink, opts *EmitOptions) error {
   173  	if opts == nil {
   174  		opts = &EmitOptions{}
   175  	}
   176  	e := &emitter{
   177  		ctx:       ctx,
   178  		pi:        pi,
   179  		sink:      sink,
   180  		opts:      opts,
   181  		impl:      make(map[impl]struct{}),
   182  		anchored:  make(map[ast.Node]struct{}),
   183  		fmeta:     make(map[*ast.File]bool),
   184  		variadics: make(map[*types.Slice]bool),
   185  	}
   186  
   187  	// Emit a node to represent the package as a whole.
   188  	e.writeFact(pi.VName, facts.NodeKind, nodes.Package)
   189  	if url := e.opts.docURL(pi); url != "" {
   190  		e.writeFact(pi.VName, facts.DocURI, url)
   191  	}
   192  	e.emitPackageMarkedSource(pi)
   193  
   194  	// Emit facts for all the source files claimed by this package.
   195  	for file, text := range pi.SourceText {
   196  		vname := pi.FileVName(file)
   197  		e.writeFact(vname, facts.NodeKind, nodes.File)
   198  		e.writeFact(vname, facts.Text, text)
   199  		// All Go source files are encoded as UTF-8, which is the default.
   200  
   201  		e.writeEdge(vname, pi.VName, edges.ChildOf)
   202  	}
   203  
   204  	// Traverse the AST of each file in the package for xref entries.
   205  	for _, file := range pi.Files {
   206  		e.cmap = ast.NewCommentMap(pi.FileSet, file, file.Comments)
   207  		e.writeDoc(file.Doc, pi.VName)                        // capture package comments
   208  		e.writeRef(file.Name, pi.VName, edges.DefinesBinding) // define a binding for the package
   209  		ast.Walk(newASTVisitor(func(node ast.Node, stack stackFunc) bool {
   210  			switch n := node.(type) {
   211  			case *ast.Ident:
   212  				e.visitIdent(n, stack)
   213  			case *ast.FuncDecl:
   214  				e.visitFuncDecl(n, stack)
   215  			case *ast.FuncLit:
   216  				e.visitFuncLit(n, stack)
   217  			case *ast.ValueSpec:
   218  				e.visitValueSpec(n, stack)
   219  			case *ast.TypeSpec:
   220  				e.visitTypeSpec(n, stack)
   221  			case *ast.ImportSpec:
   222  				e.visitImportSpec(n, stack)
   223  			case *ast.AssignStmt:
   224  				e.visitAssignStmt(n, stack)
   225  			case *ast.RangeStmt:
   226  				e.visitRangeStmt(n, stack)
   227  			case *ast.CompositeLit:
   228  				e.visitCompositeLit(n, stack)
   229  			case *ast.IndexExpr:
   230  				e.visitIndexExpr(n, stack)
   231  			case *ast.IndexListExpr:
   232  				e.visitIndexListExpr(n, stack)
   233  			case *ast.ArrayType:
   234  				e.visitArrayType(n, stack)
   235  			case *ast.CallExpr:
   236  				e.visitCallExpr(n, stack)
   237  			}
   238  			return true
   239  		}), file)
   240  	}
   241  
   242  	// Emit edges from each named type to the interface types it satisfies, for
   243  	// those interface types that are known to this compiltion.
   244  	e.emitSatisfactions()
   245  
   246  	// TODO(fromberger): Add diagnostics for type-checker errors.
   247  	if opts.verbose() {
   248  		for _, err := range pi.Errors {
   249  			log.WarningContextf(ctx, "Type resolution error: %v", err)
   250  		}
   251  	}
   252  	return e.firstErr
   253  }
   254  
   255  type emitter struct {
   256  	ctx      context.Context
   257  	pi       *PackageInfo
   258  	sink     Sink
   259  	opts     *EmitOptions
   260  	impl     map[impl]struct{}                    // see checkImplements
   261  	rmap     map[*ast.File]map[int]metadata.Rules // see applyRules
   262  	fmeta    map[*ast.File]bool                   // see applyRules
   263  	anchored map[ast.Node]struct{}                // see writeAnchor
   264  	firstErr error
   265  	cmap     ast.CommentMap // current file's CommentMap
   266  
   267  	// lazily-initialized lookup table based on opts.FlagConstructors
   268  	flagConstructors map[string]map[string]*gopb.FlagConstructor
   269  
   270  	variadics map[*types.Slice]bool
   271  }
   272  
   273  type refKind int
   274  
   275  const (
   276  	readRef refKind = iota
   277  	writeRef
   278  	readWriteRef
   279  )
   280  
   281  func exprRefKind(tgt ast.Expr, stack stackFunc, depth int) refKind {
   282  	switch parent := stack(depth + 1).(type) {
   283  	case *ast.AssignStmt:
   284  		// Check if identifier is being assigned; we assume this is not a definition
   285  		// and checked by the caller.
   286  		for _, lhs := range parent.Lhs {
   287  			if lhs == tgt {
   288  				switch parent.Tok {
   289  				case token.ASSIGN, token.DEFINE:
   290  					return writeRef
   291  				default: // +=, etc.
   292  					return readWriteRef
   293  				}
   294  			}
   295  		}
   296  	case *ast.IncDecStmt:
   297  		return readWriteRef
   298  	case *ast.SelectorExpr:
   299  		if id, ok := tgt.(*ast.Ident); ok && id == parent.Sel {
   300  			return exprRefKind(parent, stack, depth+1)
   301  		}
   302  	case *ast.KeyValueExpr:
   303  		if tgt == parent.Key {
   304  			if c, ok := stack(depth + 2).(*ast.CompositeLit); ok {
   305  				if _, isMap := c.Type.(*ast.MapType); !isMap {
   306  					return writeRef
   307  				}
   308  			}
   309  		}
   310  	}
   311  	return readRef
   312  }
   313  
   314  // visitIdent handles referring identifiers. Declaring identifiers are handled
   315  // as part of their parent syntax.
   316  func (e *emitter) visitIdent(id *ast.Ident, stack stackFunc) {
   317  	obj := e.pi.Info.Uses[id]
   318  	if obj == nil {
   319  		// Defining identifiers are handled by their parent nodes.
   320  		return
   321  	}
   322  
   323  	if sig, ok := obj.Type().(*types.Signature); ok && sig.Recv() != nil && sig.RecvTypeParams().Len() > 0 {
   324  		// Lookup the original non-instantiated method to reference.
   325  		if n, ok := deref(sig.Recv().Type()).(*types.Named); ok {
   326  			f, _, _ := types.LookupFieldOrMethod(n.Origin(), true, obj.Pkg(), obj.Name())
   327  			if f != nil {
   328  				obj = f
   329  			}
   330  		}
   331  	}
   332  
   333  	// Receiver type parameter identifiers are both usages and definitions; take
   334  	// the opportunity to emit a binding and do not continue to emit a Ref edge.
   335  	if def, ok := e.pi.Info.Defs[id].(*types.TypeName); ok && def == obj {
   336  		e.writeBinding(id, nodes.TVar, nil)
   337  		return
   338  	}
   339  
   340  	var target *spb.VName
   341  	if n, ok := obj.(*types.TypeName); ok && obj.Pkg() == nil {
   342  		// Handle type arguments in instantiated types.
   343  		target = e.emitType(n.Type())
   344  	} else {
   345  		target = e.pi.ObjectVName(obj)
   346  	}
   347  
   348  	if target == nil {
   349  		// This should not happen in well-formed packages, but can if the
   350  		// extractor gets confused. Avoid emitting confusing references in such
   351  		// cases. Note that in this case we need to emit a fresh anchor, since
   352  		// we aren't otherwise emitting a reference.
   353  		e.writeNodeDiagnostic(id, diagnostic{
   354  			Message: fmt.Sprintf("Unable to identify the package for %q", id.Name),
   355  		})
   356  		return
   357  	}
   358  
   359  	var refs []*spb.VName
   360  	refKind := exprRefKind(id, stack, 0)
   361  	if refKind == readRef || refKind == readWriteRef {
   362  		refs = append(refs, e.writeRef(id, target, edges.Ref))
   363  	}
   364  	if refKind == writeRef || refKind == readWriteRef {
   365  		refs = append(refs, e.writeRef(id, target, edges.RefWrites))
   366  	}
   367  
   368  	if e.opts.emitAnchorScopes() {
   369  		parent := e.callContext(stack).vname
   370  		for _, ref := range refs {
   371  			e.writeEdge(ref, parent, edges.ChildOf)
   372  		}
   373  	}
   374  	if call, ok := isCall(id, obj, stack); ok {
   375  		var callAnchor *spb.VName
   376  		if e.opts.emitRefCallOverIdentifier() {
   377  			callAnchor = e.writeRef(id, target, edges.RefCall)
   378  		} else {
   379  			callAnchor = e.writeRef(call, target, edges.RefCall)
   380  		}
   381  
   382  		// Paint an edge to the function blamed for the call, or if there is
   383  		// none then to the package initializer.
   384  		e.writeEdge(callAnchor, e.callContext(stack).vname, edges.ChildOf)
   385  	}
   386  }
   387  
   388  // visitFuncDecl handles function and method declarations and their parameters.
   389  func (e *emitter) visitFuncDecl(decl *ast.FuncDecl, stack stackFunc) {
   390  	info := &funcInfo{vname: new(spb.VName)}
   391  	e.pi.function[decl] = info
   392  
   393  	// Get the type of this function, even if its name is blank.
   394  	obj, _ := e.pi.Info.Defs[decl.Name].(*types.Func)
   395  	if obj == nil {
   396  		return // a redefinition, for example
   397  	}
   398  
   399  	// Special case: There may be multiple package-level init functions, so
   400  	// override the normal signature generation to include a discriminator.
   401  	if decl.Recv == nil && obj.Name() == "init" {
   402  		e.pi.numInits++
   403  		e.pi.sigs[obj] = fmt.Sprintf("%s#%d", e.pi.Signature(obj), e.pi.numInits)
   404  	}
   405  
   406  	info.vname = e.mustWriteBinding(decl.Name, nodes.Function, nil)
   407  	e.writeDef(decl, info.vname)
   408  	e.writeDoc(decl.Doc, info.vname)
   409  
   410  	// For concrete methods: Emit the receiver if named, and connect the method
   411  	// to its declaring type.
   412  	sig := obj.Type().(*types.Signature)
   413  	if sig.Recv() != nil {
   414  		// The receiver is treated as parameter 0.
   415  		if names := decl.Recv.List[0].Names; names != nil {
   416  			if recv := e.writeVarBinding(names[0], nodes.LocalParameter, info.vname); recv != nil {
   417  				e.writeEdge(info.vname, recv, edges.ParamIndex(0))
   418  			}
   419  		}
   420  
   421  		// The method should be a child of its (named) enclosing type.
   422  		if named, _ := deref(sig.Recv().Type()).(*types.Named); named != nil {
   423  			base := e.pi.ObjectVName(named.Obj())
   424  			e.writeEdge(info.vname, base, edges.ChildOf)
   425  		}
   426  	}
   427  	e.emitParameters(decl.Type, sig, info)
   428  }
   429  
   430  // rewrittenCorpusForVName returns the new corpus that should be assigned to the
   431  // given vname based on the OverrideStdlibCorpus and UseCompilationCorpusForAll options
   432  func (e *emitter) rewrittenCorpusForVName(v *spb.VName) string {
   433  	if e.opts.OverrideStdlibCorpus != "" && v.GetCorpus() == govname.GolangCorpus {
   434  		return e.opts.OverrideStdlibCorpus
   435  	}
   436  	if e.opts.UseCompilationCorpusForAll {
   437  		return e.pi.VName.GetCorpus()
   438  	}
   439  	if v.GetCorpus() == "" {
   440  		// If the VName doesn't specify a corpus, use the compilation unit's corpus
   441  		return e.pi.VName.GetCorpus()
   442  	}
   443  	return v.GetCorpus()
   444  }
   445  
   446  // emitTApp emits a tapp node and returns its VName.  The new tapp is emitted
   447  // with given constructor and parameters.  The constructor's kind is also
   448  // emitted if this is the first time seeing it.
   449  func (e *emitter) emitTApp(ms *cpb.MarkedSource, ctorKind string, ctor *spb.VName, params ...*spb.VName) *spb.VName {
   450  	if ctorKind != "" && e.pi.typeEmitted.Add(ctor.Signature) {
   451  		e.writeFact(ctor, facts.NodeKind, ctorKind)
   452  		if ctorKind == nodes.TBuiltin {
   453  			e.emitBuiltinMarkedSource(ctor)
   454  		}
   455  	}
   456  	components := []any{ctor}
   457  	for _, p := range params {
   458  		components = append(components, p)
   459  	}
   460  	v := &spb.VName{Language: govname.Language, Signature: hashSignature(components)}
   461  	v.Corpus = e.rewrittenCorpusForVName(v)
   462  	if e.pi.typeEmitted.Add(v.Signature) {
   463  		e.writeFact(v, facts.NodeKind, nodes.TApp)
   464  		e.writeEdge(v, ctor, edges.ParamIndex(0))
   465  		for i, p := range params {
   466  			e.writeEdge(v, p, edges.ParamIndex(i+1))
   467  		}
   468  		if ms != nil && e.opts.emitMarkedSource() {
   469  			e.emitCode(v, ms)
   470  		}
   471  	}
   472  	return v
   473  }
   474  
   475  // emitType emits the type as a node and returns its VName.  VNames are cached
   476  // so the type nodes are only emitted the first time they are seen.
   477  func (e *emitter) emitType(typ types.Type) *spb.VName {
   478  	v, ok := e.pi.typeVName[typ]
   479  	if ok {
   480  		return v
   481  	}
   482  
   483  	switch typ := typ.(type) {
   484  	case *types.Named:
   485  		if typ.TypeArgs().Len() == 0 {
   486  			v = e.pi.ObjectVName(typ.Obj())
   487  		} else {
   488  			// Instantiated Named types produce tapps
   489  			ctor := e.emitType(typ.Origin())
   490  			args := typ.TypeArgs()
   491  			var params []*spb.VName
   492  			for i := 0; i < args.Len(); i++ {
   493  				params = append(params, e.emitType(args.At(i)))
   494  			}
   495  			v = e.emitTApp(genericTAppMS, "", ctor, params...)
   496  		}
   497  	case *types.Basic:
   498  		v = govname.BasicType(typ)
   499  		if e.pi.typeEmitted.Add(v.Signature) {
   500  			e.writeFact(v, facts.NodeKind, nodes.TBuiltin)
   501  			e.emitBuiltinMarkedSource(v)
   502  		}
   503  	case *types.Array:
   504  		v = e.emitTApp(arrayTAppMS(typ.Len()), nodes.TBuiltin, govname.ArrayConstructorType(typ.Len()), e.emitType(typ.Elem()))
   505  	case *types.Slice:
   506  		if e.variadics[typ] {
   507  			v = e.emitTApp(variadicTAppMS, nodes.TBuiltin, govname.VariadicConstructorType(), e.emitType(typ.Elem()))
   508  		} else {
   509  			v = e.emitTApp(sliceTAppMS, nodes.TBuiltin, govname.SliceConstructorType(), e.emitType(typ.Elem()))
   510  		}
   511  	case *types.Pointer:
   512  		v = e.emitTApp(pointerTAppMS, nodes.TBuiltin, govname.PointerConstructorType(), e.emitType(typ.Elem()))
   513  	case *types.Chan:
   514  		v = e.emitTApp(chanTAppMS(typ.Dir()), nodes.TBuiltin, govname.ChanConstructorType(typ.Dir()), e.emitType(typ.Elem()))
   515  	case *types.Map:
   516  		v = e.emitTApp(mapTAppMS, nodes.TBuiltin, govname.MapConstructorType(), e.emitType(typ.Key()), e.emitType(typ.Elem()))
   517  	case *types.Tuple: // function return types
   518  		v = e.emitTApp(tupleTAppMS, nodes.TBuiltin, govname.TupleConstructorType(), e.visitTuple(typ)...)
   519  	case *types.Signature: // function types
   520  		ms := &cpb.MarkedSource{
   521  			Kind: cpb.MarkedSource_TYPE,
   522  			Child: []*cpb.MarkedSource{{
   523  				Kind:          cpb.MarkedSource_PARAMETER_LOOKUP_BY_PARAM,
   524  				LookupIndex:   3,
   525  				PreText:       "func(",
   526  				PostChildText: ", ",
   527  				PostText:      ")",
   528  			}},
   529  		}
   530  
   531  		if typ.Variadic() {
   532  			// Mark last parameter type as variadic.
   533  			last := typ.Params().Len() - 1
   534  			if slice, ok := typ.Params().At(last).Type().(*types.Slice); ok {
   535  				e.variadics[slice] = true
   536  			}
   537  		}
   538  		params := e.visitTuple(typ.Params())
   539  
   540  		var ret *spb.VName
   541  		if typ.Results().Len() == 1 {
   542  			ret = e.emitType(typ.Results().At(0).Type())
   543  		} else {
   544  			ret = e.emitType(typ.Results())
   545  		}
   546  		if typ.Results().Len() != 0 {
   547  			ms.Child = append(ms.Child, &cpb.MarkedSource{
   548  				Kind:    cpb.MarkedSource_BOX,
   549  				PreText: " ",
   550  				Child: []*cpb.MarkedSource{{
   551  					Kind:        cpb.MarkedSource_LOOKUP_BY_PARAM,
   552  					LookupIndex: 1,
   553  				}},
   554  			})
   555  		}
   556  
   557  		var recv *spb.VName
   558  		if r := typ.Recv(); r != nil {
   559  			recv = e.emitType(r.Type())
   560  			ms.Child = append([]*cpb.MarkedSource{{
   561  				Kind:     cpb.MarkedSource_BOX,
   562  				PreText:  "(",
   563  				PostText: ") ",
   564  				Child: []*cpb.MarkedSource{{
   565  					Kind:        cpb.MarkedSource_LOOKUP_BY_PARAM,
   566  					LookupIndex: 2,
   567  				}},
   568  			}}, ms.Child...)
   569  		} else {
   570  			recv = e.emitType(types.NewTuple())
   571  		}
   572  
   573  		v = e.emitTApp(ms, nodes.TBuiltin, govname.FunctionConstructorType(),
   574  			append([]*spb.VName{ret, recv}, params...)...)
   575  	case *types.Interface:
   576  		v = &spb.VName{Language: govname.Language, Signature: hashSignature(typ)}
   577  		if e.pi.typeEmitted.Add(v.Signature) {
   578  			e.writeFact(v, facts.NodeKind, nodes.Interface)
   579  			if e.opts.emitMarkedSource() {
   580  				e.emitCode(v, &cpb.MarkedSource{
   581  					Kind:    cpb.MarkedSource_TYPE,
   582  					PreText: typ.String(),
   583  				})
   584  			}
   585  		}
   586  	case *types.Struct:
   587  		v = &spb.VName{Language: govname.Language, Signature: hashSignature(typ)}
   588  		if e.pi.typeEmitted.Add(v.Signature) {
   589  			e.writeFact(v, facts.NodeKind, nodes.Record)
   590  			if e.opts.emitMarkedSource() {
   591  				e.emitCode(v, &cpb.MarkedSource{
   592  					Kind:    cpb.MarkedSource_TYPE,
   593  					PreText: typ.String(),
   594  				})
   595  			}
   596  		}
   597  	case *types.TypeParam:
   598  		v = e.pi.ObjectVName(typ.Obj())
   599  	default:
   600  		log.Warningf("unknown type %T: %+v", typ, typ)
   601  	}
   602  
   603  	e.pi.typeVName[typ] = v
   604  	return v
   605  }
   606  
   607  func (e *emitter) emitTypeOf(expr ast.Expr) *spb.VName { return e.emitType(e.pi.Info.TypeOf(expr)) }
   608  
   609  func (e *emitter) visitTuple(t *types.Tuple) []*spb.VName {
   610  	size := t.Len()
   611  	ts := make([]*spb.VName, size)
   612  	for i := 0; i < size; i++ {
   613  		ts[i] = e.emitType(t.At(i).Type())
   614  	}
   615  	return ts
   616  }
   617  
   618  // visitFuncLit handles function literals and their parameters.  The signature
   619  // for a function literal is named relative to the signature of its parent
   620  // function, or the file scope if the literal is at the top level.
   621  func (e *emitter) visitFuncLit(flit *ast.FuncLit, stack stackFunc) {
   622  	fi := e.callContext(stack)
   623  	if fi == nil {
   624  		panic(fmt.Sprintf("Function literal without a context: %v", flit))
   625  	}
   626  
   627  	fi.numAnons++
   628  	info := &funcInfo{vname: proto.Clone(fi.vname).(*spb.VName)}
   629  	info.vname.Language = govname.Language
   630  	info.vname.Signature += "$" + strconv.Itoa(fi.numAnons)
   631  	e.pi.function[flit] = info
   632  	def := e.writeDef(flit, info.vname)
   633  	if e.opts.emitAnchorScopes() {
   634  		e.writeEdge(def, fi.vname, edges.ChildOf)
   635  	}
   636  	e.writeFact(info.vname, facts.NodeKind, nodes.Function)
   637  
   638  	if sig, ok := e.pi.Info.Types[flit].Type.(*types.Signature); ok {
   639  		e.emitParameters(flit.Type, sig, info)
   640  	}
   641  }
   642  
   643  // visitValueSpec handles variable and constant bindings.
   644  func (e *emitter) visitValueSpec(spec *ast.ValueSpec, stack stackFunc) {
   645  	kind := nodes.Variable
   646  	if stack(1).(*ast.GenDecl).Tok == token.CONST {
   647  		kind = nodes.Constant
   648  	}
   649  	doc := specComment(spec, stack)
   650  	for _, id := range spec.Names {
   651  		ctx := e.nameContext(stack)
   652  		target := e.writeBinding(id, kind, ctx)
   653  		if target == nil {
   654  			continue // type error (reported elsewhere)
   655  		}
   656  		if kind == nodes.Variable && e.isNonFileOrPackage(ctx) {
   657  			e.writeFact(target, facts.Subkind, nodes.Local)
   658  		}
   659  		e.writeDoc(doc, target)
   660  	}
   661  
   662  	// Handle members of anonymous types declared in situ.
   663  	if spec.Type != nil {
   664  		e.emitAnonMembers(spec.Type)
   665  	}
   666  	for _, v := range spec.Values {
   667  		if lit, ok := v.(*ast.CompositeLit); ok {
   668  			e.emitAnonMembers(lit.Type)
   669  		}
   670  	}
   671  }
   672  
   673  func (e *emitter) isNonFileOrPackage(v *spb.VName) bool {
   674  	return v.GetSignature() != "" && e.pi.VName != v
   675  }
   676  
   677  // visitTypeSpec handles type declarations, including the bindings for fields
   678  // of struct types and methods of interfaces.
   679  func (e *emitter) visitTypeSpec(spec *ast.TypeSpec, stack stackFunc) {
   680  	obj := e.pi.Info.Defs[spec.Name]
   681  	if obj == nil {
   682  		return // type error
   683  	}
   684  	target := e.mustWriteBinding(spec.Name, "", e.nameContext(stack))
   685  	e.writeDef(spec, target)
   686  	e.writeDoc(specComment(spec, stack), target)
   687  
   688  	if e.pi.ImportPath == "builtin" {
   689  		// Ignore everything but defs/docs in special builtin package
   690  		return
   691  	}
   692  
   693  	mapNamedFields(spec.TypeParams, func(i int, id *ast.Ident) {
   694  		v := e.writeBinding(id, nodes.TVar, nil)
   695  		e.writeEdge(target, v, edges.TParamIndex(i))
   696  	})
   697  
   698  	// Emit type-specific structure.
   699  	switch t := obj.Type().Underlying().(type) {
   700  	case *types.Struct:
   701  		e.writeFact(target, facts.NodeKind, nodes.Record)
   702  		e.writeFact(target, facts.Subkind, nodes.Struct)
   703  		// Add parent edges for all fields, including promoted ones.
   704  		for i, n := 0, t.NumFields(); i < n; i++ {
   705  			e.writeEdge(e.pi.ObjectVName(t.Field(i)), target, edges.ChildOf)
   706  		}
   707  
   708  		// Add bindings for the explicitly-named fields in this declaration.
   709  		// Parent edges were already added, so skip them here.
   710  		if st, ok := spec.Type.(*ast.StructType); ok {
   711  			mapNamedFields(st.Fields, func(i int, id *ast.Ident) {
   712  				target := e.writeVarBinding(id, nodes.Field, nil)
   713  				f := st.Fields.List[i]
   714  				e.writeDoc(firstNonEmptyComment(f.Doc, f.Comment), target)
   715  				e.emitAnonMembers(f.Type)
   716  			})
   717  
   718  			// Handle anonymous fields. Such fields behave as if they were
   719  			// named by the base identifier of their type.
   720  			for _, field := range st.Fields.List {
   721  				if len(field.Names) != 0 {
   722  					continue // already handled above
   723  				}
   724  				id, ok := e.pi.findFieldName(field.Type)
   725  				obj := e.pi.Info.Defs[id]
   726  				if ok && obj != nil {
   727  					// Don't write a fresh anchor here; we already wrote one as
   728  					// part of the ref to the type, and we don't want duplicate
   729  					// outputs.
   730  					anchor := e.pi.AnchorVName(e.pi.Span(id))
   731  					target := e.pi.ObjectVName(obj)
   732  					e.writeEdge(anchor, target, edges.DefinesBinding)
   733  					e.writeFact(target, facts.NodeKind, nodes.Variable)
   734  					e.writeFact(target, facts.Subkind, nodes.Field)
   735  					e.writeDoc(firstNonEmptyComment(field.Doc, field.Comment), target)
   736  				}
   737  			}
   738  		}
   739  
   740  	case *types.Interface:
   741  		e.writeFact(target, facts.NodeKind, nodes.Interface)
   742  		// Add parent edges for all methods, including inherited ones.
   743  		for i, n := 0, t.NumMethods(); i < n; i++ {
   744  			e.writeEdge(e.pi.ObjectVName(t.Method(i)), target, edges.ChildOf)
   745  		}
   746  		// Mark the interface as an extension of any embedded interfaces.
   747  		for i, n := 0, t.NumEmbeddeds(); i < n; i++ {
   748  			if named, ok := t.EmbeddedType(i).(*types.Named); ok {
   749  				if eobj := named.Obj(); e.checkImplements(obj, eobj) {
   750  					e.writeEdge(target, e.pi.ObjectVName(eobj), edges.Extends)
   751  				}
   752  			}
   753  		}
   754  
   755  		// Add bindings for the explicitly-named methods in this declaration.
   756  		// Parent edges were already added, so skip them here.
   757  		if it, ok := spec.Type.(*ast.InterfaceType); ok {
   758  			mapNamedFields(it.Methods, func(i int, id *ast.Ident) {
   759  				field := it.Methods.List[i]
   760  				target := e.writeBinding(id, nodes.Function, nil)
   761  				e.writeDoc(firstNonEmptyComment(field.Doc, field.Comment), target)
   762  
   763  				info := &funcInfo{vname: target}
   764  
   765  				// The interface is the anonymous receiver (param 0)
   766  				e.emitAnonParameter(spec.Name, 0, info)
   767  
   768  				obj := e.pi.Info.Defs[id]
   769  				if obj != nil {
   770  					sig := obj.Type().(*types.Signature)
   771  					if sig != nil {
   772  						if typ, ok := field.Type.(*ast.FuncType); ok {
   773  							e.emitParameters(typ, sig, info)
   774  						}
   775  					}
   776  				}
   777  			})
   778  		}
   779  
   780  	default:
   781  		// We model a newtype form whose underlying type is not already a
   782  		// struct (e.g., "type Foo int") as if it were a record with a single
   783  		// unexported field of the underlying type. That is not really what Go
   784  		// does, but it is close enough for the graph model to work. Since
   785  		// there is no actual field declaration, however, we don't emit that.
   786  		e.writeFact(target, facts.NodeKind, nodes.Record)
   787  		e.writeFact(target, facts.Subkind, nodes.Type)
   788  	}
   789  }
   790  
   791  // visitImportSpec handles references to imported packages.
   792  func (e *emitter) visitImportSpec(spec *ast.ImportSpec, stack stackFunc) {
   793  	ipath, _ := strconv.Unquote(spec.Path.Value)
   794  	if vPath, ok := e.pi.Vendored[ipath]; ok {
   795  		ipath = vPath
   796  	}
   797  
   798  	pkg := e.pi.Dependencies[ipath]
   799  	target := e.pi.PackageVName[pkg]
   800  	if target == nil {
   801  		if ipath != "C" {
   802  			if e.opts.verbose() {
   803  				log.Warningf("Unable to resolve import path %q", ipath)
   804  			}
   805  		}
   806  		return
   807  	}
   808  
   809  	e.writeRef(spec.Path, target, edges.RefImports)
   810  	if e.opts.shouldEmit(target) && !e.pi.standardLib.Contains(ipath) {
   811  		e.writeFact(target, facts.NodeKind, nodes.Package)
   812  		e.pi.standardLib.Add(ipath)
   813  	}
   814  }
   815  
   816  // visitAssignStmt handles bindings introduced by short-declaration syntax in
   817  // assignment statments, e.g., "x, y := 1, 2".
   818  func (e *emitter) visitAssignStmt(stmt *ast.AssignStmt, stack stackFunc) {
   819  	if stmt.Tok != token.DEFINE {
   820  		return // no new bindings in this statement
   821  	}
   822  
   823  	// Not all the names in a short declaration assignment may be defined here.
   824  	// We only add bindings for newly-defined ones, of which there must be at
   825  	// least one in a well-typed program.
   826  	up := e.nameContext(stack)
   827  	for _, expr := range stmt.Lhs {
   828  		if id, _ := expr.(*ast.Ident); id != nil {
   829  			// Add a binding only if this is the definition site for the name.
   830  			if obj := e.pi.Info.Defs[id]; obj != nil && obj.Pos() == id.Pos() {
   831  				var subkind string
   832  				if e.isNonFileOrPackage(up) {
   833  					subkind = nodes.Local
   834  				}
   835  				e.writeVarBinding(id, subkind, up)
   836  			}
   837  		}
   838  	}
   839  
   840  	// TODO(fromberger): Add information about initializers where available.
   841  }
   842  
   843  // visitRangeStmt handles the bindings introduced by a for ... range statement.
   844  func (e *emitter) visitRangeStmt(stmt *ast.RangeStmt, stack stackFunc) {
   845  	if stmt.Tok != token.DEFINE {
   846  		return // no new bindings in this statement
   847  	}
   848  
   849  	// In a well-typed program, the key and value will always be identifiers.
   850  	up := e.nameContext(stack)
   851  	if key, _ := stmt.Key.(*ast.Ident); key != nil {
   852  		e.writeVarBinding(key, "", up)
   853  	}
   854  	if val, _ := stmt.Value.(*ast.Ident); val != nil {
   855  		e.writeVarBinding(val, "", up)
   856  	}
   857  }
   858  
   859  // visitCompositeLit handles references introduced by positional initializers
   860  // in composite literals that construct (pointer to) struct values. Named
   861  // initializers are handled separately.
   862  func (e *emitter) visitCompositeLit(expr *ast.CompositeLit, stack stackFunc) {
   863  	if len(expr.Elts) == 0 {
   864  		return // no fields to initialize
   865  	}
   866  
   867  	tv, ok := e.pi.Info.Types[expr]
   868  	if !ok {
   869  		if e.opts.verbose() {
   870  			log.Warningf("Unable to determine composite literal type (%s)", e.pi.FileSet.Position(expr.Pos()))
   871  		}
   872  		return
   873  	}
   874  	sv, ok := deref(tv.Type.Underlying()).(*types.Struct)
   875  	if !ok {
   876  		return // non-struct type, e.g. a slice; nothing to do here
   877  	}
   878  
   879  	if n := sv.NumFields(); n < len(expr.Elts) {
   880  		// Embedded struct fields from an imported package may not appear in
   881  		// the list if the import did not succeed.  To remain robust against
   882  		// such cases, don't try to read into the fields of a struct type if
   883  		// the counts don't line up. The information we emit will still be
   884  		// correct, we'll just miss some initializers.
   885  		log.Errorf("Struct has %d fields but %d initializers (skipping)", n, len(expr.Elts))
   886  		return
   887  	}
   888  	for i, elt := range expr.Elts {
   889  		// The keys for key-value initializers are handled upstream of us, so
   890  		// we need only handle the values. But note that key-value initializers
   891  		// may not be in order, so we have to take care to get the right field.
   892  		// Positional fields must be in order, in well-formed code.
   893  		switch t := elt.(type) {
   894  		case *ast.KeyValueExpr:
   895  			f, ok := fieldIndex(t.Key, sv)
   896  			if !ok {
   897  				log.Errorf("Found no field index for %v (skipping)", t.Key)
   898  				continue
   899  			}
   900  			e.emitPosRef(t.Value, sv.Field(f), edges.RefInit)
   901  		default:
   902  			e.emitPosRef(t, sv.Field(i), edges.RefInit)
   903  		}
   904  	}
   905  }
   906  
   907  // visitIndexExpr handles references to instantiated types with a single type
   908  // parameter.
   909  func (e *emitter) visitIndexExpr(expr *ast.IndexExpr, stack stackFunc) {
   910  	if n, ok := e.pi.Info.TypeOf(expr).(*types.Named); ok && n.TypeArgs().Len() > 0 {
   911  		e.writeRef(expr, e.emitType(n), edges.Ref)
   912  	}
   913  }
   914  
   915  // visitIndexListExpr handles references to instantiated types with multiple
   916  // type parameters.
   917  func (e *emitter) visitIndexListExpr(expr *ast.IndexListExpr, stack stackFunc) {
   918  	if n, ok := e.pi.Info.TypeOf(expr).(*types.Named); ok && n.TypeArgs().Len() > 0 {
   919  		e.writeRef(expr, e.emitType(n), edges.Ref)
   920  	}
   921  }
   922  
   923  // visitArrayType handles references to array types.
   924  func (e *emitter) visitArrayType(expr *ast.ArrayType, stack stackFunc) {
   925  	e.emitAnonMembers(expr.Elt)
   926  }
   927  
   928  // visitCallExpr handles call expressions
   929  func (e *emitter) visitCallExpr(expr *ast.CallExpr, stack stackFunc) {
   930  	e.emitFlags(expr, stack)
   931  }
   932  
   933  var deprecatedFlagRE = regexp.MustCompile(`(?i)\bdeprecated\b`)
   934  
   935  func (e *emitter) emitFlags(expr *ast.CallExpr, stack stackFunc) {
   936  	if !e.opts.emitFlagNodes() {
   937  		return
   938  	}
   939  	var funIdent *ast.Ident
   940  	switch expr := expr.Fun.(type) {
   941  	case *ast.SelectorExpr:
   942  		funIdent = expr.Sel
   943  	case *ast.Ident:
   944  		funIdent = expr
   945  	}
   946  	funObj, ok := e.pi.Info.Uses[funIdent].(*types.Func)
   947  	if !ok {
   948  		return
   949  	}
   950  
   951  	ctor := e.flagConstructor(funObj)
   952  	if ctor == nil {
   953  		sig, ok := funObj.Type().(*types.Signature)
   954  		if ok && sig.Recv() == nil {
   955  			// Check for a flag lookup/set instead.
   956  			e.emitFlagLookup(expr, funObj, stack)
   957  			e.emitFlagSet(expr, funObj, stack)
   958  		}
   959  		return
   960  	}
   961  	// Check for expected arguments.
   962  	if expected := int(max(
   963  		ctor.NameArgPosition,
   964  		ctor.DescriptionArgPosition,
   965  		ctor.GetVarArgPosition(),
   966  	)); len(expr.Args) <= expected {
   967  		log.Errorf("Expected at least %d arguments for call to %s.%s; found %d", expected, ctor.GetPkgPath(), ctor.GetFuncName(), len(expr.Args))
   968  		return
   969  	}
   970  
   971  	// Parse the flag name
   972  	nameArg, ok := expr.Args[ctor.NameArgPosition].(*ast.BasicLit)
   973  	if !ok || nameArg.Kind != token.STRING {
   974  		return
   975  	}
   976  	flagName, err := strconv.Unquote(nameArg.Value)
   977  	if err != nil {
   978  		return
   979  	}
   980  
   981  	// Get the context of the flag to construct its VName.
   982  	fi := e.callContext(stack)
   983  	if fi == nil {
   984  		return
   985  	}
   986  
   987  	// Construct a node for the flag within the file
   988  	flagNode := proto.Clone(fi.vname).(*spb.VName)
   989  	flagNode.Language = "go"
   990  	flagNode.Signature = "flag " + flagName
   991  	e.writeFact(flagNode, facts.NodeKind, "google/gflag")
   992  	if e.opts.emitMarkedSource() {
   993  		// TODO: MarkedSource initializer
   994  		ms := &cpb.MarkedSource{
   995  			Child: []*cpb.MarkedSource{{
   996  				Kind:    cpb.MarkedSource_IDENTIFIER,
   997  				PreText: flagName,
   998  				Link:    []*cpb.Link{{Definition: []string{kytheuri.ToString(flagNode)}}},
   999  			}},
  1000  		}
  1001  		e.emitCode(flagNode, ms)
  1002  	}
  1003  	e.writeEdge(flagNode, e.flagNameNode(fi, flagName), edges.Named)
  1004  
  1005  	// Emit the documentation for the flag
  1006  	if docArg, ok := expr.Args[ctor.DescriptionArgPosition].(*ast.BasicLit); ok && docArg.Kind == token.STRING {
  1007  		if doc, err := strconv.Unquote(docArg.Value); err == nil {
  1008  			docNode := proto.Clone(flagNode).(*spb.VName)
  1009  			docNode.Signature += " doc"
  1010  			e.writeFact(docNode, facts.NodeKind, nodes.Doc)
  1011  			e.writeFact(docNode, facts.Text, doc)
  1012  			e.writeEdge(docNode, flagNode, edges.Documents)
  1013  
  1014  			if deprecatedFlagRE.MatchString(doc) {
  1015  				e.writeFact(flagNode, facts.Deprecated, "")
  1016  			}
  1017  		}
  1018  	}
  1019  
  1020  	// Write a defines/binding over the flag name string
  1021  	file, start, end := e.pi.Span(nameArg)
  1022  	anchor := e.pi.AnchorVName(file, start, end)
  1023  	e.writeAnchor(nameArg, anchor, start, end)
  1024  	e.writeEdge(anchor, flagNode, edges.DefinesBinding)
  1025  
  1026  	var identDef types.Object
  1027  	if ctor.VarArgPosition != nil {
  1028  		identDef = e.pi.Info.Uses[findIdentifier(expr.Args[ctor.GetVarArgPosition()])]
  1029  	} else {
  1030  		switch parent := stack(1).(type) {
  1031  		case *ast.ValueSpec:
  1032  			for i, name := range parent.Names {
  1033  				if expr == parent.Values[i] {
  1034  					identDef = e.pi.Info.Defs[name]
  1035  					break
  1036  				}
  1037  			}
  1038  		case *ast.AssignStmt:
  1039  			for i, v := range parent.Lhs {
  1040  				if name, ok := v.(*ast.Ident); ok && expr == parent.Rhs[i] {
  1041  					identDef = e.pi.Info.Defs[name]
  1042  					break
  1043  				}
  1044  			}
  1045  		}
  1046  	}
  1047  	if identDef == nil {
  1048  		return
  1049  	}
  1050  
  1051  	// If we found the flag definition in an assignment, associate the variable
  1052  	// node with the flag node.
  1053  	e.writeEdge(e.pi.ObjectVName(identDef), flagNode, edges.Denotes)
  1054  }
  1055  
  1056  func (e *emitter) emitFlagLookup(expr *ast.CallExpr, funObj *types.Func, stack stackFunc) {
  1057  	if !e.flagLookup(funObj) {
  1058  		return
  1059  	}
  1060  	// flag.Lookup(name) invocation
  1061  	if len(expr.Args) != 1 {
  1062  		return
  1063  	}
  1064  	nameArg, ok := expr.Args[0].(*ast.BasicLit)
  1065  	if !ok || nameArg.Kind != token.STRING {
  1066  		return
  1067  	}
  1068  	flagName, err := strconv.Unquote(nameArg.Value)
  1069  	if err != nil {
  1070  		return
  1071  	}
  1072  
  1073  	fi := e.callContext(stack)
  1074  	if fi == nil {
  1075  		return
  1076  	}
  1077  
  1078  	// Write a ref over the flag name string
  1079  	file, start, end := e.pi.Span(nameArg)
  1080  	anchor := e.pi.AnchorVName(file, start, end)
  1081  	e.writeAnchor(nameArg, anchor, start, end)
  1082  	e.writeEdge(anchor, e.flagNameNode(fi, flagName), edges.Ref)
  1083  }
  1084  
  1085  func (e *emitter) emitFlagSet(expr *ast.CallExpr, funObj *types.Func, stack stackFunc) {
  1086  	if !e.flagSet(funObj) {
  1087  		return
  1088  	}
  1089  	// flag.Set(name, val) invocation
  1090  	if len(expr.Args) != 2 {
  1091  		return
  1092  	}
  1093  	nameArg, ok := expr.Args[0].(*ast.BasicLit)
  1094  	if !ok || nameArg.Kind != token.STRING {
  1095  		return
  1096  	}
  1097  	flagName, err := strconv.Unquote(nameArg.Value)
  1098  	if err != nil {
  1099  		return
  1100  	}
  1101  
  1102  	fi := e.callContext(stack)
  1103  	if fi == nil {
  1104  		return
  1105  	}
  1106  
  1107  	// Write a ref/writes over the flag name string
  1108  	file, start, end := e.pi.Span(nameArg)
  1109  	anchor := e.pi.AnchorVName(file, start, end)
  1110  	e.writeAnchor(nameArg, anchor, start, end)
  1111  	e.writeEdge(anchor, e.flagNameNode(fi, flagName), edges.RefWrites)
  1112  }
  1113  
  1114  func (e *emitter) flagNameNode(caller *funcInfo, flagName string) *spb.VName {
  1115  	nameNode := &spb.VName{
  1116  		Corpus:    caller.vname.Corpus,
  1117  		Language:  "flag",
  1118  		Signature: flagName,
  1119  	}
  1120  	e.writeFact(nameNode, facts.NodeKind, "name")
  1121  	return nameNode
  1122  }
  1123  
  1124  func findIdentifier(expr ast.Expr) *ast.Ident {
  1125  	for expr != nil {
  1126  		switch e := expr.(type) {
  1127  		case *ast.SelectorExpr:
  1128  			return e.Sel
  1129  		case *ast.UnaryExpr:
  1130  			if e.Op != token.AND {
  1131  				return nil
  1132  			}
  1133  			expr = e.X
  1134  		case *ast.Ident:
  1135  			return e
  1136  		default:
  1137  			return nil
  1138  		}
  1139  	}
  1140  	return nil
  1141  }
  1142  
  1143  func (e *emitter) flagLookup(f *types.Func) bool {
  1144  	pkg := f.Pkg()
  1145  	return pkg != nil && pkg.Name() == "flag" && f.Name() == "Lookup"
  1146  }
  1147  
  1148  func (e *emitter) flagSet(f *types.Func) bool {
  1149  	pkg := f.Pkg()
  1150  	return pkg != nil && pkg.Name() == "flag" && f.Name() == "Set"
  1151  }
  1152  
  1153  func (e *emitter) flagConstructor(f *types.Func) *gopb.FlagConstructor {
  1154  	if e.flagConstructors == nil {
  1155  		// Initial the flag constructor lookup table.
  1156  		e.flagConstructors = map[string]map[string]*gopb.FlagConstructor{}
  1157  		for _, ctor := range e.opts.FlagConstructors.GetFlag() {
  1158  			pkg := e.flagConstructors[ctor.GetPkgPath()]
  1159  			if pkg == nil {
  1160  				pkg = map[string]*gopb.FlagConstructor{}
  1161  				e.flagConstructors[ctor.GetPkgPath()] = pkg
  1162  			}
  1163  			pkg[ctor.GetFuncName()] = ctor
  1164  		}
  1165  	}
  1166  	pkg := f.Pkg()
  1167  	if pkg == nil {
  1168  		return nil
  1169  	}
  1170  	sig, ok := f.Type().(*types.Signature)
  1171  	if !ok || sig.Recv() != nil {
  1172  		// We only handle top-level flags
  1173  		return nil
  1174  	}
  1175  	return e.flagConstructors[pkg.Path()][f.Name()]
  1176  }
  1177  
  1178  // emitPosRef emits an anchor spanning loc, pointing to obj.
  1179  func (e *emitter) emitPosRef(loc ast.Node, obj types.Object, kind string) {
  1180  	target := e.pi.ObjectVName(obj)
  1181  	file, start, end := e.pi.Span(loc)
  1182  	anchor := e.pi.AnchorVName(file, start, end)
  1183  	e.writeAnchor(loc, anchor, start, end)
  1184  	e.writeEdge(anchor, target, kind)
  1185  }
  1186  
  1187  // emitParameters emits parameter edges for the parameters of a function type,
  1188  // given the type signature and info of the enclosing declaration or function
  1189  // literal.
  1190  func (e *emitter) emitParameters(ftype *ast.FuncType, sig *types.Signature, info *funcInfo) {
  1191  	paramIndex := 0
  1192  
  1193  	// If there is a receiver, it is treated as param.0.
  1194  	if sig.Recv() != nil {
  1195  		paramIndex++
  1196  	}
  1197  
  1198  	// Emit bindings and parameter edges for the parameters.
  1199  	mapAllFields(ftype.Params, func(i int, id *ast.Ident) {
  1200  		if sig.Params().At(i) != nil {
  1201  			field := ftype.Params.List[i]
  1202  			e.emitAnonMembers(field.Type)
  1203  
  1204  			if param := e.writeVarBinding(id, nodes.LocalParameter, info.vname); param != nil {
  1205  				e.writeEdge(info.vname, param, edges.ParamIndex(paramIndex))
  1206  
  1207  				// Field object does not associate any comments with the parameter; use CommentMap to find them
  1208  				e.writeDoc(firstNonEmptyComment(e.cmap.Filter(field).Comments()...), param)
  1209  			} else if typ, ok := field.Type.(*ast.Ident); ok {
  1210  				// Unnamed function parameter
  1211  				e.emitAnonParameter(typ, paramIndex, info)
  1212  			}
  1213  		}
  1214  		paramIndex++
  1215  	})
  1216  	// Emit bindings for any named result variables.
  1217  	// Results are not considered parameters.
  1218  	mapNamedFields(ftype.Results, func(i int, id *ast.Ident) {
  1219  		e.writeVarBinding(id, "", info.vname)
  1220  	})
  1221  	// Emit bindings for type parameters
  1222  	mapNamedFields(ftype.TypeParams, func(i int, id *ast.Ident) {
  1223  		v := e.writeBinding(id, nodes.TVar, nil)
  1224  		e.writeEdge(info.vname, v, edges.TParamIndex(i))
  1225  	})
  1226  }
  1227  
  1228  func (e *emitter) emitAnonParameter(typ *ast.Ident, paramIndex int, info *funcInfo) {
  1229  	info.numAnons++
  1230  	param := proto.Clone(info.vname).(*spb.VName)
  1231  	param.Signature += "$" + strconv.Itoa(info.numAnons)
  1232  	e.writeFact(param, facts.NodeKind, nodes.Variable)
  1233  	e.writeFact(param, facts.Subkind, nodes.LocalParameter)
  1234  	e.writeEdge(info.vname, param, edges.ParamIndex(paramIndex))
  1235  	if e.opts.emitMarkedSource() {
  1236  		ms := &cpb.MarkedSource{
  1237  			// An unnamed parameter will only have a MarkedSource.TYPE
  1238  			Child: []*cpb.MarkedSource{{
  1239  				Kind:    cpb.MarkedSource_TYPE,
  1240  				PreText: typ.String(),
  1241  			}},
  1242  		}
  1243  		e.emitCode(param, ms)
  1244  	}
  1245  }
  1246  
  1247  // emitAnonMembers checks whether expr denotes an anonymous struct or interface
  1248  // type, and if so emits bindings for its member fields/methods. The resulting
  1249  // members do not parent to the type, since it has no referential identity; but
  1250  // we do capture documentation in the unlikely event someone wrote any.
  1251  func (e *emitter) emitAnonMembers(expr ast.Expr) {
  1252  	if st, ok := expr.(*ast.StructType); ok {
  1253  		mapNamedFields(st.Fields, func(i int, id *ast.Ident) {
  1254  			target := e.writeVarBinding(id, nodes.Field, nil) // no parent
  1255  			e.writeDoc(firstNonEmptyComment(st.Fields.List[i].Doc, st.Fields.List[i].Comment), target)
  1256  		})
  1257  	} else if it, ok := expr.(*ast.InterfaceType); ok {
  1258  		mapNamedFields(it.Methods, func(i int, id *ast.Ident) {
  1259  			target := e.writeBinding(id, nodes.Function, nil) // no parent
  1260  			e.writeDoc(firstNonEmptyComment(it.Methods.List[i].Doc, it.Methods.List[i].Comment), target)
  1261  		})
  1262  	}
  1263  }
  1264  
  1265  // An override represents the relationship that x overrides y.
  1266  type override struct {
  1267  	x, y types.Object
  1268  }
  1269  
  1270  // overrides represents a set of override relationships we've already generated.
  1271  type overrides map[override]bool
  1272  
  1273  // seen reports whether an x overrides y was already cached, and if not adds it
  1274  // to the set.
  1275  func (o overrides) seen(x, y types.Object) bool {
  1276  	ov := override{x: x, y: y}
  1277  	ok := o[ov]
  1278  	if !ok {
  1279  		o[ov] = true
  1280  	}
  1281  	return ok
  1282  }
  1283  
  1284  // emitSatisfactions visits each named type known through the compilation being
  1285  // indexed, and emits edges connecting it to any known interfaces its method
  1286  // set satisfies.
  1287  func (e *emitter) emitSatisfactions() {
  1288  	// Find all the Named types mentioned in this compilation.
  1289  	var allTypes []*types.Named
  1290  
  1291  	// For the current source package, use all names, even local ones.
  1292  	for _, obj := range e.pi.Info.Defs {
  1293  		if obj, ok := obj.(*types.TypeName); ok {
  1294  			if n, ok := obj.Type().(*types.Named); ok {
  1295  				allTypes = append(allTypes, n)
  1296  			}
  1297  		}
  1298  	}
  1299  
  1300  	// Include instance types.
  1301  	for _, t := range e.pi.Info.Types {
  1302  		if n, ok := t.Type.(*types.Named); ok && n.TypeArgs().Len() > 0 {
  1303  			allTypes = append(allTypes, n)
  1304  		}
  1305  	}
  1306  
  1307  	// For dependencies, we only have access to package-level types, not those
  1308  	// defined by inner scopes.
  1309  	for _, pkg := range e.pi.Dependencies {
  1310  		scope := pkg.Scope()
  1311  		for _, name := range scope.Names() {
  1312  			if obj, ok := scope.Lookup(name).(*types.TypeName); ok {
  1313  				// Note that the names of some "named" types that are brought
  1314  				// in from dependencies may not be known at this point -- the
  1315  				// compiled package headers omit the names if they are not
  1316  				// needed.  Skip such cases, even though they would qualify if
  1317  				// we had the source package.
  1318  				if n, ok := obj.Type().(*types.Named); ok && obj.Name() != "" {
  1319  					allTypes = append(allTypes, n)
  1320  				}
  1321  			}
  1322  		}
  1323  	}
  1324  
  1325  	// Shared Context across all generic assignability checks.
  1326  	tctx := types.NewContext()
  1327  
  1328  	// Cache the method set of each named type in this package.
  1329  	var msets typeutil.MethodSetCache
  1330  	// Cache the overrides we've noticed to avoid duplicate entries.
  1331  	cache := make(overrides)
  1332  	for _, x := range allTypes {
  1333  		xobj := x.Obj()
  1334  		if xobj.Pkg() != e.pi.Package {
  1335  			continue // not from this package
  1336  		}
  1337  
  1338  		// Check whether x is a named type with methods; if not, skip it.
  1339  		if len(typeutil.IntuitiveMethodSet(x, &msets)) == 0 {
  1340  			continue // no methods to consider
  1341  		}
  1342  
  1343  		// N.B. This implementation is quadratic in the number of visible
  1344  		// interfaces, but that's probably OK since are only considering a
  1345  		// single compilation.
  1346  
  1347  		// Check the method sets of both x and pointer-to-x for overrides.
  1348  		xmset := msets.MethodSet(xobj.Type())
  1349  		pxmset := msets.MethodSet(types.NewPointer(xobj.Type()))
  1350  
  1351  		for _, y := range allTypes {
  1352  			yobj := y.Obj()
  1353  			if xobj == yobj {
  1354  				continue
  1355  			}
  1356  
  1357  			ymset := msets.MethodSet(yobj.Type())
  1358  
  1359  			ifx, ify := isInterface(x), isInterface(y)
  1360  			switch {
  1361  			case ifx && ify && ymset.Len() > 0:
  1362  				// x and y are both interfaces. Note that extension is handled
  1363  				// elsewhere as part of the type spec for the interface.
  1364  				if assignableTo(tctx, x, y) {
  1365  					e.writeSatisfies(xobj, yobj)
  1366  				}
  1367  				if assignableTo(tctx, y, x) {
  1368  					e.writeSatisfies(yobj, xobj)
  1369  				}
  1370  
  1371  			case ifx:
  1372  				// y is a concrete type
  1373  				pymset := msets.MethodSet(types.NewPointer(y))
  1374  				if assignableTo(tctx, y, x) {
  1375  					e.writeSatisfies(yobj, xobj)
  1376  					e.emitOverrides(ymset, pymset, xmset, cache)
  1377  				}
  1378  
  1379  			case ify && ymset.Len() > 0:
  1380  				// x is a concrete type
  1381  				if assignableTo(tctx, x, y) {
  1382  					e.writeSatisfies(xobj, yobj)
  1383  					e.emitOverrides(xmset, pxmset, ymset, cache)
  1384  				}
  1385  
  1386  			default:
  1387  				// Both x and y are concrete.
  1388  			}
  1389  		}
  1390  	}
  1391  }
  1392  
  1393  // Add xm-(overrides)-ym for each concrete method xm with a corresponding
  1394  // abstract method ym.
  1395  func (e *emitter) emitOverrides(xmset, pxmset, ymset *types.MethodSet, cache overrides) {
  1396  	for i, n := 0, ymset.Len(); i < n; i++ {
  1397  		ym := ymset.At(i)
  1398  		yobj := ym.Obj()
  1399  		xm := xmset.Lookup(yobj.Pkg(), yobj.Name())
  1400  		if xm == nil {
  1401  			if pxmset != nil {
  1402  				xm = pxmset.Lookup(yobj.Pkg(), yobj.Name())
  1403  			}
  1404  			if xm == nil {
  1405  				continue // this method is not part of the interface we're probing
  1406  			}
  1407  		}
  1408  
  1409  		xobj := xm.Obj()
  1410  		if cache.seen(xobj, yobj) {
  1411  			continue
  1412  		}
  1413  
  1414  		xvname := e.pi.ObjectVName(xobj)
  1415  		yvname := e.pi.ObjectVName(yobj)
  1416  		if e.pi.typeEmitted.Add(xvname.Signature + "+" + yvname.Signature) {
  1417  			e.writeEdge(xvname, yvname, edges.Overrides)
  1418  		}
  1419  
  1420  		xt := e.emitType(xobj.Type())
  1421  		yt := e.emitType(yobj.Type())
  1422  		if e.pi.typeEmitted.Add(xt.Signature + "+" + yt.Signature) {
  1423  			e.writeEdge(xt, yt, edges.Satisfies)
  1424  		}
  1425  	}
  1426  }
  1427  
  1428  func isInterface(typ types.Type) bool { _, ok := typ.Underlying().(*types.Interface); return ok }
  1429  
  1430  func (e *emitter) check(err error) {
  1431  	if err != nil && e.firstErr == nil {
  1432  		e.firstErr = err
  1433  		log.Errorf("indexing %q: %v", e.pi.ImportPath, err)
  1434  	}
  1435  }
  1436  
  1437  func (e *emitter) checkImplements(src, tgt types.Object) bool {
  1438  	i := impl{A: src, B: tgt}
  1439  	if _, ok := e.impl[i]; ok {
  1440  		return false
  1441  	}
  1442  	e.impl[i] = struct{}{}
  1443  	return true
  1444  }
  1445  
  1446  func (e *emitter) writeSatisfies(src, tgt types.Object) {
  1447  	if e.checkImplements(src, tgt) {
  1448  		e.writeEdge(e.pi.ObjectVName(src), e.pi.ObjectVName(tgt), edges.Satisfies)
  1449  	}
  1450  }
  1451  
  1452  func (e *emitter) writeFact(src *spb.VName, name, value string) {
  1453  	if corpus := e.rewrittenCorpusForVName(src); corpus != src.GetCorpus() {
  1454  		src = proto.Clone(src).(*spb.VName)
  1455  		src.Corpus = corpus
  1456  	}
  1457  	e.check(e.sink.writeFact(e.ctx, src, name, value))
  1458  }
  1459  
  1460  func (e *emitter) writeEdge(src, tgt *spb.VName, kind string) {
  1461  	if corpus := e.rewrittenCorpusForVName(src); corpus != src.GetCorpus() {
  1462  		src = proto.Clone(src).(*spb.VName)
  1463  		src.Corpus = corpus
  1464  	}
  1465  	if corpus := e.rewrittenCorpusForVName(tgt); corpus != tgt.GetCorpus() {
  1466  		tgt = proto.Clone(tgt).(*spb.VName)
  1467  		tgt.Corpus = corpus
  1468  	}
  1469  	e.check(e.sink.writeEdge(e.ctx, src, tgt, kind))
  1470  }
  1471  
  1472  func (e *emitter) writeAnchor(node ast.Node, src *spb.VName, start, end int) {
  1473  	if corpus := e.rewrittenCorpusForVName(src); corpus != src.GetCorpus() {
  1474  		src = proto.Clone(src).(*spb.VName)
  1475  		src.Corpus = corpus
  1476  	}
  1477  	if _, ok := e.anchored[node]; ok {
  1478  		return // this node already has an anchor
  1479  	}
  1480  	if node != nil {
  1481  		e.anchored[node] = struct{}{}
  1482  	}
  1483  	e.check(e.sink.writeAnchor(e.ctx, src, start, end))
  1484  }
  1485  
  1486  func (e *emitter) writeDiagnostic(src *spb.VName, d diagnostic) {
  1487  	if corpus := e.rewrittenCorpusForVName(src); corpus != src.GetCorpus() {
  1488  		src = proto.Clone(src).(*spb.VName)
  1489  		src.Corpus = corpus
  1490  	}
  1491  	e.check(e.sink.writeDiagnostic(e.ctx, src, d))
  1492  }
  1493  
  1494  func (e *emitter) writeNodeDiagnostic(src ast.Node, d diagnostic) {
  1495  	file, start, end := e.pi.Span(src)
  1496  	anchor := e.pi.AnchorVName(file, start, end)
  1497  	e.writeAnchor(src, anchor, start, end)
  1498  	e.writeDiagnostic(anchor, d)
  1499  }
  1500  
  1501  // writeRef emits an anchor spanning origin and referring to target with an
  1502  // edge of the given kind. The vname of the anchor is returned.
  1503  func (e *emitter) writeRef(origin ast.Node, target *spb.VName, kind string) *spb.VName {
  1504  	file, start, end := e.pi.Span(origin)
  1505  	anchor := e.pi.AnchorVName(file, start, end)
  1506  	e.writeAnchor(origin, anchor, start, end)
  1507  	e.writeEdge(anchor, target, kind)
  1508  
  1509  	// Check whether we are intended to emit metadata linkage edges, and if so,
  1510  	// whether there are any to process.
  1511  	e.applyRules(file, start, end, kind, func(rule metadata.Rule) {
  1512  		if rule.Reverse {
  1513  			e.writeEdge(rule.VName, target, rule.EdgeOut)
  1514  		} else {
  1515  			e.writeEdge(target, rule.VName, rule.EdgeOut)
  1516  		}
  1517  		if rule.Semantic != nil {
  1518  			e.writeFact(target, facts.SemanticGenerated, strings.ToLower(rule.Semantic.String()))
  1519  		}
  1520  		if rule.EdgeOut == edges.Generates && !e.fmeta[file] {
  1521  			e.fmeta[file] = true
  1522  			if rule.VName.Path != "" && target.Path != "" {
  1523  				ruleVName := narrowToFileVName(rule.VName)
  1524  				fileTarget := narrowToFileVName(anchor)
  1525  				if rule.Reverse {
  1526  					e.writeEdge(ruleVName, fileTarget, rule.EdgeOut)
  1527  				} else {
  1528  					e.writeEdge(fileTarget, ruleVName, rule.EdgeOut)
  1529  				}
  1530  			}
  1531  		}
  1532  	})
  1533  
  1534  	return anchor
  1535  }
  1536  
  1537  func narrowToFileVName(v *spb.VName) *spb.VName {
  1538  	return &spb.VName{Corpus: v.GetCorpus(), Root: v.GetRoot(), Path: v.GetPath()}
  1539  }
  1540  
  1541  // mustWriteBinding is as writeBinding, but panics if id does not resolve.  Use
  1542  // this in cases where the object is known already to exist.
  1543  func (e *emitter) mustWriteBinding(id *ast.Ident, kind string, parent *spb.VName) *spb.VName {
  1544  	if target := e.writeBinding(id, kind, parent); target != nil {
  1545  		return target
  1546  	}
  1547  	panic("unresolved definition") // logged in writeBinding
  1548  }
  1549  
  1550  // writeVarBinding is as writeBinding, assuming the kind is "variable".
  1551  // If subkind != "", it is also emitted as a subkind.
  1552  func (e *emitter) writeVarBinding(id *ast.Ident, subkind string, parent *spb.VName) *spb.VName {
  1553  	vname := e.writeBinding(id, nodes.Variable, parent)
  1554  	if vname != nil && subkind != "" {
  1555  		e.writeFact(vname, facts.Subkind, subkind)
  1556  	}
  1557  	return vname
  1558  }
  1559  
  1560  // writeBinding emits a node of the specified kind for the target of id.  If
  1561  // the identifier is not "_", an anchor for a binding definition of the target
  1562  // is also emitted at id. If parent != nil, the target is also recorded as its
  1563  // child. The target vname is returned.
  1564  func (e *emitter) writeBinding(id *ast.Ident, kind string, parent *spb.VName) *spb.VName {
  1565  	if id == nil {
  1566  		return nil
  1567  	}
  1568  	obj := e.pi.Info.Defs[id]
  1569  	if obj == nil {
  1570  		loc := e.pi.FileSet.Position(id.Pos())
  1571  		log.Errorf("Missing definition for id %q at %s", id.Name, loc)
  1572  		return nil
  1573  	}
  1574  	target := e.pi.ObjectVName(obj)
  1575  	if e.pi.ImportPath == "builtin" && parent != nil && (parent.GetSignature() == "package" || parent.GetSignature() == "") {
  1576  		// Special-case top-level builtin bindings: https://pkg.go.dev/builtin
  1577  		target = govname.Builtin(id.String())
  1578  		kind = "tbuiltin"
  1579  	}
  1580  	if kind != "" {
  1581  		e.writeFact(target, facts.NodeKind, kind)
  1582  	}
  1583  	if id.Name != "_" {
  1584  		e.writeRef(id, target, edges.DefinesBinding)
  1585  	}
  1586  	if parent != nil {
  1587  		e.writeEdge(target, parent, edges.ChildOf)
  1588  	}
  1589  	if e.opts.emitMarkedSource() {
  1590  		e.emitCode(target, e.MarkedSource(obj))
  1591  	}
  1592  	e.writeEdge(target, e.emitTypeOf(id), edges.Typed)
  1593  	return target
  1594  }
  1595  
  1596  // writeDef emits a spanning anchor and defines edge for the specified node.
  1597  // This function does not create the target node.
  1598  func (e *emitter) writeDef(node ast.Node, target *spb.VName) *spb.VName {
  1599  	return e.writeRef(node, target, edges.Defines)
  1600  }
  1601  
  1602  // writeDoc adds associations between comment groups and a documented node.
  1603  // It also handles marking deprecated facts on the target.
  1604  func (e *emitter) writeDoc(comments *ast.CommentGroup, target *spb.VName) {
  1605  	if comments == nil || len(comments.List) == 0 || target == nil {
  1606  		return
  1607  	}
  1608  
  1609  	var lines []string
  1610  	for _, comment := range comments.List {
  1611  		lines = append(lines, trimComment(comment.Text))
  1612  	}
  1613  	trimmedComment := strings.Join(lines, "\n")
  1614  
  1615  	docNode := proto.Clone(target).(*spb.VName)
  1616  	docNode.Signature += " doc"
  1617  	e.writeFact(docNode, facts.NodeKind, nodes.Doc)
  1618  	e.writeFact(docNode, facts.Text, escComment.Replace(trimmedComment))
  1619  	e.writeEdge(docNode, target, edges.Documents)
  1620  	e.emitDeprecation(target, lines)
  1621  
  1622  	e.emitDocLinks(comments, trimmedComment)
  1623  }
  1624  
  1625  func (e *emitter) emitDocLinks(comments *ast.CommentGroup, trimmedComment string) {
  1626  	// Tree traversal functions for [*comment.Block]s
  1627  	var visitBlock func(comment.Block)
  1628  	var visitText func(comment.Text) string
  1629  
  1630  	// Simply visit each [comment.Block] to find all [comment.Text] nodes
  1631  	visitBlock = func(b comment.Block) {
  1632  		switch b := b.(type) {
  1633  		case *comment.Paragraph:
  1634  			for _, t := range b.Text {
  1635  				visitText(t)
  1636  			}
  1637  		case *comment.List:
  1638  			for _, item := range b.Items {
  1639  				for _, sub := range item.Content {
  1640  					visitBlock(sub)
  1641  				}
  1642  			}
  1643  		case *comment.Heading:
  1644  			for _, t := range b.Text {
  1645  				visitText(t)
  1646  			}
  1647  		case *comment.Code:
  1648  		// nothing to traverse
  1649  		default:
  1650  			log.Errorf("Unknown comment.Block type: %T", b)
  1651  		}
  1652  	}
  1653  
  1654  	// Keep track of last seen doc link offset so we can handle duplicates
  1655  	lastOffset := -1
  1656  	lastLine := 0
  1657  
  1658  	// Emit refs for DocLinks; returns the text string for the visited Text
  1659  	visitText = func(t comment.Text) string {
  1660  		switch t := t.(type) {
  1661  		case comment.Plain:
  1662  			return string(t)
  1663  		case comment.Italic:
  1664  			return string(t)
  1665  		case *comment.Link:
  1666  			var text string
  1667  			for _, sub := range t.Text {
  1668  				text += visitText(sub)
  1669  			}
  1670  			return text
  1671  		case *comment.DocLink:
  1672  			// Reconstruct the text of the DocLink to find its position.
  1673  			text := "["
  1674  			for _, sub := range t.Text {
  1675  				text += visitText(sub)
  1676  			}
  1677  			text += "]"
  1678  
  1679  			target := e.resolveDocLink(t)
  1680  			if target == nil {
  1681  				if e.opts.verbose() {
  1682  					log.Warningf("Cannot resolve DocLink: %s", t.DefaultURL(e.opts.docBase()))
  1683  				}
  1684  				return text
  1685  			}
  1686  
  1687  			for i := lastLine; i < len(comments.List); i++ {
  1688  				c := comments.List[i]
  1689  				file, start, end := e.pi.Span(c)
  1690  				lineOffset := 0
  1691  				if lastOffset >= start && lastOffset <= end {
  1692  					lineOffset = lastOffset - start
  1693  				}
  1694  
  1695  				pos := strings.Index(c.Text[lineOffset:], text)
  1696  				if pos < 0 {
  1697  					continue
  1698  				}
  1699  				pos += lineOffset
  1700  				lastOffset = start + pos + len(text)
  1701  				lastLine = i
  1702  
  1703  				linkStart, linkEnd := pos+start, pos+start+len(text)
  1704  				anchor := e.pi.AnchorVName(file, linkStart, linkEnd)
  1705  				e.writeAnchor(nil, anchor, linkStart, linkEnd)
  1706  				e.writeEdge(anchor, target, edges.RefDoc)
  1707  
  1708  				return text
  1709  			}
  1710  
  1711  			log.Errorf("Failed to find DocLink: %q", text)
  1712  			return text
  1713  		default:
  1714  			log.Errorf("Unknown comment.Text type: %T", t)
  1715  			return ""
  1716  		}
  1717  	}
  1718  
  1719  	parser := &comment.Parser{
  1720  		LookupPackage: func(name string) (string, bool) {
  1721  			if e.pi.Name == name {
  1722  				return e.pi.ImportPath, true
  1723  			}
  1724  			for _, d := range e.pi.Dependencies {
  1725  				if d.Name() == name {
  1726  					return d.Path(), true
  1727  				}
  1728  			}
  1729  			return "", false
  1730  		},
  1731  		// Assume all symbols are valid; we'll check them in [visitText]
  1732  		LookupSym: func(recv, name string) bool { return true },
  1733  	}
  1734  
  1735  	doc := parser.Parse(trimmedComment)
  1736  	for _, c := range doc.Content {
  1737  		visitBlock(c)
  1738  	}
  1739  }
  1740  
  1741  func (e *emitter) resolveDocLink(link *comment.DocLink) *spb.VName {
  1742  	scope := e.pi.Package.Scope()
  1743  	if pkg := e.pi.Dependencies[link.ImportPath]; pkg != nil {
  1744  		scope = pkg.Scope()
  1745  	}
  1746  
  1747  	switch {
  1748  	case link.Name == "" && link.Recv == "":
  1749  		// Package reference
  1750  		if pkg := e.pi.Dependencies[link.ImportPath]; pkg != nil {
  1751  			return e.pi.PackageVName[pkg]
  1752  		}
  1753  		if e.pi.ImportPath == link.ImportPath {
  1754  			return e.pi.PackageVName[e.pi.Package]
  1755  		}
  1756  	case link.Recv != "":
  1757  		// Member reference
  1758  		if recv := scope.Lookup(link.Recv); recv != nil && recv.Pkg() != nil {
  1759  			if n, ok := deref(recv.Type()).(*types.Named); ok {
  1760  				obj, _, _ := types.LookupFieldOrMethod(n.Origin(), true, recv.Pkg(), link.Name)
  1761  				if obj != nil {
  1762  					return e.pi.ObjectVName(obj)
  1763  				}
  1764  			}
  1765  		}
  1766  	case link.Name != "":
  1767  		// Simple name reference
  1768  		if obj := scope.Lookup(link.Name); obj != nil {
  1769  			return e.pi.ObjectVName(obj)
  1770  		}
  1771  	default:
  1772  		log.Errorf("Unknown DocLink shape: %+v", link)
  1773  	}
  1774  	return nil
  1775  }
  1776  
  1777  // emitDeprecation emits a deprecated fact for the specified target if the
  1778  // comment lines indicate it is deprecated per https://github.com/golang/go/wiki/Deprecated
  1779  func (e *emitter) emitDeprecation(target *spb.VName, lines []string) {
  1780  	var deplines []string
  1781  	for _, line := range lines {
  1782  		if len(deplines) == 0 {
  1783  			if msg := strings.TrimPrefix(line, "Deprecated:"); msg != line {
  1784  				deplines = append(deplines, strings.TrimSpace(msg))
  1785  			}
  1786  		} else if line == "" {
  1787  			break
  1788  		} else {
  1789  			deplines = append(deplines, strings.TrimSpace(line))
  1790  		}
  1791  	}
  1792  	if len(deplines) > 0 {
  1793  		e.writeFact(target, facts.Deprecated, strings.Join(deplines, " "))
  1794  	}
  1795  }
  1796  
  1797  // isCall reports whether id is a call to obj.  This holds if id is in call
  1798  // position ("id(...") or is the RHS of a selector in call position
  1799  // ("x.id(...)"). If so, the nearest enclosing call expression is also
  1800  // returned.
  1801  //
  1802  // This will not match if there are redundant parentheses in the expression.
  1803  func isCall(id *ast.Ident, obj types.Object, stack stackFunc) (*ast.CallExpr, bool) {
  1804  	if _, ok := obj.(*types.Func); ok {
  1805  		if call, ok := stack(1).(*ast.CallExpr); ok && call.Fun == id {
  1806  			return call, true // id(...)
  1807  		}
  1808  		if sel, ok := stack(1).(*ast.SelectorExpr); ok && sel.Sel == id {
  1809  			if call, ok := stack(2).(*ast.CallExpr); ok && call.Fun == sel {
  1810  				return call, true // x.id(...)
  1811  			}
  1812  		}
  1813  	}
  1814  	return nil, false
  1815  }
  1816  
  1817  // callContext returns funcInfo for the nearest enclosing parent function, not
  1818  // including the node itself, or the enclosing package initializer if the node
  1819  // is at the top level.
  1820  func (e *emitter) callContext(stack stackFunc) *funcInfo {
  1821  	for i := 1; ; i++ {
  1822  		switch p := stack(i).(type) {
  1823  		case *ast.FuncDecl, *ast.FuncLit:
  1824  			return e.pi.function[p]
  1825  		case *ast.File:
  1826  			if e.opts.useFileAsTopLevelScope() {
  1827  				return &funcInfo{vname: e.pi.FileVName(p)}
  1828  			}
  1829  			fi := e.pi.packageInit[p]
  1830  			if fi == nil {
  1831  				// Lazily emit a virtual node to represent the static
  1832  				// initializer for top-level expressions in this file of the
  1833  				// package.  We only do this if there are expressions that need
  1834  				// to be initialized.
  1835  				vname := proto.Clone(e.pi.VName).(*spb.VName)
  1836  				vname.Signature += fmt.Sprintf(".<init>@%d", p.Package)
  1837  				fi = &funcInfo{vname: vname}
  1838  				e.pi.packageInit[p] = fi
  1839  				e.writeFact(vname, facts.NodeKind, nodes.Function)
  1840  				e.writeEdge(vname, e.pi.VName, edges.ChildOf)
  1841  
  1842  				// The callgraph requires we provide the caller with a
  1843  				// definition (http://www.kythe.io/docs/schema/callgraph.html).
  1844  				// Since there is no location, attach it to the beginning of
  1845  				// the file itself.
  1846  				anchor := e.pi.AnchorVName(p, 0, 0)
  1847  				e.check(e.sink.writeAnchor(e.ctx, anchor, 0, 0))
  1848  				e.writeEdge(anchor, vname, edges.Defines)
  1849  			}
  1850  			return fi
  1851  		}
  1852  	}
  1853  }
  1854  
  1855  // nameContext returns the vname for the nearest enclosing parent node, not
  1856  // including the node itself, or the enclosing package vname if the node is at
  1857  // the top level.
  1858  func (e *emitter) nameContext(stack stackFunc) *spb.VName {
  1859  	if fi := e.callContext(stack); !e.pi.isPackageInit(fi) {
  1860  		return fi.vname
  1861  	}
  1862  	return e.pi.VName
  1863  }
  1864  
  1865  // applyRules calls apply for each metadata rule matching the given combination
  1866  // of location and kind.
  1867  func (e *emitter) applyRules(file *ast.File, start, end int, kind string, apply func(r metadata.Rule)) {
  1868  	if e.opts == nil || !e.opts.EmitLinkages {
  1869  		return // nothing to do
  1870  	} else if e.rmap == nil {
  1871  		e.rmap = make(map[*ast.File]map[int]metadata.Rules)
  1872  	}
  1873  
  1874  	// Lazily populate a cache of file :: start :: rules mappings, so that we
  1875  	// need only scan the rules coincident on the starting point of the range
  1876  	// we care about. In almost all cases that will be just one, if any.
  1877  	rules, ok := e.rmap[file]
  1878  	if !ok {
  1879  		rules = make(map[int]metadata.Rules)
  1880  		for _, rule := range e.pi.Rules[file] {
  1881  			rules[rule.Begin] = append(rules[rule.Begin], rule)
  1882  		}
  1883  		e.rmap[file] = rules
  1884  	}
  1885  
  1886  	for _, rule := range rules[start] {
  1887  		if rule.End == end && rule.EdgeIn == kind {
  1888  			apply(rule)
  1889  		}
  1890  	}
  1891  }
  1892  
  1893  // A visitFunc visits a node of the Go AST. The function can use stack to
  1894  // retrieve AST nodes on the path from the node up to the root.  If the return
  1895  // value is true, the children of node are also visited; otherwise they are
  1896  // skipped.
  1897  type visitFunc func(node ast.Node, stack stackFunc) bool
  1898  
  1899  // A stackFunc returns the ith stack entry above of an AST node, where 0
  1900  // denotes the node itself. If the ith entry does not exist, the function
  1901  // returns nil.
  1902  type stackFunc func(i int) ast.Node
  1903  
  1904  // astVisitor implements ast.Visitor, passing each visited node to a callback
  1905  // function.
  1906  type astVisitor struct {
  1907  	stack []ast.Node
  1908  	visit visitFunc
  1909  }
  1910  
  1911  func newASTVisitor(f visitFunc) ast.Visitor { return &astVisitor{visit: f} }
  1912  
  1913  // Visit implements the required method of the ast.Visitor interface.
  1914  func (w *astVisitor) Visit(node ast.Node) ast.Visitor {
  1915  	if node == nil {
  1916  		w.stack = w.stack[:len(w.stack)-1] // pop
  1917  		return w
  1918  	}
  1919  
  1920  	w.stack = append(w.stack, node) // push
  1921  	if !w.visit(node, w.parent) {
  1922  		return nil
  1923  	}
  1924  	return w
  1925  }
  1926  
  1927  func (w *astVisitor) parent(i int) ast.Node {
  1928  	if i >= len(w.stack) {
  1929  		return nil
  1930  	}
  1931  	return w.stack[len(w.stack)-1-i]
  1932  }
  1933  
  1934  // deref returns the base type of T if it is a pointer, otherwise T itself.
  1935  func deref(T types.Type) types.Type {
  1936  	if U, ok := T.Underlying().(*types.Pointer); ok {
  1937  		return U.Elem()
  1938  	}
  1939  	return T
  1940  }
  1941  
  1942  // mapNamedFields applies f to each identifier declared in fields.  Each call to
  1943  // f is given the offset and the identifier.
  1944  func mapNamedFields(fields *ast.FieldList, f func(i int, id *ast.Ident)) {
  1945  	mapFields(fields, f, false)
  1946  }
  1947  
  1948  // mapAllFields applies f to each identifier declared in fields.  Each call to f
  1949  // is given the offset and the identifier.  If a field has no names, nil is
  1950  // passed to f as the Ident.
  1951  func mapAllFields(fields *ast.FieldList, f func(i int, id *ast.Ident)) {
  1952  	mapFields(fields, f, true)
  1953  }
  1954  
  1955  // mapFields applies f to each identifier declared in fields.  Each call to f is
  1956  // given the offset and the identifier.  If a field has no names and
  1957  // includeUnnamed is true, nil is passed to f as the Ident.
  1958  func mapFields(fields *ast.FieldList, f func(i int, id *ast.Ident), includeUnnamed bool) {
  1959  	if fields == nil {
  1960  		return
  1961  	}
  1962  	for i, field := range fields.List {
  1963  		if includeUnnamed && len(field.Names) == 0 {
  1964  			f(i, nil)
  1965  		}
  1966  		for _, id := range field.Names {
  1967  			f(i, id)
  1968  		}
  1969  	}
  1970  }
  1971  
  1972  // fieldIndex reports whether sv has a field named by expr, which must be of
  1973  // type *ast.Ident, and returns its positional index if so.
  1974  //
  1975  // N.B. This is a linear scan, but the count of fields should almost always be
  1976  // small enough not to worry about it.
  1977  func fieldIndex(expr ast.Expr, sv *types.Struct) (int, bool) {
  1978  	want := expr.(*ast.Ident).Name
  1979  	for i := 0; i < sv.NumFields(); i++ {
  1980  		if sv.Field(i).Name() == want {
  1981  			return i, true
  1982  		}
  1983  	}
  1984  	return -1, false
  1985  }
  1986  
  1987  var escComment = strings.NewReplacer("[", `\[`, "]", `\]`, `\`, `\\`)
  1988  
  1989  // trimComment removes the comment delimiters from a comment.  For single-line
  1990  // comments, it also removes a single leading space, if present; for multi-line
  1991  // comments it discards leading and trailing whitespace.
  1992  func trimComment(text string) string {
  1993  	if single := strings.TrimPrefix(text, "//"); single != text {
  1994  		return strings.TrimPrefix(single, " ")
  1995  	}
  1996  	return strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(text, "/*"), "*/"))
  1997  }
  1998  
  1999  // specComment returns the innermost comment associated with spec, or nil.
  2000  func specComment(spec ast.Spec, stack stackFunc) *ast.CommentGroup {
  2001  	var comment *ast.CommentGroup
  2002  	switch t := spec.(type) {
  2003  	case *ast.TypeSpec:
  2004  		comment = firstNonEmptyComment(t.Doc, t.Comment)
  2005  	case *ast.ValueSpec:
  2006  		comment = firstNonEmptyComment(t.Doc, t.Comment)
  2007  	case *ast.ImportSpec:
  2008  		comment = firstNonEmptyComment(t.Doc, t.Comment)
  2009  	}
  2010  	if comment == nil {
  2011  		if t, ok := stack(1).(*ast.GenDecl); ok {
  2012  			return t.Doc
  2013  		}
  2014  	}
  2015  	return comment
  2016  }
  2017  
  2018  func firstNonEmptyComment(cs ...*ast.CommentGroup) *ast.CommentGroup {
  2019  	for _, c := range cs {
  2020  		if c != nil && len(c.List) > 0 {
  2021  			return c
  2022  		}
  2023  	}
  2024  	return nil
  2025  }
  2026  
  2027  func canBeAssignableTo(v, t types.Type) bool {
  2028  	return types.AssignableTo(v, t) || types.AssignableTo(types.NewPointer(v), t)
  2029  }
  2030  
  2031  func assignableTo(tctx *types.Context, V, T types.Type) bool {
  2032  	// If V and T are not both named, or do not have matching non-empty type
  2033  	// parameter lists, fall back on types.AssignableTo.
  2034  	VN, Vnamed := V.(*types.Named)
  2035  	TN, Tnamed := T.(*types.Named)
  2036  	if !Vnamed || !Tnamed {
  2037  		return canBeAssignableTo(V, T)
  2038  	}
  2039  
  2040  	vtparams := VN.TypeParams()
  2041  	ttparams := TN.TypeParams()
  2042  	if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || VN.TypeArgs().Len() != 0 || TN.TypeArgs().Len() != 0 {
  2043  		return canBeAssignableTo(V, T)
  2044  	}
  2045  
  2046  	// V and T have the same (non-zero) number of type params. Instantiate both
  2047  	// with the type parameters of V. This must always succeed for V, and will
  2048  	// succeed for T if and only if the type set of each type parameter of V is a
  2049  	// subset of the type set of the corresponding type parameter of T, meaning
  2050  	// that every instantiation of V corresponds to a valid instantiation of T.
  2051  
  2052  	targs := make([]types.Type, vtparams.Len())
  2053  	for i := 0; i < vtparams.Len(); i++ {
  2054  		targs[i] = vtparams.At(i)
  2055  	}
  2056  
  2057  	vinst, err := types.Instantiate(tctx, V, targs, true)
  2058  	if err != nil {
  2059  		log.Errorf("type parameters should satisfy their own constraints: %v", err)
  2060  		return false
  2061  	}
  2062  
  2063  	tinst, err := types.Instantiate(tctx, T, targs, true)
  2064  	if err != nil {
  2065  		return false
  2066  	}
  2067  
  2068  	return canBeAssignableTo(vinst, tinst)
  2069  }