Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
dropsonic committed Feb 9, 2023
2 parents 4922768 + 0a7eb02 commit fca07d4
Show file tree
Hide file tree
Showing 139 changed files with 4,299 additions and 2,001 deletions.
71 changes: 70 additions & 1 deletion docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,75 @@
# Acuminator Release Notes
This document provides information about fixes, enhancements, and key features that are available in Acuminator.

## Acuminator 3.1.1
Acuminator 3.1.1 includes the bug fixes and enhancements described in this section, as well as the features that have been implemented in previous versions.

### Enhancements
In Acuminator 3.1.1, the following enhancements have been implemented:
- The [PX1042](diagnostics/PX1042.md) diagnostic has been changed to reflect the changes in Acumatica Platform. Starting with Acumatica ERP 2023 R1, Acumatica runtime has been changed to allow execution of database queries in the `RowSelecting` event handler without a separate connection scope. Therefore, in Acumatica ERP 2023 R1 and later versions, this diagnostic is disabled.
- Localization diagnostics [PX1050](diagnostics/PX1050.md), [PX1051](diagnostics/PX1051.md), and [PX1053](diagnostics/PX1053.md) have been enhanced to support the `PX.Objects.Common.Exceptions.PXExceptionInfo` class. This class represents a data transfer object frequently used in Acumatica code to store data about exceptions. Localization diagnostics will treat this data the same way they treat Acumatica Framework exceptions derived from `PXException` as follows:
- Check that hard-coded strings are not passed as arguments to the `PXExceptionInfo` constructor calls. Only localizable string constants can be passed to the `PXExceptionInfo` constructor.
- Do not report error when the `PXExceptionInfo.MessageFormat` property is passed to APIs checked by Acuminator localization diagnostics, such as `PXException` constructor calls.
- The [PX1016](diagnostics/PX1016.md) diagnostic has been changed to not check for the `IsActive` method in graph extensions that invlude the override of the `Configure` method with the screen configuration and workflows. Information about the `Configure` method has been added to the graph semantic model.
- The [PX1018](diagnostics/PX1018.md) diagnostic has been added to not show a warning about abstract graphs and generic graphs that have a generic type parameter as their primary DAC.

#### Analysis of Data Type Attributes and DAC Field DB Boundness Calculation
The Acuminator analysis of Acumatica data type attributes has been significantly reworked:
- Calculation of relationships between Acumatica attributes has been improved.
- The unbound [PXVariantAttribute](https://help.acumatica.com/(W(98))/Help?ScreenId=ShowWiki&pageid=92f5623d-eebb-e5e7-db17-5aa98633b219) is now supported.

The heuristic calculation of DAC field's relationship with a database (which we call _DB boundness_) has been significantly improved:
- The set of possible DB boundness values has been extended. Previously, Acuminator could calculate only four types of DAC field's DB boundness: _NotDefined_, _Unbound_, _DbBound_, and _Unknown_.<br/>
Now Acuminator displays three more values:
- _PXDBScalar_
- _PXDBCalced_
- _Error_ (for the case when Acuminator can prove that the data type attributes on a DAC field property are declared incorrectly)
These new values are displayed in the Code Map for DACs and DAC extensions. The _Error_ value is displayed in the Code Map as __"Inconsistent"__.
- Support for Acumatica aggregator attributes in the DB boundness calculation has been improved.<br/>
Aggregator attributes are attributes derived from the [PXAggregateAttribute](https://help.acumatica.com/(W(98))/Help?ScreenId=ShowWiki&pageid=9c64f185-b2a4-14ee-eef1-d78c0e05d100) class. They can combine functionality from several attributes:
```C#
[PXDBInt]
[PXUIField(DisplayName = "Customer")]
[PXDefault]
[PXSelector(typeof(Search<BAccountR.bAccountID,
Where<BAccountR.status, Equal<BAccount.status.active>>>))]
public class CustomerActiveAttribute : PXAggregateAttribute { }

public class ARInvoice : IBqlTable
{
[CustomerActive]
public override Int32? CustomerID { get; set; }
}
```
- Calculation of DB boundness has been improved to support hybrid data type attributes with mixed DB boundnesses. Such attributes can be placed on both bound and unbound DAC field properties. They usually have the `IsDBField` (or `NonDB` in case of `PXDBLocalizableStringAttribute`) flag which configures the attribute's DB boundness. The flag may have a default value, also it could be explicitly set on the attribute's declaration on a DAC field property or an aggregator attribute. Acumatica code includes a number of such attributes: `PeriodIDAttribute`, `PXEntityAttribute`, and attributes derived from them. They are supported in the new release.
- The DB boundness calculation now supports combinations of hybrid and aggregator attributes and combines the default DB boundness with the DB boundness explicitly set on attribute's application on a DAC field property or an aggregator attribute.
- The calculated attribute's DB boundness and information about the attribute's data type is now cached in the DAC semantic model and shared between Acuminator DAC analyzers.

The changes in the attribute analysis provided an ability to make significant improvements in the following diagnostics:
- The [PX1095](diagnostics/PX1095.md) diagnostic now supports both `PXDBCalcedAttribute` and `PXDBScalarAttribute` attributes. Any of them, when used on a DAC field property, requires an unbound data type attribute like `PXStringAttribute` placed on the same DAC field property. Previously, the PX1095 diagnostic checked only `PXDBCalcedAttribute` but starting from this release both attributes are checked.
- The precision and performance of the following diagnostics has been improved:
- [PX1019](diagnostics/PX1019.md)
- [PX1020](diagnostics/PX1020.md)
- [PX1021](diagnostics/PX1021.md)
- [PX1023](diagnostics/PX1023.md)
- [PX1030](diagnostics/PX1030.md)
- [PX1095](diagnostics/PX1095.md)

### Fixed Bugs
In this version of Acuminator, the following bugs have been fixed:
- The published version 3.1 of the `Acuminator.Analyzers` nuget package was corrupted and did not work. The nuget package is fixed in this release.
- Graph Semantic Model incorrectly collected actions, action delegates, views, and view delegates for non-generic graph extensions derived from other graph extensions. This led to different possible bugs in static code analysis of graphs and graph extensions. The Code Map also displayed incorrect data.
- The [PX1091](diagnostics/PX1091.md) diagnostic did not report error in a scenarios involving a graph action witn an action delegate and a class hierarchy of graph extensions. In particular, the error was not reported in a scenario with a `Base` and `Derived` graph extensions when the action delegate was re-declared in `Base` and overridden in `Derived`, and the override calls the base action delegate from the graph via extension's `Base` property.
- The false alert in the [PX1091](diagnostics/PX1091.md) diagnostic for a call to the base action delegate method via `base` keyword in the action delegate method C# override.
- The incorrect resolution of C# property and method overrides which resulted in the incorrect collection of data for the graph extension's `Initialize` method in case of several method overrides.
- Minor bugfixes in code analysis and performance optimizations.

### Other Changes
Stability of the Acuminator tests infrastructure has been improved in the following ways:
- Validation of the test initial state has been added
- Error processing for failed tests has been enhanced


## Acuminator 3.1
Acuminator 3.1 includes the bug fixes and enhancements described in this section, as well as the features that have been implemented in previous versions.

Expand Down Expand Up @@ -61,7 +130,7 @@ In this version of Acuminator, the following bugs have been fixed:
- When a diagnostic was suppressed in a global suppression file via a code fix for a project without the Acuminator suppression file, Acuminator incorrectly generated it in Visual Studio 2022. It did not generate the "AdditionalFiles" section in the project file for the generated suppression file.
- The [PX1086](diagnostics/PX1086.md) diagnostic failed on syntax expressions that create collections with the collection initializer when the constructor braces were omitted.
- The process of creating a graph semantic model has been improved. Now runtime errors that occurred in diagnostics of graphs and graph extensions have been fixed.
- The performance of the the [PX1073](diagnostics/PX1073.md) and [PX1074](diagnostics/PX1074.md) diagnostics has been improved. Runtime errors during the analysis of a graph extension were fixed in these diagnostics through the removal of the redundant analysis of events from the base graph.
- The performance of the [PX1073](diagnostics/PX1073.md) and [PX1074](diagnostics/PX1074.md) diagnostics has been improved. Runtime errors during the analysis of a graph extension were fixed in these diagnostics through the removal of the redundant analysis of events from the base graph.
- Minor bugs with inter-procedural analysis of local functions have been fixed.
- Acuminator failed during the analysis of code with a graph that is a generic type parameter that is passed to the `PXGraph.InstanceCreated.AddHandler` method.

Expand Down
10 changes: 5 additions & 5 deletions docs/Summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ Acuminator does not perform static analysis of projects whose names contain `Tes
| [PX1036](diagnostics/PX1036.md) | The DAC must have one primary key which should be named `PK`. The class containing DAC foreign keys should be named `FK`. The single unique key in the DAC should be named `UK`. All unique keys in the DAC should be declared in a public static class named `UK`. | Warning (ISV Level 3: Informational) | Available |
| [PX1037](diagnostics/PX1037.md) | An unbound DAC field cannot be used in a key declaration. | Error (ISV Level 3: Informational) | Unavailable |
| [PX1040](diagnostics/PX1040.md) | Instance constructors in BLC extensions are strictly prohibited. You should use the `Initialize()` method instead. | Error | Available |
| [PX1042](diagnostics/PX1042.md) | In a `RowSelecting` handler, BQL statements and other database queries must be executed only inside a separate connection scope. | Error | Available |
| [PX1042](diagnostics/PX1042.md) | In a `RowSelecting` handler, BQL statements and other database queries must be executed only inside a separate connection scope. In Acumatica ERP 2023 R1 and later versions, this diagnostic is disabled. | Error | Available |
| [PX1043](diagnostics/PX1043.md) | Changes cannot be saved to the database from event handlers. | Error | Unavailable |
| [PX1044](diagnostics/PX1044.md) | Changes to `PXCache` cannot be performed in event handlers. | Error | Unavailable |
| [PX1045](diagnostics/PX1045.md) | `PXGraph` instances cannot be created in event handlers. | Error | Unavailable |
| [PX1046](diagnostics/PX1046.md) | Long-running operations cannot be started within event handlers. | Error | Unavailable |
| [PX1047](diagnostics/PX1047.md) | In the `FieldDefaulting`, `FieldVerifying`, and `RowSelected` event handlers, DAC instances passed to these event handlers cannot be modified. | Error | Unavailable |
| [PX1048](diagnostics/PX1048.md) | For the `RowInserting` and `RowSelecting` events, only the DAC instance that is passed in the event arguments can be modified in the event handler. | Error | Unavailable |
| [PX1049](diagnostics/PX1049.md) | In `RowSelected` event handlers, BQL statements and other database queries should be avoided. | Warning (ISV Level 1: Significant) | Unavailable |
| [PX1050](diagnostics/PX1050.md) | Hardcoded strings cannot be used as parameters for localization methods and `PXException` constructors. | Error | Unavailable |
| [PX1051](diagnostics/PX1051.md) | The strings defined in a class without the `PXLocalizable` attribute cannot be used as parameters for localization methods and `PXException` constructors. | Error | Unavailable |
| [PX1050](diagnostics/PX1050.md) | Hardcoded strings cannot be used as parameters for localization methods, `PXException` and `PXExceptionInfo` constructors. | Error | Unavailable |
| [PX1051](diagnostics/PX1051.md) | The strings defined in a class without the `PXLocalizable` attribute cannot be used as parameters for localization methods, `PXException` and `PXExceptionInfo` constructors. | Error | Unavailable |
| [PX1052](diagnostics/PX1052.md) | Plain text strings cannot be used in the methods of the `LocalizeFormat` family. | Error | Unavailable |
| [PX1053](diagnostics/PX1053.md) | Concatenated strings cannot be used as parameters for localization methods and `PXException` constructors. | Error | Unavailable |
| [PX1053](diagnostics/PX1053.md) | Concatenated strings cannot be used as parameters for localization methods, `PXException` and `PXExceptionInfo` constructors. | Error | Unavailable |
| [PX1054](diagnostics/PX1054.md) | A `PXGraph` instance cannot start a long-running operation during the `PXGraph` initialization. | Error | Unavailable |
| [PX1055](diagnostics/PX1055.md) | An invalid primary key of the DAC is used. | Error | Available |
| [PX1056](diagnostics/PX1056.md) | A PXGraph instance cannot be initialized inside the `IsActive` or `IsActiveForGraph<TGraph>` method. | Error | Unavailable |
Expand Down Expand Up @@ -92,7 +92,7 @@ Acuminator does not perform static analysis of projects whose names contain `Tes
| [PX1092](diagnostics/PX1092.md) | Action handlers must be decorated with the `PXUIField` attribute and with the `PXButton` attribute or its successors. | Error | Available |
| [PX1093](diagnostics/PX1093.md) | In a graph declaration, the first type parameter of `PXGraph` must be the graph type. | Error | Available |
| [PX1094](diagnostics/PX1094.md) | Every DAC should be decorated with the `PXHidden` or `PXCacheName` attribute. | Warning (ISV Level 3: Informational) | Available |
| [PX1095](diagnostics/PX1095.md) | A field with the `PXDBCalced` attribute must have an unbound type attribute, such as `PXDate` or `PXDecimal`. | Error | Unavailable |
| [PX1095](diagnostics/PX1095.md) | A field with the `PXDBCalced` or `PXDBScalar` attribute must have an unbound type attribute, such as `PXDate` or `PXDecimal`. | Error | Unavailable |

## Code Refactoring
Acuminator suggest the following code refactoring:
Expand Down
4 changes: 4 additions & 0 deletions docs/dev/CodingGuidelines/CodingGuidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ Diagnostic and code fix messages should follow the following rules:

### Analyzers

Acuminator analyzers are Roslyn analyzers. Therefore, the following links may be useful:
* Roslyn documentation section: https://github.com/dotnet/roslyn/tree/main/docs/analyzers
* Roslyn documentation on analyzer actions: https://github.com/dotnet/roslyn/blob/main/docs/analyzers/Analyzer%20Actions%20Semantics.md

Overall Acuminator analyzers can be divided into two categories:
* Independent analyzers
* Aggregated analyzers
Expand Down
49 changes: 39 additions & 10 deletions docs/diagnostics/PX1016.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,43 @@ This document describes the PX1016 diagnostic.
## Diagnostic Description
A DAC or a graph extension must include the public static `IsActive` method with no parameters and the `bool` return type. Extensions that are constantly active reduce performance.

To fix the issue, in the `IsActive` method, you should enable the DAC or graph extension depending on a condition. For example, you can enable an extension if the feature for which this extension is needed is enabled.
Graph extensions containing an override of the `Configure` method are considered to be special extensions that are used only to specify the screen configuration and workflow:
```C#
public virtual void Configure(PXScreenConfiguration graph) { }
```
The diagnostic does not check such extensions for the `IsActive` method declaration.

In case you want your extension to be always enabled, you should suppress the diagnostic.
You can use two approaches to fix the issue in the `IsActive` method as described in the following sections.

## Example of Code that Results in the Error
### Suppression Comment
If you want your DAC or graph extension to be always enabled, suppress the diagnostic with the suppression comment:
```C#
// Acuminator disable once PX1016 ExtensionDoesNotDeclareIsActiveMethod extension should be constantly active
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
...
}
```
It is a well-known suppression case, therefore Acuminator will generate a default justification _extension should be constantly active_ for the suppression.
Do not add a trivial `IsActive` method implementation as shown in the following code. Such implementation will take a small performance cost from your application without any benefit.
```C#
public class POOrderEntryExt : PXGraphExtension<POOrderEntry>
{
public static bool IsActive() => true; // Do not add such trivial implementations, suppress PX1016 diagnostic instead
}
```

### IsActive Method Implementation
If your a DAC or graph extension should be enabled depending on a condition, implement the `IsActive` method. For example, you can enable an extension, if the feature for which this extension is needed is enabled, as shown in the following code.
```C#
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
...
public static bool IsActive() => PXAccess.FeatureInstalled<FeaturesSet.retainage>();
}
```

## Example of Code that Results in the Error
```C#
// A diagnostic must be shown on SOOrderEntryExt
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
Expand All @@ -26,22 +57,20 @@ public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
```

## Example of the Fixed Code

If you need an extension to be always enabled, suppress the diagnostic as shown in the following code.
```C#
// Acuminator disable once PX1016 ExtensionDoesNotDeclareIsActiveMethod extension should be constantly active
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
...
public static bool IsActive() { return PXAccess.FeatureInstalled<FeaturesSet.retainage>(); }
}
```

## Example of the Suppression Comment

If extension should be enabled depending on condition, implement the `IsActive` method as shown in the following code.
```C#
// Acuminator disable once PX1016 ExtensionDoesNotDeclareIsActiveMethod
// because this extension should be always enabled
public class SOOrderEntryExt : PXGraphExtension<SOOrderEntry>
{
...
public static bool IsActive() => PXAccess.FeatureInstalled<FeaturesSet.retainage>();
}
```
```
10 changes: 10 additions & 0 deletions docs/diagnostics/PX1018.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ This document describes the PX1018 diagnostic.
## Diagnostic Description
You can specify a DAC as the second type parameter of a graph to implicitly add definitions of standard actions (such as **Cancel** and **Save**) to the graph. The DAC that is specified as the second type parameter must be the same as the primary DAC of the primary data view.

The diagnostic does not check abstract graphs and generic graphs that have generic type parameter as their primary DAC. Such graphs are used as base classes for derived graphs and are not used directly by Acumatica screens. The primary view can be declared in a derived graph. Here is an example of the generic graph with a generic type parameter as a primary DAC:
```C#
public class ServiceContractEntryBase<TGraph, TPrimary> : PXGraph<TGraph, TPrimary>
where TGraph : PX.Data.PXGraph
where TPrimary : class, PX.Data.IBqlTable, new()
{
//...
}
```

To fix the issue, you can use one of the following options:
- In the second type parameter of the graph, specify the primary DAC of the primary data view.
- Change the primary DAC of the primary data view so that it matches the second type parameter of the graph.
Expand Down
Loading

0 comments on commit fca07d4

Please sign in to comment.