This is an automated email from the ASF dual-hosted git repository.
tmysik pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 3cc64b4f7c Fix incorrect unused coloring #5551
new 137b7651eb Merge pull request #5670 from
junichi11/php-gh-5551-incorrect-unused
3cc64b4f7c is described below
commit 3cc64b4f7c706ce5e4875b6e78deeb39da603817
Author: Junichi Yamamoto <[email protected]>
AuthorDate: Fri Mar 17 11:24:11 2023 +0900
Fix incorrect unused coloring #5551
When there is an anonymous class in a method body, the anonymous class also
removes method blocks of the enclosing class that need to be scanned.
So, to prevent that, use `Map<TypeInfo, List<Block>>` instead of
`List<Block>`
---
.../modules/php/editor/csl/SemanticAnalysis.java | 52 +++++++++++--------
.../unit/data/testfiles/semantic/gh5551_01.php | 51 +++++++++++++++++++
.../data/testfiles/semantic/gh5551_01.php.semantic | 51 +++++++++++++++++++
.../unit/data/testfiles/semantic/gh5551_02.php | 59 ++++++++++++++++++++++
.../data/testfiles/semantic/gh5551_02.php.semantic | 59 ++++++++++++++++++++++
.../php/editor/csl/SemanticAnalyzerTest.java | 8 +++
6 files changed, 259 insertions(+), 21 deletions(-)
diff --git
a/php/php.editor/src/org/netbeans/modules/php/editor/csl/SemanticAnalysis.java
b/php/php.editor/src/org/netbeans/modules/php/editor/csl/SemanticAnalysis.java
index dbe9780708..a1aa52130c 100644
---
a/php/php.editor/src/org/netbeans/modules/php/editor/csl/SemanticAnalysis.java
+++
b/php/php.editor/src/org/netbeans/modules/php/editor/csl/SemanticAnalysis.java
@@ -227,7 +227,7 @@ public class SemanticAnalysis extends SemanticAnalyzer {
// for unsed private method: name, identifier
private final Map<UnusedIdentifier, ASTNodeColoring>
privateUnusedMethods;
// this is holder of blocks, which has to be scanned for usages in the
class.
- private List<Block> needToScan = new ArrayList<>();
+ private final Map<TypeInfo, List<Block>> needToScan = new HashMap<>();
private final Snapshot snapshot;
@@ -409,18 +409,16 @@ public class SemanticAnalysis extends SemanticAnalyzer {
scan(cldec.getInterfaes());
Identifier name = cldec.getName();
addColoringForNode(name, createTypeNameColoring(name));
- needToScan = new ArrayList<>();
+ needToScan.put(typeInfo, new ArrayList<>());
if (cldec.getBody() != null) {
cldec.getBody().accept(this);
// find all usages in the method bodies
- while (!needToScan.isEmpty()) {
- Block block = needToScan.remove(0);
- block.accept(this);
- }
+ scanMethodBodies();
addColoringForUnusedPrivateConstants();
addColoringForUnusedPrivateFields();
}
+ needToScan.remove(typeInfo);
removeFromPath();
}
@@ -515,8 +513,8 @@ public class SemanticAnalysis extends SemanticAnalyzer {
// don't scan the body now. It should be scanned after all
declarations
// are known
Block body = md.getFunction().getBody();
- if (body != null) {
- needToScan.add(body);
+ if (body != null && needToScan.get(typeInfo) != null) {
+ needToScan.get(typeInfo).add(body);
}
}
}
@@ -595,23 +593,24 @@ public class SemanticAnalysis extends SemanticAnalyzer {
// to avoid recognizing $this as an instance of an anonymous
class
scan(node.ctorParams());
addToPath(node);
+ // GH-5551 keep original type info to scan parent blocks
+ TypeInfo originalTypeInfo = typeInfo;
typeInfo = new ClassInstanceCreationTypeInfo(node);
scan(node.getAttributes());
scan(node.getSuperClass());
scan(node.getInterfaces());
- needToScan = new ArrayList<>();
+ needToScan.put(typeInfo, new ArrayList<>());
Block body = node.getBody();
if (body != null) {
body.accept(this);
// find all usages in the method bodies
- while (!needToScan.isEmpty()) {
- Block block = needToScan.remove(0);
- block.accept(this);
- }
+ scanMethodBodies();
addColoringForUnusedPrivateConstants();
addColoringForUnusedPrivateFields();
}
+ needToScan.remove(typeInfo);
+ typeInfo = originalTypeInfo;
removeFromPath();
} else {
super.visit(node);
@@ -639,14 +638,13 @@ public class SemanticAnalysis extends SemanticAnalyzer {
typeInfo = new TypeDeclarationTypeInfo(node);
Identifier name = node.getName();
addColoringForNode(name, createTypeNameColoring(name));
- needToScan = new ArrayList<>();
+ needToScan.put(typeInfo, new ArrayList<>());
if (node.getBody() != null) {
node.getBody().accept(this);
- for (Block block : needToScan) {
- block.accept(this);
- }
+ scanMethodBodies();
addColoringForUnusedPrivateFields();
}
+ needToScan.remove(typeInfo);
removeFromPath();
}
@@ -661,13 +659,12 @@ public class SemanticAnalysis extends SemanticAnalyzer {
typeInfo = new TypeDeclarationTypeInfo(node);
Identifier name = node.getName();
addColoringForNode(name, createTypeNameColoring(name));
- needToScan = new ArrayList<>();
+ needToScan.put(typeInfo, new ArrayList<>());
if (node.getBody() != null) {
node.getBody().accept(this);
- for (Block block : needToScan) {
- block.accept(this);
- }
+ scanMethodBodies();
}
+ needToScan.remove(typeInfo);
removeFromPath();
}
@@ -991,6 +988,19 @@ public class SemanticAnalysis extends SemanticAnalyzer {
super.visit(node);
}
+ /**
+ * Find all usages in the method bodies.
+ */
+ private void scanMethodBodies() {
+ if (needToScan.get(typeInfo) == null) {
+ return;
+ }
+ for (Block block : needToScan.get(typeInfo)) {
+ block.accept(this);
+ }
+ needToScan.get(typeInfo).clear();
+ }
+
private class FieldAccessVisitor extends DefaultVisitor {
private final Set<ColoringAttributes> coloring;
diff --git a/php/php.editor/test/unit/data/testfiles/semantic/gh5551_01.php
b/php/php.editor/test/unit/data/testfiles/semantic/gh5551_01.php
new file mode 100644
index 0000000000..4c1256e5e3
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/semantic/gh5551_01.php
@@ -0,0 +1,51 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+class TestClass {
+ public function testMethod(string $test): string {
+ return $test;
+ }
+}
+
+interface TestInterface {
+ public function testMethod(string $test): string;
+}
+
+class GH5551 {
+
+ private function usedPrivateMethod1(): TestClass {
+ return new TestClass();
+ }
+
+ private function usedPrivateMethod2(): TestInterface {
+ return new class implements TestInterface {
+ public function testMethod(string $test): string {
+ return $test;
+ }
+ };
+ }
+
+ private function unusedPrivateMethod(): void {
+ }
+
+ public function test() {
+ echo $this->usedPrivateMethod1()->testMethod("test1"), PHP_EOL;
+ echo $this->usedPrivateMethod2()->testMethod("test2"), PHP_EOL;
+ }
+}
diff --git
a/php/php.editor/test/unit/data/testfiles/semantic/gh5551_01.php.semantic
b/php/php.editor/test/unit/data/testfiles/semantic/gh5551_01.php.semantic
new file mode 100644
index 0000000000..dbcdcefa6a
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/semantic/gh5551_01.php.semantic
@@ -0,0 +1,51 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+class |>CLASS:TestClass<| {
+ public function |>METHOD:testMethod<|(string $test): string {
+ return $test;
+ }
+}
+
+interface |>CLASS:TestInterface<| {
+ public function |>METHOD:testMethod<|(string $test): string;
+}
+
+class |>CLASS:GH5551<| {
+
+ private function |>METHOD:usedPrivateMethod1<|(): TestClass {
+ return new TestClass();
+ }
+
+ private function |>METHOD:usedPrivateMethod2<|(): TestInterface {
+ return new class implements TestInterface {
+ public function |>METHOD:testMethod<|(string $test): string {
+ return $test;
+ }
+ };
+ }
+
+ private function |>METHOD,UNUSED:unusedPrivateMethod<|(): void {
+ }
+
+ public function |>METHOD:test<|() {
+ echo
$this->|>CUSTOM1:usedPrivateMethod1<|()->|>CUSTOM1:testMethod<|("test1"),
PHP_EOL;
+ echo
$this->|>CUSTOM1:usedPrivateMethod2<|()->|>CUSTOM1:testMethod<|("test2"),
PHP_EOL;
+ }
+}
diff --git a/php/php.editor/test/unit/data/testfiles/semantic/gh5551_02.php
b/php/php.editor/test/unit/data/testfiles/semantic/gh5551_02.php
new file mode 100644
index 0000000000..2d7f8cb0d0
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/semantic/gh5551_02.php
@@ -0,0 +1,59 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+class TestClass {
+ public function testMethod(string $test): string {
+ return $test;
+ }
+}
+
+interface TestInterface {
+ public function testMethod(string $test): string;
+}
+
+class GH5551 {
+
+ private function usedPrivateMethod1(): TestClass {
+ return new TestClass();
+ }
+
+ private function usedPrivateMethod2(): TestInterface {
+ return new class implements TestInterface {
+
+ private function unusedPrivateMethod(): void {
+ }
+
+ private function usedPrivateMethod(): void {
+ }
+
+ public function testMethod(string $test): string {
+ $this->usedPrivateMethod();
+ return $test;
+ }
+ };
+ }
+
+ private function unusedPrivateMethod(): void {
+ }
+
+ public function test() {
+ echo $this->usedPrivateMethod1()->testMethod("test1"), PHP_EOL;
+ echo $this->usedPrivateMethod2()->testMethod("test2"), PHP_EOL;
+ }
+}
diff --git
a/php/php.editor/test/unit/data/testfiles/semantic/gh5551_02.php.semantic
b/php/php.editor/test/unit/data/testfiles/semantic/gh5551_02.php.semantic
new file mode 100644
index 0000000000..870be797d9
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/semantic/gh5551_02.php.semantic
@@ -0,0 +1,59 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+class |>CLASS:TestClass<| {
+ public function |>METHOD:testMethod<|(string $test): string {
+ return $test;
+ }
+}
+
+interface |>CLASS:TestInterface<| {
+ public function |>METHOD:testMethod<|(string $test): string;
+}
+
+class |>CLASS:GH5551<| {
+
+ private function |>METHOD:usedPrivateMethod1<|(): TestClass {
+ return new TestClass();
+ }
+
+ private function |>METHOD:usedPrivateMethod2<|(): TestInterface {
+ return new class implements TestInterface {
+
+ private function |>METHOD,UNUSED:unusedPrivateMethod<|(): void {
+ }
+
+ private function |>METHOD:usedPrivateMethod<|(): void {
+ }
+
+ public function |>METHOD:testMethod<|(string $test): string {
+ $this->|>CUSTOM1:usedPrivateMethod<|();
+ return $test;
+ }
+ };
+ }
+
+ private function |>METHOD,UNUSED:unusedPrivateMethod<|(): void {
+ }
+
+ public function |>METHOD:test<|() {
+ echo
$this->|>CUSTOM1:usedPrivateMethod1<|()->|>CUSTOM1:testMethod<|("test1"),
PHP_EOL;
+ echo
$this->|>CUSTOM1:usedPrivateMethod2<|()->|>CUSTOM1:testMethod<|("test2"),
PHP_EOL;
+ }
+}
diff --git
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/SemanticAnalyzerTest.java
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/SemanticAnalyzerTest.java
index 633e0221b8..f7c50a0cc9 100644
---
a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/SemanticAnalyzerTest.java
+++
b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/SemanticAnalyzerTest.java
@@ -217,4 +217,12 @@ public class SemanticAnalyzerTest extends
SemanticAnalysisTestBase {
public void testConstantsInTraits() throws Exception {
checkSemantic("testfiles/semantic/constantsInTraits.php");
}
+
+ public void testGH5551_01() throws Exception {
+ checkSemantic("testfiles/semantic/gh5551_01.php");
+ }
+
+ public void testGH5551_02() throws Exception {
+ checkSemantic("testfiles/semantic/gh5551_02.php");
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists