This is an automated email from the ASF dual-hosted git repository. junichi11 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 f55ac21e3e Adding a new error hint that checks if the return statement has a value if the return type is specified for the function, as suggested in #5078 Fixing the cancelability bug in ReturnTypeHintError by reverting from a for each loop to a normal loop new 232ad487ab Merge pull request #5648 from troizet/return_statement_filled_value_hint f55ac21e3e is described below commit f55ac21e3eceeb5709318d20ec4b01dced1c1aed Author: Alexey Borokhvostov <troi...@gmail.com> AuthorDate: Fri Mar 10 21:53:38 2023 +0700 Adding a new error hint that checks if the return statement has a value if the return type is specified for the function, as suggested in #5078 Fixing the cancelability bug in ReturnTypeHintError by reverting from a for each loop to a normal loop --- .../editor/verification/ReturnTypeHintError.java | 45 ++++++-- ...rnTypeHint.php.testNeverReturnTypeHint_01.hints | 25 ++++- ...rnTypeHint.php.testNeverReturnTypeHint_02.hints | 6 + .../testReturnStatementWithoutValueHintError.php | 125 +++++++++++++++++++++ ...hp.testReturnStatementWithoutValueHint_01.hints | 0 ...hp.testReturnStatementWithoutValueHint_02.hints | 0 ...hp.testReturnStatementWithoutValueHint_03.hints | 30 +++++ ...hp.testReturnStatementWithoutValueHint_04.hints | 33 ++++++ ...urnTypeHint.php.testVoidReturnTypeHint_02.hints | 6 + .../verification/ReturnTypeHintErrorTest.java | 16 +++ 10 files changed, 277 insertions(+), 9 deletions(-) diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/verification/ReturnTypeHintError.java b/php/php.editor/src/org/netbeans/modules/php/editor/verification/ReturnTypeHintError.java index 2db7904335..2f4ee1e3d4 100644 --- a/php/php.editor/src/org/netbeans/modules/php/editor/verification/ReturnTypeHintError.java +++ b/php/php.editor/src/org/netbeans/modules/php/editor/verification/ReturnTypeHintError.java @@ -39,17 +39,19 @@ import org.netbeans.modules.php.editor.parser.PHPParseResult; import org.netbeans.modules.php.editor.parser.astnodes.ASTNode; import org.netbeans.modules.php.editor.parser.astnodes.Expression; import org.netbeans.modules.php.editor.parser.astnodes.FunctionDeclaration; +import org.netbeans.modules.php.editor.parser.astnodes.IntersectionType; import org.netbeans.modules.php.editor.parser.astnodes.LambdaFunctionDeclaration; import org.netbeans.modules.php.editor.parser.astnodes.NamespaceName; import org.netbeans.modules.php.editor.parser.astnodes.NullableType; import org.netbeans.modules.php.editor.parser.astnodes.ReturnStatement; +import org.netbeans.modules.php.editor.parser.astnodes.UnionType; import org.netbeans.modules.php.editor.parser.astnodes.visitors.DefaultVisitor; import org.openide.filesystems.FileObject; import org.openide.util.NbBundle; /** * Check "void" and "never" return type. - * + * Checks if the return statement has a value if a return type is specified for the function. */ public class ReturnTypeHintError extends HintErrorRule { @@ -116,6 +118,7 @@ public class ReturnTypeHintError extends HintErrorRule { NamespaceName namespaceName = (NamespaceName) returnType; String name = CodeUtils.extractUnqualifiedName(namespaceName); checkVoidAndNeverReturnStatements(statements, name, hints); + checkReturnStatementsWithoutValue(statements, name, hints); } else if (returnType instanceof NullableType) { Expression type = ((NullableType) returnType).getType(); if (type instanceof NamespaceName) { @@ -123,6 +126,10 @@ public class ReturnTypeHintError extends HintErrorRule { String name = CodeUtils.extractUnqualifiedName(namespaceName); checkInvalidVoidAndNeverReturnType(type, name, hints); } + checkReturnStatementsWithoutValue(statements, "", hints); // NOI18N + } else if (returnType instanceof UnionType + || returnType instanceof IntersectionType) { + checkReturnStatementsWithoutValue(statements, "", hints); // NOI18N } } @@ -133,9 +140,9 @@ public class ReturnTypeHintError extends HintErrorRule { "ReturnTypeHintErrorVoidDesc=\"{0}\" cannot return anything" }) private void checkVoidAndNeverReturnStatements(Set<ReturnStatement> statements, String name, List<Hint> hints) { - if (Type.VOID.equals(name) || isNeverType(name)) { + if (isVoidType(name) || isNeverType(name)) { // check empty return statement - statements.forEach((statement) -> { + for (ReturnStatement statement: statements) { if (CancelSupport.getDefault().isCancelled()) { return; } @@ -143,7 +150,7 @@ public class ReturnTypeHintError extends HintErrorRule { if (expression != null || isNeverType(name)) { addHint(statement, Bundle.ReturnTypeHintErrorVoidDesc(name), hints); } - }); + } } } @@ -152,17 +159,39 @@ public class ReturnTypeHintError extends HintErrorRule { "ReturnTypeHintErrorInvalidVoidDesc=\"{0}\" cannot be used with \"?\"" }) private void checkInvalidVoidAndNeverReturnType(Expression returnType, String name, List<Hint> hints) { - if (Type.VOID.equals(name) - || isNeverType(name)) { + if (isVoidType(name) || isNeverType(name)) { addHint(returnType, Bundle.ReturnTypeHintErrorInvalidVoidDesc(name), hints); } } + @NbBundle.Messages({ + "ReturnStatementWithoutValueHintErrorDesc=Return statement must be filled with the value" + }) + private void checkReturnStatementsWithoutValue(Set<ReturnStatement> statements, String name, List<Hint> hints) { + if (!isVoidType(name) && !isNeverType(name)) { + // check empty return statement + for (ReturnStatement statement: statements) { + if (CancelSupport.getDefault().isCancelled()) { + return; + } + Expression expression = statement.getExpression(); + if (expression == null) { + addHint(statement, Bundle.ReturnStatementWithoutValueHintErrorDesc(), hints); + } + } + } + } + private boolean isNeverType(String name) { - return getPhpVersion(fileObject).hasNeverType() - && Type.NEVER.equals(name); + return Type.NEVER.equals(name) + && getPhpVersion(fileObject).hasNeverType(); } + private boolean isVoidType(String name) { + return Type.VOID.equals(name) + && getPhpVersion(fileObject).hasVoidReturnType(); + } + private void addHint(ASTNode node, String description, List<Hint> hints) { hints.add(new Hint(this, description, diff --git a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testNeverReturnTypeHint.php.testNeverReturnTypeHint_01.hints b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testNeverReturnTypeHint.php.testNeverReturnTypeHint_01.hints index 8b13789179..90eba6b7c1 100644 --- a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testNeverReturnTypeHint.php.testNeverReturnTypeHint_01.hints +++ b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testNeverReturnTypeHint.php.testNeverReturnTypeHint_01.hints @@ -1 +1,24 @@ - + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value diff --git a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testNeverReturnTypeHint.php.testNeverReturnTypeHint_02.hints b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testNeverReturnTypeHint.php.testNeverReturnTypeHint_02.hints index 5410ef7995..3b672eb1b6 100644 --- a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testNeverReturnTypeHint.php.testNeverReturnTypeHint_02.hints +++ b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testNeverReturnTypeHint.php.testNeverReturnTypeHint_02.hints @@ -6,6 +6,9 @@ function invalidNeverReturnType2(): ?never { // invalidNeverReturnType2 func HINT:"never" cannot be used with "?" return; ------- +HINT:Return statement must be filled with the value + return; + ------- HINT:"never" cannot return anything return true; // neverReturnType3 func ------------ @@ -61,6 +64,9 @@ HINT:"never" cannot be used with "?" $anon = function(): ?never { // anon2 trait ----- HINT:"never" cannot be used with "?" + return; + ------- +HINT:Return statement must be filled with the value public function neverReturnType2(): ?never; // neverReturnType2 interface ----- HINT:"never" cannot be used with "?" diff --git a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php new file mode 100644 index 0000000000..fd451404f2 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php @@ -0,0 +1,125 @@ +<?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. + */ + +function ret1(): void +{ + if (false) { + return; + } + return 10; +} + +function ret2(): never +{ + if (false) { + return; + } + return 10; +} + +function ret3(): int +{ + if (false) { + return; + } + return 10; +} + +function ret4() +{ + if (false) { + return; + } + return 10; +} + +function ret5(): int|string +{ + if (false) { + return; + } + return 'string'; +} + +function ret6(): ClassA&ClassB +{ + if (false) { + return; + } + return new ClassA(); +} + +function ret7(): ?int +{ + if (false) { + return; + } + return 10; +} + +function ret8(): int|null +{ + if (false) { + return; + } + return null; +} + +function ret9(): false +{ + if (false) { + return; + } + return false; +} + +$anon1 = function(): string { + return; +}; + +$anon2 = function(): string { + return 'string'; +}; + +$anon3 = function() { + return; +}; + +class ClassA {} +class ClassB extends ClassA {} + + +class TestClass +{ + public function ret1(): string + { + return; + } + + public function ret2(): string + { + return 'string'; + } + + public function ret3() + { + return; + } +} diff --git a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_01.hints b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_01.hints new file mode 100644 index 0000000000..e69de29bb2 diff --git a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_02.hints b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_02.hints new file mode 100644 index 0000000000..e69de29bb2 diff --git a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_03.hints b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_03.hints new file mode 100644 index 0000000000..a86bb8e809 --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_03.hints @@ -0,0 +1,30 @@ + return 10; + ---------- +HINT:"void" cannot return anything + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value diff --git a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_04.hints b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_04.hints new file mode 100644 index 0000000000..a6533283bd --- /dev/null +++ b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testReturnStatementWithoutValueHintError.php.testReturnStatementWithoutValueHint_04.hints @@ -0,0 +1,33 @@ + return 10; + ---------- +HINT:"void" cannot return anything + return; + ------- +HINT:"never" cannot return anything + return 10; + ---------- +HINT:"never" cannot return anything + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value + return; + ------- +HINT:Return statement must be filled with the value diff --git a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testVoidReturnTypeHint.php.testVoidReturnTypeHint_02.hints b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testVoidReturnTypeHint.php.testVoidReturnTypeHint_02.hints index 0a428c10b7..ded1843c62 100644 --- a/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testVoidReturnTypeHint.php.testVoidReturnTypeHint_02.hints +++ b/php/php.editor/test/unit/data/testfiles/verification/ReturnTypeHintError/testVoidReturnTypeHint.php.testVoidReturnTypeHint_02.hints @@ -4,6 +4,9 @@ HINT:"void" cannot be used with "?" function invalidVoidReturnType2(): ?void { // invalidVoidReturnType2 func ---- HINT:"void" cannot be used with "?" + return; + ------- +HINT:Return statement must be filled with the value return true; // voidReturnType3 func ------------ HINT:"void" cannot return anything @@ -43,6 +46,9 @@ HINT:"void" cannot be used with "?" $anon = function(): ?void { // anon2 trait ---- HINT:"void" cannot be used with "?" + return; + ------- +HINT:Return statement must be filled with the value public function voidReturnType2(): ?void; // voidReturnType2 interface ---- HINT:"void" cannot be used with "?" diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/verification/ReturnTypeHintErrorTest.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/verification/ReturnTypeHintErrorTest.java index bf4664db3b..d511fdcab9 100644 --- a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/verification/ReturnTypeHintErrorTest.java +++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/verification/ReturnTypeHintErrorTest.java @@ -43,6 +43,22 @@ public class ReturnTypeHintErrorTest extends PHPHintsTestBase { checkHints(new ReturnTypeHintErrorStub(PhpVersion.PHP_81), "testNeverReturnTypeHint.php"); } + public void testReturnStatementWithoutValueHint_01() throws Exception { + checkHints(new ReturnTypeHintErrorStub(PhpVersion.PHP_56), "testReturnStatementWithoutValueHintError.php"); + } + + public void testReturnStatementWithoutValueHint_02() throws Exception { + checkHints(new ReturnTypeHintErrorStub(PhpVersion.PHP_70), "testReturnStatementWithoutValueHintError.php"); + } + + public void testReturnStatementWithoutValueHint_03() throws Exception { + checkHints(new ReturnTypeHintErrorStub(PhpVersion.PHP_71), "testReturnStatementWithoutValueHintError.php"); + } + + public void testReturnStatementWithoutValueHint_04() throws Exception { + checkHints(new ReturnTypeHintErrorStub(PhpVersion.PHP_81), "testReturnStatementWithoutValueHintError.php"); + } + @Override protected String getTestDirectory() { return TEST_DIRECTORY + "ReturnTypeHintError/"; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org For additional commands, e-mail: commits-h...@netbeans.apache.org For further information about the NetBeans mailing lists, visit: https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists