Skip to content

Commit

Permalink
refactor(analyzer): minor - get comp node iface
Browse files Browse the repository at this point in the history
  • Loading branch information
emil14 committed Jan 15, 2025
1 parent e060eb1 commit d8543f7
Showing 1 changed file with 38 additions and 41 deletions.
79 changes: 38 additions & 41 deletions internal/compiler/analyzer/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,28 @@ func (a Analyzer) analyzeNode(
}
}

bindDirectiveArgs, usesBindDirective := node.Directives[compiler.BindDirective]
if usesBindDirective && len(bindDirectiveArgs) != 1 {
bindArg, hasBind := node.Directives[compiler.BindDirective]
if hasBind && len(bindArg) != 1 {
return src.Node{}, foundInterface{}, &compiler.Error{
Message: "Node with #bind directive must provide exactly one argument",
Meta: nodeEntity.Meta(),
}
}

if hasBind && nodeEntity.Kind == src.InterfaceEntity {
return src.Node{}, foundInterface{}, &compiler.Error{
Message: "Interface node cannot use #bind directive",
Meta: nodeEntity.Meta(),
}
}

if nodeEntity.Kind == src.InterfaceEntity && node.DIArgs != nil {
return src.Node{}, foundInterface{}, &compiler.Error{
Message: "Only component node can have dependency injection",
Meta: nodeEntity.Meta(),
}
}

// We need to get resolved frame from parent type parameters
// in order to be able to resolve node's args
// since they can refer to type parameter of the parent (interface)
Expand Down Expand Up @@ -111,15 +125,21 @@ func (a Analyzer) analyzeNode(
}
}

nodeIface, aerr := a.getNodeInterface(
nodeEntity,
usesBindDirective,
node,
scope,
resolvedNodeArgs,
)
if aerr != nil {
return src.Node{}, foundInterface{}, aerr
var nodeIface src.Interface
if nodeEntity.Kind == src.InterfaceEntity {
nodeIface = nodeEntity.Interface
} else {
var err *compiler.Error
nodeIface, err = a.getComponentNodeInterface(
nodeEntity,
hasBind,
node,
scope,
resolvedNodeArgs,
)
if err != nil {
return src.Node{}, foundInterface{}, err
}
}

if node.ErrGuard {
Expand Down Expand Up @@ -206,31 +226,16 @@ func (a Analyzer) analyzeNode(
}, nil
}

// also does validation
func (a Analyzer) getNodeInterface(
// getComponentNodeInterface returns interface of the component node.
// It also performs some validation.
func (a Analyzer) getComponentNodeInterface(
entity src.Entity,
usesBindDirective bool,
hasBind bool,
node src.Node,
scope src.Scope,
resolvedNodeArgs []typesystem.Expr,
) (src.Interface, *compiler.Error) {
if entity.Kind == src.InterfaceEntity {
if usesBindDirective {
return src.Interface{}, &compiler.Error{
Message: "Interface node cannot use #bind directive",
Meta: entity.Meta(),
}
}

if node.DIArgs != nil {
return src.Interface{}, &compiler.Error{
Message: "Only component node can have dependency injection",
Meta: entity.Meta(),
}
}

return entity.Interface, nil
}
// TODO: node.OverloadIndex needs to be set here based on how node is used in the network

var version src.Component
if len(entity.Component) == 1 {
Expand All @@ -239,22 +244,14 @@ func (a Analyzer) getNodeInterface(
version = entity.Component[*node.OverloadIndex]
}

externArgs, hasExternDirective := version.Directives[compiler.ExternDirective]

if usesBindDirective && !hasExternDirective {
_, hasExtern := version.Directives[compiler.ExternDirective]
if hasBind && !hasExtern {
return src.Interface{}, &compiler.Error{
Message: "Node can't use #bind if it isn't instantiated with the component that use #extern",
Meta: entity.Meta(),
}
}

if len(externArgs) > 1 && len(resolvedNodeArgs) != 1 {
return src.Interface{}, &compiler.Error{
Message: "Component that use #extern directive with > 1 argument, must have exactly one type-argument for overloading",
Meta: entity.Meta(),
}
}

iface := version.Interface

_, hasAutoPortsDirective := version.Directives[compiler.AutoportsDirective]
Expand Down

0 comments on commit d8543f7

Please sign in to comment.