private void ReadExcludeMeta(DocItem doc) { if (!HasAttributes) { return; } ASMetaData meta = new ASMetaData("Style"); meta.Kind = ASMetaKind.Exclude; string sKind = GetAttribute("kind"); string sName = GetAttribute("name"); if (doc.Meta == null) { doc.Meta = new List <ASMetaData>(); } meta.Params = new Dictionary <string, string>(); meta.Params["kind"] = sKind; meta.Params["name"] = sName; meta.RawParams = String.Format("kind=\"{0}\", name=\"{1}\"", sKind, sName); doc.Meta.Add(meta); }
private void ReadParamDesc(DocItem doc) { if (IsEmptyElement) { return; } string name = null; string desc = null; string eon = Name; ReadStartElement(); while (Name != eon) { if (NodeType == XmlNodeType.Element) { switch (Name) { case "apiItemName": name = ReadValue(); break; case "apiDesc": desc = ReadValue(); break; } } Read(); } if (name != null && desc != null) { if (doc.Params == null) { doc.Params = new Dictionary <string, string>(); } doc.Params[name] = desc; } }
private void ReadExcludeMeta(DocItem doc) { if (!HasAttributes) return; ASMetaData meta = new ASMetaData("Style"); meta.Kind = ASMetaKind.Exclude; string sKind = GetAttribute("kind"); string sName = GetAttribute("name"); if (doc.Meta == null) doc.Meta = new List<ASMetaData>(); meta.Params = new Dictionary<string, string>(); meta.Params["kind"] = sKind; meta.Params["name"] = sName; meta.RawParams = String.Format("kind=\"{0}\", name=\"{1}\"", sKind, sName); doc.Meta.Add(meta); }
private void ReadParamDesc(DocItem doc) { if (IsEmptyElement) return; string name = null; string desc = null; string eon = Name; ReadStartElement(); while (Name != eon) { if (NodeType == XmlNodeType.Element) switch (Name) { case "apiItemName": name = ReadValue(); break; case "apiDesc": desc = ReadValue(); break; } Read(); } if (name != null && desc != null) { if (doc.Params == null) doc.Params = new Dictionary<string, string>(); doc.Params[name] = desc; } }
private void ReadReturnsDesc(DocItem doc) { if (IsEmptyElement) return; string eon = Name; ReadStartElement(); while (Name != eon) { if (Name == "apiDesc") doc.Returns = ReadValue(); if (Name == "apiType") ReadApiType(doc); if (Name == "apiOperationClassifier") ReadApiType_apiOperationClassifier(doc); Read(); } }
private void ReadApiType_apiOperationClassifier(DocItem doc) { doc.ApiType = ReadValue(); }
private void ReadApiType(DocItem doc) { doc.ApiType = GetAttribute("value"); }
private void ProcessDeclarationNodes(DocItem doc) { if (NodeType != XmlNodeType.Element) return; switch (Name) { case "shortdesc": doc.ShortDesc = ReadValue(); break; case "apiDesc": doc.LongDesc = ReadValue(); break; case "apiData": doc.Value = ReadValue(); break; case "apiValueClassifier": if (ReadValue() == "String") doc.Value = '"' + doc.Value + '"'; break; case "style": ReadStyleMeta(doc); break; case "Exclude": ReadExcludeMeta(doc); break; case "adobeApiEvent": ReadEventMeta(doc); break; case "apiName": break; // TODO validate event name case "apiClassifier": case "apiConstructor": case "apiValue": case "apiOperation": ReadDeclaration(); break; case "apiParam": ReadParamDesc(doc); break; case "apiReturn": ReadReturnsDesc(doc); break; case "apiInheritDoc": break; // TODO link inherited doc? //case "apiConstructorDetail": //case "apiOperationDetail": case "apiClassifierDetail": case "apiDetail": case "related-links": SkipContents(); break; case "prolog": SkipContents(); break; // TODO parse metadata case "apiType": ReadApiType(doc); break; case "apiOperationClassifier": ReadApiType_apiOperationClassifier(doc); break; } }
/// <summary> /// Create virtual FileModel objects from Abc bytecode /// </summary> /// <param name="abcs"></param> /// <param name="path"></param> /// <param name="context"></param> public static void Convert(ContentParser parser, PathModel path, IASContext context) { path.Files.Clear(); inSWF = Path.GetExtension(path.Path).ToLower() == ".swf"; // extract documentation ParseDocumentation(parser); // extract models FileModel privateClasses = new FileModel(Path.Combine(path.Path, "__Private.as")); privateClasses.Version = 3; privateClasses.Package = "private"; genericTypes = new Dictionary <string, FileModel>(); imports = new Dictionary <string, string>(); foreach (Abc abc in parser.Abcs) { // types foreach (Traits trait in abc.classes) { Traits instance = trait.itraits; if (instance == null) { continue; } imports.Clear(); FileModel model = new FileModel(""); model.Context = context; model.Package = reSafeChars.Replace(instance.name.uri, "_"); model.HasPackage = true; string filename = reSafeChars.Replace(trait.name.ToString(), "_").TrimEnd('$'); filename = Path.Combine(model.Package.Replace('.', Path.DirectorySeparatorChar), filename); model.FileName = Path.Combine(path.Path, filename); model.Version = 3; ClassModel type = new ClassModel(); model.Classes = new List <ClassModel>(); model.Classes.Add(type); type.InFile = model; type.Type = instance.name.ToTypeString(); type.Name = instance.name.localName; thisDocs = GetDocs(model.Package); if (thisDocs != null) { docPath = (model.Package.Length > 0 ? model.Package + ":" : "globalClassifier:") + type.Name; if (thisDocs.ContainsKey(docPath)) { DocItem doc = thisDocs[docPath]; setDoc(doc, type); if (doc.Meta != null) { model.MetaDatas = doc.Meta; } } if (model.Package.Length == 0) { docPath = type.Name; } } if (instance.baseName.uri == model.Package) { type.ExtendsType = ImportType(instance.baseName.localName); } else { type.ExtendsType = ImportType(instance.baseName); } if (instance.interfaces != null && instance.interfaces.Length > 0) { type.Implements = new List <string>(); foreach (QName name in instance.interfaces) { type.Implements.Add(ImportType(name)); } } if (model.Package == "private") { model.Package = ""; type.Access = Visibility.Private; type.Namespace = "private"; } else if (model.Package == "__AS3__.vec") { model.Package = ""; type.Access = Visibility.Private; type.Namespace = "private"; string genType = type.Name; if (type.Name.IndexOf("$") > 0) { string[] itype = type.Name.Split('$'); genType = itype[0]; type.Name = itype[0] + "$" + itype[1]; type.IndexType = itype[1]; } if (genericTypes.ContainsKey(genType)) { model.Classes.Clear(); type.InFile = genericTypes[genType]; genericTypes[genType].Classes.Add(type); } else { genericTypes[genType] = model; } } else if (type.Name.StartsWith("_")) { type.Access = Visibility.Private; type.Namespace = "private"; } else { type.Access = Visibility.Public; type.Namespace = "public"; } type.Flags = FlagType.Class; if (instance.flags == TraitMember.Function) { type.Flags |= FlagType.Interface; } type.Members = GetMembers(trait.members, FlagType.Static, instance.name); type.Members.Add(GetMembers(instance.members, FlagType.Dynamic, instance.name)); if ((type.Flags & FlagType.Interface) > 0) { // TODO properly support interface multiple inheritance type.ExtendsType = null; if (type.Implements != null && type.Implements.Count > 0) { type.ExtendsType = type.Implements[0]; type.Implements.RemoveAt(0); if (type.Implements.Count == 0) { type.Implements = null; } } foreach (MemberModel member in type.Members) { member.Access = Visibility.Public; member.Namespace = ""; } } // constructor if (instance.init != null && (type.Flags & FlagType.Interface) == 0) { List <MemberInfo> temp = new List <MemberInfo>(new MemberInfo[] { instance.init }); MemberList result = GetMembers(temp, 0, instance.name); if (result.Count > 0) { MemberModel ctor = result[0]; ctor.Flags |= FlagType.Constructor; ctor.Access = Visibility.Public; ctor.Type = type.Type; ctor.Namespace = "public"; type.Members.Merge(result); type.Constructor = ctor.Name; } result = null; temp = null; } else { type.Constructor = type.Name; } if (type.Access == Visibility.Private) { model = privateClasses; type.InFile = model; } if (model.Classes.Count > 0 || model.Members.Count > 0) { AddImports(model, imports); path.AddFile(model); } } // packages if (abc.scripts == null) { continue; } foreach (Traits trait in abc.scripts) { FileModel model = null; foreach (MemberInfo info in trait.members) { if (info.kind == TraitMember.Class) { continue; } MemberModel member = GetMember(info, 0); if (member == null) { continue; } if (model == null || model.Package != info.name.uri) { AddImports(model, imports); string package = info.name.uri ?? ""; string filename = package.Length > 0 ? "package.as" : "toplevel.as"; filename = Path.Combine(package.Replace('.', Path.DirectorySeparatorChar), filename); filename = Path.Combine(path.Path, filename); if (path.HasFile(filename)) { model = path.GetFile(filename); } else { model = new FileModel(""); model.Context = context; model.Package = package; model.HasPackage = true; model.FileName = filename; model.Version = 3; path.AddFile(model); } } thisDocs = GetDocs(model.Package); if (thisDocs != null) { docPath = "globalOperation:" + (model.Package.Length > 0 ? model.Package + ":" : "") + member.Name; if (member.Access == Visibility.Public && !String.IsNullOrEmpty(member.Namespace) && member.Namespace != "public") { docPath += member.Namespace + ":"; } if ((member.Flags & FlagType.Setter) > 0) { docPath += ":set"; } else if ((member.Flags & FlagType.Getter) > 0) { docPath += ":get"; } if (thisDocs.ContainsKey(docPath)) { setDoc(thisDocs[docPath], member); } } member.InFile = model; member.IsPackageLevel = true; model.Members.Add(member); } AddImports(model, imports); } } if (privateClasses.Classes.Count > 0) { path.AddFile(privateClasses); } // some SWCs need manual fixes CustomFixes(path); // fake SWC (like 'playerglobal_rb.swc', only provides documentation) if (path.Files.Count == 1) { foreach (FileModel model in path.Files.Values) { if (model.GetPublicClass().QualifiedName == "Empty") { path.Files.Clear(); break; } } } }
public void Parse(Dictionary<string, DocItem> packageDocs) { docs = packageDocs; DocItem doc = new DocItem(); MoveToContent(); while (Read()) ProcessDeclarationNodes(doc); docs = null; }
private static void setDoc(DocItem doc, MemberModel decl) { decl.Comments = doc.LongDesc; if (doc.Value != null) decl.Value = doc.Value; if (!String.IsNullOrEmpty(doc.ApiType) && doc.ApiType.EndsWith("*/")) { // TODO Extract features in comments } }
private void ReadStyleMeta(DocItem doc) { if (IsEmptyElement || !HasAttributes) return; ASMetaData meta = new ASMetaData("Style"); meta.Kind = ASMetaKind.Style; meta.Comments = ""; string sName = GetAttribute("name"); string sType = GetAttribute("type"); //string sInherit = GetAttribute("inherit"); //string sFormat = GetAttribute("format"); string sEnum = GetAttribute("enumeration"); string sDefault = null; string eon = Name; ReadStartElement(); while (Name != eon) { if (NodeType == XmlNodeType.Element) switch (Name) { case "description": meta.Comments = ReadValue() ?? ""; break; case "default": sDefault = ReadValue(); break; } Read(); } if (doc.Meta == null) doc.Meta = new List<ASMetaData>(); if (sDefault != null) meta.Comments = meta.Comments.Trim() + "\n@default\t" + sDefault; meta.Params = new Dictionary<string, string>(); meta.Params["name"] = sName; meta.Params["type"] = sType; meta.RawParams = String.Format("name=\"{0}\", type=\"{1}\"", sName, sType); if (sEnum != null) { meta.Params["enumeration"] = sEnum; meta.RawParams += ", enumeration=\"" + sEnum + "\""; } doc.Meta.Add(meta); }
private void ReadDeclaration() { if (IsEmptyElement) return; DocItem doc = new DocItem(); string id = GetAttribute("id"); if (id != null) { // type doubled in doc: "flash.utils:IDataOutput:flash.utils:IDataOutput:writeDouble" int colon = id.IndexOf(':') + 1; if (colon > 0) { int dup = id.IndexOf(id.Substring(0, colon), colon); if (dup > 0) id = id.Substring(dup); } doc.ApiType = id; } string eon = Name; ReadStartElement(); while (Name != eon) { ProcessDeclarationNodes(doc); Read(); } if (id != null) { if (doc.LongDesc == null) doc.LongDesc = ""; if (doc.ShortDesc == null) doc.ShortDesc = doc.LongDesc; else doc.LongDesc = doc.LongDesc.Trim(); if (doc.LongDesc.Length == 0 && doc.ShortDesc.Length > 0) doc.LongDesc = doc.ShortDesc; if (doc.Params != null) foreach (string name in doc.Params.Keys) doc.LongDesc += "\n@param\t" + name + "\t" + doc.Params[name].Trim(); if (doc.Returns != null) doc.LongDesc += "\n@return\t" + doc.Returns.Trim(); if (doc.ShortDesc.Length > 0 || doc.LongDesc.Length > 0) docs[id] = doc; } }
private void ReadEventMeta(DocItem doc) { if (IsEmptyElement) return; ASMetaData meta = new ASMetaData("Event"); meta.Kind = ASMetaKind.Event; meta.Comments = ""; string eName = null; string eType = null; string eFullType = null; string eon = Name; ReadStartElement(); while (Name != eon) { if (NodeType == XmlNodeType.Element) switch (Name) { case "shortdesc": meta.Comments = ReadValue() ?? ""; break; case "apiDesc": if (meta.Comments == "") meta.Comments = ReadValue() ?? ""; break; case "apiName": eName = ReadValue(); break; case "adobeApiEventClassifier": eType = ReadValue().Replace(':', '.'); break; case "apiEventType": eFullType = ReadValue(); break; } Read(); } if (doc.Meta == null) doc.Meta = new List<ASMetaData>(); meta.Params = new Dictionary<string, string>(); meta.Params["name"] = eName; meta.Params["type"] = eType; if (eFullType != null) meta.Comments = meta.Comments.Trim() + "\n@eventType\t" + eFullType.Replace(':', '.'); meta.RawParams = String.Format("name=\"{0}\", type=\"{1}\"", eName, eType); doc.Meta.Add(meta); }
private void ReadDeclaration() { if (IsEmptyElement) { return; } DocItem doc = new DocItem(); string id = GetAttribute("id"); if (id != null) { // type doubled in doc: "flash.utils:IDataOutput:flash.utils:IDataOutput:writeDouble" int colon = id.IndexOf(':') + 1; if (colon > 0) { int dup = id.IndexOf(id.Substring(0, colon), colon); if (dup > 0) { id = id.Substring(dup); } } doc.ApiType = id; } string eon = Name; ReadStartElement(); while (Name != eon) { ProcessDeclarationNodes(doc); Read(); } if (id != null) { if (doc.LongDesc == null) { doc.LongDesc = ""; } if (doc.ShortDesc == null) { doc.ShortDesc = doc.LongDesc; } else { doc.LongDesc = doc.LongDesc.Trim(); } if (doc.LongDesc.Length == 0 && doc.ShortDesc.Length > 0) { doc.LongDesc = doc.ShortDesc; } if (doc.Params != null) { foreach (string name in doc.Params.Keys) { doc.LongDesc += "\n@param\t" + name + "\t" + doc.Params[name].Trim(); } } if (doc.Returns != null) { doc.LongDesc += "\n@return\t" + doc.Returns.Trim(); } if (doc.ShortDesc.Length > 0 || doc.LongDesc.Length > 0) { docs[id] = doc; } } }