@Override
 public PsiType resolve(PsiDocTag psiDocTag) {
   PsiDocTagValue value = psiDocTag.getValueElement();
   if (value != null) {
     String exceptionName = value.getText();
     if (exceptionName != null) {
       PsiClass psiClass = javaPsiFacade.findClass(exceptionName, globalSearchScope);
       if (psiClass != null) {
         return elementFactory.createType(psiClass);
       } else {
         PsiClass[] classesByName =
             shortNamesCache.getClassesByName(exceptionName, globalSearchScope);
         PsiClass encapsulatingClass = PsiTreeUtil.getParentOfType(psiDocTag, PsiClass.class);
         if (encapsulatingClass != null && classesByName.length > 0) {
           String packageName =
               ClassUtil.extractPackageName(encapsulatingClass.getQualifiedName());
           PsiClass closestClass =
               PsiClassSelector.selectClassByPackage(packageName, classesByName);
           return elementFactory.createType(closestClass);
         }
         logger.log(Level.WARNING, "No classes found with name: " + exceptionName);
       }
     }
   }
   return null;
 }
  private PsiClassType createEnumType() {
    JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
    PsiClass enumClass = facade.findClass(JAVA_LANG_ENUM, getResolveScope());
    PsiElementFactory factory = facade.getElementFactory();
    if (enumClass != null) {
      PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
      PsiTypeParameter[] typeParameters = enumClass.getTypeParameters();
      if (typeParameters.length == 1) {
        substitutor = substitutor.put(typeParameters[0], factory.createType(this));
      }

      return factory.createType(enumClass, substitutor);
    }
    return TypesUtil.createTypeByFQClassName(JAVA_LANG_ENUM, this);
  }
  public static PsiType eliminateWildcards(PsiType type, final boolean eliminateInTypeArguments) {
    if (eliminateInTypeArguments && type instanceof PsiClassType) {
      PsiClassType classType = (PsiClassType) type;
      JavaResolveResult resolveResult = classType.resolveGenerics();
      PsiClass aClass = (PsiClass) resolveResult.getElement();
      if (aClass != null) {
        PsiManager manager = aClass.getManager();
        PsiTypeParameter[] typeParams = aClass.getTypeParameters();
        Map<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
        for (PsiTypeParameter typeParam : typeParams) {
          PsiType substituted = resolveResult.getSubstitutor().substitute(typeParam);
          if (substituted instanceof PsiWildcardType) {
            substituted = ((PsiWildcardType) substituted).getBound();
            if (substituted == null)
              substituted = TypeConversionUtil.typeParameterErasure(typeParam);
          }
          map.put(typeParam, substituted);
        }

        PsiElementFactory factory =
            JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
        PsiSubstitutor substitutor = factory.createSubstitutor(map);
        type = factory.createType(aClass, substitutor);
      }
    } else if (type instanceof PsiArrayType) {
      return eliminateWildcards(((PsiArrayType) type).getComponentType(), false).createArrayType();
    } else if (type instanceof PsiWildcardType) {
      final PsiType bound = ((PsiWildcardType) type).getBound();
      return bound != null ? bound : ((PsiWildcardType) type).getExtendsBound(); // object
    } else if (type instanceof PsiCapturedWildcardType && !eliminateInTypeArguments) {
      return eliminateWildcards(
          ((PsiCapturedWildcardType) type).getWildcard(), eliminateInTypeArguments);
    }
    return type;
  }
 @NotNull
 @Override
 public PsiClassType rawType() {
   PsiClass psiClass = resolve();
   PsiElementFactory factory = JavaPsiFacade.getElementFactory(psiClass.getProject());
   return factory.createType(psiClass, factory.createRawSubstitutor(psiClass));
 }
 private static boolean isIndexOfCall(@NotNull PsiMethodCallExpression expression) {
   final PsiReferenceExpression methodExpression = expression.getMethodExpression();
   final String methodName = methodExpression.getReferenceName();
   if (!HardcodedMethodConstants.INDEX_OF.equals(methodName)) {
     return false;
   }
   final PsiExpressionList argumentList = expression.getArgumentList();
   final PsiExpression[] arguments = argumentList.getExpressions();
   if (arguments.length != 1) {
     return false;
   }
   final PsiExpression qualifier = methodExpression.getQualifierExpression();
   if (qualifier == null) {
     return false;
   }
   final PsiType qualifierType = qualifier.getType();
   if (qualifierType == null) {
     return false;
   }
   final Project project = expression.getProject();
   final GlobalSearchScope projectScope = GlobalSearchScope.allScope(project);
   final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
   final PsiClass javaUtilListClass =
       psiFacade.findClass(CommonClassNames.JAVA_UTIL_LIST, projectScope);
   if (javaUtilListClass == null) {
     return false;
   }
   final PsiElementFactory factory = psiFacade.getElementFactory();
   final PsiClassType javaUtilListType = factory.createType(javaUtilListClass);
   return javaUtilListType.isAssignableFrom(qualifierType);
 }
 private static PsiType genNewListBy(PsiType genericOwner, PsiManager manager) {
   PsiClass list =
       JavaPsiFacade.getInstance(manager.getProject())
           .findClass(JAVA_UTIL_LIST, genericOwner.getResolveScope());
   PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject());
   if (list == null) return factory.createTypeFromText(JAVA_UTIL_LIST, null);
   return factory.createType(list, PsiUtil.extractIterableTypeParameter(genericOwner, false));
 }
  @NotNull
  public static PsiType getLeastUpperBound(PsiClass[] classes, PsiManager manager) {
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject());

    if (classes.length == 0) return factory.createTypeByFQClassName(JAVA_LANG_OBJECT);

    PsiType type = factory.createType(classes[0]);

    for (int i = 1; i < classes.length; i++) {
      PsiType t = getLeastUpperBound(type, factory.createType(classes[i]), manager);
      if (t != null) {
        type = t;
      }
    }

    return type;
  }
 private static PsiType createType(PsiClass cls, PsiSubstitutor currentSubstitutor, int arrayDim) {
   final PsiElementFactory elementFactory =
       JavaPsiFacade.getInstance(cls.getProject()).getElementFactory();
   PsiType newType = elementFactory.createType(cls, currentSubstitutor);
   for (int i = 0; i < arrayDim; i++) {
     newType = newType.createArrayType();
   }
   return newType;
 }
Exemple #9
0
  public static PsiMethod generateSetterPrototype(
      PsiField field, final PsiClass containingClass, boolean returnSelf) {
    Project project = field.getProject();
    JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
    PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory();

    String name = field.getName();
    boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
    VariableKind kind = codeStyleManager.getVariableKind(field);
    String propertyName = codeStyleManager.variableNameToPropertyName(name, kind);
    String setName = suggestSetterName(project, field);
    try {
      PsiMethod setMethod =
          factory.createMethod(
              setName, returnSelf ? factory.createType(containingClass) : PsiType.VOID);
      String parameterName =
          codeStyleManager.propertyNameToVariableName(propertyName, VariableKind.PARAMETER);
      PsiParameter param = factory.createParameter(parameterName, field.getType());

      annotateWithNullableStuff(field, factory, param);

      setMethod.getParameterList().add(param);
      PsiUtil.setModifierProperty(setMethod, PsiModifier.PUBLIC, true);
      PsiUtil.setModifierProperty(setMethod, PsiModifier.STATIC, isStatic);

      @NonNls StringBuffer buffer = new StringBuffer();
      buffer.append("{\n");
      if (name.equals(parameterName)) {
        if (!isStatic) {
          buffer.append("this.");
        } else {
          String className = containingClass.getName();
          if (className != null) {
            buffer.append(className);
            buffer.append(".");
          }
        }
      }
      buffer.append(name);
      buffer.append("=");
      buffer.append(parameterName);
      buffer.append(";\n");
      if (returnSelf) {
        buffer.append("return this;\n");
      }
      buffer.append("}");
      PsiCodeBlock body = factory.createCodeBlockFromText(buffer.toString(), null);
      setMethod.getBody().replace(body);
      setMethod = (PsiMethod) CodeStyleManager.getInstance(project).reformat(setMethod);
      return setMethod;
    } catch (IncorrectOperationException e) {
      LOG.error(e);
      return null;
    }
  }
  private PsiMethod generateMethodFor(
      PsiField field, String methodName, String parameterName, PsiElementFactory elementFactory) {
    PsiMethod withMethod =
        elementFactory.createMethod(
            methodName, elementFactory.createType(field.getContainingClass()));
    PsiParameter parameter = elementFactory.createParameter(parameterName, field.getType());
    withMethod.getParameterList().add(parameter);
    PsiUtil.setModifierProperty(withMethod, PsiModifier.PUBLIC, true);

    return withMethod;
  }
  private static PsiType genNewMapBy(PsiType genericOwner, PsiManager manager) {
    PsiClass map =
        JavaPsiFacade.getInstance(manager.getProject())
            .findClass(JAVA_UTIL_MAP, genericOwner.getResolveScope());
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(manager.getProject());
    if (map == null) return factory.createTypeFromText(JAVA_UTIL_MAP, null);

    final PsiType key = PsiUtil.substituteTypeParameter(genericOwner, JAVA_UTIL_MAP, 0, false);
    final PsiType value = PsiUtil.substituteTypeParameter(genericOwner, JAVA_UTIL_MAP, 1, false);
    return factory.createType(map, key, value);
  }
 private void addParameters(
     final PsiElementFactory factory, final PsiMethod methodCopy, final boolean isInterface)
     throws IncorrectOperationException {
   final Set<Map.Entry<PsiClass, String>> entries = myOldClassParameterNames.entrySet();
   for (final Map.Entry<PsiClass, String> entry : entries) {
     final PsiClassType type = factory.createType(entry.getKey());
     final PsiParameter parameter = factory.createParameter(entry.getValue(), type);
     if (isInterface) {
       PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL, false);
     }
     methodCopy.getParameterList().add(parameter);
   }
 }
  private PsiMethod[] getDefEnumMethods() {
    return CachedValuesManager.getCachedValue(
        this,
        () -> {
          PsiMethod[] defMethods = new PsiMethod[4];
          final PsiManagerEx manager = getManager();
          final PsiElementFactory factory = JavaPsiFacade.getElementFactory(getProject());
          defMethods[0] =
              new LightMethodBuilder(manager, GroovyLanguage.INSTANCE, "values")
                  .setMethodReturnType(
                      factory.createTypeFromText(
                          CommonClassNames.JAVA_UTIL_COLLECTION + "<" + getName() + ">", this))
                  .setContainingClass(this)
                  .addModifier(PsiModifier.PUBLIC)
                  .addModifier(PsiModifier.STATIC);

          defMethods[1] =
              new LightMethodBuilder(manager, GroovyLanguage.INSTANCE, "next")
                  .setMethodReturnType(factory.createType(this))
                  .setContainingClass(this)
                  .addModifier(PsiModifier.PUBLIC);

          defMethods[2] =
              new LightMethodBuilder(manager, GroovyLanguage.INSTANCE, "previous")
                  .setMethodReturnType(factory.createType(this))
                  .setContainingClass(this)
                  .addModifier(PsiModifier.PUBLIC);

          defMethods[3] =
              new LightMethodBuilder(manager, GroovyLanguage.INSTANCE, "valueOf")
                  .setMethodReturnType(factory.createType(this))
                  .setContainingClass(this)
                  .addParameter("name", CommonClassNames.JAVA_LANG_STRING)
                  .addModifier(PsiModifier.PUBLIC)
                  .addModifier(PsiModifier.STATIC);

          return CachedValueProvider.Result.create(defMethods, this);
        });
  }
  @Nullable
  private static PsiClassType createCollection(
      Project project, String collectionName, PsiType... item) {
    PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
    PsiClass collection =
        JavaPsiFacade.getInstance(project)
            .findClass(collectionName, GlobalSearchScope.allScope(project));
    if (collection == null) return null;

    PsiTypeParameter[] parameters = collection.getTypeParameters();
    if (parameters.length != 1) return null;

    return factory.createType(collection, item);
  }
  /**
   * Returns a boxed class type corresponding to the primitive type.
   *
   * @param context where this boxed type is to be used
   * @return the class type, or null if the current language level does not support autoboxing or it
   *     was not possible to resolve the reference to the class.
   */
  @Nullable
  public PsiClassType getBoxedType(PsiElement context) {
    PsiFile file = context.getContainingFile();
    LanguageLevel languageLevel = PsiUtil.getLanguageLevel(file);
    if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_5)) return null;

    String boxedQName = getBoxedTypeName();
    // [ven]previous call returns null for NULL, VOID
    if (boxedQName == null) return null;
    JavaPsiFacade facade = JavaPsiFacade.getInstance(file.getProject());
    PsiClass aClass = facade.findClass(boxedQName, context.getResolveScope());
    if (aClass == null) return null;

    PsiElementFactory factory = facade.getElementFactory();
    return factory.createType(aClass, PsiSubstitutor.EMPTY, languageLevel, getAnnotations());
  }
 public static PsiSubstitutor obtainFinalSubstitutor(
     @NotNull PsiClass candidateClass,
     @NotNull PsiSubstitutor candidateSubstitutor,
     @NotNull PsiClass aClass,
     @NotNull PsiSubstitutor substitutor,
     @NotNull PsiElementFactory elementFactory,
     @NotNull LanguageLevel languageLevel) {
   if (PsiUtil.isRawSubstitutor(aClass, substitutor)) {
     return elementFactory.createRawSubstitutor(candidateClass);
   }
   final PsiType containingType =
       elementFactory.createType(candidateClass, candidateSubstitutor, languageLevel);
   PsiType type = substitutor.substitute(containingType);
   if (!(type instanceof PsiClassType)) return candidateSubstitutor;
   return ((PsiClassType) type).resolveGenerics().getSubstitutor();
 }
  @NotNull
  public PsiClassType[] getReferencedTypes() {
    final PsiClassReferenceListStub stub = getStub();
    if (stub != null) {
      return stub.getReferencedTypes();
    }

    final PsiJavaCodeReferenceElement[] refs = getReferenceElements();
    final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
    PsiClassType[] types = new PsiClassType[refs.length];
    for (int i = 0; i < types.length; i++) {
      types[i] = factory.createType(refs[i]);
    }

    return types;
  }
  @Nullable
  private static PsiSubstitutor getSuperMethodSignatureSubstitutorImpl(
      @NotNull MethodSignature methodSignature, @NotNull MethodSignature superSignature) {
    // normalize generic method declarations: correlate type parameters
    // todo: correlate type params by name?
    PsiTypeParameter[] methodTypeParameters = methodSignature.getTypeParameters();
    PsiTypeParameter[] superTypeParameters = superSignature.getTypeParameters();

    // both methods are parameterized and number of parameters mismatch
    if (methodTypeParameters.length != superTypeParameters.length) return null;

    PsiSubstitutor result = superSignature.getSubstitutor();
    for (int i = 0; i < methodTypeParameters.length; i++) {
      PsiTypeParameter methodTypeParameter = methodTypeParameters[i];
      PsiElementFactory factory =
          JavaPsiFacade.getInstance(methodTypeParameter.getProject()).getElementFactory();
      result = result.put(superTypeParameters[i], factory.createType(methodTypeParameter));
    }

    return result;
  }
  public static PsiType buildTypeFromTypeString(
      @NotNull final String typeName,
      @NotNull final PsiElement context,
      @NotNull final PsiFile psiFile) {
    PsiType resultType;
    final PsiManager psiManager = psiFile.getManager();

    if (typeName.indexOf('<') != -1 || typeName.indexOf('[') != -1 || typeName.indexOf('.') == -1) {
      try {
        return JavaPsiFacade.getInstance(psiManager.getProject())
            .getElementFactory()
            .createTypeFromText(typeName, context);
      } catch (Exception ignored) {
      } // invalid syntax will produce unresolved class type
    }

    PsiClass aClass =
        JavaPsiFacade.getInstance(psiManager.getProject())
            .findClass(typeName, context.getResolveScope());

    if (aClass == null) {
      final LightClassReference ref =
          new LightClassReference(
              psiManager,
              PsiNameHelper.getShortClassName(typeName),
              typeName,
              PsiSubstitutor.EMPTY,
              psiFile);
      resultType = new PsiClassReferenceType(ref, null);
    } else {
      PsiElementFactory factory =
          JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
      PsiSubstitutor substitutor = factory.createRawSubstitutor(aClass);
      resultType = factory.createType(aClass, substitutor);
    }

    return resultType;
  }
 private static PsiClassType getEnumSuperType(
     @NotNull PsiClass psiClass, @NotNull PsiElementFactory factory) {
   PsiClassType superType;
   final PsiManager manager = psiClass.getManager();
   final PsiClass enumClass =
       JavaPsiFacade.getInstance(manager.getProject())
           .findClass("java.lang.Enum", psiClass.getResolveScope());
   if (enumClass == null) {
     try {
       superType = (PsiClassType) factory.createTypeFromText("java.lang.Enum", null);
     } catch (IncorrectOperationException e) {
       superType = null;
     }
   } else {
     final PsiTypeParameter[] typeParameters = enumClass.getTypeParameters();
     PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
     if (typeParameters.length == 1) {
       substitutor = substitutor.put(typeParameters[0], factory.createType(psiClass));
     }
     superType = new PsiImmediateClassType(enumClass, substitutor);
   }
   return superType;
 }
  @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;
  }
  @Nullable
  private static PsiExpression createDefaultValue(
      JavaChangeInfo changeInfo,
      final PsiElementFactory factory,
      final JavaParameterInfo info,
      final PsiExpressionList list)
      throws IncorrectOperationException {
    if (info.isUseAnySingleVariable()) {
      final PsiResolveHelper resolveHelper =
          JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
      final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager());
      final VariablesProcessor processor =
          new VariablesProcessor(false) {
            protected boolean check(PsiVariable var, ResolveState state) {
              if (var instanceof PsiField
                  && !resolveHelper.isAccessible((PsiField) var, list, null)) return false;
              if (var instanceof PsiLocalVariable
                  && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset())
                return false;
              if (PsiTreeUtil.isAncestor(var, list, false)) return false;
              final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(var.getType());
              return type.isAssignableFrom(varType);
            }

            public boolean execute(PsiElement pe, ResolveState state) {
              super.execute(pe, state);
              return size() < 2;
            }
          };
      PsiScopesUtil.treeWalkUp(processor, list, null);
      if (processor.size() == 1) {
        final PsiVariable result = processor.getResult(0);
        return factory.createExpressionFromText(result.getName(), list);
      }
      if (processor.size() == 0) {
        final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class);
        if (parentClass != null) {
          PsiClass containingClass = parentClass;
          final Set<PsiClass> containingClasses = new HashSet<PsiClass>();
          while (containingClass != null) {
            if (type.isAssignableFrom(factory.createType(containingClass, PsiSubstitutor.EMPTY))) {
              containingClasses.add(containingClass);
            }
            containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
          }
          if (containingClasses.size() == 1) {
            return RefactoringUtil.createThisExpression(
                parentClass.getManager(),
                containingClasses.contains(parentClass)
                    ? null
                    : containingClasses.iterator().next());
          }
        }
      }
    }
    final PsiCallExpression callExpression =
        PsiTreeUtil.getParentOfType(list, PsiCallExpression.class);
    final String defaultValue = info.getDefaultValue();
    return callExpression != null
        ? info.getValue(callExpression)
        : defaultValue.length() > 0 ? factory.createExpressionFromText(defaultValue, list) : null;
  }
  @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;
  }
Exemple #24
0
  @Override
  public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) {
    if (!LambdaUtil.isFunctionalType(myT)) {
      return false;
    }

    final PsiType groundTargetType =
        FunctionalInterfaceParameterizationUtil.getGroundTargetType(myT);
    final PsiClassType.ClassResolveResult classResolveResult =
        PsiUtil.resolveGenericsClassInType(groundTargetType);
    final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(classResolveResult);
    if (interfaceMethod == null) {
      return false;
    }

    final PsiSubstitutor substitutor =
        LambdaUtil.getSubstitutor(interfaceMethod, classResolveResult);
    final PsiParameter[] targetParameters = interfaceMethod.getParameterList().getParameters();
    final PsiType interfaceMethodReturnType = interfaceMethod.getReturnType();
    final PsiType returnType = substitutor.substitute(interfaceMethodReturnType);
    final PsiType[] typeParameters = myExpression.getTypeParameters();

    final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult =
        PsiMethodReferenceUtil.getQualifierResolveResult(myExpression);

    if (!myExpression.isExact()) {
      for (PsiParameter parameter : targetParameters) {
        if (!session.isProperType(substitutor.substitute(parameter.getType()))) {
          return false;
        }
      }
    } else {
      final PsiMember applicableMember = myExpression.getPotentiallyApplicableMember();
      LOG.assertTrue(applicableMember != null);

      final PsiClass applicableMemberContainingClass = applicableMember.getContainingClass();
      final PsiClass containingClass = qualifierResolveResult.getContainingClass();

      PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
      psiSubstitutor =
          applicableMemberContainingClass == null
                  || containingClass == null
                  || myExpression.isConstructor()
              ? psiSubstitutor
              : TypeConversionUtil.getSuperClassSubstitutor(
                  applicableMemberContainingClass, containingClass, psiSubstitutor);

      PsiType applicableMethodReturnType =
          applicableMember instanceof PsiMethod
              ? ((PsiMethod) applicableMember).getReturnType()
              : null;
      int idx = 0;
      for (PsiTypeParameter param :
          ((PsiTypeParameterListOwner) applicableMember).getTypeParameters()) {
        if (idx < typeParameters.length) {
          psiSubstitutor = psiSubstitutor.put(param, typeParameters[idx++]);
        }
      }
      final PsiParameter[] parameters =
          applicableMember instanceof PsiMethod
              ? ((PsiMethod) applicableMember).getParameterList().getParameters()
              : PsiParameter.EMPTY_ARRAY;
      if (targetParameters.length == parameters.length + 1) {
        specialCase(session, constraints, substitutor, targetParameters, true);
        for (int i = 1; i < targetParameters.length; i++) {
          constraints.add(
              new TypeCompatibilityConstraint(
                  session.substituteWithInferenceVariables(
                      psiSubstitutor.substitute(parameters[i - 1].getType())),
                  substitutor.substitute(targetParameters[i].getType())));
        }
      } else if (targetParameters.length == parameters.length) {
        for (int i = 0; i < targetParameters.length; i++) {
          constraints.add(
              new TypeCompatibilityConstraint(
                  session.substituteWithInferenceVariables(
                      psiSubstitutor.substitute(parameters[i].getType())),
                  substitutor.substitute(targetParameters[i].getType())));
        }
      } else {
        return false;
      }
      if (returnType != PsiType.VOID && returnType != null) {
        if (applicableMethodReturnType == PsiType.VOID) {
          return false;
        }

        if (applicableMethodReturnType != null) {
          constraints.add(
              new TypeCompatibilityConstraint(
                  returnType,
                  session.substituteWithInferenceVariables(
                      psiSubstitutor.substitute(applicableMethodReturnType))));
        } else if (applicableMember instanceof PsiClass
            || applicableMember instanceof PsiMethod
                && ((PsiMethod) applicableMember).isConstructor()) {
          final PsiElementFactory elementFactory =
              JavaPsiFacade.getElementFactory(applicableMember.getProject());
          if (containingClass != null) {
            final PsiType classType =
                session.substituteWithInferenceVariables(
                    elementFactory.createType(containingClass, psiSubstitutor));
            constraints.add(new TypeCompatibilityConstraint(returnType, classType));
          }
        }
      }
      return true;
    }

    final Map<PsiElement, PsiType> map = LambdaUtil.getFunctionalTypeMap();
    final PsiType added = map.put(myExpression, session.startWithFreshVars(groundTargetType));
    final JavaResolveResult resolve;
    try {
      resolve = myExpression.advancedResolve(true);
    } finally {
      if (added == null) {
        map.remove(myExpression);
      }
    }
    final PsiElement element = resolve.getElement();
    if (element == null) {
      return false;
    }

    if (PsiType.VOID.equals(returnType) || returnType == null) {
      return true;
    }

    if (element instanceof PsiMethod) {
      final PsiMethod method = (PsiMethod) element;
      final PsiType referencedMethodReturnType;
      final PsiClass containingClass = method.getContainingClass();
      LOG.assertTrue(containingClass != null, method);
      PsiClass qContainingClass = qualifierResolveResult.getContainingClass();
      PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor();
      if (qContainingClass != null) {
        if (PsiUtil.isRawSubstitutor(qContainingClass, psiSubstitutor)) {
          psiSubstitutor = PsiSubstitutor.EMPTY;
        }
        if (qContainingClass.isInheritor(containingClass, true)) {
          psiSubstitutor =
              TypeConversionUtil.getClassSubstitutor(
                  containingClass, qContainingClass, PsiSubstitutor.EMPTY);
          LOG.assertTrue(psiSubstitutor != null);
        }
      }

      if (method.isConstructor()) {
        referencedMethodReturnType =
            JavaPsiFacade.getElementFactory(method.getProject())
                .createType(containingClass, PsiSubstitutor.EMPTY);
      } else {
        referencedMethodReturnType = method.getReturnType();
      }
      LOG.assertTrue(referencedMethodReturnType != null, method);

      if (!PsiTreeUtil.isContextAncestor(containingClass, myExpression, false)
          || PsiUtil.getEnclosingStaticElement(myExpression, containingClass) != null) {
        session.initBounds(myExpression, containingClass.getTypeParameters());
      }

      session.initBounds(myExpression, method.getTypeParameters());

      // if i) the method reference elides NonWildTypeArguments,
      //  ii) the compile-time declaration is a generic method, and
      // iii) the return type of the compile-time declaration mentions at least one of the method's
      // type parameters;
      if (typeParameters.length == 0 && method.getTypeParameters().length > 0) {
        final PsiClass interfaceClass = classResolveResult.getElement();
        LOG.assertTrue(interfaceClass != null);
        if (PsiPolyExpressionUtil.mentionsTypeParameters(
            referencedMethodReturnType, ContainerUtil.newHashSet(method.getTypeParameters()))) {
          // the constraint reduces to the bound set B3 which would be used to determine the method
          // reference's invocation type
          // when targeting the return type of the function type, as defined in 18.5.2.
          session.collectApplicabilityConstraints(
              myExpression, ((MethodCandidateInfo) resolve), groundTargetType);
          session.registerReturnTypeConstraints(referencedMethodReturnType, returnType);
          return true;
        }
      }

      if (PsiType.VOID.equals(referencedMethodReturnType)) {
        return false;
      }

      int idx = 0;
      for (PsiTypeParameter param : method.getTypeParameters()) {
        if (idx < typeParameters.length) {
          psiSubstitutor = psiSubstitutor.put(param, typeParameters[idx++]);
        }
      }

      final PsiParameter[] parameters = method.getParameterList().getParameters();
      if (targetParameters.length == parameters.length + 1
          && !method.isVarArgs()
          && PsiPolyExpressionUtil.mentionsTypeParameters(
              referencedMethodReturnType,
              ContainerUtil.newHashSet(
                  containingClass.getTypeParameters()))) { // todo specification bug?
        specialCase(session, constraints, substitutor, targetParameters, false);
      }
      constraints.add(
          new TypeCompatibilityConstraint(
              returnType,
              session.substituteWithInferenceVariables(
                  psiSubstitutor.substitute(referencedMethodReturnType))));
    }

    return true;
  }
  @Nullable
  private static PsiMethod generateStaticFactory(
      @Nullable PsiMethod constructor,
      PsiClass containingClass,
      PsiTypeParameter[] params,
      PsiJavaCodeReferenceElement reference) {
    final StringBuilder buf = new StringBuilder();
    buf.append("public static ");
    buf.append("<");
    buf.append(
        StringUtil.join(
            params,
            new Function<PsiTypeParameter, String>() {
              @Override
              public String fun(PsiTypeParameter psiTypeParameter) {
                final String extendsList =
                    psiTypeParameter.getLanguage().isKindOf(JavaLanguage.INSTANCE)
                        ? psiTypeParameter.getExtendsList().getText()
                        : null;
                return psiTypeParameter.getName()
                    + (StringUtil.isEmpty(extendsList) ? "" : " " + extendsList);
              }
            },
            ", "));
    buf.append(">");

    final PsiElementFactory elementFactory =
        JavaPsiFacade.getElementFactory(containingClass.getProject());

    String qualifiedName = containingClass.getQualifiedName();

    PsiElement qualifier = reference != null ? reference.getQualifier() : null;
    if (qualifier instanceof PsiJavaCodeReferenceElement) {
      final JavaResolveResult resolveResult =
          ((PsiJavaCodeReferenceElement) qualifier).advancedResolve(false);
      final PsiElement element = resolveResult.getElement();
      if (element instanceof PsiClass) {
        final String outerClassSubstitutedQName =
            elementFactory
                .createType((PsiClass) element, resolveResult.getSubstitutor())
                .getInternalCanonicalText();
        qualifiedName = outerClassSubstitutedQName + "." + containingClass.getName();
      }
    } else if (reference != null
        && qualifier == null
        && containingClass.getContainingClass() != null) {
      qualifiedName = null;
    }

    buf.append(qualifiedName != null ? qualifiedName : containingClass.getName());
    final PsiTypeParameter[] parameters = containingClass.getTypeParameters();
    buf.append("<");
    buf.append(
        StringUtil.join(
            parameters,
            new Function<PsiTypeParameter, String>() {
              @Override
              public String fun(PsiTypeParameter psiTypeParameter) {
                return psiTypeParameter.getName();
              }
            },
            ", "));
    buf.append("> ");

    String staticFactoryName = "staticFactory";
    final JavaCodeStyleManager styleManager =
        JavaCodeStyleManager.getInstance(containingClass.getProject());
    staticFactoryName =
        styleManager.suggestUniqueVariableName(staticFactoryName, containingClass, false);
    buf.append(staticFactoryName);
    if (constructor == null) {
      buf.append("()");
    } else {
      buf.append("(")
          .append(
              StringUtil.join(
                  constructor.getParameterList().getParameters(),
                  new Function<PsiParameter, String>() {
                    int myIdx = 0;

                    @Override
                    public String fun(PsiParameter psiParameter) {
                      return psiParameter.getType().getCanonicalText() + " p" + myIdx++;
                    }
                  },
                  ","))
          .append(")");
    }
    buf.append("{}");

    try {
      return elementFactory.createMethodFromText(
          buf.toString(), constructor != null ? constructor : containingClass);
    } catch (IncorrectOperationException e) {
      return null;
    }
  }
  public JavaCodeFragment createCodeFragment(
      TextWithImports textWithImports, PsiElement context, Project project) {
    String text = textWithImports.getText();
    String imports = textWithImports.getImports();
    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);
    final GroovyFile toEval = factory.createGroovyFile(text, false, context);
    final Set<String> namesList = new HashSet<String>();
    final GrClosableBlock closure = PsiTreeUtil.getParentOfType(context, GrClosableBlock.class);

    final Set<String> valList = new HashSet<String>();
    toEval.accept(
        new GroovyRecursiveElementVisitor() {
          public void visitReferenceExpression(GrReferenceExpression referenceExpression) {
            super.visitReferenceExpression(referenceExpression);
            PsiElement resolved = referenceExpression.resolve();

            if (resolved instanceof PsiMethod
                && "getDelegate".equals(((PsiMethod) resolved).getName())
                && closure != null) {
              replaceWithReference(referenceExpression, "owner");
              return;
            }

            if (resolved instanceof GrField && !referenceExpression.isQualified()) {
              replaceWithReference(
                  referenceExpression,
                  (closure == null ? "delegate" : "owner")
                      + "."
                      + referenceExpression.getReferenceName());
              return;
            }

            if (resolved instanceof GrVariableBase
                && !(resolved instanceof GrField)
                && !PsiTreeUtil.isAncestor(toEval, resolved, false)) {
              final String name = ((GrVariableBase) resolved).getName();
              if (resolved instanceof ClosureSyntheticParameter
                  && PsiTreeUtil.isAncestor(
                      toEval, ((ClosureSyntheticParameter) resolved).getClosure(), false)) {
                return;
              }
              namesList.add(name);
              if (closure != null
                  && PsiTreeUtil.findCommonParent(resolved, closure) != closure
                  && !(resolved instanceof ClosureSyntheticParameter)) {
                // Evaluating inside closure for outer variable definitions
                // All non-local variables are accessed by references
                valList.add("this." + name);
              } else {
                valList.add(name);
              }
            }
          }

          @Override
          public void visitThisExpression(final GrThisReferenceExpression thisExpression) {
            super.visitThisExpression(thisExpression);
            replaceWithReference(thisExpression, closure == null ? "delegate" : "owner");
          }

          @Override
          public void visitSuperExpression(final GrSuperReferenceExpression superExpression) {
            super.visitSuperExpression(superExpression);
            replaceWithReference(superExpression, closure == null ? "delegate" : "owner");
          }

          private void replaceWithReference(GrExpression expr, final String exprText) {
            final GroovyPsiElementFactory factory =
                GroovyPsiElementFactory.getInstance(expr.getProject());
            visitReferenceExpression(
                (GrReferenceExpression)
                    expr.replaceWithExpression(factory.createExpressionFromText(exprText), false));
          }

          public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
            if (refElement.getQualifier() != null) {
              super.visitCodeReferenceElement(refElement);
            } else {
              PsiElement resolved = refElement.resolve();
              if (resolved instanceof PsiClass) {
                String qName = ((PsiClass) resolved).getQualifiedName();
                if (qName != null) {
                  int dotIndex = qName.lastIndexOf(".");
                  if (dotIndex < 0) return;
                  String packageName = qName.substring(0, dotIndex);
                  refElement.setQualifier(factory.createReferenceElementFromText(packageName));
                }
              }
            }
          }
        });

    text = toEval.getText();

    String[] names = namesList.toArray(new String[namesList.size()]);
    String[] vals = valList.toArray(new String[valList.size()]);

    PsiClass contextClass = PsiUtil.getContextClass(context);
    boolean isStatic = isStaticContext(context);
    StringBuffer javaText = new StringBuffer();

    javaText.append("groovy.lang.MetaClass mc;\n");
    javaText.append("java.lang.Class clazz;\n");
    if (!isStatic) {
      javaText.append("clazz = ((java.lang.Object)this).getClass();\n");
      javaText.append("mc = ((groovy.lang.GroovyObject)this).getMetaClass();\n");
    } else {
      javaText
          .append("clazz = java.lang.Class.forName(\"")
          .append(contextClass.getQualifiedName())
          .append("\");\n");
      javaText.append(
          "mc = groovy.lang.GroovySystem.getMetaClassRegistry().getMetaClass(clazz);\n");
    }

    javaText.append(createProperty(stripImports(text, toEval), imports, names));

    javaText.append(
        "groovy.lang.ExpandoMetaClass emc = new groovy.lang.ExpandoMetaClass(clazz);\n");
    if (!isStatic) {
      javaText.append("emc.setProperty(\"").append(EVAL_NAME).append("\", closure);\n");
      javaText.append("((groovy.lang.GroovyObject)this).setMetaClass(emc);\n");
    } else {
      javaText
          .append("((groovy.lang.GroovyObject)emc.getProperty(\"static\")).setProperty(\"")
          .append(EVAL_NAME)
          .append("\", closure);\n");
      javaText.append(
          "groovy.lang.GroovySystem.getMetaClassRegistry().setMetaClass(clazz, emc);\n");
    }
    javaText.append("emc.initialize();\n");
    javaText.append(unwrapVals(vals));
    if (!isStatic) {
      javaText
          .append("java.lang.Object res = ((groovy.lang.MetaClassImpl)emc).invokeMethod(this, \"")
          .append(EVAL_NAME)
          .append("\", ")
          .append("resVals")
          .append(");\n");
      javaText.append(
          "((groovy.lang.GroovyObject)this).setMetaClass(mc);"); // try/finally is not supported
    } else {
      javaText
          .append(
              "java.lang.Object res = ((groovy.lang.MetaClassImpl)emc).invokeStaticMethod(clazz, \"")
          .append(EVAL_NAME)
          .append("\", ")
          .append("resVals")
          .append(");\n");
      javaText.append("groovy.lang.GroovySystem.getMetaClassRegistry().setMetaClass(clazz, mc);\n");
    }
    javaText.append("res");

    PsiElementFactory elementFactory =
        JavaPsiFacade.getInstance(toEval.getProject()).getElementFactory();
    JavaCodeFragment result =
        elementFactory.createCodeBlockCodeFragment(javaText.toString(), null, true);
    if (contextClass != null) {
      result.setThisType(elementFactory.createType(contextClass));
    }
    return result;
  }
  private static void startTemplate(
      GrTypeParameterList oldTypeParameterList,
      final Project project,
      final GrTypeDefinition psiClass,
      final GrTypeDefinition targetClass,
      boolean includeClassName) {
    PsiElementFactory jfactory = JavaPsiFacade.getElementFactory(project);
    final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(project);
    GrCodeReferenceElement ref = elementFactory.createCodeReferenceElementFromClass(psiClass);
    try {
      if (psiClass.isInterface()) {
        GrImplementsClause clause = targetClass.getImplementsClause();
        if (clause == null) {
          clause =
              (GrImplementsClause)
                  targetClass.addAfter(
                      elementFactory.createImplementsClause(),
                      targetClass.getNameIdentifierGroovy());
        }
        ref = (GrCodeReferenceElement) clause.add(ref);
      } else {
        GrExtendsClause clause = targetClass.getExtendsClause();
        if (clause == null) {
          clause =
              (GrExtendsClause)
                  targetClass.addAfter(
                      elementFactory.createExtendsClause(), targetClass.getNameIdentifierGroovy());
        }
        ref = (GrCodeReferenceElement) clause.add(ref);
      }
      if (psiClass.hasTypeParameters() || includeClassName) {
        final Editor editor =
            CodeInsightUtil.positionCursor(
                project, targetClass.getContainingFile(), targetClass.getLBrace());
        final TemplateBuilderImpl templateBuilder =
            editor == null || ApplicationManager.getApplication().isUnitTestMode()
                ? null
                : (TemplateBuilderImpl)
                    TemplateBuilderFactory.getInstance().createTemplateBuilder(targetClass);

        if (includeClassName && templateBuilder != null) {
          templateBuilder.replaceElement(targetClass.getNameIdentifier(), targetClass.getName());
        }

        if (oldTypeParameterList != null) {
          for (PsiTypeParameter parameter : oldTypeParameterList.getTypeParameters()) {
            final PsiElement param =
                ref.getTypeArgumentList()
                    .add(elementFactory.createTypeElement(jfactory.createType(parameter)));
            if (templateBuilder != null) {
              templateBuilder.replaceElement(param, param.getText());
            }
          }
        }

        final GrTypeParameterList typeParameterList = targetClass.getTypeParameterList();
        assert typeParameterList != null;
        typeParameterList.replace(oldTypeParameterList);

        if (templateBuilder != null) {
          templateBuilder.setEndVariableBefore(ref);
          final Template template = templateBuilder.buildTemplate();
          template.addEndVariable();

          final PsiFile containingFile = targetClass.getContainingFile();

          PsiDocumentManager.getInstance(project)
              .doPostponedOperationsAndUnblockDocument(editor.getDocument());

          final TextRange textRange = targetClass.getTextRange();
          final int startClassOffset = textRange.getStartOffset();
          editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset());
          CreateFromUsageBaseFix.startTemplate(
              editor,
              template,
              project,
              new TemplateEditingAdapter() {
                @Override
                public void templateFinished(Template template, boolean brokenOff) {
                  chooseAndImplement(
                      psiClass,
                      project,
                      PsiTreeUtil.getParentOfType(
                          containingFile.findElementAt(startClassOffset), GrTypeDefinition.class),
                      editor);
                }
              },
              getTitle(psiClass));
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  protected void changeSelf(PsiElementFactory factory, UsageInfo[] usages)
      throws IncorrectOperationException {
    final MethodJavaDocHelper javaDocHelper = new MethodJavaDocHelper(myMember);
    PsiParameterList paramList = myMember.getParameterList();
    PsiElement addParameterAfter = null;
    PsiDocTag anchor = null;
    List<PsiType> addedTypes = new ArrayList<PsiType>();

    final PsiClass containingClass = myMember.getContainingClass();
    LOG.assertTrue(containingClass != null);

    if (mySettings.isDelegate()) {
      List<ParameterInfoImpl> params = new ArrayList<ParameterInfoImpl>();
      PsiParameter[] parameters = myMember.getParameterList().getParameters();

      if (mySettings.isMakeClassParameter()) {
        params.add(
            new ParameterInfoImpl(
                -1,
                mySettings.getClassParameterName(),
                factory.createType(containingClass, PsiSubstitutor.EMPTY),
                "this"));
      }

      if (mySettings.isMakeFieldParameters()) {
        for (Settings.FieldParameter parameter : mySettings.getParameterOrderList()) {
          params.add(
              new ParameterInfoImpl(
                  -1,
                  mySettings.getClassParameterName(),
                  parameter.type,
                  parameter.field.getName()));
        }
      }

      for (int i = 0; i < parameters.length; i++) {
        params.add(new ParameterInfoImpl(i));
      }

      final PsiType returnType = myMember.getReturnType();
      LOG.assertTrue(returnType != null);
      JavaChangeSignatureUsageProcessor.generateDelegate(
          new JavaChangeInfoImpl(
              VisibilityUtil.getVisibilityModifier(myMember.getModifierList()),
              myMember,
              myMember.getName(),
              CanonicalTypes.createTypeWrapper(returnType),
              params.toArray(new ParameterInfoImpl[params.size()]),
              new ThrownExceptionInfo[0],
              false,
              Collections.<PsiMethod>emptySet(),
              Collections.<PsiMethod>emptySet()));
    }

    if (mySettings.isMakeClassParameter()) {
      // Add parameter for object
      PsiType parameterType = factory.createType(containingClass, PsiSubstitutor.EMPTY);
      addedTypes.add(parameterType);

      final String classParameterName = mySettings.getClassParameterName();
      PsiParameter parameter = factory.createParameter(classParameterName, parameterType);
      if (makeClassParameterFinal(usages)) {
        PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL, true);
      }
      addParameterAfter = paramList.addAfter(parameter, null);
      anchor = javaDocHelper.addParameterAfter(classParameterName, anchor);
    }

    if (mySettings.isMakeFieldParameters()) {
      List<Settings.FieldParameter> parameters = mySettings.getParameterOrderList();

      for (Settings.FieldParameter fieldParameter : parameters) {
        final PsiType fieldParameterType = fieldParameter.field.getType();
        final PsiParameter parameter =
            factory.createParameter(fieldParameter.name, fieldParameterType);
        addedTypes.add(fieldParameterType);
        if (makeFieldParameterFinal(fieldParameter.field, usages)) {
          PsiUtil.setModifierProperty(parameter, PsiModifier.FINAL, true);
        }
        addParameterAfter = paramList.addAfter(parameter, addParameterAfter);
        anchor = javaDocHelper.addParameterAfter(fieldParameter.name, anchor);
      }
    }
    makeStatic(myMember);

    if (myAdditionalMethods != null) {
      for (PsiMethod method : myAdditionalMethods) {
        makeStatic(method);
      }
    }
  }
  private void replaceInnerTypeUsages() {
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject);
    final PsiElementFactory elementFactory = facade.getElementFactory();
    final PsiResolveHelper resolveHelper = facade.getResolveHelper();
    final Map<UsageInfo, PsiElement> replacementMap = new HashMap<UsageInfo, PsiElement>();
    for (final PsiClass targetClass : myTargetClasses) {
      final PsiSubstitutor superClassSubstitutor =
          TypeConversionUtil.getSuperClassSubstitutor(
              mySuperClass, targetClass, PsiSubstitutor.EMPTY);
      final PsiClassType targetClassType =
          elementFactory.createType(targetClass, superClassSubstitutor);
      targetClass.accept(
          new JavaRecursiveElementWalkingVisitor() {
            @Override
            public void visitTypeElement(final PsiTypeElement typeElement) {
              super.visitTypeElement(typeElement);
              final PsiType superClassType = typeElement.getType();
              if (PsiUtil.resolveClassInType(superClassType) == mySuperClass) {
                PsiSubstitutor subst =
                    getSuperClassSubstitutor(
                        superClassType, targetClassType, resolveHelper, targetClass);
                replacementMap.put(
                    new UsageInfo(typeElement),
                    elementFactory.createTypeElement(
                        elementFactory.createType(targetClass, subst)));
              }
            }

            @Override
            public void visitNewExpression(final PsiNewExpression expression) {
              super.visitNewExpression(expression);
              final PsiType superClassType = expression.getType();
              if (PsiUtil.resolveClassInType(superClassType) == mySuperClass) {
                PsiSubstitutor subst =
                    getSuperClassSubstitutor(
                        superClassType, targetClassType, resolveHelper, targetClass);
                try {
                  replacementMap.put(
                      new UsageInfo(expression),
                      elementFactory.createExpressionFromText(
                          "new "
                              + elementFactory.createType(targetClass, subst).getCanonicalText()
                              + expression.getArgumentList().getText(),
                          expression));
                } catch (IncorrectOperationException e) {
                  LOG.error(e);
                }
              }
            }
          });
    }
    try {
      for (Map.Entry<UsageInfo, PsiElement> elementEntry : replacementMap.entrySet()) {
        final PsiElement element = elementEntry.getKey().getElement();
        if (element != null) {
          element.replace(elementEntry.getValue());
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  @Nullable
  private static GrExpression createDefaultValue(
      GroovyPsiElementFactory factory,
      JavaChangeInfo changeInfo,
      JavaParameterInfo info,
      final GrArgumentList list) {
    if (info.isUseAnySingleVariable()) {
      final PsiResolveHelper resolveHelper =
          JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
      final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager());
      final VariablesProcessor processor =
          new VariablesProcessor(false) {
            @Override
            protected boolean check(PsiVariable var, ResolveState state) {
              if (var instanceof PsiField
                  && !resolveHelper.isAccessible((PsiField) var, list, null)) return false;
              if (var instanceof GrVariable
                  && PsiUtil.isLocalVariable(var)
                  && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset()) {
                return false;
              }
              if (PsiTreeUtil.isAncestor(var, list, false)) return false;
              final PsiType _type =
                  var instanceof GrVariable ? ((GrVariable) var).getTypeGroovy() : var.getType();
              final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(_type);
              return type.isAssignableFrom(varType);
            }

            @Override
            public boolean execute(@NotNull PsiElement pe, @NotNull ResolveState state) {
              super.execute(pe, state);
              return size() < 2;
            }
          };
      ResolveUtil.treeWalkUp(list, processor, false);
      if (processor.size() == 1) {
        final PsiVariable result = processor.getResult(0);
        return factory.createExpressionFromText(result.getName(), list);
      }
      if (processor.size() == 0) {
        final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class);
        if (parentClass != null) {
          PsiClass containingClass = parentClass;
          final Set<PsiClass> containingClasses = new HashSet<PsiClass>();
          final PsiElementFactory jfactory = JavaPsiFacade.getElementFactory(list.getProject());
          while (containingClass != null) {
            if (type.isAssignableFrom(jfactory.createType(containingClass, PsiSubstitutor.EMPTY))) {
              containingClasses.add(containingClass);
            }
            containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
          }
          if (containingClasses.size() == 1) {
            return factory.createThisExpression(
                containingClasses.contains(parentClass)
                    ? null
                    : containingClasses.iterator().next());
          }
        }
      }
    }

    final String value = info.getDefaultValue();
    return !StringUtil.isEmpty(value) ? factory.createExpressionFromText(value, list) : null;
  }