Commit 0da5fa01 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 79928d00
...@@ -494,6 +494,7 @@ func (s StrSet) Itemv() []string { ...@@ -494,6 +494,7 @@ func (s StrSet) Itemv() []string {
return itemv return itemv
} }
/*
// findPackageNoZTrace is (*build.Context).Import but filters-out ztrace* files from found package // findPackageNoZTrace is (*build.Context).Import but filters-out ztrace* files from found package
// //
// we don't load what should be generated by us for 2 reasons: // we don't load what should be generated by us for 2 reasons:
...@@ -528,6 +529,7 @@ func findPackageNoZTrace(ctxt *build.Context, importPath, fromDir string, mode b ...@@ -528,6 +529,7 @@ func findPackageNoZTrace(ctxt *build.Context, importPath, fromDir string, mode b
return bp, err return bp, err
} }
*/
// tracegen generates code according to tracing directives in a package @ pkgpath // tracegen generates code according to tracing directives in a package @ pkgpath
// //
...@@ -536,12 +538,36 @@ func findPackageNoZTrace(ctxt *build.Context, importPath, fromDir string, mode b ...@@ -536,12 +538,36 @@ func findPackageNoZTrace(ctxt *build.Context, importPath, fromDir string, mode b
func tracegen(pkgpath string, ctxt *build.Context, cwd string) error { func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
// TODO test-only with .TestGoFiles .XTestGoFiles // TODO test-only with .TestGoFiles .XTestGoFiles
// filter-out ztrace* files when disovering packages
//
// we don't load what should be generated by us for 2 reasons:
// - code generated could be wrong with older version of the
// tool - it should not prevent from regenerating.
// - generated code imports packages which might be not there
// yet in gopath (lab.nexedi.com/kirr/go123/tracing)
ctxtReadDir := ctxt.ReadDir
if ctxtReadDir == nil {
ctxtReadDir = ioutil.ReadDir
}
ctxtNoZTrace := *ctxt
ctxtNoZTrace.ReadDir = func(dir string) ([]os.FileInfo, error) {
fv, err := ctxtReadDir(dir)
okv := fv[:0]
for _, f := range fv {
if !strings.HasPrefix(f.Name(), "ztrace") {
okv = append(okv, f)
}
}
return okv, err
}
// XXX text
conf := loader.Config{ conf := loader.Config{
ParserMode: parser.ParseComments, ParserMode: parser.ParseComments,
TypeCheckFuncBodies: func(path string) bool { return false }, TypeCheckFuncBodies: func(path string) bool { return false },
Build: ctxt, Build: &ctxtNoZTrace,
Cwd: cwd, Cwd: cwd,
FindPackage: findPackageNoZTrace, // FindPackage: findPackageNoZTrace,
} }
conf.Import(pkgpath) conf.Import(pkgpath)
...@@ -570,76 +596,85 @@ func tracegen(pkgpath string, ctxt *build.Context, cwd string) error { ...@@ -570,76 +596,85 @@ func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
return err // XXX err ctx return err // XXX err ctx
} }
// prologue // write ztrace.go with code generated for trace events and imports
prologue := &Buffer{} ztrace_go := filepath.Join(pkgdir, "ztrace.go")
prologue.WriteString(magic) if len(tpkg.Eventv) == 0 && len(tpkg.Importv) == 0 {
prologue.emit("\npackage %v", tpkg.Pkgi.Pkg.Name()) err = removeFile(ztrace_go)
prologue.emit("// code generated for tracepoints")
prologue.emit("\nimport (")
prologue.emit("\t%q", "lab.nexedi.com/kirr/neo/go/xcommon/tracing")
prologue.emit("\t%q", "unsafe")
// import of all packages needed for used types will go here in the end
needPkg := StrSet{}
// code for trace:event definitions
text := &Buffer{}
for _, event := range tpkg.Eventv {
needPkg.Add(event.NeedPkgv()...)
err = traceEventCodeTmpl.Execute(text, event)
if err != nil { if err != nil {
panic(err) // XXX return err
}
} else {
// prologue
prologue := &Buffer{}
prologue.WriteString(magic)
prologue.emit("\npackage %v", tpkg.Pkgi.Pkg.Name())
prologue.emit("// code generated for tracepoints")
prologue.emit("\nimport (")
prologue.emit("\t%q", "lab.nexedi.com/kirr/neo/go/xcommon/tracing")
prologue.emit("\t%q", "unsafe")
// import of all packages needed for used types will go here in the end
needPkg := StrSet{}
// code for trace:event definitions
text := &Buffer{}
for _, event := range tpkg.Eventv {
needPkg.Add(event.NeedPkgv()...)
err = traceEventCodeTmpl.Execute(text, event)
if err != nil {
panic(err) // XXX
}
} }
}
// TODO export hash
// code for trace:import imports // TODO export hash
for _, timport := range tpkg.Importv {
text.emit("\n// traceimport: %v", timport.PkgPath)
impPkgi := lprog.Package(timport.PkgPath) // code for trace:import imports
if impPkgi == nil { for _, timport := range tpkg.Importv {
// TODO do not require vvv text.emit("\n// traceimport: %v", timport.PkgPath)
return fmt.Errorf("%v: package %s must be also regularly imported", timport.Pos, timport.PkgPath)
}
impPkg, err := packageTrace(lprog, impPkgi) impPkgi := lprog.Package(timport.PkgPath)
if err != nil { if impPkgi == nil {
return err // XXX err ctx // TODO do not require vvv
} return fmt.Errorf("%v: package %s must be also regularly imported", timport.Pos, timport.PkgPath)
}
for _, event := range impPkg.Eventv { impPkg, err := packageTrace(lprog, impPkgi)
needPkg.Add(event.NeedPkgv()...)
importedEvent := struct{
*traceEvent
ImporterPkg *types.Package
} {event, pkgi.Pkg }
err = traceEventImportTmpl.Execute(text, importedEvent)
if err != nil { if err != nil {
panic(err) // XXX return err // XXX err ctx
}
for _, event := range impPkg.Eventv {
needPkg.Add(event.NeedPkgv()...)
importedEvent := struct{
*traceEvent
ImporterPkg *types.Package
} {event, pkgi.Pkg }
err = traceEventImportTmpl.Execute(text, importedEvent)
if err != nil {
panic(err) // XXX
}
} }
} }
}
// TODO check export hash // TODO check export hash
// finish prologue with needed imports // finish prologue with needed imports
needPkg.Delete(pkgpath) // our pkg - no need to import needPkg.Delete(pkgpath) // our pkg - no need to import
needPkgv := needPkg.Itemv() needPkgv := needPkg.Itemv()
if len(needPkgv) > 0 { if len(needPkgv) > 0 {
prologue.emit("") prologue.emit("")
} }
for _, needpkg := range needPkgv { for _, needpkg := range needPkgv {
prologue.emit("\t%q", needpkg) prologue.emit("\t%q", needpkg)
} }
prologue.emit(")") prologue.emit(")")
// write output to ztrace.go // write output to ztrace.go
fulltext := append(prologue.Bytes(), text.Bytes()...) fulltext := append(prologue.Bytes(), text.Bytes()...)
err = writeFile(filepath.Join(pkgdir, "ztrace.go"), fulltext) err = writeFile(ztrace_go, fulltext)
if err != nil { if err != nil {
return err return err
}
} }
// write empty ztrace.s so go:linkname works, if there are trace imports // write empty ztrace.s so go:linkname works, if there are trace imports
...@@ -647,7 +682,7 @@ func tracegen(pkgpath string, ctxt *build.Context, cwd string) error { ...@@ -647,7 +682,7 @@ func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
if len(tpkg.Importv) == 0 { if len(tpkg.Importv) == 0 {
err = removeFile(ztrace_s) err = removeFile(ztrace_s)
} else { } else {
text.Reset() text := &Buffer{}
text.WriteString(magic) text.WriteString(magic)
text.emit("// empty .s so `go build` does not use -complete for go:linkname to work") text.emit("// empty .s so `go build` does not use -complete for go:linkname to work")
......
...@@ -136,7 +136,8 @@ func TestGoTraceGen(t *testing.T) { ...@@ -136,7 +136,8 @@ func TestGoTraceGen(t *testing.T) {
} }
// XXX autodetect (go list ?) // XXX autodetect (go list ?)
testv := []string{"a/pkg1", "b/pkg2", "c/pkg3"} //testv := []string{"a/pkg1", "b/pkg2", "c/pkg3", "d/pkg4"}
testv := []string{"a/pkg1"}
for _, tpkg := range testv { for _, tpkg := range testv {
err = tracegen(tpkg, tBuildCtx, "" /* = local imorts disabled */) err = tracegen(tpkg, tBuildCtx, "" /* = local imorts disabled */)
......
// Code generated by lab.nexedi.com/kirr/go123/tracing/cmd/gotrace; DO NOT EDIT. // Code generated by lab.nexedi.com/kirr/go123/tracing/cmd/gotrace; DO NOT EDIT.
package pkg1
import (
"non-existent"
)
Bad bad bad - I'm invalid go file. Bad bad bad - I'm invalid go file.
package pkg4
// this package does not use tracepoints at all
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment