mirror of https://github.com/mono/CppSharp.git
1 changed files with 16 additions and 77 deletions
@ -1,103 +1,42 @@ |
|||||||
using System.Collections.Generic; |
using System.Collections.Generic; |
||||||
using System.IO; |
using System.IO; |
||||||
|
using System.Linq; |
||||||
using System.Text; |
using System.Text; |
||||||
using CppSharp.AST; |
using CppSharp.AST; |
||||||
using CppAbi = CppSharp.Parser.AST.CppAbi; |
|
||||||
|
|
||||||
namespace CppSharp.Passes |
namespace CppSharp.Passes |
||||||
{ |
{ |
||||||
public class GenerateInlinesCodePass : TranslationUnitPass |
public class GenerateInlinesCodePass : TranslationUnitPass |
||||||
{ |
{ |
||||||
private TranslationUnit currentUnit; |
public GenerateInlinesCodePass() |
||||||
private readonly List<string> headers = new List<string>(); |
{ |
||||||
private readonly List<string> mangledInlines = new List<string>(); |
this.SkipPatterns = new List<string>(); |
||||||
|
} |
||||||
|
|
||||||
|
public List<string> SkipPatterns { get; private set; } |
||||||
|
|
||||||
public override bool VisitLibrary(ASTContext context) |
public override bool VisitLibrary(ASTContext context) |
||||||
{ |
{ |
||||||
bool result = base.VisitLibrary(context); |
bool result = base.VisitLibrary(context); |
||||||
Directory.CreateDirectory(Driver.Options.OutputDir); |
Directory.CreateDirectory(Driver.Options.OutputDir); |
||||||
WriteInlinesIncludes(); |
WriteInlinesIncludes(context); |
||||||
WriteInlinedSymbols(); |
|
||||||
return result; |
return result; |
||||||
} |
} |
||||||
|
|
||||||
private void WriteInlinesIncludes() |
private void WriteInlinesIncludes(ASTContext context) |
||||||
{ |
{ |
||||||
var cppBuilder = new StringBuilder(); |
var cppBuilder = new StringBuilder(); |
||||||
headers.Sort(); |
foreach (var header in from translationUnit in context.TranslationUnits |
||||||
foreach (var header in headers) |
where translationUnit.IsValid && !translationUnit.IsSystemHeader && |
||||||
|
translationUnit.GenerationKind == GenerationKind.Generate |
||||||
|
let fileName = translationUnit.FileName |
||||||
|
where SkipPatterns.All(p => !fileName.EndsWith(p)) |
||||||
|
orderby fileName |
||||||
|
select fileName) |
||||||
cppBuilder.AppendFormat("#include \"{0}\"\n", header); |
cppBuilder.AppendFormat("#include \"{0}\"\n", header); |
||||||
var cpp = string.Format("{0}.cpp", Driver.Options.InlinesLibraryName); |
var cpp = string.Format("{0}.cpp", Driver.Options.InlinesLibraryName); |
||||||
var path = Path.Combine(Driver.Options.OutputDir, cpp); |
var path = Path.Combine(Driver.Options.OutputDir, cpp); |
||||||
File.WriteAllText(path, cppBuilder.ToString()); |
File.WriteAllText(path, cppBuilder.ToString()); |
||||||
} |
} |
||||||
|
|
||||||
private void WriteInlinedSymbols() |
|
||||||
{ |
|
||||||
switch (Driver.Options.Abi) |
|
||||||
{ |
|
||||||
case CppAbi.Microsoft: |
|
||||||
var defBuilder = new StringBuilder("EXPORTS\r\n"); |
|
||||||
for (int i = 0; i < mangledInlines.Count; i++) |
|
||||||
defBuilder.AppendFormat(" {0} @{1}\r\n", |
|
||||||
mangledInlines[i], i + 1); |
|
||||||
var def = string.Format("{0}.def", Driver.Options.InlinesLibraryName); |
|
||||||
File.WriteAllText(Path.Combine(Driver.Options.OutputDir, def), |
|
||||||
defBuilder.ToString()); |
|
||||||
break; |
|
||||||
default: |
|
||||||
var symbolsBuilder = new StringBuilder(); |
|
||||||
foreach (var mangledInline in mangledInlines) |
|
||||||
symbolsBuilder.AppendFormat("{0}\n", mangledInline); |
|
||||||
var txt = string.Format("{0}.txt", Driver.Options.InlinesLibraryName); |
|
||||||
File.WriteAllText(Path.Combine(Driver.Options.OutputDir, txt), |
|
||||||
symbolsBuilder.ToString()); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
public override bool VisitTranslationUnit(TranslationUnit unit) |
|
||||||
{ |
|
||||||
currentUnit = unit; |
|
||||||
return base.VisitTranslationUnit(unit); |
|
||||||
} |
|
||||||
|
|
||||||
public override bool VisitFunctionDecl(Function function) |
|
||||||
{ |
|
||||||
CheckForSymbols(function); |
|
||||||
return base.VisitFunctionDecl(function); |
|
||||||
} |
|
||||||
|
|
||||||
public override bool VisitVariableDecl(Variable variable) |
|
||||||
{ |
|
||||||
CheckForSymbols(variable); |
|
||||||
return base.VisitVariableDecl(variable); |
|
||||||
} |
|
||||||
|
|
||||||
private void CheckForSymbols(IMangledDecl mangled) |
|
||||||
{ |
|
||||||
string symbol = mangled.Mangled; |
|
||||||
var declaration = (Declaration) mangled; |
|
||||||
if (declaration.IsGenerated && AccessValid(declaration) && |
|
||||||
!Driver.Symbols.FindSymbol(ref symbol) && |
|
||||||
!currentUnit.FilePath.EndsWith("_impl.h") && |
|
||||||
!currentUnit.FilePath.EndsWith("_p.h")) |
|
||||||
{ |
|
||||||
if (!headers.Contains(currentUnit.FileName)) |
|
||||||
headers.Add(currentUnit.FileName); |
|
||||||
if (!mangledInlines.Contains(mangled.Mangled)) |
|
||||||
mangledInlines.Add(mangled.Mangled); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
private static bool AccessValid(Declaration declaration) |
|
||||||
{ |
|
||||||
if (declaration.Access == AccessSpecifier.Private) |
|
||||||
{ |
|
||||||
var method = declaration as Method; |
|
||||||
return method != null && method.IsOverride; |
|
||||||
} |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|||||||
Loading…
Reference in new issue