1111
1212namespace CppSharp . Passes
1313{
14+ /// <summary>
15+ /// This is used by GetterSetterToPropertyPass to decide how to process
16+ /// getter/setter class methods into properties.
17+ /// </summary>
18+ public enum PropertyDetectionMode
19+ {
20+ /// <summary>
21+ /// No methods are converted to properties.
22+ /// </summary>
23+ None ,
24+ /// <summary>
25+ /// All compatible methods are converted to properties.
26+ /// </summary>
27+ All ,
28+ /// <summary>
29+ /// Only methods starting with certain keyword are converted to properties.
30+ /// Right now we consider getter methods starting with "get", "is" and "has".
31+ /// </summary>
32+ Keywords ,
33+ /// <summary>
34+ /// Heuristics based mode that uses english dictionary words to decide
35+ /// if a getter method is an action and thus not to be considered as a
36+ /// property.
37+ /// </summary>
38+ Dictionary
39+ }
40+
1441 public class GetterSetterToPropertyPass : TranslationUnitPass
1542 {
1643 static GetterSetterToPropertyPass ( )
@@ -44,6 +71,9 @@ public GetterSetterToPropertyPass()
4471
4572 public override bool VisitClassDecl ( Class @class )
4673 {
74+ if ( Options . PropertyDetectionMode == PropertyDetectionMode . None )
75+ return false ;
76+
4777 if ( ! base . VisitClassDecl ( @class ) )
4878 return false ;
4979
@@ -86,35 +116,58 @@ protected IEnumerable<Property> GenerateProperties(Class @class)
86116
87117 private IEnumerable < Property > CleanUp ( Class @class , List < Property > properties )
88118 {
89- if ( ! Options . UsePropertyDetectionHeuristics )
119+ #pragma warning disable CS0618
120+ if ( ! Options . UsePropertyDetectionHeuristics ||
121+ #pragma warning restore CS0618
122+ Options . PropertyDetectionMode == PropertyDetectionMode . All )
90123 return properties ;
91124
92125 for ( int i = properties . Count - 1 ; i >= 0 ; i -- )
93126 {
94- Property property = properties [ i ] ;
95- if ( property . HasSetter || property . IsExplicitlyGenerated )
96- continue ;
97-
98- string firstWord = GetFirstWord ( property . GetMethod . Name ) ;
99- if ( firstWord . Length < property . GetMethod . Name . Length &&
100- Match ( firstWord , new [ ] { "get" , "is" , "has" } ) )
127+ var property = properties [ i ] ;
128+ if ( KeepProperty ( property ) )
101129 continue ;
102130
103- if ( Match ( firstWord , new [ ] { "to" , "new" , "on" } ) ||
104- Verbs . Contains ( firstWord ) )
105- {
106- property . GetMethod . GenerationKind = GenerationKind . Generate ;
107- @class . Properties . Remove ( property ) ;
108- properties . RemoveAt ( i ) ;
109- }
131+ property . GetMethod . GenerationKind = GenerationKind . Generate ;
132+ @class . Properties . Remove ( property ) ;
133+ properties . RemoveAt ( i ) ;
110134 }
111135
112136 return properties ;
113137 }
114138
139+ public virtual bool KeepProperty ( Property property )
140+ {
141+ if ( property . HasSetter || property . IsExplicitlyGenerated )
142+ return true ;
143+
144+ var firstWord = GetFirstWord ( property . GetMethod . Name ) ;
145+ var isKeyword = firstWord . Length < property . GetMethod . Name . Length &&
146+ Match ( firstWord , new [ ] { "get" , "is" , "has" } ) ;
147+
148+ switch ( Options . PropertyDetectionMode )
149+ {
150+ case PropertyDetectionMode . Keywords :
151+ return isKeyword ;
152+ case PropertyDetectionMode . Dictionary :
153+ var isAction = Match ( firstWord , new [ ] { "to" , "new" , "on" } ) || Verbs . Contains ( firstWord ) ;
154+ return isKeyword || ! isAction ;
155+ default :
156+ return false ;
157+ }
158+ }
159+
115160 private static void CreateOrUpdateProperty ( List < Property > properties , Method method ,
116161 string name , QualifiedType type , bool isSetter = false )
117162 {
163+ string NormalizeName ( string name )
164+ {
165+ return string . IsNullOrEmpty ( name ) ?
166+ name : string . Concat ( char . ToLowerInvariant ( name [ 0 ] ) , name . Substring ( 1 ) ) ;
167+ }
168+
169+ var normalizedName = NormalizeName ( name ) ;
170+
118171 Type underlyingType = GetUnderlyingType ( type ) ;
119172 Property property = properties . Find (
120173 p => p . Field == null &&
@@ -124,10 +177,10 @@ private static void CreateOrUpdateProperty(List<Property> properties, Method met
124177 p . GetMethod . OriginalReturnType ) . Equals ( underlyingType ) ) ||
125178 ( p . HasSetter && GetUnderlyingType (
126179 p . SetMethod . Parameters [ 0 ] . QualifiedType ) . Equals ( underlyingType ) ) ) &&
127- Match ( p , name ) ) ;
180+ Match ( p , normalizedName ) ) ;
128181
129182 if ( property == null )
130- properties . Add ( property = new Property { Name = name , QualifiedType = type } ) ;
183+ properties . Add ( property = new Property { Name = normalizedName , QualifiedType = type } ) ;
131184
132185 method . AssociatedDeclaration = property ;
133186
@@ -201,7 +254,9 @@ private static void ProcessProperties(Class @class, IEnumerable<Property> proper
201254 property . SetMethod . OriginalReturnType . Type . Desugar ( ) . IsPrimitiveType ( PrimitiveType . Void ) )
202255 property . SetMethod . GenerationKind = GenerationKind . Internal ;
203256 property . Namespace = @class ;
257+
204258 @class . Properties . Add ( property ) ;
259+
205260 RenameConflictingMethods ( @class , property ) ;
206261 CombineComments ( property ) ;
207262 }
@@ -294,14 +349,8 @@ private static string GetPropertyName(string name)
294349 ( string . Compare ( name , firstWord , StringComparison . InvariantCultureIgnoreCase ) == 0 ) ||
295350 char . IsNumber ( name [ 3 ] ) ) return name ;
296351
297- if ( name . Length == 4 )
298- {
299- return char . ToLowerInvariant (
300- name [ 3 ] ) . ToString ( CultureInfo . InvariantCulture ) ;
301- }
302-
303- return string . Concat ( char . ToLowerInvariant (
304- name [ 3 ] ) . ToString ( CultureInfo . InvariantCulture ) , name . AsSpan ( 4 ) ) ;
352+ var rest = ( name . Length == 4 ) ? string . Empty : name . Substring ( 4 ) ;
353+ return string . Concat ( name [ 3 ] , rest ) ;
305354 }
306355
307356 private static string GetPropertyNameFromSetter ( string name )
@@ -314,7 +363,6 @@ private static string GetPropertyNameFromSetter(string name)
314363 return nameBuilder . ToString ( ) ;
315364
316365 nameBuilder . TrimUnderscores ( ) ;
317- nameBuilder [ 0 ] = char . ToLowerInvariant ( nameBuilder [ 0 ] ) ;
318366 return nameBuilder . ToString ( ) ;
319367 }
320368
0 commit comments