Пример #1
0
        public List <SubscriptDeclaration> AllSubscripts()
        {
            var allSubFuncs = Members.OfType <FunctionDeclaration> ().Where(decl => decl.IsSubscript).ToList();
            var allSubs     = new List <SubscriptDeclaration> ();

            while (allSubFuncs.Count > 0)
            {
                int i = allSubFuncs.Count - 1;
                FunctionDeclaration decl = allSubFuncs [i];
                allSubFuncs.RemoveAt(i);
                if (decl.IsSubscriptMaterializer)
                {
                    continue;
                }
                if (decl.IsSubscriptGetter)
                {
                    FunctionDeclaration setter       = GetAndRemoveSetter(allSubFuncs, decl);
                    FunctionDeclaration materializer = GetAndRemoveMaterializer(allSubFuncs, decl);
                    allSubs.Add(new SubscriptDeclaration(decl, setter, materializer));
                }
                else if (decl.IsSubscriptSetter)
                {
                    FunctionDeclaration getter       = GetAndRemoveGetter(allSubFuncs, decl);
                    FunctionDeclaration materializer = GetAndRemoveMaterializer(allSubFuncs, decl);
                    allSubs.Add(new SubscriptDeclaration(getter, decl, materializer));
                }
            }
            return(allSubs);
        }
        public static FunctionDeclaration FuncFromXElement(XElement elem, ModuleDeclaration module, BaseDeclaration parent)
        {
            FunctionDeclaration decl = new FunctionDeclaration {
                Name              = (string)elem.Attribute("name"),
                Module            = module,
                Parent            = parent,
                Access            = TypeDeclaration.AccessibilityFromString((string)elem.Attribute("accessibility")),
                ReturnTypeName    = Ex.ThrowOnNull((string)elem.Attribute("returnType"), "returnType"),
                IsProperty        = elem.BoolAttribute("isProperty"),
                IsStatic          = elem.BoolAttribute("isStatic"),
                IsFinal           = elem.BoolAttribute("isFinal"),
                OperatorType      = OperatorTypeFromElement((string)elem.Attribute("operatorKind")),
                HasThrows         = elem.BoolAttribute("hasThrows"),
                IsDeprecated      = elem.BoolAttribute("isDeprecated"),
                IsUnavailable     = elem.BoolAttribute("isUnavailable"),
                IsOptional        = elem.BoolAttribute("isOptional"),
                ObjCSelector      = (string)elem.Attribute("objcSelector"),
                IsRequired        = elem.BoolAttribute("isRequired"),
                IsConvenienceInit = elem.BoolAttribute("isConvenienceInit")
            };

            decl.ParameterLists.AddRange(ParameterItem.ParameterListListFromXElement(elem.Element("parameterlists")));
            if (decl.IsProperty && (decl.IsSetter || decl.IsSubscriptSetter))
            {
                decl.ParameterLists [decl.ParameterLists.Count - 1] =
                    MassageLastPropertySetterParameterList(decl.ParameterLists.Last());
            }
            return(decl);
        }
        public static BaseDeclaration FromXElement(XElement elem, ModuleDeclaration module, BaseDeclaration parent)
        {
            var             generics = GenericDeclaration.FromXElement(elem.Element("genericparameters"));
            BaseDeclaration decl     = null;

            switch (elem.Name.ToString())
            {
            case "func":
                decl = FunctionDeclaration.FuncFromXElement(elem, module, parent);
                break;

            case "typedeclaration":
                decl = TypeDeclaration.TypeFromXElement(elem, module, parent);
                break;

            case "property":
                decl = PropertyDeclaration.PropFromXElement(elem, module, parent);
                break;

            default:
                decl = new BaseDeclaration {
                    Name   = (string)elem.Attribute("name"),
                    Access = TypeDeclaration.AccessibilityFromString((string)elem.Attribute("accessibility"))
                };
                break;
            }
            decl.Generics.AddRange(generics);
            return(decl);
        }
        public static bool AreEqualIgnoreNamesReferencesInvariant(FunctionDeclaration fn1, IList <ParameterItem> pl1,
                                                                  FunctionDeclaration fn2, IList <ParameterItem> pl2, bool matchPartialNames)
        {
            if (pl1.Count != pl2.Count)
            {
                return(false);
            }

            for (int i = 0; i < pl1.Count; i++)
            {
                var p1 = SubstituteSelfFromParent(fn1, pl1 [i]);
                var p2 = SubstituteSelfFromParent(fn2, pl2 [i]);
                p1 = RecastAsReference(p1);
                p2 = RecastAsReference(p2);


                // Names invariant means TYPE names not parameter names
                if (!ParameterNamesMatch(p1, p2))
                {
                    // we give a pass on matching "self".
                    // this is done because "self" is a keyword in swift
                    // and when matching a wrapper function, we can't call
                    // a parameter "self" but have to call it "thisN" where
                    // N is either an empty string or a number.
                    // This is because there might be a real parameter named "this"
                    // and we had to rename it.
                    // The end result is that we can't use a "this" test, but we
                    // can use a "self" test.
                    var parmName1 = p1.NameIsRequired ? p1.PublicName : p1.PrivateName;
                    var parmName2 = p2.NameIsRequired ? p2.PublicName : p2.PrivateName;
                    if (parmName1 != "self" && parmName2 != "self")
                    {
                        return(false);
                    }
                }
                if (fn1.IsTypeSpecGeneric(p1))
                {
                    if (!fn2.IsTypeSpecGeneric(p2))
                    {
                        return(false);
                    }
                    continue;
                }
                if (!p1.EqualsIgnoreName(p2))
                {
                    if (matchPartialNames)
                    {
                        if (!p1.EqualsIgnoreNamesPartialMatch(p2))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
 static ParameterItem SubstituteSelfFromParent(FunctionDeclaration func, ParameterItem p)
 {
     if (func.Parent == null || !p.TypeSpec.HasDynamicSelf)
     {
         return(p);
     }
     p          = new ParameterItem(p);
     p.TypeSpec = p.TypeSpec.ReplaceName("Self", func.Parent.ToFullyQualifiedNameWithGenerics());
     return(p);
 }
Пример #6
0
        static FunctionDeclaration GetAndRemoveGetter(List <FunctionDeclaration> decls, FunctionDeclaration other)
        {
            var      plToMatch     = new List <ParameterItem> ();
            TypeSpec returnToMatch = null;
            var      selfToMatch   = other.Parent;

            if (other.IsSetter)
            {
                // setter -
                // The arguments to a setter are
                // value, arg1, arg2 ... argn
                // We want to match the type of the return of the getter to the value of the setter
                // as well as the parameters
                List <ParameterItem> pl = other.ParameterLists.Last();
                plToMatch.AddRange(pl.GetRange(1, pl.Count - 1));
                returnToMatch = pl [0].TypeSpec;
            }
            else
            {
                // materializer.
                // The arguments to a materializer are
                // buffer, callbackStoragebuffer, arg1, arg2 ... argn
                // We have no return to match. Oops.
                List <ParameterItem> pl = other.ParameterLists.Last();
                plToMatch.AddRange(pl.GetRange(2, pl.Count - 2));
                returnToMatch = null;
            }


            for (int i = 0; i < decls.Count; i++)
            {
                FunctionDeclaration getter = decls [i];
                if (getter.Parent != selfToMatch)
                {
                    return(null);
                }
                if (!getter.IsSubscriptGetter)
                {
                    continue;
                }
                if ((returnToMatch != null && returnToMatch.Equals(getter.ReturnTypeSpec)) || returnToMatch == null)
                {
                    List <ParameterItem> targetPl = getter.ParameterLists.Last();
                    if (ParmsMatch(plToMatch, targetPl))
                    {
                        decls.RemoveAt(i);
                        return(getter);
                    }
                }
            }
            return(null);
        }
Пример #7
0
        static FunctionDeclaration GetAndRemoveSetter(List <FunctionDeclaration> decls, FunctionDeclaration other)
        {
            var plToMatch   = new List <ParameterItem> ();
            var selfToMatch = other.Parent;

            if (other.IsGetter)
            {
                // getter -
                // The arguments to a getter are
                // arg1, arg2 ... argn
                // We want to match the type of the return of the getter to the value of the setter
                // as well as the parameters
                List <ParameterItem> pl   = other.ParameterLists.Last();
                ParameterItem        item = new ParameterItem();
                item.PublicName  = "";
                item.PrivateName = "retval";
                item.TypeSpec    = other.ReturnTypeSpec;
                item.TypeName    = other.ReturnTypeName;
                plToMatch.Add(item);
                plToMatch.AddRange(pl);
            }
            else
            {
                // we don't have enough information to match on setter
                // and since we don't use the materializer, NBD.

                // materializer.
                // The arguments to a materializer are
                // buffer, callbackStoragebuffer, arg1, arg2 ... argn
                // We have no return to match. Oops.
                return(null);
            }

            for (int i = 0; i < decls.Count; i++)
            {
                FunctionDeclaration setter = decls [i];
                if (!setter.IsSubscriptGetter)
                {
                    continue;
                }
                List <ParameterItem> targetPl = setter.ParameterLists.Last();
                if (ParmsMatch(plToMatch, targetPl))
                {
                    decls.RemoveAt(i);
                    return(setter);
                }
            }
            return(null);
        }
 public FunctionDeclaration(FunctionDeclaration other)
     : base(other)
 {
     ParameterLists    = CopyOf(other.ParameterLists);
     ReturnTypeName    = other.ReturnTypeName;
     IsProperty        = other.IsProperty;
     IsStatic          = other.IsStatic;
     IsFinal           = other.IsFinal;
     HasThrows         = other.HasThrows;
     IsDeprecated      = other.IsDeprecated;
     IsUnavailable     = other.IsUnavailable;
     OperatorType      = other.OperatorType;
     IsOptional        = other.IsOptional;
     ObjCSelector      = other.ObjCSelector;
     IsRequired        = other.IsRequired;
     IsConvenienceInit = other.IsConvenienceInit;
 }
        static bool SubscriptParametersMatch(FunctionDeclaration getter, FunctionDeclaration setter)
        {
            if (getter.ParameterLists.Count != 2 || setter.ParameterLists.Count != 2)
            {
                return(false);
            }
            TypeSpec returnType = getter.ReturnTypeSpec;

            if (getter.ParameterLists [1].Count != setter.ParameterLists [1].Count - 1)
            {
                return(false);
            }
            if (!returnType.Equals(setter.ParameterLists [1] [0].TypeSpec))
            {
                return(false);
            }

            return(ParameterItem.AreEqualIgnoreNamesReferencesInvariant(getter, getter.ParameterLists [1],
                                                                        setter, setter.ParameterLists [1].Skip(1).ToList(), true));
        }
        public bool MatchesSignature(FunctionDeclaration other, bool ignoreFirstParameterListIfPresent)
        {
            if (!TypeSpec.BothNullOrEqual(this.ReturnTypeSpec, other.ReturnTypeSpec))
            {
                return(false);
            }
            if (this.ParameterLists.Count != other.ParameterLists.Count)
            {
                return(false);
            }
            int startIndex = ignoreFirstParameterListIfPresent && this.ParameterLists.Count > 1 ? 1 : 0;

            for (int i = startIndex; i < this.ParameterLists.Count; i++)
            {
                if (!ParameterItem.AreEqualIgnoreNamesReferencesInvariant(this, this.ParameterLists [i], other, other.ParameterLists [i], true))
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #11
0
        public bool VirtualMethodExistsInInheritedBoundType(FunctionDeclaration func, TypeMapper typeMapper)
        {
            // virtual methods are only in classes
            if (!(this is ClassDeclaration))
            {
                return(false);
            }
            var classInheritance = Inheritance.FirstOrDefault(inh => inh.InheritanceKind == InheritanceKind.Class);

            if (classInheritance == null)
            {
                return(false);
            }

            var inheritedEntity = typeMapper.GetEntityForTypeSpec(classInheritance.InheritedTypeSpec);

            if (inheritedEntity == null)
            {
                throw ErrorHelper.CreateError(ReflectorError.kTypeMapBase + 18, $"Unable to find type database entry for class {classInheritance.InheritedTypeName} while searching inheritance.");
            }

            // if we get here, the Type has to be a ClassDeclaration
            var inheritedClass = inheritedEntity.Type as ClassDeclaration;

            var methods = inheritedClass.AllVirtualMethods().FindAll(fn => fn.Name == func.Name &&
                                                                     fn.ParameterLists.Last().Count == func.ParameterLists.Last().Count).ToList();

            foreach (var method in methods)
            {
                if (ParmsMatchWithNames(method.ParameterLists.Last(), func.ParameterLists.Last()) &&
                    method.ReturnTypeSpec.Equals(func.ReturnTypeSpec))
                {
                    return(true);
                }
            }
            return(inheritedClass.VirtualMethodExistsInInheritedBoundType(func, typeMapper));
        }
Пример #12
0
 static FunctionDeclaration GetAndRemoveMaterializer(List <FunctionDeclaration> decls, FunctionDeclaration other)
 {
     // FIXME - materializers don't have enough to match on with 100% confidence
     // Materializers are (probably) not needed by tom-swifty, so no big
     return(null);
 }