Skip to content

Commit

Permalink
feat(api): add resolved path filters for xrefs
Browse files Browse the repository at this point in the history
  • Loading branch information
schroederc committed May 5, 2022
1 parent 1e4467b commit 76ca533
Show file tree
Hide file tree
Showing 6 changed files with 292 additions and 238 deletions.
9 changes: 9 additions & 0 deletions kythe/go/services/cli/commands_xrefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ type xrefsCommand struct {
nodeDefinitions bool
anchorText bool

resolvedPathFilters flagutil.StringList

excludeGenerated bool
}

Expand All @@ -66,6 +68,7 @@ func (c *xrefsCommand) SetFlags(flag *flag.FlagSet) {
flag.StringVar(&c.workspaceURI, "workspace_uri", "", "Workspace URI to patch cross-references")
flag.BoolVar(&c.relatedNodes, "related_nodes", true, "Whether to request related nodes")
flag.Var(&c.nodeFilters, "filters", "CSV list of additional fact filters to use when requesting related nodes")
flag.Var(&c.resolvedPathFilters, "resolved_path_filters", "CSV list of additional resolved path filters to use")
flag.Var(&c.buildConfigs, "build_config", "CSV set of build configs with which to filter file decorations")
flag.BoolVar(&c.nodeDefinitions, "node_definitions", false, "Whether to request definition locations for related nodes")
flag.BoolVar(&c.anchorText, "anchor_text", false, "Whether to request text for anchors")
Expand Down Expand Up @@ -96,6 +99,12 @@ func (c xrefsCommand) Run(ctx context.Context, flag *flag.FlagSet, api API) erro
Root: ".+",
})
}
for _, f := range c.resolvedPathFilters {
req.CorpusPathFilters.Filter = append(req.CorpusPathFilters.Filter, &xpb.CorpusPathFilter{
Type: xpb.CorpusPathFilter_INCLUDE_ONLY,
ResolvedPath: f,
})
}
if c.relatedNodes {
req.Filter = []string{facts.NodeKind, facts.Subkind}
if len(c.nodeFilters) > 0 && (len(c.nodeFilters) != 1 || c.nodeFilters[0] != "") {
Expand Down
16 changes: 15 additions & 1 deletion kythe/go/serving/xrefs/xrefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"flag"
"fmt"
"log"
"path/filepath"
"regexp"
"strings"

Expand Down Expand Up @@ -228,6 +229,19 @@ type Table struct {

// MakePatcher returns a patching client that targets a Workspace.
MakePatcher func(context.Context, *xpb.Workspace) (MultiFilePatcher, error)

// ResolvePath is used to resolve CorpusPaths for filtering. If unset,
// DefaultResolvePath will be used.
ResolvePath PathResolver
}

// A PathResolver resolves a CorpusPath into a single filepath.
type PathResolver func(*cpb.CorpusPath) string

// DefaultResolvePath returns the default resolved path for the CorpusPath by
// joining its corpus, root, and path into a single filepath.
func DefaultResolvePath(cp *cpb.CorpusPath) string {
return filepath.Join(cp.GetCorpus(), cp.GetRoot(), cp.GetPath())
}

// A MultiFilePatcher provides an interface to patch sets of xref anchors to an
Expand Down Expand Up @@ -611,7 +625,7 @@ func (t *Table) CrossReferences(ctx context.Context, req *xpb.CrossReferencesReq
return nil, err
}

filter, err := compileCorpusPathFilters(req.GetCorpusPathFilters())
filter, err := compileCorpusPathFilters(req.GetCorpusPathFilters(), t.ResolvePath)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid corpus_path_filters %s: %v", strings.ReplaceAll(req.GetCorpusPathFilters().String(), "\n", " "), err)
}
Expand Down
23 changes: 18 additions & 5 deletions kythe/go/serving/xrefs/xrefs_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,16 @@ import (
xpb "kythe.io/kythe/proto/xref_go_proto"
)

func compileCorpusPathFilters(fs *xpb.CorpusPathFilters) (*corpusPathFilter, error) {
func compileCorpusPathFilters(fs *xpb.CorpusPathFilters, pr PathResolver) (*corpusPathFilter, error) {
if len(fs.GetFilter()) == 0 {
return nil, nil
}
if pr == nil {
pr = DefaultResolvePath
}
f := &corpusPathFilter{}
for _, filter := range fs.GetFilter() {
p, err := compileCorpusPathFilter(filter)
p, err := compileCorpusPathFilter(filter, pr)
if err != nil {
return nil, err
}
Expand All @@ -41,8 +44,8 @@ func compileCorpusPathFilters(fs *xpb.CorpusPathFilters) (*corpusPathFilter, err
return f, nil
}

func compileCorpusPathFilter(f *xpb.CorpusPathFilter) (*corpusPathPattern, error) {
p := &corpusPathPattern{}
func compileCorpusPathFilter(f *xpb.CorpusPathFilter, pr PathResolver) (*corpusPathPattern, error) {
p := &corpusPathPattern{pathResolver: pr}
if f.GetType() == xpb.CorpusPathFilter_EXCLUDE {
p.inverse = true
}
Expand All @@ -65,19 +68,29 @@ func compileCorpusPathFilter(f *xpb.CorpusPathFilter) (*corpusPathPattern, error
return nil, err
}
}
if resolvedPath := f.GetResolvedPath(); resolvedPath != "" {
p.resolvedPath, err = regexp.Compile(resolvedPath)
if err != nil {
return nil, err
}
}
return p, nil
}

type corpusPathPattern struct {
corpus, root, path *regexp.Regexp

pathResolver PathResolver
resolvedPath *regexp.Regexp

inverse bool
}

func (p *corpusPathPattern) Allow(c *cpb.CorpusPath) bool {
return p.inverse != ((p.corpus == nil || p.corpus.MatchString(c.GetCorpus())) &&
(p.root == nil || p.root.MatchString(c.GetRoot())) &&
(p.path == nil || p.path.MatchString(c.GetPath())))
(p.path == nil || p.path.MatchString(c.GetPath())) &&
(p.resolvedPath == nil || p.resolvedPath.MatchString(p.pathResolver(c))))
}

type corpusPathFilter struct {
Expand Down
5 changes: 4 additions & 1 deletion kythe/go/serving/xrefs/xrefs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2639,11 +2639,14 @@ func TestCorpusPathFilters(t *testing.T) {
{mustParseFilters(`filter: { type: EXCLUDE root: ".+" } filter: { type: INCLUDE_ONLY corpus: "^kythe3"}`),
[]string{cps("kythe3", "", "any/path"), cps("kythe3//branch", "", "some/path")},
[]string{cps("kythe3", "genfiles", "any/path"), cps("kythe3//branch", "bin", "some/path")}},
{mustParseFilters(`filter: { type: INCLUDE_ONLY resolved_path: "^kythe3/branch/genfiles/"}`),
[]string{cps("kythe3//branch", "genfiles", "any/path"), cps("kythe3//branch", "genfiles/more", "any/path")},
[]string{cps("kythe3", "bin", "any/path"), cps("kythe3", "genfiles", "some/path")}},
}

for i, test := range tests {
t.Run(strconv.Itoa(i), func(t *testing.T) {
f, err := compileCorpusPathFilters(test.filters)
f, err := compileCorpusPathFilters(test.filters, nil)
testutil.Fatalf(t, "Error: %v", err)

for _, include := range test.includes {
Expand Down
4 changes: 4 additions & 0 deletions kythe/proto/xref.proto
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,10 @@ message CorpusPathFilter {
string root = 3;
// Path pattern to match against.
string path = 4;

// Fully resolved path pattern to match against. The resolved path is
// determined by the server implementation.
string resolved_path = 5;
}

// TODO(schroederc): eliminate duplicate serving.ExpandedAnchor message
Expand Down

0 comments on commit 76ca533

Please sign in to comment.