diff --git a/CHANGELOG.md b/CHANGELOG.md index e45e570eb..06ab5aef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,20 @@ Since 2018.1, the version numbers and release cycle match Rider's versions and r ## 2022.1.1 * [Commits](https://github.com/JetBrains/resharper-unity/compare/net221-rtm-2022.1.0...net221-rtm-2022.1.1) +* [Milestone](https://github.com/JetBrains/resharper-unity/milestone/52?closed=1) + +### Added + +- Add "means implicit use" external annotations for `OverlayAttribute` and `EditorToolbarElementAttribute` ([RIDER-76826](https://youtrack.jetbrains.com/issue/RIDER-76826), [#2312](https://github.com/JetBrains/resharper-unity/pull/2312)) + +### Changed + +- Treat types that implement `ISystem` as ECS systems ([#2301](https://github.com/JetBrains/resharper-unity/issues/2301), [#2312](https://github.com/JetBrains/resharper-unity/pull/2312)) ### Fixed +- Fix incorrect method signature warning for semi-documented `OnPostprocessAllAssets` event function overload ([RIDER-76682](https://youtrack.jetbrains.com/issue/RIDER-76682), [#2312](https://github.com/JetBrains/resharper-unity/pull/2312)) +- Fix method signature warnings for `[MenuItem]` with the optional `MenuCommand` parameter, and when the `validate` argument is set via named property instead of positional argument ([RIDER-76680](https://youtrack.jetbrains.com/issue/RIDER-76680), [RIDER-76681](https://youtrack.jetbrains.com/issue/RIDER-76681), [#2312](https://github.com/JetBrains/resharper-unity/pull/2312)) - Fix exception when asset reference a missing script ([DEXP-661796](https://youtrack.jetbrains.com/issue/DEXP-661796)) diff --git a/resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatureProblemAnalyzer.cs b/resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatureProblemAnalyzer.cs index 750ce954f..6a47dd0fd 100644 --- a/resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatureProblemAnalyzer.cs +++ b/resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatureProblemAnalyzer.cs @@ -1,14 +1,15 @@ -using System.Collections.Concurrent; +#nullable enable + +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using JetBrains.Metadata.Reader.API; using JetBrains.ReSharper.Feature.Services.Daemon; using JetBrains.ReSharper.Plugins.Unity.CSharp.Daemon.Errors; using JetBrains.ReSharper.Plugins.Unity.UnityEditorIntegration.Api; using JetBrains.ReSharper.Psi; -using JetBrains.ReSharper.Psi.CSharp.Parsing; using JetBrains.ReSharper.Psi.CSharp.Tree; +using JetBrains.ReSharper.Psi.Tree; using JetBrains.Util.dataStructures; using MethodSignature = JetBrains.ReSharper.Plugins.Unity.UnityEditorIntegration.Api.MethodSignature; @@ -90,10 +91,9 @@ protected override void Analyze(IAttribute element, ElementProblemAnalyzerData d } } - [CanBeNull] - private MethodSignature[] GetExpectedMethodSignatures(ITypeElement attributeTypeElement, - IAttribute attribute, - PredefinedType predefinedType) + private MethodSignature[]? GetExpectedMethodSignatures(ITypeElement attributeTypeElement, + IAttribute attribute, + PredefinedType predefinedType) { var attributeClrName = attributeTypeElement.GetClrName(); if (myMethodSignatures.TryGetValue(attributeClrName, out var signatures)) @@ -117,8 +117,7 @@ private MethodSignature[] GetExpectedMethodSignatures(ITypeElement attributeType return signatures; } - [CanBeNull] - private MethodSignature[] GetSignaturesFromRequiredSignatureAttribute(ITypeElement attributeTypeElement) + private MethodSignature[]? GetSignaturesFromRequiredSignatureAttribute(ITypeElement attributeTypeElement) { var signatures = new FrugalLocalList(); foreach (var method in attributeTypeElement.Methods) @@ -141,9 +140,8 @@ private MethodSignature[] GetSignaturesFromRequiredSignatureAttribute(ITypeEleme return signatures.IsEmpty ? null : signatures.ToArray(); } - [CanBeNull] - private MethodSignature[] GetSignaturesFromKnownAttributes(IClrTypeName attributeClrName, - PredefinedType predefinedType) + private MethodSignature[]? GetSignaturesFromKnownAttributes(IClrTypeName attributeClrName, + PredefinedType predefinedType) { if (ourKnownAttributes.Contains(attributeClrName)) { @@ -156,9 +154,8 @@ private MethodSignature[] GetSignaturesFromKnownAttributes(IClrTypeName attribut return null; } - [CanBeNull] - private MethodSignature[] GetSpecialCaseSignatures( - IClrTypeName attributeClrName, PredefinedType predefinedType) + private MethodSignature[]? GetSpecialCaseSignatures(IClrTypeName attributeClrName, + PredefinedType predefinedType) { if (Equals(attributeClrName, KnownTypes.OnOpenAssetAttribute)) return GetOnOpenAssetMethodSignature(predefinedType); @@ -166,38 +163,53 @@ private MethodSignature[] GetSpecialCaseSignatures( return GetPostProcessBuildMethodSignature(predefinedType); return null; } - - [CanBeNull] - private MethodSignature[] GetNonCacheableSignatures(IAttribute attribute, - IClrTypeName attributeClrName, PredefinedType predefinedType) + + private MethodSignature[]? GetNonCacheableSignatures(IAttribute attribute, + IClrTypeName attributeClrName, + PredefinedType predefinedType) { if (Equals(attributeClrName, KnownTypes.MenuItemAttribute)) return GetMenuItemMethodSignature(attribute, predefinedType); return null; } + private static MethodSignature GetStaticVoidMethodSignature(PredefinedType predefinedType) => + new(predefinedType.Void, true); + private MethodSignature[] GetMenuItemMethodSignature(IAttribute attribute, PredefinedType predefinedType) { - if (attribute.Arguments.Count <= 1) // MenuItem("text") - return new[] { new MethodSignature(predefinedType.Void, true) }; - var secondParameter = attribute.Arguments[1].FirstChild?.FirstChild; - if (secondParameter != null) + IExpression? validateArgExpression = null; + if (attribute.Arguments.Count > 1) { - // MenuItem("text", true) - if (secondParameter.NodeType.Equals(CSharpTokenType.TRUE_KEYWORD)) - return new[] { new MethodSignature(predefinedType.Bool, true) }; - // MenuItem("text", false) - if (secondParameter.NodeType.Equals(CSharpTokenType.FALSE_KEYWORD)) - return new[] { new MethodSignature(predefinedType.Void, true) }; + // [MenuItem("Something", true|false)] + validateArgExpression = attribute.Arguments[1].Expression; + } + else + { + // [MenuItem("Something", validate = true|false)] + foreach (var assignment in attribute.PropertyAssignments) + { + if (assignment.PropertyNameIdentifier?.Name == "validate") + { + validateArgExpression = assignment.Source; + break; + } + } } - - return null; - } - [NotNull] - private static MethodSignature GetStaticVoidMethodSignature(PredefinedType predefinedType) - { - return new MethodSignature(predefinedType.Void, true); + var returnType = predefinedType.Void; + if (validateArgExpression != null && validateArgExpression.IsConstantValue() && + validateArgExpression.ConstantValue.IsBoolean(out var validate) && validate) + { + returnType = predefinedType.Bool; + } + + var menuCommandType = myKnownTypesCache.GetByClrTypeName(KnownTypes.MenuCommand, predefinedType.Module); + return new[] + { + new MethodSignature(returnType, true), + new MethodSignature(returnType, true, new[] { menuCommandType }, new[] { "menuCommand" }) + }; } private static MethodSignature[] GetOnOpenAssetMethodSignature(PredefinedType predefinedType) @@ -225,4 +237,4 @@ private MethodSignature[] GetPostProcessBuildMethodSignature(PredefinedType pred }; } } -} \ No newline at end of file +} diff --git a/resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Highlightings/IconsProviders/TypeDetector.cs b/resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Highlightings/IconsProviders/TypeDetector.cs index 182600901..ce980b9b1 100644 --- a/resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Highlightings/IconsProviders/TypeDetector.cs +++ b/resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Highlightings/IconsProviders/TypeDetector.cs @@ -46,19 +46,19 @@ public override bool AddDeclarationHighlighting(IDeclaration node, IHighlighting } else if (typeElement.DerivesFrom(KnownTypes.Editor) || typeElement.DerivesFrom(KnownTypes.EditorWindow)) { - AddEditorHighlighting(consumer, element, "Editor", "Custom Unity Editor", context); + AddEditorHighlighting(consumer, element, "Editor", "Custom Unity editor", context); } else if (typeElement.DerivesFromScriptableObject()) { - AddMonoBehaviourHighlighting(consumer, element, "Scriptable object", "Scriptable Object", context); + AddMonoBehaviourHighlighting(consumer, element, "Scriptable object", "Unity scriptable object", context); } else if (myUnityApi.IsUnityType(typeElement)) { AddUnityTypeHighlighting(consumer, element, "Unity type", "Custom Unity type", context); } - else if (myUnityApi.IsComponentSystemType(typeElement)) + else if (UnityApi.IsDotsSystemType(typeElement)) { - AddUnityECSHighlighting(consumer, element, "Unity ECS", "Unity entity component system object", + AddUnityECSHighlighting(consumer, element, "ECS system", "Unity entities system", context); } diff --git a/resharper/resharper-unity/src/Unity/CSharp/Daemon/UsageChecking/UsageInspectionsSuppressor.cs b/resharper/resharper-unity/src/Unity/CSharp/Daemon/UsageChecking/UsageInspectionsSuppressor.cs index 820c8a307..a57abac48 100644 --- a/resharper/resharper-unity/src/Unity/CSharp/Daemon/UsageChecking/UsageInspectionsSuppressor.cs +++ b/resharper/resharper-unity/src/Unity/CSharp/Daemon/UsageChecking/UsageInspectionsSuppressor.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +#nullable enable + +using System.Collections.Generic; using JetBrains.Annotations; using JetBrains.Application; using JetBrains.Metadata.Reader.API; @@ -52,7 +54,7 @@ public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out Impl switch (element) { case IClass cls when unityApi.IsUnityType(cls) || - unityApi.IsComponentSystemType(cls) || + UnityApi.IsDotsSystemType(cls) || IsUxmlFactory(cls): flags = ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature; return true; @@ -110,9 +112,7 @@ public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out Impl private bool IsUxmlFactory(IClass cls) { var baseClass = cls.GetBaseClassType(); - if (baseClass == null) - return false; - return myUxmlFactoryBaseClasses.Contains(baseClass.GetClrName()); + return baseClass != null && myUxmlFactoryBaseClasses.Contains(baseClass.GetClrName()); } private static bool IsAnimationEvent(ISolution solution, IDeclaredElement property) @@ -155,7 +155,7 @@ private bool IsImplicitlyUsedInterfaceProperty(IProperty property) return false; } - private bool HasOptionalParameter(UnityEventFunction function) + private static bool HasOptionalParameter(UnityEventFunction function) { foreach (var parameter in function.Parameters) { @@ -166,12 +166,12 @@ private bool HasOptionalParameter(UnityEventFunction function) return false; } - private bool IsEventHandler(UnityApi unityApi, [CanBeNull] IMethod method) + private static bool IsEventHandler(UnityApi unityApi, IMethod? method) { if (method == null) return false; - var type = method.GetContainingType(); + var type = method.ContainingType; if (!unityApi.IsUnityType(type)) return false; diff --git a/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/KnownTypes.cs b/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/KnownTypes.cs index dd156461c..a08d16256 100644 --- a/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/KnownTypes.cs +++ b/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/KnownTypes.cs @@ -1,8 +1,12 @@ -using JetBrains.Metadata.Reader.API; +#nullable enable + +using System.Diagnostics.CodeAnalysis; +using JetBrains.Metadata.Reader.API; using JetBrains.Metadata.Reader.Impl; namespace JetBrains.ReSharper.Plugins.Unity.UnityEditorIntegration.Api { + [SuppressMessage("ReSharper", "InconsistentNaming")] public static class KnownTypes { // System @@ -81,10 +85,11 @@ public static class KnownTypes public static readonly IClrTypeName GizmoType = new ClrTypeName("UnityEditor.GizmoType"); public static readonly IClrTypeName InitializeOnLoadAttribute = new ClrTypeName("UnityEditor.InitializeOnLoadAttribute"); public static readonly IClrTypeName InitializeOnLoadMethodAttribute = new ClrTypeName("UnityEditor.InitializeOnLoadMethodAttribute"); + public static readonly IClrTypeName MenuCommand = new ClrTypeName("UnityEditor.MenuCommand"); + public static readonly IClrTypeName MenuItemAttribute = new ClrTypeName("UnityEditor.MenuItem"); public static readonly IClrTypeName PreferenceItem = new ClrTypeName("UnityEditor.PreferenceItem"); public static readonly IClrTypeName PropertyDrawer = new ClrTypeName("UnityEditor.PropertyDrawer"); public static readonly IClrTypeName RequiredSignatureAttribute = new ClrTypeName("UnityEditor.RequiredSignatureAttribute"); - public static readonly IClrTypeName MenuItemAttribute = new ClrTypeName("UnityEditor.MenuItem"); // UnityEditor.Callbacks public static readonly IClrTypeName DidReloadScripts = new ClrTypeName("UnityEditor.Callbacks.DidReloadScripts"); @@ -98,7 +103,7 @@ public static class KnownTypes // ECS/DOTS public static readonly IClrTypeName ComponentSystemBase = new ClrTypeName("Unity.Entities.ComponentSystemBase"); - public static readonly IClrTypeName JobComponentSystem = new ClrTypeName("Unity.Entities.JobComponentSystem"); + public static readonly IClrTypeName ISystem = new ClrTypeName("Unity.Entities.ISystem"); // Burst public static readonly IClrTypeName BurstCompiler = new ClrTypeName("Unity.Burst.BurstCompiler"); @@ -109,13 +114,13 @@ public static class KnownTypes public static readonly IClrTypeName SharedStatic = new ClrTypeName("Unity.Burst.SharedStatic`1"); // Jobs - public static readonly IClrTypeName Job = new ClrTypeName("Unity.Jobs.IJob"); - public static readonly IClrTypeName JobFor = new ClrTypeName("Unity.Jobs.IJobFor"); - public static readonly IClrTypeName JobParallelFor = new ClrTypeName("Unity.Jobs.IJobParallelFor"); - public static readonly IClrTypeName AnimationJob = new ClrTypeName("UnityEngine.Animations.IAnimationJob"); - public static readonly IClrTypeName JobParallelForTransform = new ClrTypeName("UnityEngine.Jobs.IJobParallelForTransform"); - public static readonly IClrTypeName JobParticleSystem = new ClrTypeName("UnityEngine.ParticleSystemJobs.IJobParticleSystem"); - public static readonly IClrTypeName JobParticleSystemParallelFor = new ClrTypeName("UnityEngine.ParticleSystemJobs.IJobParticleSystemParallelFor"); - public static readonly IClrTypeName JobParticleSystemParallelForBatch = new ClrTypeName("UnityEngine.ParticleSystemJobs.IJobParticleSystemParallelForBatch"); + // public static readonly IClrTypeName Job = new ClrTypeName("Unity.Jobs.IJob"); + // public static readonly IClrTypeName JobFor = new ClrTypeName("Unity.Jobs.IJobFor"); + // public static readonly IClrTypeName JobParallelFor = new ClrTypeName("Unity.Jobs.IJobParallelFor"); + // public static readonly IClrTypeName AnimationJob = new ClrTypeName("UnityEngine.Animations.IAnimationJob"); + // public static readonly IClrTypeName JobParallelForTransform = new ClrTypeName("UnityEngine.Jobs.IJobParallelForTransform"); + // public static readonly IClrTypeName JobParticleSystem = new ClrTypeName("UnityEngine.ParticleSystemJobs.IJobParticleSystem"); + // public static readonly IClrTypeName JobParticleSystemParallelFor = new ClrTypeName("UnityEngine.ParticleSystemJobs.IJobParticleSystemParallelFor"); + // public static readonly IClrTypeName JobParticleSystemParallelForBatch = new ClrTypeName("UnityEngine.ParticleSystemJobs.IJobParticleSystemParallelForBatch"); } -} \ No newline at end of file +} diff --git a/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/UnityApi.cs b/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/UnityApi.cs index 86b0983e2..22a524d82 100644 --- a/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/UnityApi.cs +++ b/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/UnityApi.cs @@ -47,13 +47,11 @@ public UnityApi(UnityVersion unityVersion, UnityTypeCache unityTypeCache, UnityT myKnownTypesCache = knownTypesCache; } - public bool IsUnityType([NotNullWhen(true)] ITypeElement? type) => type != null && myUnityTypeCache.IsUnityType(type); + public bool IsUnityType([NotNullWhen(true)] ITypeElement? type) => + type != null && myUnityTypeCache.IsUnityType(type); - public bool IsComponentSystemType([NotNullWhen(true)] ITypeElement? typeElement) - { - // This covers ComponentSystem, JobComponentSystem and SystemBase - return typeElement.DerivesFrom(KnownTypes.ComponentSystemBase); - } + public static bool IsDotsSystemType([NotNullWhen(true)] ITypeElement? typeElement) => + typeElement.DerivesFrom(KnownTypes.ComponentSystemBase) || typeElement.DerivesFrom(KnownTypes.ISystem); // A serialised field cannot be abstract or generic, but a type declaration that will be serialised can be. This // method differentiates between a type declaration and a type usage. Consider renaming if we ever need to diff --git a/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/api.xml b/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/api.xml index a40f5aabe..59b0ce668 100644 --- a/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/api.xml +++ b/resharper/resharper-unity/src/Unity/UnityEditorIntegration/Api/api.xml @@ -83,7 +83,7 @@ - + diff --git a/resharper/resharper-unity/src/Unity/annotations/UnityEditor.CoreModule.xml b/resharper/resharper-unity/src/Unity/annotations/UnityEditor.CoreModule.xml index 8afa87e05..64d9b5d15 100644 --- a/resharper/resharper-unity/src/Unity/annotations/UnityEditor.CoreModule.xml +++ b/resharper/resharper-unity/src/Unity/annotations/UnityEditor.CoreModule.xml @@ -95,6 +95,14 @@ + + + + + UnityEditor.Overlays.Overlay + + + @@ -107,4 +115,12 @@ + + + + + + UnityEngine.UIElements.VisualElement + + diff --git a/resharper/resharper-unity/src/Unity/annotations/UnityEditor.xml b/resharper/resharper-unity/src/Unity/annotations/UnityEditor.xml index 5f68fafee..c5e3883bd 100644 --- a/resharper/resharper-unity/src/Unity/annotations/UnityEditor.xml +++ b/resharper/resharper-unity/src/Unity/annotations/UnityEditor.xml @@ -95,6 +95,14 @@ + + + + + UnityEditor.Overlays.Overlay + + + @@ -107,4 +115,12 @@ + + + + + + UnityEngine.UIElements.VisualElement + + diff --git a/resharper/resharper-unity/test/data/Unity.Rider/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs.gold b/resharper/resharper-unity/test/data/Unity.Rider/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs.gold index 5112576d4..e60314e13 100644 --- a/resharper/resharper-unity/test/data/Unity.Rider/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs.gold +++ b/resharper/resharper-unity/test/data/Unity.Rider/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs.gold @@ -120,7 +120,7 @@ public class ||AllWrong|(34)|(35) : AssetPostprocessor (26): ReSharper Unity Implicitly Used Identifier: (27): UnityCodeInsights: Event function | Event function | (28): ReSharper Unity Implicitly Used Identifier: -(29): UnityCodeInsights: Scriptable object | Scriptable object | Scriptable Object +(29): UnityCodeInsights: Scriptable object | Scriptable object | Unity scriptable object (30): ReSharper Unity Implicitly Used Identifier: (31): UnityCodeInsights: Script | Script | Unity script (32): ReSharper Unity Implicitly Used Identifier: diff --git a/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/InvalidStaticModifierWarning.cs b/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/InvalidStaticModifierWarning.cs deleted file mode 100644 index fdc88fe24..000000000 --- a/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/InvalidStaticModifierWarning.cs +++ /dev/null @@ -1,43 +0,0 @@ -using UnityEditor; - -public class Class1 -{ - [MenuItem("MyMenu/Log Selected Transform Name")] - static void LogSelectedTransformName() - { - } - - [MenuItem("MyMenu/Log Selected Transform Name", true)] - static bool ValidateLogSelectedTransformName() - { - return Selection.activeTransform != null; - } -} - -public class Class2 -{ - [MenuItem("MyMenu/Log Selected Transform Name")] - void LogSelectedTransformName() - { - } - - [MenuItem("MyMenu/Log Selected Transform Name", true)] - bool ValidateLogSelectedTransformName() - { - return Selection.activeTransform != null; - } -} - -public class Class3 -{ - [MenuItem("MyMenu/Log Selected Transform Name")] - bool LogSelectedTransformName() - { - } - - [MenuItem("MyMenu/Log Selected Transform Name", false)] - bool ValidateLogSelectedTransformName() - { - return Selection.activeTransform != null; - } -} \ No newline at end of file diff --git a/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/InvalidStaticModifierWarning.cs.gold b/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/InvalidStaticModifierWarning.cs.gold deleted file mode 100644 index 60b274a05..000000000 --- a/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/InvalidStaticModifierWarning.cs.gold +++ /dev/null @@ -1,48 +0,0 @@ -using UnityEditor; - -public class Class1 -{ - [MenuItem("MyMenu/Log Selected Transform Name")] - static void LogSelectedTransformName() - { - } - - [MenuItem("MyMenu/Log Selected Transform Name", true)] - static bool ValidateLogSelectedTransformName() - { - return Selection.activeTransform != null; - } -} - -public class Class2 -{ - [MenuItem("MyMenu/Log Selected Transform Name")] - void |LogSelectedTransformName|(0)() - { - } - - [MenuItem("MyMenu/Log Selected Transform Name", true)] - bool |ValidateLogSelectedTransformName|(1)() - { - return Selection.activeTransform != null; - } -} - -public class Class3 -{ - [MenuItem("MyMenu/Log Selected Transform Name")] - bool |LogSelectedTransformName|(2)() - { - } - - [MenuItem("MyMenu/Log Selected Transform Name", false)] - bool |ValidateLogSelectedTransformName|(3)() - { - return Selection.activeTransform != null; - } -} ---------------------------------------------------------- -(0): ReSharper Warning: Missing static modifier -(1): ReSharper Warning: Missing static modifier -(2): ReSharper Warning: Incorrect method signature. Expected 'static void LogSelectedTransformName()' -(3): ReSharper Warning: Incorrect method signature. Expected 'static void ValidateLogSelectedTransformName()' diff --git a/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/MenuItemAttributeSignature.cs b/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/MenuItemAttributeSignature.cs new file mode 100644 index 000000000..6a221d2e2 --- /dev/null +++ b/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/MenuItemAttributeSignature.cs @@ -0,0 +1,88 @@ +using UnityEditor; + +public class ValidSignatures +{ + [MenuItem("MyMenu/Log Selected Transform Name")] + static void LogSelectedTransformName() + { + } + + [MenuItem("MyMenu/Log Selected Transform Name")] + static void OptionalMenuCommandArgument(MenuCommand command) + { + } + + [MenuItem("MyMenu/Log Selected Transform Name", true)] + static bool ValidateLogSelectedTransformName() + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", validate = true)] + static bool ValidateLogSelectedTransformName(MenuCommand command) + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", priority = 100, validate = true)] + static bool ValidateLogSelectedTransformName() + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", priority = 100, validate = true)] + static bool ValidateLogSelectedTransformName(MenuCommand command) + { + return Selection.activeTransform != null; + } +} + +public class MissingStatic +{ + [MenuItem("MyMenu/Log Selected Transform Name")] + void LogSelectedTransformName() + { + } + + [MenuItem("MyMenu/Log Selected Transform Name")] + void LogSelectedTransformName2(MenuCommand command) + { + } + + [MenuItem("MyMenu/Log Selected Transform Name", true)] + bool ValidateLogSelectedTransformName() + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", validate = true)] + bool ValidateLogSelectedTransformName2() + { + return Selection.activeTransform != null; + } +} + +public class IncorrectReturnType +{ + [MenuItem("MyMenu/Log Selected Transform Name")] + bool LogSelectedTransformName() + { + } + + [MenuItem("MyMenu/Log Selected Transform Name")] + bool LogSelectedTransformName2(MenuCommand menuCommand) + { + } + + [MenuItem("MyMenu/Log Selected Transform Name", false)] + bool ValidateLogSelectedTransformName() + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", validate = false)] + bool ValidateLogSelectedTransformName2() + { + return Selection.activeTransform != null; + } +} diff --git a/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/MenuItemAttributeSignature.cs.gold b/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/MenuItemAttributeSignature.cs.gold new file mode 100644 index 000000000..c645943dc --- /dev/null +++ b/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatures/MenuItemAttributeSignature.cs.gold @@ -0,0 +1,98 @@ +using UnityEditor; + +public class ValidSignatures +{ + [MenuItem("MyMenu/Log Selected Transform Name")] + static void LogSelectedTransformName() + { + } + + [MenuItem("MyMenu/Log Selected Transform Name")] + static void OptionalMenuCommandArgument(MenuCommand command) + { + } + + [MenuItem("MyMenu/Log Selected Transform Name", true)] + static bool ValidateLogSelectedTransformName() + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", validate = true)] + static bool ValidateLogSelectedTransformName(MenuCommand command) + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", priority = 100, validate = true)] + static bool ValidateLogSelectedTransformName() + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", priority = 100, validate = true)] + static bool ValidateLogSelectedTransformName(MenuCommand command) + { + return Selection.activeTransform != null; + } +} + +public class MissingStatic +{ + [MenuItem("MyMenu/Log Selected Transform Name")] + void |LogSelectedTransformName|(0)() + { + } + + [MenuItem("MyMenu/Log Selected Transform Name")] + void |LogSelectedTransformName2|(1)(MenuCommand command) + { + } + + [MenuItem("MyMenu/Log Selected Transform Name", true)] + bool |ValidateLogSelectedTransformName|(2)() + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", validate = true)] + bool |ValidateLogSelectedTransformName2|(3)() + { + return Selection.activeTransform != null; + } +} + +public class IncorrectReturnType +{ + [MenuItem("MyMenu/Log Selected Transform Name")] + bool |LogSelectedTransformName|(4)() + { + } + + [MenuItem("MyMenu/Log Selected Transform Name")] + bool |LogSelectedTransformName2|(5)(MenuCommand menuCommand) + { + } + + [MenuItem("MyMenu/Log Selected Transform Name", false)] + bool |ValidateLogSelectedTransformName|(6)() + { + return Selection.activeTransform != null; + } + + [MenuItem("MyMenu/Log Selected Transform Name", validate = false)] + bool |ValidateLogSelectedTransformName2|(7)() + { + return Selection.activeTransform != null; + } +} + +--------------------------------------------------------- +(0): ReSharper Warning: Incorrect method signature +(1): ReSharper Warning: Incorrect method signature +(2): ReSharper Warning: Incorrect method signature +(3): ReSharper Warning: Incorrect method signature +(4): ReSharper Warning: Incorrect method signature +(5): ReSharper Warning: Incorrect method signature +(6): ReSharper Warning: Incorrect method signature +(7): ReSharper Warning: Incorrect method signature diff --git a/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs.gold b/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs.gold index 73da842be..561377807 100644 --- a/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs.gold +++ b/resharper/resharper-unity/test/data/Unity/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs.gold @@ -143,7 +143,7 @@ This callback is used by UnityVS to take over project generation from Unity (26): ReSharper Unity Implicitly Used Identifier: (27): Unity Gutter Icon: Unity event function (28): ReSharper Unity Implicitly Used Identifier: -(29): Unity Gutter Icon: Scriptable Object +(29): Unity Gutter Icon: Unity scriptable object (30): ReSharper Unity Implicitly Used Identifier: (31): Unity Gutter Icon: Unity script (32): ReSharper Unity Implicitly Used Identifier: diff --git a/resharper/resharper-unity/test/src/Unity.Tests/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatureAnalyzerTests.cs b/resharper/resharper-unity/test/src/Unity.Tests/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatureAnalyzerTests.cs index 5fe309081..03e03d065 100644 --- a/resharper/resharper-unity/test/src/Unity.Tests/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatureAnalyzerTests.cs +++ b/resharper/resharper-unity/test/src/Unity.Tests/Unity/CSharp/Daemon/Stages/Analysis/AttributedMethodSignatureAnalyzerTests.cs @@ -15,6 +15,6 @@ public class AttributedMethodSignatureAnalyzerTests : CSharpHighlightingTestBase [Test] public void TestDidReloadScriptsSignature() { DoNamedTest2(); } [Test] public void TestPostProcessSceneAttributeSignature() { DoNamedTest2(); } [Test] public void TestPostProcessBuildAttributeSignature() { DoNamedTest2(); } - [Test] public void TestInvalidStaticModifierWarning() { DoNamedTest2(); } + [Test] public void TestMenuItemAttributeSignature() { DoNamedTest2(); } } -} \ No newline at end of file +} diff --git a/tools/apiParser/src/Program.cs b/tools/apiParser/src/Program.cs index 79bedff19..aeacfb83d 100644 --- a/tools/apiParser/src/Program.cs +++ b/tools/apiParser/src/Program.cs @@ -271,6 +271,26 @@ private static void AddUndocumentedApis(UnityApi unityApi, Version apiVersion) eventFunction.AddParameter("content", ApiType.String); type.MergeEventFunction(eventFunction, apiVersion); } + + // OnPostprocessAllAssets got a new parameter in 2021.2. Only the new parameter has an official doc page + // but that page says: + // Note: A version of this callback without the didDomainReload parameter is also available + // (OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)) + if (apiVersion >= new Version(2021, 2)) + { + // This function will match the pre 2021.2 functions and extend it's max applicable version + description = + "This is called after importing of any number of assets is complete (when the Assets progress bar has reached the end)."; + var functions = type.FindEventFunctions("OnPostprocessAllAssets"); + eventFunction = new UnityApiEventFunction("OnPostprocessAllAssets", + true, false, ApiType.Void, apiVersion, description, + "Documentation/en/ScriptReference/AssetPostprocessor.OnPostprocessAllAssets.html"); + eventFunction.AddParameter("importedAssets", ApiType.StringArray); + eventFunction.AddParameter("deletedAssets", ApiType.StringArray); + eventFunction.AddParameter("movedAssets", ApiType.StringArray); + eventFunction.AddParameter("movedFromAssetPaths", ApiType.StringArray); + type.MergeEventFunction(eventFunction, apiVersion); + } } // From AssetModificationProcessorInternal