@@ -9,120 +9,79 @@ namespace CppSharp.Passes
99{
1010 public class CleanInvalidDeclNamesPass : TranslationUnitPass
1111 {
12- private int uniqueName ;
13-
14- string CheckName ( string name )
12+ public override bool VisitClassDecl ( Class @class )
1513 {
16- // Generate a new name if the decl still does not have a name
17- if ( string . IsNullOrWhiteSpace ( name ) )
18- return string . Format ( "_{0}" , uniqueName ++ ) ;
19-
20- // Clean up the item name if the first digit is not a valid name.
21- if ( char . IsNumber ( name [ 0 ] ) )
22- return '_' + name ;
14+ if ( ! base . VisitClassDecl ( @class ) )
15+ return false ;
2316
24- // TODO: Fix this to not need per-generator code.
25- var units = new List < TranslationUnit > { new TranslationUnit ( ) } ;
26- if ( Options . IsCLIGenerator )
27- return new CLIHeaders ( Context , units ) . SafeIdentifier ( name ) ;
17+ if ( @class . Layout != null )
18+ {
19+ int order = 0 ;
20+ foreach ( var field in @class . Layout . Fields )
21+ field . Name = CheckName ( field . Name , ref order ) ;
22+ }
2823
29- return new CSharpSources ( Context , units ) . SafeIdentifier ( name ) ;
24+ return true ;
3025 }
3126
32- public override bool VisitDeclaration ( Declaration decl )
27+ public override bool VisitEnumDecl ( Enumeration @enum )
3328 {
34- if ( ! base . VisitDeclaration ( decl ) )
29+ if ( ! base . VisitEnumDecl ( @enum ) )
3530 return false ;
3631
37- // Do not clean up namespace names since it can mess up with the
38- // names of anonymous or the global namespace.
39- if ( decl is Namespace )
40- return true ;
41-
42- // types with empty names are assumed to be private
43- if ( decl is Class && string . IsNullOrWhiteSpace ( decl . Name ) )
44- {
45- decl . Name = decl . Namespace . Name == "_" ? "__" : "_" ;
46- decl . ExplicitlyIgnore ( ) ;
47- return true ;
48- }
49-
50- var function = decl as Function ;
51- var method = function as Method ;
52- if ( ( function == null || ! function . IsOperator ) && ! ( decl is Enumeration ) &&
53- ( method == null || method . Kind == CXXMethodKind . Normal ) )
54- decl . Name = CheckName ( decl . Name ) ;
55-
32+ CheckChildrenNames ( @enum . Items ,
33+ string . IsNullOrEmpty ( @enum . Name ) ? 1 : 0 ) ;
34+ CheckEnumName ( @enum ) ;
5635 return true ;
5736 }
5837
59- public override bool VisitParameterDecl ( Parameter parameter )
38+ public override bool VisitFunctionDecl ( Function function )
6039 {
61- return VisitDeclaration ( parameter ) ;
40+ if ( ! base . VisitFunctionDecl ( function ) )
41+ return false ;
42+
43+ CheckChildrenNames ( function . Parameters ) ;
44+ return true ;
6245 }
6346
64- public override bool VisitClassDecl ( Class @class )
47+ public override bool VisitDeclarationContext ( DeclarationContext context )
6548 {
66- var currentUniqueName = uniqueName ;
67- uniqueName = 0 ;
68- base . VisitClassDecl ( @class ) ;
69- uniqueName = currentUniqueName ;
70-
71- if ( ! @class . IsDependent )
72- foreach ( var field in @class . Layout . Fields . Where ( f => string . IsNullOrEmpty ( f . Name ) ) )
73- field . Name = @class . Name == "_" ? "__" : "_" ;
74-
75- if ( @class is ClassTemplateSpecialization &&
76- ! ( from c in @class . Namespace . Classes
77- where c . Name == @class . Name && ! ( @class is ClassTemplateSpecialization ) &&
78- c != ( ( ClassTemplateSpecialization ) @class ) . TemplatedDecl . TemplatedClass
79- select c ) . Any ( ) )
80- return true ;
81-
82- if ( @class . Namespace . Classes . Any ( d => d != @class && d . Name == @class . Name ) )
49+ if ( ! base . VisitDeclarationContext ( context ) )
50+ return false ;
51+
52+ DeclarationContext currentContext = context ;
53+ int parents = 0 ;
54+ while ( currentContext != null )
8355 {
84- // we need the new name in each iteration so no point in StringBuilder
85- var name = @class . Name ;
86- do
87- {
88- name += '_' ;
89- } while ( @class . Namespace . Name == name ||
90- @class . Classes . Any ( d => d != @class && d . Name == name ) ) ;
91- @class . Name = name ;
56+ parents ++ ;
57+ currentContext = currentContext . Namespace ;
9258 }
59+ int order = parents % 2 ;
60+ CheckChildrenNames ( context . Declarations , ref order ) ;
61+
62+ var @class = context as Class ;
63+ if ( @class != null )
64+ CheckChildrenNames ( @class . Fields , order ) ;
9365
9466 return true ;
9567 }
9668
97- public override bool VisitFunctionDecl ( Function function )
69+ public override bool VisitFunctionType ( FunctionType function , TypeQualifiers quals )
9870 {
99- var currentUniqueName = uniqueName ;
100- uniqueName = 0 ;
101- var ret = base . VisitFunctionDecl ( function ) ;
102- uniqueName = currentUniqueName ;
71+ if ( ! base . VisitFunctionType ( function , quals ) )
72+ return false ;
10373
104- return ret ;
74+ CheckChildrenNames ( function . Parameters ) ;
75+ return true ;
10576 }
10677
107- public override bool VisitEvent ( Event @event )
108- {
109- var currentUniqueName = uniqueName ;
110- uniqueName = 0 ;
111- var ret = base . VisitEvent ( @event ) ;
112- uniqueName = currentUniqueName ;
113-
114- return ret ;
115- }
78+ private void CheckChildrenNames ( IEnumerable < Declaration > children , int order = 0 ) =>
79+ CheckChildrenNames ( children , ref order ) ;
11680
117- public override bool VisitFunctionType ( FunctionType type ,
118- TypeQualifiers quals )
81+ private void CheckChildrenNames ( IEnumerable < Declaration > children , ref int order )
11982 {
120- var currentUniqueName = this . uniqueName ;
121- this . uniqueName = 0 ;
122- var ret = base . VisitFunctionType ( type , quals ) ;
123- this . uniqueName = currentUniqueName ;
124-
125- return ret ;
83+ foreach ( var child in children )
84+ child . Name = CheckName ( child . Name , ref order ) ;
12685 }
12786
12887 private void CheckEnumName ( Enumeration @enum )
@@ -139,7 +98,9 @@ private void CheckEnumName(Enumeration @enum)
13998 // Try a simple heuristic to make sure we end up with a valid name.
14099 if ( prefix . Length < 3 )
141100 {
142- @enum . Name = CheckName ( @enum . Name ) ;
101+ int order = @enum . Namespace . Enums . Count ( e => e != @enum &&
102+ string . IsNullOrEmpty ( e . Name ) ) ;
103+ @enum . Name = CheckName ( @enum . Name , ref order ) ;
143104 return ;
144105 }
145106
@@ -151,40 +112,22 @@ private void CheckEnumName(Enumeration @enum)
151112 @enum . Name = prefixBuilder . ToString ( ) ;
152113 }
153114
154- public override bool VisitEnumDecl ( Enumeration @enum )
115+ private string CheckName ( string name , ref int order )
155116 {
156- if ( ! base . VisitEnumDecl ( @enum ) )
157- return false ;
158-
159- CheckEnumName ( @enum ) ;
160- return true ;
161- }
162-
163- public override bool VisitEnumItemDecl ( Enumeration . Item item )
164- {
165- if ( ! base . VisitEnumItemDecl ( item ) )
166- return false ;
117+ // Generate a new name if the decl still does not have a name
118+ if ( string . IsNullOrWhiteSpace ( name ) )
119+ return $ "_{ order ++ } ";
167120
168- item . Name = CheckName ( item . Name ) ;
169- return true ;
170- }
121+ // Clean up the item name if the first digit is not a valid name.
122+ if ( char . IsNumber ( name [ 0 ] ) )
123+ return '_' + name ;
171124
172- public override bool VisitFieldDecl ( Field field )
173- {
174- if ( ! base . VisitFieldDecl ( field ) )
175- return false ;
125+ // TODO: Fix this to not need per-generator code.
126+ var units = new List < TranslationUnit > { new TranslationUnit ( ) } ;
127+ if ( Options . IsCLIGenerator )
128+ return new CLIHeaders ( Context , units ) . SafeIdentifier ( name ) ;
176129
177- if ( field . Class . Fields . Count ( c => c . Name . Equals ( field . Name ) ) > 1 )
178- {
179- StringBuilder str = new StringBuilder ( ) ;
180- str . Append ( field . Name ) ;
181- do
182- {
183- str . Append ( '_' ) ;
184- } while ( field . Class . Fields . Any ( c => c . Name . Equals ( str . ToString ( ) ) ) ) ;
185- field . Name = str . ToString ( ) ;
186- }
187- return true ;
130+ return new CSharpSources ( Context , units ) . SafeIdentifier ( name ) ;
188131 }
189132 }
190133}
0 commit comments