feat(go_indexer): add deprecation facts for go (#3692)
diff --git a/kythe/go/indexer/BUILD b/kythe/go/indexer/BUILD
index a605370..3a4b0fa 100644
--- a/kythe/go/indexer/BUILD
+++ b/kythe/go/indexer/BUILD
@@ -49,6 +49,11 @@
)
go_indexer_test(
+ name = "deprecation_test",
+ srcs = ["testdata/basic/deprecation.go"],
+)
+
+go_indexer_test(
name = "filenode_test",
srcs = ["testdata/basic/filenode.go"],
import_path = "test/basic",
diff --git a/kythe/go/indexer/emit.go b/kythe/go/indexer/emit.go
index 5b77624..8cd78b8 100644
--- a/kythe/go/indexer/emit.go
+++ b/kythe/go/indexer/emit.go
@@ -970,6 +970,7 @@
func (e *emitter) writeDef(node ast.Node, target *spb.VName) { e.writeRef(node, target, edges.Defines) }
// writeDoc adds associations between comment groups and a documented node.
+// It also handles marking deprecated facts on the target.
func (e *emitter) writeDoc(comments *ast.CommentGroup, target *spb.VName) {
if comments == nil || len(comments.List) == 0 || target == nil {
return
@@ -981,8 +982,29 @@
docNode := proto.Clone(target).(*spb.VName)
docNode.Signature += " doc"
e.writeFact(docNode, facts.NodeKind, nodes.Doc)
- e.writeFact(docNode, facts.Text, strings.Join(lines, "\n"))
+ e.writeFact(docNode, facts.Text, escComment.Replace(strings.Join(lines, "\n")))
e.writeEdge(docNode, target, edges.Documents)
+ e.emitDeprecation(target, lines)
+}
+
+// emitDeprecation emits a deprecated fact for the specified target if the
+// comment lines indicate it is deprecated per https://github.com/golang/go/wiki/Deprecated
+func (e *emitter) emitDeprecation(target *spb.VName, lines []string) {
+ var deplines []string
+ for _, line := range lines {
+ if len(deplines) == 0 {
+ if msg := strings.TrimPrefix(line, "Deprecated:"); msg != line {
+ deplines = append(deplines, strings.TrimSpace(msg))
+ }
+ } else if line == "" {
+ break
+ } else {
+ deplines = append(deplines, strings.TrimSpace(line))
+ }
+ }
+ if len(deplines) > 0 {
+ e.writeFact(target, facts.Deprecated, strings.Join(deplines, " "))
+ }
}
// isCall reports whether id is a call to obj. This holds if id is in call
@@ -1159,14 +1181,12 @@
// trimComment removes the comment delimiters from a comment. For single-line
// comments, it also removes a single leading space, if present; for multi-line
-// comments it discards leading and trailing whitespace. Brackets and backslash
-// characters are escaped per http://www.kythe.io/docs/schema/#doc.
+// comments it discards leading and trailing whitespace.
func trimComment(text string) string {
if single := strings.TrimPrefix(text, "//"); single != text {
- return escComment.Replace(strings.TrimPrefix(single, " "))
+ return strings.TrimPrefix(single, " ")
}
- trimmed := strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(text, "/*"), "*/"))
- return escComment.Replace(trimmed)
+ return strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(text, "/*"), "*/"))
}
// specComment returns the innermost comment associated with spec, or nil.
diff --git a/kythe/go/indexer/testdata/basic/deprecation.go b/kythe/go/indexer/testdata/basic/deprecation.go
new file mode 100644
index 0000000..4e691ae
--- /dev/null
+++ b/kythe/go/indexer/testdata/basic/deprecation.go
@@ -0,0 +1,50 @@
+// Package deprecate tests deprecation.
+
+//- @+3dep defines/binding Pkg
+
+// Deprecated: dep should not be used
+package dep
+
+//- Pkg.node/kind package
+//- Pkg.tag/deprecated "dep should not be used"
+
+//- @+6topLevel defines/binding TopLevel
+//- TopLevel.node/kind variable
+//- TopLevel.tag/deprecated "topLevel has insufficient precision"
+//- TopLevel childof Pkg
+
+// Deprecated: topLevel has insufficient precision
+var topLevel int
+
+//- @+4outer defines/binding Outer
+//- Outer.tag/deprecated "outer has been replaced by inner"
+
+// Deprecated: outer has been replaced by inner
+func outer() {
+ //- @+6stabby defines/binding V
+ //- V.node/kind variable
+ //- V childof Outer
+ //- V.tag/deprecated "stabby is too sharp"
+
+ // Deprecated: stabby is too sharp
+ var stabby bool
+
+ _ = stabby // suppress unused variable error
+}
+
+//- @+6multilineDep defines/binding Func
+//- Func.tag/deprecated "more than one line for deprecation message"
+
+// Deprecated: more than one
+// line for deprecation
+// message
+func multilineDep() {
+}
+
+//- @+6magic defines/binding Const
+//- Const.node/kind constant
+//- Const.tag/deprecated "use technology instead"
+//- Const childof Pkg
+
+// Deprecated: use technology instead
+const magic = "beans"
diff --git a/kythe/go/util/schema/facts/facts.go b/kythe/go/util/schema/facts/facts.go
index 53feddb..d95752c 100644
--- a/kythe/go/util/schema/facts/facts.go
+++ b/kythe/go/util/schema/facts/facts.go
@@ -27,6 +27,7 @@
Code = prefix + "code"
Complete = prefix + "complete"
ContextURL = prefix + "context/url"
+ Deprecated = prefix + "tag/deprecated"
Details = prefix + "details"
DocURI = prefix + "doc/uri"
Message = prefix + "message"