示例#1
0
// appendSigReference appends the given type reference to the given signature code
// buffer, returning true if any portion is dynamic.
func appendSigReference(typeRef typegraph.TypeReference, buf *bytes.Buffer) bool {
	if typeRef.IsAny() {
		buf.WriteString("any")
		return false
	}

	if typeRef.IsStruct() {
		buf.WriteString("struct")
		return false
	}

	if typeRef.IsNull() {
		buf.WriteString("null")
		return false
	}

	if typeRef.IsVoid() {
		buf.WriteString("void")
		return false
	}

	referredType := typeRef.ReferredType()
	if referredType.TypeKind() == typegraph.GenericType {
		buf.WriteString("\" + $t.typeid(")
		buf.WriteString(referredType.Name())
		buf.WriteString(") + \"")
		return true
	}

	// Add the type's unique ID.
	buf.WriteString(referredType.GlobalUniqueId())

	// If there are no generics, then we're done.
	if !typeRef.HasGenerics() {
		return false
	}

	// Otherwise, append the generics.
	buf.WriteRune('<')

	var dynamic = false
	for index, generic := range typeRef.Generics() {
		if index > 0 {
			buf.WriteRune(',')
		}

		genericDynamic := appendSigReference(generic, buf)
		dynamic = dynamic || genericDynamic
	}

	buf.WriteRune('>')
	return dynamic
}
示例#2
0
// InnerInstanceName returns the name of an inner instance of the given type, when accessed under a
// type instance which structurally composes it.
func (p Pather) InnerInstanceName(innerType typegraph.TypeReference) string {
	var name = unidecode.Unidecode(innerType.ReferredType().Name())
	if !innerType.HasGenerics() {
		return name
	}

	for _, generic := range innerType.Generics() {
		name = name + "$"
		name = name + p.InnerInstanceName(generic)
	}

	return name
}
示例#3
0
// TypeReferenceCall returns source for retrieving an object reference to the type defined by the given
// type reference.
func (p Pather) TypeReferenceCall(typeRef typegraph.TypeReference) string {
	if typeRef.IsAny() {
		return "$t.any"
	}

	if typeRef.IsStruct() {
		return "$t.struct"
	}

	if typeRef.IsNull() {
		return "$t.null"
	}

	if typeRef.IsVoid() {
		return "$t.void"
	}

	referredType := typeRef.ReferredType()
	if referredType.TypeKind() == typegraph.GenericType {
		return referredType.Name()
	}

	// Add the type name.
	typePath := p.GetTypePath(referredType)

	// If there are no generics, then simply return the type path.
	if !typeRef.HasGenerics() {
		return typePath
	}

	// Invoke the type with generics (if any).
	var genericsString = "("
	for index, generic := range typeRef.Generics() {
		if index > 0 {
			genericsString = genericsString + ", "
		}

		genericsString = genericsString + p.TypeReferenceCall(generic)
	}

	genericsString = genericsString + ")"
	return typePath + genericsString
}
示例#4
0
// scopeSmlNormalAttribute scopes an SML expression attribute under a declaration.
func (sb *scopeBuilder) scopeSmlAttribute(node compilergraph.GraphNode, propsType typegraph.TypeReference, context scopeContext) (string, bool) {
	attributeName := node.Get(parser.NodeSmlAttributeName)

	// If the props type is a struct or class, ensure that the attribute name exists.
	var allowedValueType = sb.sg.tdg.AnyTypeReference()
	if propsType.IsRefToStruct() || propsType.IsRefToClass() {
		module := compilercommon.InputSource(node.Get(parser.NodePredicateSource))
		resolvedMember, rerr := propsType.ResolveAccessibleMember(attributeName, module, typegraph.MemberResolutionInstance)
		if rerr != nil {
			sb.decorateWithError(node, "%v", rerr)
			return attributeName, false
		}

		allowedValueType = resolvedMember.AssignableType()
	} else {
		// The props type must be a mapping, so the value must match it value type.
		allowedValueType = propsType.Generics()[0]
	}

	// Scope the attribute value (if any). If none, then we default to a boolean value.
	var attributeValueType = sb.sg.tdg.BoolTypeReference()

	valueNode, hasValueNode := node.TryGetNode(parser.NodeSmlAttributeValue)
	if hasValueNode {
		attributeValueScope := sb.getScope(valueNode, context)
		if !attributeValueScope.GetIsValid() {
			return attributeName, false
		}

		attributeValueType = attributeValueScope.ResolvedTypeRef(sb.sg.tdg)
	}

	// Ensure it matches the assignable value type.
	if serr := attributeValueType.CheckSubTypeOf(allowedValueType); serr != nil {
		sb.decorateWithError(node, "Cannot assign value of type %v for attribute %v: %v", attributeValueType, attributeName, serr)
		return attributeName, false
	}

	return attributeName, true
}