blob: 60178611c3682999efe75d4a713b4eb4ad5ebde3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2014 Wind River Systems, Inc.
*
* 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:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.refactoring.rename;
import org.eclipse.core.resources.IFile;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import junit.framework.Test;
import junit.framework.TestSuite;
public class RenameMacroTests extends RenameTestBase {
public RenameMacroTests(String name) {
super(name);
}
public static Test suite() {
return suite(true);
}
public static Test suite(boolean cleanup) {
TestSuite suite = new TestSuite(RenameMacroTests.class);
if (cleanup) {
suite.addTest(new RenameMacroTests("cleanupProject"));
}
return suite;
}
public void testMacroRename() throws Exception {
StringBuilder buf = new StringBuilder();
buf.append("#define HALLO x \n");
buf.append("class v1 { \n");
buf.append(" int HALLO; \n");
buf.append("}; \n");
buf.append("class HALLO { \n");
buf.append(" int v; \n");
buf.append("}; \n");
buf.append("class v3 { \n");
buf.append(" int v; \n");
buf.append("}; \n");
buf.append("class v4 { \n");
buf.append(" int HALLO(); \n");
buf.append("}; \n");
buf.append("int v4::HALLO(){} \n");
buf.append("void f(int par1){ \n");
buf.append(" { \n");
buf.append(" int HALLO; v1::v++; \n");
buf.append(" } \n");
buf.append("} \n");
String contents = buf.toString();
IFile cpp = importFile("test.cpp", contents);
int offset1 = contents.indexOf("HALLO");
int offset2 = contents.indexOf("HALLO", offset1 + 1);
Change ch = getRefactorChanges(cpp, offset1, "WELT");
assertTotalChanges(6, ch);
int off = offset1;
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
ch = getRefactorChanges(cpp, offset2, "WELT");
assertTotalChanges(6, ch);
off = offset1;
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
assertChange(ch, cpp, off, 5, "WELT");
off = contents.indexOf("HALLO", off + 1);
}
public void testMacroNameConflicts() throws Exception {
createCppFwdDecls("cpp_fwd.hh");
createCppDefs("cpp_def.hh");
StringBuilder buf = new StringBuilder();
buf.append("#include \"cpp_fwd.hh\" \n");
buf.append("#include \"cpp_def.hh\" \n");
buf.append("#define MACRO 1 \n");
buf.append("int v1(); int v2(); int v3(); \n");
buf.append("static int s1(); \n");
buf.append("static int s2(); \n");
buf.append("void f(int par1){ \n");
buf.append(" int w1; v1(); \n");
buf.append(" extern_var; \n");
buf.append(" var_def; \n");
buf.append(" enum_item; \n");
buf.append("} \n");
String contents = buf.toString();
IFile cpp = importFile("test.cpp", contents);
buf = new StringBuilder();
buf.append("static int static_other_file(); \n");
importFile("other.cpp", buf.toString());
waitForIndexer();
int offset1 = contents.indexOf("MACRO");
// conflicts after renaming
RefactoringStatus status = checkConditions(cpp, offset1, "w1");
assertRefactoringError(status,
"A conflict was encountered during refactoring. \n" + "Type of problem: Name conflict \n"
+ "New element: w1 \n" + "Conflicting element type: Local variable");
status = checkConditions(cpp, contents.indexOf("par1"), "MACRO");
assertRefactoringError(status, "'MACRO' conflicts with the name of an existing macro.");
status = checkConditions(cpp, offset1, "par1");
assertRefactoringError(status,
"A conflict was encountered during refactoring. \n" + "Type of problem: Name conflict \n"
+ "New element: par1 \n" + "Conflicting element type: Parameter");
status = checkConditions(cpp, offset1, "extern_var");
assertRefactoringError(status,
"A conflict was encountered during refactoring. \n" + "Type of problem: Name conflict \n"
+ "New element: extern_var \n" + "Conflicting element type: Global variable");
status = checkConditions(cpp, offset1, "var_def");
assertRefactoringError(status,
"A conflict was encountered during refactoring. \n" + "Type of problem: Name conflict \n"
+ "New element: var_def \n" + "Conflicting element type: Global variable");
status = checkConditions(cpp, offset1, "enum_item");
assertRefactoringError(status,
"A conflict was encountered during refactoring. \n" + "Type of problem: Name conflict \n"
+ "New element: enum_item \n" + "Conflicting element type: Enumerator");
}
public void testClassMacroClash() throws Exception {
StringBuilder buf = new StringBuilder();
buf.append("class CC {int a;}; \n");
String contents = buf.toString();
IFile cpp = importFile("test.cpp", contents);
buf = new StringBuilder();
buf.append("#define CC mm \n");
buf.append("int CC; \n");
String contents2 = buf.toString();
IFile cpp2 = importFile("test2.cpp", contents2);
int offset1 = contents.indexOf("CC");
Change ch = getRefactorChanges(cpp, offset1, "CCC");
assertTotalChanges(1, ch);
int offset2 = contents2.indexOf("CC");
ch = getRefactorChanges(cpp2, offset2, "CCC");
assertTotalChanges(2, ch);
}
public void testMacroRename_434917() throws Exception {
StringBuilder buf = new StringBuilder();
buf.append("#define CC mm\n");
String contents = buf.toString();
IFile header = importFile("test.h", contents);
buf = new StringBuilder();
buf.append("#include \"test.h\"\n");
buf.append("int CC;\n");
String contents2 = buf.toString();
IFile source = importFile("test.cpp", contents2);
int offset = contents.indexOf("CC");
Change ch = getRefactorChanges(header, offset, "CCC");
assertTotalChanges(2, ch);
}
public void testIncludeGuard() throws Exception {
StringBuilder buf = new StringBuilder();
buf.append("#ifndef _guard \n");
buf.append("#define _guard \n");
buf.append(" int HALLO \n");
buf.append("#endif /* _guard */ \n");
String contents = buf.toString();
IFile cpp = importFile("test.cpp", contents);
int offset1 = contents.indexOf("_guard");
int offset2 = contents.indexOf("_guard", offset1 + 1);
Change ch = getRefactorChanges(cpp, offset2, "WELT");
assertTotalChanges(2, 0, 1, ch);
int off = offset1;
assertChange(ch, cpp, off, 6, "WELT");
off = contents.indexOf("_guard", off + 1);
assertChange(ch, cpp, off, 6, "WELT");
}
public void testMacroParameters() throws Exception {
StringBuilder buf = new StringBuilder();
buf.append("int var; \n");
buf.append("#define M1(var) var \n");
buf.append("#define M2(var, x) (var+x)*var \n");
buf.append("#define M3 var \n");
String contents = buf.toString();
IFile cpp = importFile("test.cpp", contents);
int offset1 = contents.indexOf("var");
Change ch = getRefactorChanges(cpp, offset1, "xxx");
assertTotalChanges(1, 1, 0, ch);
}
public void testRenameMacroAsMacroArgument() throws Exception {
StringBuilder buf = new StringBuilder();
buf.append("#define M1(var) var \n");
buf.append("#define M2 1 \n");
buf.append("int b= M2; \n");
buf.append("int a= M1(M2); \n");
String contents = buf.toString();
IFile cpp = importFile("test.cpp", contents);
int offset1 = contents.indexOf("M2");
Change ch = getRefactorChanges(cpp, offset1, "xxx");
assertTotalChanges(countOccurrences(contents, "M2"), ch);
}
}