Skip to content

Commit

Permalink
feat(go_indexer): support metadata semantic types (#5598)
Browse files Browse the repository at this point in the history
  • Loading branch information
schroederc committed Apr 28, 2023
1 parent c0b848b commit e79d8ee
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 55 deletions.
19 changes: 11 additions & 8 deletions kythe/go/indexer/emit.go
Expand Up @@ -1114,19 +1114,18 @@ func (e *emitter) writeRef(origin ast.Node, target *spb.VName, kind string) *spb
} else {
e.writeEdge(target, rule.VName, rule.EdgeOut)
}
if rule.Semantic != nil {
e.writeFact(target, facts.SemanticGenerated, strings.ToLower(rule.Semantic.String()))
}
if rule.EdgeOut == edges.Generates && !e.fmeta[file] {
e.fmeta[file] = true
if rule.VName.Path != "" && target.Path != "" {
ruleVName := *rule.VName
ruleVName.Signature = ""
ruleVName.Language = ""
fileTarget := *anchor
fileTarget.Signature = ""
fileTarget.Language = ""
ruleVName := narrowToFileVName(rule.VName)
fileTarget := narrowToFileVName(anchor)
if rule.Reverse {
e.writeEdge(&ruleVName, &fileTarget, rule.EdgeOut)
e.writeEdge(ruleVName, fileTarget, rule.EdgeOut)
} else {
e.writeEdge(&fileTarget, &ruleVName, rule.EdgeOut)
e.writeEdge(fileTarget, ruleVName, rule.EdgeOut)
}
}
}
Expand All @@ -1135,6 +1134,10 @@ func (e *emitter) writeRef(origin ast.Node, target *spb.VName, kind string) *spb
return anchor
}

func narrowToFileVName(v *spb.VName) *spb.VName {
return &spb.VName{Corpus: v.GetCorpus(), Root: v.GetRoot(), Path: v.GetPath()}
}

// mustWriteBinding is as writeBinding, but panics if id does not resolve. Use
// this in cases where the object is known already to exist.
func (e *emitter) mustWriteBinding(id *ast.Ident, kind string, parent *spb.VName) *spb.VName {
Expand Down
11 changes: 11 additions & 0 deletions kythe/go/indexer/testdata/meta.go
Expand Up @@ -10,6 +10,11 @@ func Barfoo() {}
// ^ ^ offset 84
// \ offset 78

func SetFoo() {}

// ^ ^ offset 143
// \ offset 137

// Note: The locations in this file are connected to the offsets defined in the
// associated meta file. If you move anything above this comment without
// updating the metadata, the test may break.
Expand All @@ -27,3 +32,9 @@ func Barfoo() {}
//- Barfoo.node/kind function
//- _AltB=vname(gsig2, gcorp, groot, gpath, glang) generates Barfoo
//- vname("", gcorp, groot, gpath, "") generates vname("", kythe, _, "go/indexer/metadata_test/meta.go", "")

//- SA.node/kind anchor
//- SA.loc/start 137
//- SA.loc/end 143
//- SA defines/binding SetFoo
//- SetFoo.semantic/generated set
14 changes: 14 additions & 0 deletions kythe/go/indexer/testdata/meta.go.linkage
Expand Up @@ -26,6 +26,20 @@
"language": "glang",
"path": "gpath"
}
},
{
"type": "anchor_defines",
"begin": 137,
"end": 143,
"edge": "%/kythe/edge/generates",
"semantic": "SET",
"vname": {
"signature": "foo",
"corpus": "gcorp",
"root": "groot",
"language": "glang",
"path": "gpath"
}
}
]
}
2 changes: 1 addition & 1 deletion kythe/go/util/metadata/BUILD
Expand Up @@ -8,8 +8,8 @@ go_library(
deps = [
"//kythe/go/util/schema/edges",
"//kythe/proto:storage_go_proto",
"@io_bazel_rules_go//proto/wkt:descriptor_go_proto",
"@org_golang_google_protobuf//encoding/protojson:go_default_library",
"@org_golang_google_protobuf//types/descriptorpb:go_default_library",
],
)

Expand Down
51 changes: 34 additions & 17 deletions kythe/go/util/metadata/metadata.go
Expand Up @@ -31,7 +31,7 @@ import (

"google.golang.org/protobuf/encoding/protojson"

protopb "github.com/golang/protobuf/protoc-gen-go/descriptor"
protopb "google.golang.org/protobuf/types/descriptorpb"
spb "kythe.io/kythe/proto/storage_go_proto"
)

Expand Down Expand Up @@ -64,16 +64,27 @@ func (rs Rules) MarshalJSON() ([]byte, error) {
}
}
f.Meta[i] = rule{
Type: rtype,
Begin: r.Begin,
End: r.End,
VName: v,
Edge: kind,
Type: rtype,
Begin: r.Begin,
End: r.End,
VName: v,
Edge: kind,
Semantic: r.Semantic,
}
}
return json.Marshal(f)
}

// Semantic is a reexport of protopb.GeneratedCodeInfo_Annotation_Semantic
type Semantic = protopb.GeneratedCodeInfo_Annotation_Semantic

// Reexport of the Semantic enum values
var (
SemanticNone Semantic = protopb.GeneratedCodeInfo_Annotation_NONE
SemanticSet Semantic = protopb.GeneratedCodeInfo_Annotation_SET
SemanticAlias Semantic = protopb.GeneratedCodeInfo_Annotation_ALIAS
)

// A Rule denotes a single metadata rule, associating type linkage information
// for an anchor spanning a given range of text.
type Rule struct {
Expand All @@ -85,6 +96,8 @@ type Rule struct {
EdgeOut string // outbound edge kind to emit
VName *spb.VName // the vname to create an edge to or from
Reverse bool // whether to draw to vname (false) or from it (true)

Semantic *Semantic // whether to apply special semantics.
}

// The types below are intermediate structures used for JSON marshaling.
Expand All @@ -104,6 +117,8 @@ type rule struct {
End int `json:"end"`
Edge string `json:"edge,omitempty"`
VName json.RawMessage `json:"vname,omitempty"`

Semantic *Semantic `json:"semantic,omitempty"`
}

// Parse parses a single JSON metadata object from r and returns the
Expand Down Expand Up @@ -132,11 +147,12 @@ func Parse(r io.Reader) (Rules, error) {
v = &msg
}
rs[i] = Rule{
Begin: meta.Begin,
End: meta.End,
EdgeOut: edges.Canonical(meta.Edge),
Reverse: edges.IsReverse(meta.Edge),
VName: v,
Begin: meta.Begin,
End: meta.End,
EdgeOut: edges.Canonical(meta.Edge),
Reverse: edges.IsReverse(meta.Edge),
VName: v,
Semantic: meta.Semantic,
}
switch t := meta.Type; t {
case "nop":
Expand Down Expand Up @@ -182,12 +198,13 @@ func FromGeneratedCodeInfo(msg *protopb.GeneratedCodeInfo, vname *spb.VName) Rul
Signature: strings.Join(sig, "."),
}
rs[i] = Rule{
EdgeIn: edges.DefinesBinding,
EdgeOut: edges.Generates,
Reverse: true,
Begin: int(anno.GetBegin()),
End: int(anno.GetEnd()),
VName: vname,
EdgeIn: edges.DefinesBinding,
EdgeOut: edges.Generates,
Reverse: true,
Begin: int(anno.GetBegin()),
End: int(anno.GetEnd()),
VName: vname,
Semantic: anno.Semantic,
}
}
return rs
Expand Down
31 changes: 19 additions & 12 deletions kythe/go/util/metadata/metadata_test.go
Expand Up @@ -27,7 +27,7 @@ import (

"google.golang.org/protobuf/proto"

protopb "github.com/golang/protobuf/protoc-gen-go/descriptor"
protopb "google.golang.org/protobuf/types/descriptorpb"
spb "kythe.io/kythe/proto/storage_go_proto"
)

Expand All @@ -42,13 +42,17 @@ func TestParse(t *testing.T) {
// NOP values, multiple rules.
{`{"type":"kythe0","meta":[
{"type":"nop"},
{"type":"nop","begin":42,"end":99}
{"type":"nop","begin":42,"end":99},
{"type":"nop","semantic":"SET"}
]}`, Rules{
{},
{
Begin: 42,
End: 99,
},
{
Semantic: SemanticSet.Enum(),
},
}},

// Test vector from the C++ implementation.
Expand Down Expand Up @@ -104,11 +108,12 @@ func TestRoundTrip(t *testing.T) {
Language: "glang",
Root: "groot",
},
Reverse: true,
EdgeIn: edges.DefinesBinding,
EdgeOut: edges.Generates,
Begin: 179,
End: 182,
Reverse: true,
EdgeIn: edges.DefinesBinding,
EdgeOut: edges.Generates,
Begin: 179,
End: 182,
Semantic: SemanticSet.Enum(),
}},
}
for _, test := range tests {
Expand Down Expand Up @@ -137,6 +142,7 @@ func TestGeneratedCodeInfo(t *testing.T) {
SourceFile: proto.String("a"),
Begin: proto.Int32(1),
End: proto.Int32(100),
Semantic: SemanticSet.Enum(),
}},
}
want := Rules{{
Expand All @@ -145,11 +151,12 @@ func TestGeneratedCodeInfo(t *testing.T) {
Language: "protobuf",
Path: "a",
},
Reverse: true,
EdgeIn: edges.DefinesBinding,
EdgeOut: edges.Generates,
Begin: 1,
End: 100,
Reverse: true,
EdgeIn: edges.DefinesBinding,
EdgeOut: edges.Generates,
Begin: 1,
End: 100,
Semantic: SemanticSet.Enum(),
}}
{
got := FromGeneratedCodeInfo(in, nil)
Expand Down
35 changes: 18 additions & 17 deletions kythe/go/util/schema/facts/facts.go
Expand Up @@ -21,23 +21,24 @@ const prefix = "/kythe/" // duplicated to avoid a circular import

// Node fact labels
const (
AnchorEnd = prefix + "loc/end"
AnchorStart = prefix + "loc/start"
BuildConfig = prefix + "build/config"
Code = prefix + "code"
Complete = prefix + "complete"
ContextURL = prefix + "context/url"
Deprecated = prefix + "tag/deprecated"
Details = prefix + "details"
DocURI = prefix + "doc/uri"
Message = prefix + "message"
NodeKind = prefix + "node/kind"
ParamDefault = prefix + "param/default"
SnippetEnd = prefix + "snippet/end"
SnippetStart = prefix + "snippet/start"
Subkind = prefix + "subkind"
Text = prefix + "text"
TextEncoding = prefix + "text/encoding"
AnchorEnd = prefix + "loc/end"
AnchorStart = prefix + "loc/start"
BuildConfig = prefix + "build/config"
Code = prefix + "code"
Complete = prefix + "complete"
ContextURL = prefix + "context/url"
Deprecated = prefix + "tag/deprecated"
Details = prefix + "details"
DocURI = prefix + "doc/uri"
Message = prefix + "message"
NodeKind = prefix + "node/kind"
ParamDefault = prefix + "param/default"
SemanticGenerated = prefix + "semantic/generated"
SnippetEnd = prefix + "snippet/end"
SnippetStart = prefix + "snippet/start"
Subkind = prefix + "subkind"
Text = prefix + "text"
TextEncoding = prefix + "text/encoding"
)

// DefaultTextEncoding is the implicit value for TextEncoding if it is empty or
Expand Down

0 comments on commit e79d8ee

Please sign in to comment.