Skip to content

Commit

Permalink
Add properties support
Browse files Browse the repository at this point in the history
  • Loading branch information
ulrichb committed Aug 28, 2017
1 parent d69aa3e commit 1a02cbf
Show file tree
Hide file tree
Showing 67 changed files with 1,487 additions and 227 deletions.
Binary file modified Doc/OptionsPage.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions History.md
@@ -1,4 +1,5 @@
### vNext ###
- Added support for properties => Implicit Nullability now finally supports all members where ReSharper provides nullability analysis :)
- ReSharper 2017.2 support

### 3.7.0 ###
Expand Down
6 changes: 0 additions & 6 deletions ImplicitNullability.sln.DotSettings
Expand Up @@ -10,12 +10,6 @@
<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File8180D39E8F16764B90221B1534307E85/@KeyIndexDefined">True</s:Boolean>
<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=File8180D39E8F16764B90221B1534307E85/RelativePriority/@EntryValue">1</s:Double>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertClosureToMethodGroup/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=1A1F3D486A9E2841BB2DB59EF8FE603B/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=1A1F3D486A9E2841BB2DB59EF8FE603B/Color/@EntryValue">255, 128, 0</s:String>
<s:Boolean x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=1A1F3D486A9E2841BB2DB59EF8FE603B/MatchComments/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=1A1F3D486A9E2841BB2DB59EF8FE603B/Name/@EntryValue">Property Support</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=1A1F3D486A9E2841BB2DB59EF8FE603B/Pattern/@EntryValue">(?&lt;=\W|^)(?&lt;TAG&gt;PROP_SUPPORT)(\W|$)(.*)</s:String>
<s:String x:Key="/Default/PatternsAndTemplates/Todo/TodoPatterns/=1A1F3D486A9E2841BB2DB59EF8FE603B/TodoIconStyle/@EntryValue">Normal</s:String>
<s:Boolean x:Key="/Default/RunConfigs/Config/=2ABAA791BC405F448A48723281A097EE/@KeyIndexDefined">True</s:Boolean>
<s:String x:Key="/Default/RunConfigs/Config/=2ABAA791BC405F448A48723281A097EE/DefaultAction/@EntryValue">run</s:String>
<s:String x:Key="/Default/RunConfigs/Config/=2ABAA791BC405F448A48723281A097EE/Exe/Arguments/@EntryValue">/c "powershell -ExecutionPolicy Bypass -File Build\Build.ps1 -Configuration Release &amp; PAUSE"</s:String>
Expand Down
6 changes: 3 additions & 3 deletions README.md
Expand Up @@ -84,14 +84,13 @@ Another goal of this extension is to bring ReSharper's static analysis in sync w

### Differences to ReSharper's "Implicit [NotNull] Value Analysis Mode"

Since version 2016.1 ReSharper supports a comparable feature (see *Code Inspection | Settings*) with the following differences.
Since version 2016.1 ReSharper supports (in the "internal mode") a comparable feature (see *Code Inspection | Settings*) with the following differences.

_Implicit Nullability_ ...
* ... rules can be enabled / disabled for _specific_ code elements like parameters or (readonly) fields.
* ... supports (project specific) [configuration by code](#code-configuration).
* ... adds additional [warnings](#code-inspection-warnings).
* ... adds [type highlighting](#type-highlighting) for explicit or implicit `[NotNull]` elements.
* ... does not support properties at the moment.

## Type highlighting

Expand All @@ -112,8 +111,9 @@ _Implicit Nullability_ can also be configured by code using an [`AssemblyMetadat
Example:
```C#
[assembly: AssemblyMetadata("ImplicitNullability.AppliesTo",
"InputParameters, RefParameters, OutParametersAndResult, Fields")]
"InputParameters, RefParameters, OutParametersAndResult, Fields, Properties")]
[assembly: AssemblyMetadata("ImplicitNullability.Fields", "RestrictToReadonly")]
[assembly: AssemblyMetadata("ImplicitNullability.Properties", "RestrictToGetterOnly")]
[assembly: AssemblyMetadata("ImplicitNullability.GeneratedCode", "Exclude")]
```

Expand Down
Expand Up @@ -14,6 +14,9 @@ public static class ImplicitNullabilitySettingsExtensions
bool enableFields = false,
bool fieldsRestrictToReadonly = false,
bool fieldsRestrictToReferenceTypes = false,
bool enableProperties = false,
bool propertiesRestrictToGetterOnly = false,
bool propertiesRestrictToReferenceTypes = false,
GeneratedCodeOptions generatedCode = GeneratedCodeOptions.Exclude)
{
// Fixate default values:
Expand All @@ -24,6 +27,9 @@ public static class ImplicitNullabilitySettingsExtensions
Assert.That(settingsStore.GetValue((ImplicitNullabilitySettings s) => s.EnableFields), Is.True);
Assert.That(settingsStore.GetValue((ImplicitNullabilitySettings s) => s.FieldsRestrictToReadonly), Is.True);
Assert.That(settingsStore.GetValue((ImplicitNullabilitySettings s) => s.FieldsRestrictToReferenceTypes), Is.False);
Assert.That(settingsStore.GetValue((ImplicitNullabilitySettings s) => s.EnableProperties), Is.True);
Assert.That(settingsStore.GetValue((ImplicitNullabilitySettings s) => s.PropertiesRestrictToGetterOnly), Is.True);
Assert.That(settingsStore.GetValue((ImplicitNullabilitySettings s) => s.PropertiesRestrictToReferenceTypes), Is.False);
Assert.That(settingsStore.GetValue((ImplicitNullabilitySettings s) => s.GeneratedCode), Is.EqualTo(GeneratedCodeOptions.Exclude));

settingsStore.SetValue((ImplicitNullabilitySettings s) => s.Enabled, true);
Expand All @@ -33,6 +39,9 @@ public static class ImplicitNullabilitySettingsExtensions
settingsStore.SetValue((ImplicitNullabilitySettings s) => s.EnableFields, enableFields);
settingsStore.SetValue((ImplicitNullabilitySettings s) => s.FieldsRestrictToReadonly, fieldsRestrictToReadonly);
settingsStore.SetValue((ImplicitNullabilitySettings s) => s.FieldsRestrictToReferenceTypes, fieldsRestrictToReferenceTypes);
settingsStore.SetValue((ImplicitNullabilitySettings s) => s.EnableProperties, enableProperties);
settingsStore.SetValue((ImplicitNullabilitySettings s) => s.PropertiesRestrictToGetterOnly, propertiesRestrictToGetterOnly);
settingsStore.SetValue((ImplicitNullabilitySettings s) => s.PropertiesRestrictToReferenceTypes, propertiesRestrictToReferenceTypes);
settingsStore.SetValue((ImplicitNullabilitySettings s) => s.GeneratedCode, generatedCode);
}

Expand All @@ -46,6 +55,7 @@ public static class ImplicitNullabilitySettingsExtensions
enableRefParameters: true,
enableOutParametersAndResult: true,
enableFields: true,
enableProperties: true,
generatedCode: generatedCode);
}
}
Expand Down
Expand Up @@ -93,6 +93,34 @@ public void WithEnabledFieldsAndRestrictToReferenceTypes()
definedExpectedWarningSymbols: new[] { "Flds", "RtRT" });
}

[Test]
public void WithEnabledProperties()
{
Test(changeSettings: x => x.EnableImplicitNullability(enableProperties: true),
definedExpectedWarningSymbols: new[] { "Prps" },
//
assert: issueFilePaths =>
{
// Fixation of selected files
Assert.That(issueFilePaths, Has.Some.EqualTo("PropertiesSample.cs"));
Assert.That(issueFilePaths, Has.Some.EqualTo("PropertiesSampleTests.cs"));
});
}

[Test]
public void WithEnabledPropertiesAndRestrictToGetterOnly()
{
Test(changeSettings: x => x.EnableImplicitNullability(enableProperties: true, propertiesRestrictToGetterOnly: true),
definedExpectedWarningSymbols: new[] { "Prps", "RtGo" });
}

[Test]
public void WithEnabledPropertiesAndRestrictToReferenceTypes()
{
Test(changeSettings: x => x.EnableImplicitNullability(enableProperties: true, propertiesRestrictToReferenceTypes: true),
definedExpectedWarningSymbols: new[] { "Prps", "RtRT" });
}

[Test]
public void WithoutEnabledImplicitNullabilityOptions()
{
Expand All @@ -105,7 +133,7 @@ public void WithoutEnabledImplicitNullabilityOptions()
public void WithEnabledImplicitNullabilityAndIncludeGeneratedCode()
{
Test(changeSettings: x => x.EnableImplicitNullabilityForAllCodeElements(GeneratedCodeOptions.Include),
definedExpectedWarningSymbols: new[] { "MIn", "MRef", "MOut", "Flds", "InclGenCode" },
definedExpectedWarningSymbols: new[] { "MIn", "MRef", "MOut", "Flds", "Prps", "InclGenCode" },
//
assert: issueFiles =>
{
Expand All @@ -121,8 +149,8 @@ public void WithEnabledImplicitNullabilityUsingAssemblyMetadataAttributeInExtern
{
Test(changeSettings: x => x.EnableImplicitNullability( /* no options*/),
projectFilter: x => x.Name == ExternalCodeConsumerProjectName,
// as configured in ImplicitNullabilityAssemblyMetadata.cs:
definedExpectedWarningSymbols: new[] { "MIn", "MRef", "MOut", "Flds", "RtRo", "RtRT" },
// as configured in ImplicitNullabilityConfigurationAttributes.cs:
definedExpectedWarningSymbols: new[] { "External", "MIn", "MRef", "MOut", "Flds", "Prps", "RtRo", "RtGo", "RtRT" },
//
assert: issueFiles =>
{
Expand Down
Expand Up @@ -15,6 +15,9 @@ public class AssemblyAttributeConfigurationTranslatorTest
private static readonly ImplicitNullabilityFieldOptions AllFieldOptions =
ImplicitNullabilityFieldOptions.RestrictToReadonly | ImplicitNullabilityFieldOptions.RestrictToReferenceTypes;

private static readonly ImplicitNullabilityPropertyOptions AllPropertyOptions =
ImplicitNullabilityPropertyOptions.RestrictToGetterOnly | ImplicitNullabilityPropertyOptions.RestrictToReferenceTypes;

[Test]
public void GenerateAttributeCode_WithNoAppliesTo()
{
Expand All @@ -32,48 +35,52 @@ public void GenerateAttributeCode_WithAllOptionsEnabled()
ImplicitNullabilityAppliesTo.InputParameters |
ImplicitNullabilityAppliesTo.RefParameters |
ImplicitNullabilityAppliesTo.OutParametersAndResult |
ImplicitNullabilityAppliesTo.Fields,
ImplicitNullabilityAppliesTo.Fields |
ImplicitNullabilityAppliesTo.Properties,
AllFieldOptions,
AllPropertyOptions,
GeneratedCodeOptions.Exclude);

var result = AssemblyAttributeConfigurationTranslator.GenerateAttributeCode(configuration);

Assert.That(result, Is.EqualTo(
ExpectedAssemblyMetadataAttribute(
"ImplicitNullability.AppliesTo",
"InputParameters, RefParameters, OutParametersAndResult, Fields") + NewLine +
"InputParameters, RefParameters, OutParametersAndResult, Fields, Properties") + NewLine +
ExpectedAssemblyMetadataAttribute("ImplicitNullability.Fields", "RestrictToReadonly, RestrictToReferenceTypes") + NewLine +
ExpectedAssemblyMetadataAttribute("ImplicitNullability.Properties", "RestrictToGetterOnly, RestrictToReferenceTypes") + NewLine +
ExpectedAssemblyMetadataAttribute("ImplicitNullability.GeneratedCode", "Exclude")));
}

[Test]
public void GenerateAttributeCode_WithFieldOptionsButAppliesToFieldsDisabled()
public void GenerateAttributeCode_WithFieldOrPropertyOptions_ButAppliesToFieldsOrPropertiesDisabled()
{
var configuration = new ImplicitNullabilityConfiguration(
ImplicitNullabilityAppliesTo.InputParameters, AllFieldOptions, GeneratedCodeOptions.Exclude);
ImplicitNullabilityAppliesTo.InputParameters, AllFieldOptions, AllPropertyOptions, GeneratedCodeOptions.Exclude);

var result = AssemblyAttributeConfigurationTranslator.GenerateAttributeCode(configuration);

Assert.That(result, Is.EqualTo(
ExpectedAssemblyMetadataAttribute("ImplicitNullability.AppliesTo", "InputParameters") + NewLine +
ExpectedAssemblyMetadataAttribute("ImplicitNullability.GeneratedCode", "Exclude")),
"'ImplicitNullability.Fields'-attribute should not be rendered");
"'options'-attribute should not be rendered");
}

[Test]
public void GenerateAttributeCode_WithoutFieldOptionsButAppliesToFieldsEnabled()
public void GenerateAttributeCode_WithoutFieldOrPropertyOptions_ButAppliesToFieldsOrPropertiesEnabled()
{
var configuration = new ImplicitNullabilityConfiguration(
ImplicitNullabilityAppliesTo.InputParameters | ImplicitNullabilityAppliesTo.Fields,
ImplicitNullabilityAppliesTo.InputParameters | ImplicitNullabilityAppliesTo.Fields | ImplicitNullabilityAppliesTo.Properties,
ImplicitNullabilityFieldOptions.NoOption,
ImplicitNullabilityPropertyOptions.NoOption,
GeneratedCodeOptions.Exclude);

var result = AssemblyAttributeConfigurationTranslator.GenerateAttributeCode(configuration);

Assert.That(result, Is.EqualTo(
ExpectedAssemblyMetadataAttribute("ImplicitNullability.AppliesTo", "InputParameters, Fields") + NewLine +
ExpectedAssemblyMetadataAttribute("ImplicitNullability.AppliesTo", "InputParameters, Fields, Properties") + NewLine +
ExpectedAssemblyMetadataAttribute("ImplicitNullability.GeneratedCode", "Exclude")),
"'ImplicitNullability.Fields'-attribute should not be rendered");
"'options'-attribute should not be rendered");
}

[Test]
Expand All @@ -82,6 +89,7 @@ public void GenerateAttributeCode_WithIncludeGeneratedCode()
var configuration = new ImplicitNullabilityConfiguration(
ImplicitNullabilityAppliesTo.InputParameters,
ImplicitNullabilityFieldOptions.NoOption,
ImplicitNullabilityPropertyOptions.NoOption,
GeneratedCodeOptions.Include);

var result = AssemblyAttributeConfigurationTranslator.GenerateAttributeCode(configuration);
Expand Down

0 comments on commit 1a02cbf

Please sign in to comment.