Exemple #1
0
        void AddTypeAndNamespaceFromSyntax(TypeSyntax typeSyntax, bool convertedType)
        {
            if (convertedType)
            {
                throw new NotImplementedException();
            }

            {
                TypeInfo    typeInfo            = currentFileModel.semanticModel.GetTypeInfo(typeSyntax);
                ITypeSymbol typeSymbol          = typeInfo.Type;
                ITypeSymbol convertedTypeSymbol = typeInfo.ConvertedType;
                if (typeSymbol != null)
                {
                    AddTypeAndNamespace(typeSymbol);
                    return;
                }
            }

            // the type syntax was not a type
            SymbolInfo symbolInfo = currentFileModel.semanticModel.GetSymbolInfo(typeSyntax);

            if (symbolInfo.Symbol == null)
            {
                throw new InvalidOperationException();
            }
            if (CSharpToD.generateDebug)
            {
                writer.Write("// '{0}' is not a type, it is a(n) '{1}'",
                             typeSyntax.GetText().ToString().Trim().Replace("\n", "").Replace("\r\n", ""),
                             symbolInfo.Symbol.Kind);
            }
        }
        public void GenerateCode()
        {
            if (CSharpToD.log)
            {
                this.log = new BufferedNativeFileSink(NativeFile.Open(
                                                          Path.Combine(CSharpToD.logDirectory, projectModels.outputName),
                                                          FileMode.Create, FileAccess.Write, FileShare.ReadWrite), new byte[256]);
            }

            // Determine File Name
            String projectSourceDirectory;

            if (namespaceTree.subnodes.Count == 0)
            {
                projectSourceDirectory = null;
                this.filenameFullPath  = Path.Combine(CSharpToD.generatedCodePath, projectModels.outputName + ".d");
            }
            else
            {
                projectSourceDirectory = Path.Combine(CSharpToD.generatedCodePath,
                                                      projectModels.outputName);
                this.filenameFullPath = Path.Combine(projectSourceDirectory, "package.d");
            }

            ProjectFirstPassVisitor firstPass;

            SynchronizedDirectoryCreator.Create(Path.GetDirectoryName(filenameFullPath));
            Console.WriteLine("Creating D Source File '{0}'...", filenameFullPath);
            using (DlangWriter writer = new DlangWriter(new BufferedNativeFileSink(
                                                            NativeFile.Open(filenameFullPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite), new byte[512])))
            {
                writer.WriteLine("module {0};", projectModels.outputName);
                writer.WriteLine();

                //
                // First Pass: find imports
                //
                firstPass = new ProjectFirstPassVisitor(writer, log);
                this.namespaceTree.FirstPassVisit(firstPass);

                //
                // Write Imports
                //
                foreach (KeyValuePair <String, HashSet <TypeSymbolAndArity> > namespaceAndTypes in firstPass.typeSymbolsByNamespace)
                {
                    String @namespace = namespaceAndTypes.Key;
                    if (@namespace.Length > 0)
                    {
                        writer.WriteLine("import {0}.{1} :", projectModels.outputName, @namespace);
                        writer.Tab();
                        uint typeIndex = 0;
                        uint lastIndex = (uint)namespaceAndTypes.Value.Count - 1;
                        foreach (TypeSymbolAndArity typeSymbol in namespaceAndTypes.Value)
                        {
                            writer.Write(typeSymbol.name);
                            if (typeSymbol.arity > 0)
                            {
                                writer.Write("{0}", typeSymbol.arity);
                            }
                            if (typeIndex < lastIndex)
                            {
                                writer.WriteLine(",");
                            }
                            else
                            {
                                writer.WriteLine(";");
                            }
                            typeIndex++;
                        }
                        writer.Untab();
                    }
                }

                //
                // Generate Code
                //
                {
                    var generator = new ProjectVisitorGenerator(this, writer, firstPass);
                    this.namespaceTree.GenerateCode(writer, generator);
                }
            }

            //
            // Generate Namespace Alias Files
            //
            foreach (KeyValuePair <String, HashSet <TypeSymbolAndArity> > namespaceAndTypes in firstPass.typeSymbolsByNamespace)
            {
                String @namespace = namespaceAndTypes.Key;
                if (@namespace.Length > 0)
                {
                    //
                    // Determine Namespace Alias Filename
                    //
                    String namespaceAliasFilename;
                    {
                        Boolean namespaceHasChildNamespaces = false;
                        foreach (string otherNamespace in firstPass.typeSymbolsByNamespace.Keys)
                        {
                            if (otherNamespace.Length > @namespace.Length &&
                                otherNamespace.StartsWith(@namespace))
                            {
                                namespaceHasChildNamespaces = true;
                                break;
                            }
                        }

                        String filenameRelative;
                        if (namespaceHasChildNamespaces)
                        {
                            filenameRelative = Path.Combine(
                                @namespace.Replace('.', Path.DirectorySeparatorChar), "package.d");
                        }
                        else
                        {
                            int lastDotIndex = @namespace.LastIndexOf('.');
                            if (lastDotIndex < 0)
                            {
                                filenameRelative = @namespace + ".d";
                            }
                            else
                            {
                                filenameRelative = Path.Combine(
                                    @namespace.Remove(lastDotIndex).Replace('.', Path.DirectorySeparatorChar),
                                    @namespace.Substring(lastDotIndex + 1) + ".d");
                            }
                        }
                        namespaceAliasFilename = Path.Combine(projectSourceDirectory, filenameRelative);
                        namespaceFiles.Add(namespaceAliasFilename);
                        //Console.WriteLine("[DEBUG] Namespace '{0}' going to file '{1}'", @namespace, filenameFullPath);
                    }

                    SynchronizedDirectoryCreator.Create(Path.GetDirectoryName(namespaceAliasFilename));
                    Console.WriteLine("Creating D Source File '{0}'...", namespaceAliasFilename);
                    using (DlangWriter writer = new DlangWriter(new BufferedNativeFileSink(
                                                                    NativeFile.Open(namespaceAliasFilename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite), new byte[512])))
                    {
                        writer.WriteLine("module {0}.{1};", projectModels.outputName, @namespace);
                        writer.WriteLine();
                        writer.WriteLine("static import {0};", projectModels.outputName);
                        writer.WriteLine();
                        foreach (TypeSymbolAndArity typeSymbol in namespaceAndTypes.Value)
                        {
                            if (typeSymbol.arity > 0)
                            {
                                writer.WriteLine("alias {0}{1} = {2}.{3}.{0}{1};",
                                                 typeSymbol.name, typeSymbol.arity, projectModels.outputName, @namespace);
                            }
                            else
                            {
                                writer.WriteLine("alias {0} = {1}.{2}.{0};",
                                                 typeSymbol.name, projectModels.outputName, @namespace);
                            }
                        }
                    }
                }
            }
        }