本文整理汇总了Golang中kythe/io/kythe/go/services/xrefs.NodesMap函数的典型用法代码示例。如果您正苦于以下问题:Golang NodesMap函数的具体用法?Golang NodesMap怎么用?Golang NodesMap使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了NodesMap函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: sortReferences
func sortReferences(d *xpb.DecorationsReply) {
refs := d.Reference
spans := make([]struct{ start, end int }, len(refs))
nodes := xrefs.NodesMap(d.Node)
for i, r := range refs {
if n, ok := nodes[r.SourceTicket]; ok {
// Ignore errors; 0 works fine for sorting purposes
start, _ := strconv.Atoi(string(n[schema.AnchorStartFact]))
end, _ := strconv.Atoi(string(n[schema.AnchorEndFact]))
spans[i] = struct{ start, end int }{start, end}
}
}
sort.Sort(bySpan{refs, spans})
}
示例2: main
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
flagutil.UsageError("not given any files")
}
xs := xrefs.WebClient(*remoteAPI)
for _, file := range flag.Args() {
ticket := (&kytheuri.URI{Corpus: *corpus, Path: file}).String()
decor, err := xs.Decorations(ctx, &xpb.DecorationsRequest{
Location: &xpb.Location{Ticket: ticket},
SourceText: true,
References: true,
})
if err != nil {
log.Fatalf("Failed to get decorations for file %q", file)
}
nodes := xrefs.NodesMap(decor.Nodes)
emitted := stringset.New()
for _, r := range decor.Reference {
if r.Kind != schema.DefinesBindingEdge || emitted.Contains(r.TargetTicket) {
continue
}
ident := string(nodes[r.TargetTicket][identifierFact])
if ident == "" {
continue
}
offset, err := strconv.Atoi(string(nodes[r.SourceTicket][schema.AnchorStartFact]))
if err != nil {
log.Printf("Invalid start offset for anchor %q", r.SourceTicket)
continue
}
fields, err := getTagFields(xs, r.TargetTicket)
if err != nil {
log.Printf("Failed to get tagfields for %q: %v", r.TargetTicket, err)
}
fmt.Printf("%s\t%s\t%d;\"\t%s\n",
ident, file, offsetLine(decor.SourceText, offset), strings.Join(fields, "\t"))
emitted.Add(r.TargetTicket)
}
}
}
示例3: displayReferences
func displayReferences(decor *xpb.DecorationsReply) error {
if *displayJSON {
return json.NewEncoder(out).Encode(decor)
}
nodes := xrefs.NodesMap(decor.Node)
// TODO(schroederc): return anchor locations from server
norm := xrefs.NewNormalizer(decor.SourceText)
for _, ref := range decor.Reference {
nodeKind := factValue(nodes, ref.TargetTicket, schema.NodeKindFact, "UNKNOWN")
subkind := factValue(nodes, ref.TargetTicket, schema.SubkindFact, "")
startOffset := factValue(nodes, ref.SourceTicket, schema.AnchorStartFact, "_")
endOffset := factValue(nodes, ref.SourceTicket, schema.AnchorEndFact, "_")
// ignore errors (locations will be 0)
s, _ := strconv.Atoi(startOffset)
e, _ := strconv.Atoi(endOffset)
loc, err := norm.Location(&xpb.Location{
Kind: xpb.Location_SPAN,
Start: &xpb.Location_Point{ByteOffset: int32(s)},
End: &xpb.Location_Point{ByteOffset: int32(e)},
})
if err != nil {
return fmt.Errorf("error normalizing reference location for anchor %q: %v", ref.SourceTicket, err)
}
r := strings.NewReplacer(
"@[email protected]", ref.SourceTicket,
"@[email protected]", ref.TargetTicket,
"@[email protected]", ref.Kind,
"@[email protected]", nodeKind,
"@[email protected]", subkind,
"@^offs[email protected]", startOffset,
"@^[email protected]", strconv.Itoa(int(loc.Start.LineNumber)),
"@^[email protected]", strconv.Itoa(int(loc.Start.ColumnOffset)),
"@[email protected]", endOffset,
"@[email protected]", strconv.Itoa(int(loc.End.LineNumber)),
"@[email protected]", strconv.Itoa(int(loc.End.ColumnOffset)),
)
if _, err := r.WriteString(out, refFormat+"\n"); err != nil {
return err
}
}
return nil
}
示例4: getTagFields
func getTagFields(xs xrefs.Service, ticket string) ([]string, error) {
reply, err := xs.Edges(ctx, &xpb.EdgesRequest{
Ticket: []string{ticket},
Kind: []string{schema.ChildOfEdge, schema.ParamEdge},
Filter: []string{schema.NodeKindFact, schema.SubkindFact, identifierFact},
})
if err != nil || len(reply.EdgeSet) == 0 {
return nil, err
}
var fields []string
nodes := xrefs.NodesMap(reply.Node)
edges := xrefs.EdgesMap(reply.EdgeSet)
switch string(nodes[ticket][schema.NodeKindFact]) + "|" + string(nodes[ticket][schema.SubkindFact]) {
case schema.FunctionKind + "|":
fields = append(fields, "f")
fields = append(fields, "arity:"+strconv.Itoa(len(edges[ticket][schema.ParamEdge])))
case schema.EnumKind + "|" + schema.EnumClassSubkind:
fields = append(fields, "g")
case schema.PackageKind + "|":
fields = append(fields, "p")
case schema.RecordKind + "|" + schema.ClassSubkind:
fields = append(fields, "c")
case schema.VariableKind + "|":
fields = append(fields, "v")
}
for _, parent := range edges[ticket][schema.ChildOfEdge] {
parentIdent := string(nodes[parent][identifierFact])
if parentIdent == "" {
continue
}
switch string(nodes[parent][schema.NodeKindFact]) + "|" + string(nodes[parent][schema.SubkindFact]) {
case schema.FunctionKind + "|":
fields = append(fields, "function:"+parentIdent)
case schema.RecordKind + "|" + schema.ClassSubkind:
fields = append(fields, "class:"+parentIdent)
case schema.EnumKind + "|" + schema.EnumClassSubkind:
fields = append(fields, "enum:"+parentIdent)
}
}
return fields, nil
}
示例5: getTagFields
func getTagFields(xs xrefs.Service, ticket string) ([]string, error) {
reply, err := xs.Edges(ctx, &gpb.EdgesRequest{
Ticket: []string{ticket},
Kind: []string{edges.ChildOf, edges.Param},
Filter: []string{facts.NodeKind, facts.Subkind, identifierFact},
})
if err != nil || len(reply.EdgeSets) == 0 {
return nil, err
}
var fields []string
nmap := xrefs.NodesMap(reply.Nodes)
emap := xrefs.EdgesMap(reply.EdgeSets)
switch string(nmap[ticket][facts.NodeKind]) + "|" + string(nmap[ticket][facts.Subkind]) {
case nodes.Function + "|":
fields = append(fields, "f")
fields = append(fields, "arity:"+strconv.Itoa(len(emap[ticket][edges.Param])))
case nodes.Enum + "|" + nodes.EnumClass:
fields = append(fields, "g")
case nodes.Package + "|":
fields = append(fields, "p")
case nodes.Record + "|" + nodes.Class:
fields = append(fields, "c")
case nodes.Variable + "|":
fields = append(fields, "v")
}
for parent := range emap[ticket][edges.ChildOf] {
parentIdent := string(nmap[parent][identifierFact])
if parentIdent == "" {
continue
}
switch string(nmap[parent][facts.NodeKind]) + "|" + string(nmap[parent][facts.Subkind]) {
case nodes.Function + "|":
fields = append(fields, "function:"+parentIdent)
case nodes.Record + "|" + nodes.Class:
fields = append(fields, "class:"+parentIdent)
case nodes.Enum + "|" + nodes.EnumClass:
fields = append(fields, "enum:"+parentIdent)
}
}
return fields, nil
}
示例6: displayDecorations
func displayDecorations(decor *xpb.DecorationsReply) error {
if *displayJSON {
return jsonMarshaler.Marshal(out, decor)
}
nodes := xrefs.NodesMap(decor.Nodes)
for _, ref := range decor.Reference {
nodeKind := factValue(nodes, ref.TargetTicket, facts.NodeKind, "UNKNOWN")
subkind := factValue(nodes, ref.TargetTicket, facts.Subkind, "")
loc := &xpb.Location{
Kind: xpb.Location_SPAN,
Start: ref.AnchorStart,
End: ref.AnchorEnd,
}
var targetDef string
if ref.TargetDefinition != "" {
targetDef = ref.TargetDefinition
// TODO(schroederc): fields from decor.DefinitionLocations
// TODO(zarko): fields from decor.ExtendsOverrides
}
r := strings.NewReplacer(
"@[email protected]", ref.SourceTicket,
"@[email protected]", ref.TargetTicket,
"@[email protected]", ref.Kind,
"@[email protected]", nodeKind,
"@[email protected]", subkind,
"@^[email protected]", itoa(loc.Start.ByteOffset),
"@^[email protected]", itoa(loc.Start.LineNumber),
"@^[email protected]", itoa(loc.Start.ColumnOffset),
"@[email protected]", itoa(loc.End.ByteOffset),
"@[email protected]", itoa(loc.End.LineNumber),
"@[email protected]", itoa(loc.End.ColumnOffset),
"@[email protected]", targetDef,
)
if _, err := r.WriteString(out, refFormat+"\n"); err != nil {
return err
}
}
return nil
}
示例7: displayDecorations
func displayDecorations(decor *xpb.DecorationsReply) error {
if *displayJSON {
return jsonMarshaler.Marshal(out, decor)
}
nodes := xrefs.NodesMap(decor.Node)
for _, ref := range decor.Reference {
nodeKind := factValue(nodes, ref.TargetTicket, schema.NodeKindFact, "UNKNOWN")
subkind := factValue(nodes, ref.TargetTicket, schema.SubkindFact, "")
loc := &xpb.Location{
Kind: xpb.Location_SPAN,
Start: ref.AnchorStart,
End: ref.AnchorEnd,
}
r := strings.NewReplacer(
"@[email protected]", ref.SourceTicket,
"@[email protected]", ref.TargetTicket,
"@[email protected]", ref.Kind,
"@[email protected]", nodeKind,
"@[email protected]", subkind,
"@^[email protected]", itoa(loc.Start.ByteOffset),
"@^[email protected]", itoa(loc.Start.LineNumber),
"@^[email protected]", itoa(loc.Start.ColumnOffset),
"@[email protected]", itoa(loc.End.ByteOffset),
"@[email protected]", itoa(loc.End.LineNumber),
"@[email protected]", itoa(loc.End.ColumnOffset),
)
if _, err := r.WriteString(out, refFormat+"\n"); err != nil {
return err
}
}
return nil
}
示例8: completeDefinition
func completeDefinition(definesAnchor string) (*definition, error) {
parentReply, err := xs.Edges(ctx, &xpb.EdgesRequest{
Ticket: []string{definesAnchor},
Kind: []string{schema.ChildOfEdge},
Filter: []string{schema.NodeKindFact, schema.AnchorLocFilter},
})
if err != nil {
return nil, err
}
parentNodes := xrefs.NodesMap(parentReply.Node)
var files []string
for _, parent := range xrefs.EdgesMap(parentReply.EdgeSet)[definesAnchor][schema.ChildOfEdge] {
if string(parentNodes[parent][schema.NodeKindFact]) == schema.FileKind {
files = append(files, parent)
}
}
if len(files) == 0 {
return nil, nil
} else if len(files) > 1 {
return nil, fmt.Errorf("anchor has multiple file parents %q: %v", definesAnchor, files)
}
vName, err := kytheuri.Parse(files[0])
if err != nil {
return nil, err
}
start, end := parseAnchorSpan(parentNodes[definesAnchor])
return &definition{
File: vName.VName(),
Start: start,
End: end,
}, nil
}
示例9: main
func main() {
flag.Parse()
if *offset < 0 {
flagutil.UsageError("non-negative --offset required")
} else if *signature == "" && *path == "" {
flagutil.UsageError("must provide at least --path or --signature")
}
if strings.HasPrefix(*remoteAPI, "http://") || strings.HasPrefix(*remoteAPI, "https://") {
xs = xrefs.WebClient(*remoteAPI)
idx = search.WebClient(*remoteAPI)
} else {
conn, err := grpc.Dial(*remoteAPI)
if err != nil {
log.Fatalf("Error connecting to remote API %q: %v", *remoteAPI, err)
}
defer conn.Close()
xs = xrefs.GRPC(xpb.NewXRefServiceClient(conn))
idx = search.GRPC(spb.NewSearchServiceClient(conn))
}
relPath := *path
if !*ignoreLocalRepo {
if _, err := os.Stat(relPath); err == nil {
absPath, err := filepath.Abs(relPath)
if err != nil {
log.Fatal(err)
}
kytheRoot := findKytheRoot(filepath.Dir(absPath))
if kytheRoot != "" {
relPath, err = filepath.Rel(filepath.Join(kytheRoot, *root), absPath)
if err != nil {
log.Fatal(err)
}
}
}
}
partialFile := &spb.VName{
Signature: *signature,
Corpus: *corpus,
Root: *root,
Path: relPath,
Language: *language,
}
reply, err := idx.Search(ctx, &spb.SearchRequest{
Partial: partialFile,
Fact: fileFacts,
})
if err != nil {
log.Fatalf("Error locating file {%v}: %v", partialFile, err)
}
if len(reply.Ticket) == 0 {
log.Fatalf("Could not locate file {%v}", partialFile)
} else if len(reply.Ticket) > 1 {
log.Fatalf("Ambiguous file {%v}; multiple results: %v", partialFile, reply.Ticket)
}
fileTicket := reply.Ticket[0]
decor, err := xs.Decorations(ctx, &xpb.DecorationsRequest{
// TODO(schroederc): limit Location to a SPAN around *offset
Location: &xpb.Location{Ticket: fileTicket},
References: true,
SourceText: true,
DirtyBuffer: readDirtyBuffer(ctx),
})
if err != nil {
log.Fatal(err)
}
nodes := xrefs.NodesMap(decor.Node)
en := json.NewEncoder(os.Stdout)
for _, ref := range decor.Reference {
start, end := parseAnchorSpan(nodes[ref.SourceTicket])
if start <= *offset && *offset < end {
var r reference
r.Span.Start = start
r.Span.End = end
r.Span.Text = string(decor.SourceText[start:end])
r.Kind = strings.TrimPrefix(ref.Kind, schema.EdgePrefix)
r.Node.Ticket = ref.TargetTicket
node := nodes[ref.TargetTicket]
r.Node.Kind = string(node[schema.NodeKindFact])
r.Node.Subkind = string(node[schema.SubkindFact])
if eReply, err := xs.Edges(ctx, &xpb.EdgesRequest{
Ticket: []string{ref.TargetTicket},
Kind: []string{schema.NamedEdge, definedAtEdge},
}); err != nil {
log.Printf("WARNING: error getting edges for %q: %v", ref.TargetTicket, err)
} else {
edges := xrefs.EdgesMap(eReply.EdgeSet)[ref.TargetTicket]
for _, name := range edges[schema.NamedEdge] {
if uri, err := kytheuri.Parse(name); err != nil {
log.Printf("WARNING: named node ticket (%q) could not be parsed: %v", name, err)
} else {
r.Node.Names = append(r.Node.Names, uri.Signature)
}
}
//.........这里部分代码省略.........
示例10: main
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
flagutil.UsageError("not given any files")
}
xs := xrefs.WebClient(*remoteAPI)
idx := search.WebClient(*remoteAPI)
for _, file := range flag.Args() {
results, err := idx.Search(ctx, &spb.SearchRequest{
Partial: &spb.VName{Path: file},
Fact: []*spb.SearchRequest_Fact{{
Name: schema.NodeKindFact,
Value: []byte(schema.FileKind),
}},
})
if err != nil {
log.Fatalf("Error searching for ticket of file %q", file)
} else if len(results.Ticket) == 0 {
log.Printf("Could not find ticket for file %q", file)
continue
} else if len(results.Ticket) != 1 {
log.Printf("Multiple tickets found for file %q; choosing first from %v", file, results.Ticket)
}
ticket := results.Ticket[0]
decor, err := xs.Decorations(ctx, &xpb.DecorationsRequest{
Location: &xpb.Location{Ticket: ticket},
SourceText: true,
References: true,
})
if err != nil {
log.Fatalf("Failed to get decorations for file %q", file)
}
nodes := xrefs.NodesMap(decor.Node)
emitted := stringset.New()
for _, r := range decor.Reference {
if r.Kind != schema.DefinesBindingEdge || emitted.Contains(r.TargetTicket) {
continue
}
ident := string(nodes[r.TargetTicket][identifierFact])
if ident == "" {
continue
}
offset, err := strconv.Atoi(string(nodes[r.SourceTicket][schema.AnchorStartFact]))
if err != nil {
log.Printf("Invalid start offset for anchor %q", r.SourceTicket)
continue
}
fields, err := getTagFields(xs, r.TargetTicket)
if err != nil {
log.Printf("Failed to get tagfields for %q: %v", r.TargetTicket, err)
}
fmt.Printf("%s\t%s\t%d;\"\t%s\n",
ident, file, offsetLine(decor.SourceText, offset), strings.Join(fields, "\t"))
emitted.Add(r.TargetTicket)
}
}
}
示例11: completeAnchors
func completeAnchors(ctx context.Context, xs xrefs.NodesEdgesService, retrieveText bool, files map[string]*fileNode, edgeKind string, anchors []string) ([]*xpb.CrossReferencesReply_RelatedAnchor, error) {
edgeKind = schema.Canonicalize(edgeKind)
// AllEdges is relatively safe because each anchor will have very few parents (almost always 1)
reply, err := xrefs.AllEdges(ctx, xs, &xpb.EdgesRequest{
Ticket: anchors,
Kind: []string{schema.ChildOfEdge},
Filter: []string{
schema.NodeKindFact,
schema.AnchorLocFilter,
schema.SnippetLocFilter,
},
})
if err != nil {
return nil, err
}
nodes := xrefs.NodesMap(reply.Nodes)
var result []*xpb.CrossReferencesReply_RelatedAnchor
for ticket, es := range reply.EdgeSets {
if nodeKind := string(nodes[ticket][schema.NodeKindFact]); nodeKind != schema.AnchorKind {
log.Printf("Found non-anchor target to %q edge: %q (kind: %q)", edgeKind, ticket, nodeKind)
continue
}
// Parse anchor location start/end facts
so, eo, err := getSpan(nodes[ticket], schema.AnchorStartFact, schema.AnchorEndFact)
if err != nil {
log.Printf("Invalid anchor span for %q: %v", ticket, err)
continue
}
// For each file parent to the anchor, add an Anchor to the result.
for kind, g := range es.Groups {
if kind != schema.ChildOfEdge {
continue
}
for _, edge := range g.Edge {
parent := edge.TargetTicket
if parentKind := string(nodes[parent][schema.NodeKindFact]); parentKind != schema.FileKind {
log.Printf("Found non-file parent to anchor: %q (kind: %q)", parent, parentKind)
continue
}
a := &xpb.Anchor{
Ticket: ticket,
Kind: edgeKind,
Parent: parent,
}
file, ok := files[a.Parent]
if !ok {
nReply, err := xs.Nodes(ctx, &xpb.NodesRequest{Ticket: []string{a.Parent}})
if err != nil {
return nil, fmt.Errorf("error getting file contents for %q: %v", a.Parent, err)
}
nMap := xrefs.NodesMap(nReply.Nodes)
text := nMap[a.Parent][schema.TextFact]
file = &fileNode{
text: text,
encoding: string(nMap[a.Parent][schema.TextEncodingFact]),
norm: xrefs.NewNormalizer(text),
}
files[a.Parent] = file
}
a.Start, a.End, err = normalizeSpan(file.norm, int32(so), int32(eo))
if err != nil {
log.Printf("Invalid anchor span %q in file %q: %v", ticket, a.Parent, err)
continue
}
if retrieveText && a.Start.ByteOffset < a.End.ByteOffset {
a.Text, err = text.ToUTF8(file.encoding, file.text[a.Start.ByteOffset:a.End.ByteOffset])
if err != nil {
log.Printf("Error decoding anchor text: %v", err)
}
}
if snippetStart, snippetEnd, err := getSpan(nodes[ticket], schema.SnippetStartFact, schema.SnippetEndFact); err == nil {
startPoint, endPoint, err := normalizeSpan(file.norm, int32(snippetStart), int32(snippetEnd))
if err != nil {
log.Printf("Invalid snippet span %q in file %q: %v", ticket, a.Parent, err)
} else {
a.Snippet, err = text.ToUTF8(file.encoding, file.text[startPoint.ByteOffset:endPoint.ByteOffset])
if err != nil {
log.Printf("Error decoding snippet text: %v", err)
}
a.SnippetStart = startPoint
a.SnippetEnd = endPoint
}
}
// fallback to a line-based snippet if the indexer did not provide its own snippet offsets
if a.Snippet == "" {
a.SnippetStart = &xpb.Location_Point{
ByteOffset: a.Start.ByteOffset - a.Start.ColumnOffset,
LineNumber: a.Start.LineNumber,
}
//.........这里部分代码省略.........
示例12: Decorations
// Decorations implements part of the xrefs.Service interface.
func (db *DB) Decorations(req *xpb.DecorationsRequest) (*xpb.DecorationsReply, error) {
if req.GetLocation() == nil {
return nil, errors.New("missing location")
} else if req.Location.Kind != xpb.Location_FILE {
return nil, fmt.Errorf("%s location kind unimplemented", req.Location.Kind)
} else if len(req.DirtyBuffer) != 0 {
return nil, errors.New("dirty buffers unimplemented")
}
fileTicket := req.Location.Ticket
edgesReply, err := db.Edges(&xpb.EdgesRequest{
Ticket: []string{fileTicket},
Kind: []string{revChildOfEdge},
Filter: []string{schema.NodeKindFact, schema.TextFact, schema.TextEncodingFact},
})
if err != nil {
return nil, err
}
reply := &xpb.DecorationsReply{
Location: &xpb.Location{
Ticket: fileTicket,
},
}
nodes := xrefs.NodesMap(edgesReply.Node)
if req.SourceText {
if nodes[fileTicket] == nil {
nodesReply, err := db.Nodes(&xpb.NodesRequest{Ticket: []string{fileTicket}})
if err != nil {
return nil, err
}
nodes = xrefs.NodesMap(nodesReply.Node)
}
reply.SourceText = nodes[fileTicket][schema.TextFact]
reply.Encoding = string(nodes[fileTicket][schema.TextEncodingFact])
}
nodeTickets := stringset.New()
if req.References {
// Traverse the following chain of edges:
// file --%/kythe/edge/childof-> []anchor --forwardEdgeKind-> []target
edges := xrefs.EdgesMap(edgesReply.EdgeSet)
for _, anchor := range edges[fileTicket][revChildOfEdge] {
if string(nodes[anchor][schema.NodeKindFact]) != schema.AnchorKind {
continue
}
uri, err := kytheuri.Parse(anchor)
if err != nil {
return nil, fmt.Errorf("invalid anchor ticket found %q: %v", anchor, err)
}
rows, err := db.anchorEdgesStmt.Query(schema.ChildOfEdge, uri.Signature, uri.Corpus, uri.Root, uri.Path, uri.Language)
if err != nil {
return nil, fmt.Errorf("anchor %q edge query error: %v", anchor, err)
}
for rows.Next() {
var target kytheuri.URI
var kind string
if err := rows.Scan(&target.Signature, &target.Corpus, &target.Root, &target.Path, &target.Language, &kind); err != nil {
return nil, fmt.Errorf("anchor %q edge scan error: %v", anchor, err)
}
ticket := target.String()
reply.Reference = append(reply.Reference, &xpb.DecorationsReply_Reference{
SourceTicket: anchor,
Kind: kind,
TargetTicket: ticket,
})
nodeTickets.Add(anchor, ticket)
}
}
}
nodesReply, err := db.Nodes(&xpb.NodesRequest{Ticket: nodeTickets.Slice()})
if err != nil {
return nil, err
}
reply.Node = nodesReply.Node
return reply, nil
}
示例13: Decorations
// Decorations implements part of the Service interface.
func (g *GraphStoreService) Decorations(ctx context.Context, req *xpb.DecorationsRequest) (*xpb.DecorationsReply, error) {
if len(req.DirtyBuffer) > 0 {
return nil, errors.New("UNIMPLEMENTED: dirty buffers")
} else if req.GetLocation() == nil {
// TODO(schroederc): allow empty location when given dirty buffer
return nil, errors.New("missing location")
}
fileVName, err := kytheuri.ToVName(req.Location.Ticket)
if err != nil {
return nil, fmt.Errorf("invalid file ticket %q: %v", req.Location.Ticket, err)
}
text, encoding, err := getSourceText(ctx, g.gs, fileVName)
if err != nil {
return nil, fmt.Errorf("failed to retrieve file text: %v", err)
}
norm := xrefs.NewNormalizer(text)
loc, err := norm.Location(req.GetLocation())
if err != nil {
return nil, err
}
reply := &xpb.DecorationsReply{
Location: loc,
Nodes: make(map[string]*xpb.NodeInfo),
}
// Handle DecorationsRequest.SourceText switch
if req.SourceText {
if loc.Kind == xpb.Location_FILE {
reply.SourceText = text
} else {
reply.SourceText = text[loc.Start.ByteOffset:loc.End.ByteOffset]
}
reply.Encoding = encoding
}
// Handle DecorationsRequest.References switch
if req.References {
// Traverse the following chain of edges:
// file --%/kythe/edge/childof-> []anchor --forwardEdgeKind-> []target
//
// Add []anchor and []target nodes to reply.Nodes
// Add all {anchor, forwardEdgeKind, target} tuples to reply.Reference
patterns := xrefs.ConvertFilters(req.Filter)
children, err := getEdges(ctx, g.gs, fileVName, func(e *spb.Entry) bool {
return e.EdgeKind == revChildOfEdgeKind
})
if err != nil {
return nil, fmt.Errorf("failed to retrieve file children: %v", err)
}
targetSet := stringset.New()
for _, edge := range children {
anchor := edge.Target
ticket := kytheuri.ToString(anchor)
anchorNodeReply, err := g.Nodes(ctx, &xpb.NodesRequest{
Ticket: []string{ticket},
})
if err != nil {
return nil, fmt.Errorf("failure getting reference source node: %v", err)
} else if len(anchorNodeReply.Nodes) != 1 {
return nil, fmt.Errorf("found %d nodes for {%+v}", len(anchorNodeReply.Nodes), anchor)
}
node, ok := xrefs.NodesMap(anchorNodeReply.Nodes)[ticket]
if !ok {
return nil, fmt.Errorf("failed to find info for node %q", ticket)
} else if string(node[schema.NodeKindFact]) != schema.AnchorKind {
// Skip child if it isn't an anchor node
continue
}
anchorStart, err := strconv.Atoi(string(node[schema.AnchorStartFact]))
if err != nil {
log.Printf("Invalid anchor start offset %q for node %q: %v", node[schema.AnchorStartFact], ticket, err)
continue
}
anchorEnd, err := strconv.Atoi(string(node[schema.AnchorEndFact]))
if err != nil {
log.Printf("Invalid anchor end offset %q for node %q: %v", node[schema.AnchorEndFact], ticket, err)
continue
}
if loc.Kind == xpb.Location_SPAN {
// Check if anchor fits within/around requested source text window
if !xrefs.InSpanBounds(req.SpanKind, int32(anchorStart), int32(anchorEnd), loc.Start.ByteOffset, loc.End.ByteOffset) {
continue
} else if anchorStart > anchorEnd {
log.Printf("Invalid anchor offset span %d:%d", anchorStart, anchorEnd)
continue
}
}
targets, err := getEdges(ctx, g.gs, anchor, func(e *spb.Entry) bool {
//.........这里部分代码省略.........
示例14: displayEdgeGraph
func displayEdgeGraph(reply *xpb.EdgesReply) error {
nodes := xrefs.NodesMap(reply.Nodes)
edges := make(map[string]map[string]stringset.Set)
for source, es := range reply.EdgeSets {
for gKind, g := range es.Groups {
for _, edge := range g.Edge {
tgt := edge.TargetTicket
src, kind := source, gKind
if schema.EdgeDirection(kind) == schema.Reverse {
src, kind, tgt = tgt, schema.MirrorEdge(kind), src
}
groups, ok := edges[src]
if !ok {
groups = make(map[string]stringset.Set)
edges[src] = groups
}
targets, ok := groups[kind]
if !ok {
targets = stringset.New()
groups[kind] = targets
}
targets.Add(tgt)
}
}
}
if _, err := fmt.Println("digraph kythe {"); err != nil {
return err
}
for ticket, node := range nodes {
if _, err := fmt.Printf(` %q [label=<<table><tr><td colspan="2">%s</td></tr>`, ticket, html.EscapeString(ticket)); err != nil {
return err
}
var facts []string
for fact := range node {
facts = append(facts, fact)
}
sort.Strings(facts)
for _, fact := range facts {
if _, err := fmt.Printf("<tr><td>%s</td><td>%s</td></tr>", html.EscapeString(fact), html.EscapeString(string(node[fact]))); err != nil {
return err
}
}
if _, err := fmt.Println("</table>> shape=plaintext];"); err != nil {
return err
}
}
if _, err := fmt.Println(); err != nil {
return err
}
for src, groups := range edges {
for kind, targets := range groups {
for tgt := range targets {
if _, err := fmt.Printf("\t%q -> %q [label=%q];\n", src, tgt, kind); err != nil {
return err
}
}
}
}
if _, err := fmt.Println("}"); err != nil {
return err
}
return nil
}
示例15: main
func main() {
flag.Parse()
if flag.NArg() > 0 {
flagutil.UsageErrorf("unknown non-flag argument(s): %v", flag.Args())
} else if *offset < 0 && (*lineNumber < 0 || *columnOffset < 0) {
flagutil.UsageError("non-negative --offset (or --line and --column) required")
} else if *signature == "" && *path == "" {
flagutil.UsageError("must provide at least --path or --signature")
}
defer (*apiFlag).Close()
xs, idx = *apiFlag, *apiFlag
relPath := *path
if *localRepoRoot != "NONE" {
if _, err := os.Stat(relPath); err == nil {
absPath, err := filepath.Abs(relPath)
if err != nil {
log.Fatal(err)
}
if *dirtyBuffer == "" {
*dirtyBuffer = absPath
}
kytheRoot := *localRepoRoot
if kytheRoot == "" {
kytheRoot = findKytheRoot(filepath.Dir(absPath))
}
if kytheRoot != "" {
relPath, err = filepath.Rel(filepath.Join(kytheRoot, *root), absPath)
if err != nil {
log.Fatal(err)
}
}
}
}
partialFile := &spb.VName{
Signature: *signature,
Corpus: *corpus,
Root: *root,
Path: relPath,
Language: *language,
}
reply, err := idx.Search(ctx, &spb.SearchRequest{
Partial: partialFile,
Fact: fileFacts,
})
if err != nil {
log.Fatalf("Error locating file {%v}: %v", partialFile, err)
}
if len(reply.Ticket) == 0 {
log.Fatalf("Could not locate file {%v}", partialFile)
} else if len(reply.Ticket) > 1 {
log.Fatalf("Ambiguous file {%v}; multiple results: %v", partialFile, reply.Ticket)
}
fileTicket := reply.Ticket[0]
text := readDirtyBuffer(ctx)
decor, err := xs.Decorations(ctx, &xpb.DecorationsRequest{
// TODO(schroederc): limit Location to a SPAN around *offset
Location: &xpb.Location{Ticket: fileTicket},
References: true,
SourceText: true,
DirtyBuffer: text,
Filter: []string{
schema.NodeKindFact,
schema.SubkindFact,
schema.AnchorLocFilter, // TODO(schroederc): remove once backwards-compatibility fix below is removed
},
})
if err != nil {
log.Fatal(err)
}
if text == nil {
text = decor.SourceText
}
nodes := xrefs.NodesMap(decor.Node)
// Normalize point within source text
point := normalizedPoint(text)
en := json.NewEncoder(os.Stdout)
for _, ref := range decor.Reference {
var start, end int
if ref.AnchorStart == nil || ref.AnchorEnd == nil {
// TODO(schroederc): remove this backwards-compatibility fix
start, end = parseAnchorSpan(nodes[ref.SourceTicket])
} else {
start, end = int(ref.AnchorStart.ByteOffset), int(ref.AnchorEnd.ByteOffset)
}
if start <= point && point < end {
var r reference
r.Span.Start = start
r.Span.End = end
r.Span.Text = string(text[start:end])
r.Kind = strings.TrimPrefix(ref.Kind, schema.EdgePrefix)
r.Node.Ticket = ref.TargetTicket
node := nodes[ref.TargetTicket]
//.........这里部分代码省略.........