Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding support for overriding the output class for constants and methods #291

Merged
merged 2 commits into from
Nov 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
188 changes: 68 additions & 120 deletions README.md

Large diffs are not rendered by default.

38 changes: 27 additions & 11 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ private void VisitEnumDecl(EnumDecl enumDecl)
if (name.StartsWith("__AnonymousEnum_"))
{
isAnonymousEnum = true;
name = _config.MethodClassName;
name = GetClass(name);
}

StartUsingOutputBuilder(name);
Expand Down Expand Up @@ -418,10 +418,14 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
return;
}

var name = GetRemappedCursorName(functionDecl);
var className = name;

if (functionDecl.DeclContext is not CXXRecordDecl cxxRecordDecl)
{
cxxRecordDecl = null;
StartUsingOutputBuilder(_config.MethodClassName);
className = GetClass(name);
StartUsingOutputBuilder(className);
}
else if ((Cursor)functionDecl.LexicalDeclContext != cxxRecordDecl)
{
Expand All @@ -430,7 +434,6 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
}

var accessSppecifier = GetAccessSpecifier(functionDecl);
var name = GetRemappedCursorName(functionDecl);

var cxxMethodDecl = functionDecl as CXXMethodDecl;
var body = functionDecl.Body;
Expand Down Expand Up @@ -494,7 +497,9 @@ private void VisitFunctionDecl(FunctionDecl functionDecl)
Location = functionDecl.Location
};

_outputBuilder.BeginFunctionOrDelegate(in desc, ref _isMethodClassUnsafe);
_ = _isTopLevelClassUnsafe.TryGetValue(className, out var isUnsafe);
_outputBuilder.BeginFunctionOrDelegate(in desc, ref isUnsafe);
_isTopLevelClassUnsafe[className] = isUnsafe;

_outputBuilder.BeginFunctionInnerPrototype(escapedName);

Expand Down Expand Up @@ -1121,8 +1126,10 @@ private void VisitRecordDecl(RecordDecl recordDecl)

if (_testOutputBuilder != null)
{
var className = GetClass(iidName);

_testOutputBuilder.AddUsingDirective("System");
_testOutputBuilder.AddUsingDirective($"static {GetNamespace(_config.MethodClassName)}.{_config.MethodClassName}");
_testOutputBuilder.AddUsingDirective($"static {GetNamespace(className)}.{className}");

_testOutputBuilder.WriteIndented("/// <summary>Validates that the <see cref=\"Guid\" /> of the <see cref=\"");
_testOutputBuilder.Write(escapedName);
Expand Down Expand Up @@ -1633,7 +1640,9 @@ void OutputMarkerInterface(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethodD
Location = cxxMethodDecl.Location
};

_outputBuilder.BeginFunctionOrDelegate(in desc, ref _isMethodClassUnsafe);
var isUnsafe = true;
_outputBuilder.BeginFunctionOrDelegate(in desc, ref isUnsafe);

_outputBuilder.BeginFunctionInnerPrototype(desc.EscapedName);

Visit(cxxMethodDecl.Parameters);
Expand Down Expand Up @@ -1758,7 +1767,9 @@ void OutputVtblHelperMethod(CXXRecordDecl cxxRecordDecl, CXXMethodDecl cxxMethod
Location = cxxMethodDecl.Location
};

_outputBuilder.BeginFunctionOrDelegate(in desc, ref _isMethodClassUnsafe);
var isUnsafe = true;
_outputBuilder.BeginFunctionOrDelegate(in desc, ref isUnsafe);

_outputBuilder.BeginFunctionInnerPrototype(desc.EscapedName);

Visit(cxxMethodDecl.Parameters);
Expand Down Expand Up @@ -2560,7 +2571,9 @@ void VisitConstantArrayFieldDecl(RecordDecl recordDecl, FieldDecl constantArray)
Location = constantArray.Location
};

_outputBuilder.BeginFunctionOrDelegate(in function, ref _isMethodClassUnsafe);
var isUnsafe = false;
_outputBuilder.BeginFunctionOrDelegate(in function, ref isUnsafe);

_outputBuilder.BeginFunctionInnerPrototype("AsSpan");

if (type.Size == 1)
Expand Down Expand Up @@ -2647,7 +2660,9 @@ void ForFunctionProtoType(TypedefDecl typedefDecl, FunctionProtoType functionPro
Location = typedefDecl.Location
};

_outputBuilder.BeginFunctionOrDelegate(in desc, ref _isMethodClassUnsafe);
var isUnsafe = desc.IsUnsafe;
_outputBuilder.BeginFunctionOrDelegate(in desc, ref isUnsafe);

_outputBuilder.BeginFunctionInnerPrototype(escapedName);

Visit(typedefDecl.CursorChildren.OfType<ParmVarDecl>());
Expand Down Expand Up @@ -2817,14 +2832,15 @@ private void VisitVarDecl(VarDecl varDecl)
}

var openedOutputBuilder = false;
var className = GetClass(name);

if (_outputBuilder is null)
{
openedOutputBuilder = true;

if (IsUnsafe(varDecl, type) && (!varDecl.HasInit || !IsStmtAsWritten<StringLiteral>(varDecl.Init, out _, removeParens: true)))
{
_isMethodClassUnsafe = true;
_isTopLevelClassUnsafe[className] = true;
}
}

Expand Down Expand Up @@ -2957,7 +2973,7 @@ private void VisitVarDecl(VarDecl varDecl)

if (openedOutputBuilder)
{
StartUsingOutputBuilder(_config.MethodClassName);
StartUsingOutputBuilder(className);

if ((kind == ValueKind.String) && (typeName == "ReadOnlySpan<byte>"))
{
Expand Down
32 changes: 14 additions & 18 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -596,9 +596,11 @@ private void VisitDeclRefExpr(DeclRefExpr declRefExpr)
{
if (enumName.StartsWith("__AnonymousEnum_"))
{
if (outputBuilder.Name != _config.MethodClassName)
var className = GetClass(enumName);

if (outputBuilder.Name != className)
{
outputBuilder.AddUsingDirective($"static {GetNamespace(_config.MethodClassName)}.{_config.MethodClassName}");
outputBuilder.AddUsingDirective($"static {GetNamespace(enumName)}.{className}");
}
}
else
Expand All @@ -615,23 +617,17 @@ private void VisitDeclRefExpr(DeclRefExpr declRefExpr)
}
else
{
if (TryGetNamespace(name, out var namespaceName))
if (TryGetClass(name, out var className))
{
var namespaceNameParts = namespaceName.Split(';');
namespaceName = namespaceNameParts[0];

if (namespaceNameParts.Length == 2)
{
if ($"{_currentNamespace}.{outputBuilder.Name}" != namespaceName)
{
outputBuilder.AddUsingDirective($"static {namespaceName}.{namespaceNameParts[1]}");
}
}
else if (_currentNamespace != namespaceName)
if (TryGetNamespace(className, out var namespaceName) && ((_currentNamespace != namespaceName) || (_currentClass != className)))
{
outputBuilder.AddUsingDirective(namespaceName);
outputBuilder.AddUsingDirective($"static {namespaceName}.{className}");
}
}
else if (TryGetNamespace(name, out var namespaceName) && (_currentNamespace != namespaceName))
{
outputBuilder.AddUsingDirective(namespaceName);
}

if (declRefExpr.Decl is FunctionDecl)
{
Expand Down Expand Up @@ -1351,7 +1347,7 @@ void HandleUnmanagedConstant(InitListExpr initListExpr, Type type, string typeNa
if (_testOutputBuilder != null)
{
_testOutputBuilder.AddUsingDirective("System");
_testOutputBuilder.AddUsingDirective($"static {GetNamespace(_config.MethodClassName)}.{_config.MethodClassName}");
_testOutputBuilder.AddUsingDirective($"static {GetNamespace(_outputBuilder.Name)}.{_outputBuilder.Name}");

_testOutputBuilder.WriteIndented("/// <summary>Validates that the value of the <see cref=\"");
_testOutputBuilder.Write(escapedName);
Expand Down Expand Up @@ -2289,9 +2285,9 @@ private void VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr unaryExprOrT
}
else
{
if (_outputBuilder.Name == _config.MethodClassName)
if (_topLevelClassNames.Contains(_outputBuilder.Name))
{
_isMethodClassUnsafe = true;
_isTopLevelClassUnsafe[_outputBuilder.Name] = true;
}

var parentType = null as Type;
Expand Down
Loading