Skip to content

Commit

Permalink
Merge pull request #5300 from apache/php82-support
Browse files Browse the repository at this point in the history
PHP 8.2 Support
  • Loading branch information
tmysik committed Jan 17, 2023
2 parents 8fbcf30 + 4e0486e commit a97c358
Show file tree
Hide file tree
Showing 466 changed files with 70,211 additions and 58,138 deletions.
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.86
OpenIDE-Module-Specification-Version: 2.87
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"PhpVersion.PHP_74=PHP 7.4",
"PhpVersion.PHP_80=PHP 8.0",
"PhpVersion.PHP_81=PHP 8.1",
"PhpVersion.PHP_82=PHP 8.2",
})
public enum PhpVersion {

Expand Down Expand Up @@ -96,7 +97,13 @@ public enum PhpVersion {
* PHP 8.1.
* @since 2.80
*/
PHP_81(Bundle.PhpVersion_PHP_81());
PHP_81(Bundle.PhpVersion_PHP_81()),
/**
* PHP 8.2.
* @since 2.87
*/
PHP_82(Bundle.PhpVersion_PHP_82()),
;

private final String displayName;
private final boolean namespaces;
Expand Down Expand Up @@ -220,6 +227,17 @@ public boolean hasNeverType() {
return this.compareTo(PhpVersion.PHP_81) >= 0;
}

/**
* Check whether this version supports the null, false, and true types.
*
* @return {@code true} if this version supports null, false, and true
* types, {@code false} otherwise
* @since 2.87
*/
public boolean hasNullAndFalseAndTrueTypes() {
return this.compareTo(PhpVersion.PHP_82) >= 0;
}

/**
* Check whether this is supported version yet by PHP official.
*
Expand Down Expand Up @@ -254,6 +272,7 @@ private enum Period {
PHP_74(LocalDate.of(2019, 11, 28), LocalDate.of(2021, 11, 28), LocalDate.of(2022, 11, 28)),
PHP_80(LocalDate.of(2020, 11, 26), LocalDate.of(2022, 11, 26), LocalDate.of(2023, 11, 26)),
PHP_81(LocalDate.of(2021, 11, 25), LocalDate.of(2023, 11, 25), LocalDate.of(2024, 11, 25)),
PHP_82(LocalDate.of(2022, 12, 8), LocalDate.of(2024, 12, 8), LocalDate.of(2025, 12, 8)),
;

private final LocalDate initialRelease;
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.19.0
spec.version.base=2.22.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.83</specification-version>
<specification-version>2.87</specification-version>
</run-dependency>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ private static String getParamDefaultValue(Expression expr) {
}
return expr == null ? null : " "; //NOI18N
}

private static String getParamDefaultValue(ArrayCreation param) {
StringBuilder sb = new StringBuilder("["); //NOI18N
List<ArrayElement> arrayElements = param.getElements();
Expand Down Expand Up @@ -826,4 +826,15 @@ public static String removeNullableTypePrefix(String typeName) {
public static OffsetRange getOffsetRagne(@NonNull ASTNode node) {
return new OffsetRange(node.getStartOffset(), node.getEndOffset());
}

public static boolean isDnfType(UnionType unionType) {
if (unionType != null) {
for (Expression type : unionType.getTypes()) {
if (type instanceof IntersectionType) {
return true;
}
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public final class PhpModifiers extends Modifier {
public static final String VISIBILITY_PRIVATE = "private"; // NOI18N
public static final String VISIBILITY_PROTECTED = "protected"; // NOI18N

public static final String FINAL_MODIFIER = "final"; // NOI18N
public static final String ABSTRACT_MODIFIER = "abstract"; // NOI18N
public static final String READONLY_MODIFIER = "readonly"; // NOI18N

public static PhpModifiers noModifiers() {
return fromBitMask(new int[]{});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public boolean isAbstract() {
return getClassElement().isAbstract();
}

@Override
public boolean isReadonly() {
return getClassElement().isReadonly();
}

@Override
public boolean isAnonymous() {
return getClassElement().isAnonymous();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ public interface ClassElement extends TraitedElement {
Collection<QualifiedName> getFQMixinClassNames();
boolean isFinal();
boolean isAbstract();
boolean isReadonly();
boolean isAnonymous();
}
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,7 @@ private static boolean isType(Token<PHPTokenId> token) {
|| id == PHPTokenId.PHP_STATIC
|| id == PHPTokenId.PHP_NULL
|| id == PHPTokenId.PHP_FALSE
|| id == PHPTokenId.PHP_TRUE
|| id == PHPTokenId.PHP_ARRAY
|| id == PHPTokenId.PHP_ITERABLE
|| id == PHPTokenId.PHP_CALLABLE;
Expand Down Expand Up @@ -1285,8 +1286,12 @@ private static List<? extends Token<PHPTokenId>> getPreceedingLineTokens(Token<P
break;
}
Token<PHPTokenId> cToken = tokenSequence.token();
if (cToken.id() == PHPTokenId.WHITESPACE
&& TokenUtilities.indexOf(cToken.text(), '\n') != -1) { // NOI18N
if ((cToken.id() == PHPTokenId.WHITESPACE
&& TokenUtilities.indexOf(cToken.text(), '\n') != -1) // NOI18N
|| cToken.id() == PHPTokenId.PHP_LINE_COMMENT) {
// e.g.
// public bool $bool = true; // line comment
// public tru^e $true = true;
break;
}
tokens.addLast(cToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,11 @@ private static List<TypeConstantElement> getAllOverriddenConstants(TypeConstantE
}

private static void getOverriddenConstants(TypeConstantElement constant, List<TypeConstantElement> constants) {
if (constant.isMagic()) {
// e.g. A::class
// prevent NPE in getIndex()
return;
}
Set<TypeConstantElement> overriddenConstants = getOverriddenConstants(constant);
constants.addAll(overriddenConstants);
for (TypeConstantElement overriddenConstant : overriddenConstants) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
import org.netbeans.modules.php.editor.model.NamespaceScope;
import org.netbeans.modules.php.editor.model.ParameterInfoSupport;
import org.netbeans.modules.php.editor.model.Scope;
import org.netbeans.modules.php.editor.model.TraitScope;
import org.netbeans.modules.php.editor.model.TypeScope;
import org.netbeans.modules.php.editor.model.VariableName;
import org.netbeans.modules.php.editor.model.VariableScope;
Expand Down Expand Up @@ -266,7 +267,7 @@ private static enum UseType {
PHPTokenId.WHITESPACE, PHPTokenId.PHP_STRING, PHPTokenId.PHP_NS_SEPARATOR,
PHPTokenId.PHP_TYPE_BOOL, PHPTokenId.PHP_TYPE_FLOAT, PHPTokenId.PHP_TYPE_INT, PHPTokenId.PHP_TYPE_STRING, PHPTokenId.PHP_TYPE_VOID,
PHPTokenId.PHP_TYPE_OBJECT, PHPTokenId.PHP_TYPE_MIXED, PHPTokenId.PHP_SELF, PHPTokenId.PHP_PARENT, PHPTokenId.PHP_STATIC,
PHPTokenId.PHP_NULL, PHPTokenId.PHP_FALSE, PHPTokenId.PHP_ARRAY, PHPTokenId.PHP_ITERABLE, PHPTokenId.PHP_CALLABLE,
PHPTokenId.PHP_NULL, PHPTokenId.PHP_FALSE, PHPTokenId.PHP_TRUE, PHPTokenId.PHP_ARRAY, PHPTokenId.PHP_ITERABLE, PHPTokenId.PHP_CALLABLE,
PHPTokenId.PHPDOC_COMMENT_START, PHPTokenId.PHPDOC_COMMENT, PHPTokenId.PHPDOC_COMMENT_END,
PHPTokenId.PHP_COMMENT_START, PHPTokenId.PHP_COMMENT, PHPTokenId.PHP_COMMENT_END
);
Expand Down Expand Up @@ -319,7 +320,6 @@ public CodeCompletionResult complete(CodeCompletionContext completionContext) {
if (CancelSupport.getDefault().isCancelled()) {
return CodeCompletionResult.NONE;
}

CompletionContext context = CompletionContextFinder.findCompletionContext(info, caretOffset);
LOGGER.log(Level.FINE, "CC context: {0}", context);

Expand Down Expand Up @@ -534,7 +534,7 @@ public CodeCompletionResult complete(CodeCompletionContext completionContext) {
typesForTypeName.addAll(Type.getSpecialTypesForType());
}
if (isNullableType(info, caretOffset)) {
typesForTypeName.remove(Type.FALSE);
// ?false, ?true is OK since PHP 8.2
typesForTypeName.remove(Type.NULL);
}
if (isUnionType(info, caretOffset)) {
Expand All @@ -555,7 +555,7 @@ public CodeCompletionResult complete(CodeCompletionContext completionContext) {
typesForReturnTypeName.add(Type.STATIC);
}
if (isNullableType(info, caretOffset)) {
typesForReturnTypeName.remove(Type.FALSE);
// ?false, ?true is OK since PHP 8.2
typesForReturnTypeName.remove(Type.NULL);
typesForReturnTypeName.remove(Type.VOID);
typesForReturnTypeName.remove(Type.NEVER);
Expand Down Expand Up @@ -1154,7 +1154,7 @@ private void autoCompleteKeywordsInPHPDoc(final PHPCompletionResult completionRe
String prefix = doc.getText(start, 1);
if (CodeUtils.NULLABLE_TYPE_PREFIX.equals(prefix)) {
List<String> keywords = new ArrayList<>(Type.getTypesForEditor());
keywords.remove(Type.FALSE);
// ?false, ?true is OK since PHP 8.2
keywords.remove(Type.NULL);
autoCompleteKeywords(completionResult, request, keywords);
} else {
Expand Down Expand Up @@ -1301,7 +1301,7 @@ private void autoCompleteFieldType(ParserResult info, int caretOffset, final PHP
}
}
if (isNullableType) {
keywords.remove(Type.FALSE);
// ?false, ?true is OK since PHP 8.2
keywords.remove(Type.NULL);
}
if (isUnionType(info, caretOffset)) {
Expand Down Expand Up @@ -1350,6 +1350,7 @@ private boolean completeFieldTypes(TokenSequence<PHPTokenId> tokenSequence, int
PHPTokenId.PHP_ITERABLE,
PHPTokenId.PHP_SELF,
PHPTokenId.PHP_PARENT,
PHPTokenId.PHP_TRUE,
PHPTokenId.PHP_FALSE,
PHPTokenId.PHP_NULL,
PHPTokenId.PHP_STRING,
Expand Down Expand Up @@ -1492,15 +1493,32 @@ public boolean isAccepted(PhpElement element) {
for (InterfaceElement backedEnum : enums) {
accessibleTypeMembers.addAll(request.index.getAccessibleTypeMembers(backedEnum, backedEnum));
}
if (!staticContext && "name".startsWith(request.prefix)) { // NOI18N
// All Cases have a read-only property, name
// see: https://www.php.net/manual/en/language.enumerations.basics.php
// e.g. E::Case->name;
completionResult.add(PHPCompletionItem.AdditionalFieldItem.getItem("name", Type.STRING, enumElement.getFullyQualifiedName().toString(), request)); // NOI18N
}
if (!staticContext
&& !backingTypeName.isEmpty()) {
&& !backingTypeName.isEmpty()
&& "value".startsWith(request.prefix)) { // NOI18N
completionResult.add(PHPCompletionItem.AdditionalFieldItem.getItem("value", backingTypeName, enumElement.getFullyQualifiedName().toString(), request)); // NOI18N
}
}
for (final PhpElement phpElement : accessibleTypeMembers) {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
// https://wiki.php.net/rfc/deprecations_php_8_1 Accessing static members on traits
// e.g. T::$staticField, T::staticMethod() : deprecated since PHP 8.1
// we can fix this here in the future
if (typeScope instanceof TraitScope
&& !specialVariable
&& phpElement instanceof TypeConstantElement) {
// PHP 8.2: prohibit direct access through a trait name
// e.g. T::CONSTANT;
continue;
}
if (duplicateElementCheck.add(phpElement)) {
if (methodsFilter.isAccepted(phpElement)) {
MethodElement method = (MethodElement) phpElement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ public void visit(TraitDeclaration node) {
if (isCancelled()) {
return;
}
addToPath(node);
scan(node.getAttributes());
typeInfo = new TypeDeclarationTypeInfo(node);
Identifier name = node.getName();
Expand All @@ -646,6 +647,7 @@ public void visit(TraitDeclaration node) {
}
addColoringForUnusedPrivateFields();
}
removeFromPath();
}

@Override
Expand Down Expand Up @@ -810,13 +812,14 @@ public void visit(ConstantDeclaration node) {
}
if (parentNode instanceof ClassDeclaration
|| parentNode instanceof InterfaceDeclaration
|| parentNode instanceof TraitDeclaration
|| parentNode instanceof ClassInstanceCreation
|| parentNode instanceof EnumDeclaration) {
boolean isPrivate = Modifier.isPrivate(node.getModifier());
List<Identifier> names = node.getNames();
for (Identifier identifier : names) {
Set<ColoringAttributes> coloring = createConstantDeclarationColoring(identifier);
if (!isPrivate) {
if (!isPrivate || parentNode instanceof TraitDeclaration) {
addColoringForNode(identifier, coloring);
} else {
privateUnusedConstants.put(new UnusedIdentifier(identifier.getName(), typeInfo), new ASTNodeColoring(identifier, coloring));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,11 @@ public boolean isAbstract() {
return getPhpModifiers().isAbstract();
}

@Override
public boolean isReadonly() {
return getPhpModifiers().isReadonly();
}

@Override
public boolean isAnonymous() {
return CodeUtils.isSyntheticTypeName(getName());
Expand Down
Loading

0 comments on commit a97c358

Please sign in to comment.