Skip to content

Commit

Permalink
Refactor UNT0014 (#352)
Browse files Browse the repository at this point in the history
* Refactor UNT0014

* Rename
  • Loading branch information
sailro authored Sep 3, 2024
1 parent 2e60bb5 commit 1de7746
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 17 deletions.
129 changes: 114 additions & 15 deletions src/Microsoft.Unity.Analyzers.Tests/GetComponentIncorrectTypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private void Start()
}

[Fact]
public async Task GetComponentLegacyTest()
public async Task GetComponentLegacyInconclusiveTest()
{
const string test = @"
using UnityEngine;
Expand All @@ -108,6 +108,7 @@ class Camera : MonoBehaviour
{
private void Start()
{
// we only check for the generic overload.
var hello = GetComponent(""Hello"");
}
}
Expand All @@ -133,7 +134,43 @@ private void Method<T>() where T : Component
}

[Fact]
public async Task GetGenericMethodComponentIncorrectTest()
public async Task GetGenericClassComponentCorrectTest()
{
const string test = @"
using UnityEngine;
class Camera<T> : MonoBehaviour where T : Component
{
private void Method()
{
var hello = GetComponent<T>();
}
}
";
await VerifyCSharpDiagnosticAsync(test);
}

[Fact]
public async Task GetGenericClassComponentInconclusiveTest()
{
const string test = @"
using UnityEngine;
class Camera<T> : MonoBehaviour
{
private void Method()
{
// We need to infer on usages to be able to support this. For now, we don't.
GetComponent<T>();
}
}
";

await VerifyCSharpDiagnosticAsync(test);
}

[Fact]
public async Task GetGenericMethodInconclusiveTest()
{
const string test = @"
using UnityEngine;
Expand All @@ -142,52 +179,114 @@ class Camera : MonoBehaviour
{
private void Method<T>()
{
// We need to infer on usages to be able to support this. For now, we don't.
GetComponent<T>();
}
}
";
var diagnostic = ExpectDiagnostic()
.WithLocation(8, 9)
.WithArguments("T");

await VerifyCSharpDiagnosticAsync(test, diagnostic);
await VerifyCSharpDiagnosticAsync(test);
}

[Fact]
public async Task GetGenericClassComponentCorrectTest()
public async Task GetGenericMethodExplicitInterfaceCorrectTest()
{
const string test = @"
using UnityEngine;
class Camera<T> : MonoBehaviour where T : Component
class Camera : MonoBehaviour
{
private void Method()
private void Start()
{
var hello = GetComponent<T>();
Test<IMyInterface>();
}
private void Test<T>() where T : IMyInterface
{
gameObject.GetComponent<T>();
}
private interface IMyInterface { }
}
";
await VerifyCSharpDiagnosticAsync(test);
}

[Fact]
public async Task GetGenericMethodExplicitTypeCorrectTest()
{
const string test = @"
using UnityEngine;
class Camera : MonoBehaviour
{
private void Start()
{
Test<Component>();
}
private void Test<T>() where T : Component
{
gameObject.GetComponent<T>();
}
}
";
await VerifyCSharpDiagnosticAsync(test);
}

[Fact]
public async Task GetGenericClassComponentIncorrectTest()
public async Task GetGenericMethodExplicitTypeIncorrectTest()
{
const string test = @"
using System;
using UnityEngine;
class Camera<T> : MonoBehaviour
class Camera : MonoBehaviour
{
private void Method()
private void Start()
{
GetComponent<T>();
Test<Exception>();
}
private void Test<T>() where T : Exception
{
gameObject.GetComponent<T>();
}
}
";
var diagnostic = ExpectDiagnostic()
.WithLocation(8, 9)
.WithLocation(14, 9)
.WithArguments("T");

await VerifyCSharpDiagnosticAsync(test, diagnostic);
}

[Fact]
public async Task GetGenericMethodTypeReferenceConstraintInconclusiveTest()
{
const string test = @"
using UnityEngine;
class Camera : MonoBehaviour
{
private void Start()
{
// this one is valid,
Test<IMyInterface>();
// this one is not, but we need to infer on usages to be able to support this. For now, we don't.
Test<object>();
}
private void Test<T>() where T : class
{
gameObject.GetComponent<T>();
}
private interface IMyInterface { }
}
";

await VerifyCSharpDiagnosticAsync(test);
}
}
13 changes: 11 additions & 2 deletions src/Microsoft.Unity.Analyzers/GetComponentIncorrectType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,25 @@ private static bool HasInvalidTypeArgument(IMethodSymbol method, out string? ide
if (argumentType == null)
return false;

if (argumentType.Extends(typeof(UnityEngine.Component)) || argumentType.TypeKind == TypeKind.Interface)
if (IsComponentOrInterface(argumentType))
return false;

if (argumentType.TypeKind == TypeKind.TypeParameter && argumentType is ITypeParameterSymbol typeParameter)
{
if (typeParameter.ConstraintTypes.Any(t => t.Extends(typeof(UnityEngine.Component))))
// We need to infer the effective generic tye given usage, but we don't do that yet.
if (typeParameter.ConstraintTypes.IsEmpty)
return false;

if (typeParameter.ConstraintTypes.Any(IsComponentOrInterface))
return false;
}

identifier = argumentType.Name;
return true;
}

private static bool IsComponentOrInterface(ITypeSymbol argumentType)
{
return argumentType.Extends(typeof(UnityEngine.Component)) || argumentType.TypeKind == TypeKind.Interface;
}
}

0 comments on commit 1de7746

Please sign in to comment.