mirror of https://github.com/mono/CppSharp.git
1 changed files with 145 additions and 0 deletions
@ -0,0 +1,145 @@ |
|||||||
|
using System.Linq; |
||||||
|
using CppSharp.AST; |
||||||
|
|
||||||
|
namespace CppSharp.Passes |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// This pass implements checks for helper macros in declarations.
|
||||||
|
/// The supported macros are listed below with a "CS" prefix which
|
||||||
|
/// stands for CppSharp. Using custom prefixes is also supported by
|
||||||
|
/// passing the value to the constructor of the pass.
|
||||||
|
///
|
||||||
|
/// CS_IGNORE (declarations)
|
||||||
|
/// Used to ignore declarations from being processed.
|
||||||
|
///
|
||||||
|
/// CS_VALUE_TYPE (classes and structs)
|
||||||
|
/// Used to flag that a class or struct is a value type.
|
||||||
|
///
|
||||||
|
/// CS_IN_OUT / CS_OUT (parameters)
|
||||||
|
/// Used in function parameters to specify their usage kind.
|
||||||
|
///
|
||||||
|
/// CS_FLAGS (enums)
|
||||||
|
/// Used to specify that enumerations represent bitwise flags.
|
||||||
|
///
|
||||||
|
/// CS_READONLY (fields and properties)
|
||||||
|
/// Used in fields and properties to specify read-only semantics.
|
||||||
|
///
|
||||||
|
/// CS_EQUALS / CS_HASHCODE (methods)
|
||||||
|
/// Used to flag method as representing the .NET Equals or
|
||||||
|
/// Hashcode methods.
|
||||||
|
///
|
||||||
|
/// There isn't a standardized header provided by CppSharp so you will
|
||||||
|
/// have to define these on your own.
|
||||||
|
/// </summary>
|
||||||
|
public class CheckMacroPass : TranslationUnitPass |
||||||
|
{ |
||||||
|
private readonly string Prefix; |
||||||
|
|
||||||
|
public CheckMacroPass(string prefix = "CS") |
||||||
|
{ |
||||||
|
Prefix = prefix; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitDeclaration(Declaration decl) |
||||||
|
{ |
||||||
|
if (AlreadyVisited(decl)) |
||||||
|
return false; |
||||||
|
|
||||||
|
var expansions = decl.PreprocessedEntities.OfType<MacroExpansion>(); |
||||||
|
|
||||||
|
if (expansions.Any(e => e.Text == Prefix + "_IGNORE" && |
||||||
|
e.Location != MacroLocation.ClassBody && |
||||||
|
e.Location != MacroLocation.FunctionBody && |
||||||
|
e.Location != MacroLocation.FunctionParameters)) |
||||||
|
decl.ExplicityIgnored = true; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitClassDecl(Class @class) |
||||||
|
{ |
||||||
|
var expansions = @class.PreprocessedEntities.OfType<MacroExpansion>(); |
||||||
|
|
||||||
|
if (expansions.Any(e => e.Text == Prefix + "_VALUE_TYPE")) |
||||||
|
@class.Type = ClassType.ValueType; |
||||||
|
|
||||||
|
return base.VisitClassDecl(@class); |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitParameterDecl(Parameter parameter) |
||||||
|
{ |
||||||
|
if (!VisitDeclaration(parameter)) |
||||||
|
return false; |
||||||
|
|
||||||
|
var expansions = parameter.PreprocessedEntities.OfType<MacroExpansion>(); |
||||||
|
|
||||||
|
if (expansions.Any(e => e.Text == Prefix + "_OUT")) |
||||||
|
parameter.Usage = ParameterUsage.Out; |
||||||
|
|
||||||
|
if (expansions.Any(e => e.Text == Prefix + "_IN_OUT")) |
||||||
|
parameter.Usage = ParameterUsage.InOut; |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitEnumDecl(Enumeration @enum) |
||||||
|
{ |
||||||
|
if (!VisitDeclaration(@enum)) |
||||||
|
return false; |
||||||
|
|
||||||
|
var expansions = @enum.PreprocessedEntities.OfType<MacroExpansion>(); |
||||||
|
|
||||||
|
if (expansions.Any(e => e.Text == Prefix + "_FLAGS")) |
||||||
|
@enum.SetFlags(); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitMethodDecl(Method method) |
||||||
|
{ |
||||||
|
var expansions = method.PreprocessedEntities.OfType<MacroExpansion>(); |
||||||
|
|
||||||
|
if (expansions.Any(e => e.Text == Prefix + "_HASHCODE" |
||||||
|
|| e.Text == Prefix + "_EQUALS")) |
||||||
|
method.ExplicityIgnored = true; |
||||||
|
|
||||||
|
return base.VisitMethodDecl(method); |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitFieldDecl(Field field) |
||||||
|
{ |
||||||
|
if (!VisitDeclaration(field)) |
||||||
|
return false; |
||||||
|
|
||||||
|
var expansions = field.PreprocessedEntities.OfType<MacroExpansion>(); |
||||||
|
|
||||||
|
if (expansions.Any(e => e.Text == Prefix + "_READONLY")) |
||||||
|
{ |
||||||
|
var quals = field.QualifiedType.Qualifiers; |
||||||
|
quals.IsConst = true; |
||||||
|
|
||||||
|
var qualType = field.QualifiedType; |
||||||
|
qualType.Qualifiers = quals; |
||||||
|
|
||||||
|
field.QualifiedType = qualType; |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public override bool VisitProperty(Property property) |
||||||
|
{ |
||||||
|
var expansions = property.PreprocessedEntities.OfType<MacroExpansion>(); |
||||||
|
|
||||||
|
if (expansions.Any(e => e.Text == Prefix + "_READONLY")) |
||||||
|
{ |
||||||
|
var setMethod = property.SetMethod; |
||||||
|
|
||||||
|
if (setMethod != null) |
||||||
|
property.SetMethod.ExplicityIgnored = true; |
||||||
|
} |
||||||
|
|
||||||
|
return base.VisitProperty(property); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue