Skip to content

Commit

Permalink
Fix properties when a setter precedes a getter
Browse files Browse the repository at this point in the history
Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
  • Loading branch information
ddobrev committed Sep 19, 2019
1 parent ed6f8f1 commit ce27429
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 22 deletions.
58 changes: 39 additions & 19 deletions src/Generator/Passes/GetterSetterToPropertyPass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,16 @@ private static Property GetProperty(Method method, string name,
{
Type underlyingType = GetUnderlyingType(type);
Class @class = (Class) method.Namespace;

Property property = @class.Properties.Find(
p => p.Field == null &&
((!isSetter && p.HasSetter && p.Name == name) ||
(isSetter && p.HasGetter &&
GetReadWritePropertyName(p.GetMethod, name) == name)) &&
((p.HasGetter &&
GetUnderlyingType(p.GetMethod.OriginalReturnType).Equals(underlyingType)) ||
(p.HasSetter &&
GetUnderlyingType(p.SetMethod.Parameters[0].QualifiedType).Equals(underlyingType)))) ??
((!isSetter && p.SetMethod?.IsStatic == method.IsStatic) ||
(isSetter && p.GetMethod?.IsStatic == method.IsStatic)) &&
((p.HasGetter && GetUnderlyingType(
p.GetMethod.OriginalReturnType).Equals(underlyingType)) ||
(p.HasSetter && GetUnderlyingType(
p.SetMethod.Parameters[0].QualifiedType).Equals(underlyingType))) &&
Match(p, name)) ??
new Property { Name = name, QualifiedType = type };

if (property.Namespace == null)
Expand All @@ -160,13 +161,43 @@ private static Property GetProperty(Method method, string name,
(int) method.Access);
}

property.Name = property.OriginalName = name;
method.GenerationKind = GenerationKind.Internal;
if (method.ExplicitInterfaceImpl != null)
property.ExplicitInterfaceImpl = method.ExplicitInterfaceImpl;
return property;
}

private static bool Match(Property property, string name)
{
if (string.IsNullOrEmpty(name))
return false;

if (property.Name == name)
return true;

if (property.Name == RemovePrefix(name))
return true;

if (RemovePrefix(property.Name) == name)
{
property.Name = name;
return true;
}

return property.SetMethod != null &&
GetPropertyNameFromSetter(property.SetMethod.Name) == name;
}

private static string RemovePrefix(string identifier)
{
if (string.IsNullOrEmpty(identifier))
return identifier;

string name = GetPropertyName(identifier);
return name.StartsWith("is", StringComparison.Ordinal) && name != "is" ?
char.ToLowerInvariant(name[2]) + name.Substring(3) : name;
}

private static void ProcessProperties(Class @class, IEnumerable<Property> newProperties)
{
foreach (Property property in newProperties)
Expand Down Expand Up @@ -275,17 +306,6 @@ private static void RenameConflictingMethods(Class @class, Property property)
}
}

private static string GetReadWritePropertyName(INamedDecl getter, string afterSet)
{
string name = GetPropertyName(getter.Name);
if (name != afterSet && name.StartsWith("is", StringComparison.Ordinal) &&
name != "is")
{
name = char.ToLowerInvariant(name[2]) + name.Substring(3);
}
return name;
}

private static Type GetUnderlyingType(QualifiedType type)
{
TagType tagType = type.Type as TagType;
Expand Down
9 changes: 6 additions & 3 deletions src/Generator/Passes/MultipleInheritancePass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,19 @@ where property.IsDeclared

if (@interface.Bases.Count == 0)
{
QualifiedType intPtr = new QualifiedType(
new BuiltinType(PrimitiveType.IntPtr));
var instance = new Property
{
{
Namespace = @interface,
Name = Helpers.InstanceIdentifier,
QualifiedType = new QualifiedType(new BuiltinType(PrimitiveType.IntPtr)),
QualifiedType = intPtr,
GetMethod = new Method
{
Name = Helpers.InstanceIdentifier,
SynthKind = FunctionSynthKind.InterfaceInstance,
Namespace = @interface
Namespace = @interface,
OriginalReturnType = intPtr
}
};

Expand Down
9 changes: 9 additions & 0 deletions tests/Common/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,15 @@ void TestProperties::setStartWithVerb(int value)
{
}

void TestProperties::setSetterBeforeGetter(bool value)
{
}

bool TestProperties::isSetterBeforeGetter()
{
return true;
}

bool TestProperties::contains(char c)
{
return true;
Expand Down
3 changes: 3 additions & 0 deletions tests/Common/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,9 @@ struct DLL_API TestProperties
int startWithVerb();
void setStartWithVerb(int value);

void setSetterBeforeGetter(bool value);
bool isSetterBeforeGetter();

bool contains(char c);
bool contains(const char* str);
private:
Expand Down

0 comments on commit ce27429

Please sign in to comment.