示例#1
0
// 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)))
}
示例#2
0
// 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
}
示例#3
0
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
}
示例#4
0
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)
	}
}
示例#5
0
// 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
}
示例#6
0
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")
	}
}
示例#7
0
// 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
	}
}
示例#8
0
// 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
	}
}
示例#9
0
// 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)
		}
	}
}