// referredTypeNode returns the node to which the type reference refers. func (tr TypeReference) referredTypeNode() compilergraph.GraphNode { if tr.getSlot(trhSlotFlagSpecial)[0] != specialFlagNormal { panic(fmt.Sprintf("Cannot get referred type for special type references of type %s", tr.getSlot(trhSlotFlagSpecial))) } return tr.tdg.layer.GetNode(compilergraph.GraphNodeId(tr.getSlot(trhSlotTypeId))) }
// SourceNodeId returns the ID of the source node for this member, if any. func (tn TGMember) SourceNodeId() (compilergraph.GraphNodeId, bool) { idFound, hasId := tn.GraphNode.TryGetValue(NodePredicateSource) if !hasId { return compilergraph.GraphNodeId(""), false } return idFound.NodeId(), true }
func (t *ScopeInfo) CalledOperator(tg *typegraph.TypeGraph) (typegraph.TGMember, bool) { if t.CalledOpReference == nil { return typegraph.TGMember{}, false } nodeId := compilergraph.GraphNodeId(t.CalledOpReference.GetReferencedNode()) return tg.GetTypeOrMember(nodeId).(typegraph.TGMember), true }
func (r *ScopeReference) GetNode(srg *srg.SRG, tg *typegraph.TypeGraph) compilergraph.GraphNode { nodeId := compilergraph.GraphNodeId(r.GetReferencedNode()) if r.GetIsSRGNode() { return srg.GetNode(nodeId) } else { return tg.GetNode(nodeId) } }
// checkStaticDependencyCycle checks the given variable/field node for a initialization dependency // cycle. func (sb *scopeBuilder) checkStaticDependencyCycle(varNode compilergraph.GraphNode, currentDep *proto.ScopeReference, encountered *ordered_map.OrderedMap, path []typegraph.TGMember) bool { // If we've already examined this dependency, nothing else to do. if _, found := encountered.Get(currentDep.GetReferencedNode()); found { return true } encountered.Set(currentDep.GetReferencedNode(), true) // Lookup the dependency (which is a type or module member) in the type graph. memberNodeId := compilergraph.GraphNodeId(currentDep.GetReferencedNode()) member := sb.sg.tdg.GetTypeOrMember(memberNodeId) // Find the associated source node. sourceNodeId, hasSourceNode := member.SourceNodeId() if !hasSourceNode { return true } updatedPath := append([]typegraph.TGMember(nil), path...) updatedPath = append(updatedPath, member.(typegraph.TGMember)) // If we've found the variable itself, then we have a dependency cycle. if sourceNodeId == varNode.GetNodeId() { // Found a cycle. var chain bytes.Buffer chain.WriteString(member.Title()) chain.WriteRune(' ') chain.WriteString(member.Name()) for _, cMember := range updatedPath { chain.WriteString(" -> ") chain.WriteString(cMember.Title()) chain.WriteRune(' ') chain.WriteString(cMember.Name()) } sb.decorateWithError(varNode, "Initialization cycle found on %v %v: %s", member.Title(), member.Name(), chain.String()) sb.Status = false return false } // Lookup the dependency in the SRG, so we can recursively check *its* dependencies. srgNode, hasSRGNode := sb.sg.srg.TryGetNode(sourceNodeId) if !hasSRGNode { return true } // Recursively lookup the static deps for the node and check them. nodeScope := sb.getScopeForRootNode(srgNode) for _, staticDep := range nodeScope.GetStaticDependencies() { if !sb.checkStaticDependencyCycle(varNode, staticDep, encountered, updatedPath) { return false } } return true }
func (t *ScopeInfo) TargetedNode(srg *srg.SRG) (compilergraph.GraphNode, bool) { if t.TargetedReference == nil { return compilergraph.GraphNode{}, false } nodeId := compilergraph.GraphNodeId(t.TargetedReference.GetReferencedNode()) if t.TargetedReference.GetIsSRGNode() { return srg.GetNode(nodeId), true } else { panic("Cannot have a non-SRG targeted node") } }
// getNamedScopeForScope returns namedScopeInfo for the given name, if it references a node by name. func (sb *scopeBuilder) getNamedScopeForScope(scope *proto.ScopeInfo) (namedScopeInfo, bool) { if scope.GetNamedReference() == nil { return namedScopeInfo{}, false } namedReference := scope.GetNamedReference() nodeId := compilergraph.GraphNodeId(namedReference.GetReferencedNode()) if namedReference.GetIsSRGNode() { referencedNode := sb.sg.srg.GetNamedScope(nodeId) return namedScopeInfo{referencedNode, nil, sb}, true } else { referencedNode := sb.sg.tdg.GetTypeOrMember(nodeId) return namedScopeInfo{srg.SRGNamedScope{}, referencedNode, sb}, true } }
// GetReferencedName returns the ReferencedName struct for the given scope, if it refers to a named scope. func (sg *ScopeGraph) GetReferencedName(scope proto.ScopeInfo) (ReferencedName, bool) { if scope.GetNamedReference() == nil { return ReferencedName{}, false } namedReference := scope.GetNamedReference() nodeId := compilergraph.GraphNodeId(namedReference.GetReferencedNode()) if namedReference.GetIsSRGNode() { referencedNode := sg.srg.GetNamedScope(nodeId) return ReferencedName{referencedNode, nil, sg}, true } else { referencedNode := sg.tdg.GetTypeOrMember(nodeId) return ReferencedName{srg.SRGNamedScope{}, referencedNode, sg}, true } }
// recursivelyCollectInitDependencies recursively collects the initialization dependency fields for the // field member, placing them in the deps map. func (gm generatingModule) recursivelyCollectInitDependencies(current typegraph.TGMember, field typegraph.TGMember, deps map[typegraph.TGMember]bool) { if _, found := deps[current]; found { return } if field.NodeId != current.NodeId && current.IsField() { deps[current] = true } else { srgMember, hasSRGMember := gm.Generator.getSRGMember(current) if !hasSRGMember { return } scope, _ := gm.Generator.scopegraph.GetScope(srgMember.GraphNode) for _, staticDep := range scope.GetStaticDependencies() { memberNodeId := compilergraph.GraphNodeId(staticDep.GetReferencedNode()) member := gm.Generator.scopegraph.TypeGraph().GetTypeOrMember(memberNodeId) gm.recursivelyCollectInitDependencies(member.(typegraph.TGMember), field, deps) } } }