コード例 #1
0
ファイル: typereference.go プロジェクト: Serulian/compiler
// adjustedMemberSignature returns the member signature found on the given node, adjusted for
// the parent type's generics, as specified in this type reference. Will panic if the type reference
// does not refer to the node's parent type.
func (tr TypeReference) adjustedMemberSignature(node compilergraph.GraphNode) string {
	compilerutil.DCHECK(func() bool {
		return node.StartQuery().In(NodePredicateMember).GetNode() == tr.referredTypeNode()
	}, "Type reference must be parent of member node")

	// Retrieve the generics of the parent type.
	parentNode := tr.referredTypeNode()
	pgit := parentNode.StartQuery().Out(NodePredicateTypeGeneric).BuildNodeIterator()

	// Parse the member signature.
	esig := &proto.MemberSig{}
	memberSig := node.GetTagged(NodePredicateMemberSignature, esig).(*proto.MemberSig)

	// Replace the generics of the parent type in the signature with those of the type reference.
	generics := tr.Generics()

	var index = 0
	var memberType = tr.Build(memberSig.GetMemberType()).(TypeReference)
	for pgit.Next() {
		genericNode := pgit.Node()
		genericRef := generics[index]
		genericType := TGTypeDecl{genericNode, tr.tdg}

		// Replace the generic in the member type.
		memberType = memberType.ReplaceType(genericType, genericRef)

		// Replace the generic in any generic constraints.
		for cindex, constraint := range memberSig.GetGenericConstraints() {
			memberSig.GenericConstraints[cindex] = tr.Build(constraint).(TypeReference).
				ReplaceType(genericType, genericRef).
				Value()
		}

		index = index + 1
	}

	adjustedType := memberType.Value()
	memberSig.MemberType = &adjustedType
	return memberSig.Value()
}