SonarQube fails with PHP readonly property promotion

Good day, I have a following example of a code which is scanned by sonarqube:

<?php

declare(strict_types=1);

namespace MyCoolNamespace;

class Domain
{
    public function __construct(readonly private string $prop) {}
}

And the following logs from sonarqube:

Unable to find image 'sonarsource/sonar-scanner-cli:latest' locally
latest: Pulling from sonarsource/sonar-scanner-cli
Digest: sha256:494ecc3b5b1ee1625bd377b3905c4284e4f0cc155cff397805a244dee1c7d575
Status: Downloaded newer image for sonarsource/sonar-scanner-cli:latest
INFO: Scanner configuration file: /opt/sonar-scanner/conf/sonar-scanner.properties
INFO: Project root configuration file: /usr/src/sonar-project.properties
INFO: SonarScanner 5.0.1.3006
INFO: Java 17.0.8 Alpine (64-bit)
INFO: Linux 6.1.0-1012-oem amd64
INFO: User cache: /opt/sonar-scanner/.sonar/cache
INFO: Analyzing on SonarQube server 
INFO: Default locale: "en_US", source code encoding: "UTF-8" (analysis is platform dependent)
INFO: Load global settings
INFO: Load global settings (done) | time=1161ms
INFO: Server id: 
INFO: User cache: /opt/sonar-scanner/.sonar/cache
INFO: Load/download plugins
INFO: Load plugins index
INFO: Load plugins index (done) | time=193ms
INFO: Load/download plugins (done) | time=121066ms
INFO: Process project properties
INFO: Process project properties (done) | time=7ms
INFO: Execute project builders
INFO: Execute project builders (done) | time=2ms
INFO: Project key: 
INFO: Base dir: /usr/src
INFO: Working dir: /usr/src/.scannerwork
INFO: Load project settings for component key: ''
INFO: Load project settings for component key: '' (done) | time=178ms
INFO: Load quality profiles
INFO: Load quality profiles (done) | time=211ms
INFO: Load active rules
INFO: Load active rules (done) | time=4483ms
INFO: Load analysis cache
INFO: Load analysis cache | time=312ms
INFO: Load project repositories
INFO: Load project repositories (done) | time=189ms
INFO: Indexing files...
INFO: Project configuration:
INFO: 538 files indexed
INFO: 0 files ignored because of scm ignore settings
INFO: Quality profile for json: Sonar way
INFO: Quality profile for php: Sonar way
INFO: ------------- Run sensors on module 
INFO: Load metrics repository
INFO: Load metrics repository (done) | time=184ms
INFO: Sensor JaCoCo XML Report Importer [jacoco]
INFO: 'sonar.coverage.jacoco.xmlReportPaths' is not defined. Using default locations: target/site/jacoco/jacoco.xml,target/site/jacoco-it/jacoco.xml,build/reports/jacoco/test/jacocoTestReport.xml
INFO: No report imported, no coverage information will be imported by JaCoCo XML Report Importer
INFO: Sensor JaCoCo XML Report Importer [jacoco] (done) | time=3ms
INFO: Sensor IaC CloudFormation Sensor [iac]
INFO: 0 source files to be analyzed
INFO: 0/0 source files have been analyzed
INFO: Sensor IaC CloudFormation Sensor [iac] (done) | time=13ms
INFO: Sensor IaC Kubernetes Sensor [iac]
INFO: 0 source files to be analyzed
INFO: 0/0 source files have been analyzed
INFO: Sensor IaC Kubernetes Sensor [iac] (done) | time=5ms
INFO: Sensor CSS Rules [javascript]
INFO: 392 source files to be analyzed
INFO: 392/392 source files have been analyzed
INFO: Hit the cache for 0 out of 0
INFO: Miss the cache for 0 out of 0
INFO: Sensor CSS Rules [javascript] (done) | time=6359ms
INFO: Sensor C# Project Type Information [csharp]
INFO: Sensor C# Project Type Information [csharp] (done) | time=2ms
INFO: Sensor C# Analysis Log [csharp]
INFO: Sensor C# Analysis Log [csharp] (done) | time=21ms
INFO: Sensor C# Properties [csharp]
INFO: Sensor C# Properties [csharp] (done) | time=0ms
INFO: Sensor HTML [web]
INFO: Sensor HTML [web] (done) | time=172ms
INFO: Sensor PHP sensor [php]
INFO: Starting PHP symbol indexer
INFO: 537 source files to be analyzed
INFO: 537/537 source files have been analyzed
INFO: Cached information of global symbols will be used for 0 out of 537 files. Global symbols were recomputed for the remaining files.
INFO: Starting PHP rules
INFO: 537 source files to be analyzed
...
ERROR: Could not analyse app/src/MyCoolNamespace/Domain.php
java.lang.IllegalStateException: Tokens of file app/src/MyCoolNamespace/Domain.php should be provided in order.
Previous token: Range[from [line=9, lineOffset=41] to [line=9, lineOffset=48]]
Last token: Range[from [line=9, lineOffset=32] to [line=9, lineOffset=40]]
	at org.sonar.api.utils.Preconditions.checkState(Preconditions.java:61)
	at org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens.addToken(DefaultCpdTokens.java:82)
	at org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens.addToken(DefaultCpdTokens.java:71)
	at org.sonar.plugins.php.AnalysisScanner.lambda$saveCpdData$1(AnalysisScanner.java:207)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at org.sonar.plugins.php.AnalysisScanner.saveCpdData(AnalysisScanner.java:207)
	at org.sonar.plugins.php.AnalysisScanner.computeMeasuresAndSaveCpdData(AnalysisScanner.java:188)
	at org.sonar.plugins.php.AnalysisScanner.scanFile(AnalysisScanner.java:171)
	at org.sonar.plugins.php.Scanner.processFile(Scanner.java:116)
	at org.sonar.plugins.php.Scanner.execute(Scanner.java:76)
	at org.sonar.plugins.php.Scanner.execute(Scanner.java:62)
	at org.sonar.plugins.php.AnalysisScanner.execute(AnalysisScanner.java:104)
	at org.sonar.plugins.php.PHPSensor.execute(PHPSensor.java:109)
	at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:88)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:61)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:79)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:61)
	at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:82)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
	at org.sonar.scanner.scan.SpringProjectScanContainer.scan(SpringProjectScanContainer.java:403)
	at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:399)
	at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:368)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
	at org.sonar.scanner.bootstrap.SpringGlobalContainer.doAfterStart(SpringGlobalContainer.java:137)
	at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:188)
	at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:167)
	at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:72)
	at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:66)
	at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
	at jdk.proxy1/jdk.proxy1.$Proxy0.execute(Unknown Source)
	at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
	at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:126)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:81)
	at org.sonarsource.scanner.cli.Main.main(Main.java:62)

if i remove readonly key everything works:

<?php

declare(strict_types=1);

namespace MyCoolNamespace;

class Domain
{
    public function __construct(private string $prop) {}
}

Is this an issue of sonarqube? Thank you

Hey there.

What version of SonarQube are you using? You should be able to find that info in the footer of your instance.

Hey,

its Community EditionVersion 9.9.1 (build 69595)

Hey @John_Khaun,

welcome to the community. I can verify that we crash on your reproducer. I created this ticket to address the problem. We will implement it in the next iteration. However, we will not backport the fix to the LTS version, so unfortunately you have to update to the latest version when the fix will be delivered.

Thanks for your report and your contribution.

Best,

1 Like

Hello Nils_Werner
We are also affected by this bug.
Since we are using the LTS Developer version of Sonarqube and are very interested in this fix, I have to follow up here.
Why will this fix not be included / backported into the LTS version?
We would prefer not to have to wait another six months to receive the fix.

Hi @007,

In this instance the issue is not a blocker (it just emits a log), so it will not be backported. This is in line with our policies around minor bug fixes.

It has been made available in SonarQube 10.5 and of course in the next LTS this year.

Denis