Extract files for error locations

Co-authored-by: Chris Smowton <smowton@github.com>
This commit is contained in:
Sauyon Lee
2021-03-31 00:03:32 -07:00
parent 7e3e2f9adf
commit cd6fb7d699
3 changed files with 43 additions and 12 deletions

View File

@@ -236,6 +236,11 @@ type FileInfo struct {
NextErr int
}
func (extraction *Extraction) SeenFile(path string) bool {
_, ok := extraction.FileInfo[path]
return ok
}
func (extraction *Extraction) GetFileInfo(path string) *FileInfo {
if fileInfo, ok := extraction.FileInfo[path]; ok {
return fileInfo
@@ -487,13 +492,15 @@ func (extraction *Extraction) extractError(tw *trap.Writer, err packages.Error,
}
transformed := filepath.ToSlash(srcarchive.TransformPath(ffile))
extraction.extractFileInfo(tw, ffile)
extraction.Lock.Lock()
diagLbl := extraction.StatWriter.Labeler.FreshID()
dbscheme.DiagnosticsTable.Emit(extraction.StatWriter, diagLbl, 1, tag, err.Msg, err.Msg,
emitLocation(
extraction.StatWriter, extraction.StatWriter.Labeler.GlobalID(ffile+";sourcefile"),
line, col, line, col,
))
flbl := extraction.StatWriter.Labeler.FileLabelFor(ffile)
dbscheme.DiagnosticsTable.Emit(
extraction.StatWriter, diagLbl, 1, tag, err.Msg, err.Msg,
emitLocation(extraction.StatWriter, flbl, line, col, line, col))
dbscheme.DiagnosticForTable.Emit(extraction.StatWriter, diagLbl, extraction.Label, extraction.GetFileIdx(transformed), extraction.GetNextErr(transformed))
extraction.Lock.Unlock()
dbscheme.ErrorsTable.Emit(tw, lbl, kind, err.Msg, pos, transformed, line, col, pkglbl, idx)
@@ -585,6 +592,16 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string) {
components := strings.Split(path, "/")
parentPath := ""
var parentLbl trap.Label
// We may visit the same file twice because `extractError` calls this function to describe files containing
// compilation errors. It is also called for user source files being extracted.
extraction.Lock.Lock()
if extraction.SeenFile(path) {
extraction.Lock.Unlock()
return
}
extraction.Lock.Unlock()
for i, component := range components {
if i == 0 {
if component == "" {
@@ -597,12 +614,13 @@ func (extraction *Extraction) extractFileInfo(tw *trap.Writer, file string) {
}
if i == len(components)-1 {
stem, ext := stemAndExt(component)
lbl := tw.Labeler.FileLabel()
lbl := tw.Labeler.FileLabelFor(path)
dbscheme.FilesTable.Emit(tw, lbl, path, stem, ext, 0)
dbscheme.ContainerParentTable.Emit(tw, parentLbl, lbl)
extractLocation(tw, lbl, 0, 0, 0, 0)
dbscheme.HasLocationTable.Emit(tw, lbl, emitLocation(tw, lbl, 0, 0, 0, 0))
extraction.Lock.Lock()
dbscheme.CompilationCompilingFilesTable.Emit(extraction.StatWriter, extraction.Label, extraction.GetFileIdx(path), extraction.StatWriter.Labeler.FileLabelFor(tw))
slbl := extraction.StatWriter.Labeler.FileLabelFor(path)
dbscheme.CompilationCompilingFilesTable.Emit(extraction.StatWriter, extraction.Label, extraction.GetFileIdx(path), slbl)
extraction.Lock.Unlock()
break
}

View File

@@ -62,7 +62,7 @@ func (l *Labeler) GlobalID(key string) Label {
return label
}
// FileLabel returns the label for the file with which the trap writer is associated
// FileLabel returns the label for a file with path `path`.
func (l *Labeler) FileLabel() Label {
if l.fileLabel == InvalidLabel {
l.fileLabel = l.GlobalID(l.tw.path + ";sourcefile")
@@ -71,8 +71,8 @@ func (l *Labeler) FileLabel() Label {
}
// FileLabelFor returns the label for the file for which the trap writer `tw` is associated
func (l *Labeler) FileLabelFor(tw *Writer) Label {
return l.GlobalID(tw.path + ";sourcefile")
func (l *Labeler) FileLabelFor(path string) Label {
return l.GlobalID(path + ";sourcefile")
}
// LocalID associates a label with the given AST node `nd` and returns it

View File

@@ -180,9 +180,22 @@ class Folder extends Container, @folder {
/** A file. */
class File extends Container, @file, Documentable, ExprParent, GoModExprParent, DeclParent,
ScopeNode {
string path;
File() {
files(this, path, _, _, _) and
(
// Exclude `.go` files that have not been extracted. Non-extracted files only exist in the `files`
// table if we are reporting compilation errors relating to them in the `diagnostics` table.
not path.matches("%.go")
or
exists(this.getAChild())
)
}
override Location getLocation() { has_location(this, result) }
override string getAbsolutePath() { files(this, result, _, _, _) }
override string getAbsolutePath() { result = path }
/** Gets the number of lines in this file. */
int getNumberOfLines() { numlines(this, result, _, _) }