code: func getSourceFromFile(file string, reader *sourceReader, fns graph.Nodes, start, end int) (graph.Nodes, string, error) {
  	lineNodes := make(map[int]graph.Nodes)
  
  	// Collect source coordinates from profile.
  	const margin = 5 // Lines before first/after last sample.
  	if start == 0 {
  		if fns[0].Info.StartLine != 0 {
  			start = fns[0].Info.StartLine
  		} else {
  			start = fns[0].Info.Lineno - margin
  		}
  	} else {
  		start -= margin
  	}
  	if end == 0 {
  		end = fns[0].Info.Lineno
  	}
  	end += margin
  	for _, n := range fns {
  		lineno := n.Info.Lineno
  		nodeStart := n.Info.StartLine
  		if nodeStart == 0 {
  			nodeStart = lineno - margin
  		}
  		nodeEnd := lineno + margin
  		if nodeStart < start {
  			start = nodeStart
  		} else if nodeEnd > end {
  			end = nodeEnd
  		}
  		lineNodes[lineno] = append(lineNodes[lineno], n)
  	}
  	if start < 1 {
  		start = 1
  	}
  
  	var src graph.Nodes
  	for lineno := start; lineno <= end; lineno++ {
  		line, ok := reader.line(file, lineno)
  		if !ok {
  			break
  		}
  		flat, cum := lineNodes[lineno].Sum()
  		src = append(src, &graph.Node{
  			Info: graph.NodeInfo{
  				Name:   strings.TrimRight(line, "\n"),
  				Lineno: lineno,
  			},
  			Flat: flat,
  			Cum:  cum,
  		})
  	}
  	if err := reader.fileError(file); err != nil {
  		return nil, file, err
  	}
  	return src, file, nil
  }
docs: // getSourceFromFile collects the sources of a function from a source
  // file and annotates it with the samples in fns. Returns the sources
  // as nodes, using the info.name field to hold the source code.