You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by tm...@apache.org on 2019/08/16 15:33:00 UTC
[netbeans] branch master updated: [NETBEANS-2992] Code completion
does not work well inside Closures
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 acdaf52 [NETBEANS-2992] Code completion does not work well inside Closures
new 2f16e2e Merge pull request #1434 from junichi11/netbeans-2992
acdaf52 is described below
commit acdaf52d880133c6c9153c6caecb00f22cde47ff
Author: Junichi Yamamoto <ju...@apache.org>
AuthorDate: Fri Aug 16 21:35:45 2019 +0900
[NETBEANS-2992] Code completion does not work well inside Closures
- Change the current scope when `$this` is used in anonymous functions
---
.../modules/php/editor/model/ModelUtils.java | 12 ++++
.../php/editor/model/impl/ModelVisitor.java | 14 ++++-
.../php/editor/model/impl/VariousUtils.java | 21 ++++++-
.../testfiles/completion/lib/nb2992/nb2992.php | 70 ++++++++++++++++++++++
.../lib/nb2992/nb2992.php.testNb2992_01.completion | 4 ++
.../lib/nb2992/nb2992.php.testNb2992_02.completion | 4 ++
.../lib/nb2992/nb2992.php.testNb2992_03.completion | 4 ++
.../issue247082.php.testForKeywords.completion | 1 -
.../completion/PHPCodeCompletionNb2992Test.java | 58 ++++++++++++++++++
9 files changed, 185 insertions(+), 3 deletions(-)
diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/model/ModelUtils.java b/php/php.editor/src/org/netbeans/modules/php/editor/model/ModelUtils.java
index 869eced..d79558f 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/model/ModelUtils.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/model/ModelUtils.java
@@ -631,4 +631,16 @@ public final class ModelUtils {
}
return result;
}
+
+ /**
+ * Check whether the scope is anonymous function scope.
+ *
+ * @param scope the scope
+ * @return {@code true} if the scope is anonymous function scope,
+ * {@code false} otherwise
+ */
+ public static boolean isAnonymousFunction(Scope scope) {
+ return scope instanceof FunctionScope
+ && ((FunctionScope) scope).isAnonymous();
+ }
}
diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelVisitor.java b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelVisitor.java
index 90d6a7a..c9e38ae 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelVisitor.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/ModelVisitor.java
@@ -760,9 +760,21 @@ public final class ModelVisitor extends DefaultTreePathVisitor {
return;
}
Scope scope = modelBuilder.getCurrentScope();
+ ASTNodeInfo<Variable> varInfo = ASTNodeInfo.create(node);
+ // NETBEANS-2992
+ // when $this is used in anonymous function, change the current scope
+ if (ModelUtils.isAnonymousFunction(scope)
+ && "$this".equals(varInfo.getName())) { // NOI18N
+ Scope inScope = scope.getInScope();
+ while (!(inScope instanceof MethodScope) && inScope instanceof FunctionScope) {
+ inScope = inScope.getInScope();
+ }
+ if (inScope instanceof MethodScope) {
+ scope = inScope;
+ }
+ }
prepareVariable(node, scope);
if (scope instanceof VariableNameFactory) {
- ASTNodeInfo<Variable> varInfo = ASTNodeInfo.create(node);
if (scope instanceof MethodScope && "$this".equals(varInfo.getName())) { //NOI18N
scope = scope.getInScope();
}
diff --git a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java
index 432dce8..a6dd8c9 100644
--- a/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java
+++ b/php/php.editor/src/org/netbeans/modules/php/editor/model/impl/VariousUtils.java
@@ -593,7 +593,7 @@ public final class VariousUtils {
|| (operation.startsWith(VariousUtils.ARRAY_TYPE_PREFIX))) {
Set<TypeScope> newRecentTypes = new HashSet<>();
String varName = frag;
- VariableName var = ModelUtils.getFirst(varScope.getDeclaredVariables(), varName);
+ VariableName var = getVariableName(varScope, varName);
if (var != null) {
if (i + 2 < len && VariousUtils.FIELD_TYPE_PREFIX.startsWith(fragments[i + 1])) {
fldVarStack.push(var);
@@ -684,6 +684,25 @@ public final class VariousUtils {
return recentTypes;
}
+ @CheckForNull
+ private static VariableName getVariableName(final VariableScope varScope, String varName) {
+ VariableName var = ModelUtils.getFirst(varScope.getDeclaredVariables(), varName);
+ // NETBEANS-2992
+ // when $this is used in anonymous function, check the parent scope
+ if (var == null
+ && ModelUtils.isAnonymousFunction(varScope)
+ && varName.equals("$this")) { // NOI18N
+ Scope inScope = varScope.getInScope();
+ while (ModelUtils.isAnonymousFunction(inScope)) {
+ inScope = inScope.getInScope();
+ }
+ if (inScope instanceof VariableScope) {
+ var = ModelUtils.getFirst(((VariableScope) inScope).getDeclaredVariables(), varName);
+ }
+ }
+ return var;
+ }
+
private static Collection<TypeScope> filterSuperTypes(final Collection<? extends TypeScope> typeScopes) {
final Collection<TypeScope> result = new HashSet<>();
if (typeScopes.size() > 1) {
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php b/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php
new file mode 100644
index 0000000..e6ff4c0
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php
@@ -0,0 +1,70 @@
+<?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 Validator
+{
+ public function validate(\Closure $closure): void
+ {
+ $closure();
+ }
+}
+
+class Test
+{
+ public function testMethod(): void
+ {
+ echo "test" . PHP_EOL;
+ }
+}
+
+class Example
+{
+ /**
+ * @var Validator
+ */
+ private $validator;
+ /**
+ * @var Test
+ */
+ private $test;
+ public function __construct()
+ {
+ $this->validator = new Validator;
+ $this->test = new Test;
+ }
+ public function main(): void
+ {
+ $this->validator->validate(
+ function () {
+ $this->test-> // test1
+ },
+ );
+ $func = function () {
+ $this->test->testMethod(); // test2
+ };
+ $func();
+ // PHP 7.4 Arrow Function
+ $func2 = fn() => $this->test->testMethod(); //test3
+ $func2();
+ }
+
+}
+
+$example = new Example();
+$example->main();
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_01.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_01.completion
new file mode 100644
index 0000000..b7524c9
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_01.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+$this->test->| // test1
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+METHOD testMethod() [PUBLIC] Test
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_02.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_02.completion
new file mode 100644
index 0000000..a244787
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_02.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+$this->test->|testMethod(); // test2
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+METHOD testMethod() [PUBLIC] Test
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_03.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_03.completion
new file mode 100644
index 0000000..3dc5ebf
--- /dev/null
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/nb2992/nb2992.php.testNb2992_03.completion
@@ -0,0 +1,4 @@
+Code completion result for source line:
+$func2 = fn() => $this->test->test|Method(); //test3
+(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
+METHOD testMethod() [PUBLIC] Test
diff --git a/php/php.editor/test/unit/data/testfiles/completion/lib/tests247082/issue247082.php.testForKeywords.completion b/php/php.editor/test/unit/data/testfiles/completion/lib/tests247082/issue247082.php.testForKeywords.completion
index 4114956..408116d 100644
--- a/php/php.editor/test/unit/data/testfiles/completion/lib/tests247082/issue247082.php.testForKeywords.completion
+++ b/php/php.editor/test/unit/data/testfiles/completion/lib/tests247082/issue247082.php.testForKeywords.completion
@@ -3,7 +3,6 @@ echo |self::MY_CONST . PHP_EOL;
(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
CLASS A [PUBLIC] issue247082.php
CLASS ParentA [PUBLIC] issue247082.php
-VARIABLE ? $this [PUBLIC] issue247082.php
VARIABLE ? $val [PUBLIC] issue247082.php
KEYWORD A $this-> null
KEYWORD parent:: null
diff --git a/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletionNb2992Test.java b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletionNb2992Test.java
new file mode 100644
index 0000000..478d6e2
--- /dev/null
+++ b/php/php.editor/test/unit/src/org/netbeans/modules/php/editor/completion/PHPCodeCompletionNb2992Test.java
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+package org.netbeans.modules.php.editor.completion;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.Map;
+import org.netbeans.api.java.classpath.ClassPath;
+import org.netbeans.modules.php.project.api.PhpSourcePath;
+import org.netbeans.spi.java.classpath.support.ClassPathSupport;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+
+
+public class PHPCodeCompletionNb2992Test extends PHPCodeCompletionTestBase {
+
+ public PHPCodeCompletionNb2992Test(String testName) {
+ super(testName);
+ }
+
+ public void testNb2992_01() throws Exception {
+ checkCompletion("testfiles/completion/lib/nb2992/nb2992.php", "$this->test->^ // test1", false);
+ }
+
+ public void testNb2992_02() throws Exception {
+ checkCompletion("testfiles/completion/lib/nb2992/nb2992.php", "$this->test->^testMethod(); // test2", false);
+ }
+
+ public void testNb2992_03() throws Exception {
+ checkCompletion("testfiles/completion/lib/nb2992/nb2992.php", "$func2 = fn() => $this->test->test^Method(); //test3", false);
+ }
+
+ @Override
+ protected Map<String, ClassPath> createClassPathsForTest() {
+ return Collections.singletonMap(
+ PhpSourcePath.SOURCE_CP,
+ ClassPathSupport.createClassPath(new FileObject[] {
+ FileUtil.toFileObject(new File(getDataDir(), "/testfiles/completion/lib/nb2992"))
+ })
+ );
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists