mirror of https://github.com/mono/CppSharp.git
c-sharpdotnetmonobindingsbridgecclangcpluspluscppsharpglueinteropparserparsingpinvokeswigsyntax-treevisitorsxamarinxamarin-bindings
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
302 lines
8.4 KiB
302 lines
8.4 KiB
using System; |
|
using CppSharp.AST; |
|
|
|
namespace CppSharp.Passes |
|
{ |
|
public class CheckIgnoredDeclsPass : TranslationUnitPass |
|
{ |
|
public CheckIgnoredDeclsPass() |
|
{ |
|
} |
|
|
|
public override bool VisitDeclaration(Declaration decl) |
|
{ |
|
if (decl.ExplicityIgnored) |
|
return false; |
|
|
|
if (decl.IsDependent) |
|
{ |
|
decl.ExplicityIgnored = true; |
|
Console.WriteLine("Decl '{0}' was ignored due to dependent context", |
|
decl.Name); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public override bool VisitFieldDecl(Field field) |
|
{ |
|
if (!VisitDeclaration(field)) |
|
return false; |
|
|
|
var type = field.Type; |
|
|
|
string msg; |
|
if (!HasInvalidType(type, out msg)) |
|
return false; |
|
|
|
field.ExplicityIgnored = true; |
|
|
|
Console.WriteLine("Field '{0}' was ignored due to {1} type", |
|
field.Name, msg); |
|
|
|
return true; |
|
} |
|
|
|
public override bool VisitFunctionDecl(Function function) |
|
{ |
|
if (!VisitDeclaration(function)) |
|
return false; |
|
|
|
var ret = function.ReturnType; |
|
|
|
string msg; |
|
if (HasInvalidType(ret.Type, out msg)) |
|
{ |
|
function.ExplicityIgnored = true; |
|
Console.WriteLine("Function '{0}' was ignored due to {1} return decl", |
|
function.Name, msg); |
|
return false; |
|
} |
|
|
|
foreach (var param in function.Parameters) |
|
{ |
|
if (HasInvalidDecl(param, out msg)) |
|
{ |
|
function.ExplicityIgnored = true; |
|
Console.WriteLine("Function '{0}' was ignored due to {1} param", |
|
function.Name, msg); |
|
return false; |
|
} |
|
|
|
if (HasInvalidType(param.Type, out msg)) |
|
{ |
|
function.ExplicityIgnored = true; |
|
Console.WriteLine("Function '{0}' was ignored due to {1} param", |
|
function.Name, msg); |
|
return false; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public override bool VisitMethodDecl(Method method) |
|
{ |
|
if (!VisitDeclaration(method)) |
|
return false; |
|
|
|
if (method.Access != AccessSpecifier.Public) |
|
{ |
|
method.ExplicityIgnored = true; |
|
return false; |
|
} |
|
|
|
return base.VisitMethodDecl(method); |
|
} |
|
|
|
public override bool VisitTypedefDecl(TypedefDecl typedef) |
|
{ |
|
if (!VisitDeclaration(typedef)) |
|
return false; |
|
|
|
string msg; |
|
if (HasInvalidType(typedef.Type, out msg)) |
|
{ |
|
typedef.ExplicityIgnored = true; |
|
Console.WriteLine("Typedef '{0}' was ignored due to {1} type", |
|
typedef.Name, msg); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public override bool VisitProperty(Property property) |
|
{ |
|
if (!VisitDeclaration(property)) |
|
return false; |
|
|
|
string msg; |
|
if (HasInvalidDecl(property, out msg)) |
|
{ |
|
property.ExplicityIgnored = true; |
|
Console.WriteLine("Property '{0}' was ignored due to {1} decl", |
|
property.Name, msg); |
|
return false; |
|
} |
|
|
|
if (HasInvalidType(property.Type, out msg)) |
|
{ |
|
property.ExplicityIgnored = true; |
|
Console.WriteLine("Property '{0}' was ignored due to {1} type", |
|
property.Name, msg); |
|
return false; |
|
} |
|
|
|
if (property.GetMethod != null && !VisitFunctionDecl(property.GetMethod)) |
|
{ |
|
property.ExplicityIgnored = true; |
|
Console.WriteLine("Property '{0}' was ignored due to ignored getter", |
|
property.Name, msg); |
|
return false; |
|
} |
|
|
|
if (property.SetMethod != null && !VisitFunctionDecl(property.SetMethod)) |
|
{ |
|
property.ExplicityIgnored = true; |
|
Console.WriteLine("Property '{0}' was ignored due to ignored setter", |
|
property.Name, msg); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public override bool VisitVariableDecl(Variable variable) |
|
{ |
|
if (!VisitDeclaration(variable)) |
|
return false; |
|
|
|
string msg; |
|
if (HasInvalidDecl(variable, out msg)) |
|
{ |
|
variable.ExplicityIgnored = true; |
|
Console.WriteLine("Variable '{0}' was ignored due to {1} decl", |
|
variable.Name, msg); |
|
return false; |
|
} |
|
|
|
if (HasInvalidType(variable.Type, out msg)) |
|
{ |
|
variable.ExplicityIgnored = true; |
|
Console.WriteLine("Variable '{0}' was ignored due to {1} type", |
|
variable.Name, msg); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public override bool VisitEvent(Event @event) |
|
{ |
|
if (!VisitDeclaration(@event)) |
|
return false; |
|
|
|
string msg; |
|
if (HasInvalidDecl(@event, out msg)) |
|
{ |
|
@event.ExplicityIgnored = true; |
|
Console.WriteLine("Event '{0}' was ignored due to {1} decl", |
|
@event.Name, msg); |
|
return false; |
|
} |
|
|
|
foreach (var param in @event.Parameters) |
|
{ |
|
if (HasInvalidDecl(param, out msg)) |
|
{ |
|
@event.ExplicityIgnored = true; |
|
Console.WriteLine("Event '{0}' was ignored due to {1} param", |
|
@event.Name, msg); |
|
return false; |
|
} |
|
|
|
if (HasInvalidType(param.Type, out msg)) |
|
{ |
|
@event.ExplicityIgnored = true; |
|
Console.WriteLine("Event '{0}' was ignored due to {1} param", |
|
@event.Name, msg); |
|
return false; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
#region Helpers |
|
|
|
/// <remarks> |
|
/// Checks if a given type is invalid, which can happen for a number of |
|
/// reasons: incomplete definitions, being explicitly ignored, or also |
|
/// by being a type we do not know how to handle. |
|
/// </remarks> |
|
bool HasInvalidType(AST.Type type, out string msg) |
|
{ |
|
if (type == null) |
|
{ |
|
msg = "null"; |
|
return true; |
|
} |
|
|
|
if (!IsTypeComplete(type)) |
|
{ |
|
msg = "incomplete"; |
|
return true; |
|
} |
|
|
|
if (IsTypeIgnored(type)) |
|
{ |
|
msg = "ignored"; |
|
return true; |
|
} |
|
|
|
msg = null; |
|
return false; |
|
} |
|
|
|
bool HasInvalidDecl(Declaration decl, out string msg) |
|
{ |
|
if (decl == null) |
|
{ |
|
msg = "null"; |
|
return true; |
|
} |
|
|
|
if (!IsDeclComplete(decl)) |
|
{ |
|
msg = "incomplete"; |
|
return true; |
|
} |
|
|
|
if (IsDeclIgnored(decl)) |
|
{ |
|
msg = "ignored"; |
|
return true; |
|
} |
|
|
|
msg = null; |
|
return false; |
|
} |
|
|
|
static bool IsTypeComplete(AST.Type type) |
|
{ |
|
var checker = new TypeCompletionChecker(); |
|
return type.Visit(checker); |
|
} |
|
|
|
static bool IsDeclComplete(Declaration decl) |
|
{ |
|
var checker = new TypeCompletionChecker(); |
|
return decl.Visit(checker); |
|
} |
|
|
|
bool IsTypeIgnored(AST.Type type) |
|
{ |
|
var checker = new TypeIgnoreChecker(Driver.TypeDatabase); |
|
type.Visit(checker); |
|
|
|
return checker.IsIgnored; |
|
} |
|
|
|
bool IsDeclIgnored(Declaration decl) |
|
{ |
|
var checker = new TypeIgnoreChecker(Driver.TypeDatabase); |
|
decl.Visit(checker); |
|
|
|
return checker.IsIgnored; |
|
} |
|
|
|
#endregion |
|
} |
|
}
|
|
|