go-jsonnet/linter/linter.go
Stanisław Barzowski 45f3912215 Make parser package internal
There is no reason for external users to directly depend
on parser. It had a few random things exported as well,
namely errors and "children" functions (helpers for AST
traversal).

It was easy to extract the errors package, but I needed to leave
children in parser for now. The errors package was also
made internal, but it's a candidate for making it public
again potentially (if someone wants to display error messages
just like us). For now it's probably too incomplete anyway.

This change has a potential of breaking the existing users
since we technically remove public APIs. These were not needed
or even helpful for actually running Jsonnet code, but perhaps
someone used them anyway.
2019-09-03 17:28:33 +02:00

56 lines
1.4 KiB
Go

// Package linter analyses Jsonnet code for code "smells".
package linter
import (
"io"
"github.com/google/go-jsonnet/ast"
"github.com/google/go-jsonnet/internal/errors"
)
// ErrorWriter encapsulates a writer and an error state indicating when at least
// one error has been written to the writer.
type ErrorWriter struct {
ErrorsFound bool
Writer io.Writer
}
func (e *ErrorWriter) writeError(err errors.StaticError) {
e.ErrorsFound = true
e.Writer.Write([]byte(err.Error() + "\n"))
}
type variable struct {
name ast.Identifier
declNode ast.Node
uses []ast.Node
param bool // TODO enum
}
// LintingInfo holds additional information about the program
// which was gathered during linting. The data should only be added to it.
// It is global, i.e. it holds the same data regardless of scope we're
// currently analyzing.
type LintingInfo struct {
variables []variable
}
// Lint analyses a node and reports any issues it encounters to an error writer.
func Lint(node ast.Node, e *ErrorWriter) {
lintingInfo := LintingInfo{
variables: nil,
}
std := variable{
name: "std",
declNode: nil,
uses: nil,
param: false,
}
findVariables(node, &lintingInfo, vScope{"std": &std})
for _, v := range lintingInfo.variables {
if len(v.uses) == 0 && !v.param {
e.writeError(errors.MakeStaticError("Unused variable: "+string(v.name), *v.declNode.Loc()))
}
}
}