Skip to content

Commit

Permalink
feat(analyzer): (attempt to) improve compiler errors
Browse files Browse the repository at this point in the history
  • Loading branch information
emil14 committed Oct 27, 2024
1 parent b221981 commit dd73124
Show file tree
Hide file tree
Showing 29 changed files with 363 additions and 422 deletions.
6 changes: 3 additions & 3 deletions cmd/lsp/server/get_file_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ func (s *Server) GetFileView(glspCtx *glsp.Context, req GetFileViewRequest) (Get

scope := src.Scope{
Location: src.Location{
ModRef: s.index.EntryModRef,
PkgName: pkgName,
FileName: fileName,
Module: s.index.EntryModRef,
Package: pkgName,
Filename: fileName,
},
Build: *s.index,
}
Expand Down
7 changes: 2 additions & 5 deletions examples/compare_values/main.neva
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
flow Main(start) (stop) {
Eq, Ternary, Println
Eq, Println
---
:start -> [
{ 2 -> eq:actual },
{ 2 -> eq:compared }
]
eq -> ternary:if
'They match' -> ternary:then
'They do not match' -> ternary:else
ternary -> println -> :stop
(eq ? 'They match' : 'They do not match') -> println -> :stop
}
11 changes: 5 additions & 6 deletions internal/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package builder

import (
"context"
"fmt"
"io/fs"
"os"
"path/filepath"
Expand Down Expand Up @@ -31,7 +30,7 @@ func (b Builder) Build(
entryMod, entryModRootPath, err := b.LoadModuleByPath(ctx, wd)
if err != nil {
return compiler.RawBuild{}, "", &compiler.Error{
Err: fmt.Errorf("build entry mod: %w", err),
Message: "build entry mod: " + err.Error(),
}
}

Expand All @@ -51,7 +50,7 @@ func (b Builder) Build(
stdMod, _, err := b.LoadModuleByPath(ctx, b.stdLibPath)
if err != nil {
return compiler.RawBuild{}, "", &compiler.Error{
Err: fmt.Errorf("build stdlib mod: %w", err),
Message: "build stdlib mod: " + err.Error(),
}
}

Expand All @@ -61,7 +60,7 @@ func (b Builder) Build(
release, err := acquireLockFile()
if err != nil {
return compiler.RawBuild{}, "", &compiler.Error{
Err: fmt.Errorf("failed to acquire lock file: %w", err),
Message: "failed to acquire lock file: " + err.Error(),
}
}
defer release()
Expand All @@ -78,14 +77,14 @@ func (b Builder) Build(
depWD, _, err := b.downloadDep(depModRef)
if err != nil {
return compiler.RawBuild{}, "", &compiler.Error{
Err: fmt.Errorf("download dep: %w", err),
Message: "download dep: " + err.Error(),
}
}

depMod, _, err := b.LoadModuleByPath(ctx, depWD)
if err != nil {
return compiler.RawBuild{}, "", &compiler.Error{
Err: fmt.Errorf("build dep mod: %w", err),
Message: "build dep mod: " + err.Error(),
}
}

Expand Down
52 changes: 24 additions & 28 deletions internal/compiler/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,21 @@ type Analyzer struct {

func (a Analyzer) AnalyzeExecutableBuild(build src.Build, mainPkgName string) (src.Build, *compiler.Error) {
location := src.Location{
ModRef: build.EntryModRef,
PkgName: mainPkgName,
Module: build.EntryModRef,
Package: mainPkgName,
}

entryMod, ok := build.Modules[build.EntryModRef]
if !ok {
return src.Build{}, &compiler.Error{
Err: fmt.Errorf("entry module not found: %s", build.EntryModRef),
Message: fmt.Sprintf("entry module not found: %s", build.EntryModRef),
Location: &location,
}
}

if _, ok := entryMod.Packages[mainPkgName]; !ok {
return src.Build{}, &compiler.Error{
Err: errors.New("main package not found"),
Message: "main package not found",
Location: &location,
}
}
Expand Down Expand Up @@ -89,17 +89,17 @@ func (a Analyzer) AnalyzeBuild(build src.Build) (src.Build, *compiler.Error) {
func (a Analyzer) analyzeModule(modRef src.ModuleRef, build src.Build) (map[string]src.Package, *compiler.Error) {
if modRef != build.EntryModRef && modRef.Version == "" {
return nil, &compiler.Error{
Err: errors.New("every dependency module must have version"),
Location: &src.Location{ModRef: modRef},
Message: "every dependency module must have version",
Location: &src.Location{Module: modRef},
}
}

location := src.Location{ModRef: modRef}
location := src.Location{Module: modRef}
mod := build.Modules[modRef]

if len(mod.Packages) == 0 {
return nil, &compiler.Error{
Err: errors.New("module must contain at least one package"),
Message: "module must contain at least one package",
Location: &location,
}
}
Expand All @@ -110,8 +110,8 @@ func (a Analyzer) analyzeModule(modRef src.ModuleRef, build src.Build) (map[stri
for pkgName, pkg := range pkgsCopy {
scope := src.Scope{
Location: src.Location{
ModRef: modRef,
PkgName: pkgName,
Module: modRef,
Package: pkgName,
},
Build: build,
}
Expand All @@ -120,7 +120,7 @@ func (a Analyzer) analyzeModule(modRef src.ModuleRef, build src.Build) (map[stri
if err != nil {
return nil, compiler.Error{
Location: &src.Location{
PkgName: pkgName,
Package: pkgName,
},
}.Wrap(err)
}
Expand All @@ -134,7 +134,7 @@ func (a Analyzer) analyzeModule(modRef src.ModuleRef, build src.Build) (map[stri
func (a Analyzer) analyzePkg(pkg src.Package, scope src.Scope) (src.Package, *compiler.Error) {
if len(pkg) == 0 {
return nil, &compiler.Error{
Err: errors.New("package must contain at least one file"),
Message: "package must contain at least one file",
Location: &scope.Location,
}
}
Expand All @@ -148,26 +148,22 @@ func (a Analyzer) analyzePkg(pkg src.Package, scope src.Scope) (src.Package, *co
}
}

if err := pkg.Entities(func(entity src.Entity, entityName, fileName string) error {
scopeWithFile := scope.WithLocation(src.Location{
FileName: fileName,
ModRef: scope.Location.ModRef,
PkgName: scope.Location.PkgName,
for result := range pkg.Entities() {
relocatedScope := scope.Relocate(src.Location{
Module: scope.Location.Module,
Package: scope.Location.Package,
Filename: result.FileName,
})

resolvedEntity, err := a.analyzeEntity(entity, scopeWithFile)
analyzedEntity, err := a.analyzeEntity(result.Entity, relocatedScope)
if err != nil {
return compiler.Error{
Location: &scopeWithFile.Location,
Meta: entity.Meta(),
return nil, compiler.Error{
Location: &relocatedScope.Location,
Meta: result.Entity.Meta(),
}.Wrap(err)
}

analyzedFiles[fileName].Entities[entityName] = resolvedEntity

return nil
}); err != nil {
return nil, err.(*compiler.Error) //nolint:forcetypeassert
analyzedFiles[result.FileName].Entities[result.EntityName] = analyzedEntity
}

return analyzedFiles, nil
Expand All @@ -179,7 +175,7 @@ func (a Analyzer) analyzeEntity(entity src.Entity, scope src.Scope) (src.Entity,
Kind: entity.Kind,
}

isStd := scope.Location.ModRef.Path == "std"
isStd := scope.Location.Module.Path == "std"

switch entity.Kind {
case src.TypeEntity:
Expand Down Expand Up @@ -226,7 +222,7 @@ func (a Analyzer) analyzeEntity(entity src.Entity, scope src.Scope) (src.Entity,
resolvedEntity.Component = analyzedComponent
default:
return src.Entity{}, &compiler.Error{
Err: fmt.Errorf("unknown entity kind: %v", entity.Kind),
Message: fmt.Sprintf("unknown entity kind: %v", entity.Kind),
Location: &scope.Location,
Meta: entity.Meta(),
}
Expand Down
9 changes: 4 additions & 5 deletions internal/compiler/analyzer/component.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package analyzer

import (
"errors"
"strings"

"github.com/nevalang/neva/internal/compiler"
Expand All @@ -16,7 +15,7 @@ func (a Analyzer) analyzeComponent(

if isRuntimeFunc && len(runtimeFuncArgs) == 0 {
return src.Component{}, &compiler.Error{
Err: errors.New("Flow that use #extern directive must provide at least one argument"),
Message: "Flow that use #extern directive must provide at least one argument",
Location: &scope.Location,
Meta: &component.Meta,
}
Expand All @@ -27,7 +26,7 @@ func (a Analyzer) analyzeComponent(
parts := strings.Split(runtimeFuncArg, " ")
if len(parts) != 2 {
return src.Component{}, &compiler.Error{
Err: errors.New("Component that use #extern with more than one argument must provide arguments in a form of <type, flow_ref> pairs"),
Message: "Component that use #extern with more than one argument must provide arguments in a form of <type, flow_ref> pairs",
Location: &scope.Location,
Meta: &component.Meta,
}
Expand All @@ -53,7 +52,7 @@ func (a Analyzer) analyzeComponent(
if isRuntimeFunc {
if len(component.Nodes) != 0 || len(component.Net) != 0 {
return src.Component{}, &compiler.Error{
Err: errors.New("Flow with nodes or network cannot use #extern directive"),
Message: "Component with nodes or network cannot use #extern directive",
Location: &scope.Location,
Meta: &component.Meta,
}
Expand All @@ -75,7 +74,7 @@ func (a Analyzer) analyzeComponent(

if len(component.Net) == 0 {
return src.Component{}, &compiler.Error{
Err: errors.New("Flow must have network"),
Message: "Component must have network",
Location: &scope.Location,
Meta: &component.Meta,
}
Expand Down
Loading

0 comments on commit dd73124

Please sign in to comment.