Skip to content

Commit

Permalink
Merge pull request #6911 from junichi11/php-named-argument-cc-for-con…
Browse files Browse the repository at this point in the history
…structor

Fix the named argument code completion for constructors
  • Loading branch information
junichi11 committed Jan 4, 2024
2 parents 561522e + 24ba6df commit d81235c
Show file tree
Hide file tree
Showing 22 changed files with 888 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ public static enum CompletionContext {
HTML, CLASS_NAME, INTERFACE_NAME, BACKING_TYPE,
TYPE_NAME, RETURN_TYPE_NAME, RETURN_UNION_OR_INTERSECTION_TYPE_NAME, FIELD_TYPE_NAME, CONST_TYPE_NAME, VISIBILITY_MODIFIER_OR_TYPE_NAME, STRING,
CLASS_MEMBER, STATIC_CLASS_MEMBER, PHPDOC, INHERITANCE, EXTENDS, IMPLEMENTS, METHOD_NAME,
CLASS_MEMBER_PARAMETER_NAME, STATIC_CLASS_MEMBER_PARAMETER_NAME, FUNCTION_PARAMETER_NAME,
CLASS_MEMBER_PARAMETER_NAME, STATIC_CLASS_MEMBER_PARAMETER_NAME, FUNCTION_PARAMETER_NAME, CONSTRUCTOR_PARAMETER_NAME,
CLASS_CONTEXT_KEYWORDS, SERVER_ENTRY_CONSTANTS, NONE, NEW_CLASS, GLOBAL, NAMESPACE_KEYWORD,
GROUP_USE_KEYWORD, GROUP_USE_CONST_KEYWORD, GROUP_USE_FUNCTION_KEYWORD,
USE_KEYWORD, USE_CONST_KEYWORD, USE_FUNCTION_KEYWORD, DEFAULT_PARAMETER_VALUE, OPEN_TAG, THROW, THROW_NEW, CATCH, CLASS_MEMBER_IN_STRING,
Expand Down Expand Up @@ -1608,6 +1608,8 @@ private static CompletionContext getNamedArgumentsContext(final int caretOffset,
retval = CompletionContext.CLASS_MEMBER_PARAMETER_NAME;
} else if (acceptTokenChains(ts, STATIC_CLASS_MEMBER_TOKENCHAINS, true)) {
retval = CompletionContext.STATIC_CLASS_MEMBER_PARAMETER_NAME;
} else if (acceptTokenChains(ts, CLASS_NAME_TOKENCHAINS, true)) {
retval = CompletionContext.CONSTRUCTOR_PARAMETER_NAME;
} else {
retval = CompletionContext.FUNCTION_PARAMETER_NAME;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport;
import org.netbeans.modules.parsing.spi.indexing.support.QuerySupport.Kind;
import org.netbeans.modules.php.api.PhpVersion;
import org.netbeans.modules.php.api.util.StringUtils;
import org.netbeans.modules.php.editor.CodeUtils;
import org.netbeans.modules.php.editor.NavUtils;
import org.netbeans.modules.php.editor.PredefinedSymbols;
Expand Down Expand Up @@ -432,6 +433,10 @@ public CodeCompletionResult complete(CodeCompletionContext completionContext) {
case EXPRESSION:
autoCompleteExpression(completionResult, request);
break;
case CONSTRUCTOR_PARAMETER_NAME:
autoCompleteExpression(completionResult, request);
autoCompleteConstructorParameterName(completionResult, request);
break;
case CLASS_MEMBER_PARAMETER_NAME:
autoCompleteExpression(completionResult, request);
autoCompleteClassMethodParameterName(completionResult, request, false);
Expand Down Expand Up @@ -1604,6 +1609,32 @@ public boolean isAccepted(PhpElement element) {
}
}

private void autoCompleteConstructorParameterName(final PHPCompletionResult completionResult, final PHPCompletionItem.CompletionRequest request) {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
TokenHierarchy<?> th = request.info.getSnapshot().getTokenHierarchy();
TokenSequence<PHPTokenId> tokenSequence = LexUtilities.getPHPTokenSequence(th, request.anchor);
if (tokenSequence == null) {
return;
}
Token<? extends PHPTokenId> constructorTypeName = CompletionContextFinder.findFunctionInvocationName(tokenSequence, request.anchor);
if (constructorTypeName != null) {
Model model = request.result.getModel();
NamespaceScope namespaceScope = ModelUtils.getNamespaceScope(model.getFileScope(), request.anchor);
String fqTypeName = VariousUtils.qualifyTypeNames(constructorTypeName.text().toString(), request.anchor, namespaceScope);
Set<AliasedName> aliasedNames = ModelUtils.getAliasedNames(model, request.anchor);
Set<MethodElement> constructors = request.index.getConstructors(NameKind.exact(fqTypeName), aliasedNames, Trait.ALIAS);
Set<String> duplicateCheck = new HashSet<>();
for (MethodElement constructor : constructors) {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
addParameterNameItems(completionResult, request, constructor.getParameters(), duplicateCheck);
}
}
}

private void autoCompleteClassMethodParameterName(
final PHPCompletionResult completionResult,
PHPCompletionItem.CompletionRequest request,
Expand Down Expand Up @@ -1685,26 +1716,15 @@ private void autoCompleteClassMethodParameterName(
accessibleTypeMembers.addAll(request.index.getAccessibleMixinTypeMembers(typeScope, enclosingType));
}
}
Set<String> duplicateCheck = new HashSet<>();
for (final PhpElement phpElement : accessibleTypeMembers) {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
if (duplicateElementCheck.add(phpElement)) {
if (methodsFilter.isAccepted(phpElement)) {
MethodElement method = (MethodElement) phpElement;
for (ParameterElement parameter : method.getParameters()) {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
String name = parameter.getName();
if (name != null) {
name = name.substring(1);
}
if (name != null
&& name.startsWith(request.prefix)) {
completionResult.add(new PHPCompletionItem.ParameterNameItem(parameter, request));
}
}
addParameterNameItems(completionResult, request, method.getParameters(), duplicateCheck);
}
}
}
Expand Down Expand Up @@ -1739,25 +1759,30 @@ private void autoCompleteFunctionParameterName(final PHPCompletionResult complet
if (functionElement.isAnonymous()) {
continue;
}
for (ParameterElement parameter : functionElement.getParameters()) {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
String name = parameter.getName();
if (name != null) {
name = name.substring(1);
}
if (name != null
&& name.startsWith(request.prefix)
&& duplicateCheck.add(name)) {
completionResult.add(new PHPCompletionItem.ParameterNameItem(parameter, request));
}
}
addParameterNameItems(completionResult, request, functionElement.getParameters(), duplicateCheck);
}
}
}
}

private void addParameterNameItems(final PHPCompletionResult completionResult, final PHPCompletionItem.CompletionRequest request,
List<ParameterElement> parameters, Set<String> duplicateCheck) {
for (ParameterElement parameter : parameters) {
if (CancelSupport.getDefault().isCancelled()) {
return;
}
String name = parameter.getName();
if (!StringUtils.isEmpty(name)) {
name = name.substring(1);
}
if (!StringUtils.isEmpty(name)
&& name.startsWith(request.prefix)
&& duplicateCheck.add(name)) {
completionResult.add(new PHPCompletionItem.ParameterNameItem(parameter, request));
}
}
}

private void autoCompleteClassConstants(final PHPCompletionResult completionResult, final PHPCompletionItem.CompletionRequest request) {
// NETBANS-1855
// complete access prefix i.e. add "self::" to the top of constant names
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,31 @@ public String getRhsHtml(HtmlFormatter formatter) {
return null;
}

public static boolean insertOnlyParameterName(CompletionRequest request) {
boolean result = false;
TokenHierarchy<?> tokenHierarchy = request.result.getSnapshot().getTokenHierarchy();
TokenSequence<PHPTokenId> tokenSequence = (TokenSequence<PHPTokenId>) tokenHierarchy.tokenSequence();
if (tokenSequence != null) {
tokenSequence.move(request.anchor);
// na^me: -> only parameter name
// n^ age: -> add also ":"
while (tokenSequence.moveNext()) {
Token<PHPTokenId> token = tokenSequence.token();
PHPTokenId id = token.id();
if (id == PHPTokenId.PHP_STRING) {
continue;
}
if (id == PHPTokenId.PHP_TOKEN
&& TokenUtilities.textEquals(token.text(), ":")) { // NOI18N
result = true;
break;
}
break;
}
}
return result;
}

public static boolean insertOnlyMethodsName(CompletionRequest request) {
if (request.insertOnlyMethodsName != null) {
return request.insertOnlyMethodsName;
Expand Down Expand Up @@ -2048,7 +2073,11 @@ public ParameterNameItem(ParameterElement parameterElement, CompletionRequest re

@Override
public String getName() {
return parameterElement.getName().substring(1) + ":"; // NOI18N
return getParameterName() + ":"; // NOI18N
}

private String getParameterName() {
return parameterElement.getName().substring(1);
}

@Override
Expand Down Expand Up @@ -2091,6 +2120,12 @@ public String getInsertPrefix() {

@Override
public String getCustomInsertTemplate() {
if (insertOnlyParameterName(request)) {
// ^maxLength: (^: caret)
// we are unsure whether a user expects to add or override an item in this context
// so, just add a name (i.e. don't add ":")
return getParameterName();
}
return getName() + " "; // NOI18N
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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 NamedArguments {
public function __construct(int $param1, int|array|null $array, $default = "default") {
}
}

$instance = new NamedArguments();
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
Code completion result for source line:
$instance = new NamedArguments(|);
(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
CLASS NamedArguments [PUBLIC] namedArgumentsConstructor01.php
VARIABLE NamedArguments $instance [PUBLIC] namedArgumentsConstructor01.php
PARAMETER array: Parameter Name
PARAMETER default: Parameter Name
PARAMETER param1: Parameter Name
------------------------------------
VARIABLE $GLOBALS PHP Platform
VARIABLE $HTTP_RAW_POST_DATA PHP Platform
VARIABLE $_COOKIE PHP Platform
VARIABLE $_ENV PHP Platform
VARIABLE $_FILES PHP Platform
VARIABLE $_GET PHP Platform
VARIABLE $_POST PHP Platform
VARIABLE $_REQUEST PHP Platform
VARIABLE $_SERVER PHP Platform
VARIABLE $_SESSION PHP Platform
VARIABLE $argc PHP Platform
VARIABLE $argv PHP Platform
VARIABLE $http_response_header PHP Platform
VARIABLE $php_errormsg PHP Platform
KEYWORD abstract null
KEYWORD and null
KEYWORD array null
KEYWORD as null
KEYWORD break null
KEYWORD case null
KEYWORD catch null
KEYWORD class null
KEYWORD clone null
KEYWORD const null
KEYWORD continue null
KEYWORD declare null
KEYWORD default null
KEYWORD die() Language Construct
KEYWORD do null
KEYWORD echo ''; Language Construct
KEYWORD else null
KEYWORD elseif null
KEYWORD empty() Language Construct
KEYWORD enddeclare null
KEYWORD endfor null
KEYWORD endforeach null
KEYWORD endif null
KEYWORD endswitch null
KEYWORD endwhile null
KEYWORD enum null
KEYWORD eval() Language Construct
KEYWORD exit() Language Construct
KEYWORD extends null
KEYWORD final null
KEYWORD finally null
KEYWORD fn null
KEYWORD for null
KEYWORD foreach null
KEYWORD function null
KEYWORD global null
KEYWORD goto null
KEYWORD if null
KEYWORD implements null
KEYWORD include ''; Language Construct
KEYWORD include_once ''; Language Construct
KEYWORD instanceof null
KEYWORD interface null
KEYWORD isset() Language Construct
KEYWORD list() Language Construct
KEYWORD match null
KEYWORD namespace null
KEYWORD new null
KEYWORD or null
KEYWORD print ''; Language Construct
KEYWORD private null
KEYWORD protected null
KEYWORD public null
KEYWORD readonly null
KEYWORD require ''; Language Construct
KEYWORD require_once ''; Language Construct
KEYWORD return ; Language Construct
KEYWORD static null
KEYWORD switch null
KEYWORD throw null
KEYWORD trait null
KEYWORD try null
KEYWORD unset() Language Construct
KEYWORD use null
KEYWORD var null
KEYWORD while null
KEYWORD xor null
KEYWORD yield null
KEYWORD yield from null
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?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 NamedArguments {
public function __construct(int $param1, int|array|null $array, $default = "default") {
}
}

$instance = new NamedArguments(arr);
$instance = new NamedArguments()
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Code completion result for source line:
$instance = new NamedArguments(arr|);
(QueryType=COMPLETION, prefixSearch=true, caseSensitive=true)
PARAMETER array: Parameter Name
------------------------------------
KEYWORD array null

0 comments on commit d81235c

Please sign in to comment.