hcl: Simplify the text DiagnosticWriter using new Range functions
Now that we have helper methods for computing relationships between ranges, we can eliminate all of the tricky line-counting and byte-counting code here and instead use the higher-level operations. The result is a single loop using the RangeScanner.
This commit is contained in:
parent
368a3f81c0
commit
14cfe59a52
@ -2,7 +2,6 @@ package hcl
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -70,21 +69,15 @@ func (w *diagnosticTextWriter) WriteDiagnostic(diag *Diagnostic) error {
|
|||||||
if diag.Subject != nil {
|
if diag.Subject != nil {
|
||||||
|
|
||||||
file := w.files[diag.Subject.Filename]
|
file := w.files[diag.Subject.Filename]
|
||||||
if file == nil || file.Bytes == nil {
|
if file == nil || file.Bytes == nil || diag.Subject.Empty() {
|
||||||
fmt.Fprintf(w.wr, " on %s line %d:\n (source code not available)\n\n", diag.Subject.Filename, diag.Subject.Start.Line)
|
fmt.Fprintf(w.wr, " on %s line %d:\n (source code not available)\n\n", diag.Subject.Filename, diag.Subject.Start.Line)
|
||||||
} else {
|
} else {
|
||||||
src := file.Bytes
|
snipRange := *diag.Subject
|
||||||
r := bytes.NewReader(src)
|
|
||||||
sc := bufio.NewScanner(r)
|
|
||||||
sc.Split(bufio.ScanLines)
|
|
||||||
|
|
||||||
var startLine, endLine int
|
|
||||||
if diag.Context != nil {
|
if diag.Context != nil {
|
||||||
startLine = diag.Context.Start.Line
|
// Show enough of the source code to include both the subject
|
||||||
endLine = diag.Context.End.Line
|
// and context ranges, which overlap in all reasonable
|
||||||
} else {
|
// situations.
|
||||||
startLine = diag.Subject.Start.Line
|
snipRange = RangeOver(snipRange, *diag.Context)
|
||||||
endLine = diag.Subject.End.Line
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var contextLine string
|
var contextLine string
|
||||||
@ -95,35 +88,18 @@ func (w *diagnosticTextWriter) WriteDiagnostic(diag *Diagnostic) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li := 1
|
|
||||||
var ls string
|
|
||||||
for sc.Scan() {
|
|
||||||
ls = sc.Text()
|
|
||||||
|
|
||||||
if li == startLine {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
li++
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(w.wr, " on %s line %d%s:\n", diag.Subject.Filename, diag.Subject.Start.Line, contextLine)
|
fmt.Fprintf(w.wr, " on %s line %d%s:\n", diag.Subject.Filename, diag.Subject.Start.Line, contextLine)
|
||||||
|
|
||||||
// TODO: Generate markers for the specific characters that are in the Context and Subject ranges.
|
src := file.Bytes
|
||||||
// For now, we just print out the lines.
|
sc := NewRangeScanner(src, diag.Subject.Filename, bufio.ScanLines)
|
||||||
|
|
||||||
fmt.Fprintf(w.wr, "%4d: %s\n", li, ls)
|
|
||||||
|
|
||||||
if endLine > li {
|
|
||||||
for sc.Scan() {
|
for sc.Scan() {
|
||||||
ls = sc.Text()
|
lineRange := sc.Range()
|
||||||
li++
|
if !lineRange.Overlaps(snipRange) {
|
||||||
|
continue
|
||||||
fmt.Fprintf(w.wr, "%4d: %s\n", li, ls)
|
|
||||||
|
|
||||||
if li == endLine {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(w.wr, "%4d: %s\n", lineRange.Start.Line, sc.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
w.wr.Write([]byte{'\n'})
|
w.wr.Write([]byte{'\n'})
|
||||||
|
@ -45,10 +45,12 @@ All splines must be pre-reticulated.
|
|||||||
Detail: `"baz" is not a supported top-level attribute. Did you mean "bam"?`,
|
Detail: `"baz" is not a supported top-level attribute. Did you mean "bam"?`,
|
||||||
Subject: &Range{
|
Subject: &Range{
|
||||||
Start: Pos{
|
Start: Pos{
|
||||||
|
Byte: 16,
|
||||||
Column: 1,
|
Column: 1,
|
||||||
Line: 3,
|
Line: 3,
|
||||||
},
|
},
|
||||||
End: Pos{
|
End: Pos{
|
||||||
|
Byte: 19,
|
||||||
Column: 4,
|
Column: 4,
|
||||||
Line: 3,
|
Line: 3,
|
||||||
},
|
},
|
||||||
@ -71,10 +73,12 @@ attribute. Did you mean "bam"?
|
|||||||
Detail: `"pizza" is not a supported attribute. Did you mean "pizzetta"?`,
|
Detail: `"pizza" is not a supported attribute. Did you mean "pizzetta"?`,
|
||||||
Subject: &Range{
|
Subject: &Range{
|
||||||
Start: Pos{
|
Start: Pos{
|
||||||
|
Byte: 42,
|
||||||
Column: 3,
|
Column: 3,
|
||||||
Line: 5,
|
Line: 5,
|
||||||
},
|
},
|
||||||
End: Pos{
|
End: Pos{
|
||||||
|
Byte: 47,
|
||||||
Column: 8,
|
Column: 8,
|
||||||
Line: 5,
|
Line: 5,
|
||||||
},
|
},
|
||||||
@ -83,10 +87,12 @@ attribute. Did you mean "bam"?
|
|||||||
// whether we're able to show a multi-line context when needed.
|
// whether we're able to show a multi-line context when needed.
|
||||||
Context: &Range{
|
Context: &Range{
|
||||||
Start: Pos{
|
Start: Pos{
|
||||||
|
Byte: 24,
|
||||||
Column: 1,
|
Column: 1,
|
||||||
Line: 4,
|
Line: 4,
|
||||||
},
|
},
|
||||||
End: Pos{
|
End: Pos{
|
||||||
|
Byte: 60,
|
||||||
Column: 2,
|
Column: 2,
|
||||||
Line: 6,
|
Line: 6,
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user