using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.Parser;
using ASTContext = CppSharp.Parser.AST.ASTContext;
using NativeLibrary = CppSharp.Parser.AST.NativeLibrary;
namespace CppSharp
{
public class ClangParser
{
///
/// Context with translation units ASTs.
///
public ASTContext ASTContext { get; private set; }
///
/// Fired when source files are parsed.
///
public Action, ParserResult> SourcesParsed = delegate {};
///
/// Fired when library files are parsed.
///
public Action LibraryParsed = delegate {};
public ClangParser()
{
ASTContext = new ASTContext();
}
public ClangParser(ASTContext context)
{
ASTContext = context;
}
///
/// Get info about that target
///
///
///
public ParserTargetInfo GetTargetInfo(ParserOptions options)
{
options.ASTContext = ASTContext;
return Parser.ClangParser.GetTargetInfo(options);
}
///
/// Parses a C++ source file to a translation unit.
///
private ParserResult ParseSourceFile(SourceFile file)
{
var options = file.Options;
options.ASTContext = ASTContext;
options.AddSourceFiles(file.Path);
var result = Parser.ClangParser.ParseHeader(options);
SourcesParsed(new[] { file }, result);
return result;
}
///
/// Parses C++ source files to a translation unit.
///
private void ParseSourceFiles(IList files)
{
var options = files[0].Options;
options.ASTContext = ASTContext;
foreach (var file in files)
options.AddSourceFiles(file.Path);
using (var result = Parser.ClangParser.ParseHeader(options))
SourcesParsed(files, result);
}
///
/// Parses the project source files.
///
public void ParseProject(Project project, bool unityBuild)
{
// TODO: Search for cached AST trees on disk
// TODO: Do multi-threaded parsing of source files
if (unityBuild)
ParseSourceFiles(project.Sources);
else
foreach (var parserResult in project.Sources.Select(s => ParseSourceFile(s)).ToList())
parserResult.Dispose();
}
///
/// Parses a library file with symbols.
///
public ParserResult ParseLibrary(string file, ParserOptions options)
{
options.LibraryFile = file;
var result = Parser.ClangParser.ParseLibrary(options);
LibraryParsed(file, result);
return result;
}
///
/// Converts a native parser AST to a managed AST.
///
static public AST.ASTContext ConvertASTContext(ASTContext context)
{
var converter = new ASTConverter(context);
return converter.Convert();
}
public static AST.NativeLibrary ConvertLibrary(NativeLibrary library)
{
var newLibrary = new AST.NativeLibrary
{
FileName = library.FileName,
ArchType = (ArchType) library.ArchType
};
for (uint i = 0; i < library.SymbolsCount; ++i)
{
var symbol = library.GetSymbols(i);
newLibrary.Symbols.Add(symbol);
}
for (uint i = 0; i < library.DependenciesCount; i++)
{
newLibrary.Dependencies.Add(library.GetDependencies(i));
}
return newLibrary;
}
}
}