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

Fix truncated message in generated Obsolete attributes #420

Merged
merged 9 commits into from
Mar 1, 2023
38 changes: 33 additions & 5 deletions sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5936,9 +5936,31 @@ private void WithAttributes(NamedDecl namedDecl, bool onlySupportedOSPlatform =
}
}

if (!isTestOutput && namedDecl.HasAttrs)
if (!isTestOutput)
{
foreach (var attr in namedDecl.Attrs)
var declAttrs = namedDecl.HasAttrs
? namedDecl.Attrs
: Enumerable.Empty<Attr>();

if (namedDecl is FieldDecl fieldDecl)
{
if (fieldDecl.Type is TypedefType defType && defType.Decl.HasAttrs)
{
declAttrs = declAttrs.Concat(defType.Decl.Attrs);
}
}
else if (namedDecl is RecordDecl recordDecl)
{
var typedefName = recordDecl.TypedefNameForAnonDecl;
if (typedefName != null && typedefName.HasAttrs)
{
declAttrs = declAttrs.Concat(typedefName.Attrs);
}
}

var obsoleteEmitted = false;

foreach (var attr in declAttrs)
{
switch (attr.Kind)
{
Expand All @@ -5953,20 +5975,26 @@ private void WithAttributes(NamedDecl namedDecl, bool onlySupportedOSPlatform =

case CX_AttrKind.CX_AttrKind_Deprecated:
{
if (obsoleteEmitted)
{
break;
}

var attrText = GetSourceRangeContents(namedDecl.TranslationUnit.Handle, attr.Extent);

var textStart = attrText.IndexOf('"');
var textLength = attrText.LastIndexOf('"') - textStart;

if (textLength > 2)
if (textLength > 1)
{
var text = attrText.AsSpan(textStart + 1, textLength - 2);
var text = attrText.AsSpan(textStart + 1, textLength - 1);
outputBuilder.WriteCustomAttribute($"Obsolete(\"{text}\")");
}
else
{
outputBuilder.WriteCustomAttribute($"Obsolete");
}
obsoleteEmitted = true;
break;
}

Expand Down Expand Up @@ -6241,7 +6269,7 @@ private void WithTestAssertEqual(string expected, string actual)
_testOutputBuilder.WriteIndented("Assert.Equal");
_testOutputBuilder.Write('(');
_testOutputBuilder.Write(expected);
_testOutputBuilder.Write(", ");;
_testOutputBuilder.Write(", ");
_testOutputBuilder.Write(actual);
_testOutputBuilder.Write(')');
_testOutputBuilder.WriteSemicolon();
Expand Down
6 changes: 3 additions & 3 deletions sources/ClangSharp/Cursors/Decls/TagDecl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public unsafe class TagDecl : TypeDecl, IDeclContext, IRedeclarable<TagDecl>
{
private readonly Lazy<TagDecl?> _definition;
private readonly Lazy<IReadOnlyList<IReadOnlyList<NamedDecl>>> _templateParameterLists;
private readonly Lazy<TypedefNameDecl> _typedefNameForAnonDecl;
private readonly Lazy<TypedefNameDecl?> _typedefNameForAnonDecl;

private protected TagDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_DeclKind expectedDeclKind) : base(handle, expectedCursorKind, expectedDeclKind)
{
Expand Down Expand Up @@ -42,7 +42,7 @@ private protected TagDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_D
return templateParameterLists;
});

_typedefNameForAnonDecl = new Lazy<TypedefNameDecl>(() => TranslationUnit.GetOrCreate<TypedefNameDecl>(Handle.TypedefNameForAnonDecl));
_typedefNameForAnonDecl = new Lazy<TypedefNameDecl?>(() => !Handle.TypedefNameForAnonDecl.IsNull ? TranslationUnit.GetOrCreate<TypedefNameDecl>(Handle.TypedefNameForAnonDecl) : null);
}

public new TagDecl CanonicalDecl => (TagDecl)base.CanonicalDecl;
Expand All @@ -65,5 +65,5 @@ private protected TagDecl(CXCursor handle, CXCursorKind expectedCursorKind, CX_D

public IReadOnlyList<IReadOnlyList<NamedDecl>> TemplateParameterLists => _templateParameterLists.Value;

public TypedefNameDecl TypedefNameForAnonDecl => _typedefNameForAnonDecl.Value;
public TypedefNameDecl? TypedefNameForAnonDecl => _typedefNameForAnonDecl.Value;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information.

using System.Threading.Tasks;
using NUnit.Framework;

namespace ClangSharp.UnitTests;

public abstract class DeprecatedToObsoleteTest : PInvokeGeneratorTest
{
[TestCase("int", "int")]
public Task SimpleStructMembers(string nativeType, string expectedManagedType) => SimpleStructMembersImpl(nativeType, expectedManagedType);

[Test]
public Task StructDecl() => StructDeclImpl();

[TestCase("int", "int")]
public Task SimpleTypedefStructMembers(string nativeType, string expectedManagedType) => SimpleTypedefStructMembersImpl(nativeType, expectedManagedType);

[Test]
public Task TypedefStructDecl() => TypedefStructDeclImpl();

[Test]
public Task SimpleEnumMembers() => SimpleEnumMembersImpl();

[Test]
public Task EnumDecl() => EnumDeclImpl();

[TestCase("int", "int")]
public Task SimpleVarDecl(string nativeType, string expectedManagedType) => SimpleVarDeclImpl(nativeType, expectedManagedType);

[Test]
public Task FuncDecl() => FuncDeclImpl();

[Test]
public Task InstanceFunc() => InstanceFuncImpl();

[Test]
public Task FuncPtrDecl() => FuncPtrDeclImpl();

[Test]
public Task FuncDeclDllImport() => FuncDllImportImpl();

protected abstract Task SimpleStructMembersImpl(string nativeType, string expectedManagedType);

protected abstract Task StructDeclImpl();

protected abstract Task SimpleTypedefStructMembersImpl(string nativeType, string expectedManagedType);

protected abstract Task TypedefStructDeclImpl();

protected abstract Task SimpleEnumMembersImpl();

protected abstract Task EnumDeclImpl();

protected abstract Task SimpleVarDeclImpl(string nativeType, string expectedManagedType);

protected abstract Task FuncDeclImpl();

protected abstract Task InstanceFuncImpl();

protected abstract Task FuncPtrDeclImpl();

protected abstract Task FuncDllImportImpl();
}
Loading