use of org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo in project intellij-community by JetBrains.
the class ExtractUtil method mustAddVariableDeclaration.
/*
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<>();
for (VariableInfo var : vars) {
names.put(var.getName(), var);
}
List<VariableInfo> result = new ArrayList<>();
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[statements.length - 1], varName) == null) {
result.add(names.get(varName));
}
}
return result;
}
use of org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo in project intellij-community by JetBrains.
the class ExtractUtil method generateBody.
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<>();
for (ParameterInfo info : infos) {
declaredVars.add(info.getName());
}
for (VariableInfo info : mustAddVariableDeclaration(helper.getStatements(), outputInfos)) {
declaredVars.add(info.getName());
}
List<VariableInfo> genDecl = new ArrayList<>();
final Collection<GrVariable> outside = collectUsedLocalVarsOrParamsDeclaredOutside(helper);
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');
}
final StringPartInfo stringPartInfo = helper.getStringPartInfo();
if (!isSingleExpression(helper.getStatements()) && stringPartInfo == null) {
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 = stringPartInfo != null ? stringPartInfo.createLiteralFromSelected() : (GrExpression) PsiUtil.skipParentheses(helper.getStatements()[0], false);
boolean addReturn = !isVoid && forceReturn && !PsiUtil.isVoidMethodCall(expr);
if (addReturn) {
buffer.append("return ");
final GrExpression methodCall = ApplicationStatementUtil.convertToMethodCallExpression(expr);
buffer.append(methodCall.getText());
} else {
buffer.append(expr != null ? expr.getText() : "");
}
}
}
use of org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.VariableInfo in project intellij-community by JetBrains.
the class GroovyExtractChooser method buildInfo.
@NotNull
private static InitialInfo buildInfo(@NotNull Project project, @NotNull PsiFile file, int start, int end, boolean forceStatements, @NotNull SelectionModel selectionModel, @Nullable GrVariable variable) throws GrRefactoringError {
PsiElement[] elements = getElementsInOffset(file, start, end, forceStatements);
//if (elements.length == 1 && elements[0] instanceof GrExpression) {
// selectionModel.setSelection(start, elements[0].getTextRange().getEndOffset());
//}
GrStatement[] statements = getStatementsByElements(elements);
if (statements.length == 0) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.should.represent.a.statement.set"));
}
for (GrStatement statement : statements) {
if (GroovyRefactoringUtil.isSuperOrThisCall(statement, true, true)) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.contains.invocation.of.another.class.constructor"));
}
}
GrStatement statement0 = statements[0];
PsiClass owner = PsiUtil.getContextClass(statement0);
GrStatementOwner declarationOwner = GroovyRefactoringUtil.getDeclarationOwner(statement0);
if (owner == null || declarationOwner == null && !ExtractUtil.isSingleExpression(statements)) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("refactoring.is.not.supported.in.the.current.context"));
}
if (declarationOwner == null && ExtractUtil.isSingleExpression(statements) && statement0 instanceof GrExpression && PsiType.VOID.equals(((GrExpression) statement0).getType())) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.expression.has.void.type"));
}
if (ExtractUtil.isSingleExpression(statements) && GrIntroduceHandlerBase.expressionIsIncorrect((GrExpression) statement0, true)) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.should.represent.an.expression"));
}
if (ExtractUtil.isSingleExpression(statements) && statement0.getParent() instanceof GrAssignmentExpression && ((GrAssignmentExpression) statement0.getParent()).getLValue() == statement0) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.expression.should.not.be.lvalue"));
}
// collect information about return statements in selected statement set
Set<GrStatement> allReturnStatements = new HashSet<>();
GrControlFlowOwner controlFlowOwner = ControlFlowUtils.findControlFlowOwner(statement0);
LOG.assertTrue(controlFlowOwner != null);
final Instruction[] flow = new ControlFlowBuilder(project, GrAllVarsInitializedPolicy.getInstance()).buildControlFlow(controlFlowOwner);
allReturnStatements.addAll(ControlFlowUtils.collectReturns(flow, true));
ArrayList<GrStatement> returnStatements = new ArrayList<>();
for (GrStatement returnStatement : allReturnStatements) {
for (GrStatement statement : statements) {
if (PsiTreeUtil.isAncestor(statement, returnStatement, false)) {
returnStatements.add(returnStatement);
break;
}
}
}
// collect information about variables in selected block
FragmentVariableInfos fragmentVariableInfos = ReachingDefinitionsCollector.obtainVariableFlowInformation(statement0, statements[statements.length - 1], controlFlowOwner, flow);
VariableInfo[] inputInfos = fragmentVariableInfos.getInputVariableNames();
VariableInfo[] outputInfos = fragmentVariableInfos.getOutputVariableNames();
if (outputInfos.length == 1 && !returnStatements.isEmpty()) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("multiple.output.values"));
}
boolean hasInterruptingStatements = false;
for (GrStatement statement : statements) {
hasInterruptingStatements = GroovyRefactoringUtil.hasWrongBreakStatements(statement) || GroovyRefactoringUtil.hasWrongContinueStatements(statement);
if (hasInterruptingStatements)
break;
}
// must be replaced by return statement
boolean hasReturns = !returnStatements.isEmpty();
List<GrStatement> returnStatementsCopy = new ArrayList<>(returnStatements.size());
returnStatementsCopy.addAll(returnStatements);
boolean isReturnStatement = isReturnStatement(statements[statements.length - 1], returnStatementsCopy);
boolean isLastStatementOfMethod = isLastStatementOfMethodOrClosure(statements);
if (hasReturns && !isLastStatementOfMethod && !isReturnStatement || hasInterruptingStatements) {
throw new GrRefactoringError(GroovyRefactoringBundle.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow"));
}
return new InitialInfo(inputInfos, outputInfos, elements, statements, returnStatements, null, project, variable);
}
Aggregations