integrated-application-development / sonar-delphi

Delphi language plugin for SonarQube
GNU Lesser General Public License v3.0
104 stars 16 forks source link

Error in symbol table construction for files without the `program` header #227

Closed zaneduffield closed 5 months ago

zaneduffield commented 6 months ago

Prerequisites

SonarDelphi version

1.4.0

SonarQube version

No response

Issue description

The program <name> header isn't technically necessary in a Delphi program file. The compiler will happily accept

begin
end.

but scanning with sonar-delphi gives the following error

java.lang.ClassCastException: class au.com.integradev.delphi.antlr.ast.node.CommonDelphiNodeImpl cannot be cast to class org.sonar.plugins.communitydelphi.api.ast.FileHeaderNode (au.com.integradev.delphi.antlr.ast.node.CommonDelphiNodeImpl and org.sonar.plugins.communitydelphi.api.ast.FileHeaderNode are in unnamed module of loader org.sonar.classloader.ClassRealm @3549bca9)
    at au.com.integradev.delphi.antlr.ast.DelphiAstImpl.getFileHeader(DelphiAstImpl.java:96)
    at au.com.integradev.delphi.antlr.ast.visitors.SymbolTableVisitor$1.visit(SymbolTableVisitor.java:246)
    at au.com.integradev.delphi.symbol.SymbolTableBuilder.runSymbolTableVisitor(SymbolTableBuilder.java:315)
    at au.com.integradev.delphi.symbol.SymbolTableBuilder.process(SymbolTableBuilder.java:287)
    at au.com.integradev.delphi.symbol.SymbolTableBuilder.indexUnit(SymbolTableBuilder.java:396)
    at au.com.integradev.delphi.symbol.SymbolTableBuilder.build(SymbolTableBuilder.java:477)
    at au.com.integradev.delphi.DelphiSensor.executeOnFiles(DelphiSensor.java:119)
    at au.com.integradev.delphi.DelphiSensor.execute(DelphiSensor.java:83)
    at org.sonarsource.sonarlint.core.analysis.container.analysis.sensor.SensorsExecutor.executeSensor(SensorsExecutor.java:75)
    at org.sonarsource.sonarlint.core.analysis.container.analysis.sensor.SensorsExecutor.execute(SensorsExecutor.java:66)
    at org.sonarsource.sonarlint.core.analysis.container.analysis.AnalysisContainer.doAfterStart(AnalysisContainer.java:122)
    at org.sonarsource.sonarlint.core.plugin.commons.container.SpringComponentContainer.startComponents(SpringComponentContainer.java:182)
    at org.sonarsource.sonarlint.core.plugin.commons.container.SpringComponentContainer.execute(SpringComponentContainer.java:161)
    at org.sonarsource.sonarlint.core.analysis.container.module.ModuleContainer.analyze(ModuleContainer.java:71)
    at au.com.integradev.delphilint.analysis.AnalysisOrchestrator.runAnalysis(AnalysisOrchestrator.java:147)
    at au.com.integradev.delphilint.server.AnalysisServer.analyze(AnalysisServer.java:115)
    at au.com.integradev.delphilint.server.TlvConnection.processRequest(TlvConnection.java:171)
    at au.com.integradev.delphilint.server.TlvConnection.readStream(TlvConnection.java:158)
    at au.com.integradev.delphilint.server.TlvConnection.run(TlvConnection.java:70)
    at au.com.integradev.delphilint.App.main(App.java:70)

It seems that the symbol table construction code is assuming what kind of node the AST starts with.

Steps to reproduce

Analyse the following code with sonar-delphi

begin
end.

Minimal Delphi code exhibiting the issue

No response

Cirras commented 6 months ago

As you noted - technically allowed by the parser, but the symbol table construction makes unsafe assumptions about the presence of the file header.

Let's fix it. 👍