StefanMaron / BusinessCentral.LinterCop

Community driven code linter for AL (MS Dynamics 365 Business Central)
https://stefanmaron.com
MIT License
77 stars 31 forks source link

Rule0052InternalProceduresNotReferencedAnalyzer #517

Closed fvet closed 7 months ago

fvet commented 9 months ago

When opening most of our project, I get a failure with below message (making our pipelines failing as well)

Analyzer 'BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer' threw an exception of type 'System.NullReferenceException' with message 'System.NullReferenceException: Object reference not set to an instance of an object.
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.MethodSymbolAnalyzer.<>c__DisplayClass7_0.<AnalyzeObjectSyntax>b__0(SyntaxNode syntaxNode)
   at Microsoft.Dynamics.Nav.CodeAnalysis.SyntaxNode.WalkDescendantsAndPerformAction(Action`1 action, Func`2 descendIntoChildren) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\Syntax\SyntaxNode.cs:line 1482
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.MethodSymbolAnalyzer.AnalyzeObjectSyntax(CompilationAnalysisContext compilationAnalysisContext)
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.CheckApplicationObjects(CompilationAnalysisContext compilationAnalysisContext)
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.AnalyzerExecutor.<>c__DisplayClass48_1.<ExecuteCompilationActionsCore>b__0() in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 618
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock(DiagnosticAnalyzer analyzer, Action analyze, Nullable`1 info) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 1102'
Arthurvdv commented 9 months ago

@rvanbekkum I could use your help here. I've try'ed to walk though the code with this error message, but not sure what is causing this.

.Identifier.ValueText?.ToLowerInvariant()

https://github.com/StefanMaron/BusinessCentral.LinterCop/blob/4f622a1727d6c4963ff332901fbc4541c28a989f/Design/Rule0052and0053InternalProceduresNotReferenced.cs#L128

A guess here, that the ValueText is possible null here. It would be great if you could help set a Try/Catch and raising a LC0000 Diagnostic to identify the AL object that's causes this error.

making our pipelines failing as well

@fvet Is it an deliberate choice to run the Pre-release version instead of the Latest (stable) version of the LinterCop in your pipelines? See https://github.com/StefanMaron/BusinessCentral.LinterCop/issues/500 for more details about this.

fvet commented 9 months ago

@Arthurvdv It's not a deliberate choice to use pre-releases... I was about to ask if I could indeed use the stable releases only in pipelines.

Here's the script we use

[CmdletBinding()]
param (
    [string]$AgentBuildDirectory,
    [string]$BuildSourcesDirectory,
    [ValidateScript({ ($_ -as [System.URI]).AbsoluteURI -ne $null })]
    [string]$GitHubUri = 'https://raw.githubusercontent.com/StefanMaron/vsc-lintercop/master/DownloadFile.ps1'
)

if ([string]::IsNullOrEmpty($AgentBuildDirectory)) { $AgentBuildDirectory = $env:AGENT_BUILDDIRECTORY }
if (-not(Test-Path -Path $AgentBuildDirectory)) { "Invalid value for parameter 'AgentBuildDirectory' or environment variable AGENT_BUILDDIRECTORY is empty" }

if ([string]::IsNullOrEmpty($BuildSourcesDirectory)) { $BuildSourcesDirectory = $env:BUILD_SOURCESDIRECTORY }
if (-not(Test-Path -Path $BuildSourcesDirectory)) { "Invalid value for parameter 'BuildSourcesDirectory' or environment variable BUILD_SOURCESDIRECTORY is empty" }

$FileName = $GitHubUri.Substring($GitHubUri.LastIndexOf("/") + 1)

if ($FileName.IndexOfAny([System.IO.Path]::GetInvalidFileNameChars()) -ne -1) {
    Throw "$FileName contains invalid characters"
}

try {
    Write-Host "Downloading PowerShell script from $GitHubUri..." -ForegroundColor Yellow
    Invoke-WebRequest -Uri $GitHubUri -OutFile $AgentBuildDirectory\$FileName
} 
catch [System.Net.WebException] {
    Throw "Error connecting to $GitHubUri. Please check your the parameters"
}

Write-Host "Success. Now executing $FileName" -ForegroundColor Green
& $AgentBuildDirectory\$FileName $BuildSourcesDirectory $false

Doesn't the $false part exclude the use of the pre-release?

& $AgentBuildDirectory\$FileName $BuildSourcesDirectory $false

rvanbekkum commented 9 months ago

@fvet Do you have an example that reproduces this exception? It has to be a special case because we have already been using this rule for more than a year on all our projects, so I am curious to see when this happens. πŸ™Š

Arthurvdv commented 9 months ago

Doesn't the $false part exclude the use of the pre-release?

Indeed, currently $false isn’t supported (yet) and needs to be false (without the $ sign).

jwikman commented 9 months ago

I got the very same error now, in pre-release of 0.30.13.

I have no more useful information though, since unhandled exceptions seems to be thrown in app.json, with no clue on where the issue was.

Is it time for the old LC0000 rule again? πŸ˜‰

pri-kise commented 8 months ago

I got the very same error now, in pre-release of 0.30.13.

I have no more useful information though, since unhandled exceptions seems to be thrown in app.json, with no clue on where the issue was.

Is it time for the old LC0000 rule again? πŸ˜‰

I got the same exception shown on the app.json file. Don't know what might cause this issue.

warning AD0001: Analyzer 'BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer' threw an exception of type 'System.NullReferenceException' with message 'System.NullReferenceException: Object reference not set to an instance of an object.
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.MethodSymbolAnalyzer.<>c__DisplayClass7_0.<AnalyzeObjectSyntax>b__0(SyntaxNode syntaxNode)
   at Microsoft.Dynamics.Nav.CodeAnalysis.SyntaxNode.WalkDescendantsAndPerformAction(Action`1 action, Func`2 descendIntoChildren) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\Syntax\SyntaxNode.cs:line 1482
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.MethodSymbolAnalyzer.AnalyzeObjectSyntax(CompilationAnalysisContext compilationAnalysisContext)
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.CheckApplicationObjects(CompilationAnalysisContext compilationAnalysisContext)
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.AnalyzerExecutor.<>c__DisplayClass48_1.<ExecuteCompilationActionsCore>b__0() in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 618
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock(DiagnosticAnalyzer analyzer, Action analyze, Nullable`1 info) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 1079'
fvet commented 8 months ago

@fvet Do you have an example that reproduces this exception? It has to be a special case because we have already been using this rule for more than a year on all our projects, so I am curious to see when this happens. πŸ™Š

It's a 600+ files project, so hard to isolate. If by any chance, we could get the file / object in the error log, I would be able to search more in detail...

rvanbekkum commented 8 months ago

See https://github.com/StefanMaron/BusinessCentral.LinterCop/issues/520 for an example that reproduces the issue

rvanbekkum commented 8 months ago

I think it might be a difference in how the DLL is built by the LinterCop build pipeline. Will check later on.

Arthurvdv commented 8 months ago

@rvanbekkum, I'm seeing the same differences.

This is a strange one for me. I've try'ed with the dotnet build --no-restore --configuration Release on my local machine, where I can't get a repo on this. Switching over the to the artifact generated by the github runner then indeed the error occurs.

Do you have any idea what could cause this?

rvanbekkum commented 8 months ago

I don't have an idea yet, but I have not extensively investigated the GitHub runner build pipeline yet. There will probably be something that makes the difference. In our company's Azure DevOps organisation we have a build pipeline for a codecop and the artifact that is produced from that pipeline has always worked fine, so I have another reference to compare it with. ;)

Arthurvdv commented 8 months ago

Could it be you're using an other .NET SDK version then 7.0.405 ?

I was still running with 6.0.418 on my machine, but unfortunately switching to 7.0.405 I couldn't create a repo on this when I build the artifact local.

rvanbekkum commented 8 months ago

The target framework of the BusinessCentral.LinterCop project is .NET Standard 2.1 Locally I am using .NET SDK 8.0.101. If I build the project locally and then copy the .dll file to my bin/Analyzers folder, then everything works perfectly fine. It looks like it is somewhere a problem with how the GitHub build pipeline builds the BusinessCentral.LinterCop project. I am not directly sure how to solve that; maybe using a newer SDK could solve the issue, but I would not expect so πŸ˜…

Arthurvdv commented 8 months ago

Updating the GitHub build pipeline to .NET SDK 8.0.101 doesn't resolve this, but the setup of the codeAnalyzers seems to be the issue here.

Error

  "al.codeAnalyzers": [
    "${PerTenantExtensionCop}",
    "${analyzerfolder}BusinessCentral.LinterCop.dll"

No error

  "al.codeAnalyzers": [
    "${AppSourceCop}",
    "${analyzerfolder}BusinessCentral.LinterCop.dll"

It seems you referencing an method that's encapsulated in the AppSourceCop.dll it seems?

rvanbekkum commented 8 months ago

I have checked with this setup (PerTenant + LinterCop VS AppSourceCop + LinterCop), but neither does result into an exception for me. (I'm sorry, that doesn't help finding the source of the issue ... πŸ˜… but thought it might be good to share anyways).

It seems you referencing an method that's encapsulated in the AppSourceCop.dll it seems?

What do you mean with this exactly?

Arthurvdv commented 8 months ago
"al.codeAnalyzers": [
  "${analyzerfolder}BusinessCentral.LinterCop.dll"
]

image

I'm not sure of this is the root cause, but depending on the setup of the al.codeAnalyzers in the settings.json file, the Microsoft.Dynamics.Nav.Analyzers.Common.dll assembly is loaded/accessible or not. For example, only setting the LinterCop could throw an error like this above.

β€”β€”β€”β€”-

<Reference Include="Microsoft.Dynamics.Nav.Analyzers.Common">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>ALLanguage/extension/bin/Analyzers/Microsoft.Dynamics.Nav.Analyzers.Common.dll</HintPath>
    <Private>False</Private>
</Reference>

https://github.com/StefanMaron/BusinessCentral.LinterCop/blob/fe8dc2c844176f87d5eb04f0e4ef99182c956218/BusinessCentral.LinterCop.csproj#L21C1-L25C21

Does the LinterCop maybe missing something in the csproj-file? πŸ€”

@fvet Could you share the al.codeAnalyzers setup you're using?

rvanbekkum commented 8 months ago

This is also an issue with rule LC0033. See https://github.com/StefanMaron/BusinessCentral.LinterCop/issues/529#issuecomment-1929009835

fvet commented 8 months ago

@fvet Could you share the al.codeAnalyzers setup you're using?

Here's the one I'm using in all our projects

"al.codeAnalyzers": [
        "${CodeCop}",
        "${UICop}",
        "${AppSourceCop}",
        "${analyzerFolder}BusinessCentral.LinterCop.dll"
    ],
Arthurvdv commented 8 months ago

You have the CodeCop and AppSourceCop also defined, which should take care the libraries are loaded.

@fvet are you still experiencing this issue or did https://github.com/StefanMaron/BusinessCentral.LinterCop/pull/535 resolve also this?

fvet commented 8 months ago

@Arthurvdv Still facing the Rule0052InternalProceduresNotReferencedAnalyzer error (with "linterCop.load-pre-releases": true, and AL extension v12.6.936426)

Analyzer 'BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer' threw an exception of type 'System.NullReferenceException' with message 'System.NullReferenceException: Object reference not set to an instance of an object.
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.MethodSymbolAnalyzer.<>c__DisplayClass7_0.<AnalyzeObjectSyntax>b__0(SyntaxNode syntaxNode)
   at Microsoft.Dynamics.Nav.CodeAnalysis.SyntaxNode.WalkDescendantsAndPerformAction(Action`1 action, Func`2 descendIntoChildren) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\Syntax\SyntaxNode.cs:line 1482
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.MethodSymbolAnalyzer.AnalyzeObjectSyntax(CompilationAnalysisContext compilationAnalysisContext)
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.CheckApplicationObjects(CompilationAnalysisContext compilationAnalysisContext)
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.AnalyzerExecutor.<>c__DisplayClass48_1.<ExecuteCompilationActionsCore>b__0() in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 618
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock(DiagnosticAnalyzer analyzer, Action analyze, Nullable`1 info) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 1102'

For my reference only: occurs in our app Rental And Consumption

Arthurvdv commented 7 months ago

It took me some more time then I expected to add an Try/Catch on this rule to generate a LC0000.

I've updated the pre-release v0.30.14 version of the LinterCop.

Can you try again to see if this generates an LC0000 diagnostic?

fvet commented 7 months ago

C:\Users\xxx.vscode\extensions\ms-dynamics-smb.al-12.6.936426\bin\Analyzers

image

"linterCop.load-pre-releases": true,

Reported diagnostic with ID 'LC0000' is not supported by the analyzer (Parameter 'diagnostic')

Analyzer 'BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer' threw an exception of type 'System.ArgumentException' with message 'System.ArgumentException: Reported diagnostic with ID 'LC0000' is not supported by the analyzer (Parameter 'diagnostic')
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.DiagnosticAnalysisContextHelpers.VerifyArguments(Diagnostic diagnostic, Func`2 isSupportedDiagnostic) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\DiagnosticAnalysisContextHelpers.cs:line 46
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.CompilationAnalysisContext.ReportDiagnostic(Diagnostic diagnostic) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalysisContext.cs:line 350
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.MethodSymbolAnalyzer.<>c__DisplayClass7_1.<AnalyzeObjectSyntax>b__0(SyntaxNode syntaxNode)
   at Microsoft.Dynamics.Nav.CodeAnalysis.SyntaxNode.WalkDescendantsAndPerformAction(Action`1 action, Func`2 descendIntoChildren) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\Syntax\SyntaxNode.cs:line 1482
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.MethodSymbolAnalyzer.AnalyzeObjectSyntax(CompilationAnalysisContext compilationAnalysisContext)
   at BusinessCentral.LinterCop.Design.Rule0052InternalProceduresNotReferencedAnalyzer.CheckApplicationObjects(CompilationAnalysisContext compilationAnalysisContext)
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.AnalyzerExecutor.<>c__DisplayClass48_1.<ExecuteCompilationActionsCore>b__0() in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 618
   at Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock(DiagnosticAnalyzer analyzer, Action analyze, Nullable`1 info) in D:\a\_work\1\s\source\Prod\Microsoft.Dynamics.Nav.CodeAnalysis\DiagnosticAnalyzer\AnalyzerExecutor.cs:line 1102'
Arthurvdv commented 7 months ago

image

I see now I didn't correctly initialized the diagnostic descriptor 😳

I've updated the pre-release v0.30.14 version of the LinterCop again and with some luck you now should get an LC0000 diagnostic?

Arthurvdv commented 7 months ago

https://github.com/StefanMaron/BusinessCentral.LinterCop/issues/559 by @fvet

There was an Error in Rule \"Rule0052\" of type \"Exception\" at Line 140 Scenario is a report with a requestpage containing a listpart with an internal function. The internal function is referenced via RequestOptionsPage.controlname.Page.functionname.

image

Arthurvdv commented 7 months ago

@fvet, thank you for taking the time to provide this feedback!

This was a great help to find the issue, which is now resolved in the in the (pre)release version of v0.30.15 of the LinterCop.


@rvanbekkum FYI (not sure if you want to also update your internal Code Analyzer on this?)

I needed to change this, because the GetContainingObjectSyntax returns the requestpage as object, where the GetContainingApplicationObjectSyntax return the page object.

https://github.com/StefanMaron/BusinessCentral.LinterCop/blob/1af3ee958f397f814ed5295b1d2fe8edac87e824/Design/Rule0052and0053InternalProceduresNotReferenced.cs#L152

fvet commented 7 months ago

@Arthurvdv I can confirm the error is fixed. Thanks a lot for your continued effort on this extension!

rvanbekkum commented 7 months ago

Very nice and thanks for sharing what the issue was and how you solved it. Good learn for the future. πŸ™‚