Exemplo n.º 1
0
        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);
                    }
                }
            }
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 3
0
 public TypeSpecToSLType(TypeMapper parent, bool forOverride)
 {
     this.parent   = Ex.ThrowOnNull(parent, nameof(parent));
     isForOverride = forOverride;
 }
Exemplo n.º 4
0
 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)));
 }