func (stc *srgTypeConstructor) DefineDependencies(annotator typegraph.Annotator, graph *typegraph.TypeGraph) { for _, srgType := range stc.srg.GetTypes() { // Decorate all types with their inheritance. if srgType.TypeKind() != srg.InterfaceType { for _, inheritsRef := range srgType.Inheritance() { // Resolve the type to which the inherits points. resolvedType, err := stc.BuildTypeRef(inheritsRef, graph) if err != nil { annotator.ReportError(srgType.Node(), "%s", err.Error()) continue } if srgType.TypeKind() == srg.ClassType { if resolvedType.ReferredType().TypeKind() != typegraph.ClassType { switch resolvedType.ReferredType().TypeKind() { case typegraph.GenericType: annotator.ReportError(srgType.Node(), "Type '%s' cannot derive from a generic ('%s')", srgType.Name(), resolvedType.ReferredType().Name()) case typegraph.ImplicitInterfaceType: annotator.ReportError(srgType.Node(), "Type '%s' cannot derive from an interface ('%s')", srgType.Name(), resolvedType.ReferredType().Name()) } continue } annotator.DefineParentType(srgType.Node(), resolvedType) } else if srgType.TypeKind() == srg.NominalType { annotator.DefineParentType(srgType.Node(), resolvedType) } } } // Decorate all type generics with their constraints. for _, srgGeneric := range srgType.Generics() { // Note: If the constraint is not valid, the resolve method will report the error and return Any, which is the correct type. constraintType, _ := stc.resolvePossibleType(srgGeneric.Node(), srgGeneric.GetConstraint, graph, annotator) // If the constraint type is `any` and this is a generic on a struct, then // change it to a structural any reference. if srgType.TypeKind() == srg.StructType && constraintType.IsAny() { constraintType = graph.StructTypeReference() } annotator.DefineGenericConstraint(srgGeneric.Node(), constraintType) } } }
func (trr *TypeReferenceResolver) resolveTypeRef(typeref srg.SRGTypeRef, tdg *typegraph.TypeGraph) (typegraph.TypeReference, error) { switch typeref.RefKind() { case srg.TypeRefVoid: return tdg.VoidTypeReference(), nil case srg.TypeRefAny: return tdg.AnyTypeReference(), nil case srg.TypeRefStruct: return tdg.StructTypeReference(), nil case srg.TypeRefMapping: innerType, err := trr.ResolveTypeRef(typeref.InnerReference(), tdg) if err != nil { return tdg.AnyTypeReference(), err } return tdg.NewTypeReference(tdg.MappingType(), innerType), nil case srg.TypeRefSlice: innerType, err := trr.ResolveTypeRef(typeref.InnerReference(), tdg) if err != nil { return tdg.AnyTypeReference(), err } return tdg.NewTypeReference(tdg.SliceType(), innerType), nil case srg.TypeRefStream: innerType, err := trr.ResolveTypeRef(typeref.InnerReference(), tdg) if err != nil { return tdg.AnyTypeReference(), err } return tdg.NewTypeReference(tdg.StreamType(), innerType), nil case srg.TypeRefNullable: innerType, err := trr.ResolveTypeRef(typeref.InnerReference(), tdg) if err != nil { return tdg.AnyTypeReference(), err } return innerType.AsNullable(), nil case srg.TypeRefPath: // Resolve the package type for the type ref. resolvedTypeInfo, found := typeref.ResolveType() if !found { sourceError := compilercommon.SourceErrorf(typeref.Location(), "Type '%s' could not be found", typeref.ResolutionPath()) return tdg.AnyTypeReference(), sourceError } // If the type information refers to an SRG type or generic, find the node directly // in the type graph. var constructedRef = tdg.AnyTypeReference() if !resolvedTypeInfo.IsExternalPackage { // Get the type in the type graph. resolvedType, hasResolvedType := tdg.GetTypeForSourceNode(resolvedTypeInfo.ResolvedType.Node()) if !hasResolvedType { panic(fmt.Sprintf("Could not find typegraph type for SRG type %v", resolvedTypeInfo.ResolvedType.Name())) } constructedRef = tdg.NewTypeReference(resolvedType) } else { // Otherwise, we search for the type in the type graph based on the package from which it // was imported. resolvedType, hasResolvedType := tdg.ResolveTypeUnderPackage(resolvedTypeInfo.ExternalPackageTypePath, resolvedTypeInfo.ExternalPackage) if !hasResolvedType { sourceError := compilercommon.SourceErrorf(typeref.Location(), "Type '%s' could not be found", typeref.ResolutionPath()) return tdg.AnyTypeReference(), sourceError } constructedRef = tdg.NewTypeReference(resolvedType) } // Add the generics. if typeref.HasGenerics() { for _, srgGeneric := range typeref.Generics() { genericTypeRef, err := trr.ResolveTypeRef(srgGeneric, tdg) if err != nil { return tdg.AnyTypeReference(), err } constructedRef = constructedRef.WithGeneric(genericTypeRef) } } // Add the parameters. if typeref.HasParameters() { for _, srgParameter := range typeref.Parameters() { parameterTypeRef, err := trr.ResolveTypeRef(srgParameter, tdg) if err != nil { return tdg.AnyTypeReference(), err } constructedRef = constructedRef.WithParameter(parameterTypeRef) } } return constructedRef, nil default: panic(fmt.Sprintf("Unknown kind of SRG type ref: %v", typeref.RefKind())) return tdg.AnyTypeReference(), nil } }