/* To declare or not a variable to which method call result will be assigned. */ private static List<VariableInfo> mustAddVariableDeclaration( @NotNull GrStatement[] statements, @NotNull VariableInfo[] vars) { Map<String, VariableInfo> names = new HashMap<String, VariableInfo>(); for (VariableInfo var : vars) { names.put(var.getName(), var); } List<VariableInfo> result = new ArrayList<VariableInfo>(); for (GrStatement statement : statements) { if (statement instanceof GrVariableDeclaration) { GrVariableDeclaration declaration = (GrVariableDeclaration) statement; for (GrVariable variable : declaration.getVariables()) { final VariableInfo removed = names.remove(variable.getName()); if (removed != null) { result.add(removed); } } } } for (String varName : names.keySet()) { if (ResolveUtil.resolveProperty(statements[0], varName) == null) { result.add(names.get(varName)); } } return result; }
public static void removeVariable(GrVariable variable) { final GrVariableDeclaration varDecl = (GrVariableDeclaration) variable.getParent(); final List<GrVariable> variables = Arrays.asList(varDecl.getVariables()); if (!variables.contains(variable)) { throw new IllegalArgumentException(); } final PsiElement parent = varDecl.getParent(); final ASTNode owner = parent.getNode(); if (variables.size() == 1 && owner != null) { PsiElement next = varDecl.getNextSibling(); // remove redundant semicolons //noinspection ConstantConditions while (next != null && next.getNode() != null && next.getNode().getElementType() == mSEMI) { PsiElement tmpNext = next.getNextSibling(); //noinspection ConstantConditions next.delete(); next = tmpNext; } removeNewLineAfter(varDecl); varDecl.delete(); return; } variable.delete(); }
public GrInplaceConstantIntroducer( GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) { super(IntroduceConstantHandler.REFACTORING_NAME, choice, context); myContext = context; myPanel = new GrInplaceIntroduceConstantPanel(); GrVariable localVar = GrIntroduceHandlerBase.resolveLocalVar(context); if (localVar != null) { ArrayList<String> result = ContainerUtil.newArrayList(localVar.getName()); GrExpression initializer = localVar.getInitializerGroovy(); if (initializer != null) { ContainerUtil.addAll( result, GroovyNameSuggestionUtil.suggestVariableNames( initializer, new GroovyInplaceFieldValidator(context), true)); } mySuggestedNames = ArrayUtil.toStringArray(result); } else { GrExpression expression = context.getExpression(); assert expression != null; mySuggestedNames = GroovyNameSuggestionUtil.suggestVariableNames( expression, new GroovyInplaceFieldValidator(context), true); } }
@Override protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { final GrMethodCallExpression expression = (GrMethodCallExpression) element; final GrClosableBlock block = expression.getClosureArguments()[0]; final GrParameterList parameterList = block.getParameterList(); final GrParameter[] parameters = parameterList.getParameters(); String var; if (parameters.length == 1) { var = parameters[0].getText(); var = StringUtil.replace(var, GrModifier.DEF, ""); } else { var = "it"; } final GrExpression invokedExpression = expression.getInvokedExpression(); GrExpression qualifier = ((GrReferenceExpression) invokedExpression).getQualifierExpression(); final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(element.getProject()); if (qualifier == null) { qualifier = elementFactory.createExpressionFromText("this"); } StringBuilder builder = new StringBuilder(); builder.append("for (").append(var).append(" in ").append(qualifier.getText()).append(") {\n"); String text = block.getText(); final PsiElement blockArrow = block.getArrow(); int index; if (blockArrow != null) { index = blockArrow.getStartOffsetInParent() + blockArrow.getTextLength(); } else { index = 1; } while (index < text.length() && Character.isWhitespace(text.charAt(index))) index++; text = text.substring(index, text.length() - 1); builder.append(text); builder.append("}"); final GrStatement statement = elementFactory.createStatementFromText(builder.toString()); GrForStatement forStatement = (GrForStatement) expression.replaceWithStatement(statement); final GrForClause clause = forStatement.getClause(); GrVariable variable = clause.getDeclaredVariable(); forStatement = updateReturnStatements(forStatement); if (variable == null) return; if (ApplicationManager.getApplication().isUnitTestMode()) return; final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project); final Document doc = documentManager.getDocument(element.getContainingFile()); if (doc == null) return; documentManager.doPostponedOperationsAndUnblockDocument(doc); editor.getCaretModel().moveToOffset(variable.getTextOffset()); new VariableInplaceRenamer(variable, editor).performInplaceRename(); }
@Override protected void checkVariable(@NotNull GrVariable variable) throws GrRefactoringError { final GrExpression initializer = variable.getInitializerGroovy(); if (initializer == null) { throw new GrRefactoringError( RefactoringBundle.message("variable.does.not.have.an.initializer", variable.getName())); } checkExpression(initializer); }
private void flushForeachLoopVariable(@Nullable GrForClause clause) { if (clause instanceof GrForInClause) { GrVariable variable = clause.getDeclaredVariable(); if (variable != null && myPolicy.isVariableInitialized(variable)) { addNodeAndCheckPending( new ReadWriteVariableInstruction(variable.getName(), variable, WRITE)); } } }
private static void appendInferredType( PsiElement originalElement, GrVariable variable, StringBuilder buffer) { PsiType inferredType = null; if (PsiImplUtil.isWhiteSpaceOrNls(originalElement)) { originalElement = PsiTreeUtil.prevLeaf(originalElement); } if (originalElement != null && originalElement.getNode().getElementType() == GroovyTokenTypes.mIDENT) { originalElement = originalElement.getParent(); } if (originalElement instanceof GrReferenceExpression) { inferredType = ((GrReferenceExpression) originalElement).getType(); } else if (originalElement instanceof GrVariableDeclaration) { inferredType = variable.getTypeGroovy(); } else if (originalElement instanceof GrVariable) { inferredType = ((GrVariable) originalElement).getTypeGroovy(); } if (inferredType != null) { buffer.append("[inferred type] "); appendTypeString(buffer, inferredType, originalElement); } else { buffer.append("[cannot infer type]"); } }
@Nullable private static String getTypeText(GrVariable var) { final PsiType type = var.getTypeGroovy(); if (type == null) return null; return type.getCanonicalText(); }
public void visitVariable(GrVariable variable) { super.visitVariable(variable); if (myPolicy.isVariableInitialized(variable)) { ReadWriteVariableInstruction writeInst = new ReadWriteVariableInstruction(variable.getName(), variable, WRITE); addNodeAndCheckPending(writeInst); } }
private NameSuggestionsField createNameField(GrVariable var) { List<String> names = new ArrayList<String>(); if (var != null) { names.add(var.getName()); } ContainerUtil.addAll(names, suggestNames()); return new NameSuggestionsField( ArrayUtil.toStringArray(names), myProject, GroovyFileType.GROOVY_FILE_TYPE); }
@Nullable private static PsiType getLeastUpperBoundByVar(final GrVariable resolved) { CachedValue<PsiType> data = resolved.getUserData(LEAST_UPPER_BOUND_TYPE); if (data == null) { data = CachedValuesManager.getManager(resolved.getProject()) .createCachedValue( new CachedValueProvider<PsiType>() { @Override public Result<PsiType> compute() { return Result.create( getLeastUpperBoundByVarImpl(resolved), PsiModificationTracker.MODIFICATION_COUNT, ProjectRootManager.getInstance(resolved.getProject())); } }, false); } return data.getValue(); }
@Override public GrTypeElement getTypeElementGroovyForVariable(GrVariable var) { if (isTuple()) { final PsiElement psiElement = PsiUtil.skipWhitespacesAndComments(var.getPrevSibling(), false); if (psiElement instanceof GrTypeElement) { return (GrTypeElement) psiElement; } return null; } else { return getTypeElementGroovy(); } }
private void alignVariableDeclarations(List<GrStatement> group, boolean classLevel) { AlignmentProvider.Aligner typeElement = myAlignmentProvider.createAligner(true); AlignmentProvider.Aligner varName = myAlignmentProvider.createAligner(true); AlignmentProvider.Aligner eq = myAlignmentProvider.createAligner(true); for (GrStatement statement : group) { GrVariableDeclaration varDeclaration = (GrVariableDeclaration) statement; GrVariable[] variables = varDeclaration.getVariables(); for (GrVariable variable : variables) { varName.append(variable.getNameIdentifierGroovy()); } if (classLevel && mySettings.ALIGN_GROUP_FIELD_DECLARATIONS) { typeElement.append(varDeclaration.getTypeElementGroovy()); ASTNode current_eq = variables[variables.length - 1].getNode().findChildByType(GroovyTokenTypes.mASSIGN); if (current_eq != null) { eq.append(current_eq.getPsi()); } } } }
@NotNull public LinkedHashSet<String> suggestNames() { final GrExpression expression = myContext.getExpression(); final GrVariable var = myContext.getVar(); final StringPartInfo stringPart = myContext.getStringPart(); if (expression != null) { return new LinkedHashSet<String>( Arrays.asList( GroovyNameSuggestionUtil.suggestVariableNames(expression, myValidator, myForStatic))); } else if (stringPart != null) { return new LinkedHashSet<String>( Arrays.asList( GroovyNameSuggestionUtil.suggestVariableNames( stringPart.getLiteral(), myValidator, myForStatic))); } else { assert var != null; return new LinkedHashSet<String>( Arrays.asList( GroovyNameSuggestionUtil.suggestVariableNameByType(var.getType(), myValidator))); } }
private GrTypeComboBox createTypeComboBox( GrVariable var, GrExpression expr, StringPartInfo stringPartInfo) { GrTypeComboBox box; if (var != null) { box = GrTypeComboBox.createTypeComboBoxWithDefType(var.getDeclaredType(), var); } else if (expr != null) { box = GrTypeComboBox.createTypeComboBoxFromExpression(expr); } else if (stringPartInfo != null) { box = GrTypeComboBox.createTypeComboBoxFromExpression(stringPartInfo.getLiteral()); } else { box = GrTypeComboBox.createEmptyTypeComboBox(); } box.addClosureTypesFrom(inferClosureReturnType(), myInfo.getContext()); if (expr == null && var == null && stringPartInfo == null) { box.setSelectedIndex(box.getItemCount() - 1); } return box; }
private static boolean variablesAreEquivalent( @NotNull GrVariable var1, @NotNull GrVariable var2) { final GrExpression initializer1 = (GrExpression) var1.getInitializer(); final GrExpression initializer2 = (GrExpression) var2.getInitializer(); if (!expressionsAreEquivalent(initializer1, initializer2)) { return false; } final PsiType type1 = var1.getType(); final PsiType type2 = var2.getType(); if (!typesAreEquivalent(type1, type2)) { return false; } final String name1 = var1.getName(); final String name2 = var2.getName(); if (name1 == null) { return name2 == null; } return name1.equals(name2); }
public static void generateBody( ExtractInfoHelper helper, boolean isVoid, StringBuilder buffer, boolean forceReturn) { VariableInfo[] outputInfos = helper.getOutputVariableInfos(); ParameterInfo[] infos = helper.getParameterInfos(); Set<String> declaredVars = new HashSet<String>(); for (ParameterInfo info : infos) { declaredVars.add(info.getName()); } for (VariableInfo info : mustAddVariableDeclaration(helper.getStatements(), outputInfos)) { declaredVars.add(info.getName()); } List<VariableInfo> genDecl = new ArrayList<VariableInfo>(); final Collection<GrVariable> outside = collectUsedLocalVarsOrParamsDeclaredOutside(helper.getStatements()); for (final GrVariable variable : outside) { if (!declaredVars.contains(variable.getName())) { genDecl.add( new VariableInfo() { @NotNull @Override public String getName() { return variable.getName(); } @Override public PsiType getType() { return variable.getDeclaredType(); } }); } } final List<GrStatement> statements = generateVarDeclarations(genDecl, helper.getProject(), null); for (GrStatement statement : statements) { buffer.append(statement.getText()).append('\n'); } if (!isSingleExpression(helper.getStatements()) || statements.size() > 0) { for (PsiElement element : helper.getInnerElements()) { buffer.append(element.getText()); } // append return statement if (!isVoid && outputInfos.length > 0) { buffer.append('\n'); if (forceReturn) { buffer.append("return "); } if (outputInfos.length > 1) buffer.append('['); for (VariableInfo info : outputInfos) { buffer.append(info.getName()).append(", "); } buffer.delete(buffer.length() - 2, buffer.length()); if (outputInfos.length > 1) buffer.append(']'); } } else { GrExpression expr = (GrExpression) PsiUtil.skipParentheses(helper.getStatements()[0], false); boolean addReturn = !isVoid && forceReturn; if (addReturn) { buffer.append("return "); expr = ApplicationStatementUtil.convertToMethodCallExpression(expr); buffer.append(expr.getText()); } else { buffer.append(expr != null ? expr.getText() : ""); } } }
private void calculateAlignments(List<ASTNode> children, boolean classLevel) { List<Alignment> currentGroup = null; for (ASTNode child : children) { PsiElement psi = child.getPsi(); if (psi instanceof GrLabeledStatement) { List<LeafPsiElement> table = getSpockTable(((GrLabeledStatement) psi).getStatement()); if (table.isEmpty()) { currentGroup = null; } else { currentGroup = new ArrayList<Alignment>(); for (LeafPsiElement expression : table) { Alignment alignment = Alignment.createAlignment(true); currentGroup.add(alignment); ContainerUtil.putIfNotNull(expression, alignment, myInnerAlignments); } } } else if (currentGroup != null && isTablePart(psi)) { List<LeafPsiElement> table = getSpockTable((GrStatement) psi); for (int i = 0; i < Math.min(table.size(), currentGroup.size()); i++) { myInnerAlignments.put(table.get(i), currentGroup.get(i)); } } else if (psi instanceof GrVariableDeclaration) { if (!classLevel || currentGroup == null || fieldGroupEnded(psi)) { currentGroup = Arrays.asList( Alignment.createAlignment(true), Alignment.createAlignment(true), Alignment.createAlignment(true)); } GrVariable[] variables = ((GrVariableDeclaration) psi).getVariables(); if (variables.length > 0) { Alignment varName = currentGroup.get(1); for (GrVariable variable : variables) { myInnerAlignments.put(variable.getNameIdentifierGroovy(), varName); } if (classLevel && mySettings.ALIGN_GROUP_FIELD_DECLARATIONS) { ContainerUtil.putIfNotNull( ((GrVariableDeclaration) psi).getTypeElementGroovy(), currentGroup.get(0), myInnerAlignments); ASTNode eq = variables[variables.length - 1].getNode().findChildByType(GroovyTokenTypes.mASSIGN); if (eq != null) { myInnerAlignments.put(eq.getPsi(), currentGroup.get(2)); } } } } else if (GeeseUtil.isClosureRBrace(psi) && myGroovySettings.USE_FLYING_GEESE_BRACES) { myInnerAlignments.put(psi, GeeseUtil.calculateRBraceAlignment(psi, myInnerAlignments)); } else { if (psi instanceof PsiComment) { PsiElement prev = psi.getPrevSibling(); if (prev != null && prev.getNode().getElementType() != mNLS || classLevel && !fieldGroupEnded(psi)) { continue; } } currentGroup = null; } } }
@Override protected void performRefactoring(UsageInfo[] usages) { GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); PsiType initializerType = mySettings.getSelectedType(); // Changing external occurrences (the tricky part) IntroduceParameterUtil.processUsages(usages, this); final GrMethod toReplaceIn = (GrMethod) mySettings.getToReplaceIn(); final PsiMethod toSearchFor = (PsiMethod) mySettings.getToSearchFor(); final boolean methodsToProcessAreDifferent = toReplaceIn != toSearchFor; if (mySettings.generateDelegate()) { GroovyIntroduceParameterUtil.generateDelegate(toReplaceIn, myParameterInitializer, myProject); if (methodsToProcessAreDifferent) { final GrMethod method = GroovyIntroduceParameterUtil.generateDelegate( toSearchFor, myParameterInitializer, myProject); final PsiClass containingClass = method.getContainingClass(); if (containingClass != null && containingClass.isInterface()) { final GrOpenBlock block = method.getBlock(); if (block != null) { block.delete(); } } } } // Changing signature of initial method // (signature of myMethodToReplaceIn will be either changed now or have already been changed) LOG.assertTrue(initializerType == null || initializerType.isValid()); final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(mySettings.getName(), toReplaceIn.getBlock()); IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts( new UsageInfo(toReplaceIn), usages, this); if (methodsToProcessAreDifferent) { IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts( new UsageInfo(toSearchFor), usages, this); } // Replacing expression occurrences for (UsageInfo usage : usages) { if (usage instanceof ChangedMethodCallInfo) { PsiElement element = usage.getElement(); GroovyIntroduceParameterUtil.processChangedMethodCall(element, mySettings, myProject); } else if (usage instanceof InternalUsageInfo) { PsiElement element = usage.getElement(); if (element == null) continue; GrExpression newExpr = factory.createExpressionFromText(mySettings.getName()); if (element instanceof GrExpression) { ((GrExpression) element).replaceWithExpression(newExpr, true); } else { element.replace(newExpr); } } } final StringPartInfo stringPartInfo = mySettings.getStringPartInfo(); if (stringPartInfo != null) { final GrExpression expr = GrIntroduceHandlerBase.processLiteral( mySettings.getName(), mySettings.getStringPartInfo(), mySettings.getProject()); final Editor editor = PsiUtilBase.findEditor(expr); if (editor != null) { editor.getSelectionModel().removeSelection(); editor.getCaretModel().moveToOffset(expr.getTextRange().getEndOffset()); } } final GrVariable var = mySettings.getVar(); if (var != null && mySettings.removeLocalVariable()) { var.delete(); } fieldConflictsResolver.fix(); }
private void writeTupleDeclaration( GrVariableDeclaration variableDeclaration, StringBuilder builder, ExpressionContext expressionContext) { GrVariable[] variables = variableDeclaration.getVariables(); final GrExpression tupleInitializer = variableDeclaration.getTupleInitializer(); if (tupleInitializer instanceof GrListOrMap) { for (GrVariable variable : variables) { writeVariableSeparately(variable, builder, expressionContext); builder.append(";\n"); } } else if (tupleInitializer != null) { GroovyResolveResult iteratorMethodResult = resolveMethod( tupleInitializer, "iterator", GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, GrClosableBlock.EMPTY_ARRAY, variableDeclaration); final PsiType iteratorType = inferIteratorType(iteratorMethodResult, tupleInitializer); final String iteratorName = genIteratorVar( variableDeclaration, builder, expressionContext, tupleInitializer, iteratorType, iteratorMethodResult); final GrModifierList modifierList = variableDeclaration.getModifierList(); PsiType iterableTypeParameter = PsiUtil.extractIterableTypeParameter(iteratorType, false); for (final GrVariable v : variables) { ModifierListGenerator.writeModifiers(builder, modifierList); final PsiType type = context.typeProvider.getVarType(v); writeType(builder, type, variableDeclaration); builder.append(' ').append(v.getName()); builder.append(" = "); wrapInCastIfNeeded( builder, type, iterableTypeParameter, tupleInitializer, expressionContext, new StatementWriter() { @Override public void writeStatement(StringBuilder builder, ExpressionContext context) { builder .append(iteratorName) .append(".hasNext() ? ") .append(iteratorName) .append(".next() : null"); } }); builder.append(";\n"); } } else { writeSimpleVarDeclaration(variableDeclaration, builder, expressionContext); } }
private static void writeVariableWithoutSemicolonAndInitializer( StringBuilder builder, GrVariable var, ExpressionContext context) { ModifierListGenerator.writeModifiers(builder, var.getModifierList()); writeType(builder, context.typeProvider.getVarType(var), var); builder.append(' ').append(var.getName()); }
public void visitVariable(GrVariable variable) { if (myExpression.equals(variable.getInitializerGroovy())) { PsiType type = variable.getType(); myResult = createSimpleSubTypeResult(type); } }