コード例 #1
0
// buildStructInitializerExpression builds an initializer expression for a struct type.
func (db *domBuilder) buildStructInitializerExpression(structType typegraph.TypeReference, initializers map[string]codedom.Expression, node compilergraph.GraphNode) codedom.Expression {
	staticType := structType.ReferredType()

	var arguments = make([]codedom.Expression, 0)
	for _, field := range staticType.RequiredFields() {
		arguments = append(arguments, initializers[field.Name()])
		delete(initializers, field.Name())
	}

	constructor, found := structType.ResolveMember("new", typegraph.MemberResolutionStatic)
	if !found {
		panic(fmt.Sprintf("Missing new constructor on type %v", structType))
	}

	newCall := codedom.MemberCall(
		codedom.MemberReference(
			codedom.TypeLiteral(structType, node),
			constructor,
			node),
		constructor,
		arguments,
		node)

	// If there are no initializers, then just return the new value directly.
	if len(initializers) == 0 {
		return newCall
	}

	return db.buildInitializationCompoundExpression(structType, initializers, newCall, node)
}
コード例 #2
0
ファイル: typesig.go プロジェクト: Serulian/compiler
// 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
}
コード例 #3
0
ファイル: es5pather.go プロジェクト: Serulian/compiler
// 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
}
コード例 #4
0
ファイル: es5pather.go プロジェクト: Serulian/compiler
// 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
}