Async Code Analyzers


We have a reference model for all Appframe365 development objects. When versions are created Appframe365 does best effort to stamp referenced object into stbl_System_ReferenceIdentity and stbl_System_Reference. All current possible object types are hard coded inside sviw_System_ObjectTypes. With the help of system queue it is now possible to perform code analysis when reference identity is created. stbl_System_ReferenceIdentity_ITrig is calling Code.Analyzer.Analyze. Keep in mind that Code analysis will only be performed on development databases. References are not created in staging and production databases.

Creating Analyzer

To author your own analyzer you can create a code module and implement IAnalyzer interface. Empty Implementation below.

using Appframe365.Web.Code;
using Appframe365.Web.Context;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Testing {
    public class ExampleAnalyzer : IAnalyzer {
        
        async Task<IEnumerable<Finding>> IAnalyzer.CollectAsync(ReferenceIdentity id, IConnectionContext ctx, CancellationToken ct) {
            await Task.Factory.StartNew(() => false, ct);
            throw new NotImplementedException();
        }

        bool IAnalyzer.IsFitFor(ReferenceIdentity id) { return id.Type > 100; }
    }
}
3 parameters are available in IAnalyzer.CollectAsync.

ReferenceIdentity

  • Type - directly reflects sviw_System_ObjectTypes.Type
  • Name - name of the object.
  • Version - version of the object.

Reference Identity reflects Appframe365 development object version. All Appframe365 objects have name and version and are of specific type. Implement IAnalyzer.IsFitFor to filter out objects you do not want to analyze.

IConnectionContext

You can use IConnectionContext to perform regular operations from inside of analyzer. You will have to fetch object files you are trying to analyze using this connection context. Keep in mind this is most probably going to be JobsContext.Current. Permissions will differ from regular developer permissions.

CancellationToken

Since analysis is performed asynchronously you can also handle cancellation in case the operation got cancelled in a middle of execution. You can use CancellationToken.IsCancellationRequested to check if operation is cancelled.

Returning Findings

Once fully analyzed implementation should return a list of findings. If no findings were found empty list should be returned. Finding fully describes analysis finding in a source. When persisted it will reside in stbl_System_Finding and stbl_System_ReferenceIdentityFinding. Use Finding constructor to create a finding.

  • type - type as defined in sviw_System_ObjectTypes. Is unique in stbl_System_Finding  together with name.
  • name - short name of the finding. Is unique in stbl_System_Finding  together with type.
  • description - full description of the finding. Including description what to do about it. Resides in stbl_System_Finding.
  • severity - Hint = 1, Info = 2, Warning = 4, Error = 8. Resides in stbl_System_Finding.
  • details - specific finding details like method name, line and column numbers. Resides in stbl_System_ReferenceIdentityFinding.

Existing Implementations

There are 2 analyzers implemented, 1 for IL and 1 for SQL. SQLAnalyzer is implemented directly in Code module. AssemblyILAnalyzer is implemented inside Appframe365.Web.Code but you can easily extend its behavior by implementing ILCollectorSet. Example of ICollectorSet implementation can be found in Code.ConnectionContextILCollectorSet Code module. In case of IL analysis it is extremely useful to have ILSpy by your side. In case of SQL analysis it is very useful to have SQL Script Dom Visualizer.




Related articles

Placeholder "LocalizeWeb2016" failed