using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace CppSharp.AST { public enum CppAbi { Itanium, Microsoft, ARM, iOS, iOS64 } /// /// A library contains all the modules. /// public class ASTContext { public List TranslationUnits; public ASTContext() { TranslationUnits = new List(); } static private string NormalizeTranslationUnitFilePath(string name) { if (name.StartsWith("<")) return name; try { name = Path.GetFullPath(name); } catch (ArgumentException) { // Normalization errors are expected when dealing with virtual // compiler files like . } return name; } /// Finds an existing or creates a new one translation unit given a path. public TranslationUnit FindOrCreateTranslationUnit(string file) { file = NormalizeTranslationUnitFilePath(file); var translationUnit = TranslationUnits.Find(m => m.FilePath.Equals(file)); if (translationUnit == null) { translationUnit = new TranslationUnit(file); TranslationUnits.Add(translationUnit); } return translationUnit; } /// Finds an existing enum in the library modules. public IEnumerable FindEnum(string name) { return TranslationUnits.Select( module => module.FindEnum(name)).Where(type => type != null); } /// Finds the complete declaration of an enum. public Enumeration FindCompleteEnum(string name) { return FindEnum(name).FirstOrDefault(@enum => !@enum.IsIncomplete); } /// Finds an existing struct/class in the library modules. public IEnumerable FindClass(string name, bool create = false, bool ignoreCase = false) { return TranslationUnits.Select( module => module.FindClass(name, ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal)) .Where(type => type != null); } /// Finds the complete declaration of a class. public Class FindCompleteClass(string name, bool ignoreCase = false) { return FindClass(name, ignoreCase: ignoreCase).FirstOrDefault( @class => !@class.IsIncomplete); } /// Finds an existing function in the library modules. public IEnumerable FindFunction(string name) { return TranslationUnits.Select(module => module.FindFunction(name)) .Where(type => type != null); } /// Finds an existing typedef in the library modules. public IEnumerable FindTypedef(string name) { return TranslationUnits.Select(module => module.FindTypedef(name)) .Where(type => type != null); } /// Finds an existing declaration by name. public IEnumerable FindDecl(string name) where T : Declaration { switch (typeof(T).Name) { case "Enumeration": foreach (var module in TranslationUnits) yield return module.FindEnum(name) as T; break; case "Class": foreach (var module in TranslationUnits) yield return module.FindClass(name) as T; break; case "ClassTemplate": foreach (var module in TranslationUnits) foreach (var template in module.FindClassTemplate(name)) yield return template as T; break; case "Function": foreach (var module in TranslationUnits) yield return module.FindFunction(name) as T; break; case "Variable": foreach (var variable in from unit in TranslationUnits from variable in unit.Variables where variable.Name == name select variable) yield return variable as T; break; default: foreach (var decl in from unit in TranslationUnits from decl in unit.Declarations where decl.Name == name select decl) yield return decl as T; break; } } public void SetEnumAsFlags(string name) { var enums = FindEnum(name); foreach(var @enum in enums) @enum.SetFlags(); } public void ExcludeFromPass(string name, System.Type type) { var decls = FindDecl(name); foreach (var decl in decls) decl.ExcludeFromPasses.Add(type); } /// /// Use this to rename namespaces. /// public void RenameNamespace(string name, string newName) { foreach (var unit in TranslationUnits) { var @namespace = unit.FindNamespace(name); if (@namespace != null) @namespace.Name = newName; } } } }