未验证 提交 356bce2e 编写于 作者: M msftbot[bot] 提交者: GitHub

Merge pull request #48107 from davidwengier/FixNativeCasts

Don't offer to remove necessary native integer casts
......@@ -8131,5 +8131,161 @@ void Goo()
}
}");
}
[WorkItem(47800, "https://github.com/dotnet/roslyn/issues/47800")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)]
public async Task RemoveNativeIntCastsAsIdentity()
{
var source =
@"using System;
public class C {
public nint N(IntPtr x) => [|(nint)|]x;
}";
var fixedCode =
@"using System;
public class C {
public nint N(IntPtr x) => x;
}";
var test = new VerifyCS.Test()
{
TestCode = source,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp9
};
await test.RunAsync();
}
[WorkItem(47800, "https://github.com/dotnet/roslyn/issues/47800")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)]
public async Task DoRemoveNativeIntCasts()
{
var source =
@"using System;
public class C {
public nuint N(IntPtr x) => (nuint)(nint)x;
}";
var test = new VerifyCS.Test()
{
TestCode = source,
FixedCode = source,
LanguageVersion = LanguageVersion.CSharp9
};
await test.RunAsync();
}
[WorkItem(47800, "https://github.com/dotnet/roslyn/issues/47800")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)]
public async Task RemoveNativeUIntCastsAsIdentity()
{
var source =
@"using System;
public class C {
public nuint N(UIntPtr x) => [|(nuint)|]x;
}";
var fixedCode =
@"using System;
public class C {
public nuint N(UIntPtr x) => x;
}";
var test = new VerifyCS.Test()
{
TestCode = source,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp9
};
await test.RunAsync();
}
[WorkItem(47800, "https://github.com/dotnet/roslyn/issues/47800")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)]
public async Task DoRemoveNativeUIntCasts()
{
var source =
@"using System;
public class C {
public nint N(UIntPtr x) => (nint)(nuint)x;
}";
var test = new VerifyCS.Test()
{
TestCode = source,
FixedCode = source,
LanguageVersion = LanguageVersion.CSharp9
};
await test.RunAsync();
}
[WorkItem(47800, "https://github.com/dotnet/roslyn/issues/47800")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)]
public async Task RemoveIntPtrCastsAsIdentity()
{
var source =
@"
using System;
class C
{
public void M(IntPtr x)
{
var v = [|(IntPtr)|]x;
}
}";
var fixedCode =
@"
using System;
class C
{
public void M(IntPtr x)
{
var v = x;
}
}";
await VerifyCS.VerifyCodeFixAsync(source, fixedCode);
}
[WorkItem(47800, "https://github.com/dotnet/roslyn/issues/47800")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnnecessaryCast)]
public async Task RemoveUIntPtrCastsAsIdentity()
{
var source =
@"
using System;
class C
{
public void M(UIntPtr x)
{
var v = [|(UIntPtr)|]x;
}
}";
var fixedCode =
@"
using System;
class C
{
public void M(UIntPtr x)
{
var v = x;
}
}";
await VerifyCS.VerifyCodeFixAsync(source, fixedCode);
}
}
}
......@@ -455,6 +455,50 @@ private static bool IsObjectCastInInterpolation(ExpressionSyntax castNode, IType
if (IsTypeLessExpressionNotInTargetTypedLocation(castNode, castedExpressionType))
return true;
// If we have something like `(nuint)(nint)x` where x is an IntPtr then the nint cast cannot be removed
// as IntPtr to nuint is invalid.
if (IsIntPtrToNativeIntegerNestedCast(castNode, castType, castedExpressionType, semanticModel, cancellationToken))
return true;
return false;
}
private static bool IsIntPtrToNativeIntegerNestedCast(ExpressionSyntax castNode, ITypeSymbol castType, ITypeSymbol castedExpressionType, SemanticModel semanticModel, CancellationToken cancellationToken)
{
if (castedExpressionType == null)
{
return false;
}
if (castType.SpecialType is not (SpecialType.System_IntPtr or SpecialType.System_UIntPtr))
{
return false;
}
if (castNode.WalkUpParentheses().Parent is CastExpressionSyntax castExpression)
{
var parentCastType = semanticModel.GetTypeInfo(castExpression, cancellationToken).Type;
if (parentCastType == null)
{
return false;
}
var oppositeType = castType.SpecialType == SpecialType.System_IntPtr ? SpecialType.System_UIntPtr : SpecialType.System_IntPtr;
// Given (nuint)(nint)myIntPtr we would normally suggest removing the (nint) cast as being identity
// but it is required as a means to get from IntPtr to nuint, and vice versa from UIntPtr to nint,
// so we check for an identity cast from [U]IntPtr to n[u]int, and a parent cast to the opposite.
if (castedExpressionType.SpecialType == castType.SpecialType &&
!castedExpressionType.IsNativeIntegerType &&
castType.IsNativeIntegerType &&
parentCastType.IsNativeIntegerType &&
parentCastType.SpecialType == oppositeType)
{
return true;
}
}
return false;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册