Skip to content

Commit 0875d01

Browse files
committed
PHP 8.4 Support: new MyClass()->method() without parentheses (Part 5)
- apache#8035 - https://wiki.php.net/rfc#php_84 - https://wiki.php.net/rfc/new_without_parentheses - Fix Code Completion feature - Add unit tests Note: The following case is not supported yet. The statement is broken. (it has a syntax error.) So, the anonymous class is not parsed correctly. i.e. We can't get members. We have to sanitize an error part. ```php echo new class() { public const string CONSTANT = "constant"; }::^ ```
1 parent 00f65b8 commit 0875d01

File tree

124 files changed

+2292
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+2292
-2
lines changed

php/php.editor/src/org/netbeans/modules/php/editor/model/ModelUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ public static Collection<? extends TypeScope> resolveTypeAfterReferenceToken(Mod
283283
}
284284
}
285285
if (scp != null) {
286-
String semiType = VariousUtils.getSemiType(tokenSequence, VariousUtils.State.START, scp);
286+
String semiType = VariousUtils.getSemiType(tokenSequence, VariousUtils.State.START, scp, model);
287287
if (semiType != null) {
288288
return VariousUtils.getType(scp, semiType, offset, true);
289289
}

php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import org.netbeans.modules.php.editor.model.FunctionScope;
5454
import org.netbeans.modules.php.editor.model.IndexScope;
5555
import org.netbeans.modules.php.editor.model.MethodScope;
56+
import org.netbeans.modules.php.editor.model.Model;
5657
import org.netbeans.modules.php.editor.model.ModelElement;
5758
import org.netbeans.modules.php.editor.model.ModelUtils;
5859
import org.netbeans.modules.php.editor.model.NamespaceScope;
@@ -1288,7 +1289,7 @@ public enum State {
12881289
};
12891290

12901291
@org.netbeans.api.annotations.common.SuppressWarnings({"SF_SWITCH_FALLTHROUGH"})
1291-
public static String getSemiType(TokenSequence<PHPTokenId> tokenSequence, State state, VariableScope varScope) {
1292+
public static String getSemiType(TokenSequence<PHPTokenId> tokenSequence, State state, VariableScope varScope, Model model) {
12921293
int commasCount = 0;
12931294
String possibleClassName = ""; //NOI18N
12941295
int anchor = -1;
@@ -1478,6 +1479,16 @@ public static String getSemiType(TokenSequence<PHPTokenId> tokenSequence, State
14781479
//no-op
14791480
}
14801481
} else {
1482+
if (token.id() == PHPTokenId.PHP_CURLY_CLOSE
1483+
&& (state == State.REFERENCE || state == State.STATIC_REFERENCE)) {
1484+
// new class(){}->, new class(){}?->, new class(){}::
1485+
ClassScope anonymousClass = getAnonymousClass(tokenSequence.offset() + tokenSequence.token().length(), model);
1486+
if (anonymousClass != null) {
1487+
state = State.STOP;
1488+
metaAll.insert(0, PRE_OPERATION_TYPE_DELIMITER + VariousUtils.CONSTRUCTOR_TYPE_PREFIX + anonymousClass.getName());
1489+
break;
1490+
}
1491+
}
14811492
if (state.equals(State.VARBASE)) {
14821493
metaAll.insert(0, PRE_OPERATION_TYPE_DELIMITER + VariousUtils.VAR_TYPE_PREFIX);
14831494
state = State.STOP;
@@ -1521,6 +1532,18 @@ public static String getSemiType(TokenSequence<PHPTokenId> tokenSequence, State
15211532
return null;
15221533
}
15231534

1535+
@CheckForNull
1536+
private static ClassScope getAnonymousClass(int anonymousClassEndOffset, Model model) {
1537+
Collection<? extends ClassScope> classScopes = ModelUtils.getDeclaredClasses(model.getFileScope());
1538+
for (ClassScope classScope : classScopes) {
1539+
if (classScope.isAnonymous()
1540+
&& classScope.getBlockRange().getEnd() == anonymousClassEndOffset) {
1541+
return classScope;
1542+
}
1543+
}
1544+
return null;
1545+
}
1546+
15241547
private static boolean isPossibleAnonymousObjectCall(final TokenSequence<PHPTokenId> tokenSequence) {
15251548
boolean result = true;
15261549
boolean skippedOpenParenthesis = tokenSequence.movePrevious();
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
/*
3+
* Licensed to the Apache Software Foundation (ASF) under one
4+
* or more contributor license agreements. See the NOTICE file
5+
* distributed with this work for additional information
6+
* regarding copyright ownership. The ASF licenses this file
7+
* to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance
9+
* with the License. You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing,
14+
* software distributed under the License is distributed on an
15+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
* KIND, either express or implied. See the License for the
17+
* specific language governing permissions and limitations
18+
*/
19+
class Test {
20+
const IMPLICIT_PUBLIC_TEST_CONST = "implicit public test const";
21+
public const string PUBLIC_TEST_CONST = "public test const";
22+
protected const string PROTECTED_TEST_CONST = "protected test const";
23+
private const string PRIVATE_TEST_CONST = "private test const";
24+
25+
public int $publicTestField = 1;
26+
protected int $protectedTestField = 2;
27+
private int $privateTestField = 3;
28+
29+
public static string $publicStaticTestField = "public static test field";
30+
protected static string $protectedStaticTestField = "protected static test field";
31+
private static string $privateStaticTestField = "private static test field";
32+
33+
public function publicTestMethod(): string {
34+
return "public test method";
35+
}
36+
37+
protected function protectedTestMethod(): string {
38+
return "protected test method";
39+
}
40+
41+
private function privateTestMethod(): string {
42+
return "private test method";
43+
}
44+
45+
public static function publicStaticTestMethod(): string {
46+
return "public static test method";
47+
}
48+
49+
protected static function protectedStaticTestMethod(): string {
50+
return "protected static test method";
51+
}
52+
53+
private static function privateStaticTestMethod(): string {
54+
return "private static test method";
55+
}
56+
}
57+

0 commit comments

Comments
 (0)