|
|
|
|
@ -9,120 +9,79 @@ namespace CppSharp.Passes
@@ -9,120 +9,79 @@ namespace CppSharp.Passes
|
|
|
|
|
{ |
|
|
|
|
public class CleanInvalidDeclNamesPass : TranslationUnitPass |
|
|
|
|
{ |
|
|
|
|
private int uniqueName; |
|
|
|
|
|
|
|
|
|
string CheckName(string name) |
|
|
|
|
public override bool VisitClassDecl(Class @class) |
|
|
|
|
{ |
|
|
|
|
// Generate a new name if the decl still does not have a name
|
|
|
|
|
if (string.IsNullOrWhiteSpace(name)) |
|
|
|
|
return string.Format("_{0}", uniqueName++); |
|
|
|
|
|
|
|
|
|
// Clean up the item name if the first digit is not a valid name.
|
|
|
|
|
if (char.IsNumber(name[0])) |
|
|
|
|
return '_' + name; |
|
|
|
|
if (!base.VisitClassDecl(@class)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
// TODO: Fix this to not need per-generator code.
|
|
|
|
|
var units = new List<TranslationUnit> { new TranslationUnit() }; |
|
|
|
|
if (Options.IsCLIGenerator) |
|
|
|
|
return new CLIHeaders(Context, units).SafeIdentifier(name); |
|
|
|
|
if (@class.Layout != null) |
|
|
|
|
{ |
|
|
|
|
int order = 0; |
|
|
|
|
foreach (var field in @class.Layout.Fields) |
|
|
|
|
field.Name = CheckName(field.Name, ref order); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return new CSharpSources(Context, units).SafeIdentifier(name); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool VisitDeclaration(Declaration decl) |
|
|
|
|
public override bool VisitEnumDecl(Enumeration @enum) |
|
|
|
|
{ |
|
|
|
|
if (!base.VisitDeclaration(decl)) |
|
|
|
|
if (!base.VisitEnumDecl(@enum)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
// Do not clean up namespace names since it can mess up with the
|
|
|
|
|
// names of anonymous or the global namespace.
|
|
|
|
|
if (decl is Namespace) |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
// types with empty names are assumed to be private
|
|
|
|
|
if (decl is Class && string.IsNullOrWhiteSpace(decl.Name)) |
|
|
|
|
{ |
|
|
|
|
decl.Name = decl.Namespace.Name == "_" ? "__" : "_"; |
|
|
|
|
decl.ExplicitlyIgnore(); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var function = decl as Function; |
|
|
|
|
var method = function as Method; |
|
|
|
|
if ((function == null || !function.IsOperator) && !(decl is Enumeration) && |
|
|
|
|
(method == null || method.Kind == CXXMethodKind.Normal)) |
|
|
|
|
decl.Name = CheckName(decl.Name); |
|
|
|
|
|
|
|
|
|
CheckChildrenNames(@enum.Items, |
|
|
|
|
string.IsNullOrEmpty(@enum.Name) ? 1 : 0); |
|
|
|
|
CheckEnumName(@enum); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool VisitParameterDecl(Parameter parameter) |
|
|
|
|
public override bool VisitFunctionDecl(Function function) |
|
|
|
|
{ |
|
|
|
|
return VisitDeclaration(parameter); |
|
|
|
|
if (!base.VisitFunctionDecl(function)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
CheckChildrenNames(function.Parameters); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool VisitClassDecl(Class @class) |
|
|
|
|
public override bool VisitDeclarationContext(DeclarationContext context) |
|
|
|
|
{ |
|
|
|
|
var currentUniqueName = uniqueName; |
|
|
|
|
uniqueName = 0; |
|
|
|
|
base.VisitClassDecl(@class); |
|
|
|
|
uniqueName = currentUniqueName; |
|
|
|
|
|
|
|
|
|
if (!@class.IsDependent) |
|
|
|
|
foreach (var field in @class.Layout.Fields.Where(f => string.IsNullOrEmpty(f.Name))) |
|
|
|
|
field.Name = @class.Name == "_" ? "__" : "_"; |
|
|
|
|
|
|
|
|
|
if (@class is ClassTemplateSpecialization && |
|
|
|
|
!(from c in @class.Namespace.Classes |
|
|
|
|
where c.Name == @class.Name && !(@class is ClassTemplateSpecialization) && |
|
|
|
|
c != ((ClassTemplateSpecialization) @class).TemplatedDecl.TemplatedClass |
|
|
|
|
select c).Any()) |
|
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
if (@class.Namespace.Classes.Any(d => d != @class && d.Name == @class.Name)) |
|
|
|
|
if (!base.VisitDeclarationContext(context)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
DeclarationContext currentContext = context; |
|
|
|
|
int parents = 0; |
|
|
|
|
while (currentContext != null) |
|
|
|
|
{ |
|
|
|
|
// we need the new name in each iteration so no point in StringBuilder
|
|
|
|
|
var name = @class.Name; |
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
name += '_'; |
|
|
|
|
} while (@class.Namespace.Name == name || |
|
|
|
|
@class.Classes.Any(d => d != @class && d.Name == name)); |
|
|
|
|
@class.Name = name; |
|
|
|
|
parents++; |
|
|
|
|
currentContext = currentContext.Namespace; |
|
|
|
|
} |
|
|
|
|
int order = parents % 2; |
|
|
|
|
CheckChildrenNames(context.Declarations, ref order); |
|
|
|
|
|
|
|
|
|
var @class = context as Class; |
|
|
|
|
if (@class != null) |
|
|
|
|
CheckChildrenNames(@class.Fields, order); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool VisitFunctionDecl(Function function) |
|
|
|
|
public override bool VisitFunctionType(FunctionType function, TypeQualifiers quals) |
|
|
|
|
{ |
|
|
|
|
var currentUniqueName = uniqueName; |
|
|
|
|
uniqueName = 0; |
|
|
|
|
var ret = base.VisitFunctionDecl(function); |
|
|
|
|
uniqueName = currentUniqueName; |
|
|
|
|
if (!base.VisitFunctionType(function, quals)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
CheckChildrenNames(function.Parameters); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool VisitEvent(Event @event) |
|
|
|
|
{ |
|
|
|
|
var currentUniqueName = uniqueName; |
|
|
|
|
uniqueName = 0; |
|
|
|
|
var ret = base.VisitEvent(@event); |
|
|
|
|
uniqueName = currentUniqueName; |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
private void CheckChildrenNames(IEnumerable<Declaration> children, int order = 0) => |
|
|
|
|
CheckChildrenNames(children, ref order); |
|
|
|
|
|
|
|
|
|
public override bool VisitFunctionType(FunctionType type, |
|
|
|
|
TypeQualifiers quals) |
|
|
|
|
private void CheckChildrenNames(IEnumerable<Declaration> children, ref int order) |
|
|
|
|
{ |
|
|
|
|
var currentUniqueName = this.uniqueName; |
|
|
|
|
this.uniqueName = 0; |
|
|
|
|
var ret = base.VisitFunctionType(type, quals); |
|
|
|
|
this.uniqueName = currentUniqueName; |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
foreach (var child in children) |
|
|
|
|
child.Name = CheckName(child.Name, ref order); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void CheckEnumName(Enumeration @enum) |
|
|
|
|
@ -139,7 +98,9 @@ namespace CppSharp.Passes
@@ -139,7 +98,9 @@ namespace CppSharp.Passes
|
|
|
|
|
// Try a simple heuristic to make sure we end up with a valid name.
|
|
|
|
|
if (prefix.Length < 3) |
|
|
|
|
{ |
|
|
|
|
@enum.Name = CheckName(@enum.Name); |
|
|
|
|
int order = @enum.Namespace.Enums.Count(e => e != @enum && |
|
|
|
|
string.IsNullOrEmpty(e.Name)); |
|
|
|
|
@enum.Name = CheckName(@enum.Name, ref order); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -151,40 +112,22 @@ namespace CppSharp.Passes
@@ -151,40 +112,22 @@ namespace CppSharp.Passes
|
|
|
|
|
@enum.Name = prefixBuilder.ToString(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool VisitEnumDecl(Enumeration @enum) |
|
|
|
|
private string CheckName(string name, ref int order) |
|
|
|
|
{ |
|
|
|
|
if (!base.VisitEnumDecl(@enum)) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
CheckEnumName(@enum); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public override bool VisitEnumItemDecl(Enumeration.Item item) |
|
|
|
|
{ |
|
|
|
|
if (!base.VisitEnumItemDecl(item)) |
|
|
|
|
return false; |
|
|
|
|
// Generate a new name if the decl still does not have a name
|
|
|
|
|
if (string.IsNullOrWhiteSpace(name)) |
|
|
|
|
return $"_{order++}"; |
|
|
|
|
|
|
|
|
|
item.Name = CheckName(item.Name); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
// Clean up the item name if the first digit is not a valid name.
|
|
|
|
|
if (char.IsNumber(name[0])) |
|
|
|
|
return '_' + name; |
|
|
|
|
|
|
|
|
|
public override bool VisitFieldDecl(Field field) |
|
|
|
|
{ |
|
|
|
|
if (!base.VisitFieldDecl(field)) |
|
|
|
|
return false; |
|
|
|
|
// TODO: Fix this to not need per-generator code.
|
|
|
|
|
var units = new List<TranslationUnit> { new TranslationUnit() }; |
|
|
|
|
if (Options.IsCLIGenerator) |
|
|
|
|
return new CLIHeaders(Context, units).SafeIdentifier(name); |
|
|
|
|
|
|
|
|
|
if (field.Class.Fields.Count(c => c.Name.Equals(field.Name)) > 1) |
|
|
|
|
{ |
|
|
|
|
StringBuilder str = new StringBuilder(); |
|
|
|
|
str.Append(field.Name); |
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
str.Append('_'); |
|
|
|
|
} while (field.Class.Fields.Any(c => c.Name.Equals(str.ToString()))); |
|
|
|
|
field.Name = str.ToString(); |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
return new CSharpSources(Context, units).SafeIdentifier(name); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|