Exemple #1
0
  @Nullable
  public static LookupElementBuilder createPropertyLookupElement(
      @NotNull PsiMethod accessor,
      @Nullable GroovyResolveResult resolveResult,
      @Nullable PrefixMatcher matcher) {
    String propName;
    PsiType propType;
    final boolean getter = GroovyPropertyUtils.isSimplePropertyGetter(accessor, null);
    if (getter) {
      propName = GroovyPropertyUtils.getPropertyNameByGetter(accessor);
    } else if (GroovyPropertyUtils.isSimplePropertySetter(accessor, null)) {
      propName = GroovyPropertyUtils.getPropertyNameBySetter(accessor);
    } else {
      return null;
    }
    assert propName != null;
    if (!PsiUtil.isValidReferenceName(propName)) {
      propName = "'" + propName + "'";
    }

    if (matcher != null && !matcher.prefixMatches(propName)) {
      return null;
    }

    if (getter) {
      propType = PsiUtil.getSmartReturnType(accessor);
    } else {
      propType = accessor.getParameterList().getParameters()[0].getType();
    }

    final PsiType substituted =
        resolveResult != null ? resolveResult.getSubstitutor().substitute(propType) : propType;

    LookupElementBuilder builder =
        LookupElementBuilder.create(
                generatePropertyResolveResult(propName, accessor, propType, resolveResult),
                propName)
            .withIcon(JetgroovyIcons.Groovy.Property);
    if (substituted != null) {
      builder = builder.withTypeText(substituted.getPresentableText());
    }
    return builder;
  }
  @Nullable
  private PsiType getNominalTypeInner(PsiElement resolved) {
    if (resolved == null && !"class".equals(getReferenceName())) {
      resolved = resolve();
    }

    if (resolved instanceof PsiClass) {
      final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
      if (PsiUtil.isInstanceThisRef(this)) {
        final PsiClassType categoryType = GdkMethodUtil.getCategoryType((PsiClass) resolved);
        if (categoryType != null) {
          return categoryType;
        } else {
          return factory.createType((PsiClass) resolved);
        }
      }
      if (getParent() instanceof GrReferenceExpression || PsiUtil.isSuperReference(this)) {
        return factory.createType((PsiClass) resolved);
      } else {
        return TypesUtil.createJavaLangClassType(
            factory.createType((PsiClass) resolved), getProject(), getResolveScope());
      }
    }

    if (resolved instanceof GrVariable) {
      return ((GrVariable) resolved).getDeclaredType();
    }

    if (resolved instanceof PsiVariable) {
      return ((PsiVariable) resolved).getType();
    }

    if (resolved instanceof PsiMethod) {
      PsiMethod method = (PsiMethod) resolved;
      if (PropertyUtil.isSimplePropertySetter(method)
          && !method.getName().equals(getReferenceName())) {
        return method.getParameterList().getParameters()[0].getType();
      }

      // 'class' property with explicit generic
      PsiClass containingClass = method.getContainingClass();
      if (containingClass != null
          && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())
          && "getClass".equals(method.getName())) {
        return TypesUtil.createJavaLangClassType(
            GrReferenceResolveUtil.getQualifierType(this), getProject(), getResolveScope());
      }

      return PsiUtil.getSmartReturnType(method);
    }

    if (resolved instanceof GrReferenceExpression) {
      PsiElement parent = resolved.getParent();
      if (parent instanceof GrAssignmentExpression) {
        GrAssignmentExpression assignment = (GrAssignmentExpression) parent;
        if (resolved.equals(assignment.getLValue())) {
          GrExpression rValue = assignment.getRValue();
          if (rValue != null) {
            PsiType rType = rValue.getType();
            if (rType != null) {
              return rType;
            }
          }
        }
      }
    }

    if (resolved == null) {
      final PsiType fromClassRef = getTypeFromClassRef(this);
      if (fromClassRef != null) {
        return fromClassRef;
      }

      final PsiType fromMapAccess = getTypeFromMapAccess(this);
      if (fromMapAccess != null) {
        return fromMapAccess;
      }

      final PsiType fromSpreadOperator = getTypeFromSpreadOperator(this);
      if (fromSpreadOperator != null) {
        return fromSpreadOperator;
      }
    }

    return null;
  }
  @Override
  @Nullable
  public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
    if (element instanceof GrVariable || element instanceof GrImplicitVariable) {
      StringBuilder buffer = new StringBuilder();
      PsiVariable variable = (PsiVariable) element;

      if (originalElement instanceof GrVariableDeclaration
          && ((GrVariableDeclaration) originalElement).getVariables().length > 1) {
        for (GrVariable var : ((GrVariableDeclaration) originalElement).getVariables()) {
          generateVariableInfo(originalElement, buffer, var);
          buffer.append("\n\n");
        }
      } else {
        generateVariableInfo(originalElement, buffer, variable);
      }
      return buffer.toString();
    } else if (element instanceof PsiMethod) {
      StringBuilder buffer = new StringBuilder();
      PsiMethod method = (PsiMethod) element;
      if (method instanceof GrGdkMethod) {
        buffer.append("[GDK] ");
      } else {
        PsiClass hisClass = method.getContainingClass();
        if (hisClass != null) {
          String qName = hisClass.getQualifiedName();
          if (qName != null) {
            buffer.append(qName).append("\n");
          }
        }
      }

      PsiSubstitutor substitutor = calcSubstitutor(originalElement);
      if (!method.isConstructor()) {
        final PsiType substituted = substitutor.substitute(PsiUtil.getSmartReturnType(method));
        PsiImplUtil.appendTypeString(buffer, substituted, originalElement);
        buffer.append(" ");
      }
      buffer.append(method.getName()).append(" ");
      buffer.append("(");
      PsiParameter[] parameters = method.getParameterList().getParameters();
      for (int i = 0; i < parameters.length; i++) {
        PsiParameter parameter = parameters[i];
        if (i > 0) buffer.append(", ");
        if (parameter instanceof GrParameter) {
          GroovyPresentationUtil.appendParameterPresentation(
              (GrParameter) parameter, substitutor, TypePresentation.LINK, buffer);
        } else {
          PsiType type = parameter.getType();
          PsiImplUtil.appendTypeString(buffer, substitutor.substitute(type), originalElement);
          buffer.append(" ");
          buffer.append(parameter.getName());
        }
      }
      buffer.append(")");
      final PsiClassType[] referencedTypes = method.getThrowsList().getReferencedTypes();
      if (referencedTypes.length > 0) {
        buffer.append("\nthrows ");
        for (PsiClassType referencedType : referencedTypes) {
          PsiImplUtil.appendTypeString(buffer, referencedType, originalElement);
          buffer.append(", ");
        }
        buffer.delete(buffer.length() - 2, buffer.length());
      }
      return buffer.toString();
    } else if (element instanceof GrTypeDefinition) {
      return generateClassInfo((GrTypeDefinition) element);
    }

    return null;
  }
  @Nullable
  private PsiType getNominalTypeInner(@Nullable PsiElement resolved) {
    if (resolved == null && !"class".equals(getReferenceName())) {
      resolved = resolve();
    }

    if (resolved instanceof PsiClass) {
      final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
      if (PsiUtil.isInstanceThisRef(this)) {
        final PsiClassType categoryType = GdkMethodUtil.getCategoryType((PsiClass) resolved);
        if (categoryType != null) {
          return categoryType;
        } else {
          return factory.createType((PsiClass) resolved);
        }
      } else if (PsiUtil.isSuperReference(this)) {
        PsiClass contextClass = PsiUtil.getContextClass(this);
        if (GrTraitUtil.isTrait(contextClass)) {
          PsiClassType[] extendsTypes = contextClass.getExtendsListTypes();
          PsiClassType[] implementsTypes = contextClass.getImplementsListTypes();

          PsiClassType[] superTypes =
              ArrayUtil.mergeArrays(implementsTypes, extendsTypes, PsiClassType.ARRAY_FACTORY);

          return PsiIntersectionType.createIntersection(ArrayUtil.reverseArray(superTypes));
        }
        return factory.createType((PsiClass) resolved);
      }
      if (getParent() instanceof GrReferenceExpression) {
        return factory.createType((PsiClass) resolved);
      } else {
        return TypesUtil.createJavaLangClassType(
            factory.createType((PsiClass) resolved), getProject(), getResolveScope());
      }
    }

    if (resolved instanceof GrVariable) {
      return ((GrVariable) resolved).getDeclaredType();
    }

    if (resolved instanceof PsiVariable) {
      return ((PsiVariable) resolved).getType();
    }

    if (resolved instanceof PsiMethod) {
      PsiMethod method = (PsiMethod) resolved;
      if (PropertyUtil.isSimplePropertySetter(method)
          && !method.getName().equals(getReferenceName())) {
        return method.getParameterList().getParameters()[0].getType();
      }

      // 'class' property with explicit generic
      PsiClass containingClass = method.getContainingClass();
      if (containingClass != null
          && CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName())
          && "getClass".equals(method.getName())) {
        return TypesUtil.createJavaLangClassType(
            PsiImplUtil.getQualifierType(this), getProject(), getResolveScope());
      }

      return PsiUtil.getSmartReturnType(method);
    }

    if (resolved == null) {
      final PsiType fromClassRef = getTypeFromClassRef(this);
      if (fromClassRef != null) {
        return fromClassRef;
      }

      final PsiType fromMapAccess = getTypeFromMapAccess(this);
      if (fromMapAccess != null) {
        return fromMapAccess;
      }

      final PsiType fromSpreadOperator = getTypeFromSpreadOperator(this);
      if (fromSpreadOperator != null) {
        return fromSpreadOperator;
      }
    }

    return null;
  }