/*******************************************************************************
* Copyright (c) 2005, 2014 Wind River Systems, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
******************************************************************************/
package org.eclipse.cdt.ui.tests.refactoring.rename;
import java.io.StringWriter;
import org.eclipse.core.resources.IFile;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
import org.eclipse.ltk.core.refactoring.TextEditChangeGroup;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.search.internal.core.text.FileCharSequenceProvider;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.edits.TextEditGroup;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.tests.BaseTestFramework;
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
/**
* @author markus.schorn@windriver.com
*/
public class RefactoringTests extends BaseTestFramework {
private int fBufferSize;
public RefactoringTests() {
}
public RefactoringTests(String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
CCorePlugin.getIndexManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER);
fBufferSize= FileCharSequenceProvider.BUFFER_SIZE;
FileCharSequenceProvider.BUFFER_SIZE= 1024 * 4;
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
SavedCodeReaderFactory.getInstance().getCodeReaderCache().flush();
FileCharSequenceProvider.BUFFER_SIZE= fBufferSize;
}
protected void assertTotalChanges(int numChanges, Change changes) throws Exception {
assertTotalChanges(numChanges, 0, 0, changes);
}
protected void assertTotalChanges(int numChanges, int potChanges, int commentCh,
Change changes) throws Exception {
int count[]= { 0, 0, 0 };
if (changes != null) {
countChanges(changes, count);
}
assertEquals(numChanges, count[0]);
assertEquals("potential changes: ", potChanges, count[1]);
assertEquals("comment changes: ", commentCh, count[2]);
}
private void countChanges(Change change, int[] count) {
if (change instanceof CompositeChange) {
Change[] children = ((CompositeChange) change).getChildren();
for (int i = 0; i < children.length; i++) {
countChanges(children[i], count);
}
} else if (change instanceof TextFileChange) {
TextFileChange tfc= (TextFileChange) change;
TextEditChangeGroup[] tecgs= tfc.getTextEditChangeGroups();
for (int i = 0; i < tecgs.length; i++) {
TextEditChangeGroup group = tecgs[i];
countChanges(group, count);
}
}
}
private void countChanges(TextEditChangeGroup edit, int[] count) {
String name= edit.getName();
if (name.indexOf("potential") != -1) {
count[1]++;
} else if (name.indexOf("comment") != -1) {
count[2]++;
} else {
count[0]++;
}
}
protected void assertChange(Change changes, IFile file, int startOffset, int numChars, String newText) throws Exception {
assertChange(changes, file, startOffset, numChars, newText, false);
}
protected void assertChange(Change changes, IFile file, int startOffset, int numChars, String newText, boolean potential) throws Exception {
boolean found = false;
if (changes != null && changes instanceof CompositeChange) {
found = checkCompositeChange((CompositeChange) changes, file, startOffset, numChars, newText, potential);
}
if (!found) {
fail ("Rename at offset " + startOffset + " in \"" + file.getLocation() + "\" not found.");
assertFalse(true);
}
}
private boolean checkCompositeChange(CompositeChange composite, IFile file, int startOffset, int numChars, String newText, boolean potential) {
boolean found = false;
Change[] children = composite.getChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof CompositeChange) {
found = checkCompositeChange((CompositeChange) children[i], file, startOffset, numChars, newText, potential);
} else if (children[i] instanceof TextFileChange) {
TextFileChange tuChange = (TextFileChange) children[i];
if (tuChange.getFile().toString().equals(file.toString())) {
found = checkTranslationUnitChange(tuChange, startOffset, numChars, newText, potential);
}
}
if (found)
return found;
}
return found;
}
private boolean checkTranslationUnitChange(TextFileChange change, int startOffset, int numChars, String newText, boolean potential) {
TextEditChangeGroup[] groups= change.getTextEditChangeGroups();
for (int i = 0; i < groups.length; i++) {
TextEditGroup group = groups[i].getTextEditGroup();
if ((group.getName().indexOf("potential") != -1) == potential) {
TextEdit[] edits= group.getTextEdits();
if (checkTextEdits(edits, startOffset, numChars, newText)) {
return true;
}
}
}
return false;
}
private boolean checkTextEdit(TextEdit edit, int startOffset, int numChars, String newText) {
if (edit instanceof MultiTextEdit) {
if (checkTextEdits(((MultiTextEdit) edit).getChildren(),
startOffset, numChars, newText)) {
return true;
}
} else if (edit instanceof ReplaceEdit) {
if (checkReplaceEdit((ReplaceEdit) edit, startOffset, numChars, newText)) {
return true;
}
}
return false;
}
private boolean checkTextEdits(TextEdit[] edits, int startOffset, int numChars, String newText) {
for (int i = 0; i < edits.length; i++) {
TextEdit edit = edits[i];
if (checkTextEdit(edit, startOffset, numChars, newText)) {
return true;
}
}
return false;
}
private boolean checkReplaceEdit(ReplaceEdit edit, int startOffset, int numChars, String newText) {
return (edit.getOffset() == startOffset && edit.getLength() == numChars && edit.getText().equals(newText ) );
}
protected IFile createCppFwdDecls(String fileName) throws Exception {
StringWriter writer = new StringWriter();
writer.write("class class_fwd; \n");
writer.write("struct struct_fwd; \n");
writer.write("union union_fwd; \n");
writer.write("int func_proto(); \n");
writer.write("int func_proto_ov(); \n");
writer.write("int func_proto_ov(int); \n");
writer.write("int func_proto_ov(int*); \n");
writer.write("extern int extern_var; \n");
String contents = writer.toString();
return importFile(fileName, contents );
}
protected IFile createCFwdDecls(String fileName) throws Exception {
StringWriter writer = new StringWriter();
writer.write("struct struct_fwd; \n");
writer.write("union union_fwd; \n");
writer.write("int func_proto(); \n");
writer.write("extern int extern_var; \n");
String contents = writer.toString();
return importFile(fileName, contents );
}
protected IFile createCppDefs(String fileName) throws Exception {
StringWriter writer = new StringWriter();
writer.write("class class_def { \n");
writer.write("public: \n");
writer.write(" int member; \n");
writer.write(" static int static_member; \n");
writer.write(" void method(int par); \n");
writer.write(" void static_method(int par); \n");
writer.write(" int method_ov(); \n");
writer.write(" int method_ov(int); \n");
writer.write(" int method_ov(int*); \n");
writer.write("}; \n");
writer.write("struct struct_def { \n");
writer.write(" int st_member; \n");
writer.write("}; \n");
writer.write("union union_def { \n");
writer.write(" int un_member; \n");
writer.write("}; \n");
writer.write("typedef int typedef_def; \n");
writer.write("namespace namespace_def{}; \n");
writer.write("enum enum_def { \n");
writer.write(" enum_item }; \n");
writer.write("int func_def() {} \n");
writer.write("int func_def_ov() {} \n");
writer.write("int func_def_ov(int){} \n");
writer.write("int func_def_ov(int*){} \n");
writer.write("int var_def; \n");
String contents = writer.toString();
return importFile(fileName, contents );
}
protected IFile createCDefs(String fileName) throws Exception {
StringWriter writer = new StringWriter();
writer.write("struct struct_def { \n");
writer.write(" int st_member; \n");
writer.write("}; \n");
writer.write("union union_def { \n");
writer.write(" int un_member; \n");
writer.write("}; \n");
writer.write("typedef int typedef_def; \n");
writer.write("enum enum_def { \n");
writer.write(" enum_item }; \n");
writer.write("int func_def() {} \n");
writer.write("int var_def; \n");
String contents = writer.toString();
return importFile(fileName, contents );
}
protected void assertRefactoringError(RefactoringStatus status, String msg) {
RefactoringStatusEntry e= status.getEntryMatchingSeverity(RefactoringStatus.ERROR);
assertNotNull("Expected refactoring error!", e);
assertEquals(msg, e.getMessage());
}
protected void assertRefactoringWarning(RefactoringStatus status, String msg) {
RefactoringStatusEntry e= status.getEntryMatchingSeverity(RefactoringStatus.WARNING);
assertNotNull("Expected refactoring warning!", e);
assertEquals(msg, e.getMessage());
}
protected void assertRefactoringOk(RefactoringStatus status) {
assertTrue("Expected refactoring status ok: " +
status.getMessageMatchingSeverity(status.getSeverity()),
status.getSeverity() == RefactoringStatus.OK);
}
}