mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
Patch for Alena, 161107. New PDOM Tests.
This commit is contained in:
parent
7dbd64ed6a
commit
c12e07dd19
6 changed files with 500 additions and 0 deletions
|
@ -0,0 +1,312 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 QNX Software Systems and others.
|
||||
* 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:
|
||||
* QNX - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.pdom.tests;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.AssertionFailedError;
|
||||
import junit.framework.Test;
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.IName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.core.filebuffers.FileBuffers;
|
||||
import org.eclipse.core.filebuffers.ITextFileBuffer;
|
||||
import org.eclipse.core.filebuffers.ITextFileBufferManager;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
|
||||
/**
|
||||
* Test that PDOM correctly track declarations, definitions and references of
|
||||
* objects
|
||||
*
|
||||
* @author ELaskavaia@qnx.com
|
||||
*
|
||||
*/
|
||||
public class DefDeclTests extends PDOMTestBase {
|
||||
static IPath rootPath = new Path("resources/pdomtests");
|
||||
|
||||
private String projectName = null;
|
||||
|
||||
protected PDOM pdom;
|
||||
|
||||
public static Test suite() {
|
||||
return suite(DefDeclTests.class);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
String requiredName = "defDeclTests";
|
||||
ICProject cproject = createProject(requiredName);
|
||||
this.projectName = cproject.getElementName();
|
||||
pdom = (PDOM) CCorePlugin.getPDOMManager().getPDOM(cproject);
|
||||
pdom.acquireReadLock();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
pdom.releaseReadLock();
|
||||
}
|
||||
|
||||
private IBinding findSingleBinding(String elName) throws CoreException {
|
||||
IBinding[] binds = pdom.findBindings(Pattern.compile(elName), true,
|
||||
new IndexFilter(), new NullProgressMonitor());
|
||||
assertEquals(1, binds.length);
|
||||
assertEquals(elName, binds[0].getName());
|
||||
IBinding element = binds[0];
|
||||
return element;
|
||||
}
|
||||
|
||||
private void checkReference(IBinding element, String mark, int checkCount)
|
||||
throws CoreException, BadLocationException {
|
||||
checkUsage(element, mark, checkCount, IIndex.FIND_REFERENCES);
|
||||
}
|
||||
|
||||
private void checkDeclaration(IBinding element, String mark, int num)
|
||||
throws CoreException, BadLocationException {
|
||||
checkUsage(element, mark, num, IIndex.FIND_DECLARATIONS);
|
||||
}
|
||||
|
||||
private void checkDefinition(IBinding element, String mark, int countNum)
|
||||
throws CoreException, BadLocationException {
|
||||
checkUsage(element, mark, countNum, IIndex.FIND_DEFINITIONS);
|
||||
}
|
||||
|
||||
private void checkUsage(IBinding element, String mark, int countNum,
|
||||
int flags) throws CoreException, BadLocationException {
|
||||
if (mark == null || countNum == 0) {
|
||||
getFirstUsage(element, 0, flags);
|
||||
} else {
|
||||
IName[] usage = pdom.findNames(element, flags);
|
||||
if (countNum >= 0)
|
||||
assertEquals(countNum, usage.length);
|
||||
String fail = null;
|
||||
boolean found = false;
|
||||
for (int i = 0; i < usage.length; i++) {
|
||||
IName name = usage[i];
|
||||
IASTFileLocation loc = name.getFileLocation();
|
||||
String fileName = new File(loc.getFileName()).getName();
|
||||
int markLine;
|
||||
try {
|
||||
markLine = getMarkLine(mark, fileName);
|
||||
} catch (AssertionFailedError e) {
|
||||
fail = e.getMessage();
|
||||
continue;
|
||||
}
|
||||
int nodeLine = getLineNumber(loc.getNodeOffset(), fileName);
|
||||
if (markLine != nodeLine) {
|
||||
fail = "Marker at line " + markLine + ", actual at line "
|
||||
+ nodeLine;
|
||||
} else {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found == false)
|
||||
fail(fail);
|
||||
}
|
||||
}
|
||||
|
||||
private IName getReference(IBinding binding, int k) throws CoreException {
|
||||
return getFirstUsage(binding, k, IIndex.FIND_REFERENCES);
|
||||
}
|
||||
|
||||
private IName getDefinition(IBinding binding, int k) throws CoreException {
|
||||
return getFirstUsage(binding, k, IIndex.FIND_DEFINITIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get declaration. If k>0 check that there are k of them.
|
||||
*
|
||||
* @param binding
|
||||
* @param k -
|
||||
* number of declarations, if k==-1 no check
|
||||
* @return first declaration or null of non
|
||||
* @throws CoreException
|
||||
*/
|
||||
private IName getDeclaration(IBinding binding, int k) throws CoreException {
|
||||
return getFirstUsage(binding, k, IIndex.FIND_DECLARATIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get references defined by flags. If k>0 check that there are k of them.
|
||||
*
|
||||
* @param binding
|
||||
* @param k -
|
||||
* number of references, if k==-1 no check
|
||||
* @return first references or null of non
|
||||
* @throws CoreException
|
||||
*/
|
||||
private IName getFirstUsage(IBinding binding, int k, int flags)
|
||||
throws CoreException {
|
||||
IName[] decls = pdom.findNames(binding, flags);
|
||||
if (k >= 0)
|
||||
assertEquals(k, decls.length);
|
||||
if (decls.length > 0) {
|
||||
IName ref = decls[0];
|
||||
return ref;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertAtMark(IASTFileLocation loc, String mark)
|
||||
throws CoreException, BadLocationException {
|
||||
String fileName = new File(loc.getFileName()).getName();
|
||||
int markLine = getMarkLine(mark, fileName);
|
||||
int nodeLine = getLineNumber(loc.getNodeOffset(), fileName);
|
||||
assertEquals(markLine, nodeLine);
|
||||
}
|
||||
|
||||
private int getMarkLine(String mark, String fileName) throws CoreException,
|
||||
BadLocationException {
|
||||
int markLine = getLineNumber(offset(fileName, mark), fileName);
|
||||
return markLine;
|
||||
}
|
||||
|
||||
protected int getLineNumber(int position, String projectRelativePath)
|
||||
throws CoreException {
|
||||
Path fullPath = new Path(projectName + "/" + projectRelativePath);
|
||||
ITextFileBufferManager fbm = FileBuffers.getTextFileBufferManager();
|
||||
fbm.connect(fullPath, new NullProgressMonitor());
|
||||
try {
|
||||
ITextFileBuffer buf = FileBuffers.getTextFileBufferManager()
|
||||
.getTextFileBuffer(fullPath);
|
||||
Assert.assertTrue("Could not find " + fullPath.toString(), buf
|
||||
.getModificationStamp() > 0);
|
||||
String content = buf.getDocument().get();
|
||||
int len = content.length();
|
||||
int line = 1;
|
||||
for (int i = 0; i < len && i < position; i++) {
|
||||
char c = content.charAt(i);
|
||||
if (c == '\n')
|
||||
line++;
|
||||
}
|
||||
return line;
|
||||
} finally {
|
||||
fbm.disconnect(fullPath, new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
|
||||
public void assertDefDeclRef(String name, String testNum, int def,
|
||||
int decl, int ref) throws CoreException, BadLocationException {
|
||||
String elName = name + testNum;
|
||||
IBinding binding = findSingleBinding(elName);
|
||||
checkDefinition(binding, "def" + testNum, def);
|
||||
checkDeclaration(binding, "decl" + testNum, decl);
|
||||
checkReference(binding, "ref" + testNum, ref);
|
||||
}
|
||||
|
||||
/* ------------------ Tests Started Here ------------------------ */
|
||||
public void testInit() {
|
||||
// will fail if setUp fails, maybe timelimit is too small for warm-up
|
||||
}
|
||||
|
||||
public void testSimpleDeclUsage_f01() throws Exception {
|
||||
assertDefDeclRef("foo", "01", 0, 1, 1);
|
||||
}
|
||||
|
||||
public void testKRDeclUsage_f02() throws Exception {
|
||||
assertDefDeclRef("foo", "02", 0, 1, 1);
|
||||
}
|
||||
|
||||
public void testImplicitDeclPostDecl_f03() throws Exception {
|
||||
assertDefDeclRef("foo", "03", 0, 1, 1);
|
||||
}
|
||||
|
||||
public void testImplicitDeclPostDef_f04() throws Exception {
|
||||
assertDefDeclRef("foo", "04", 1, 0, 1);
|
||||
}
|
||||
|
||||
public void testImplicitDeclNone_f05() throws Exception {
|
||||
assertDefDeclRef("foo", "05", 0, 0, 1);
|
||||
}
|
||||
|
||||
public void testNonLocalDefintion_f06() throws Exception {
|
||||
assertDefDeclRef("foo", "06", 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testWrongMatchedStaticDefinition_unexpected() throws Exception {
|
||||
assertDefDeclRef("foo", "07", 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testStaticBindings_f08_unexpected() throws Exception {
|
||||
// should be 2 bindings, otherwise how to distinguish proper def/decl
|
||||
// pairs?
|
||||
String elName = "foo" + "08";
|
||||
IBinding binding = findSingleBinding(elName);
|
||||
checkDefinition(binding, "def" + "08", 2);
|
||||
checkReference(binding, "ref" + "08", 2);
|
||||
checkDefinition(binding, "defS" + "08", 2);
|
||||
checkReference(binding, "refS" + "08", 2);
|
||||
}
|
||||
|
||||
public void testSimpleGlobalWrite_v09() throws Exception {
|
||||
assertDefDeclRef("var", "_v09", 1, 0, 1);
|
||||
}
|
||||
|
||||
public void testGlobalInitRead_v10() throws Exception {
|
||||
assertDefDeclRef("var", "_v10", 1, 0, 1);
|
||||
}
|
||||
|
||||
public void testGlobalInitRead2_v11() throws Exception {
|
||||
assertDefDeclRef("var", "_v11", 1, 0, 1);
|
||||
}
|
||||
|
||||
public void testDeclUseDef_v12() throws Exception {
|
||||
assertDefDeclRef("var", "_v12", 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testDeclDefUse_v13() throws Exception {
|
||||
assertDefDeclRef("var", "_v13", 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testDefDeclUse_v14() throws Exception {
|
||||
// Hmm. This test seems to work, but Find Declaration in the UI does not
|
||||
// work
|
||||
assertDefDeclRef("var", "_v14", 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testNamedStruct_t01() throws Exception {
|
||||
assertDefDeclRef("type", "_t01", 1, 0, 1);
|
||||
}
|
||||
|
||||
public void testStructPreDefintion_t02() throws Exception {
|
||||
assertDefDeclRef("type", "_t02", 0, 1, 1);
|
||||
}
|
||||
|
||||
public void testStructRecursive_t03() throws Exception {
|
||||
assertDefDeclRef("type", "_t03", 1, 1, 1);
|
||||
}
|
||||
|
||||
public void testStructAndTypedef_t04_unexpected() throws Exception {
|
||||
// suppose to find either 2 findings or 2 def/ref pairs
|
||||
// because type_t04 defined as struct type_04 as typedef
|
||||
String num = "_t04";
|
||||
String elName = "type" + num;
|
||||
ICompositeType element = (ICompositeType) findSingleBinding(elName);
|
||||
// checkReference(element, "ref" + num, 1);
|
||||
checkReference(element, "refS" + num, 1);
|
||||
checkDefinition(element, "defS" + num, 1);
|
||||
// checkDeclaration(element, "def" + num, 1);
|
||||
}
|
||||
|
||||
public void testTypedefAndAnonymousStruct_t05() throws Exception {
|
||||
assertDefDeclRef("type", "_t05", 1, 0, 1);
|
||||
}
|
||||
}
|
|
@ -35,6 +35,9 @@ public class PDOMTests extends TestSuite {
|
|||
|
||||
suite.addTest(CFunctionTests.suite());
|
||||
suite.addTest(CVariableTests.suite());
|
||||
|
||||
suite.addTest(DefDeclTests.suite());
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
/* ---------- Test 1 ----------
|
||||
* simple
|
||||
*/
|
||||
void foo01(); // decl01
|
||||
void bar01(){
|
||||
foo01(); // ref01
|
||||
}
|
||||
|
||||
/* ---------- Test 2 ----------
|
||||
* K&R declrations
|
||||
*/
|
||||
void foo02(); // decl02
|
||||
void bar02(){
|
||||
foo02('a'); // ref02
|
||||
}
|
||||
|
||||
/* ---------- Test 3 ----------
|
||||
* post-declaration
|
||||
*/
|
||||
|
||||
void bar03(){
|
||||
foo03(); // ref03
|
||||
}
|
||||
void foo03(); // decl03
|
||||
|
||||
/* ---------- Test 4 ----------
|
||||
* post-definition
|
||||
*/
|
||||
|
||||
void bar04(){
|
||||
foo04(); // ref04
|
||||
}
|
||||
void foo04() { // def04
|
||||
}
|
||||
/* ---------- Test 5 ----------
|
||||
* no decl/def
|
||||
*/
|
||||
|
||||
void bar05(){
|
||||
foo05(); // ref05
|
||||
}
|
||||
/* ---------- Test 6 ----------
|
||||
* function foo06 defined in second.c
|
||||
*/
|
||||
void foo06(); // decl06
|
||||
void bar06(){
|
||||
foo06(); // ref06
|
||||
}
|
||||
/* ---------- Test 7 ----------
|
||||
* static function foo07 defintined in second.c
|
||||
*/
|
||||
void foo07(); // decl07
|
||||
void bar07(){
|
||||
foo07(); // ref07
|
||||
}
|
||||
|
||||
/* ---------- Test 8 ----------
|
||||
* static function foo08 defintined in second.c
|
||||
*/
|
||||
static void bar08(){
|
||||
foo08(); // ref08
|
||||
}
|
||||
static void foo08() { // def08
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* ---------- Test 6 ----------
|
||||
* function foo06 used in func.c
|
||||
*/
|
||||
void foo06() { // def06
|
||||
}
|
||||
/* ---------- Test 7 ----------
|
||||
* function foo06 fake usage in func.c
|
||||
*/
|
||||
static void foo07() { // def07
|
||||
}
|
||||
|
||||
/* ---------- Test 8 ----------
|
||||
* static function foo08 defintined in second.c
|
||||
*/
|
||||
static void foo08() { // defS08
|
||||
}
|
||||
static void bar08(){
|
||||
foo08(); // refS08
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/* ---------- Test t02 ----------
|
||||
* tag struct
|
||||
*/
|
||||
|
||||
struct type_t01 {int a;}; // def_t01
|
||||
static void bar_t01(){
|
||||
struct type_t01 var; //ref_t01
|
||||
}
|
||||
|
||||
/* ---------- Test t02 ----------
|
||||
* struct pre-declaration
|
||||
*/
|
||||
|
||||
struct type_t02; // decl_t02
|
||||
static void bar_t02(){
|
||||
struct type_t02 * var; //ref_t02
|
||||
}
|
||||
|
||||
/* ---------- Test t03 ----------
|
||||
* struct pre-declaration and definiton
|
||||
*/
|
||||
|
||||
struct type_t03; // decl_t03
|
||||
static void bar_t03(){
|
||||
struct type_t03 * var; //ref_t03
|
||||
}
|
||||
struct type_t03 {int a;}; // def_t03
|
||||
|
||||
/* ---------- Test t04 ----------
|
||||
* typedef with structs
|
||||
*/
|
||||
|
||||
typedef struct type_t04 { // defS_t04
|
||||
struct type_t04 * next; // refS_t04
|
||||
} type_t04; // def_t04
|
||||
static void bar_t04(){
|
||||
type_t04 st; // ref_t04
|
||||
}
|
||||
/* ---------- Test t05 ----------
|
||||
* typedef with anonimous struct
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int a;
|
||||
} type_t05; // def_t05
|
||||
static void bar_t05(){
|
||||
type_t05 st; // ref_t05
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/* ---------- Test 9 ----------
|
||||
* write global
|
||||
*/
|
||||
int var_v09; // def_v09
|
||||
static void bar_v09(){
|
||||
var_v09=1; // ref_v09
|
||||
}
|
||||
|
||||
/* ---------- Test 10 ----------
|
||||
* read global
|
||||
*/
|
||||
int var_v10 = 1; // def_v10
|
||||
static void bar_v0(){
|
||||
int a = var_v10; // ref_v10
|
||||
}
|
||||
/* ---------- Test 11 ----------
|
||||
* read global in expr
|
||||
*/
|
||||
int var_v11 = 1; // def_v11
|
||||
static void bar_v11(){
|
||||
int a = 1 +
|
||||
var_v11; // ref_v11
|
||||
}
|
||||
/* ---------- Test _v12 ----------
|
||||
* def and decl
|
||||
*/
|
||||
extern int var_v12; // decl_v12
|
||||
static void bar_v12(){
|
||||
int a = var_v12; // ref_v12
|
||||
}
|
||||
int var_v12 = 1; // def_v12
|
||||
|
||||
/* ---------- Test _v13 ----------
|
||||
* def and decl
|
||||
*/
|
||||
|
||||
extern int var_v13; // decl_v13
|
||||
int var_v13 = 1; // def_v13
|
||||
|
||||
static void bar_v13(){
|
||||
int a = var_v13; // ref_v13
|
||||
}
|
||||
/* ---------- Test _v14 ----------
|
||||
* def and decl
|
||||
*/
|
||||
|
||||
|
||||
int var_v14 = 1; // def_v14
|
||||
extern int var_v14; // decl_v14
|
||||
|
||||
static void bar_v14(){
|
||||
int a = var_v14; // ref_v14
|
||||
}
|
Loading…
Add table
Reference in a new issue