Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] Load type infos correctly #11

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ require (
github.com/fatih/color v1.15.0
github.com/hexops/gotextdiff v1.0.3
github.com/stretchr/testify v1.8.2
golang.org/x/tools v0.8.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/sys v0.7.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 9 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSo
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand All @@ -19,9 +19,15 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
2 changes: 1 addition & 1 deletion internal/fsrepository/fsrepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func (r *FSRepository) ListGoSourceFiles() []*gosourcefile.GoSourceFile {
for i, path := range paths {
data, _ := os.ReadFile(path)
relativePath, _ := filepath.Rel(r.root, path)
sourceFiles[i] = gosourcefile.New(relativePath, data)
sourceFiles[i] = gosourcefile.New(r.root, relativePath, data)
}

return sourceFiles
Expand Down
24 changes: 12 additions & 12 deletions internal/fsrepository/fsrepository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func TestFSRepository_ListGoSourceFiles(t *testing.T) {
repository := fsrepository.New(dir)
files := repository.ListGoSourceFiles()
assert.Equal(t, []*gosourcefile.GoSourceFile{
gosourcefile.New("source.go", []byte("source data")),
gosourcefile.New(dir, "source.go", []byte("source data")),
}, files)
})

Expand All @@ -55,9 +55,9 @@ func TestFSRepository_ListGoSourceFiles(t *testing.T) {
repository := fsrepository.New(dir)
files := repository.ListGoSourceFiles()
assert.Equal(t, []*gosourcefile.GoSourceFile{
gosourcefile.New("source1.go", []byte("source data 1")),
gosourcefile.New("source2.go", []byte("source data 2")),
gosourcefile.New("source3.go", []byte("source data 3")),
gosourcefile.New(dir, "source1.go", []byte("source data 1")),
gosourcefile.New(dir, "source2.go", []byte("source data 2")),
gosourcefile.New(dir, "source3.go", []byte("source data 3")),
}, files)
})

Expand All @@ -69,7 +69,7 @@ func TestFSRepository_ListGoSourceFiles(t *testing.T) {
repository := fsrepository.New(dir)
files := repository.ListGoSourceFiles()
assert.Equal(t, []*gosourcefile.GoSourceFile{
gosourcefile.New("source1.go", []byte("source data 1")),
gosourcefile.New(dir, "source1.go", []byte("source data 1")),
}, files)
})

Expand All @@ -81,7 +81,7 @@ func TestFSRepository_ListGoSourceFiles(t *testing.T) {
repository := fsrepository.New(dir)
files := repository.ListGoSourceFiles()
assert.Equal(t, []*gosourcefile.GoSourceFile{
gosourcefile.New("source1.go", []byte("source data 1")),
gosourcefile.New(dir, "source1.go", []byte("source data 1")),
}, files)
})

Expand All @@ -95,9 +95,9 @@ func TestFSRepository_ListGoSourceFiles(t *testing.T) {
repository := fsrepository.New(dir)
files := repository.ListGoSourceFiles()
assert.Equal(t, []*gosourcefile.GoSourceFile{
gosourcefile.New("a/b/source3.go", []byte("source data 3")),
gosourcefile.New("a/source2.go", []byte("source data 2")),
gosourcefile.New("source1.go", []byte("source data 1")),
gosourcefile.New(dir, "a/b/source3.go", []byte("source data 3")),
gosourcefile.New(dir, "a/source2.go", []byte("source data 2")),
gosourcefile.New(dir, "source1.go", []byte("source data 1")),
}, files)
})

Expand All @@ -116,9 +116,9 @@ func TestFSRepository_ListGoSourceFiles(t *testing.T) {
repository := fsrepository.New(dir)
files := repository.ListGoSourceFiles()
assert.Equal(t, []*gosourcefile.GoSourceFile{
gosourcefile.New("a/b/source3.go", []byte("source data 3")),
gosourcefile.New("a/source2.go", []byte("source data 2")),
gosourcefile.New("source1.go", []byte("source data 1")),
gosourcefile.New(dir, "a/b/source3.go", []byte("source data 3")),
gosourcefile.New(dir, "a/source2.go", []byte("source data 2")),
gosourcefile.New(dir, "source1.go", []byte("source data 1")),
}, files)
})
}
Expand Down
60 changes: 49 additions & 11 deletions internal/gosourcefile/gosourcefile.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,58 @@
package gosourcefile

import (
"fmt"
"go/ast"
"go/parser"
"go/token"
"go/types"
"path"

"github.com/gtramontina/ooze/internal/goinfectedfile"
"github.com/gtramontina/ooze/viruses"
"golang.org/x/tools/go/packages"
)

type GoSourceFile struct {
root string
relativePath string
rawContent []byte
pkg *packages.Package
typeInfo *types.Info
}

func New(relativePath string, rawContent []byte) *GoSourceFile {
return &GoSourceFile{
func New(root string, relativePath string, rawContent []byte) *GoSourceFile {
return &GoSourceFile{ //nolint:exhaustruct // rest will be filled later
root: root,
relativePath: relativePath,
rawContent: rawContent,
}
}

func (f *GoSourceFile) Incubate(virus viruses.Virus) []*goinfectedfile.GoInfectedFile {
fileSet := token.NewFileSet()
f.loadTypeInfo()

fileTree, err := parser.ParseFile(fileSet, f.relativePath, f.rawContent, parser.ParseComments|parser.AllErrors)
if err != nil {
panic(fmt.Errorf("failed parsing file '%s': %w", f.relativePath, err))
fullPath := path.Join(f.root, f.relativePath)

idx := -1

for i, path := range f.pkg.CompiledGoFiles {
if path == fullPath {
idx = i

break
}
}

if idx < 0 {
return nil
}
Comment on lines +44 to +46
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this ever happen? I'm thinking that if it ever happens, it means that something has actually gone wrong pretty badly, no? I'd consider blowing up with a panic here. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sounds good to me.


fileTree := f.pkg.Syntax[idx]

var infectedFiles []*goinfectedfile.GoInfectedFile

ast.Inspect(fileTree, func(node ast.Node) bool {
for _, infection := range virus.Incubate(node, nil) {
infectedFiles = append(infectedFiles, goinfectedfile.New(f.relativePath, f.rawContent, infection, fileSet, fileTree))
for _, infection := range virus.Incubate(node, f.typeInfo) {
file := goinfectedfile.New(f.relativePath, f.rawContent, infection, f.pkg.Fset, fileTree)
infectedFiles = append(infectedFiles, file)
}

return true
Expand All @@ -43,6 +61,26 @@ func (f *GoSourceFile) Incubate(virus viruses.Virus) []*goinfectedfile.GoInfecte
return infectedFiles
}

func (f *GoSourceFile) loadTypeInfo() {
if f.typeInfo != nil {
return
}

pkgCfg := &packages.Config{ //nolint:exhaustruct // rest of the defaults are fine
Dir: path.Join(f.root, path.Dir(f.relativePath)),
Mode: packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedCompiledGoFiles,
}

pkgs, err := packages.Load(pkgCfg, ".")
if err != nil {
panic(err)
}

f.pkg = pkgs[0]

f.typeInfo = pkgs[0].TypesInfo
}

func (f *GoSourceFile) String() string {
return f.relativePath
}
10 changes: 5 additions & 5 deletions internal/ignoredrepository/ignoredrepository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ func TestIgnoredRepository(t *testing.T) {
)

assert.Equal(t, []*gosourcefile.GoSourceFile{
gosourcefile.New("source1.go", []byte("source 1")),
gosourcefile.New("source3.go", []byte("source 3")),
gosourcefile.New("", "source1.go", []byte("source 1")),
gosourcefile.New("", "source3.go", []byte("source 3")),
}, repository.ListGoSourceFiles())
}

Expand All @@ -63,9 +63,9 @@ func TestIgnoredRepository(t *testing.T) {
)

assert.Equal(t, []*gosourcefile.GoSourceFile{
gosourcefile.New("dir/subdir/source4.go", []byte("source 4")),
gosourcefile.New("dir/subdir/source5.go", []byte("source 5")),
gosourcefile.New("source1.go", []byte("source 1")),
gosourcefile.New("", "dir/subdir/source4.go", []byte("source 4")),
gosourcefile.New("", "dir/subdir/source5.go", []byte("source 5")),
gosourcefile.New("", "source1.go", []byte("source 1")),
}, repository.ListGoSourceFiles())
}
})
Expand Down
28 changes: 16 additions & 12 deletions internal/ooze/ooze_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ import (
)

func TestOoze_nothing_to_test(t *testing.T) {
t.SkipNow()

source0 := oozetesting.Source(`
|package dummy
|`)

source1 := oozetesting.Source(`
|package source
|
|var text = "value"
|var _ = "value"
|`)

t.Run("no files", func(t *testing.T) {
Expand Down Expand Up @@ -81,59 +83,61 @@ type scenario struct {
}

func TestOoze_with_mutations(t *testing.T) {
t.SkipNow()

source2 := oozetesting.Source(`
|package source
|
|var number = 0
|var _ = 0
|`)

source2integerincrementMutation1 := gomutatedfile.New("Integer Increment", "source2.go", source2, oozetesting.Source(`
|package source
|
|var number = 1
|var _ = 1
|`),
)

source2integerdecrementMutation1 := gomutatedfile.New("Integer Decrement", "source2.go", source2, oozetesting.Source(`
|package source
|
|var number = -1
|var _ = -1
|`),
)

source3 := oozetesting.Source(`
|package source
|
|var number0 = 0
|var number1 = 1
|var _ = 0
|var _ = 1
|`)

source3integerincrementMutation1 := gomutatedfile.New("Integer Increment", "source3.go", source3, oozetesting.Source(`
|package source
|
|var number0 = 1
|var number1 = 1
|var _ = 1
|var _ = 1
|`),
)

source3integerincrementMutation2 := gomutatedfile.New("Integer Increment", "source3.go", source3, oozetesting.Source(`
|package source
|
|var number0 = 0
|var number1 = 2
|var _ = 0
|var _ = 2
|`),
)

source4 := oozetesting.Source(`
|package source
|
|var anotherNumber = 0
|var _ = 0
|`)

source4integerincrementMutation1 := gomutatedfile.New("Integer Increment", "source4.go", source4, oozetesting.Source(`
|package source
|
|var anotherNumber = 1
|var _ = 1
|`),
)

Expand Down
2 changes: 1 addition & 1 deletion internal/oozetesting/fakerepository/fakerepository.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (r *FakeRepository) ListGoSourceFiles() []*gosourcefile.GoSourceFile {

sources := make([]*gosourcefile.GoSourceFile, 0, len(filePaths))
for _, filePath := range filePaths {
sources = append(sources, gosourcefile.New(filePath, r.fs[filePath]))
sources = append(sources, gosourcefile.New("", filePath, r.fs[filePath]))
}

return sources
Expand Down
7 changes: 6 additions & 1 deletion oozetesting/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ func NewScenarios(virusName string, virus viruses.Virus, mutations Mutations) *S
func Run(t *testing.T, scenes *Scenarios) {
t.Helper()

workDir, err := os.Getwd()
if err != nil {
t.Fatal(err)
}

for name, testcase := range scenes.mutations {
source, err := os.ReadFile(path.Join("testdata", testcase.SourceFileName))
assert.NoError(t, err)
Expand All @@ -52,7 +57,7 @@ func Run(t *testing.T, scenes *Scenarios) {
t.Run(name, func(t *testing.T) {
actualMutatedFiles := mutate(
scenes.virus,
gosourcefile.New(testcase.SourceFileName, source),
gosourcefile.New(path.Join(workDir, "testdata"), testcase.SourceFileName, source),
)

require.Equal(t,
Expand Down
2 changes: 0 additions & 2 deletions viruses/arithmetic/testdata/source.0.go
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
//go:build testdata

package source
2 changes: 0 additions & 2 deletions viruses/arithmetic/testdata/source.1.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testdata

package source

func main() {
Expand Down
2 changes: 0 additions & 2 deletions viruses/arithmetic/testdata/source.2.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testdata

package source

func main() {
Expand Down
2 changes: 0 additions & 2 deletions viruses/arithmetic/testdata/source.3.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testdata

package source

func main() {
Expand Down
2 changes: 0 additions & 2 deletions viruses/arithmetic/testdata/source.4.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testdata

package source

func main() {
Expand Down
2 changes: 0 additions & 2 deletions viruses/arithmetic/testdata/source.5.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//go:build testdata

package source

func main() {
Expand Down
Loading