コード例 #1
0
    private static void ProcessType(FxRedist redist, MemberDeclarationSyntax syntax, SemanticModel typeModel, string currentNamespace, ReportWriter reportWriter)
    {
        ISymbol symbol = typeModel.GetDeclaredSymbol(syntax);
        string  typeId = symbol.GetDocumentationCommentId();

        var typeName = typeId.Substring(2);

        if (FxdacSyntaxRewriter.s_ShouldRemoveType(typeName))
        {
            reportWriter.WriteListItem("Removed type {0}", symbol.Name);
            return;
        }
        FxAssembly typeAssembly = redist.GetAssemblyForType(typeId);

        if (typeAssembly.HasEmitedType(typeId))
        {
            return;
        }

        // rewrite type
        var rewriter = new FxdacSyntaxRewriter(reportWriter, typeModel, typeAssembly.Name);

        syntax = (MemberDeclarationSyntax)syntax.Accept(rewriter);

        // add type to assembly
        var typeSyntax = new FxType()
        {
            Declaration = syntax, Symbol = (ITypeSymbol)symbol
        };

        typeAssembly.AddType(currentNamespace, typeSyntax);
    }
コード例 #2
0
    static bool CompileAssemblies(FxRedist redist)
    {
        bool failed = false;
        Queue <FxAssembly> toCompile = new Queue <FxAssembly>(redist.Values);
        List <FxAssembly>  sorted    = new List <FxAssembly>();

        while (toCompile.Count > 0)
        {
            var a = toCompile.Dequeue();
            if (HasAllDependencies(a, sorted))
            {
                sorted.Add(a);
            }
            else
            {
                toCompile.Enqueue(a);
            }
        }

        foreach (var a in sorted)
        {
            if (HasAllDependencies(a, sorted))
            {
                if (!CompileAssembly(a))
                {
                    a.FailedToCompile = true;
                    failed            = true;
                }
            }
        }

        return(!failed);
    }
コード例 #3
0
    private static bool RefactorAssemblies(ReportWriter reportWriter, out FxRedist redist)
    {
        // prepare the right folders
        PrepareOutputFolder(s_OutputSources);
        PrepareOutputFolder(s_OutputDlls);

        // load files describing the desired factoring. verify consistency of these files.
        redist = new FxRedist();
        if (!ProcessSpecifications(redist, reportWriter))
        {
            Console.WriteLine("\nPress ENTER to exit ...");
            Console.ReadLine();
            return(false);
        }

        // compile master file
        reportWriter.WriteListStart("REMOVED");

        AddSourcesToRedist(reportWriter, redist, s_MasterAPIFile);
        AddSourcesToRedist(reportWriter, redist, s_CoreFxAPIFile);

        reportWriter.WriteListEnd();

        // generate and compile factored assemblies
        GenerateSources(redist);
        var successfulBuild = CompileAssemblies(redist);

        // warn about types that are not in any of the factored assemblies
        if (redist.Leftover.CountOfTypes > 0)
        {
            WriteMessage(ConsoleColor.Yellow, "\n{0} type[s] not assigned to an assembly", redist.Leftover.CountOfTypes);
        }

        return(successfulBuild);
    }
コード例 #4
0
    private static void AddSourcesToRedist(ReportWriter reportWriter, FxRedist redist, string source)
    {
        var parsedSource = CSharpSyntaxTree.ParseText(File.ReadAllText(source));

        var           compilation = CSharpCompilation.Create("mscorlib", new SyntaxTree[] { parsedSource });
        SemanticModel semantic    = compilation.GetSemanticModel(parsedSource);

        // assign roslyn syntax objects (types) to facored assemblies
        var masterCompilationUnit = parsedSource.GetCompilationUnitRoot();

        foreach (var memberSyntax in masterCompilationUnit.Members)
        {
            ProcessTypeOrNamespace(redist, memberSyntax, semantic, null, reportWriter);
        }
    }
コード例 #5
0
    private static bool ProcessSpecification(FxRedist redist, Dictionary <string, string> alreadyLoadedSpecification, string assemblySpecificationFile)
    {
        bool success  = true;
        var  assembly = new FxAssembly();

        assembly.Name = Path.GetFileNameWithoutExtension(assemblySpecificationFile);
        redist.Add(assembly.Name, assembly);
        string[] assemblySpecification = File.ReadAllLines(assemblySpecificationFile);

        Dictionary <string, int> unique = new Dictionary <string, int>();

        foreach (var specificationLine in assemblySpecification)
        {
            var line = specificationLine.Trim();
            if (string.IsNullOrWhiteSpace(line))
            {
                continue;
            }
            if (line.StartsWith("//"))
            {
                continue;                        // comment
            }
            if (line.StartsWith("/r:"))
            {
                assembly.References.Add(line.Substring(3));
                continue;
            }

            try {
                unique.Add("T:" + line, 0);

                try {
                    alreadyLoadedSpecification.Add(line, assemblySpecificationFile);
                }
                catch (ArgumentException) {
                    WriteMessage(ConsoleColor.Red, "{0} in files {1} and {2}", line, assemblySpecificationFile, alreadyLoadedSpecification[line]);
                    success = false;
                }
            }
            catch (ArgumentException) {
                WriteMessage(ConsoleColor.Yellow, "Type {1} duplicated in {0}", assemblySpecificationFile, line);
                success = false;
            }
        }

        assembly.Types.AddRange(unique.Keys);
        return(success);
    }
コード例 #6
0
    static void ProcessTypeOrNamespace(FxRedist redist, MemberDeclarationSyntax syntax, SemanticModel typeModel, string currentNamespace, ReportWriter reportWriter)
    {
        var namespaceSyntax = syntax as NamespaceDeclarationSyntax;

        // process all types in namespace
        if (namespaceSyntax != null)
        {
            foreach (var namespaceMember in namespaceSyntax.Members)
            {
                string namespaceName = namespaceSyntax.Name.ToString();
                ProcessTypeOrNamespace(redist, namespaceMember, typeModel, namespaceName, reportWriter);
            }
            return;
        }

        ProcessType(redist, syntax, typeModel, currentNamespace, reportWriter);
    }
コード例 #7
0
    static void PrintOrphanedTypes(FxRedist redist, ReportWriter reportWriter)
    {
        var assembliesWithOrphanedTypes = redist.Where((a) => a.Value.OrphanedTypes.Count != 0).Select((a) => a.Value).ToList();

        if (s_logOrphanedTypes && assembliesWithOrphanedTypes.Count != 0)
        {
            reportWriter.WriteListStart("ORPHANED_TYPES", "description", "Orphaned types are types in the specifications that don't exist in master source.");
            foreach (var assembly in assembliesWithOrphanedTypes)
            {
                var orphanedTypes = assembly.OrphanedTypes;
                WriteMessage(ConsoleColor.Yellow, "Orphaned types in {0}", assembly.Name);

                foreach (var type in orphanedTypes)
                {
                    reportWriter.WriteListItem("{0}", type);
                }
            }
            reportWriter.WriteListEnd();
        }
    }
コード例 #8
0
    private static void AnalyzeLayers(FxRedist redist, ReportWriter reportWriter)
    {
        var assemblies = new List <FxAssembly>(redist.Values);

        assemblies.Remove(redist.Leftover);
        Dictionary <int, List <FxAssembly> > layers = new Dictionary <int, List <FxAssembly> >();
        int layerNumber = 0;

        while (assemblies.Count != 0)
        {
            var avaliabledependencies = layers.Values.SelectMany((l) => { return(l); }).ToList();

            var nextLayer = new List <FxAssembly>();
            layers.Add(layerNumber, nextLayer);

            for (int i = assemblies.Count - 1; i >= 0; i--)
            {
                var assembly = assemblies[i];
                if (HasAllDependencies(assembly, avaliabledependencies))
                {
                    nextLayer.Add(assembly);
                    assemblies.RemoveAt(i);
                }
            }
            layerNumber++;
        }

        reportWriter.WriteListStart("Layers");
        for (int i = 0; i < layers.Count; i++)
        {
            var layer = layers[i];
            reportWriter.WriteListStart("Layer", "number", i);
            foreach (var a in layer)
            {
                reportWriter.WriteListItem(a.Name);
            }
            reportWriter.WriteListEnd();
        }
        reportWriter.WriteListEnd();
    }
コード例 #9
0
    static bool ProcessSpecifications(FxRedist redist, ReportWriter reportWriter)
    {
        Console.WriteLine("PROCESSING SPECIFICATIONS");

        Dictionary <string, string> alreadyLoadedSpecification = new Dictionary <string, string>();

        var allFiles = Directory.GetFiles(s_SpecificationFolder);

        foreach (var assemblySpecificationFile in allFiles)
        {
            if (!ProcessSpecification(redist, alreadyLoadedSpecification, assemblySpecificationFile))
            {
                return(false);
            }
        }

        foreach (var a in redist)
        {
            foreach (var reference in a.Value.References)
            {
                var referenceName = Path.GetFileNameWithoutExtension(reference);
                if (a.Value.Name == referenceName)
                {
                    WriteMessage(ConsoleColor.Red, "Assembly {0} references itself.", a.Value.Name);
                    return(false);
                }

                if (!redist.Values.Any((a2) => {
                    return(a2.Name == referenceName);
                }))
                {
                    WriteMessage(ConsoleColor.Red, "Assembly {0} references {1} that does not exist.", a.Value.Name, reference);
                    return(false);
                }
            }
        }
        return(true);
    }
コード例 #10
0
 static void GenerateSources(FxRedist assemblies)
 {
     foreach (var module in assemblies)
     {
         string file = s_OutputSources + "\\" + module.Key + ".cs";
         module.Value.SourceFile = file;
         StreamWriter sw = new StreamWriter(file);
         sw.WriteLine("[assembly:System.CLSCompliant(true)]");
         foreach (var ns in module.Value)
         {
             sw.WriteLine("namespace {0} {{", ns.Key);
             foreach (var type in ns.Value)
             {
                 if (type.Declaration != null)
                 {
                     sw.Write(type.Declaration.ToFullString());
                 }
             }
             sw.WriteLine("}} // end of {0}", ns.Key);
         }
         sw.Close();
     }
 }