object88 / langd

A Language Server Protocol implementation in Go for Go
MIT License
7 stars 0 forks source link

Test: ensure that changing an exposed func raises errors #31

Closed object88 closed 6 years ago

object88 commented 6 years ago

Test scenario:

Open a workspace that has two packages, one of which consumes an export from the other. Change the exported ident to another name, such that the workspace should not compile correctly. Verify that the Errors function lists type checker errors.

object88 commented 6 years ago

Problem is reproducible:

src1 := `package foo
    var Foof int = 1`

src2 := `package bar
    import "../foo"
    func IncFoof() int {
        foo.Foof++
        return foo.Foof
    }`

packages := map[string]map[string]string{
    "foo": map[string]string{
        "foo.go": src1,
    },
    "bar": map[string]string{
        "bar.go": src2,
    },
}

w := workspaceSetup(t, "/go/src/bar", packages, false)
done := w.Loader.Start()

w.OpenFile("/go/src/foo/foo.go", src1)
<-done

w.ChangeFile("/go/src/foo/foo.go", 1, 5, 1, 9, "FOOF")
<-done

errCount := 0
w.Loader.Errors(func(file string, errs []FileError) {
    errCount += len(errs)
})

if errCount == 0 {
    t.Errorf("Did not get any errors")
}
object88 commented 6 years ago

Need to find a way to cleanly re-trigger the type checking without rebuilding the AST, for packages which consume the changed package. May want to consider breaking ProcessStateChange into finer-grained increments, or marking individual files as changed and reprocessing the ASTs conditionally.

object88 commented 6 years ago

Also need to test scenario where exported identifier is indirectly used. Something like...

package foo
type Foo struct {}
func (f *Foo) Add() int { return 0 }
package bar
import "foo"
type Bar struct {
    F *Foo
}
package baz
import "bar"
func Do(b *Bar) {
    x := b.F.Add()
}

If Foo#Add is renamed, there should be an error in baz.

object88 commented 6 years ago

Work started in the package_errors branch. For a complete solution, we need to first understand how exports from a package are indirectly imported. Implementing a references request will help with this task.

object88 commented 6 years ago

Done with #38