Browse Source

Modified GetterSetterToPropertyPass more complex properties are supported. Now even if we only have a getter or a setter a property is created. Trying to convert multiple setter with same name and different types is an issue, so we check before creating a setter for a matching getter or the non existence of more setters.

pull/16/head
marcos henrich 12 years ago
parent
commit
06aba88fbb
  1. 102
      src/Generator/Passes/GetterSetterToPropertyPass.cs

102
src/Generator/Passes/GetterSetterToPropertyPass.cs

@ -1,4 +1,6 @@
using System; using System;
using System.Diagnostics;
using System.Linq;
using CppSharp.AST; using CppSharp.AST;
namespace CppSharp.Passes namespace CppSharp.Passes
@ -44,51 +46,97 @@ namespace CppSharp.Passes
return !isRetVoid && isGetter && method.Parameters.Count == 0; return !isRetVoid && isGetter && method.Parameters.Count == 0;
} }
Property GetOrCreateProperty(Class @class, string name, QualifiedType type)
{
var prop = @class.Properties.FirstOrDefault(property => property.Name == name
&& property.QualifiedType.Equals(type));
var prop2 = @class.Properties.FirstOrDefault(property => property.Name == name);
if (prop == null && prop2 != null)
Driver.Diagnostics.EmitWarning(DiagnosticId.PropertySynthetized,
"Property {0}::{1} already exist with type {2}", @class.Name, name, type.Type.ToString());
if (prop != null)
return prop;
prop = new Property
{
Name = name,
Namespace = @class,
QualifiedType = type
};
@class.Properties.Add(prop);
return prop;
}
public override bool VisitMethodDecl(Method method) public override bool VisitMethodDecl(Method method)
{ {
//var expansions = method.PreprocessedEntities.OfType<MacroExpansion>(); if (AlreadyVisited(method))
//if (expansions.Any(e => e.Text.Contains("ACCESSOR"))) return false;
// System.Diagnostics.Debugger.Break();
if (!IsGetter(method)) if (ASTUtils.CheckIgnoreMethod(null, method))
return false; return false;
var @class = method.Namespace as Class; var @class = method.Namespace as Class;
foreach (var classMethod in @class.Methods)
if (@class == null || @class.IsIncomplete)
return false;
if (IsGetter(method))
{ {
if (!IsSetter(classMethod)) var name = method.Name.Substring("get".Length);
continue; var prop = GetOrCreateProperty(@class, name, method.ReturnType);
prop.GetMethod = method;
if (classMethod.Parameters[0].Type.Equals(method.ReturnType.Type)) // Do not generate the original method now that we know it is a getter.
continue; method.IsGenerated = false;
var getName = method.Name.Substring("get".Length); Driver.Diagnostics.EmitMessage(DiagnosticId.PropertySynthetized,
var setName = classMethod.Name.Substring("set".Length); "Getter created: {0}::{1}", @class.Name, name);
if (getName != setName) return false;
continue; }
// We found a compatible pair of methods, create a property. if (IsSetter(method) && IsValidSetter(method))
var prop = new Property {
{ var name = method.Name.Substring("set".Length);
Name = getName,
Namespace = @class,
QualifiedType = method.ReturnType
};
// Ignore the original methods now that we have a property. var type = method.Parameters[0].QualifiedType;
method.ExplicityIgnored = true; var prop = GetOrCreateProperty(@class, name, type);
classMethod.ExplicityIgnored = true; prop.SetMethod = method;
@class.Properties.Add(prop); // Ignore the original method now that we know it is a setter.
method.IsGenerated = false;
Driver.Diagnostics.EmitMessage(DiagnosticId.PropertySynthetized, Driver.Diagnostics.EmitMessage(DiagnosticId.PropertySynthetized,
"Getter/setter property created: {0}::{1}", @class.Name, "Setter created: {0}::{1}", @class.Name, name);
getName);
return true; return false;
} }
return false; return false;
} }
// Check if a matching getter exist or no other setter exists.
private bool IsValidSetter(Method method)
{
var @class = method.Namespace as Class;
var name = method.Name.Substring("set".Length);
if (method.Parameters.Count == 0)
return false;
var type = method.Parameters[0].Type;
var getter = @class.Methods.FirstOrDefault(m => m.Name == "Get" + name && m.Type.Equals(type));
var otherSetter = @class.Methods.FirstOrDefault(m => m.Name == method.Name
&& m.Parameters.Count == 1
&& !m.Parameters[0].Type.Equals(type));
return getter != null || otherSetter == null;
}
} }
} }

Loading…
Cancel
Save