blob: 30252214fab4fa98d45b442c934c65dabfb6184d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2015 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.cdt.core.lrparser.tests;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.lrparser.gnu.GCCLanguage;
import org.eclipse.cdt.core.model.ILanguage;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Reuse the completion parse tests from the old parser for now.
*/
@SuppressWarnings("nls")
public class LRCompletionParseTest extends TestCase {
public static TestSuite suite() {
return new TestSuite(LRCompletionParseTest.class);
}
public LRCompletionParseTest() {
}
public LRCompletionParseTest(String name) {
super(name);
}
protected IASTCompletionNode parse(String code, int offset) throws Exception {
return ParseHelper.getCompletionNode(code, getCLanguage(), offset);
}
private static final Comparator<IBinding> BINDING_COMPARATOR = new Comparator<IBinding>() {
@Override
public int compare(IBinding b1, IBinding b2) {
return b1.getName().compareTo(b2.getName());
}
};
public static IBinding[] getBindings(IASTName[] names) {
List<IBinding> bindings = new ArrayList<>();
for (IASTName name : names) {
if (name.getTranslationUnit() == null)
continue;
for (IBinding binding : name.getCompletionContext().findBindings(name, true)) {
bindings.add(binding);
}
}
Collections.sort(bindings, BINDING_COMPARATOR);
return bindings.toArray(new IBinding[bindings.size()]);
}
protected ILanguage getCLanguage() {
return GCCLanguage.getDefault();
}
// First steal tests from CompletionParseTest
public void testCompletionStructField() throws Exception {
String code = "int aVar; " + "struct D{ " + " int aField1; " + " int aField2; " + "}; " + "void foo() {"
+ " struct D d; " + " d.a " + "}\n";
int index = code.indexOf("d.a");
IASTCompletionNode node = parse(code, index + 3);
assertNotNull(node);
String prefix = node.getPrefix();
assertNotNull(prefix);
assertEquals(prefix, "a");
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(2, bindings.length);
assertEquals("aField1", ((IField) bindings[0]).getName());
assertEquals("aField2", ((IField) bindings[1]).getName());
}
public void testCompletionStructFieldPointer() throws Exception {
String code = "struct Cube { " + " int nLen; "
+ " int nWidth; " + " int nHeight; "
+ "}; " + "int volume(struct Cube * pCube) { "
+ " pCube->SP ";
IASTCompletionNode node = parse(code, code.indexOf("SP"));
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(3, bindings.length);
assertEquals("nHeight", ((IField) bindings[0]).getName());
assertEquals("nLen", ((IField) bindings[1]).getName());
assertEquals("nWidth", ((IField) bindings[2]).getName());
}
public void testCompletionParametersAsLocalVariables() throws Exception {
String code = "int foo(int aParameter) {" + " int aLocal;" + " if (aLocal != 0) {"
+ " int aBlockLocal;" + " a \n";
int index = code.indexOf(" a ");
IASTCompletionNode node = parse(code, index + 2);
assertNotNull(node);
assertEquals("a", node.getPrefix()); //$NON-NLS-1$
IASTName[] names = node.getNames();
assertEquals(2, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(3, bindings.length);
assertEquals("aBlockLocal", ((IVariable) bindings[0]).getName());
assertEquals("aLocal", ((IVariable) bindings[1]).getName());
assertEquals("aParameter", ((IVariable) bindings[2]).getName());
}
public void testCompletionTypedef() throws Exception {
String code = "typedef int Int; " + "InSP";
int index = code.indexOf("SP");
IASTCompletionNode node = parse(code, index);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
assertEquals("In", node.getPrefix());
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("Int", ((ITypedef) bindings[0]).getName());
}
public void testCompletion() throws Exception {
String code = "#define GL_T 0x2001\n" + "#define GL_TRUE 0x1\n" + "typedef unsigned char GLboolean;\n"
+ "static GLboolean should_rotate = GL_T";
int index = code.indexOf("= GL_T");
IASTCompletionNode node = parse(code, index + 6);
assertNotNull(node);
assertEquals("GL_T", node.getPrefix()); //$NON-NLS-1$
IASTName[] names = node.getNames();
assertEquals(1, names.length);
}
public void testCompletionInTypeDef() throws Exception {
String code = "struct A { int name; }; \n" + "typedef struct A * PA; \n"
+ "int main() { \n" + " PA a; \n" + " a->SP \n"
+ "} \n";
int index = code.indexOf("SP"); //$NON-NLS-1$
IASTCompletionNode node = parse(code, index);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("name", ((IField) bindings[0]).getName());
}
public void _testCompletionFunctionCall() throws Exception {
String code = "struct A { \n" + " int f2; \n" + " int f4; \n"
+ "}; \n" + "const A * foo() {} \n" + "void main() \n"
+ "{ \n" + " foo()->SP \n";
int index = code.indexOf("SP");
IASTCompletionNode node = parse(code, index);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(2, bindings.length);
assertEquals("f2", ((IField) bindings[0]).getName());
assertEquals("f4", ((IField) bindings[1]).getName());
}
public void _testCompletionSizeof() throws Exception {
String code = "int f() {\n" + "short blah;\n" + "int x = sizeof(bl";
int index = code.indexOf("of(bl");
IASTCompletionNode node = parse(code, index + 5);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("blah", ((IVariable) bindings[0]).getName());
}
public void testCompletionForLoop() throws Exception {
String code = "int f() {\n" + " int biSizeImage = 5;\n" + "for (int i = 0; i < bi ";
int index = code.indexOf("< bi");
IASTCompletionNode node = parse(code, index + 4);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("biSizeImage", ((IVariable) bindings[0]).getName());
}
public void testCompletionStructPointer() throws Exception {
String code = " struct Temp { char * total; };" + " int f(struct Temp * t) {" + " t->t[5] = t->";
int index = code.indexOf("= t->");
IASTCompletionNode node = parse(code, index + 5);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(1, bindings.length);
assertEquals("total", ((IVariable) bindings[0]).getName());
}
public void testCompletionEnum() throws Exception {
String code = "typedef int DWORD;\n" + "typedef char BYTE;\n"
+ "#define MAKEFOURCC(ch0, ch1, ch2, ch3) \\\n"
+ "((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \\\n"
+ "((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))\n" + "enum e {\n" + "blah1 = 5,\n"
+ "blah2 = MAKEFOURCC('a', 'b', 'c', 'd'),\n" + "blah3\n" + "};\n" + "e mye = bl\n";
int index = code.indexOf("= bl");
IASTCompletionNode node = parse(code, index + 4);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(3, bindings.length);
assertEquals("blah1", ((IEnumerator) bindings[0]).getName());
assertEquals("blah2", ((IEnumerator) bindings[1]).getName());
assertEquals("blah3", ((IEnumerator) bindings[2]).getName());
}
public void testCompletionStructArray() throws Exception {
String code = "struct packet { int a; int b; };\n" + "struct packet buffer[5];\n"
+ "int main(int argc, char **argv) {\n" + " buffer[2].";
int index = code.indexOf("[2].");
IASTCompletionNode node = parse(code, index + 4);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
IBinding[] bindings = getBindings(names);
assertEquals(2, bindings.length);
assertEquals("a", ((IField) bindings[0]).getName());
assertEquals("b", ((IField) bindings[1]).getName());
}
public void testCompletionPreprocessorDirective() throws Exception {
IASTCompletionNode node = parse("#", 1);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
//assertEquals("#", node.getPrefix());
}
public void testCompletionPreprocessorMacro() throws Exception {
String code = "#define AMACRO 99 \n" + "int main() { \n" + " int AVAR; \n" + " int x = A \n";
int index = code.indexOf("= A");
IASTCompletionNode node = parse(code, index + 3);
assertNotNull(node);
IASTName[] names = node.getNames();
assertEquals(1, names.length);
assertEquals("A", node.getPrefix());
}
public void testCompletionInsidePreprocessorDirective() throws Exception {
String code = "#define MAC1 99 \n" + "#define MAC2 99 \n" + "#ifdef MA";
int index = code.length();
IASTCompletionNode node = parse(code, index);
assertNotNull(node);
assertEquals("MA", node.getPrefix());
}
}