예제 #1
0
// deeper reports whether block x is lexically deeper than y.
func deeper(x, y *types.Scope) bool {
	if x == y || x == nil {
		return false
	} else if y == nil {
		return true
	} else {
		return deeper(x.Parent(), y.Parent())
	}
}
예제 #2
0
func (g *Grapher) scopeLabel(s *types.Scope) (path []string) {
	node, present := g.scopeNodes[s]
	if !present {
		// TODO(sqs): diagnose why this happens. See https://github.com/sourcegraph/sourcegraph.com/issues/163.
		// log.Printf("no node found for scope (giving a dummy label); scope is: %s", s.String())
		return []string{fmt.Sprintf("ERROR%d", rand.Intn(10000))}
	}

	switch n := node.(type) {
	case *ast.File:
		return []string{}

	case *ast.Package:
		return []string{}

	case *ast.FuncType:
		// get func name
		_, astPath, _ := g.program.PathEnclosingInterval(n.Pos(), n.End())
		if false {
			log.Printf("----------")
			for i, n := range astPath {
				log.Printf("%d. %T %+v", i, n, n)
			}
		}
		if f, ok := astPath[0].(*ast.FuncDecl); ok {
			var path []string
			if f.Recv != nil {
				path = []string{derefNode(f.Recv.List[0].Type).(*ast.Ident).Name}
			}
			var uniqName string
			if f.Name.Name == "init" {
				// init function can appear multiple times in each file and
				// package, so need to uniquify it
				uniqName = f.Name.Name + uniqID(g.program.Fset.Position(f.Name.Pos()))
			} else {
				uniqName = f.Name.Name
			}
			path = append(path, uniqName)
			return path
		}
	}

	// get this scope's index in parent
	// TODO(sqs): is it necessary to uniquify this here now that we're handling
	// init above?
	p := s.Parent()
	var prefix []string
	if fs, ok := g.scopeNodes[p].(*ast.File); ok {
		// avoid file scope collisions by using file index as well
		filename := g.program.Fset.Position(fs.Name.Pos()).Filename
		prefix = []string{fmt.Sprintf("$%s", strippedFilename(filename))}
	}
	for i := 0; i < p.NumChildren(); i++ {
		if p.Child(i) == s {
			filename := g.program.Fset.Position(node.Pos()).Filename
			return append(prefix, fmt.Sprintf("$%s%d", strippedFilename(filename), i))
		}
	}

	panic("unreachable")
}