Browse Source

Sorted modules by the dependencies of their libraries, if any, before parsing.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/658/head
Dimitar Dobrev 9 years ago
parent
commit
19b0131543
  1. 19
      src/Generator/Driver.cs
  2. 40
      src/Generator/Utils/IEnumerableExtensions.cs

19
src/Generator/Driver.cs

@ -14,6 +14,7 @@ using Microsoft.CSharp; @@ -14,6 +14,7 @@ using Microsoft.CSharp;
using CppSharp.Parser;
using System;
using System.Reflection;
using CppSharp.Utils;
namespace CppSharp
{
@ -98,6 +99,23 @@ namespace CppSharp @@ -98,6 +99,23 @@ namespace CppSharp
Options.SetupMSVC();
}
public void SortModulesByDependencies()
{
if (Options.Modules.All(m => m.Libraries.Any()))
{
var sortedModules = Options.Modules.TopologicalSort(m =>
{
return from library in Symbols.Libraries
where m.Libraries.Contains(library.FileName)
from module in Options.Modules
where library.Dependencies.Intersect(module.Libraries).Any()
select module;
});
Options.Modules.Clear();
Options.Modules.AddRange(sortedModules);
}
}
void OnSourceFileParsed(IList<SourceFile> files, ParserResult result)
{
OnFileParsed(files.Select(f => f.Path), result);
@ -492,6 +510,7 @@ namespace CppSharp @@ -492,6 +510,7 @@ namespace CppSharp
if (!options.Quiet)
Log.Message("Parsing code...");
driver.SortModulesByDependencies();
driver.BuildParseOptions();
if (!driver.ParseCode())

40
src/Generator/Utils/IEnumerableExtensions.cs

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
namespace CppSharp.Utils
{
public static class IEnumerableExtensions
{
public static IList<T> TopologicalSort<T>(this ICollection<T> source, Func<T, IEnumerable<T>> dependencies, bool throwOnCycle = false)
{
var sorted = new List<T>();
var visited = new HashSet<T>();
foreach (var item in source)
Visit(item, source, visited, sorted, dependencies, throwOnCycle);
return sorted;
}
private static void Visit<T>(T item, ICollection<T> source, ISet<T> visited, ICollection<T> sorted, Func<T, IEnumerable<T>> dependencies, bool throwOnCycle)
{
if (!visited.Contains(item))
{
visited.Add(item);
foreach (var dep in dependencies(item))
Visit(dep, source, visited, sorted, dependencies, throwOnCycle);
if (source.Contains(item))
{
sorted.Add(item);
}
}
else
{
if (throwOnCycle && !sorted.Contains(item))
throw new Exception("Cyclic dependency found");
}
}
}
}
Loading…
Cancel
Save