Exemplo n.º 1
0
        public Variable(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
            : this(super)
        {
            var Child = elem.Elements();

            foreach (XElement e in Child)
            {
                switch (e.Name.LocalName)
                {
                case "ident":
                    this.Name = e.Attribute("text").Value;
                    break;

                case "question":
                    this.Optional = true;
                    break;

                case "type":
                    this.Type = Tool.NewType(e, context);
                    break;

                case "k_export":
                    this.Public = true;
                    break;

                case "k_static":
                    this.Static = true;
                    break;

                case "string":
                    this.hasString = true;
                    break;
                }
            }
        }
Exemplo n.º 2
0
        public FunctionType(XElement elem, TypeScriptDefContext context)
            : this()
        {
            var Params = elem.Element("paramlist");

            if (Params != null)
            {
                var  ParamListElem = Params.Elements();
                bool Spread        = false;

                foreach (XElement e in ParamListElem)
                {
                    if (e.Name.LocalName == "spreadop")
                    {
                        Spread = true;
                    }
                    else
                    {
                        Param p = new Param(e, null, false, context);

                        p.Spread = Spread;
                        this.Params.Add(p);
                        Spread = false;
                    }
                }
            }

            this.ReturnType = Tool.NewType(elem.Element("type"), context);
        }
Exemplo n.º 3
0
 public AnonymousType(XElement elem, TypeScriptDefContext context)
     : this()
 {
     this.Class      = new Class(elem, null, context);
     this.Class.Name = "AnonymousType" + AnonID++;
     this.Class.AddContent(elem, context);
     //this.Class.Super = new Namespace();
     //this.Class.Super.Name = "AnonymousTypes";
     context.CurrentGeneratedFiles.Add(context.OutputDirectory + "AnonymousTypes\\" + this.Class.Name + ".cs");
 }
Exemplo n.º 4
0
        // The Namespace is the only Model element where we don't parse it into the constructor
        // This is to avoid duplicating a same Namespace
        public Namespace(XElement elem, Namespace super, string name, TypeScriptDefContext context) : this(super, context)
        {
            this.Super = super;
            this.Name  = name;

            // The static class is always named [NamespaceNames]Class
            this.StaticClass.Name = name + "Class";
            if (elem != null)
            {
                this.AddContent(elem.Element("namespacecontent"), context);
            }
        }
Exemplo n.º 5
0
        // Create if needed a namespace
        // If there is already ns1.ns2 in this namespace
        // and you call it with ns1.ns2.ns3.ns4
        // it will only create ns3 and ns4 and add the content into ns4
        public void AddChildNamespace(XElement elem, TypeScriptDefContext context)
        {
            // Get the full name of the added namespace (ex: "ns1.ns2")
            var Name = Tool.GetIdent(elem);
            // Split the full name into an array
            var name = Name.Split('.');
            // Temporary variables
            Container <Declaration> tmp = this;
            Class     cls = null;
            Namespace ns  = null;

            // While there are names in the array
            while (name.Count() > 0)
            {
                // Check if there is a class in tmp matching the first remaining name
                cls = tmp.OfType <Class>().FirstOrDefault(t =>
                                                          t.Name == name[0]
                                                          );
                // If there is one, it means the added namespace references one
                // of its child classes, so tmp become this class
                if (cls != null)
                {
                    tmp = cls;
                }
                // If there is no matching class and tmp is a namespace
                else if (tmp is Namespace)
                {
                    // Search for a matching namespace in tmp
                    ns = tmp.OfType <Namespace>().FirstOrDefault(n =>
                                                                 n.Name == name[0]
                                                                 );
                    // If there isn't one
                    if (ns == null)
                    {
                        // Create it
                        ns = new Namespace(null, (Namespace)tmp, name[0], context);
                        ((Namespace)tmp).Declarations.Add(ns);
                    }
                    // Now we are sure that the namespace exists, so tmp become this one
                    tmp = ns;
                }
                // We remove the first name (the one we created if needed)
                name = name.Skip(1).ToArray();
            }

            // Now that there is no more name in the array
            // tmp is either the class referenced by the added namespace
            // or the added namespace itself
            // In either case we add its content
            tmp.AddContent(elem.Element("namespacecontent"), context);
        }
Exemplo n.º 6
0
        public Class(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
            : base(elem, super, context)
        {
            this.InitProperties();

            this.Name = Tool.GetIdent(elem);
            if (this.Name == null)
            {
                this.Name = "";
            }
            // Split based on '\\' is done if the interface has name based on the .t.ds or xml file
            // if this file is in subfolder, it's name will include some '\\' (or '/', that's the same here)
            // But this doesn't seems to work right now, need to fix it
            string[] path = this.Name.Split('\\');
            // Name is in fact the last element of the path
            this.Name = path.Last();
            // We remove the name from the path
            path = path.Take(path.Count() - 1).ToArray();
            // Prefix is now the first file path (without the name)
            if (path.Count() > 0)
            {
                this.Prefix = string.Join("\\", path) + "\\";
            }
            else
            {
                this.Prefix = "";
            }

            // Parsing the "extends" parts (inheritance)
            //var Extends = elem.Element("extends");
            //if (Extends != null)
            //{
            //    foreach (XElement e in Extends.Elements())
            //    {
            //        if (e.Name.LocalName == "dotident")
            //        {
            //            var b = new BasicType(e);
            //            if (b.ToString(this.Super) != "object")
            //                this.Inherit.Add(b.ToString(this.Super));
            //        }
            //        else if (e.Name.LocalName == "generic")
            //        {
            //            var g = new Generic(e, context);
            //            this.Inherit.Add(g.ToString(this.Super));
            //        }
            //    }
            //}
        }
Exemplo n.º 7
0
        // Parse and add content to this namespace
        public void AddContent(XElement content, TypeScriptDefContext context)
        {
#if LOG_VERBOSE
            context.Logger.WriteMessage("AddContent: '" + this.Name + "'");
#endif
            foreach (XElement elem in content.Elements())
            {
                switch (elem.Name.LocalName)
                {
                case "import":
                    this.Imports.Add(new Import(elem));
                    break;

                case "namespace":
                    this.AddChildNamespace(elem, context);     // We don't add it directly because maybe the namespace already exists
                    break;

                // Variable directly in the namespace
                case "variable":
                    this.StaticClass.Properties.Add(new Property(elem, this.StaticClass, context)
                    {
                        Static = true
                    });
                    break;

                // Function directly in the namespace
                case "function":
                    this.StaticClass.Methods.Add(new Method(elem, this.StaticClass, context)
                    {
                        Static = true
                    });
                    break;

                case "enum":
                    this.Declarations.Add(TypeDeclaration.New(elem, this, context));
                    break;

                case "interface":
                    this.Declarations.Add(TypeDeclaration.New(elem, this, context));
                    break;

                case "class":
                    this.Declarations.Add(TypeDeclaration.New(elem, this, context));
                    break;
                }
            }
        }
Exemplo n.º 8
0
        // This is simply boring XML parsing, should've used deserialization but at this time I was a noob sorry
        public GlobalProgram(XDocument doc, string name, TypeScriptDefContext context)
            : this(context)
        {
            this.Name = name;
            var      Child = doc.Root.Elements();
            string[] path  = name.Split('.');
            this.StaticClass.Name = path.Last() + "Class";

            foreach (XElement elem in Child)
            {
                switch (elem.Name.LocalName)
                {
                case "import":
                    this.Imports.Add(new Import(elem));
                    break;

                case "namespace":
                    this.AddChildNamespace(elem, context);     // We don't add it directly because maybe the namespace already exists
                    break;

                // Variable directly in the namespace
                case "variable":
                    this.StaticClass.Properties.Add(new Property(elem, this.StaticClass, context)
                    {
                        Static = true
                    });
                    break;

                // Function directly in the namespace
                case "function":
                    this.StaticClass.Methods.Add(new Method(elem, this.StaticClass, context)
                    {
                        Static = true
                    });
                    break;

                case "interface":
                    this.Declarations.Add(TypeDeclaration.New(elem, this, context));
                    break;

                case "class":
                    this.Declarations.Add(TypeDeclaration.New(elem, this, context));
                    break;
                }
            }
        }
Exemplo n.º 9
0
        // Parse and add content to this class
        public void AddContent(XElement content, TypeScriptDefContext context)
        {
            foreach (XElement e in content.Elements())
            {
                switch (e.Name.LocalName)
                {
                // Properties
                case "variable":
                    this.AddProperty(new Property(e, this, context));
                    break;

                // Methods
                case "function":
                    Method m = new Method(e, this, context);
                    if (!m.HasString)
                    {
                        this.AddMethod(m);
                    }
                    if (m.Name == "constructor" && m.Params.Count == 0)
                    {
                        this.HasParameterlessConstructor = true;
                    }
                    break;

                // If the class is a generic and has some "generic arguments"
                case "generic_arg":
                    this.GenericArg = e.Attribute("text").Value;
                    break;

                // Nested interfaces
                case "interface":
                    this.AddTypeDeclaration(TypeDeclaration.New(e, this, context));
                    break;

                // Nested classes
                case "class":
                    this.AddTypeDeclaration(TypeDeclaration.New(e, this, context));
                    break;

                // Nested enums
                case "enum":
                    this.AddTypeDeclaration(TypeDeclaration.New(e, this, context));
                    break;
                }
            }
        }
Exemplo n.º 10
0
        public Namespace(Namespace super, TypeScriptDefContext context) : base(super)
        {
            this.Declarations = new HashSet <Declaration>();
            this.Imports      = new List <Import>();
            this.StaticClass  = new Class(this)
            {
                Static = true
            };

            // Those are basic usings to allow good working
            this.Imports.Add(new Import()
            {
                Alias = "CSHTML5", Name = "CSHTML5"
            });                                                                     // Allow Interop calls
            this.Imports.Add(new Import()
            {
                Alias = "System", Name = "System"
            });
            this.Imports.Add(new Import()
            {
                Alias = "System.Collections.Generic", Name = "System.Collections.Generic"
            });

            // Those are usings that can be useful here
            this.Imports.Add(new Import()
            {
                Alias = "AnonymousTypes", Name = "AnonymousTypes"
            });
            this.Imports.Add(new Import()
            {
                Alias = "ToJavaScriptObjectExtender", Name = "ToJavaScriptObjectExtender"
            });
            this.Imports.Add(new Import()
            {
                Alias = "TypeScriptDefinitionsSupport", Name = "TypeScriptDefinitionsSupport"
            });

            // Those are aliases that are needed to compile, but they can also be added in the CSHTML5.Core
            //this.Imports.Add(new Import() { Alias = "EventListenerOrEventListenerObject", Name = "UnionType<webworker_generated.EventListener, webworker_generated.EventListenerObject>" });
            //this.Imports.Add(new Import() { Alias = "AlgorithmIdentifier", Name = "UnionType<System.String, webworker_generated.Algorithm>" });
            //this.Imports.Add(new Import() { Alias = "IDBKeyPath", Name = "System.String" });
            //this.Imports.Add(new Import() { Alias = "IDBValidKey", Name = "UnionType<System.Int32, System.Double, System.String, System.DateTime, webworker_generated.IDBArrayKey>" });
            //this.Imports.Add(new Import() { Alias = "BufferSource", Name = "System.Collections.Generic.List<object>" });
        }
Exemplo n.º 11
0
        public Generic(XElement elem, TypeScriptDefContext context)
            : this()
        {
            this.Name = elem.Element("generic").Attribute("text").Value;

            if (elem.Element("type") != null)
            {
                var types = Tool.NewType(elem.Element("type"), context);

                if (types is UnionTypeModel)
                {
                    this.TypeList = ((UnionTypeModel)types).Types;
                }
                else
                {
                    this.TypeList.Add((TSType)types);
                }
            }
        }
Exemplo n.º 12
0
        public Enum(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
            : base(elem, super, context)
        {
            this.InitProperties();

            foreach (XElement e in elem.Elements())
            {
                if (e.Name.LocalName != "ident")
                {
                    throw new Exception();
                }
                if (this.Name == null)
                {
                    this.Name = e.Attribute("text").Value;
                }
                else
                {
                    this.Values.Add(e.Attribute("text").Value);
                }
            }
        }
Exemplo n.º 13
0
        // Exports each children list
        public override void Export(TypeScriptDefContext context)
        {
#if LOG_VERBOSE
            context.Logger.WriteMessage("Namespace Export: '" + this.FullName(".") + "'");
#endif
            foreach (Declaration d in this.Declarations)
            {
#if LOG_VERBOSE
                if (d is Class)
                {
                    context.Logger.WriteMessage("Class: '" + this.FullName(".") + "." + d.Name + "'");
                }
#endif
                d.Export(context);
            }

            // Export the static class only if there is at least a property or a method
            if (StaticClass.Properties.Any() || StaticClass.Methods.Any())
            {
                StaticClass.Export(context);
            }
        }
Exemplo n.º 14
0
        public void AddContent(XElement content, TypeScriptDefContext context)
        {
            int spread = 0;

            foreach (XElement e in content.Elements())
            {
                if (e.Name.LocalName == "variable")
                {
                    Param p = new Param(e, this, spread == 1, context);
                    if (p.hasString)
                    {
                        this.HasString = true;
                    }
                    this.Params.Add(p);
                }
                else if (e.Name.LocalName == "spreadop")
                {
                    spread = 2;
                }
                spread--;
            }
        }
Exemplo n.º 15
0
        // Exporting a Class create a new file (like exporting Interface or Enum)
        public override void Export(TypeScriptDefContext context)
        {
            var res = new StringBuilder();
            // Get the imports of the Super Namespace and it's parents
            var imports = this.FirstAncestor <Namespace>().GetImportList();

            // Join them with a NewLine as separator (overrided imports.ToString() format it as needed)
            res.Append(string.Join(Environment.NewLine, imports));

            // If there was is at least an import, we add a NewLine (useless but pretty)
            if (imports.Any())
            {
                res.AppendLine(Environment.NewLine);
            }

            // Put the class in the good namespace (with full namespace's name)
            res.Append("namespace ")
            .AppendLine(this.Super.FullName("."))
            .AppendLine("{");

            // Write the class and close the namespace
            res.Append(this.ToString())
            .AppendLine("}");

            // Get the destination path (namespace structure)
            string path = context.OutputDirectory + this.Super.FullName("\\") + "\\" + this.Prefix;

            // If needed, create the destination folder
            Directory.CreateDirectory(path);

            string fileName = path + this.Name + ".cs";

            File.WriteAllText(fileName, Tool.ReIndent(res.ToString()));
            if (context.CurrentGeneratedFiles != null)
            {
                context.CurrentGeneratedFiles.Add(fileName);
            }
        }
Exemplo n.º 16
0
        public override void Export(TypeScriptDefContext context)
        {
            var res     = new StringBuilder();
            var imports = this.FirstAncestor <Namespace>().GetImportList();

            res.Append(string.Join(Environment.NewLine, imports));
            if (imports.Any())
            {
                res.AppendLine(Environment.NewLine);
            }

            res.Append("namespace ")
            .AppendLine(Super.FullName("."))
            .AppendLine("{");

            res.Append(this.ToString())
            .AppendLine("}");

            // Get the destination path (namespace structure)
            string path = Super.FullName("\\") + "\\";
            // Get the full relative file path
            string fullPath = context.OutputDirectory + path + this.Name + ".cs";

            // Split the full path
            string[] tmp = fullPath.Split('\\');
            // Remove the filename from the path
            tmp = tmp.Take(tmp.Count() - 1).ToArray();
            // If needed, create the destination folder
#if LOG_VERBOSE
            context.Logger.WriteMessage("enum: " + fullPath);
#endif
            Directory.CreateDirectory(string.Join("\\", tmp));

            File.WriteAllText(fullPath, Tool.ReIndent(res.ToString()));
            context.CurrentGeneratedFiles.Add(fullPath);
        }
Exemplo n.º 17
0
        public Function(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
            : this(super)
        {
            this.Name = elem.Element("function").Attribute("text").Value;

            while (this.Name.Length > 0 && this.Name[this.Name.Length - 1] == ' ')
            {
                this.Name = this.Name.Remove(this.Name.Length - 1);
            }

            if (this.Name.Length > 0 && this.Name[this.Name.Length - 1] == '?')
            {
                this.Optional = true;
                this.Name     = this.Name.Remove(this.Name.Length - 1);
            }

            var paramlist = elem.Element("paramlist");
            if (paramlist != null)
            {
                this.AddContent(paramlist, context);
            }

            this.ReturnType = Tool.NewType(elem.Element("type"), context);
        }
Exemplo n.º 18
0
 public void Export(TypeScriptDefContext context)
 {
     this.Class.Export(context);
 }
Exemplo n.º 19
0
        // Return the TypeDeclaration instance associated with a given XML type declaration,
        // or a newly created one that is added to the dictionary if it doesn't exist
        private static TypeDeclaration GetInstance(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
        {
            Type   typeDeclarationClass = TypeDeclaration.GetClass(elem);
            string typeDeclarationName  = TypeDeclaration.GetFullName(elem);

            try
            {
                var inst = TypeDeclaration.Instances[typeDeclarationName];

                // We update the declaration's Super if it wasn't specified previously
                // (needed for type declarations instanciated because of a variable of that type)
                if (inst.Super == null)
                {
                    inst.Super = super;
                }

                return(inst);
            }
            catch (KeyNotFoundException)
            {
                var inst = (TypeDeclaration)Activator.CreateInstance(typeDeclarationClass, elem, super, context);
                TypeDeclaration.Instances[typeDeclarationName] = inst;

                // We add content after updating the dictionary to avoid cycles
                // when declarations refer to their ancestors
                if (inst is Container <Declaration> )
                {
                    ((Container <Declaration>)inst).AddContent(elem, context);
                }

                return(inst);
            }
        }
Exemplo n.º 20
0
        // Check if a given type name is declared somewhere in a given XML subtree,
        // and return the associated TypeDeclaration instance if it is, null otherwise
        private static TypeDeclaration New(string[] name, XElement root, Container <Declaration> super, TypeScriptDefContext context)
        {
            // We create a list of the elements we're going to inspect
            var elems = new List <XElement>();

            // First we inspect the root itself (except if it is the global namespace)
            if (root.Name.LocalName != "start")
            {
                elems.Add(root);
            }
            // If there is no declaration directly in the root, we inspect its children
            IEnumerable <XElement> children;

            // We need to handle the special case of namespace elements,
            // which do not hold their declarations as direct children
            if (root.Name.LocalName == "namespace")
            {
                children = root.Element("namespacecontent").Elements();
            }
            else
            {
                children = root.Elements();
            }
            elems.AddRange(children);

            // Then for each element in the list
            foreach (XElement e in elems)
            {
                // First we make sure that it correponds either to a TypeDeclaration or a Container<TypeDeclaration>
                Type typeDeclarationClass       = TypeDeclaration.GetClass(e);
                bool isTypeDeclarationContainer = TypeDeclaration.IsTypeDeclarationContainer(e);

                if (typeDeclarationClass != null || isTypeDeclarationContainer)
                {
                    // The element identifier must be at most as long as the type name
                    string[] ident = Tool.GetIdent(e).Split('.');
                    if (ident.Length <= name.Length)
                    {
                        // If the hole identifier matches the beginning of the name
                        int match = ident.ToList().FirstMismatchIndex(name.ToList());
                        if (match == ident.Length)
                        {
                            // Either the beginning is actually the type (local) name...
                            if (name.Length == 1)
                            {
                                // ...and if the element is associated with a TypeDeclaration class,
                                // it means we have found a valid declaration, so we return an instance of said class
                                if (typeDeclarationClass != null)
                                {
                                    return(TypeDeclaration.GetInstance(e, super, context));
                                }
                            }
                            // Or the beginning is just the name of an ancestor container...
                            else if (isTypeDeclarationContainer)
                            {
                                // ...and therefore we call the method recursively on the element
                                var res = TypeDeclaration.New(name.Skip(match).ToArray(), e, super, context);
                                // If we found a valid declaration during the recursive call, we return it
                                if (res != null)
                                {
                                    return(res);
                                }
                                // Otherwise there might be another container with the same name, so we keep searching.
                                // For example it is possible that class a.b does not contain the declaration,
                                // while namespace a.b, which is going to be merged with class a.b by the compiler, does contain it.
                            }
                        }
                    }
                }
            }

            // If there is no element containing a declaration, we return null
            return(null);
        }
Exemplo n.º 21
0
        // Take either an XML type declaration or a type.dotident element, and return the associated
        // TypeDeclaration instance if it is declared somewhere in the XML, null otherwise
        public static TypeDeclaration New(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
        {
            // If the argument passed is an XML type declaration, we don't search
            // in the XML and directly return the associated instance
            if (TypeDeclaration.GetClass(elem) != null)
            {
                return(TypeDeclaration.GetInstance(elem, super, context));
            }

            string[]        name = elem.Attribute("text").Value.Split('.');
            XElement        parent;
            TypeDeclaration typeDeclaration = null;

            do
            {
                // We check if there is a declaration in the current namespace
                parent = elem.Ancestors().FirstOrDefault(e => TypeDeclaration.IsTypeDeclarationContainer(e));
                if (parent != null)
                {
                    typeDeclaration = TypeDeclaration.New(name, parent, super, context);
                    elem            = parent;
                }
            }
            // If not, we check in the parent namespace, and if not in the parent of the parent,
            // and so on until we reach the root namespace
            while (typeDeclaration == null && parent != null);

            return(typeDeclaration);
        }
Exemplo n.º 22
0
 public Property(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
     : base(elem, super, context)
 {
 }
Exemplo n.º 23
0
 public GlobalProgram(TypeScriptDefContext context)
     : base(null, context)
 {
 }
Exemplo n.º 24
0
 public Param(XElement elem, Container <Declaration> super, bool spread, TypeScriptDefContext context)
     : base(elem, super, context)
 {
     this.Spread = spread;
 }
Exemplo n.º 25
0
 public Method(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
     : base(elem, super, context)
 {
     this.IsConstructor = (this.Name == "constructor");
 }
Exemplo n.º 26
0
 public TypeDeclaration(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
     : this(super)
 {
     ((TSType)this).Name = TypeDeclaration.GetFullName(elem);
 }
Exemplo n.º 27
0
 public Namespace(XElement elem, Namespace super, TypeScriptDefContext context)
     : this(elem, super, Tool.GetIdent(elem), context)
 {
 }
Exemplo n.º 28
0
 public Signature(XElement elem, Container <Declaration> super, TypeScriptDefContext context)
     : base(elem, super, context)
 {
 }
Exemplo n.º 29
0
 public virtual void Export(TypeScriptDefContext context)
 {
     throw new NotImplementedException();
 }