void GatherGenerics(TypeMapper typeMapper, FunctionDeclaration func, SLImportModules modules, TypeSpec type, SLGenericTypeDeclarationCollection genericDecl, Dictionary <string, List <BaseConstraint> > redundantConstraints) { if (!func.IsTypeSpecGeneric(type)) { return; } if (type.ContainsGenericParameters) { var entity = typeMapper.GetEntityForTypeSpec(type); if (entity != null) { for (int i = 0; i < entity.Type.Generics.Count; i++) { var genDecl = entity.Type.Generics [i]; var originalGenTypeSpec = type.GenericParameters [i]; if (originalGenTypeSpec is NamedTypeSpec named) { var depthIndex = func.GetGenericDepthAndIndex(originalGenTypeSpec); if (depthIndex.Item1 < 0 || depthIndex.Item2 < 0) { continue; } var genRef = new SLGenericReferenceType(depthIndex.Item1, depthIndex.Item2); var genRefName = genRef.Name; List <BaseConstraint> constList = null; if (!redundantConstraints.TryGetValue(genRefName, out constList)) { constList = new List <BaseConstraint> (); redundantConstraints.Add(genRefName, constList); } constList.AddRange(genDecl.Constraints); } else if (originalGenTypeSpec is ClosureTypeSpec closure) { GatherGenerics(typeMapper, func, modules, closure.Arguments, genericDecl, redundantConstraints); GatherGenerics(typeMapper, func, modules, closure.ReturnType, genericDecl, redundantConstraints); } else if (originalGenTypeSpec is TupleTypeSpec tuple) { foreach (var tupleSpec in tuple.Elements) { GatherGenerics(typeMapper, func, modules, tupleSpec, genericDecl, redundantConstraints); } } } } foreach (var subType in type.GenericParameters) { GatherGenerics(typeMapper, func, modules, subType, genericDecl, redundantConstraints); } } else { if (type is NamedTypeSpec named) { var depthIndex = func.GetGenericDepthAndIndex(type); var gd = func.GetGeneric(depthIndex.Item1, depthIndex.Item2); var genRef = new SLGenericReferenceType(depthIndex.Item1, depthIndex.Item2); var sldecl = new SLGenericTypeDeclaration(new SLIdentifier(genRef.Name)); #if SWIFT4 if (depthIndex.Item1 >= func.GetMaxDepth()) { sldecl.Constraints.AddRange(gd.Constraints.Select(baseConstraint => MethodWrapping.ToSLGenericConstraint(func, baseConstraint, genRef.ToString()) )); } #else sldecl.Constraints.AddRange(gd.Constraints.Select(bc => { InheritanceConstraint inh = bc as InheritanceConstraint; if (inh == null) { throw new CompilerException("Equality constraints not supported (yet)"); } return(new SLGenericConstraint(true, new SLSimpleType(genRef.Name), parent.TypeSpecMapper.MapType(func, modules, inh.InheritsTypeSpec))); })); #endif genericDecl.Add(sldecl); } else if (type is ClosureTypeSpec closure) { GatherGenerics(typeMapper, func, modules, closure.Arguments, genericDecl, redundantConstraints); GatherGenerics(typeMapper, func, modules, closure.ReturnType, genericDecl, redundantConstraints); } else if (type is TupleTypeSpec tuple) { foreach (var tupleSpec in tuple.Elements) { GatherGenerics(typeMapper, func, modules, tupleSpec, genericDecl, redundantConstraints); } } } }
public SLParameter ToParameter(TypeMapper typeMapper, FunctionDeclaration func, SLImportModules modules, ParameterItem p, int index, bool dontChangeInOut, SLGenericTypeDeclarationCollection genericDecl = null, bool remapSelf = false, string remappedSelfName = "") { var pIsGeneric = func.IsTypeSpecGeneric(p) && p.TypeSpec is NamedTypeSpec; var parmTypeEntity = !pIsGeneric?typeMapper.GetEntityForTypeSpec(p.TypeSpec) : null; if (parmTypeEntity == null && !pIsGeneric && p.IsInOut) { throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 45, $"In function {func.ToFullyQualifiedName ()}, unknown type parameter type {p.PublicName}:{p.TypeName}."); } var parmKind = p.IsInOut && (pIsGeneric || !parmTypeEntity.IsStructOrEnum) ? SLParameterKind.InOut : SLParameterKind.None; SLType parmType = null; var pTypeSpec = remapSelf ? p.TypeSpec.ReplaceName("Self", remappedSelfName) : p.TypeSpec; if (genericDecl != null) { GatherGenerics(typeMapper, func, modules, pTypeSpec, genericDecl); } if (pIsGeneric) { if (pTypeSpec.ContainsGenericParameters) { var ns = pTypeSpec as NamedTypeSpec; var boundGen = new SLBoundGenericType(ns.Name, pTypeSpec.GenericParameters.Select(genParm => { return(MapType(func, modules, genParm, true)); })); if (parent.MustForcePassByReference(func, ns)) { boundGen = new SLBoundGenericType("UnsafeMutablePointer", boundGen); } parmType = boundGen; } else { var namedType = pTypeSpec as NamedTypeSpec; if (namedType == null) { throw new NotImplementedException("Can only have a named type spec here."); } var depthIndex = func.GetGenericDepthAndIndex(namedType.Name); var gd = func.GetGeneric(depthIndex.Item1, depthIndex.Item2); var genRef = new SLGenericReferenceType(depthIndex.Item1, depthIndex.Item2); parmType = genRef; } } else { parmType = MapType(func, modules, pTypeSpec, false); if (pIsGeneric) { Tuple <int, int> depthIndex = func.GetGenericDepthAndIndex(pTypeSpec); parmType = new SLGenericReferenceType(depthIndex.Item1, depthIndex.Item2); } else if (parent.MustForcePassByReference(func, pTypeSpec) && !dontChangeInOut) { parmType = new SLBoundGenericType(p.IsInOut ? "UnsafeMutablePointer" : "UnsafePointer", parmType); } } if (isForOverride && p.IsVariadic) { // if we get here, then parmType is an SLSimpleType of SwiftArray<someType> // we're going to turn it into "someType ..." var oldParmType = parmType as SLBoundGenericType; parmType = new SLVariadicType(oldParmType.BoundTypes [0]); } var publicName = !p.NameIsRequired ? null : ConjureIdentifier(p.PublicName, index); var privateName = !String.IsNullOrEmpty(p.PrivateName) ? p.PrivateName : null; return(new SLParameter(publicName, ConjureIdentifier(privateName, index), parmType, parmKind)); }
public TypeSpecToSLType(TypeMapper parent, bool forOverride) { this.parent = Ex.ThrowOnNull(parent, nameof(parent)); isForOverride = forOverride; }
public void MapParams(TypeMapper typeMapper, FunctionDeclaration func, SLImportModules modules, List <SLParameter> output, List <ParameterItem> parameters, bool dontChangeInOut, SLGenericTypeDeclarationCollection genericDeclaration = null, bool remapSelf = false, string selfReplacement = "") { output.AddRange(parameters.Select((p, i) => ToParameter(typeMapper, func, modules, p, i, dontChangeInOut, genericDeclaration, remapSelf, selfReplacement))); }
public void MapParams(TypeMapper typeMapper, FunctionDeclaration func, SLImportModules modules, List <SLParameter> output, List <ParameterItem> parameters, bool dontChangeInOut, SLGenericTypeDeclarationCollection genericDeclaration = null) { output.AddRange(parameters.Select((p, i) => ToParameter(typeMapper, func, modules, p, i, dontChangeInOut, genericDeclaration))); }