Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion php/php.api.phpmodule/manifest.mf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.modules.php.api.phpmodule
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/php/api/phpmodule/resources/Bundle.properties
OpenIDE-Module-Specification-Version: 2.80
OpenIDE-Module-Specification-Version: 2.81
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ public boolean hasMixedType() {
return this.compareTo(PhpVersion.PHP_80) >= 0;
}

/**
* Check whether this version supports the never type.
*
* @return {@code true} if this version supports never type, {@code false}
* otherwise
* @since 2.81
*/
public boolean hasNeverType() {
return this.compareTo(PhpVersion.PHP_81) >= 0;
}

/**
* Check whether this is supported version yet by PHP official.
*
Expand Down
2 changes: 1 addition & 1 deletion php/php.editor/nbproject/project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ build.compiler=extJavac
nbjavac.ignore.missing.enclosing=**/CUP$ASTPHP5Parser$actions.class
javac.compilerargs=-J-Xmx512m
nbm.needs.restart=true
spec.version.base=2.8.0
spec.version.base=2.9.0
release.external/predefined_vars-1.0.zip=docs/predefined_vars.zip
sigtest.gen.fail.on.error=false

Expand Down
2 changes: 1 addition & 1 deletion php/php.editor/nbproject/project.xml
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>2.80</specification-version>
<specification-version>2.81</specification-version>
</run-dependency>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,7 @@ private static boolean isType(Token<PHPTokenId> token) {
|| id == PHPTokenId.PHP_TYPE_INT
|| id == PHPTokenId.PHP_TYPE_STRING
|| id == PHPTokenId.PHP_TYPE_VOID
|| id == PHPTokenId.PHP_TYPE_NEVER
|| id == PHPTokenId.PHP_TYPE_OBJECT
|| id == PHPTokenId.PHP_TYPE_MIXED
|| id == PHPTokenId.PHP_SELF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,10 @@ public CodeCompletionResult complete(CodeCompletionContext completionContext) {
typesForReturnTypeName.remove(Type.FALSE);
typesForReturnTypeName.remove(Type.NULL);
typesForReturnTypeName.remove(Type.VOID);
typesForReturnTypeName.remove(Type.NEVER);
} else if (context == CompletionContext.RETURN_UNION_TYPE_NAME) {
typesForReturnTypeName.remove(Type.VOID);
typesForReturnTypeName.remove(Type.NEVER);
typesForReturnTypeName.remove(Type.MIXED);
}
autoCompleteKeywords(completionResult, request, typesForReturnTypeName);
Expand Down
2,380 changes: 1,197 additions & 1,183 deletions php/php.editor/src/org/netbeans/modules/php/editor/lexer/PHP5ColoringLexer.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public enum PHPTokenId implements TokenId {
PHP_TYPE_VOID("void", "keyword"), //NOI18N
PHP_TYPE_OBJECT("object", "keyword"), //NOI18N
PHP_TYPE_MIXED("mixed", "keyword"), //NOI18N
PHP_TYPE_NEVER("never", "keyword"), //NOI18N NETBEANS-5599 PHP 8.1
PHP_FINAL(null, "keyword"), //NOI18N
PHP_PAAMAYIM_NEKUDOTAYIM(null, "operator"), //NOI18N
PHP_EXTENDS(null, "keyword"), //NOI18N
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ private Type() {
public static final String SELF = "self"; //NOI18N
public static final String PARENT = "parent"; //NOI18N
public static final String STATIC = "static"; //NOI18N NETBEANS-4443 PHP 8.0
public static final String NEVER = "never"; //NOI18N NETBEANS-5599 PHP 8.1

private static final List<String> TYPES_FOR_EDITOR = Arrays.asList(ARRAY, CALLABLE, ITERABLE, BOOL, FLOAT, INT, STRING, OBJECT, NULL, FALSE, MIXED);
private static final List<String> TYPES_FOR_RETURN_TYPE = Arrays.asList(ARRAY, CALLABLE, ITERABLE, BOOL, FLOAT, INT, STRING, VOID, OBJECT, NULL, FALSE, MIXED);
private static final List<String> TYPES_FOR_RETURN_TYPE = Arrays.asList(ARRAY, CALLABLE, ITERABLE, BOOL, FLOAT, INT, STRING, VOID, OBJECT, NULL, FALSE, MIXED, NEVER);
private static final List<String> TYPES_FOR_FIELD_TYPE = Arrays.asList(ARRAY, ITERABLE, BOOL, FLOAT, INT, STRING, OBJECT, SELF, PARENT, NULL, FALSE, MIXED); // PHP 7.4 Typed Properties 2.0
private static final List<String> SPECIAL_TYPES_FOR_TYPE = Arrays.asList(SELF, PARENT);
private static final List<String> TYPES_FOR_PHP_DOC = Arrays.asList(STRING, INTEGER, INT, BOOLEAN, BOOL, FLOAT, DOUBLE, OBJECT, MIXED, ARRAY,
Expand All @@ -74,7 +75,7 @@ public static boolean isPrimitive(String typeName) {
|| NUMBER.equals(typeName) || CALLBACK.equals(typeName) || RESOURCE.equals(typeName)
|| DOUBLE.equals(typeName) || STRING.equals(typeName) || NULL.equals(typeName)
|| VOID.equals(typeName) || CALLABLE.equals(typeName) || ITERABLE.equals(typeName)
|| FALSE.equals(typeName) || STATIC.equals(typeName)) {
|| FALSE.equals(typeName) || STATIC.equals(typeName) || NEVER.equals(typeName)) {
retval = true;
}
return retval;
Expand All @@ -97,7 +98,8 @@ public static boolean isArray(String typeName) {
public static boolean isInvalidPropertyType(String typeName) {
return VOID.equals(typeName)
|| NULL.equals(typeName)
|| STATIC.equals(typeName);
|| STATIC.equals(typeName)
|| NEVER.equals(typeName);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@
<file name="org-netbeans-modules-php-editor-verification-PHP81UnhandledError.instance"/>
<file name="org-netbeans-modules-php-editor-verification-ReturnTypeHintError.instance"/>
<file name="org-netbeans-modules-php-editor-verification-TypeRedeclarationHintError.instance"/>
<file name="org-netbeans-modules-php-editor-verification-UnusableTypesUnhandledError.instance"/>
<file name="org-netbeans-modules-php-editor-verification-UnusableTypesHintError.instance"/>
</folder>
</folder>
</folder>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
import org.openide.filesystems.FileObject;
import org.openide.util.NbBundle;

/**
* Don't check "never" type because it may be used in older versions as a class
* name.
*/
public final class PHP81UnhandledError extends UnhandledErrorRule {

@NbBundle.Messages("PHP81UnhandledError.displayName=Language feature not compatible with PHP version indicated in project settings")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
import org.openide.util.NbBundle;

/**
* Check "void" return type.
* Check "void" and "never" return type.
*
*/
public class ReturnTypeHintError extends HintErrorRule {
Expand Down Expand Up @@ -91,7 +91,7 @@ private boolean appliesTo(FileObject file) {
return getPhpVersion(file).compareTo(PhpVersion.PHP_71) >= 0;
}

// support only "void"
// support only "void" and "never"
// XXX support types?
private void checkReturnType(Map<ASTNode, Set<ReturnStatement>> returnStatements, List<Hint> hints) {
for (Entry<ASTNode, Set<ReturnStatement>> entry : returnStatements.entrySet()) {
Expand All @@ -115,46 +115,54 @@ private void checkReturnType(Map<ASTNode, Set<ReturnStatement>> returnStatements
if (returnType instanceof NamespaceName) {
NamespaceName namespaceName = (NamespaceName) returnType;
String name = CodeUtils.extractUnqualifiedName(namespaceName);
checkVoidReturnStatements(statements, name, hints);
checkVoidAndNeverReturnStatements(statements, name, hints);
} else if (returnType instanceof NullableType) {
Expression type = ((NullableType) returnType).getType();
if (type instanceof NamespaceName) {
NamespaceName namespaceName = (NamespaceName) type;
String name = CodeUtils.extractUnqualifiedName(namespaceName);
checkInvalidVoidReturnType(type, name, hints);
checkInvalidVoidAndNeverReturnType(type, name, hints);
}
}

}
}

@NbBundle.Messages({
"ReturnTypeHintErrorVoidDesc=\"void\" cannot return anything"
"# {0} - type",
"ReturnTypeHintErrorVoidDesc=\"{0}\" cannot return anything"
})
private void checkVoidReturnStatements(Set<ReturnStatement> statements, String name, List<Hint> hints) {
if (Type.VOID.equals(name)) {
private void checkVoidAndNeverReturnStatements(Set<ReturnStatement> statements, String name, List<Hint> hints) {
if (Type.VOID.equals(name) || isNeverType(name)) {
// check empty return statement
statements.forEach((statement) -> {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
Expression expression = statement.getExpression();
if (expression != null) {
addHint(statement, Bundle.ReturnTypeHintErrorVoidDesc(), hints);
if (expression != null || isNeverType(name)) {
addHint(statement, Bundle.ReturnTypeHintErrorVoidDesc(name), hints);
}
});
}
}

@NbBundle.Messages({
"ReturnTypeHintErrorInvalidVoidDesc=\"void\" cannot be used with \"?\""
"# {0} - type",
"ReturnTypeHintErrorInvalidVoidDesc=\"{0}\" cannot be used with \"?\""
})
private void checkInvalidVoidReturnType(Expression returnType, String name, List<Hint> hints) {
if (Type.VOID.equals(name)) {
addHint(returnType, Bundle.ReturnTypeHintErrorInvalidVoidDesc(), hints);
private void checkInvalidVoidAndNeverReturnType(Expression returnType, String name, List<Hint> hints) {
if (Type.VOID.equals(name)
|| isNeverType(name)) {
addHint(returnType, Bundle.ReturnTypeHintErrorInvalidVoidDesc(name), hints);
}
}

private boolean isNeverType(String name) {
return getPhpVersion(fileObject).hasNeverType()
&& Type.NEVER.equals(name);
}

private void addHint(ASTNode node, String description, List<Hint> hints) {
hints.add(new Hint(this,
description,
Expand Down Expand Up @@ -213,15 +221,11 @@ private void addReturnStatement(ASTNode node, ReturnStatement returnStatement) {
if (node != null) {
Set<ReturnStatement> returns = returnStatements.get(node);
if (returns == null) {
HashSet<ReturnStatement> statements = new HashSet<>();
if (returnStatement != null) {
statements.add(returnStatement);
}
returnStatements.put(node, statements);
} else {
if (returnStatement != null) {
returns.add(returnStatement);
}
returns = new HashSet<>();
returnStatements.put(node, returns);
}
if (returnStatement != null) {
returns.add(returnStatement);
}
}
}
Expand Down
Loading