lang: ast: Provide better error reporting for scope errors

Print these file and line numbers when we can!
This commit is contained in:
James Shubin
2025-06-05 23:00:56 -04:00
parent 75bafa4fd3
commit dcd4f0709f
2 changed files with 23 additions and 5 deletions

View File

@@ -6828,7 +6828,8 @@ func (obj *StmtInclude) SetScope(scope *interfaces.Scope) error {
stmt, exists := scope.Classes[obj.Name]
if !exists {
return fmt.Errorf("class `%s` does not exist in this scope", obj.Name)
err := fmt.Errorf("class `%s` does not exist in this scope", obj.Name)
return highlightHelper(obj, obj.data.Logf, err)
}
class, ok := stmt.(*StmtClass)
if !ok {
@@ -10468,7 +10469,8 @@ func (obj *ExprCall) SetScope(scope *interfaces.Scope, sctx map[string]interface
if obj.data.Debug || true { // TODO: leave this on permanently?
lambdaScopeFeedback(obj.scope, obj.data.Logf)
}
return fmt.Errorf("lambda `$%s` does not exist in this scope", prefixedName)
err := fmt.Errorf("lambda `$%s` does not exist in this scope", prefixedName)
return highlightHelper(obj, obj.data.Logf, err)
}
target = f
}
@@ -10484,7 +10486,8 @@ func (obj *ExprCall) SetScope(scope *interfaces.Scope, sctx map[string]interface
if obj.data.Debug || true { // TODO: leave this on permanently?
functionScopeFeedback(obj.scope, obj.data.Logf)
}
return fmt.Errorf("func `%s` does not exist in this scope", prefixedName)
err := fmt.Errorf("func `%s` does not exist in this scope", prefixedName)
return highlightHelper(obj, obj.data.Logf, err)
}
target = f
}
@@ -11232,7 +11235,8 @@ func (obj *ExprVar) SetScope(scope *interfaces.Scope, sctx map[string]interfaces
if obj.data.Debug || true { // TODO: leave this on permanently?
variableScopeFeedback(obj.scope, obj.data.Logf)
}
return fmt.Errorf("var `$%s` does not exist in this scope", obj.Name)
err := fmt.Errorf("var `$%s` does not exist in this scope", obj.Name)
return highlightHelper(obj, obj.data.Logf, err)
}
obj.scope.Variables[obj.Name] = target
@@ -11292,7 +11296,8 @@ func (obj *ExprVar) Infer() (*types.Type, []*interfaces.UnificationInvariant, er
// lookup value from scope
expr, exists := obj.scope.Variables[obj.Name]
if !exists {
return nil, nil, fmt.Errorf("var `%s` does not exist in this scope", obj.Name)
err := fmt.Errorf("var `%s` does not exist in this scope", obj.Name)
return nil, nil, highlightHelper(obj, obj.data.Logf, err)
}
// This child call to Infer is an outlier to the common pattern where

View File

@@ -562,6 +562,19 @@ func lambdaScopeFeedback(scope *interfaces.Scope, logf func(format string, v ...
}
}
// highlightHelper give the user better file/line number feedback.
func highlightHelper(node interfaces.Node, logf func(format string, v ...interface{}), err error) error {
displayer, ok := node.(interfaces.TextDisplayer)
if ok {
if highlight := displayer.HighlightText(); highlight != "" {
logf("%s: %s", err.Error(), highlight)
}
//return fmt.Errorf("%s: %s", err.Error(), displayer.Byline())
}
return err
}
// Textarea stores the coordinates of a statement or expression in the form of a
// starting line/column and ending line/column.
type Textarea struct {