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); } } } } }
@Nullable public static PsiType substituteBoxAndNormalizeType( @Nullable PsiType type, @NotNull PsiSubstitutor substitutor, @Nullable SpreadState state, @NotNull GrExpression expression) { if (type == null) return null; GlobalSearchScope resolveScope = expression.getResolveScope(); PsiManager manager = expression.getManager(); type = substitutor.substitute(type); type = boxPrimitiveType(type, manager, resolveScope); if (type == null) return null; type = PsiImplUtil.normalizeWildcardTypeByPosition(type, expression); type = SpreadState.apply(type, state, expression.getProject()); return type; }
protected TextRange surroundExpression(GrExpression expression, PsiElement context) { GrIfStatement ifStatement = (GrIfStatement) GroovyPsiElementFactory.getInstance(expression.getProject()) .createStatementFromText("if(a){4\n} else{\n}", context); replaceToOldExpression(ifStatement.getCondition(), expression); ifStatement = expression.replaceWithStatement(ifStatement); GrStatement psiElement = ifStatement.getThenBranch(); assert psiElement instanceof GrBlockStatement; GrStatement[] statements = ((GrBlockStatement) psiElement).getBlock().getStatements(); assert statements.length > 0; GrStatement statement = statements[0]; int endOffset = statement.getTextRange().getStartOffset(); statement.getNode().getTreeParent().removeChild(statement.getNode()); return new TextRange(endOffset, endOffset); }
/** @return replaced expression or null if expression is not replaced */ @Nullable private static GrExpression addParenthesesIfNeeded( GrExpression newExpr, GrExpression oldExpr, GrExpression oldParent) { GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(oldExpr.getProject()); int parentPriorityLevel = getExprPriorityLevel(oldParent); int newPriorityLevel = getExprPriorityLevel(newExpr); if (parentPriorityLevel > newPriorityLevel) { newExpr = factory.createParenthesizedExpr(newExpr); } else if (parentPriorityLevel == newPriorityLevel && parentPriorityLevel != 0) { if (oldParent instanceof GrBinaryExpression) { GrBinaryExpression binaryExpression = (GrBinaryExpression) oldParent; if (isNotAssociative(binaryExpression) && oldExpr.equals(binaryExpression.getRightOperand())) { newExpr = factory.createParenthesizedExpr(newExpr); } } } return newExpr; }
private static void generateNameByExpr( GrExpression expr, Set<String> possibleNames, NameValidator validator, boolean forStaticVariable) { if (expr instanceof GrReferenceExpression && ((GrReferenceExpression) expr).getReferenceName() != null) { if (PsiUtil.isThisReference(expr)) { possibleNames.add(validator.validateName("thisInstance", true)); } if (PsiUtil.isSuperReference(expr)) { possibleNames.add(validator.validateName("superInstance", true)); } GrReferenceExpression refExpr = (GrReferenceExpression) expr; String name = refExpr.getReferenceName(); if (name != null && name.toUpperCase().equals(name)) { possibleNames.add(validator.validateName(name.toLowerCase(), true)); } else { generateCamelNames(possibleNames, validator, name); } if (expr.getText().equals(name)) { possibleNames.remove(name); } } if (expr instanceof GrMethodCallExpression) { generateNameByExpr( ((GrMethodCallExpression) expr).getInvokedExpression(), possibleNames, validator, forStaticVariable); } if (expr instanceof GrLiteral) { final Object value = ((GrLiteral) expr).getValue(); if (value instanceof String) { generateNameByString( possibleNames, (String) value, validator, forStaticVariable, expr.getProject()); } } }
@Nullable public static GrExpression replaceExpression( GrExpression oldExpr, GrExpression newExpr, boolean removeUnnecessaryParentheses) { PsiElement oldParent = oldExpr.getParent(); if (oldParent == null) throw new PsiInvalidElementAccessException(oldExpr); if (!(oldExpr instanceof GrApplicationStatement)) { newExpr = ApplicationStatementUtil.convertToMethodCallExpression(newExpr); } // Remove unnecessary parentheses if (removeUnnecessaryParentheses && oldParent instanceof GrParenthesizedExpression && !(oldParent.getParent() instanceof GrArgumentLabel)) { return ((GrExpression) oldParent) .replaceWithExpression(newExpr, removeUnnecessaryParentheses); } // regexes cannot be after identifier , try to replace it with simple string if (getRegexAtTheBeginning(newExpr) != null && isAfterIdentifier(oldExpr)) { final PsiElement copy = newExpr.copy(); final GrLiteral regex = getRegexAtTheBeginning(copy); LOG.assertTrue(regex != null); final GrLiteral stringLiteral = GrStringUtil.createStringFromRegex(regex); if (regex == copy) { return oldExpr.replaceWithExpression(stringLiteral, removeUnnecessaryParentheses); } else { regex.replace(stringLiteral); return oldExpr.replaceWithExpression((GrExpression) copy, removeUnnecessaryParentheses); } } GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(oldExpr.getProject()); if (oldParent instanceof GrStringInjection) { if (newExpr instanceof GrString || newExpr instanceof GrLiteral && ((GrLiteral) newExpr).getValue() instanceof String) { return GrStringUtil.replaceStringInjectionByLiteral( (GrStringInjection) oldParent, (GrLiteral) newExpr); } else { newExpr = factory.createExpressionFromText("{" + newExpr.getText() + "}"); oldParent.getNode().replaceChild(oldExpr.getNode(), newExpr.getNode()); return newExpr; } } if (PsiTreeUtil.getParentOfType(oldExpr, GrStringInjection.class, false, GrCodeBlock.class) != null) { final PsiElement replaced = oldExpr.replace(newExpr); final GrStringInjection stringInjection = PsiTreeUtil.getParentOfType(replaced, GrStringInjection.class); GrStringUtil.wrapInjection(stringInjection); assert stringInjection != null; return stringInjection.getClosableBlock(); } // check priorities if (oldParent instanceof GrExpression && !(oldParent instanceof GrParenthesizedExpression)) { GrExpression addedParenth = addParenthesesIfNeeded(newExpr, oldExpr, (GrExpression) oldParent); if (newExpr != addedParenth) { return oldExpr.replaceWithExpression(addedParenth, removeUnnecessaryParentheses); } } // if replace closure argument with expression // we should add the expression in arg list if (oldExpr instanceof GrClosableBlock && !(newExpr instanceof GrClosableBlock) && oldParent instanceof GrMethodCallExpression && ArrayUtil.contains( oldExpr, ((GrMethodCallExpression) oldParent).getClosureArguments())) { return ((GrMethodCallExpression) oldParent) .replaceClosureArgument((GrClosableBlock) oldExpr, newExpr); } newExpr = (GrExpression) oldExpr.replace(newExpr); // if newExpr is the first grand child of command argument list we should replace command arg // list with parenthesised arg list. // In other case the code will be broken. So we try to find wrapping command arg list counting // levels. After arg list replace we go inside it // to find target parenthesised expression. if (newExpr instanceof GrParenthesizedExpression && isFirstChild(newExpr)) { int parentCount = 0; PsiElement element = oldParent; while (element != null && !(element instanceof GrCommandArgumentList)) { if (element instanceof GrCodeBlock || element instanceof GrParenthesizedExpression) break; if (element instanceof PsiFile) break; final PsiElement parent = element.getParent(); if (parent == null) break; if (!isFirstChild(element)) break; element = parent; parentCount++; } if (element instanceof GrCommandArgumentList) { final GrCommandArgumentList commandArgList = (GrCommandArgumentList) element; final PsiElement parent = commandArgList.getParent(); LOG.assertTrue(parent instanceof GrApplicationStatement); final GrMethodCall methodCall = factory.createMethodCallByAppCall((GrApplicationStatement) parent); final GrMethodCall newCall = (GrMethodCall) parent.replace(methodCall); PsiElement result = newCall.getArgumentList().getAllArguments()[0]; for (int i = 0; i < parentCount; i++) { result = PsiUtil.skipWhitespacesAndComments(result.getFirstChild(), true); } LOG.assertTrue(result instanceof GrParenthesizedExpression); return (GrExpression) result; } } return newExpr; }