diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index f8c016341883..02866d216848 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -990,7 +990,7 @@ public class HighlightUtil { HighlightInfo errorResult = null; if (expression != null && expression.getType() != null) { PsiType type = expression.getType(); - if (!isValidTypeForSwitchSelector(type, expression)) { + if (!isValidTypeForSwitchSelector(type, PsiUtil.isLanguageLevel7OrHigher(expression))) { String message = JavaErrorMessages.message("incompatible.types", JavaErrorMessages.message("valid.switch.selector.types"), formatType(type)); errorResult = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, expression, message); @@ -1002,7 +1002,7 @@ public class HighlightUtil { return errorResult; } - private static boolean isValidTypeForSwitchSelector(PsiType type, PsiExpression expression) { + public static boolean isValidTypeForSwitchSelector(PsiType type, final boolean languageLevel7OrHigher) { if (TypeConversionUtil.getTypeRank(type) <= TypeConversionUtil.INT_RANK) return true; if (type instanceof PsiClassType) { PsiClass psiClass = ((PsiClassType)type).resolve(); @@ -1010,7 +1010,7 @@ public class HighlightUtil { if (psiClass.isEnum()) { return true; } - if (PsiUtil.isLanguageLevel7OrHigher(expression)) { + if (languageLevel7OrHigher) { return Comparing.strEqual(psiClass.getQualifiedName(), CommonClassNames.JAVA_LANG_STRING); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java index 93191c92549d..da3520067bcf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java @@ -24,7 +24,6 @@ import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.actions.BaseRefactoringAction; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.refactoring.convertToJava.ConvertToJavaHandler; /** @@ -49,14 +48,11 @@ public class ConvertToJavaAction extends BaseRefactoringAction { @Override protected boolean isEnabledOnElements(PsiElement[] elements) { + for (PsiElement element : elements) { - if (element instanceof GrTypeDefinition) { final PsiFile containingFile = element.getContainingFile(); - if (containingFile instanceof GroovyFile && ((GroovyFile)containingFile).getClasses().length == 1) continue; + if (containingFile instanceof GroovyFile) continue; return false; - } - if (element instanceof GroovyFile) continue; - return false; } return true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java index f4d17aa06754..b434373731a2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java @@ -632,7 +632,10 @@ public abstract class GroovyRefactoringUtil { argText.append(argument.getText()).append(", "); argument.delete(); } - argText.replace(argText.length() - 2, argText.length(), "]"); + if (arguments.size() > 0) { + argText.delete(argText.length() - 2, argText.length()); + } + argText.append("]"); if (type instanceof PsiArrayType) { type = substitutor.substitute(type); String typeText = type.getCanonicalText(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java index a7197c918cc3..be909e23cc79 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java @@ -17,10 +17,8 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; -import com.intellij.psi.CommonClassNames; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; +import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrCondition; @@ -31,18 +29,18 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrAssertStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrFlowInterruptingStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrThrowStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForClause; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; +import java.util.Set; + /** * @author Maxim.Medvedev */ @@ -51,28 +49,15 @@ public class CodeBlockGenerator extends Generator { private final StringBuilder builder; private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.refactoring.convertToJava.CodeBlockGenerator"); - private final boolean insertStatementsFromExpr; - private final ExpressionContext context; - public CodeBlockGenerator(StringBuilder builder, Project project) { - this(builder, project, false); - } - - public CodeBlockGenerator(StringBuilder builder, Project project, boolean insertStatementsFromExpr) { - this(builder, insertStatementsFromExpr, new ExpressionContext(project)); - } - - public CodeBlockGenerator(StringBuilder builder, - boolean insertStatementsFromExpr, - ExpressionContext context) { + public CodeBlockGenerator(StringBuilder builder, ExpressionContext context) { this.builder = builder; - this.insertStatementsFromExpr = insertStatementsFromExpr; this.context = context; } - public CodeBlockGenerator(StringBuilder builder, ExpressionContext context) { - this(builder, false, context); + public CodeBlockGenerator(StringBuilder builder, Project project) { + this(builder, new ExpressionContext(project)); } @Override @@ -126,32 +111,10 @@ public class CodeBlockGenerator extends Generator { writeStatement(statementBuilder, statement, null); } - private void writeStatement(StringBuilder statementBuilder, GrStatement statement, @Nullable ExpressionContext context) { - final PsiElement parent = statement.getParent(); - - final boolean addParentheses = - insertStatementsFromExpr && context != null && context.myStatements.size() > 0 && parent instanceof GrControlStatement; - if (addParentheses) { - builder.append("{\n"); - } - - if (insertStatementsFromExpr) { - if (context != null) { - for (String st : context.myStatements) { - builder.append(st).append("\n"); - } - } - } - else { - LOG.assertTrue(context != null); - LOG.assertTrue(context.myStatements.size() == 0); - context.myStatements.addAll(context.myStatements); - } - - builder.append(statementBuilder); - if (addParentheses) { - builder.append("}\n"); - } + private void writeStatement(StringBuilder statementBuilder, + GrStatement statement, + @Nullable ExpressionContext context) { + GenerationUtil.writeStatement(builder, statementBuilder, statement, context); } @Override @@ -191,9 +154,15 @@ public class CodeBlockGenerator extends Generator { final StringBuilder statementBuilder = new StringBuilder(); final ExpressionContext context = new ExpressionContext(this.context.project, this.context.myUsedVarNames); expression.accept(new ExpressionGenerator(statementBuilder, context)); + statementBuilder.append(";"); writeStatement(statementBuilder, expression, context); } + @Override + public void visitApplicationStatement(GrApplicationStatement applicationStatement) { + visitExpression(applicationStatement); + } + @Override public void visitTypeDefinition(GrTypeDefinition typeDefinition) { //todo ??????? @@ -231,7 +200,7 @@ public class CodeBlockGenerator extends Generator { LOG.assertTrue(declaredVariable != null); builder.append("for("); - writeVariableWithoutColon(builder, declaredVariable); + writeVariableWithoutSemicolonAndInitializer(builder, declaredVariable); builder.append(" : "); if (expression != null) { final ExpressionContext context = forContext.copy(); @@ -247,7 +216,7 @@ public class CodeBlockGenerator extends Generator { if (initialization instanceof GrParameter) { StringBuilder partBuilder = new StringBuilder(); - writeVariableWithoutColon(partBuilder, (GrParameter)initialization); + writeVariableWithoutSemicolonAndInitializer(partBuilder, (GrParameter)initialization); final GrExpression initializer = ((GrParameter)initialization).getDefaultInitializer(); if (initializer != null) { final ExpressionContext partContext = forContext.copy(); @@ -293,11 +262,11 @@ public class CodeBlockGenerator extends Generator { builder.append(visitor.getBuilder()); } - private static void writeVariableWithoutColon(StringBuilder builder, GrVariable var) { - if (GenerationUtil.writeModifiers(builder, var.getModifierList(), GenerationUtil.JAVA_MODIFIERS)) { + private static void writeVariableWithoutSemicolonAndInitializer(StringBuilder builder, GrVariable var) { + if (GenerationUtil.writeModifiers(builder, var.getModifierList())) { builder.append(" "); } - GenerationUtil.writeType(builder, var.getDeclaredType()); + GenerationUtil.writeType(builder, getVarType(var)); builder.append(" ").append(var.getName()); } @@ -321,7 +290,10 @@ public class CodeBlockGenerator extends Generator { @Override public void visitSwitchStatement(GrSwitchStatement switchStatement) { - //todo + final StringBuilder builder = new StringBuilder(); + final ExpressionContext copy = context.copy(); + SwitchStatementGenerator.generate(builder, copy, switchStatement); + writeStatement(builder, switchStatement, copy); } @Override @@ -343,7 +315,7 @@ public class CodeBlockGenerator extends Generator { public void visitCatchClause(GrCatchClause catchClause) { final GrParameter parameter = catchClause.getParameter(); builder.append("catch ("); - writeVariableWithoutColon(builder, parameter); + writeVariableWithoutSemicolonAndInitializer(builder, parameter); builder.append(") "); final GrOpenBlock body = catchClause.getBody(); if (body != null) { @@ -379,58 +351,150 @@ public class CodeBlockGenerator extends Generator { @Override public void visitVariableDeclaration(GrVariableDeclaration variableDeclaration) { - final GrModifierList modifierList = variableDeclaration.getModifierList(); - final GrVariable[] variables = variableDeclaration.getVariables(); StringBuilder builder = new StringBuilder(); ExpressionContext expressionContext = context.copy(); - final ExpressionGenerator expressionGenerator = new ExpressionGenerator(builder, expressionContext); if (variableDeclaration.isTuple()) { - final GrTupleDeclaration tuple = variableDeclaration.getTupleDeclaration(); - final GrExpression tupleInitializer = tuple.getInitializerGroovy(); - if (tupleInitializer instanceof GrListOrMap) { - final GrExpression[] initializers = ((GrListOrMap)tupleInitializer).getInitializers(); - for (int i = 0; i < variables.length; i++) { - final GrVariable v = variables[i]; - final PsiType type = v.getDeclaredType(); - GenerationUtil.writeModifiers(builder, modifierList); - GenerationUtil.writeType(builder, type); - builder.append(" ").append(v.getName()); - if (i < initializers.length) { - builder.append(" = "); - initializers[i].accept(expressionGenerator); + writeTupleDeclaration(variableDeclaration, builder, expressionContext); + } + else { + writeSimpleVarDeclaration(variableDeclaration, builder, expressionContext); + } + + writeStatement(builder, variableDeclaration, expressionContext); + } + + private static void writeSimpleVarDeclaration(GrVariableDeclaration variableDeclaration, + StringBuilder builder, + ExpressionContext expressionContext) { + GrVariable[] variables = variableDeclaration.getVariables(); + + final GrTypeElement typeElement = variableDeclaration.getTypeElementGroovy(); + PsiType type = null; + Set types = new HashSet(variables.length); + if (typeElement == null) { + if (variables.length > 1) { + for (GrVariable variable : variables) { + final GrExpression initializer = variable.getInitializerGroovy(); + if (initializer != null) { + final PsiType varType = initializer.getType(); + if (varType != null) { + types.add(getTypeText(varType)); + type = varType; + } } - builder.append(";\n"); + } + if (type == null) { + type = PsiType.getJavaLangObject(variableDeclaration.getManager(), variableDeclaration.getResolveScope()); } } else { - final PsiType iteratorType = - JavaPsiFacade.getElementFactory(context.project).createTypeFromText(CommonClassNames.JAVA_UTIL_ITERATOR, variableDeclaration); - final String iteratorName = GenerationUtil.suggestVarName(iteratorType, variableDeclaration, expressionContext); - builder.append("final ").append(CommonClassNames.JAVA_UTIL_ITERATOR).append(" ").append(iteratorName).append(" = "); - - GenerationUtil.invokeMethodByName(tupleInitializer, "iterator", GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, - GrClosableBlock.EMPTY_ARRAY, expressionGenerator, variableDeclaration); - for (final GrVariable v : variables) { - GenerationUtil.writeModifiers(builder, modifierList); - final PsiType type = v.getDeclaredType(); - GenerationUtil.writeType(builder, type); - builder.append(" ").append(v.getName()); - builder.append(" = ").append(iteratorName).append(".hasNext() ? ").append(iteratorName).append(".next() : null;"); - } + type = getVarType(variables[0]); } } else { - GenerationUtil.writeModifiers(builder, modifierList); - final GrTypeElement typeElement = variableDeclaration.getTypeElementGroovy(); - PsiType type = typeElement == null - ? PsiType.getJavaLangObject(variableDeclaration.getManager(), variableDeclaration.getResolveScope()) - : typeElement.getType(); - GenerationUtil.writeType(builder, type); + type = typeElement.getType(); } - writeStatement(builder, variableDeclaration, expressionContext); + + if (types.size() > 1) { + if (variableDeclaration.getParent() instanceof GrControlStatement) { + expressionContext.setInsertCurlyBrackets(); + } + for (GrVariable variable : variables) { + writeVariableSeparately(variable, builder, expressionContext); + builder.append(";\n"); + } + return; + } + + GenerationUtil.writeType(builder, type); + + builder.append(" "); + for (GrVariable variable : variables) { + writeVariableWithoutType(builder, expressionContext, variable); + builder.append(", "); + } + if (variables.length > 0) { + builder.delete(builder.length() - 2, builder.length()); + } + builder.append(";"); + } + + private static void writeVariableWithoutType(StringBuilder builder, ExpressionContext expressionContext, GrVariable variable) { + builder.append(variable.getName()); + final GrExpression initializer = variable.getInitializerGroovy(); + if (initializer != null) { + builder.append(" = "); + initializer.accept(new ExpressionGenerator(builder, expressionContext)); + } + } + + private static void writeVariableSeparately(GrVariable variable, StringBuilder builder, ExpressionContext expressionContext) { + PsiType type = getVarType(variable); + + if (GenerationUtil.writeModifiers(builder, variable.getModifierList())) { + builder.append(" "); + } + + GenerationUtil.writeType(builder, type); + builder.append(" "); + + writeVariableWithoutType(builder, expressionContext, variable); + } + + private static PsiType getVarType(GrVariable variable) { + PsiType type = variable.getDeclaredType(); + if (type == null) { + type = variable.getTypeGroovy(); + } + if (type == null) { + type = variable.getType(); + } + return type; + } + + private void writeTupleDeclaration(GrVariableDeclaration variableDeclaration, + StringBuilder builder, + ExpressionContext expressionContext) { + GrVariable[] variables = variableDeclaration.getVariables(); + final GrExpression tupleInitializer = variableDeclaration.getTupleDeclaration().getInitializerGroovy(); + if (tupleInitializer instanceof GrListOrMap) { + for (GrVariable variable : variables) { + writeVariableSeparately(variable, builder, expressionContext); + builder.append(";\n"); + } + } + else { + final PsiType iteratorType = + JavaPsiFacade.getElementFactory(context.project).createTypeFromText(CommonClassNames.JAVA_UTIL_ITERATOR, variableDeclaration); + final String iteratorName = GenerationUtil.suggestVarName(iteratorType, variableDeclaration, expressionContext); + builder.append("final ").append(CommonClassNames.JAVA_UTIL_ITERATOR).append(" ").append(iteratorName).append(" = "); + + GenerationUtil.invokeMethodByName(tupleInitializer, "iterator", GrExpression.EMPTY_ARRAY, GrNamedArgument.EMPTY_ARRAY, + GrClosableBlock.EMPTY_ARRAY, new ExpressionGenerator(builder, expressionContext), + variableDeclaration); + final GrModifierList modifierList = variableDeclaration.getModifierList(); + for (final GrVariable v : variables) { + GenerationUtil.writeModifiers(builder, modifierList); + final PsiType type = getVarType(v); + GenerationUtil.writeType(builder, type); + builder.append(" ").append(v.getName()); + builder.append(" = ").append(iteratorName).append(".hasNext() ? ").append(iteratorName).append(".next() : null;"); + } + } + } + + private void writeVariable(GrVariable variable) { + //todo + throw new UnsupportedOperationException(); + } + + private static String getTypeText(PsiType varType) { + final StringBuilder builder = new StringBuilder(); + GenerationUtil.writeType(builder, varType); + return builder.toString(); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java index 48ab2035e270..cde84e1bedf7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaHandler.java @@ -49,7 +49,7 @@ public class ConvertToJavaHandler implements RefactoringActionHandler { invokeInner(project, elements, editor); } - private void invokeInner(Project project, PsiElement[] elements, Editor editor) { + private static void invokeInner(Project project, PsiElement[] elements, Editor editor) { for (PsiElement element : elements) { if (!(element instanceof GroovyFile)) { if (!ApplicationManager.getApplication().isUnitTestMode()) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaProcessor.java index 8a4dca3074d9..c4eeebae5882 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ConvertToJavaProcessor.java @@ -16,13 +16,10 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiDirectory; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiFileFactory; +import com.intellij.psi.*; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.ui.UsageViewDescriptorAdapter; import com.intellij.usageView.UsageInfo; @@ -30,10 +27,9 @@ import com.intellij.usageView.UsageViewDescriptor; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; -import java.util.Collections; -import java.util.Map; import java.util.Set; /** @@ -73,35 +69,44 @@ public class ConvertToJavaProcessor extends BaseRefactoringProcessor { //private static String @Override protected void performRefactoring(UsageInfo[] usages) { - final GroovyToJavaGenerator generator = new GroovyToJavaGenerator(myProject, Collections.emptyList(), true); - final PsiFileFactory fileFactory = PsiFileFactory.getInstance(myProject); +// final GroovyToJavaGenerator generator = new GroovyToJavaGenerator(myProject, Collections.emptyList(), true); - PsiFile fileToOpen = null; for (GroovyFile file : myFiles) { final PsiDirectory dir = file.getContainingDirectory(); LOG.assertTrue(dir != null); - final Map fileMap = generator.generateStubs(file); - for (String fileName : fileMap.keySet()) { - file.delete(); - final PsiFile[] files = dir.getFiles(); - Set fileNames = new HashSet(); - for (PsiFile psiFile : files) { - fileNames.add(psiFile.getName()); - } - int index = 0; - String prefix = FileUtil.getNameWithoutExtension(fileName); - while (fileNames.contains(fileName)) { - fileName = prefix + index + ".java"; - } - - final PsiFile newFile = fileFactory.createFileFromText(fileName, fileMap.get(fileName)); - dir.add(newFile); + final PsiFile[] files = dir.getFiles(); + Set fileNames = new HashSet(); + for (PsiFile psiFile : files) { + fileNames.add(psiFile.getName()); } + String prefix = FileUtil.getNameWithoutExtension(file.getName()); + String fileName = prefix + ".java"; + int index = 1; + while (fileNames.contains(fileName)) { + fileName = prefix + index + ".java"; + } + final Project project = file.getProject(); + + GrTopStatement[] statements = file.getTopStatements(); + final StringBuilder builder = new StringBuilder(); + CodeBlockGenerator generator = new CodeBlockGenerator(builder, new ExpressionContext(project)); + for (GrTopStatement statement : statements) { + statement.accept(generator); + builder.append("\n"); + } + + final PsiFile newFile = (PsiFile)file.setName(fileName); + final Document document = PsiDocumentManager.getInstance(project).getDocument(newFile); + document.setText(builder); + /*final PsiFile created = PsiFileFactory.getInstance(project) + .createFileFromText(file.getScriptClass().getName() + ".java", StdLanguages.JAVA, builder.toString()); + PostprocessReformattingAspect.getInstance(project).doPostponedFormatting(); + file.delete(); + dir.add(created);*/ + //QuickfixUtil.positionCursor(project, created, created.getFirstChild()); } - - } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java index 01a04fa9b598..a333b55290de 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionContext.java @@ -26,6 +26,7 @@ class ExpressionContext { List myStatements = new ArrayList(); Set myUsedVarNames; Project project; + private boolean myShouldInsertCurlyBrackets = false; ExpressionContext(Project project, Set usedVarNames) { this.project = project; @@ -45,4 +46,12 @@ class ExpressionContext { usedVarNames.addAll(myUsedVarNames); return new ExpressionContext(project, usedVarNames); } + + public void setInsertCurlyBrackets() { + myShouldInsertCurlyBrackets = true; + } + + public boolean shouldInsertCurlyBrackets() { + return myShouldInsertCurlyBrackets; + } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java index 3b249bbde3a3..6d1d61cfe394 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.tree.IElementType; @@ -24,9 +25,9 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.intentions.conversions.ConvertGStringToStringIntention; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; -import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; @@ -58,9 +59,6 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; -import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; - -import java.util.*; /** * @author Maxim.Medvedev @@ -324,13 +322,55 @@ public class ExpressionGenerator extends Generator { @Override public void visitAssignmentExpression(GrAssignmentExpression expression) { - //todo + final GrExpression lValue = expression.getLValue(); + GrExpression rValue = expression.getRValue(); + final IElementType token = expression.getOperationToken(); + + + if (token == GroovyTokenTypes.mASSIGN) { + lValue.accept(this); + builder.append(" = "); + if (rValue != null) { + rValue.accept(this); + } + return; + } + + final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false)); + final PsiElement resolved = resolveResult.getElement(); + + if (resolved instanceof PsiMethod) { + lValue.accept(this); + builder.append(" = "); + if (rValue == null) { + rValue = factory.createExpressionFromText("null"); + } + invokeMethodOn( + ((PsiMethod)resolved), + lValue, + new GrExpression[]{rValue}, + GrNamedArgument.EMPTY_ARRAY, + GrClosableBlock.EMPTY_ARRAY, + resolveResult.getSubstitutor(), + expression + ); + } + else { + writeSimpleBinaryExpression(expression.getOpToken(), lValue, rValue); + } } @Override public void visitBinaryExpression(GrBinaryExpression expression) { final GrExpression left = expression.getLeftOperand(); GrExpression right = expression.getRightOperand(); + final PsiType ltype = left.getType(); + if (GenerationSettings.dontReplaceOperatorsWithMethodsForNumbers && + (TypesUtil.isNumericType(ltype) && (right == null || TypesUtil.isNumericType(right.getType())) || + ltype != null && TypesUtil.typeEqualsToText(ltype, CommonClassNames.JAVA_LANG_STRING))) { + writeSimpleBinaryExpression(expression.getOperationToken(), left, right); + return; + } final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(expression.multiResolve(false)); final PsiElement resolved = resolveResult.getElement(); @@ -349,11 +389,17 @@ public class ExpressionGenerator extends Generator { ); } else { - left.accept(this); - builder.append(expression.getOperationToken().getText()); - if (right != null) { - right.accept(this); - } + writeSimpleBinaryExpression(expression.getOperationToken(), left, right); + } + } + + private void writeSimpleBinaryExpression(PsiElement opToken, GrExpression left, GrExpression right) { + left.accept(this); + builder.append(" "); + builder.append(opToken.getText()); + if (right != null) { + builder.append(" "); + right.accept(this); } } @@ -408,8 +454,12 @@ public class ExpressionGenerator extends Generator { else { value = literal.getValue(); } - - //todo + if (value instanceof String) { + builder.append('"').append(StringUtil.escapeQuotes((String)value)).append('"'); + } + else { + builder.append(value); + } } @Override @@ -574,14 +624,13 @@ public class ExpressionGenerator extends Generator { PsiSubstitutor substitutor, GroovyPsiElement context) { if (method instanceof GrGdkMethod && !method.hasModifierProperty(GrModifier.STATIC)) { - LOG.assertTrue(caller != null); - final GrExpression listOrMap = - GroovyRefactoringUtil.generateArgFromMultiArg(PsiSubstitutor.EMPTY, Arrays.asList(namedArgs), null, method.getProject()); - GrExpression[] newArgs = new GrExpression[exprs.length + 2]; - System.arraycopy(exprs, 0, newArgs, 2, exprs.length); + if (caller == null) { + caller = factory.createExpressionFromText("this", context); + } + GrExpression[] newArgs = new GrExpression[exprs.length + 1]; + System.arraycopy(exprs, 0, newArgs, 1, exprs.length); newArgs[0] = caller; - newArgs[1] = listOrMap; - invokeMethodOn(((GrGdkMethod)method).getStaticMethod(), null, newArgs, GrNamedArgument.EMPTY_ARRAY, closures, substitutor, context); + invokeMethodOn(((GrGdkMethod)method).getStaticMethod(), null, newArgs, namedArgs, closures, substitutor, context); return; } @@ -593,9 +642,11 @@ public class ExpressionGenerator extends Generator { } } else { - LOG.assertTrue(caller != null, "instance method call should have caller"); - caller.accept(this); - builder.append("."); + //LOG.assertTrue(caller != null, "instance method call should have caller"); + if (caller != null) { + caller.accept(this); + builder.append("."); + } } builder.append(method.getName()); final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, substitutor); @@ -613,6 +664,7 @@ public class ExpressionGenerator extends Generator { String varName = generateListOrMapVariableDeclaration(listOrMap, type); generateListOrMapElementInsertions(listOrMap, varName); + builder.append(varName); } private void generateListOrMapElementInsertions(GrListOrMap listOrMap, String varName) { @@ -647,6 +699,17 @@ public class ExpressionGenerator extends Generator { context.myStatements.add(insertion.toString()); } } + else { + for (GrExpression arg : listOrMap.getInitializers()) { + StringBuilder insertion = new StringBuilder(); + insertion.append(varName).append(".add("); + arg.accept(new ExpressionGenerator(insertion, context)); + + insertion.append(");"); + context.myStatements.add(insertion.toString()); + } + + } //todo for list } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationSettings.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationSettings.java new file mode 100644 index 000000000000..a9ea1a4e43a3 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationSettings.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.convertToJava; + +/** + * @author Maxim.Medvedev + */ +public class GenerationSettings { + public static boolean dontReplaceOperatorsWithMethodsForNumbers = true; +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java index 3cca78c1bb92..901c0c185492 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/GenerationUtil.java @@ -20,7 +20,8 @@ import com.intellij.psi.*; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; -import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList; +import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -41,14 +42,14 @@ import java.util.List; public class GenerationUtil { private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.refactoring.convertToJava.GenerationUtil"); public static final String[] JAVA_MODIFIERS = new String[]{ - PsiModifier.PUBLIC, - PsiModifier.PROTECTED, - PsiModifier.PRIVATE, - PsiModifier.PACKAGE_LOCAL, - PsiModifier.STATIC, - PsiModifier.ABSTRACT, - PsiModifier.FINAL, - PsiModifier.NATIVE, + PsiModifier.PUBLIC, + PsiModifier.PROTECTED, + PsiModifier.PRIVATE, + PsiModifier.PACKAGE_LOCAL, + PsiModifier.STATIC, + PsiModifier.ABSTRACT, + PsiModifier.FINAL, + PsiModifier.NATIVE, }; private GenerationUtil() { @@ -79,9 +80,12 @@ public class GenerationUtil { return varNames[0]; } + public static String validateName(String name, GroovyPsiElement context, ExpressionContext expressionContext) { + return new DefaultGroovyVariableNameValidator(context, expressionContext.myUsedVarNames, true).validateName(name, true); + } + public static void writeCodeReferenceElement(StringBuilder builder, GrCodeReferenceElement referenceElement) { - //todo - throw new UnsupportedOperationException(); + builder.append(referenceElement.getText()); } public static void invokeMethodByName(GrExpression caller, @@ -146,9 +150,9 @@ public class GenerationUtil { } public static void writeClassModifiers(StringBuilder text, - @Nullable PsiModifierList modifierList, - boolean isInterface, - boolean toplevel) { + @Nullable PsiModifierList modifierList, + boolean isInterface, + boolean toplevel) { if (modifierList == null) { text.append("public "); return; @@ -166,4 +170,45 @@ public class GenerationUtil { writeModifiers(text, modifierList, allowedModifiers.toArray(new String[allowedModifiers.size()])); } + + static void writeStatement(final StringBuilder codeBlockBuilder, + StringBuilder statementBuilder, + @Nullable GrStatement statement, + @Nullable ExpressionContext context) { + final PsiElement parent = statement == null ? null : statement.getParent(); + + final boolean addParentheses; + if (statement == null) { + addParentheses = context != null && context.shouldInsertCurlyBrackets(); + } + else { + addParentheses = + context != null && (context.shouldInsertCurlyBrackets() || context.myStatements.size() > 0) && parent instanceof GrControlStatement; + } + + if (addParentheses) { + codeBlockBuilder.append("{\n"); + } + + if (context != null) { + insertStatementFromContextBefore(codeBlockBuilder, context); + } + codeBlockBuilder.append(statementBuilder); + if (addParentheses) { + codeBlockBuilder.append("}\n"); + } + } + + public static void insertStatementFromContextBefore(StringBuilder codeBlockBuilder, ExpressionContext context) { + for (String st : context.myStatements) { + codeBlockBuilder.append(st).append("\n"); + } + } + + public static void writeStatement(final StringBuilder builder, ExpressionContext context, @Nullable GrStatement statement, StatementWriter writer) { + StringBuilder statementBuilder = new StringBuilder(); + ExpressionContext statementContext = context.copy(); + writer.writeStatement(statementBuilder, statementContext); + writeStatement(builder, statementBuilder, statement, statementContext); + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/Generator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/Generator.java index 14ece08f12fd..4c9c1e3ea07a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/Generator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/Generator.java @@ -15,12 +15,12 @@ */ package org.jetbrains.plugins.groovy.refactoring.convertToJava; -import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; +import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; /** * @author Maxim.Medvedev */ -public abstract class Generator extends GroovyRecursiveElementVisitor { +public abstract class Generator extends GroovyElementVisitor { public abstract StringBuilder getBuilder(); public abstract ExpressionContext getContext(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StatementWriter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StatementWriter.java new file mode 100644 index 000000000000..b9a28fb426f9 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/StatementWriter.java @@ -0,0 +1,23 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.convertToJava; + +/** + * @author Maxim.Medvedev + */ +public interface StatementWriter { + void writeStatement(StringBuilder builder, ExpressionContext context); +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/SwitchStatementGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/SwitchStatementGenerator.java new file mode 100644 index 000000000000..0a0f3087e4b8 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/SwitchStatementGenerator.java @@ -0,0 +1,195 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.convertToJava; + +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; +import com.intellij.psi.PsiType; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSwitchStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrBreakStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; +import org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator; + +/** + * @author Maxim.Medvedev + */ +public class SwitchStatementGenerator { + + private static final boolean LANGUAGE_LEVEL_7_OR_HIGHER = false; + + private SwitchStatementGenerator() { + } + + public static void generate(StringBuilder builder, ExpressionContext context, GrSwitchStatement switchStatement) { + final GrExpression condition = switchStatement.getCondition(); + final GrCaseSection[] caseSections = switchStatement.getCaseSections(); + + final PsiType type = condition == null ? null : TypesUtil.unboxPrimitiveTypeWrapper(condition.getType()); + if (type == null || HighlightUtil.isValidTypeForSwitchSelector(type, LANGUAGE_LEVEL_7_OR_HIGHER)) { + generateSwitch(builder, context, condition, caseSections); + } + else { + generateIfs(builder, context, condition, caseSections); + } + } + + private static void generateIfs(StringBuilder builder, ExpressionContext context, GrExpression condition, GrCaseSection[] caseSections) { + if (caseSections.length == 1 && caseSections[0].getCaseLabel().isDefault()) { + //todo + } + + final GrExpression ref; + if (condition instanceof GrReferenceExpression) { + ref = condition; + } + else { + final String varName = generateConditionVar(builder, context, condition); + ref = GroovyPsiElementFactory.getInstance(context.project).createExpressionFromText(varName); + } + final GrExpression[] args = {ref}; + generateIfFromCaseSection(builder, context, caseSections, 0, args); + } + + private static void generateIfFromCaseSection(StringBuilder builder, + ExpressionContext context, + final GrCaseSection[] caseSections, + final int i, + final GrExpression[] args) { + + GenerationUtil.writeStatement(builder, context, null, new StatementWriter() { + @Override + public void writeStatement(StringBuilder builder, ExpressionContext context) { + GrCaseSection section = caseSections[i]; + boolean isCase = !section.getCaseLabel().isDefault(); + + if (isCase) { + builder.append("if ("); + GenerationUtil.invokeMethodByName( + section.getCaseLabel().getValue(), + "isCase", + args, + GrNamedArgument.EMPTY_ARRAY, + GrClosableBlock.EMPTY_ARRAY, + new ExpressionGenerator(builder, context), + section + ); + builder.append(") {\n"); + } + final ExpressionContext extended = context.extend(); + CodeBlockGenerator generator = new CodeBlockGenerator(builder, extended); + + Outer: + for (int j = i; j < caseSections.length; j++) { + section = caseSections[j]; + final GrStatement[] statements = section.getStatements(); + for (GrStatement statement : statements) { + if (statement instanceof GrBreakStatement && ((GrBreakStatement)statement).getLabelIdentifier() == null) { + break Outer; + } + statement.accept(generator); + builder.append("\n"); + } + } + + if (isCase && i + 1 < caseSections.length) { + builder.append("}\nelse "); + StringBuilder elseBuilder = new StringBuilder(); + final ExpressionContext elseContext = context.extend(); + + generateIfFromCaseSection(elseBuilder, elseContext, caseSections, i + 1, args); + GenerationUtil.insertStatementFromContextBefore(builder, elseContext); + builder.append(elseBuilder); + } + if (context.myStatements.size() > 0) context.setInsertCurlyBrackets(); + } + }); + } + + private static String generateConditionVar(StringBuilder builder, + ExpressionContext context, + GrExpression condition) { + StringBuilder conditionBuilder = new StringBuilder(); + final PsiType type = condition.getType(); + final String varName = GenerationUtil.validateName("switchArg", condition, context); + conditionBuilder.append("final "); + GenerationUtil.writeType(conditionBuilder, type); + conditionBuilder.append(" ").append(varName).append(" = "); + condition.accept(new ExpressionGenerator(conditionBuilder, context)); + conditionBuilder.append(";\n"); + GenerationUtil.insertStatementFromContextBefore(builder, context); + builder.append(conditionBuilder); + return varName; + } + + private static void generateSwitch(StringBuilder builder, + ExpressionContext context, + GrExpression condition, + GrCaseSection[] caseSections) { + builder.append("switch ("); + if (condition != null) { + condition.accept(new ExpressionGenerator(builder, context)); + } + builder.append(") {\n"); + + final ExpressionContext innerContext = context.extend(); + for (GrCaseSection section : caseSections) { + generateCaseSection(builder, context, innerContext, section); + } + + builder.append("}"); + } + + private static void generateCaseSection(StringBuilder builder, + ExpressionContext context, + ExpressionContext innerContext, + GrCaseSection section) { + if (section.getCaseLabel().isDefault()) { + builder.append("default"); + } + else { + builder.append("case "); + final GrExpression value = section.getCaseLabel().getValue(); + Object evaluated; + try { + evaluated = GroovyConstantExpressionEvaluator.evaluate(value); + } + catch (Throwable e) { + evaluated = null; + } + + if (evaluated != null) { + builder.append(evaluated); + } + else if (value != null) { + value.accept(new ExpressionGenerator(builder, context)); + } + } + + builder.append(":\n"); + final GrStatement[] statements = section.getStatements(); + CodeBlockGenerator generator = new CodeBlockGenerator(builder, innerContext); + for (GrStatement statement : statements) { + statement.accept(generator); + builder.append("\n"); + } + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy new file mode 100644 index 000000000000..58a2a302cd16 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerationTest.groovy @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.convertToJava; + + +import com.intellij.lang.StdLanguages +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ContentEntry +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.JarFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiFile +import com.intellij.psi.impl.source.PostprocessReformattingAspect +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement +import org.jetbrains.plugins.groovy.util.TestUtils + +/** + * @author Maxim.Medvedev + */ +public class CodeBlockGenerationTest extends LightCodeInsightFixtureTestCase { + public static final DefaultLightProjectDescriptor GROOVY_17_PROJECT_DESCRIPTOR = new DefaultLightProjectDescriptor() { + @Override + public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { + final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); + final VirtualFile groovyJar = JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_7LibraryName() + "!/"); + modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); + modifiableModel.commit(); + } + }; + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return GROOVY_17_PROJECT_DESCRIPTOR; + } + + @Override + protected String getBasePath() { + return TestUtils.testDataPath + "/refactoring/convertGroovyToJava/codeBlock"; + } + + private void doTest() { + final String testName = getTestName(false) + final PsiFile file = myFixture.configureByFile(testName + ".groovy"); + assertInstanceOf file, GroovyFile + + GrTopStatement[] statements = file.topStatements + final StringBuilder builder = new StringBuilder() + def generator = new CodeBlockGenerator(builder, new ExpressionContext(project)); + for (def statement: statements) { + statement.accept(generator); + builder.append("\n") + } + + final PsiFile result = createLightFile(testName + ".java", StdLanguages.JAVA, builder.toString()) + PostprocessReformattingAspect.getInstance(project).doPostponedFormatting() + final String text = result.text + final String expected = psiManager.findFile(myFixture.copyFileToProject(testName + ".java")).text + assertEquals expected, text + } + + void testSwitch1() {doTest()} + void testSwitch2() {doTest()} + void testSwitch3() {doTest()} + void testSwitch4() {doTest()} + + void _testWhile1() {doTest()} + void _testWhile2() {doTest()} + void _testWhile3() {doTest()} + +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerationTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerationTest.groovy new file mode 100644 index 000000000000..f82d6cd060b6 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerationTest.groovy @@ -0,0 +1,79 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.refactoring.convertToJava + +import com.intellij.lang.StdLanguages +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ContentEntry +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.JarFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiFile +import com.intellij.psi.impl.source.PostprocessReformattingAspect +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile +import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement +import org.jetbrains.plugins.groovy.util.TestUtils + +/** + * @author Maxim.Medvedev + */ +class ExpressionGenerationTest extends LightCodeInsightFixtureTestCase { + public static final DefaultLightProjectDescriptor GROOVY_17_PROJECT_DESCRIPTOR = new DefaultLightProjectDescriptor() { + @Override + public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { + final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); + final VirtualFile groovyJar = JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_7LibraryName() + "!/"); + modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); + modifiableModel.commit(); + } + }; + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return GROOVY_17_PROJECT_DESCRIPTOR; + } + + @Override + protected String getBasePath() { + return TestUtils.testDataPath + "/refactoring/convertGroovyToJava/codeBlock"; + } + + private void doTest() { + final String testName = getTestName(false); + final PsiFile file = myFixture.configureByFile(testName + ".groovy"); + assertInstanceOf file, GroovyFile + + GrTopStatement[] statements = file.topStatements + final StringBuilder builder = new StringBuilder() + statements.last().accept(new ExpressionGenerator(builder, new ExpressionContext(project))) + + final PsiFile result = createLightFile(testName + ".java", StdLanguages.JAVA, builder.toString()) + PostprocessReformattingAspect.getInstance(project).doPostponedFormatting() + final String text = result.text + final String expected = psiManager.findFile(myFixture.copyFileToProject(testName + ".java")).text + assertEquals expected, text + } + + void testAssignment() {//todo + } +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.groovy new file mode 100644 index 000000000000..f1227d34d243 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.groovy @@ -0,0 +1,15 @@ +def a = 2 +switch (a) { + case 1: + print a; + case 2: + print a+2 + break + case 3: + print a-1 + break + default: + print "foooo"; +} + +print "wow" diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.java new file mode 100644 index 000000000000..41c1f8e9768b --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch1.java @@ -0,0 +1,14 @@ +java.lang.Integer a = 2; +switch (a) { +case 1: +print(a); +case 2: +print(a + 2); +break; +case 3: +print(a - 1); +break; +default: +print("foooo"); +} +print("wow"); diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.groovy new file mode 100644 index 000000000000..460c787527ed --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.groovy @@ -0,0 +1,8 @@ +def a = 2; + +switch (a) { + case 2 + [4, 5]: + print a; + case [1, 2]: + print a; +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.java new file mode 100644 index 000000000000..b1399d2c654a --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch2.java @@ -0,0 +1,13 @@ +java.lang.Integer a = 2; +java.util.ArrayList integers = new java.util.ArrayList(2); +integers.add(4); +integers.add(5); +java.util.ArrayList integers1 = new java.util.ArrayList(2); +integers1.add(1); +integers1.add(2); +switch (a) { +case 2 + integers: +print(a); +case integers1: +print(a); +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.groovy new file mode 100644 index 000000000000..134f8d552102 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.groovy @@ -0,0 +1,11 @@ +def date = new Date(2011, 04, 09) + +switch (date) { + case new Date(20, 11, 23): + print "aaa" + case new Date(45, 1, 2): + print "bbb" + break + default: + print "ccc" +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java new file mode 100644 index 000000000000..ab6d5cf98598 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch3.java @@ -0,0 +1,10 @@ +java.util.Date date = new Date(2011, 4, 9); +if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(20, 11, 23), date)) { +print("aaa"); +print("bbb"); +} +else if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(45, 1, 2), date)) { +print("bbb"); +} +else print("ccc"); + diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.groovy new file mode 100644 index 000000000000..6975afb5d3de --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.groovy @@ -0,0 +1,11 @@ +def date = new Date(2011, 04, 09) + +switch (date) { + case new Date(20, 11, 23): + print "aaa" + case [1]: + print "bbb" + break + default: + print "ccc" +} diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java new file mode 100644 index 000000000000..feadc641f3e2 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/switch4.java @@ -0,0 +1,14 @@ +java.util.Date date = new Date(2011, 4, 9); +if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(new Date(20, 11, 23), date)) { +print("aaa"); +print("bbb"); +} +else { +java.util.ArrayList integers = new java.util.ArrayList(1); +integers.add(1); +if (org.codehaus.groovy.runtime.DefaultGroovyMethods.isCase(integers, date)) { +print("bbb"); +} +else print("ccc"); +} + diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.groovy index be9f67913ed1..d66a8772c33d 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.groovy +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.groovy @@ -1,2 +1,2 @@ def a = 5; -while (a < 20) a-- +while (a < 20) a=a+2 diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.java index cae661e2816f..095da612376e 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while1.java @@ -1,2 +1,2 @@ int a = 5; -while (a < 20) a--; \ No newline at end of file +while (a < 20) a=a+2; \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.groovy index 860ebeac05b3..cab5857e93eb 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.groovy +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.groovy @@ -1,2 +1,2 @@ def a = 5; -while (![1, 2, 3, 4].find {a > it}) a-- \ No newline at end of file +while (![1, 2, 3, 4].find {a > it}) a=a-1 \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.java index 068c3cc6ae1d..c9ae856cbbbd 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while2.java @@ -8,4 +8,4 @@ while (!org.codehaus.groovy.runtime.DefaultGroovyMethods.find(list, new groovy.l boolean doCall(java.lang.Integer it) { return a.equals(it); } -})) a--; +})) a=a-1; diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.groovy b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.groovy new file mode 100644 index 000000000000..2b74fe6c2da4 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.groovy @@ -0,0 +1,2 @@ +def list = [1, 2, 3] +while (list -[3, 4]) list-=1 diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.java new file mode 100644 index 000000000000..c0070d5b11b1 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/codeBlock/while3.java @@ -0,0 +1,8 @@ +java.util.List list = new java.util.ArrayList(3); +list.add(1); +list.add(2); +list.add(3); +java.util.List list1 = new java.util.ArrayList(2); +list1.add(3); +list1.add(4); +while (!org.codehaus.groovy.runtime.DefaultGroovyMethods.minus(list, list1).isEmpty()) list = org.codehaus.groovy.runtime.DefaultGroovyMethods.minus(list, 1);