Browse Source

Name anonymous types after the fields which use them

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/1187/merge
Dimitar Dobrev 6 years ago committed by João Matos
parent
commit
0e8c80c3b2
  1. 89
      src/Generator/Passes/CleanInvalidDeclNamesPass.cs
  2. 195
      tests/CSharp/AnonTypes.h
  3. 25
      tests/Common/Common.h

89
src/Generator/Passes/CleanInvalidDeclNamesPass.cs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
using System.Linq;
using System.Text;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
namespace CppSharp.Passes
@ -22,9 +23,32 @@ namespace CppSharp.Passes @@ -22,9 +23,32 @@ namespace CppSharp.Passes
if (@class.Layout != null)
{
int order = 0;
foreach (var field in @class.Layout.Fields)
field.Name = CheckName(field.Name, ref order);
var fields = @class.Layout.Fields.Where(
f => string.IsNullOrEmpty(f.Name)).ToList();
for (int i = 0; i < fields.Count; i++)
fields[i].Name = $"_{i}";
}
return true;
}
public override bool VisitFieldDecl(Field field)
{
if (!base.VisitDeclaration(field))
return false;
field.Type.Visit(this, field.QualifiedType.Qualifiers);
Class @class;
if (field.Type.TryGetClass(out @class) && string.IsNullOrEmpty(@class.OriginalName))
{
@class.Name = field.Name;
foreach (var item in @class.Fields.Where(f => f.Name == @class.Name))
Rename(item);
Rename(field);
}
return true;
@ -35,8 +59,10 @@ namespace CppSharp.Passes @@ -35,8 +59,10 @@ namespace CppSharp.Passes
if (!base.VisitEnumDecl(@enum))
return false;
CheckChildrenNames(@enum.Items,
string.IsNullOrEmpty(@enum.Name) ? 1 : 0);
Check(@enum.Items);
foreach (Enumeration.Item item in @enum.Items.Where(i => char.IsNumber(i.Name[0])))
item.Name = $"_{item.Name}";
CheckEnumName(@enum);
return true;
}
@ -46,7 +72,7 @@ namespace CppSharp.Passes @@ -46,7 +72,7 @@ namespace CppSharp.Passes
if (!base.VisitFunctionDecl(function))
return false;
CheckChildrenNames(function.Parameters);
Check(function.Parameters);
return true;
}
@ -55,18 +81,11 @@ namespace CppSharp.Passes @@ -55,18 +81,11 @@ namespace CppSharp.Passes
if (!base.VisitDeclarationContext(context))
return false;
DeclarationContext currentContext = context;
int order = -1;
while (currentContext != null)
{
order++;
currentContext = currentContext.Namespace;
}
CheckChildrenNames(context.Declarations, ref order);
Check(context.Declarations);
var @class = context as Class;
if (@class != null)
CheckChildrenNames(@class.Fields, order);
Check(@class.Fields);
return true;
}
@ -76,19 +95,10 @@ namespace CppSharp.Passes @@ -76,19 +95,10 @@ namespace CppSharp.Passes
if (!base.VisitFunctionType(function, quals))
return false;
CheckChildrenNames(function.Parameters);
Check(function.Parameters);
return true;
}
private void CheckChildrenNames(IEnumerable<Declaration> children, int order = 0) =>
CheckChildrenNames(children, ref order);
private void CheckChildrenNames(IEnumerable<Declaration> children, ref int order)
{
foreach (var child in children)
child.Name = CheckName(child.Name, ref order);
}
private void CheckEnumName(Enumeration @enum)
{
// If we still do not have a valid name, then try to guess one
@ -102,12 +112,7 @@ namespace CppSharp.Passes @@ -102,12 +112,7 @@ namespace CppSharp.Passes
// Try a simple heuristic to make sure we end up with a valid name.
if (prefix.Length < 3)
{
int order = @enum.Namespace.Enums.Count(e => e != @enum &&
string.IsNullOrEmpty(e.Name));
@enum.Name = CheckName(@enum.Name, ref order);
return;
}
var prefixBuilder = new StringBuilder(prefix);
prefixBuilder.TrimUnderscores();
@ -117,17 +122,23 @@ namespace CppSharp.Passes @@ -117,17 +122,23 @@ namespace CppSharp.Passes
@enum.Name = prefixBuilder.ToString();
}
private string CheckName(string name, ref int order)
private static void Rename(Field field)
{
// Generate a new name if the decl still does not have a name
if (string.IsNullOrWhiteSpace(name))
return $"_{order++}";
// Clean up the item name if the first digit is not a valid name.
if (char.IsNumber(name[0]))
return '_' + name;
var nameBuilder = new StringBuilder(field.Name);
for (int i = 0; i < nameBuilder.Length; i++)
{
if (!char.IsUpper(nameBuilder[i]))
break;
nameBuilder[i] = char.ToLowerInvariant(nameBuilder[i]);
}
field.Name = nameBuilder.ToString();
}
return name;
private static void Check(IEnumerable<Declaration> decls)
{
var anonymousDecls = decls.Where(p => string.IsNullOrEmpty(p.Name)).ToList();
for (int i = 0; i < anonymousDecls.Count; i++)
anonymousDecls[i].Name = $"_{i}";
}
}
}

195
tests/CSharp/AnonTypes.h

@ -0,0 +1,195 @@ @@ -0,0 +1,195 @@
#ifndef KONAN_EXAMPLE_LIB_H
#define KONAN_EXAMPLE_LIB_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
typedef bool example_lib_KBoolean;
#else
typedef _Bool example_lib_KBoolean;
#endif
typedef unsigned short example_lib_KChar;
typedef signed char example_lib_KByte;
typedef short example_lib_KShort;
typedef int example_lib_KInt;
typedef long long example_lib_KLong;
typedef unsigned char example_lib_KUByte;
typedef unsigned short example_lib_KUShort;
typedef unsigned int example_lib_KUInt;
typedef unsigned long long example_lib_KULong;
typedef float example_lib_KFloat;
typedef double example_lib_KDouble;
typedef void* example_lib_KNativePtr;
struct example_lib_KType;
typedef struct example_lib_KType example_lib_KType;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_APIHost;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_APIHost_CACAHUETE;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_APIHost_CAPI;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_kotlin_collections_Map;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Method;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_kotlin_Any;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Method_GET;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Method_POST;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Method_PUT;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Method_DELETE;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Method_PATCH;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Response;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Response_DataResponse;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Response_FileResponse;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_com_plangrid_example_Request_Response_ErrorResponse;
typedef struct {
example_lib_KNativePtr pinned;
} example_lib_kref_kotlin_Error;
typedef struct {
/* Service functions. */
void(*DisposeStablePointer)(example_lib_KNativePtr ptr);
void(*DisposeString)(const char* string);
example_lib_KBoolean(*IsInstance)(example_lib_KNativePtr ref, const example_lib_KType* type);
/* User functions. */
struct {
struct {
struct {
struct {
struct {
struct {
example_lib_KType* (*_type)(void);
struct {
example_lib_kref_com_plangrid_example_APIHost(*get)(); /* enum entry for CACAHUETE. */
} CACAHUETE;
struct {
example_lib_kref_com_plangrid_example_APIHost(*get)(); /* enum entry for CAPI. */
} CAPI;
} APIHost;
struct {
example_lib_KType* (*_type)(void);
example_lib_kref_com_plangrid_example_Request(*Request)(const char* path, example_lib_kref_kotlin_collections_Map queryParams, const char* body, example_lib_kref_com_plangrid_example_Request_Method method);
const char* (*get_path)(example_lib_kref_com_plangrid_example_Request thiz);
example_lib_kref_kotlin_collections_Map(*get_queryParams)(example_lib_kref_com_plangrid_example_Request thiz);
const char* (*get_body)(example_lib_kref_com_plangrid_example_Request thiz);
example_lib_kref_com_plangrid_example_Request_Method(*get_method)(example_lib_kref_com_plangrid_example_Request thiz);
example_lib_KBoolean(*equals)(example_lib_kref_com_plangrid_example_Request thiz, example_lib_kref_kotlin_Any other);
example_lib_KInt(*hashCode)(example_lib_kref_com_plangrid_example_Request thiz);
const char* (*toString)(example_lib_kref_com_plangrid_example_Request thiz);
const char* (*component1)(example_lib_kref_com_plangrid_example_Request thiz);
example_lib_kref_kotlin_collections_Map(*component2)(example_lib_kref_com_plangrid_example_Request thiz);
const char* (*component3)(example_lib_kref_com_plangrid_example_Request thiz);
example_lib_kref_com_plangrid_example_Request_Method(*component4)(example_lib_kref_com_plangrid_example_Request thiz);
example_lib_kref_com_plangrid_example_Request(*copy)(example_lib_kref_com_plangrid_example_Request thiz, const char* path, example_lib_kref_kotlin_collections_Map queryParams, const char* body, example_lib_kref_com_plangrid_example_Request_Method method);
struct {
example_lib_KType* (*_type)(void);
struct {
example_lib_kref_com_plangrid_example_Request_Method(*get)(); /* enum entry for GET. */
} GET;
struct {
example_lib_kref_com_plangrid_example_Request_Method(*get)(); /* enum entry for POST. */
} POST;
struct {
example_lib_kref_com_plangrid_example_Request_Method(*get)(); /* enum entry for PUT. */
} PUT;
struct {
example_lib_kref_com_plangrid_example_Request_Method(*get)(); /* enum entry for DELETE. */
} DELETE;
struct {
example_lib_kref_com_plangrid_example_Request_Method(*get)(); /* enum entry for PATCH. */
} PATCH;
} Method;
struct {
example_lib_KType* (*_type)(void);
struct {
example_lib_KType* (*_type)(void);
example_lib_kref_com_plangrid_example_Request_Response_DataResponse(*DataResponse)(const char* data);
const char* (*get_data)(example_lib_kref_com_plangrid_example_Request_Response_DataResponse thiz);
} DataResponse;
struct {
example_lib_KType* (*_type)(void);
example_lib_kref_com_plangrid_example_Request_Response_FileResponse(*FileResponse)(const char* filePath);
const char* (*get_filePath)(example_lib_kref_com_plangrid_example_Request_Response_FileResponse thiz);
} FileResponse;
struct {
example_lib_KType* (*_type)(void);
example_lib_kref_com_plangrid_example_Request_Response_ErrorResponse(*ErrorResponse)(example_lib_kref_kotlin_Error error);
example_lib_kref_kotlin_Error(*get_error)(example_lib_kref_com_plangrid_example_Request_Response_ErrorResponse thiz);
} ErrorResponse;
} Response;
} Request;
} example;
} plangrid;
} com;
} root;
} kotlin;
} example_lib_ExportedSymbols;
extern example_lib_ExportedSymbols* example_lib_symbols(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* KONAN_EXAMPLE_LIB_H */
// Code like below would hardly appear in practice
// but it's worth noting we don't support it
#if 0
struct DLL_API TestAnonTypesWithAnonFields
{
public:
struct
{
struct
{
};
};
struct
{
struct
{
};
};
struct
{
struct
{
};
};
struct
{
struct
{
};
};
};
#endif

25
tests/Common/Common.h

@ -825,31 +825,6 @@ DLL_API void va_listFunction(va_list v); @@ -825,31 +825,6 @@ DLL_API void va_listFunction(va_list v);
struct DLL_API TestNestedTypes
{
public:
struct
{
struct
{
};
};
struct
{
struct
{
};
};
struct
{
struct
{
};
};
struct
{
struct
{
};
};
union as_types
{
int as_int;

Loading…
Cancel
Save