Browse Source

Rewrite property detection logic to be more configurable.

pull/1714/head
Joao Matos 4 years ago
parent
commit
b04bf1d3e5
  1. 3
      src/CLI/Options.cs
  2. 3
      src/Generator/Options.cs
  3. 69
      src/Generator/Passes/GetterSetterToPropertyPass.cs

3
src/CLI/Options.cs

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using CppSharp.Generators; using CppSharp.Generators;
using CppSharp.Passes;
namespace CppSharp namespace CppSharp
{ {
@ -43,6 +44,8 @@ namespace CppSharp
public GeneratorKind Kind { get; set; } = GeneratorKind.CSharp; public GeneratorKind Kind { get; set; } = GeneratorKind.CSharp;
public PropertyDetectionMode PropertyMode = PropertyDetectionMode.Keywords;
public bool CheckSymbols { get; set; } public bool CheckSymbols { get; set; }
public bool UnityBuild { get; set; } public bool UnityBuild { get; set; }

3
src/Generator/Options.cs

@ -247,6 +247,9 @@ namespace CppSharp
/// </summary> /// </summary>
public HashSet<string> ExplicitlyPatchedVirtualFunctions { get; } public HashSet<string> ExplicitlyPatchedVirtualFunctions { get; }
public PropertyDetectionMode PropertyDetectionMode { get; set; } = PropertyDetectionMode.Dictionary;
[Obsolete("Use PropertyDetectionMode instead")]
public bool UsePropertyDetectionHeuristics { get; set; } = true; public bool UsePropertyDetectionHeuristics { get; set; } = true;
/// <summary> /// <summary>

69
src/Generator/Passes/GetterSetterToPropertyPass.cs

@ -11,6 +11,33 @@ using Type = CppSharp.AST.Type;
namespace CppSharp.Passes namespace CppSharp.Passes
{ {
/// <summary>
/// This is used by GetterSetterToPropertyPass to decide how to process
/// getter/setter class methods into properties.
/// </summary>
public enum PropertyDetectionMode
{
/// <summary>
/// No methods are converted to properties.
/// </summary>
None,
/// <summary>
/// All compatible methods are converted to properties.
/// </summary>
All,
/// <summary>
/// Only methods starting with certain keyword are converted to properties.
/// Right now we consider getter methods starting with "get", "is" and "has".
/// </summary>
Keywords,
/// <summary>
/// Heuristics based mode that uses english dictionary words to decide
/// if a getter method is an action and thus not to be considered as a
/// property.
/// </summary>
Dictionary
}
public class GetterSetterToPropertyPass : TranslationUnitPass public class GetterSetterToPropertyPass : TranslationUnitPass
{ {
static GetterSetterToPropertyPass() static GetterSetterToPropertyPass()
@ -44,6 +71,9 @@ namespace CppSharp.Passes
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
{ {
if (Options.PropertyDetectionMode == PropertyDetectionMode.None)
return false;
if (!base.VisitClassDecl(@class)) if (!base.VisitClassDecl(@class))
return false; return false;
@ -86,22 +116,16 @@ namespace CppSharp.Passes
private IEnumerable<Property> CleanUp(Class @class, List<Property> properties) private IEnumerable<Property> CleanUp(Class @class, List<Property> properties)
{ {
if (!Options.UsePropertyDetectionHeuristics) #pragma warning disable CS0618
if (!Options.UsePropertyDetectionHeuristics ||
#pragma warning restore CS0618
Options.PropertyDetectionMode == PropertyDetectionMode.All)
return properties; return properties;
for (int i = properties.Count - 1; i >= 0; i--) for (int i = properties.Count - 1; i >= 0; i--)
{ {
Property property = properties[i]; var property = properties[i];
if (property.HasSetter || property.IsExplicitlyGenerated) if (!KeepProperty(property))
continue;
string firstWord = GetFirstWord(property.GetMethod.Name);
if (firstWord.Length < property.GetMethod.Name.Length &&
Match(firstWord, new[] { "get", "is", "has" }))
continue;
if (Match(firstWord, new[] { "to", "new", "on" }) ||
Verbs.Contains(firstWord))
{ {
property.GetMethod.GenerationKind = GenerationKind.Generate; property.GetMethod.GenerationKind = GenerationKind.Generate;
@class.Properties.Remove(property); @class.Properties.Remove(property);
@ -112,6 +136,27 @@ namespace CppSharp.Passes
return properties; return properties;
} }
public virtual bool KeepProperty(Property property)
{
if (property.HasSetter || property.IsExplicitlyGenerated)
return true;
var firstWord = GetFirstWord(property.GetMethod.Name);
var isKeyword = firstWord.Length < property.GetMethod.Name.Length &&
Match(firstWord, new[] {"get", "is", "has"});
switch (Options.PropertyDetectionMode)
{
case PropertyDetectionMode.Keywords:
return isKeyword;
case PropertyDetectionMode.Dictionary:
var isAction = Match(firstWord, new[] {"to", "new", "on"}) || Verbs.Contains(firstWord);
return isKeyword || !isAction;
default:
return false;
}
}
private static void CreateOrUpdateProperty(List<Property> properties, Method method, private static void CreateOrUpdateProperty(List<Property> properties, Method method,
string name, QualifiedType type, bool isSetter = false) string name, QualifiedType type, bool isSetter = false)
{ {

Loading…
Cancel
Save