I do not get the correct Returntype for the PHP method?

Answered

I'm developing a plugin for IntelliJ PHPStorm, and I'm trying to extract every method from a PHP class in a PsiFile along with their return types. However, I'm encountering an issue where the return type is not correctly identified.


Here is an example method from my PHP class:

/**
 * Constrain the query to the next "page" of results after a given ID.
 *
 * @param  int  $perPage
 * @param  int|null  $lastId
 * @param  string  $column
 * @return $this
 */
public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id')
{
      $this->orders = $this->removeExistingOrdersFor($column);
      if (!is_null($lastId)) {
         $this->where($column, '>', $lastId);
      }
      return $this->orderBy($column, 'asc')->limit($perPage);
}



   /**
     * Increment the given column's values by the given amounts.
     *
     * @param  array<string, float|int|numeric-string>  $columns
     * @param  array<string, mixed>  $extra
     * @return int
     *
     * @throws \InvalidArgumentException
     */
    public function incrementEach(array $columns, array $extra = [])
    {
        return $this->update(array_merge($columns, $extra));
    }

 

As a result I get this

* @see \Illuminate\Database\Query\Builder::forPageAfterId
* @method static #S\Illuminate\Database\Query\Builder|? forPageAfterId(int $perPage = 15, int|null $lastId= 0, string $column = 'id') 



or this
* @see \Illuminate\Database\Query\Builder::incrementEach
* @method static int incrementEach(#o#?#A#M#C\Illuminate\Database\Query\Builder.incrementEach.0|#?\string|#?numeric-string[]|float[]|int[]|? $columns, #o#?#A#M#C\Illuminate\Database\Query\Builder.incrementEach.1|#?\string|mixed[]|? $extra = [])

This is incorrect because the return type should be $this or \Illuminate\Database\Query\Builder

In the second example, the return type for the  $columns parameter should be an array, but it's displayed as #o#?#A#M#C\Illuminate\Database\Query\Builder.incrementEach.0|#?\string|#?numeric-string[]|float[]|int[]|?

Does anyone know why this is happening and how to extract the return type correctly?


this is my code:

 public static List<Method> loadMethods(PsiFile facadeFile) {

        List<Method> methods = new ArrayList<>();
        PhpClass phpClass = PsiTreeUtil.findChildOfType(facadeFile, PhpClass.class);

        if (phpClass != null) {
            for (com.jetbrains.php.lang.psi.elements.Method actualMethod : phpClass.getOwnMethods()) {
                Method method = extractMethodInfo(actualMethod);
                if (method.getName() != null) {
                    methods.add(method);
                }
            }
        }
        return methods;
    }

    private static Method extractMethodInfo(com.jetbrains.php.lang.psi.elements.Method actualMethod) {
        Method method = new Method();
        if (actualMethod.getAccess().isPublic()) {
            method.setName(actualMethod.getName());
            method.setReference(
                    Objects.requireNonNull(actualMethod.getContainingClass()).getFQN()
            );
            getMethodInfo(method, actualMethod);
        }
        return method;
    }

    private static void getMethodInfo(Method method, com.jetbrains.php.lang.psi.elements.Method actualMethod) {
        String returnType = actualMethod.getType().toStringResolved();
        if (returnType.startsWith("#S")) {
            returnType = returnType.substring(2);
        }
        method.setReturnType(returnType);

        for (Parameter param : actualMethod.getParameters()) {
            if (param.getDefaultValue() != null) {
                method.addParameter(
                        param.getName(),
                        param.getType().toString(),
                        Objects.requireNonNull(
                                param.getDefaultValue()
                        ).getText()
                );
            }
            else {
                method.addParameter(
                        param.getName(),
                        param.getType().toString(),
                        ""
                );
            }
        }
    }
0
2 comments

Hi javanoob ! The correct way of working with types in PhpStorm plugins is usually by calling getType().global(project) . Please try it and come back if you need further help!

0

Artemy Pestretsov  Hi thx for your help. 
Your solution worked but now I'm encountering a different issue. The return type for the $columns parameter is incorrect. It should be an array, but it's showing up as float[]|int[]|string[]. Am I missing something or is there another way to address this?

my updated code:

    private void getMethodInfo(Method method, com.jetbrains.php.lang.psi.elements.Method actualMethod) {
        method.setReturnType(
                actualMethod.getType().global(this.project).toString()
        );

        for (Parameter param : actualMethod.getParameters()) {
         String defaultValue = param.getDefaultValue() != null ? param.getDefaultValue().getText() : "";
         method.addParameter(
                 param.getName(),
                 param.getType().global(this.project).toString(),
                 defaultValue
         );
        }
    }

 

The actual PHP methods:

   /**
     * Increment the given column's values by the given amounts.
     *
     * @param  array<string, float|int|numeric-string>  $columns
     * @param  array<string, mixed>  $extra
     * @return int
     *
     * @throws \InvalidArgumentException
     */
    public function incrementEach(array $columns, array $extra = [])
    {
        return $this->update(array_merge($columns, $extra));
    }
    
    
    
    
      /**
     * Add an "or where" clause to the query for multiple columns with "and" conditions between them.
     *
     * @param  string[]  $columns
     * @param  string  $operator
     * @param  mixed  $value
     * @return $this
     */
    public function orWhereAll($columns, $operator = null, $value = null)
    {
        return $this->whereAll($columns, $operator, $value, 'or');
    }
    
    

 

The result;

   * @see \Illuminate\Database\Query\Builder::incrementEach
   * @method static int incrementEach(float[]|int[]|string[] $columns, mixed[] $extra = [])
   
   
   
  
   
   
   * @see \Illuminate\Database\Query\Builder::orWhereAll
   * @method static \Illuminate\Database\Query\Builder orWhereAll(string[] $columns, null|string $operat  or = null, mixed $value = null)
0

Please sign in to leave a comment.