github.com/nevalang/neva@v0.23.1-0.20240507185603-7696a9bb8dda/internal/compiler/analyzer/type.go (about)

     1  package analyzer
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/nevalang/neva/internal/compiler"
     7  	src "github.com/nevalang/neva/internal/compiler/sourcecode"
     8  	"github.com/nevalang/neva/internal/compiler/sourcecode/core"
     9  	ts "github.com/nevalang/neva/internal/compiler/sourcecode/typesystem"
    10  )
    11  
    12  type analyzeTypeDefParams struct {
    13  	allowEmptyBody bool
    14  }
    15  
    16  var ErrEmptyTypeDefBody = fmt.Errorf("Type definition must have non-empty body")
    17  
    18  func (a Analyzer) analyzeTypeDef(def ts.Def, scope src.Scope, params analyzeTypeDefParams) (ts.Def, *compiler.Error) {
    19  	if !params.allowEmptyBody && def.BodyExpr == nil {
    20  		meta := def.Meta.(core.Meta) //nolint:forcetypeassert
    21  		return ts.Def{}, &compiler.Error{
    22  			Err:      ErrEmptyTypeDefBody,
    23  			Location: &scope.Location,
    24  			Meta:     &meta,
    25  		}
    26  	}
    27  
    28  	// Note that we only resolve params. Body is resolved each time there's an expression that refers to it.
    29  	// We can't resolve body without args. And don't worry about unused bodies. Unused entities are error themselves.
    30  	resolvedParams, _, err := a.resolver.ResolveParams(def.Params, scope)
    31  	if err != nil {
    32  		meta := def.Meta.(core.Meta) //nolint:forcetypeassert
    33  		return ts.Def{}, &compiler.Error{
    34  			Err:      err,
    35  			Location: &scope.Location,
    36  			Meta:     &meta,
    37  		}
    38  	}
    39  
    40  	return ts.Def{
    41  		Params:   resolvedParams,
    42  		BodyExpr: def.BodyExpr,
    43  	}, nil
    44  }
    45  
    46  func (a Analyzer) analyzeTypeExpr(expr ts.Expr, scope src.Scope) (ts.Expr, *compiler.Error) {
    47  	resolvedExpr, err := a.resolver.ResolveExpr(expr, scope)
    48  	if err != nil {
    49  		meta := expr.Meta.(core.Meta) //nolint:forcetypeassert
    50  		return ts.Expr{}, &compiler.Error{
    51  			Err:      err,
    52  			Location: &scope.Location,
    53  			Meta:     &meta,
    54  		}
    55  	}
    56  	return resolvedExpr, nil
    57  }
    58  
    59  func (a Analyzer) analyzeTypeParams(
    60  	params []ts.Param,
    61  	scope src.Scope,
    62  ) (
    63  	[]ts.Param,
    64  	*compiler.Error,
    65  ) {
    66  	resolvedParams, _, err := a.resolver.ResolveParams(params, scope)
    67  	if err != nil {
    68  		return nil, &compiler.Error{
    69  			Err:      err,
    70  			Location: &scope.Location,
    71  		}
    72  	}
    73  	return resolvedParams, nil
    74  }