blob: 00852a996d0f1f5c6dabbd1b616dd1410175e728 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.ui.tests.core;
import static org.junit.Assert.assertNotNull;
import java.util.Hashtable;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.eclipse.jdt.testplugin.JavaProjectHelper;
import org.eclipse.jdt.testplugin.TestOptions;
import org.eclipse.core.runtime.Assert;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DefaultPositionUpdater;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.Position;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.jdt.ui.tests.core.rules.ProjectTestSetup;
import org.eclipse.jdt.internal.ui.JavaPlugin;
public class CodeFormatterUtilTest extends CoreTests {
@Rule
public ProjectTestSetup pts= new ProjectTestSetup();
private IJavaProject fJProject1;
@Before
public void setUp() throws Exception {
fJProject1= JavaProjectHelper.createJavaProject("TestProject1", "bin");
JavaProjectHelper.addRequiredProject(fJProject1, pts.getProject());
Hashtable<String, String> options= TestOptions.getDefaultOptions();
options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
options.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, "999");
JavaCore.setOptions(options);
}
@After
public void tearDown() throws Exception {
JavaProjectHelper.delete(fJProject1);
}
private static String evaluateFormatterEdit(String string, TextEdit edit, Position[] positions) {
try {
Document doc= createDocument(string, positions);
edit.apply(doc, 0);
if (positions != null) {
for (Position position : positions) {
Assert.isTrue(!position.isDeleted, "Position got deleted"); //$NON-NLS-1$
}
}
return doc.get();
} catch (BadLocationException e) {
JavaPlugin.log(e); // bug in the formatter
Assert.isTrue(false, "Formatter created edits with wrong positions: " + e.getMessage()); //$NON-NLS-1$
}
return null;
}
private static Document createDocument(String string, Position[] positions) throws IllegalArgumentException {
Document doc= new Document(string);
try {
if (positions != null) {
final String POS_CATEGORY= "myCategory"; //$NON-NLS-1$
doc.addPositionCategory(POS_CATEGORY);
doc.addPositionUpdater(new DefaultPositionUpdater(POS_CATEGORY) {
@Override
protected boolean notDeleted() {
if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) {
fPosition.offset= fOffset + fLength; // deleted positions: set to end of remove
return false;
}
return true;
}
});
for (Position position : positions) {
try {
doc.addPosition(POS_CATEGORY, position);
} catch (BadLocationException e) {
throw new IllegalArgumentException("Position outside of string. offset: " + position.offset + ", length: " + position.length + ", string size: " + string.length()); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
}
}
}
} catch (BadPositionCategoryException cannotHappen) {
// can not happen: category is correctly set up
}
return doc;
}
@Test
public void testCU() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run= new Runnable() {};\n");
buf.append(" }\n");
buf.append("}\n");
String contents= buf.toString();
String formatted= CodeFormatterUtil.format(CodeFormatter.K_COMPILATION_UNIT, contents, 0, "\n", fJProject1);
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run = new Runnable() {\n");
buf.append(" };\n");
buf.append(" }\n");
buf.append("}\n");
String expected= buf.toString();
assertEqualString(formatted, expected);
}
@Test
public void testCUIndented() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run= new Runnable() {};\n");
buf.append(" }\n");
buf.append("}\n");
String contents= buf.toString();
String formatted= CodeFormatterUtil.format(CodeFormatter.K_COMPILATION_UNIT, contents, 1, "\n", fJProject1);
buf= new StringBuffer();
buf.append(" package test1;\n");
buf.append(" public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run = new Runnable() {\n");
buf.append(" };\n");
buf.append(" }\n");
buf.append(" }\n");
String expected= buf.toString();
assertEqualString(formatted, expected);
}
@Test
public void testCUNewAPI() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run= new Runnable() {};\n");
buf.append(" }\n");
buf.append("}\n");
String contents= buf.toString();
TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, contents, 0, "\n", null);
Document doc= new Document(contents);
edit.apply(doc);
String formatted= doc.get();
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run = new Runnable() {\n");
buf.append(" };\n");
buf.append(" }\n");
buf.append("}\n");
String expected= buf.toString();
assertEqualString(formatted, expected);
}
@Test
public void testCUNewAPI2() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append("/**\n");
buf.append(" * comment\n");
buf.append(" */\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run= new Runnable() {};\n");
buf.append(" }\n");
buf.append("}\n");
String contents= buf.toString();
TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, contents, 0, "\n", null);
Document doc= new Document(contents);
edit.apply(doc);
String formatted= doc.get();
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append(" /**\n");
buf.append(" * comment\n");
buf.append(" */\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run = new Runnable() {\n");
buf.append(" };\n");
buf.append(" }\n");
buf.append("}\n");
String expected= buf.toString();
assertEqualString(formatted, expected);
}
@Test
public void testCUWithPos() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run= new Runnable() {};\n");
buf.append(" }\n");
buf.append("}\n");
String contents= buf.toString();
String word1= "new";
int start1= contents.indexOf(word1);
Position pos1= new Position(start1, word1.length());
TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, contents, 0, "\n", null);
assertNotNull(edit);
String formatted= evaluateFormatterEdit(contents, edit, new Position[] { pos1});
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable run = new Runnable() {\n");
buf.append(" };\n");
buf.append(" }\n");
buf.append("}\n");
String expected= buf.toString();
assertEqualString(formatted, expected);
String curr1= formatted.substring(pos1.offset, pos1.offset + pos1.length);
assertEqualString(curr1, word1);
}
@Test
public void testPackage() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append(" package com . test1;");
String contents= buf.toString();
AST ast= AST.newAST(IASTSharedValues.SHARED_AST_LEVEL, false);
PackageDeclaration decl= ast.newPackageDeclaration();
TextEdit edit= CodeFormatterUtil.format2(decl, contents, 0, "\n", null);
assertNotNull(edit);
Document document= new Document(contents);
edit.apply(document);
buf= new StringBuffer();
buf.append("package com.test1;");
assertEqualString(document.get(), buf.toString());
}
@Test
public void testPackageWithPos() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("package com . test1;");
String contents= buf.toString();
AST ast= AST.newAST(IASTSharedValues.SHARED_AST_LEVEL, false);
PackageDeclaration node= ast.newPackageDeclaration();
String word1= "com";
int start1= contents.indexOf(word1);
String word2= ";";
int start2= contents.indexOf(word2);
Position pos1= new Position(start1, word1.length());
Position pos2= new Position(start2, word2.length());
TextEdit edit= CodeFormatterUtil.format2(node, contents, 0, "\n", null);
assertNotNull(edit);
String formatted= evaluateFormatterEdit(contents, edit, new Position[] { pos1, pos2});
buf= new StringBuffer();
buf.append("package com.test1;");
String expected= buf.toString();
assertEqualString(formatted, expected);
String curr1= formatted.substring(pos1.offset, pos1.offset + pos1.length);
assertEqualString(curr1, word1);
String curr2= formatted.substring(pos2.offset, pos2.offset + pos2.length);
assertEqualString(curr2, word2);
}
@Test
public void testVarDeclStatemenetWithPos() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("x[ ]=\nnew int[ offset]");
String contents= buf.toString();
AST ast= AST.newAST(IASTSharedValues.SHARED_AST_LEVEL, false);
VariableDeclarationFragment node= ast.newVariableDeclarationFragment();
String word1= "new";
int start1= contents.indexOf(word1);
String word2= "offset";
int start2= contents.indexOf(word2);
Position pos1= new Position(start1, word1.length());
Position pos2= new Position(start2, word2.length());
TextEdit edit= CodeFormatterUtil.format2(node, contents, 0, "\n", null);
assertNotNull(edit);
String formatted= evaluateFormatterEdit(contents, edit, new Position[] { pos1, pos2});
buf= new StringBuffer();
buf.append("x[] = new int[offset]");
String expected= buf.toString();
assertEqualString(formatted, expected);
String curr1= formatted.substring(pos1.offset, pos1.offset + pos1.length);
assertEqualString(curr1, word1);
String curr2= formatted.substring(pos2.offset, pos2.offset + pos2.length);
assertEqualString(curr2, word2);
}
@Test
public void testJavadoc() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("/** bar\n");
buf.append(" * foo\n");
buf.append(" */\n");
String contents= buf.toString();
AST ast= AST.newAST(IASTSharedValues.SHARED_AST_LEVEL, false);
Javadoc node= ast.newJavadoc();
String word1= "bar";
int start1= contents.indexOf(word1);
String word2= "foo";
int start2= contents.indexOf(word2);
Position pos1= new Position(start1, word1.length());
Position pos2= new Position(start2, word2.length());
TextEdit edit= CodeFormatterUtil.format2(node, contents, 0, "\n", null);
assertNotNull(edit);
String formatted= evaluateFormatterEdit(contents, edit, new Position[] { pos1, pos2});
buf= new StringBuffer();
buf.append("/** bar\n");
buf.append(" * foo\n");
buf.append(" */\n");
String expected= buf.toString();
assertEqualString(formatted, expected);
String curr1= formatted.substring(pos1.offset, pos1.offset + pos1.length);
assertEqualString(curr1, word1);
String curr2= formatted.substring(pos2.offset, pos2.offset + pos2.length);
assertEqualString(curr2, word2);
}
@Test
public void testJavadoc2() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("/** bar\n");
buf.append(" * foo\n");
buf.append(" */");
String contents= buf.toString();
AST ast= AST.newAST(IASTSharedValues.SHARED_AST_LEVEL, false);
Javadoc node= ast.newJavadoc();
String word1= "bar";
int start1= contents.indexOf(word1);
String word2= "foo";
int start2= contents.indexOf(word2);
Position pos1= new Position(start1, word1.length());
Position pos2= new Position(start2, word2.length());
TextEdit edit= CodeFormatterUtil.format2(node, contents, 1, "\n", null);
assertNotNull(edit);
String formatted= evaluateFormatterEdit(contents, edit, new Position[] { pos1, pos2});
buf= new StringBuffer();
buf.append(" /** bar\n");
buf.append(" * foo\n");
buf.append(" */");
String expected= buf.toString();
assertEqualString(formatted, expected);
String curr1= formatted.substring(pos1.offset, pos1.offset + pos1.length);
assertEqualString(curr1, word1);
String curr2= formatted.substring(pos2.offset, pos2.offset + pos2.length);
assertEqualString(curr2, word2);
}
@Test
public void testJavadoc3() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("/** bar\n");
buf.append(" * foo\n");
buf.append(" */");
String contents= buf.toString();
AST ast= AST.newAST(IASTSharedValues.SHARED_AST_LEVEL, false);
Javadoc node= ast.newJavadoc();
String word1= "bar";
int start1= contents.indexOf(word1);
String word2= "foo";
int start2= contents.indexOf(word2);
Position pos1= new Position(start1, word1.length());
Position pos2= new Position(start2, word2.length());
TextEdit edit= CodeFormatterUtil.format2(node, contents, 0, "\r\n", null);
assertNotNull(edit);
String formatted= evaluateFormatterEdit(contents, edit, new Position[] { pos1, pos2});
buf= new StringBuffer();
buf.append("/** bar\r\n");
buf.append(" * foo\r\n");
buf.append(" */");
String expected= buf.toString();
assertEqualString(formatted, expected);
String curr1= formatted.substring(pos1.offset, pos1.offset + pos1.length);
assertEqualString(curr1, word1);
String curr2= formatted.substring(pos2.offset, pos2.offset + pos2.length);
assertEqualString(curr2, word2);
}
@Test
public void testCatchClause() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("catch\n");
buf.append("(Exception e) {\n");
buf.append("}");
String contents= buf.toString();
AST ast= AST.newAST(IASTSharedValues.SHARED_AST_LEVEL, false);
CatchClause node= ast.newCatchClause();
String word1= "catch";
int start1= contents.indexOf(word1);
String word2= "Exception";
int start2= contents.indexOf(word2);
Position pos1= new Position(start1, word1.length());
Position pos2= new Position(start2, word2.length());
TextEdit edit= CodeFormatterUtil.format2(node, contents, 0, "\n", null);
assertNotNull(edit);
String formatted= evaluateFormatterEdit(contents, edit, new Position[] { pos1, pos2});
buf= new StringBuffer();
buf.append(" catch (Exception e) {\n");
buf.append("}");
String expected= buf.toString();
assertEqualString(formatted, expected);
String curr1= formatted.substring(pos1.offset, pos1.offset + pos1.length);
assertEqualString(curr1, word1);
String curr2= formatted.substring(pos2.offset, pos2.offset + pos2.length);
assertEqualString(curr2, word2);
}
@Test
public void testCatchStringLiteral() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("\"Hello\" ");
String contents= buf.toString();
AST ast= AST.newAST(IASTSharedValues.SHARED_AST_LEVEL, false);
StringLiteral node= ast.newStringLiteral();
TextEdit edit= CodeFormatterUtil.format2(node, contents, 0, "\n", null);
assertNotNull(edit);
Document document= new Document(contents);
edit.apply(document);
buf= new StringBuffer();
buf.append("\"Hello\"");
String expected= buf.toString();
assertEqualString(document.get(), expected);
}
@Test
public void testFormatSubstring() throws Exception {
StringBuffer buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import java.util.Vector;\n");
buf.append("\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable runnable= new Runnable() {};\n");
buf.append(" runnable.toString();\n");
buf.append(" }\n");
buf.append("}\n");
String contents= buf.toString();
String formatString= "Runnable runnable= new Runnable() {};";
int formatStart= contents.indexOf(formatString);
int formatLength= formatString.length();
String word1= "import";
int start1= contents.indexOf(word1);
String word2= "new";
int start2= contents.indexOf(word2);
String word3= "toString";
int start3= contents.indexOf(word3);
Position pos1= new Position(start1, word1.length());
Position pos2= new Position(start2, word2.length());
Position pos3= new Position(start3, word3.length());
TextEdit edit= CodeFormatterUtil.format2(CodeFormatter.K_COMPILATION_UNIT, contents, formatStart, formatLength, 0, "\n", null);
assertNotNull(edit);
String formatted= evaluateFormatterEdit(contents, edit, new Position[] { pos1, pos2, pos3});
buf= new StringBuffer();
buf.append("package test1;\n");
buf.append("\n");
buf.append("import java.util.Vector;\n");
buf.append("\n");
buf.append("public class A {\n");
buf.append(" public void foo() {\n");
buf.append(" Runnable runnable = new Runnable() {\n");
buf.append(" };\n");
buf.append(" runnable.toString();\n");
buf.append(" }\n");
buf.append("}\n");
String expected= buf.toString();
assertEqualString(formatted, expected);
String curr1= formatted.substring(pos1.offset, pos1.getOffset() + pos1.getLength());
assertEqualString(curr1, word1);
String curr2= formatted.substring(pos2.offset, pos2.getOffset() + pos2.getLength());
assertEqualString(curr2, word2);
String curr3= formatted.substring(pos3.offset, pos3.getOffset() + pos3.getLength());
assertEqualString(curr3, word3);
}
}