Beispiel #1
0
        public void GenerateScript(SymbolSet symbolSet)
        {
            Debug.Assert(symbolSet != null);

            var types = CollectEmittableTypes(symbolSet)
                        .OrderBy(t => t, typeComparer);

            // Sort the types, so similar types of types are grouped, and parent classes
            // come before derived classes.

            bool initialIndent = false;

            if (string.IsNullOrEmpty(Options.ScriptInfo.Template) == false)
            {
                int scriptIndex = Options.ScriptInfo.Template.IndexOf("{script}");

                if (scriptIndex > 0 && Options.ScriptInfo.Template[scriptIndex - 1] == ' ')
                {
                    // Heuristic to turn on initial indent:
                    // The script template has a space prior to {script}, i.e. {script} is not the
                    // first thing on a line within the template.

                    initialIndent = true;
                }
            }

            if (initialIndent)
            {
                Writer.Indent++;
            }

            foreach (TypeSymbol type in types)
            {
                TypeGenerator.GenerateScript(this, type);
            }

            GenerateModuleExports(symbolSet, types);

            foreach (TypeSymbol type in types)
            {
                if (type is ClassSymbol classSymbol)
                {
                    TypeGenerator.GenerateClassConstructorScript(this, classSymbol);
                }
            }

            if (initialIndent)
            {
                Writer.Indent--;
            }
        }
Beispiel #2
0
        public void GenerateScript(SymbolSet symbolSet)
        {
            Debug.Assert(symbolSet != null);

            List <TypeSymbol> types         = new List <TypeSymbol>();
            List <TypeSymbol> publicTypes   = new List <TypeSymbol>();
            List <TypeSymbol> internalTypes = new List <TypeSymbol>();

            bool hasNonModuleInternalTypes = false;

            foreach (NamespaceSymbol namespaceSymbol in symbolSet.Namespaces)
            {
                if (namespaceSymbol.HasApplicationTypes)
                {
                    foreach (TypeSymbol type in namespaceSymbol.Types)
                    {
                        if (type.IsApplicationType == false)
                        {
                            continue;
                        }

                        if (type.Type == SymbolType.Delegate)
                        {
                            // Nothing needs to be generated for delegate types.
                            continue;
                        }

                        if (type.Type == SymbolType.Enumeration &&
                            (type.IsPublic == false || ((EnumerationSymbol)type).Constants))
                        {
                            // Internal enums can be skipped since their values have been inlined.
                            // Public enums marked as constants can also be skipped since their
                            // values will always be inlined.
                            continue;
                        }

                        types.Add(type);

                        if (type.IsPublic)
                        {
                            publicTypes.Add(type);
                        }
                        else
                        {
                            if (type.Type != SymbolType.Class ||
                                ((ClassSymbol)type).IsModuleClass == false)
                            {
                                hasNonModuleInternalTypes = true;
                            }

                            internalTypes.Add(type);
                        }
                    }
                }
            }

            // Sort the types, so similar types of types are grouped, and parent classes
            // come before derived classes.
            IComparer <TypeSymbol> typeComparer = new TypeComparer();

            types         = types.OrderBy(t => t, typeComparer).ToList();
            publicTypes   = publicTypes.OrderBy(t => t, typeComparer).ToList();
            internalTypes = internalTypes.OrderBy(t => t, typeComparer).ToList();

            bool initialIndent = false;

            if (string.IsNullOrEmpty(Options.ScriptInfo.Template) == false)
            {
                int scriptIndex = Options.ScriptInfo.Template.IndexOf("{script}");

                if (scriptIndex > 0 && Options.ScriptInfo.Template[scriptIndex - 1] == ' ')
                {
                    // Heuristic to turn on initial indent:
                    // The script template has a space prior to {script}, i.e. {script} is not the
                    // first thing on a line within the template.

                    initialIndent = true;
                }
            }

            if (initialIndent)
            {
                Writer.Indent++;
            }

            foreach (TypeSymbol type in types)
            {
                TypeGenerator.GenerateScript(this, type);
            }

            bool generateModule = publicTypes.Count != 0 ||
                                  internalTypes.Count != 0 && hasNonModuleInternalTypes;

            if (generateModule)
            {
                Writer.Write($"var $exports = {DSharpStringResources.ScriptExportMember("module")}('");
                Writer.Write(symbolSet.ScriptName);
                Writer.Write("',");

                if (internalTypes.Count != 0 && hasNonModuleInternalTypes)
                {
                    Writer.WriteLine();
                    Writer.Indent++;
                    Writer.WriteLine("{");
                    Writer.Indent++;
                    bool firstType = true;

                    foreach (TypeSymbol type in internalTypes)
                    {
                        if (type.Type == SymbolType.Class &&
                            (((ClassSymbol)type).IsExtenderClass || ((ClassSymbol)type).IsModuleClass))
                        {
                            continue;
                        }

                        if (type.Type == SymbolType.Record &&
                            ((RecordSymbol)type).Constructor == null)
                        {
                            continue;
                        }

                        if (firstType == false)
                        {
                            Writer.WriteLine(",");
                        }

                        TypeGenerator.GenerateRegistrationScript(this, type);
                        firstType = false;
                    }

                    Writer.Indent--;
                    Writer.WriteLine();
                    Writer.Write("},");
                    Writer.Indent--;
                }
                else
                {
                    Writer.Write(" null,");
                }

                if (publicTypes.Count != 0)
                {
                    Writer.WriteLine();
                    Writer.Indent++;
                    Writer.WriteLine("{");
                    Writer.Indent++;
                    bool firstType = true;

                    foreach (TypeSymbol type in publicTypes)
                    {
                        if (type.Type == SymbolType.Class &&
                            ((ClassSymbol)type).IsExtenderClass)
                        {
                            continue;
                        }

                        if (firstType == false)
                        {
                            Writer.WriteLine(",");
                        }

                        TypeGenerator.GenerateRegistrationScript(this, type);
                        firstType = false;
                    }

                    Writer.Indent--;
                    Writer.WriteLine();
                    Writer.Write("}");
                    Writer.Indent--;
                }
                else
                {
                    Writer.Write(" null");
                }

                Writer.WriteLine(");");
                Writer.WriteLine();
            }

            foreach (TypeSymbol type in types)
            {
                if (type.Type == SymbolType.Class)
                {
                    TypeGenerator.GenerateClassConstructorScript(this, (ClassSymbol)type);
                }
            }

            if (initialIndent)
            {
                Writer.Indent--;
            }
        }
Beispiel #3
0
        private void GenerateModuleExports(SymbolSet symbolSet, IEnumerable <TypeSymbol> types)
        {
            if (!types.Any())
            {
                return;
            }

            IEnumerable <TypeSymbol> publicTypes   = types.Where(type => type.IsPublic);
            IEnumerable <TypeSymbol> internalTypes = types.Where(type => type.IsInternal);

            Writer.Write($"var $exports = {DSharpStringResources.ScriptExportMember("module")}('");
            Writer.Write(symbolSet.ScriptName);
            Writer.Write("',");

            if (internalTypes.Any())
            {
                Writer.WriteLine();
                Writer.Indent++;
                Writer.WriteLine("{");
                Writer.Indent++;
                bool firstType = true;

                foreach (TypeSymbol type in internalTypes)
                {
                    if (type.Type == SymbolType.Record && ((RecordSymbol)type).Constructor == null)
                    {
                        continue;
                    }

                    if (firstType == false)
                    {
                        Writer.WriteLine(",");
                    }

                    TypeGenerator.GenerateRegistrationScript(this, type);
                    firstType = false;
                }

                Writer.Indent--;
                Writer.WriteLine();
                Writer.Write("},");
                Writer.Indent--;
            }
            else
            {
                Writer.Write(" null,");
            }

            if (publicTypes.Any())
            {
                Writer.WriteLine();
                Writer.Indent++;
                Writer.WriteLine("{");
                Writer.Indent++;
                bool firstType = true;

                foreach (TypeSymbol type in publicTypes)
                {
                    if (firstType == false)
                    {
                        Writer.WriteLine(",");
                    }

                    TypeGenerator.GenerateRegistrationScript(this, type);
                    firstType = false;
                }

                Writer.Indent--;
                Writer.WriteLine();
                Writer.Write("}");
                Writer.Indent--;
            }
            else
            {
                Writer.Write(" null");
            }

            Writer.WriteLine(");");
            Writer.WriteLine();
        }