Skip to content

Commit

Permalink
checkpoint (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Roche committed Aug 6, 2020
1 parent 2fb4b63 commit d607749
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
38 changes: 38 additions & 0 deletions file.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ type File interface {
// File. Use Imports to obtain only direct dependencies.
TransitiveImports() []File

// UnusedImports returns all imported files that aren't used by the current
// File. Public imports are not included in this list.
UnusedImports() []File

// Dependents returns all files where the given file was directly or
// transitively imported.
Dependents() []File
Expand Down Expand Up @@ -125,6 +129,40 @@ func (f *file) TransitiveImports() []File {
return out
}

func (f *file) UnusedImports() []File {
public := make(map[int]struct{}, len(f.desc.PublicDependency))
for _, i := range f.desc.PublicDependency {
public[int(i)] = struct{}{}
}

mp := make(map[string]File, len(f.fileDependencies))
for i, fl := range f.fileDependencies {
if _, ok := public[i]; ok {
continue
}
mp[fl.Name().String()] = fl
}

for _, msg := range f.AllMessages() {
for _, imp := range msg.Imports() {
delete(mp, imp.Name().String())
}
}

for _, svc := range f.Services() {
for _, imp := range svc.Imports() {
delete(mp, imp.Name().String())
}
}

out := make([]File, 0, len(mp))
for _, fl := range mp {
out = append(out, fl)
}

return out
}

func (f *file) Dependents() []File {
if f.dependentsCache == nil {
set := make(map[string]File)
Expand Down
42 changes: 42 additions & 0 deletions file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,48 @@ func TestFile_TransitiveImports(t *testing.T) {
assert.Len(t, f.TransitiveImports(), 2)
}

func TestFile_UnusedImports(t *testing.T) {
t.Parallel()

target := &file{desc: &descriptor.FileDescriptorProto{
Name: proto.String("foobar"),
}}

unusedFile := &file{desc: &descriptor.FileDescriptorProto{
Name: proto.String("i/am/unused.proto"),
}}

target.addFileDependency(unusedFile)

publicFile := &file{desc: &descriptor.FileDescriptorProto{
Name: proto.String("i/am/public.proto"),
}}

target.addFileDependency(publicFile)
target.desc.PublicDependency = append(target.desc.PublicDependency, 1)

msgDep := dummyMsg()
usedFile := msgDep.File().(*file)

ft := &embedT{scalarT: &scalarT{}, msg: msgDep}
fld := &field{}
fld.addType(ft)
m := &msg{}
m.addField(fld)
target.addMessage(m)

mtd := &method{in: msgDep, out: m}
svc := &service{}
svc.addMethod(mtd)
target.addService(svc)

target.addFileDependency(usedFile)

unused := target.UnusedImports()
assert.Len(t, unused, 1)
assert.Equal(t, unusedFile, unused[0])
}

func TestFile_Dependents(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit d607749

Please sign in to comment.