コード例 #1
0
 @Nullable
 private static PsiType getInferredTypes(
     GrReferenceExpressionImpl refExpr, @Nullable PsiElement resolved) {
   final GrExpression qualifier = refExpr.getQualifier();
   if (qualifier == null && !(resolved instanceof PsiClass)) {
     return TypeInferenceHelper.getCurrentContext().getVariableType(refExpr);
   } else if (qualifier != null) {
     // map access
     PsiType qType = qualifier.getType();
     if (qType instanceof PsiClassType && !(qType instanceof GrMapType)) {
       PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
       PsiClass clazz = qResult.getElement();
       if (clazz != null) {
         PsiClass mapClass =
             JavaPsiFacade.getInstance(refExpr.getProject())
                 .findClass(CommonClassNames.JAVA_UTIL_MAP, refExpr.getResolveScope());
         if (mapClass != null && mapClass.getTypeParameters().length == 2) {
           PsiSubstitutor substitutor =
               TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
           if (substitutor != null) {
             return TypeConversionUtil.erasure(
                 substitutor.substitute(mapClass.getTypeParameters()[1]));
           }
         }
       }
     }
   }
   return null;
 }
コード例 #2
0
 @Nullable
 private static PsiType getTypeFromMapAccess(@NotNull GrReferenceExpressionImpl ref) {
   // map access
   GrExpression qualifier = ref.getQualifierExpression();
   if (qualifier != null) {
     PsiType qType = qualifier.getNominalType();
     if (qType instanceof PsiClassType) {
       PsiClassType.ClassResolveResult qResult = ((PsiClassType) qType).resolveGenerics();
       PsiClass clazz = qResult.getElement();
       if (clazz != null) {
         PsiClass mapClass =
             JavaPsiFacade.getInstance(ref.getProject())
                 .findClass(CommonClassNames.JAVA_UTIL_MAP, ref.getResolveScope());
         if (mapClass != null && mapClass.getTypeParameters().length == 2) {
           PsiSubstitutor substitutor =
               TypeConversionUtil.getClassSubstitutor(mapClass, clazz, qResult.getSubstitutor());
           if (substitutor != null) {
             return TypeConversionUtil.erasure(
                 substitutor.substitute(mapClass.getTypeParameters()[1]));
           }
         }
       }
     }
   }
   return null;
 }
コード例 #3
0
 @Nullable
 private static PsiType getTypeFromClassRef(@NotNull GrReferenceExpressionImpl ref) {
   if ("class".equals(ref.getReferenceName())) {
     return TypesUtil.createJavaLangClassType(
         GrReferenceResolveUtil.getQualifierType(ref), ref.getProject(), ref.getResolveScope());
   }
   return null;
 }
コード例 #4
0
 private void getVariantsFromQualifier(@NotNull GrExpression qualifier) {
   Project project = qualifier.getProject();
   PsiType qualifierType = qualifier.getType();
   final ResolveState state = ResolveState.initial();
   if (qualifierType == null || qualifierType == PsiType.VOID) {
     if (qualifier instanceof GrReferenceExpression) {
       PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
       if (resolved instanceof PsiPackage || resolved instanceof PsiVariable) {
         resolved.processDeclarations(myProcessor, state, null, myRefExpr);
         return;
       }
     }
     getVariantsFromQualifierType(TypesUtil.getJavaLangObject(qualifier), project);
   } else if (qualifierType instanceof PsiIntersectionType) {
     for (PsiType conjunct : ((PsiIntersectionType) qualifierType).getConjuncts()) {
       getVariantsFromQualifierType(conjunct, project);
     }
   } else if (qualifierType instanceof GrTraitType) {
     GrTypeDefinition definition = ((GrTraitType) qualifierType).getMockTypeDefinition();
     if (definition != null) {
       PsiClassType classType = JavaPsiFacade.getElementFactory(project).createType(definition);
       getVariantsFromQualifierType(classType, project);
     } else {
       getVariantsFromQualifierType(((GrTraitType) qualifierType).getExprType(), project);
       for (PsiClassType traitType : ((GrTraitType) qualifierType).getTraitTypes()) {
         getVariantsFromQualifierType(traitType, project);
       }
     }
   } else {
     getVariantsFromQualifierType(qualifierType, project);
     if (qualifier instanceof GrReferenceExpression
         && !PsiUtil.isSuperReference(qualifier)
         && !PsiUtil.isInstanceThisRef(qualifier)) {
       PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
       if (resolved instanceof PsiClass) { // //omitted .class
         GlobalSearchScope scope = myRefExpr.getResolveScope();
         PsiClass javaLangClass = PsiUtil.getJavaLangClass(resolved, scope);
         if (javaLangClass != null) {
           PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
           PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
           if (typeParameters.length == 1) {
             substitutor = substitutor.put(typeParameters[0], qualifierType);
           }
           PsiType javaLangClassType =
               JavaPsiFacade.getElementFactory(myRefExpr.getProject())
                   .createType(javaLangClass, substitutor);
           ResolveUtil.processAllDeclarations(javaLangClassType, myProcessor, state, myRefExpr);
         }
       }
     }
   }
 }
コード例 #5
0
 private void processRefInAnnotationImpl() {
   if (myRefExpr.getParent() instanceof GrAnnotationNameValuePair
       && ((GrAnnotationNameValuePair) myRefExpr.getParent()).getNameIdentifierGroovy() == null) {
     PsiElement parent = myRefExpr.getParent().getParent();
     if (!(parent instanceof GrAnnotation)) {
       parent = parent.getParent();
     }
     if (parent instanceof GrAnnotation) {
       new AnnotationAttributeCompletionResultProcessor((GrAnnotation) parent)
           .process(myConsumer, myMatcher);
     }
   }
 }
コード例 #6
0
  @Nullable
  private static PsiType getTypeFromSpreadOperator(@NotNull GrReferenceExpressionImpl ref) {
    if (ref.getDotTokenType() == GroovyTokenTypes.mSPREAD_DOT) {
      return TypesUtil.createType(CommonClassNames.JAVA_UTIL_LIST, ref);
    }

    return null;
  }
コード例 #7
0
  private void processIfJavaLangClass(@Nullable PsiType type) {
    if (!(type instanceof PsiClassType)) return;

    final PsiClass psiClass = ((PsiClassType) type).resolve();
    if (psiClass == null || !CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName()))
      return;

    final PsiType[] params = ((PsiClassType) type).getParameters();
    if (params.length != 1) return;

    getVariantsFromQualifierType(params[0], myRefExpr.getProject());
  }
コード例 #8
0
    @Nullable
    public PsiType fun(GrReferenceExpressionImpl refExpr) {
      PsiType result = GrReassignedLocalVarsChecker.checkReassignedVar(refExpr, true);
      if (result != null) return result;

      if (GrUnresolvedAccessInspection.isClassReference(refExpr)) {
        GrExpression qualifier = refExpr.getQualifier();
        LOG.assertTrue(qualifier != null);
        return TypesUtil.createJavaLangClassType(
            qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope());
      }

      final PsiElement resolved = refExpr.resolve();
      final PsiType inferred = getInferredTypes(refExpr, resolved);
      final PsiType nominal = refExpr.getNominalType();
      if (inferred == null || PsiType.NULL.equals(inferred)) {
        if (nominal == null) {
          // inside nested closure we could still try to infer from variable initializer. Not sound,
          // but makes sense
          if (resolved instanceof GrVariable) {
            LOG.assertTrue(resolved.isValid());
            return ((GrVariable) resolved).getTypeGroovy();
          }
        }

        return nominal;
      }

      if (nominal == null) return inferred;
      if (!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(nominal), inferred, false)) {
        if (resolved instanceof GrVariable
            && ((GrVariable) resolved).getTypeElementGroovy() != null) {
          return nominal;
        }
      }
      return inferred;
    }
コード例 #9
0
  private void getVariantsImpl() {
    GrExpression qualifier = myRefExpr.getQualifierExpression();
    if (qualifier == null) {
      ResolveUtil.treeWalkUp(myRefExpr, myProcessor, true);

      for (PsiElement e = myRefExpr.getParent(); e != null; e = e.getParent()) {
        if (e instanceof GrClosableBlock) {
          ResolveState state = ResolveState.initial().put(ClassHint.RESOLVE_CONTEXT, e);
          for (ClosureMissingMethodContributor contributor :
              ClosureMissingMethodContributor.EP_NAME.getExtensions()) {
            contributor.processMembers((GrClosableBlock) e, myProcessor, myRefExpr, state);
          }
        }
      }

      GrExpression runtimeQualifier = PsiImplUtil.getRuntimeQualifier(myRefExpr);
      if (runtimeQualifier != null) {
        getVariantsFromQualifier(runtimeQualifier);
      }

      getBindings();
    } else {
      if (myRefExpr.getDotTokenType() != GroovyTokenTypes.mSPREAD_DOT) {
        getVariantsFromQualifier(qualifier);

        if (qualifier instanceof GrReferenceExpression
            && ("class".equals(((GrReferenceExpression) qualifier).getReferenceName())
                || PsiUtil.isThisReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier))) {
          processIfJavaLangClass(qualifier.getType());
        }
      } else {
        getVariantsFromQualifierForSpreadOperator(qualifier);
      }
    }
    ResolveUtil.processCategoryMembers(myRefExpr, myProcessor, ResolveState.initial());
  }
コード例 #10
0
  @NotNull
  private Set<String> addAllRestrictedProperties() {
    if (myRefExpr.getQualifier() != null) {
      return Collections.emptySet();
    }

    Set<String> propertyNames = new HashSet<String>();
    for (GrTypeDefinition containingClass =
            PsiTreeUtil.getParentOfType(myRefExpr, GrTypeDefinition.class);
        containingClass != null;
        containingClass = PsiTreeUtil.getParentOfType(containingClass, GrTypeDefinition.class)) {
      for (PsiField field : containingClass.getFields()) {
        propertyNames.add(field.getName());
      }
    }
    return propertyNames;
  }
コード例 #11
0
 @NotNull
 public GroovyResolveResult[] resolve(
     @NotNull GrReferenceExpressionImpl refExpr, boolean incompleteCode) {
   return refExpr.doPolyResolve(incompleteCode, true);
 }
コード例 #12
0
 private void getVariantsFromQualifierForSpreadOperator(@NotNull GrExpression qualifier) {
   final PsiType spreadType = ClosureParameterEnhancer.findTypeForIteration(qualifier, myRefExpr);
   if (spreadType != null) {
     getVariantsFromQualifierType(spreadType, myRefExpr.getProject());
   }
 }
コード例 #13
0
 @Override
 @NotNull
 public GroovyResolveResult[] resolve(
     @NotNull final GrReferenceExpressionImpl refExpr, final boolean incompleteCode) {
   return refExpr.doPolyResolveWithCaching(incompleteCode, true);
 }
コード例 #14
0
  @NotNull
  private GroovyResolveResult[] resolveTypeOrPropertyInner() {
    PsiElement nameElement = getReferenceNameElement();
    String name = getReferenceName();

    if (name == null || nameElement == null) return GroovyResolveResult.EMPTY_ARRAY;

    IElementType nameType = nameElement.getNode().getElementType();
    if (nameType == GroovyTokenTypes.kTHIS) {
      GroovyResolveResult[] results = GrThisReferenceResolver.resolveThisExpression(this);
      if (results != null) {
        return results;
      }
    } else if (nameType == GroovyTokenTypes.kSUPER) {
      GroovyResolveResult[] results = GrSuperReferenceResolver.resolveSuperExpression(this);
      if (results != null) {
        return results;
      }
    }

    EnumSet<ClassHint.ResolveKind> kinds =
        getParent() instanceof GrReferenceExpression
            ? ClassHint.RESOLVE_KINDS_CLASS_PACKAGE
            : ClassHint.RESOLVE_KINDS_CLASS;

    GroovyResolveResult[] classCandidates = null;

    GrReferenceResolveRunner resolveRunner = new GrReferenceResolveRunner(this);

    ResolverProcessor processor = new PropertyResolverProcessor(name, this);
    resolveRunner.resolveImpl(processor);
    final GroovyResolveResult[] fieldCandidates = processor.getCandidates();

    if (hasAt()) {
      return fieldCandidates;
    }

    boolean canBeClassOrPackage = ResolveUtil.canBeClassOrPackage(this);

    if (canBeClassOrPackage && findClassOrPackageAtFirst()) {
      ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds);
      resolveRunner.resolveImpl(classProcessor);
      classCandidates = classProcessor.getCandidates();
      if (classCandidates.length > 0 && containsPackage(classCandidates)) {
        final PsiElement firstNonReferenceExprParent =
            PsiTreeUtil.skipParentsOfType(this, GrReferenceExpressionImpl.class);
        final GrReferenceExpressionImpl topRef =
            (GrReferenceExpressionImpl)
                PsiTreeUtil.findFirstParent(
                    this,
                    new Condition<PsiElement>() {
                      @Override
                      public boolean value(PsiElement parent) {
                        return parent.getParent() == firstNonReferenceExprParent
                            && parent instanceof GrReferenceExpressionImpl;
                      }
                    });
        if (topRef != null) {
          final String fqn = topRef.getTextSkipWhiteSpaceAndComments();
          if (JavaPsiFacade.getInstance(getProject()).findClass(fqn, getResolveScope()) != null) {
            return classCandidates;
          }
        }
      }
    }

    // if reference expression is in class we need to return field instead of accessor method
    for (GroovyResolveResult candidate : fieldCandidates) {
      final PsiElement element = candidate.getElement();
      if (element instanceof PsiField) {
        final PsiClass containingClass = ((PsiField) element).getContainingClass();
        if (containingClass != null && PsiUtil.getContextClass(this) == containingClass)
          return fieldCandidates;
      } else if (!(element instanceof GrBindingVariable)) {
        return fieldCandidates;
      }
    }

    if (classCandidates != null && classCandidates.length > 0) return classCandidates;

    final boolean isLValue = PsiUtil.isLValue(this);
    String[] accessorNames =
        isLValue
            ? GroovyPropertyUtils.suggestSettersName(name)
            : GroovyPropertyUtils.suggestGettersName(name);
    List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
    for (String accessorName : accessorNames) {
      AccessorResolverProcessor accessorResolver =
          new AccessorResolverProcessor(
              accessorName,
              name,
              this,
              !isLValue,
              false,
              PsiImplUtil.getQualifierType(this),
              getTypeArguments());
      resolveRunner.resolveImpl(accessorResolver);
      final GroovyResolveResult[] candidates = accessorResolver.getCandidates();

      // can be only one correct candidate or some incorrect
      if (candidates.length == 1 && candidates[0].isStaticsOK() && candidates[0].isAccessible()) {
        return candidates;
      } else {
        ContainerUtil.addAll(accessorResults, candidates);
      }
    }

    final ArrayList<GroovyResolveResult> fieldList = ContainerUtil.newArrayList(fieldCandidates);
    filterOutBindings(fieldList);
    if (!fieldList.isEmpty()) {
      return fieldList.toArray(new GroovyResolveResult[fieldList.size()]);
    }

    if (classCandidates == null && canBeClassOrPackage) {
      ResolverProcessor classProcessor = new ClassResolverProcessor(name, this, kinds);
      resolveRunner.resolveImpl(classProcessor);
      classCandidates = classProcessor.getCandidates();
    }

    if (classCandidates != null && classCandidates.length > 0) return classCandidates;
    if (!accessorResults.isEmpty()) return new GroovyResolveResult[] {accessorResults.get(0)};
    return GroovyResolveResult.EMPTY_ARRAY;
  }