fabriciocolombo / sonar-delphi

SonarQube Delphi Plugin
91 stars 46 forks source link

ANTLR "constExpression" parser exception #43

Open panga opened 8 years ago

panga commented 8 years ago

I've found a bug in parser of many classes of my app. It's impossible to continue the analysis with those errors... I've attached the source file and exception stack trace.

Source File: EDevice.pas.zip

Exception: Caused by: org.antlr.runtime.tree.RewriteEmptyStreamException: rule constExpression at org.antlr.runtime.tree.RewriteRuleElementStream._next(RewriteRuleElementStream.java:157) at org.antlr.runtime.tree.RewriteRuleElementStream.nextTree(RewriteRuleElementStream.java:144) at org.sonar.plugins.delphi.antlr.DelphiParser.constDeclaration(DelphiParser.java:3935) at org.sonar.plugins.delphi.antlr.DelphiParser.constSection(DelphiParser.java:3596) at org.sonar.plugins.delphi.antlr.DelphiParser.interfaceDecl(DelphiParser.java:3328) at org.sonar.plugins.delphi.antlr.DelphiParser.unitInterface(DelphiParser.java:1466) at org.sonar.plugins.delphi.antlr.DelphiParser.unit(DelphiParser.java:1222) at org.sonar.plugins.delphi.antlr.DelphiParser.file(DelphiParser.java:411) at org.sonar.plugins.delphi.antlr.ast.DelphiAST.<init>(DelphiAST.java:84) at org.sonar.plugins.delphi.DelphiSensor.analyseSourceFile(DelphiSensor.java:258) at org.sonar.plugins.delphi.DelphiSensor.parseSourceFile(DelphiSensor.java:235) at org.sonar.plugins.delphi.DelphiSensor.parseFiles(DelphiSensor.java:200) at org.sonar.plugins.delphi.DelphiSensor.analyse(DelphiSensor.java:108) at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:58) at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:50) at org.sonar.batch.phases.PhaseExecutor.execute(PhaseExecutor.java:98) at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:185) at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132) at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117) at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:243) at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:238) at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:236) at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:228) at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132) at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117) at org.sonar.batch.task.ScanTask.execute(ScanTask.java:55) at org.sonar.batch.task.TaskContainer.doAfterStart(TaskContainer.java:86) at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:132) at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:117) at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:122) at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:119) at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:79) at org.sonar.runner.batch.IsolatedLauncher.execute(IsolatedLauncher.java:48) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at org.sonar.runner.impl.BatchLauncher$1.delegateExecution(BatchLauncher.java:87)

jbabijczuk commented 8 years ago

You can add project file with compiler directives.

In sonar-project.properties add: sonar.delphi.sources.project=Project.dproj if you don't have .dproj files you can create it manually.

example:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<DCC_Define>DEBUG;MSWINDOWS</DCC_Define>
</Project>

but... you must modify DelphiProjectHelper.java too :( replace method public List getWorkgroupProjects()

public List<DelphiProject> getWorkgroupProjects() {
    List<DelphiProject> list = new ArrayList<DelphiProject>();

    String dprojPath = getProjectFile();
    String gprojPath = getWorkgroupFile();

    // Single workgroup file, containing list of .dproj files
    if (!StringUtils.isEmpty(gprojPath)) {
      try {
        DelphiUtils.LOG.debug(".groupproj file found: " + gprojPath);
        DelphiWorkgroup workGroup = new DelphiWorkgroup(new File(gprojPath));
        for (DelphiProject newProject : workGroup.getProjects()) {
          list.add(newProject);
        }
      } catch (IOException e) {
        DelphiUtils.LOG.error(e.getMessage());
        DelphiUtils.LOG.error("Skipping .groupproj reading, default configuration assumed.");
        DelphiProject newProject = new DelphiProject("Default Project");
        newProject.setIncludeDirectories(getIncludeDirectories());
        newProject.setSourceFiles(mainFiles());
        list.clear();
        list.add(newProject);
      }
    }
    // Single .dproj file
    else if (!StringUtils.isEmpty(dprojPath)) {
      File dprojFile = DelphiUtils.resolveAbsolutePath(fs.baseDir().getAbsolutePath(), dprojPath);
      DelphiUtils.LOG.info(".dproj file found: " + dprojFile);
      DelphiProject newProject = new DelphiProject(dprojFile);
      list.add(newProject);
      // jbabijczuk
      if (newProject.getIncludeDirectories().size() == 0) {
          newProject.setIncludeDirectories(getIncludeDirectories());
      }
      if (newProject.getSourceFiles().size() == 0) {
          newProject.setSourceFiles(mainFiles());
      }
       // end jbabijczuk
    }
    else {
      // No .dproj files, create default project
      DelphiProject newProject = new DelphiProject("Default Project");
      newProject.setIncludeDirectories(getIncludeDirectories());
      newProject.setSourceFiles(mainFiles());
      list.add(newProject);
    }

    return list;
  }
panga commented 8 years ago

Thanks @jbabijczuk !!

But still not working...

It picked the dproj correctly:

16:40:22.991 INFO  - .dproj file found: /trier/apps/jenkins/workspace/Automação LogTec (Sonar)/CapturaECF/CapturaECF.dproj
16:40:22.993 ERROR - no protocol: /trier/apps/jenkins/workspace/Automação LogTec (Sonar)/CapturaECF/CapturaECF.dproj
16:40:22.993 INFO  - No include directories found in project configuration.
jbabijczuk commented 8 years ago

Could you paste stack trace ?

panga commented 8 years ago

@jbabijczuk same stack trace of the issue...

cesarliws commented 8 years ago

Hi @jbabijczuk!

The parser stops in {$IFNDEF FPC} compiler directive in the next block:

procedure TLogTecThreadEnviaLPT.Execute;
var
[...]
begin
  if FsTextoAEnviar <> '' then
  begin
    with TLogTecDevice(FsOwner) do
    begin
      AssignFile(ArqPrn, Porta);
      try
[...]
      finally
{$I-}
        {$IFNDEF FPC} /// <<<--- HERE
        System.CloseFile(ArqPrn);
        {$ENDIF}
{$I+}
      end;
[...]
end;

The sources have some other compiler directives, but is only stopping at this line. After comment with // it works:

        // {$IFNDEF FPC}
        System.CloseFile(ArqPrn);
        // {$ENDIF}

The parser also stops in comments with "{ }", adding a dot to separe "{.$", like this:

{.$IFNDEF FPC}

jbabijczuk commented 8 years ago

I don't have idea what is wrong. I parsered your example code without exception.