Browse Source

Fix static class edge cases

pull/1923/head
duckdoom5 4 months ago
parent
commit
d01d7aedaf
  1. 4
      src/AST/Class.cs
  2. 43
      src/Generator/Passes/CheckStaticClassPass.cs

4
src/AST/Class.cs

@ -149,9 +149,7 @@ namespace CppSharp.AST
public bool HasNonIgnoredBase => public bool HasNonIgnoredBase =>
HasBaseClass && !IsValueType HasBaseClass && !IsValueType
&& BaseClass != null && BaseClass is { IsValueType: false, IsGenerated: true };
&& !BaseClass.IsValueType
&& BaseClass.IsGenerated;
public bool NeedsBase => HasNonIgnoredBase && IsGenerated; public bool NeedsBase => HasNonIgnoredBase && IsGenerated;

43
src/Generator/Passes/CheckStaticClassPass.cs

@ -32,8 +32,7 @@ namespace CppSharp.Passes
if (decl.Access != AccessSpecifier.Protected) if (decl.Access != AccessSpecifier.Protected)
return false; return false;
var @class = decl.Namespace as Class; return decl.Namespace is Class { IsStatic: true };
return @class != null && @class.IsStatic;
} }
static void SetDeclarationAccessToPrivate(Declaration decl) static void SetDeclarationAccessToPrivate(Declaration decl)
@ -42,7 +41,7 @@ namespace CppSharp.Passes
// as an internal in the final C# wrapper. // as an internal in the final C# wrapper.
decl.Access = AccessSpecifier.Private; decl.Access = AccessSpecifier.Private;
// We need to explicity set the generation else the // We need to explicitly set the generation else the
// now private declaration will get filtered out later. // now private declaration will get filtered out later.
decl.GenerationKind = GenerationKind.Generate; decl.GenerationKind = GenerationKind.Generate;
} }
@ -51,20 +50,34 @@ namespace CppSharp.Passes
{ {
var returnType = function.ReturnType.Type.Desugar(); var returnType = function.ReturnType.Type.Desugar();
var tag = returnType as TagType; if (returnType is not TagType tag)
if (tag == null)
returnType.IsPointerTo(out tag); returnType.IsPointerTo(out tag);
if (tag == null) var decl = tag?.Declaration;
if (decl is not Class)
return false; return false;
var @class = (Class)function.Namespace; var @class = (Class)function.Namespace;
var decl = tag.Declaration; return @class.QualifiedOriginalName == decl.QualifiedOriginalName;
}
if (!(decl is Class)) static bool AcceptsClassInstance(Function function)
return false; {
return function.Parameters.Any(param =>
{
var paramType = param.Type.Desugar();
return @class.QualifiedOriginalName == decl.QualifiedOriginalName; if (paramType is not TagType tag)
paramType.IsPointerTo(out tag);
var decl = tag?.Declaration;
if (decl is not Class)
return false;
var @class = (Class)function.Namespace;
return @class.QualifiedOriginalName == decl.QualifiedOriginalName;
}
);
} }
public override bool VisitClassDecl(Class @class) public override bool VisitClassDecl(Class @class)
@ -117,12 +130,10 @@ namespace CppSharp.Passes
return false; return false;
} }
// Check for any static function that return a pointer to the class. // Check for any static function that accepts/returns a pointer to the class.
// If one exists, we assume it's a factory function and the class is // If one exists, we assume it's not meant to be static
// not meant to be static. It's a simple heuristic, but it should be if (@class.Functions.Any(m => !m.IsOperator && (ReturnsClassInstance(m) || AcceptsClassInstance(m))) ||
// good enough for the time being. @class.Methods.Any(m => !m.IsOperator && !m.IsConstructor && (ReturnsClassInstance(m) || AcceptsClassInstance(m))))
if (@class.Functions.Any(m => !m.IsOperator && ReturnsClassInstance(m)) ||
@class.Methods.Any(m => !m.IsOperator && ReturnsClassInstance(m)))
return false; return false;
// TODO: We should take C++ friends into account here, they might allow // TODO: We should take C++ friends into account here, they might allow

Loading…
Cancel
Save