From d8543f7f227b330bbe50be3c4091dfb14fece66d Mon Sep 17 00:00:00 2001 From: Emil Valeev Date: Thu, 16 Jan 2025 01:40:04 +0500 Subject: [PATCH] refactor(analyzer): minor - get comp node iface --- internal/compiler/analyzer/nodes.go | 79 ++++++++++++++--------------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/internal/compiler/analyzer/nodes.go b/internal/compiler/analyzer/nodes.go index 008bec08..ee59c254 100644 --- a/internal/compiler/analyzer/nodes.go +++ b/internal/compiler/analyzer/nodes.go @@ -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) @@ -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 { @@ -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 { @@ -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]