From 5241929023691c3d704d77e5a9d7a327113c3955 Mon Sep 17 00:00:00 2001 From: Tomas Prochazka Date: Sat, 18 Jan 2025 11:48:43 +0100 Subject: [PATCH] Add support for PHPStan error identifiers PHPStan since version 1.11 uses identifiers for errors. Error identifers are read and displayed with this change. Reference: https://phpstan.org/blog/phpstan-1-11-errors-identifiers-phpstan-pro-reboot#error-identifiers --- .../parsers/CheckStyleReportParser.java | 4 +++ .../phpstan-log-with-error-identifiers.xml | 27 +++++++++++++++++++ .../parsers/CheckStyleReportParserTest.java | 21 +++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 php/php.code.analysis/test/unit/data/phpstan/phpstan-log-with-error-identifiers.xml diff --git a/php/php.code.analysis/src/org/netbeans/modules/php/analysis/parsers/CheckStyleReportParser.java b/php/php.code.analysis/src/org/netbeans/modules/php/analysis/parsers/CheckStyleReportParser.java index 913792344447..6c26c30594f1 100644 --- a/php/php.code.analysis/src/org/netbeans/modules/php/analysis/parsers/CheckStyleReportParser.java +++ b/php/php.code.analysis/src/org/netbeans/modules/php/analysis/parsers/CheckStyleReportParser.java @@ -165,6 +165,10 @@ private void processResultStart(Attributes attributes) { currentResult.setLine(lineNumber); currentResult.setColumn(getInt(attributes, "column")); // NOI18N String message = attributes.getValue("message"); // NOI18N + String errorIdentifier = attributes.getValue("source"); // NOI18N + if (errorIdentifier != null) { + message = String.format("%s: %s", errorIdentifier, message); // NOI18N + } currentResult.setCategory(String.format("%s: %s", attributes.getValue("severity"), message)); // NOI18N // Message can contain types like "array" and description is renderd as HTML so it has to be properly escaped. currentResult.setDescription(StringEscapeUtils.escapeHtml(message)); diff --git a/php/php.code.analysis/test/unit/data/phpstan/phpstan-log-with-error-identifiers.xml b/php/php.code.analysis/test/unit/data/phpstan/phpstan-log-with-error-identifiers.xml new file mode 100644 index 000000000000..323db30a3088 --- /dev/null +++ b/php/php.code.analysis/test/unit/data/phpstan/phpstan-log-with-error-identifiers.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/php/php.code.analysis/test/unit/src/org/netbeans/modules/php/analysis/parsers/CheckStyleReportParserTest.java b/php/php.code.analysis/test/unit/src/org/netbeans/modules/php/analysis/parsers/CheckStyleReportParserTest.java index d8a5082643a8..d75cb397bdb8 100644 --- a/php/php.code.analysis/test/unit/src/org/netbeans/modules/php/analysis/parsers/CheckStyleReportParserTest.java +++ b/php/php.code.analysis/test/unit/src/org/netbeans/modules/php/analysis/parsers/CheckStyleReportParserTest.java @@ -112,6 +112,27 @@ public void testParseWithHtmlEntities() throws Exception { assertEquals("Function count() should return int but returns array<string>.", result.getDescription()); } + public void testParseWithHtmlErrorIdentifiers() throws Exception { + FileObject root = getDataDir("phpstan/PHPStanSupport"); + FileObject workDir = root; + List results = CheckStyleReportParser.parse(getLogFile("phpstan-log-with-error-identifiers.xml"), root, workDir); + assertNotNull(results); + + assertEquals(2, results.size()); + + Result result = results.get(0); + assertEquals(FileUtil.toFile(root.getFileObject("HelloWorld.php")).getAbsolutePath(), result.getFilePath()); + assertEquals(8, result.getLine()); + assertEquals("error: nullCoalesce.expr: Expression on left side of ?? is not nullable.", result.getCategory()); + assertEquals("nullCoalesce.expr: Expression on left side of ?? is not nullable.", result.getDescription()); + + result = results.get(1); + assertEquals(FileUtil.toFile(root.getFileObject("HelloWorld.php")).getAbsolutePath(), result.getFilePath()); + assertEquals(13, result.getLine()); + assertEquals("error: return.missing: Method HelloWorld::readLength() should return float but return statement is missing.", result.getCategory()); + assertEquals("return.missing: Method HelloWorld::readLength() should return float but return statement is missing.", result.getDescription()); + } + public void testPsalmParse() throws Exception { FileObject root = getDataDir("psalm/PsalmSupport"); FileObject workDir = root;