public bool Validate(CodeGenerationOptions opt, GenericParameterDefinitionList type_params, CodeGeneratorContext context)
        {
            if (ConstraintExpressions == null || ConstraintExpressions.Length == 0)
            {
                return(true);
            }
            if (validated)
            {
                return(is_valid);
            }
            var syms = new List <ISymbol> ();

            foreach (var c in ConstraintExpressions)
            {
                var sym = opt.SymbolTable.Lookup(c, type_params);
                if (sym == null)
                {
                    Report.LogCodedWarning(0, Report.WarningUnknownGenericConstraint, c, context.GetContextTypeMember());
                    validated = true;
                    return(false);
                }
                syms.Add(sym);
            }
            Constraints = syms.ToArray();
            validated   = is_valid = true;
            return(true);
        }
示例#2
0
        public bool Validate(CodeGenerationOptions opt, GenericParameterDefinitionList type_params, CodeGeneratorContext context)
        {
            Symbol = opt.SymbolTable.Lookup(TypeName, type_params);

            if (Symbol == null || !Symbol.Validate(opt, type_params, context))
            {
                Report.LogCodedWarning(0, Report.WarningUnexpectedFieldType, this, TypeName, context.GetContextTypeMember());
                return(false);
            }

            if (!string.IsNullOrEmpty(Value) && Symbol != null && Symbol.FullName == "char" && !Value.StartsWith("(char)"))
            {
                Value = "(char)" + Value;
            }

            SetParameters = new ParameterList {
                SetterParameter,
            };

            if (!SetParameters.Validate(opt, type_params, context))
            {
                throw new NotSupportedException(
                          string.Format("Unable to generate setter parameter list {0}", context.ContextString));
            }

            return(true);
        }
        public static ClassGen CreateClass(XElement pkg, XElement elem, CodeGenerationOptions options)
        {
            var klass = new ClassGen(CreateGenBaseSupport(pkg, elem, false))
            {
                BaseType   = elem.XGetAttribute("extends"),
                FromXml    = true,
                IsAbstract = elem.XGetAttribute("abstract") == "true",
                IsFinal    = elem.XGetAttribute("final") == "true",
                // Only use an explicitly set XML attribute
                Unnest = elem.XGetAttribute("unnest") == "true" ? true :
                         elem.XGetAttribute("unnest") == "false" ? false :
                         !options.SupportNestedInterfaceTypes
            };

            FillApiSince(klass, pkg, elem);
            SetLineInfo(klass, elem, options);

            foreach (var child in elem.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "implements":
                    var iname = child.XGetAttribute("name-generic-aware");
                    iname = iname.Length > 0 ? iname : child.XGetAttribute("name");
                    klass.AddImplementedInterface(iname);
                    break;

                case "method":
                    if (child.XGetAttribute("visibility") != "kotlin-internal")
                    {
                        klass.AddMethod(CreateMethod(klass, child, options));
                    }
                    break;

                case "constructor":
                    if (child.XGetAttribute("visibility") != "kotlin-internal")
                    {
                        klass.Ctors.Add(CreateCtor(klass, child, options));
                    }
                    break;

                case "field":
                    if (child.XGetAttribute("visibility") != "kotlin-internal")
                    {
                        klass.AddField(CreateField(klass, child, options));
                    }
                    break;

                case "typeParameters":
                    break;                             // handled at GenBaseSupport

                default:
                    Report.LogCodedWarning(0, Report.WarningUnexpectedChild, klass, child.Name.ToString());
                    break;
                }
            }

            return(klass);
        }
示例#4
0
        public static Ctor CreateCtor(GenBase declaringType, XElement elem, CodeGenerationOptions options = null)
        {
            var ctor = new Ctor(declaringType)
            {
                ApiAvailableSince = declaringType.ApiAvailableSince,
                CustomAttributes  = elem.XGetAttribute("customAttributes"),
                Deprecated        = elem.Deprecated(),
                GenericArguments  = elem.GenericArguments(),
                Name       = elem.XGetAttribute("name"),
                Visibility = elem.Visibility()
            };

            SetLineInfo(ctor, elem, options);

            var idx = ctor.Name.LastIndexOf('.');

            if (idx > 0)
            {
                ctor.Name = ctor.Name.Substring(idx + 1);
            }

            // If 'elem' is a constructor for a non-static nested type, then
            // the type of the containing class must be inserted as the first argument
            ctor.IsNonStaticNestedType = idx > 0 && elem.Parent.Attribute("static").Value == "false";

            if (ctor.IsNonStaticNestedType)
            {
                string   declName = elem.Parent.XGetAttribute("name");
                string   expectedEnclosingName = declName.Substring(0, idx);
                XElement enclosingType         = GetPreviousClass(elem.Parent.PreviousNode, expectedEnclosingName);

                if (enclosingType == null)
                {
                    ctor.MissingEnclosingClass = true;
                    Report.LogCodedWarning(0, Report.WarningMissingClassForConstructor, ctor, ctor.Name, expectedEnclosingName);
                }
                else
                {
                    ctor.Parameters.AddFirst(CreateParameterFromClassElement(enclosingType, options));
                }
            }

            foreach (var child in elem.Elements())
            {
                if (child.Name == "parameter")
                {
                    ctor.Parameters.Add(CreateParameter(child, options));
                }
            }

            ctor.Name = EnsureValidIdentifer(ctor.Name);

            FillApiSince(ctor, elem);

            return(ctor);
        }
示例#5
0
        public XDocument Load(string filename)
        {
            XDocument doc = null;

            try {
                doc = XDocument.Load(filename, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
            } catch (XmlException e) {
                Report.Verbose(0, "Exception: {0}", e);
                Report.LogCodedWarning(0, Report.WarningInvalidXmlFile, e, filename, e.Message);
            }

            return(doc);
        }
        public static InterfaceGen CreateInterface(XElement pkg, XElement elem, CodeGenerationOptions options)
        {
            var iface = new InterfaceGen(CreateGenBaseSupport(pkg, elem, true))
            {
                ArgsType       = elem.XGetAttribute("argsType"),
                HasManagedName = elem.Attribute("managedName") != null,
                NoAlternatives = elem.XGetAttribute("no-alternatives") == "true",
                // Only use an explicitly set XML attribute
                Unnest = elem.XGetAttribute("unnest") == "true" ? true :
                         elem.XGetAttribute("unnest") == "false" ? false :
                         !options.SupportNestedInterfaceTypes
            };

            FillApiSince(iface, pkg, elem);
            SetLineInfo(iface, elem, options);

            foreach (var child in elem.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "implements":
                    string iname = child.XGetAttribute("name-generic-aware");
                    iname = iname.Length > 0 ? iname : child.XGetAttribute("name");
                    iface.AddImplementedInterface(iname);
                    break;

                case "method":
                    if (child.XGetAttribute("visibility") != "kotlin-internal")
                    {
                        iface.AddMethod(CreateMethod(iface, child, options));
                    }
                    break;

                case "field":
                    if (child.XGetAttribute("visibility") != "kotlin-internal")
                    {
                        iface.AddField(CreateField(iface, child, options));
                    }
                    break;

                case "typeParameters":
                    break;                             // handled at GenBaseSupport

                default:
                    Report.LogCodedWarning(0, Report.WarningUnexpectedInterfaceChild, iface, child.ToString());
                    break;
                }
            }

            return(iface);
        }
示例#7
0
 public bool Validate(CodeGenerationOptions opt, GenericParameterDefinitionList type_params, CodeGeneratorContext context)
 {
     sym = opt.SymbolTable.Lookup(type, type_params);
     if (sym == null)
     {
         Report.LogCodedWarning(0, Report.WarningUnknownParameterType, this, type, context.GetContextTypeMember());
         return(false);
     }
     if (!sym.Validate(opt, type_params, context))
     {
         Report.LogCodedWarning(0, Report.WarningInvalidParameterType, this, type, context.GetContextTypeMember());
         return(false);
     }
     return(true);
 }
 public bool Validate(CodeGenerationOptions opt, GenericParameterDefinitionList type_params, CodeGeneratorContext context)
 {
     sym = (IsEnumified ? opt.SymbolTable.Lookup(managed_type, type_params) : null) ?? opt.SymbolTable.Lookup(java_type, type_params);
     if (sym == null)
     {
         Report.LogCodedWarning(0, Report.WarningUnknownReturnType, owner, java_type, context.GetContextTypeMember());
         return(false);
     }
     if (!sym.Validate(opt, type_params, context))
     {
         Report.LogCodedWarning(0, Report.WarningInvalidReturnType, owner, java_type, context.GetContextTypeMember());
         return(false);
     }
     return(true);
 }
示例#9
0
        public List <GenBase> Parse(XDocument doc, IEnumerable <string> fixups, string apiLevel, int productVersion)
        {
            if (doc == null)
            {
                return(null);
            }
            try {
                var apiFixup = new ApiFixup(doc);
                apiFixup.Process(from fixup in fixups select Load(fixup), apiLevel, productVersion);
                ApiSource = apiFixup.ApiSource;
            } catch (XmlException ex) {
                // BG4200
                Report.LogCodedError(Report.ErrorFailedToProcessMetadata, ex.Message);
                return(null);
            }

            var root = doc.Root;

            if ((root == null) || !root.HasElements)
            {
                Report.LogCodedWarning(0, Report.WarningNoPackageElements);
                return(null);
            }

            List <GenBase> gens = new List <GenBase> ();

            foreach (var elem in root.Elements())
            {
                switch (elem.Name.LocalName)
                {
                case "package":
                    gens.AddRange(ParsePackage(elem));
                    break;

                case "enum":
                    ISymbol sym = new EnumSymbol(elem.XGetAttribute("name"));
                    opt.SymbolTable.AddType(elem.XGetAttribute("name"), sym);
                    continue;

                default:
                    Report.LogCodedWarning(0, Report.WarningUnexpectedRootChildNode, elem.Name.ToString());
                    break;
                }
            }

            return(gens);
        }
        public static List <GenBase> Parse(XDocument doc, CodeGenerationOptions options)
        {
            if (doc is null)
            {
                return(null);
            }

            var root = doc.Root;

            if ((root == null) || !root.HasElements)
            {
                Report.LogCodedWarning(0, Report.WarningNoPackageElements);
                return(null);
            }

            var gens = new List <GenBase> ();

            foreach (var elem in root.Elements())
            {
                switch (elem.Name.LocalName)
                {
                case "package":
                    gens.AddRange(ParsePackage(elem, options));
                    break;

                case "enum":
                    var name = elem.XGetAttribute("name");
                    var sym  = new EnumSymbol(name);
                    options.SymbolTable.AddType(name, sym);
                    continue;

                default:
                    Report.LogCodedWarning(0, Report.WarningUnexpectedRootChildNode, elem.Name.ToString());
                    break;
                }
            }

            return(gens);
        }
示例#11
0
        void Process(XDocument meta_doc, string apiLevelString, int productVersion)
        {
            int apiLevel = 0;

            int.TryParse(apiLevelString, out apiLevel);

            var      metadataChildren = meta_doc.XPathSelectElements("/metadata/*");
            string   prev_path        = null;
            XElement attr_last_cache  = null;

            foreach (var metaitem in metadataChildren)
            {
                if (ShouldSkip(metaitem, apiLevel, productVersion))
                {
                    continue;
                }
                if (!ShouldApply(metaitem))
                {
                    continue;
                }
                string path = metaitem.XGetAttribute("path");
                if (path != prev_path)
                {
                    attr_last_cache = null;
                }
                prev_path = path;

                switch (metaitem.Name.LocalName)
                {
                case "remove-node":
                    try {
                        var nodes = api_doc.XPathSelectElements(path).ToArray();
                        if (nodes.Any())
                        {
                            foreach (var node in nodes)
                            {
                                node.Remove();
                            }
                        }
                        else
                        {
                            // BG8A00
                            Report.LogCodedWarning(0, Report.WarningRemoveNodeMatchedNoNodes, null, metaitem, $"<remove-node path=\"{path}\" />");
                        }
                    } catch (XPathException e) {
                        // BG4301
                        Report.LogCodedError(Report.ErrorRemoveNodeInvalidXPath, e, metaitem, path);
                    }
                    break;

                case "add-node":
                    try {
                        var nodes = api_doc.XPathSelectElements(path);
                        if (!nodes.Any())
                        {
                            // BG8A01
                            Report.LogCodedWarning(0, Report.WarningAddNodeMatchedNoNodes, null, metaitem, $"<add-node path=\"{path}\" />");
                        }
                        else
                        {
                            foreach (var node in nodes)
                            {
                                node.Add(metaitem.Nodes());
                            }
                        }
                    } catch (XPathException e) {
                        // BG4302
                        Report.LogCodedError(Report.ErrorAddNodeInvalidXPath, e, metaitem, path);
                    }
                    break;

                case "change-node":
                    try {
                        var  nodes   = api_doc.XPathSelectElements(path);
                        bool matched = false;
                        foreach (var node in nodes)
                        {
                            var newChild = new XElement(metaitem.Value);
                            newChild.Add(node.Attributes());
                            newChild.Add(node.Nodes());
                            node.ReplaceWith(newChild);
                            matched = true;
                        }

                        if (!matched)
                        {
                            // BG8A03
                            Report.LogCodedWarning(0, Report.WarningChangeNodeTypeMatchedNoNodes, null, metaitem, $"<change-node-type path=\"{path}\" />");
                        }
                    } catch (XPathException e) {
                        // BG4303
                        Report.LogCodedError(Report.ErrorChangeNodeInvalidXPath, e, metaitem, path);
                    }
                    break;

                case "attr":
                    try {
                        string attr_name = metaitem.XGetAttribute("name");
                        if (string.IsNullOrEmpty(attr_name))
                        {
                            // BG4307
                            Report.LogCodedError(Report.ErrorMissingAttrName, null, metaitem, path);
                        }
                        var nodes        = attr_last_cache != null ? new XElement [] { attr_last_cache } : api_doc.XPathSelectElements(path);
                        int attr_matched = 0;
                        foreach (var n in nodes)
                        {
                            n.SetAttributeValue(attr_name, metaitem.Value);
                            attr_matched++;
                        }
                        if (attr_matched == 0)
                        {
                            // BG8A04
                            Report.LogCodedWarning(0, Report.WarningAttrMatchedNoNodes, null, metaitem, $"<attr path=\"{path}\" />");
                        }
                        if (attr_matched != 1)
                        {
                            attr_last_cache = null;
                        }
                    } catch (XPathException e) {
                        // BG4304
                        Report.LogCodedError(Report.ErrorAttrInvalidXPath, e, metaitem, path);
                    }
                    break;

                case "move-node":
                    try {
                        string parent  = metaitem.Value;
                        var    parents = api_doc.XPathSelectElements(parent);
                        bool   matched = false;
                        foreach (var parent_node in parents)
                        {
                            var nodes = parent_node.XPathSelectElements(path).ToArray();
                            foreach (var node in nodes)
                            {
                                node.Remove();
                            }
                            parent_node.Add(nodes);
                            matched = true;
                        }
                        if (!matched)
                        {
                            // BG8A05
                            Report.LogCodedWarning(0, Report.WarningMoveNodeMatchedNoNodes, null, metaitem, $"<move-node path=\"{path}\" />");
                        }
                    } catch (XPathException e) {
                        // BG4305
                        Report.LogCodedError(Report.ErrorMoveNodeInvalidXPath, e, metaitem, path);
                    }
                    break;

                case "remove-attr":
                    try {
                        string name    = metaitem.XGetAttribute("name");
                        var    nodes   = api_doc.XPathSelectElements(path);
                        bool   matched = false;

                        foreach (var node in nodes)
                        {
                            node.RemoveAttributes();
                            matched = true;
                        }

                        if (!matched)
                        {
                            // BG8A06
                            Report.LogCodedWarning(0, Report.WarningRemoveAttrMatchedNoNodes, null, metaitem, $"<remove-attr path=\"{path}\" />");
                        }
                    } catch (XPathException e) {
                        // BG4306
                        Report.LogCodedError(Report.ErrorRemoveAttrInvalidXPath, e, metaitem, path);
                    }
                    break;
                }
            }
        }
示例#12
0
        List <GenBase> ParsePackage(XElement ns, Predicate <XElement> p)
        {
            List <GenBase> result = new List <GenBase> ();
            Dictionary <string, GenBase> nested  = new Dictionary <string, GenBase> ();
            Dictionary <string, GenBase> by_name = new Dictionary <string, GenBase> ();

            foreach (var elem in ns.Elements())
            {
                string  name = elem.XGetAttribute("name");
                GenBase gen  = null;
                switch (elem.Name.LocalName)
                {
                case "class":
                    if (elem.XGetAttribute("obfuscated") == "true")
                    {
                        continue;
                    }
                    gen = XmlApiImporter.CreateClass(ns, elem, opt);
                    break;

                case "interface":
                    if (elem.XGetAttribute("obfuscated") == "true")
                    {
                        continue;
                    }
                    gen = XmlApiImporter.CreateInterface(ns, elem, opt);
                    break;

                default:
                    Report.LogCodedWarning(0, Report.WarningUnexpectedPackageChildNode, elem.Name.ToString());
                    break;
                }

                if (gen == null)
                {
                    continue;
                }
                int idx = name.IndexOf('<');
                if (idx > 0)
                {
                    name = name.Substring(0, idx);
                }
                by_name [name] = gen;
                if (name.IndexOf('.') > 0)
                {
                    nested [name] = gen;
                }
                else
                {
                    result.Add(gen);
                }
            }

            foreach (string name in nested.Keys)
            {
                string top_ancestor = name.Substring(0, name.IndexOf('.'));
                if (by_name.ContainsKey(top_ancestor))
                {
                    by_name [top_ancestor].AddNestedType(nested [name]);
                }
                else
                {
                    Report.LogCodedWarning(0, Report.WarningNestedTypeAncestorNotFound, top_ancestor, nested [name].FullName);
                    nested [name].Invalidate();
                }
            }
            return(result);
        }
        public static List <GenBase> ParsePackage(XElement ns, CodeGenerationOptions options)
        {
            var result  = new List <GenBase> ();
            var nested  = new Dictionary <string, GenBase> ();
            var by_name = new Dictionary <string, GenBase> ();

            foreach (var elem in ns.Elements())
            {
                var     name = elem.XGetAttribute("name");
                GenBase gen  = null;

                switch (elem.Name.LocalName)
                {
                case "class":
                    if (ShouldBind(elem))
                    {
                        gen = CreateClass(ns, elem, options);
                    }
                    break;

                case "interface":
                    if (ShouldBind(elem))
                    {
                        gen = CreateInterface(ns, elem, options);
                    }
                    break;

                default:
                    Report.LogCodedWarning(0, Report.WarningUnexpectedPackageChildNode, elem.Name.ToString());
                    break;
                }

                if (gen is null)
                {
                    continue;
                }

                var idx = name.IndexOf('<');

                if (idx > 0)
                {
                    name = name.Substring(0, idx);
                }

                by_name [name] = gen;

                if (name.IndexOf('.') > 0)
                {
                    nested [name] = gen;
                }
                else
                {
                    result.Add(gen);
                }
            }

            foreach (var name in nested.Keys)
            {
                var top_ancestor = name.Substring(0, name.IndexOf('.'));

                if (by_name.ContainsKey(top_ancestor))
                {
                    by_name [top_ancestor].AddNestedType(nested [name]);
                }
                else
                {
                    Report.LogCodedWarning(0, Report.WarningNestedTypeAncestorNotFound, top_ancestor, nested [name].FullName);
                    nested [name].Invalidate();
                }
            }

            return(result);
        }