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); }
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); }
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); }
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); }
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); }
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); }
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; } } }
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); }