예제 #1
0
        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);
        }
예제 #2
0
        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;
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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();
            }
        }
예제 #6
0
 private void ReadApiType_apiOperationClassifier(DocItem doc)
 {
     doc.ApiType = ReadValue();
 }
예제 #7
0
 private void ReadApiType(DocItem doc)
 {
     doc.ApiType = GetAttribute("value");
 }
예제 #8
0
        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;
            }
        }
예제 #9
0
        /// <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;
                    }
                }
            }
        }
예제 #10
0
        public void Parse(Dictionary<string, DocItem> packageDocs)
        {
            docs = packageDocs;

            DocItem doc = new DocItem();
            MoveToContent();
            while (Read())
                ProcessDeclarationNodes(doc);

            docs = null;
        }
예제 #11
0
        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
            }
        }
예제 #12
0
 private void ReadApiType_apiOperationClassifier(DocItem doc)
 {
     doc.ApiType = ReadValue();
 }
예제 #13
0
 private void ReadApiType(DocItem doc)
 {
     doc.ApiType = GetAttribute("value");
 }
예제 #14
0
        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);
        }
예제 #15
0
        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;
            }
        }
예제 #16
0
        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);
        }
예제 #17
0
        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;
                }
            }
        }