Skip to content

Minor bug fix #2334

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

Closed
wants to merge 12 commits into from
Closed
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ Since 2018.1, the version numbers and release cycle match Rider's versions and r
* [Commits](https://github.com/JetBrains/resharper-unity/compare/net221...net222)
* [Milestone](https://github.com/JetBrains/resharper-unity/milestone/53?closed=1)

### Added

- Add inspections to ensure return value of pure `Mathf` methods are used ([#2334](https://github.com/JetBrains/resharper-unity/pull/2334))

### Changed

- Update API information to Unity 2022.2.0a17 ([#2334](https://github.com/JetBrains/resharper-unity/pull/2334))
- Remove obsolete warnings for usage of string in a Burst context ([RIDER-77365](https://youtrack.jetbrains.com/issue/RIDER-77365), [RIDER-75815](https://youtrack.jetbrains.com/issue/RIDER-75815))
- Rider: Profiling Unity no longer requires restarting the editor. Profiler can detach, too
- Rider: Support new toolbar and run configurations widget in Unity projects
Expand All @@ -23,15 +28,19 @@ Since 2018.1, the version numbers and release cycle match Rider's versions and r

### Fixed

- Fix incorrect warning for field targeted `SerializeField` attribute on auto property ([RIDER-77782](https://youtrack.jetbrains.com/issue/RIDER-77782), [#2319](https://github.com/JetBrains/resharper-unity/issues/2319), [#2334](https://github.com/JetBrains/resharper-unity/pull/2334))
- Fix registry packages being added as references to `.asmdef` files ([RIDER-79306](https://youtrack.jetbrains.com/issue/RIDER-79306), [#2334](https://github.com/JetBrains/resharper-unity/pull/2334))
- Fix exception when showing online help for a non-Unity project with Unity references ([DEXP-674432](https://youtrack.jetbrains.com/issue/DEXP-674432))
- Fix exception while searching for asset usages when prefab modification has missing references ([DEXP-661796](https://youtrack.jetbrains.com/issue/DEXP-661796))
- Fix exception while referencing an asset that has been excluded for e.g. being too large ([RIDER-77992](https://youtrack.jetbrains.com/issue/RIDER-77992))
- Fix exception with references to stale `.asmdef` files ([DEXP-672670](https://youtrack.jetbrains.com/issue/DEXP-672670), [#2334](https://github.com/JetBrains/resharper-unity/pull/2334))
- Fix exception if stats are reported multiple times ([DEXP-674807](https://youtrack.jetbrains.com/issue/DEXP-674807))
- Rider: Fix navigation from log view when exception is thrown in static constructor ([RIDER-74936](https://youtrack.jetbrains.com/issue/RIDER-74936), [#2282](https://github.com/JetBrains/resharper-unity/pull/2282))
- Rider: Fix autoscroll button in Unity log view tool window ([RIDER-75609](https://youtrack.jetbrains.com/issue/RIDER-75609))
- Rider: Fix incorrectly adding files to `.csproj` when created inside a hidden folder ([RIDER-74815](https://youtrack.jetbrains.com/issue/RIDER-74815))
- Rider: Fix not showing notification of old Rider package
- Rider: Fix exception when checking for unsaved scenes at commit time without a connection to the Unity editor ([DEXP-672567](https://youtrack.jetbrains.com/issue/DEXP-672567))
- Rider: Fix exception in Commit preferences page when no project loaded ([DEXP-671465](https://youtrack.jetbrains.com/issue/DEXP-671465), [#2334](https://github.com/JetBrains/resharper-unity/pull/2334))
- Rider: Fix unnecessarily reading `EditorInstance.json` when multiple Unity projects are open ([#2329](https://github.com/JetBrains/resharper-unity/pull/2329))


Expand Down
1 change: 1 addition & 0 deletions resharper/resharper-unity.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=asmref/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Autopopup/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Delegator/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=DEXP/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=dlclose/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=dlerror/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=dlopen/@EntryIndexedValue">True</s:Boolean>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public AsmDefNameReferenceProviderFactory(Lifetime lifetime, UnitySolutionTracke

public IReferenceFactory CreateFactory(IPsiSourceFile sourceFile, IFile file, IWordIndex wordIndexForChecks)
{
// Make sure the source file is still valid. It's not clear why it would be invalid, but we get it
// See DEXP-672670
if (!sourceFile.IsValid())
return null;

// The source file might be in the external files module, so we can't look at what project it belongs to
if (!sourceFile.GetSolution().HasUnityReference() && !myUnitySolutionTracker.IsUnityProject.HasTrueValue())
return null;
Expand All @@ -38,4 +43,4 @@ public IReferenceFactory CreateFactory(IPsiSourceFile sourceFile, IFile file, IW

public DataFlow.ISignal<IReferenceProviderFactory> Changed { get; }
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#nullable enable

using System;
using System.Linq;
using JetBrains.ReSharper.Feature.Services.Daemon;
using JetBrains.ReSharper.Plugins.Unity.CSharp.Daemon.Errors;
using JetBrains.ReSharper.Plugins.Unity.UnityEditorIntegration.Api;
Expand Down Expand Up @@ -31,7 +32,10 @@ protected override void Analyze(IAttribute attribute, ElementProblemAnalyzerData
if (!Equals(attributeTypeElement.GetClrName(), KnownTypes.FormerlySerializedAsAttribute))
return;

var fields = attribute.GetFieldsByAttribute();
// Only interested in fields and constants. It might be applied to a property with the field: target, but
// we can't validate that, so we don't look for it
var fields = AttributesOwnerDeclarationNavigator.GetByAttribute(attribute)
.Where(d => d is IFieldDeclaration or IConstantDeclaration).ToList();
if (fields.Count == 0)
{
// The attribute is either on an invalid target (which is already an error), or it's got the field:
Expand All @@ -53,7 +57,7 @@ protected override void Analyze(IAttribute attribute, ElementProblemAnalyzerData
}

var field = fields[0];
if (!Api.IsSerialisedField(field))
if (!Api.IsSerialisedField(field.DeclaredElement as IField))
{
consumer.AddHighlighting(new RedundantFormerlySerializedAsAttributeWarning(attribute));
return;
Expand All @@ -62,7 +66,7 @@ protected override void Analyze(IAttribute attribute, ElementProblemAnalyzerData
var attributeInstance = attribute.GetAttributeInstance();
var nameParameter = attributeInstance.PositionParameter(0);
if (nameParameter.IsConstant && nameParameter.ConstantValue.IsString(out var value) &&
string.Equals(value, field.ShortName, StringComparison.Ordinal))
string.Equals(value, field.DeclaredName, StringComparison.Ordinal))
{
consumer.AddHighlighting(new RedundantFormerlySerializedAsAttributeWarning(attribute));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,16 @@ protected override void Analyze(IAttribute attribute, ElementProblemAnalyzerData
if (!Equals(attributeTypeElement.GetClrName(), KnownTypes.HideInInspectorAttribute))
return;

var fields = attribute.GetFieldsByAttribute();
foreach (var field in fields)
foreach (var declaration in AttributesOwnerDeclarationNavigator.GetByAttribute(attribute))
{
if (!Api.IsSerialisedField(field))
if (declaration.DeclaredElement is IField field && !Api.IsSerialisedField(field)
|| (declaration.DeclaredElement is IProperty property && attribute.Target == AttributeTarget.Field
&& !Api.IsSerialisedAutoProperty(property, attribute)))
{
consumer.AddHighlighting(new RedundantHideInInspectorAttributeWarning(attribute));
return;
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using JetBrains.ReSharper.Feature.Services.Daemon;
#nullable enable

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;
Expand All @@ -23,10 +25,11 @@ protected override void Analyze(IAttribute attribute, ElementProblemAnalyzerData
if (!Equals(attributeTypeElement.GetClrName(), KnownTypes.SerializeField))
return;

var fields = attribute.GetFieldsByAttribute();
foreach (var field in fields)
foreach (var declaration in AttributesOwnerDeclarationNavigator.GetByAttribute(attribute))
{
if (!Api.IsSerialisedField(field))
if (declaration.DeclaredElement is IField field && !Api.IsSerialisedField(field)
|| (declaration.DeclaredElement is IProperty property && attribute.Target == AttributeTarget.Field
&& !Api.IsSerialisedAutoProperty(property, attribute)))
{
consumer.AddHighlighting(new RedundantSerializeFieldAttributeWarning(attribute));
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ public bool SuppressUsageInspectionsOnElement(IDeclaredElement element, out Impl

case IProperty property when IsEventHandler(unityApi, property.Setter) ||
IsImplicitlyUsedInterfaceProperty(property) ||
IsAnimationEvent(solution, property):
IsAnimationEvent(solution, property) ||
unityApi.IsSerialisedAutoProperty(property):
flags = ImplicitUseKindFlags.Assign;
return true;
}
Expand Down Expand Up @@ -212,4 +213,4 @@ private static bool IsRequiredSignatureMethod(IMethod method)
return false;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Application.Progress;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.Bulbs;
using JetBrains.ReSharper.Feature.Services.Intentions;
using JetBrains.ReSharper.Feature.Services.QuickFixes;
using JetBrains.ReSharper.Intentions.Util;
using JetBrains.ReSharper.Plugins.Unity.CSharp.Daemon.Errors;
using JetBrains.ReSharper.Plugins.Unity.CSharp.Daemon.Stages.Analysis;
using JetBrains.ReSharper.Plugins.Unity.CSharp.Feature.Services.ContextActions;
using JetBrains.ReSharper.Plugins.Unity.UnityEditorIntegration.Api;
using JetBrains.ReSharper.Psi;
Expand Down Expand Up @@ -37,15 +35,20 @@ public IEnumerable<IntentionAction> CreateBulbItems()
{
var api = myAttribute.GetSolution().GetComponent<UnityApi>();
var typeDeclaration = myAttribute.GetContainingTypeDeclaration();
var field = myAttribute.GetFieldsByAttribute().FirstOrDefault();
var declaration = AttributesOwnerDeclarationNavigator.GetByAttribute(myAttribute)
.FirstOrDefault(d =>
// We ignore constants - if we marked the type as serialisable, the constant declaration wouldn't
// suddenly become serialisable
d is IFieldDeclaration { IsStatic: false, IsReadonly: false } ||
(d is IPropertyDeclaration { IsAuto: true, IsStatic: false, IsReadonly: false } &&
myAttribute.Target == AttributeTarget.Field));

if (field == null)
if (declaration == null)
return EmptyList<IntentionAction>.Enumerable;

if (ValidUtils.Valid(typeDeclaration)
&& typeDeclaration.DeclaredName != SharedImplUtil.MISSING_DECLARATION_NAME
&& !api.IsUnityType(typeDeclaration.DeclaredElement)
&& CouldBeSerializedField(field))
&& !api.IsUnityType(typeDeclaration.DeclaredElement))
{
return new MakeSerializable(typeDeclaration).ToQuickFixIntentions();
}
Expand All @@ -55,11 +58,6 @@ public IEnumerable<IntentionAction> CreateBulbItems()

public bool IsAvailable(IUserDataHolder cache) => ValidUtils.Valid(myAttribute);

private static bool CouldBeSerializedField(IField field)
{
return !field.IsStatic && !field.IsConstant && !field.IsReadonly;
}

private class MakeSerializable : BulbActionBase
{
private readonly ICSharpTypeDeclaration myTypeDeclaration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
using JetBrains.ReSharper.Plugins.Unity.CSharp.Caches;
using JetBrains.ReSharper.Plugins.Unity.Utils;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.CSharp.Util;
using JetBrains.ReSharper.Psi.Modules;
using JetBrains.ReSharper.Psi.Resolve;
using JetBrains.ReSharper.Psi.Util;

namespace JetBrains.ReSharper.Plugins.Unity.UnityEditorIntegration.Api
Expand Down Expand Up @@ -183,6 +185,43 @@ private bool IsSerialisedFieldContainerType([NotNullWhen(true)] IType? type, IPr
return false;
}

// An auto property can have [field: SerializeField] which makes the backing field a seralised field, albeit
// with a weird name. The auto property must be writable, or the backing field is generated as readonly, which
// isn't serialisable (so not true for getter only or init setter only properties)
public bool IsSerialisedAutoProperty(IProperty? property)
{
if (property is not { IsAuto: true, IsWritable: true }) return false;

foreach (var declaration in property.GetDeclarations())
{
var propertyDeclaration = (IPropertyDeclaration)declaration;
foreach (var attribute in propertyDeclaration.AttributesEnumerable)
{
if (IsSerialisedAutoProperty(property, attribute))
return true;
}
}

return false;
}

public bool IsSerialisedAutoProperty(IProperty? property, IAttribute attribute)
{
if (property is not { IsAuto: true, IsWritable: true, IsStatic: false }
|| attribute.Target != AttributeTarget.Field || attribute.Name == null)
{
return false;
}

var result = attribute.Name.Reference.Resolve();
if (result.ResolveErrorType == ResolveErrorType.OK && result.DeclaredElement is ITypeElement typeElement)
{
return Equals(typeElement.GetClrName(), KnownTypes.SerializeField);
}

return false;
}

// Best effort attempt at preventing false positives for type members that are actually being used inside a
// scene. We don't have enough information to do this by name, so we'll mark all potential event handlers as
// implicitly used by Unity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--This file is auto-generated-->
<api minimumVersion="5.0" maximumVersion="2022.1">
<api minimumVersion="5.0" maximumVersion="2022.2">
<type kind="class" name="AssetModificationProcessor" ns="UnityEditor" path="Documentation/en/ScriptReference/AssetModificationProcessor.html">
<message name="CanOpenForEdit" static="True" minimumVersion="2020.2" description="This is called by Unity when inspecting assets to determine if they can potentially be opened for editing." path="Documentation/en/ScriptReference/AssetModificationProcessor.CanOpenForEdit.html">
<parameters>
Expand Down Expand Up @@ -144,7 +144,7 @@
</parameters>
<returns type="System.Void" array="False" />
</message>
<message name="OnPostprocessMaterial" static="False" minimumVersion="2017.3" description="Add this function to a subclass to get a notification when a Material asset has completed importing." path="Documentation/en/ScriptReference/AssetPostprocessor.OnPostprocessMaterial.html">
<message name="OnPostprocessMaterial" static="False" minimumVersion="2017.3" description="Add this function to a subclass to get a notification when a new Material is created during an import of a ModelImporter." path="Documentation/en/ScriptReference/AssetPostprocessor.OnPostprocessMaterial.html">
<parameters>
<parameter type="UnityEngine.Material" array="False" name="material" />
</parameters>
Expand Down Expand Up @@ -224,7 +224,7 @@
</parameters>
<returns type="System.Void" array="False" />
</message>
<message name="OnPreprocessMaterialDescription" static="False" minimumVersion="2019.3" description="Add this function to a subclass to recieve a notification when a material is imported from a Model Importer." path="Documentation/en/ScriptReference/AssetPostprocessor.OnPreprocessMaterialDescription.html">
<message name="OnPreprocessMaterialDescription" static="False" minimumVersion="2019.3" description="Add this function to a subclass to recieve a notification when a new material is created during the import of a ModelImporter." path="Documentation/en/ScriptReference/AssetPostprocessor.OnPreprocessMaterialDescription.html">
<parameters>
<parameter type="UnityEditor.AssetImporters.MaterialDescription" array="False" name="description" description="MaterialDescription structure describing the imported material properties and animations." />
<parameter type="UnityEngine.Material" array="False" name="material" description="The material generated by the Model Importer." />
Expand Down
Loading