/******************************************************************************* * Copyright (c) 2006, 2015 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) * IBM Corporation * Symbian - Fix a race condition (157992) *******************************************************************************/ package org.eclipse.cdt.internal.pdom.tests; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; 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.core.parser.tests.VisibilityAsserts; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.CTestPlugin; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.ui.dialogs.IOverwriteQuery; import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; import org.eclipse.ui.wizards.datatransfer.ImportOperation; /** * @author Doug Schaefer */ public class PDOMTestBase extends BaseTestCase { protected static final IProgressMonitor PROGRESS = new NullProgressMonitor(); static IPath rootPath = new Path("resources/pdomtests"); private String projectName; protected ICProject createProject(String folderName) throws CoreException { return createProject(folderName, false); } protected ICProject createProject(String folderName, final boolean cpp) throws CoreException { final ICProject cprojects[] = new ICProject[1]; ModelJoiner mj= new ModelJoiner(); try { // Create the project projectName = "ProjTest_" + System.currentTimeMillis(); final File rootDir = CTestPlugin.getDefault().getFileInPlugin(rootPath.append(folderName)); final IWorkspace workspace = ResourcesPlugin.getWorkspace(); workspace.run(new IWorkspaceRunnable() { @Override public void run(IProgressMonitor monitor) throws CoreException { // Create the project ICProject cproject= cpp ? CProjectHelper.createCCProject(projectName, null, IPDOMManager.ID_NO_INDEXER) : CProjectHelper.createCProject(projectName, null, IPDOMManager.ID_NO_INDEXER); // Import the files at the root ImportOperation importOp = new ImportOperation(cproject.getProject().getFullPath(), rootDir, FileSystemStructureProvider.INSTANCE, new IOverwriteQuery() { @Override public String queryOverwrite(String pathString) { return IOverwriteQuery.ALL; } }); importOp.setCreateContainerStructure(false); try { importOp.run(monitor); } catch (Exception e) { throw new CoreException(new Status(IStatus.ERROR, CTestPlugin.PLUGIN_ID, 0, "Import interrupted", e)); } cprojects[0] = cproject; } }, null); mj.join(); // Index the project CCorePlugin.getIndexManager().setIndexerId(cprojects[0], IPDOMManager.ID_FAST_INDEXER); // Wait until the indexer is done try { waitForIndexer(cprojects[0]); } catch (InterruptedException e) { } } finally { mj.dispose(); } return cprojects[0]; } protected int offset(String projectRelativePath, String lookfor) throws Exception, CoreException { Path path= new Path(projectName + "/" + projectRelativePath); return TestSourceReader.indexOfInFile(lookfor, path); } protected IBinding[] findQualifiedName(PDOM pdom, String name) throws CoreException { String[] segments = name.split("::"); Pattern[] pattern = new Pattern[segments.length]; for (int i = 0; i < segments.length; i++) { pattern[i] = Pattern.compile(segments[i]); } return pdom.findBindings(pattern, true, IndexFilter.ALL_DECLARED, PROGRESS); } protected IBinding[] findQualifiedPossiblyImplicit(PDOM pdom, String name) throws CoreException { String[] segments = name.split("::"); Pattern[] pattern = new Pattern[segments.length]; for (int i = 0; i < segments.length; i++) { pattern[i] = Pattern.compile(segments[i]); } return pdom.findBindings(pattern, true, IndexFilter.ALL, PROGRESS); } protected IBinding[] findUnqualifiedName(PDOM pdom, String name) throws CoreException { String[] segments = name.split("::"); Pattern[] pattern = new Pattern[segments.length]; for (int i = 0; i < segments.length; i++) { pattern[i] = Pattern.compile(segments[i]); } return pdom.findBindings(pattern, false, IndexFilter.ALL, PROGRESS); } /** * Convenience method for checking the number of PDOM references for a * particular name. */ protected void assertReferenceCount(PDOM pdom, String name, int count) throws CoreException { assertNameCount(pdom, name, count, IIndexFragment.FIND_REFERENCES); } /** * Convenience method for checking the number of PDOM declarations for a * particular name. */ protected void assertDeclarationCount(PDOM pdom, String name, int count) throws CoreException { assertNameCount(pdom, name, count, IIndexFragment.FIND_DECLARATIONS_DEFINITIONS); } /** * Convenience method for checking the number of PDOM definitions for a * particular name. */ protected void assertDefinitionCount(PDOM pdom, String name, int count) throws CoreException { assertNameCount(pdom, name, count, IIndexFragment.FIND_DEFINITIONS); } private void assertNameCount(PDOM pdom, String name, int count, int options) throws CoreException { IBinding[] bindings = findQualifiedName(pdom, name); if (count > 0) { assertEquals(1, bindings.length); } if (bindings.length > 0) { IName[] names = pdom.findNames(bindings[0], options); assertUniqueNameCount(names, count); } else { assertEquals(0, count); } } protected void assertNameCount(PDOM pdom, IBinding binding, int options, int count) throws CoreException { IName[] names = pdom.findNames(binding, options); assertUniqueNameCount(names, count); } /** * Convenience method for checking how many unique instances (i.e. same * offset within the same file) there are within an array of INames. */ private void assertUniqueNameCount(IName[] names, int count) { Set offsets = new HashSet(); for (IName name : names) { offsets.add(name.getFileLocation()); } assertEquals(count, offsets.size()); } protected void assertType(PDOM pdom, String name, Class c) throws CoreException { IBinding[] bindings = findQualifiedName(pdom, name); assertEquals(1, bindings.length); assertTrue(c.isAssignableFrom(bindings[0].getClass())); } protected void assertCPPMemberVisibility(PDOM pdom, String name, int visibility) throws CoreException, DOMException { IBinding[] bindings = findQualifiedName(pdom, name); assertEquals(1, bindings.length); ICPPMember member = (ICPPMember) bindings[0]; VisibilityAsserts.assertVisibility(visibility, member.getVisibility()); } public static final void assertFunctionRefCount(PDOM pdom, Class[] args, IBinding[] bindingPool, int refCount) throws CoreException { IBinding[] bindings = findIFunctions(args, bindingPool); assertEquals(1, bindings.length); IName[] refs = pdom.findNames(bindings[0], IIndex.FIND_REFERENCES); assertEquals(refCount, refs.length); } // this is only approximate - composite types are not supported public static IBinding[] findIFunctions(Class[] paramTypes, IBinding[] bindings) throws CoreException { List preresult = new ArrayList(); for (IBinding binding : bindings) { if (binding instanceof IFunction) { IFunction function = (IFunction) binding; IType[] candidate = function.getType().getParameterTypes(); boolean areEqual = candidate.length == paramTypes.length; for (int j= 0; areEqual && j < paramTypes.length; j++) { if (!paramTypes[j].isAssignableFrom(candidate[j].getClass())) { areEqual = false; } } if (areEqual) { preresult.add(binding); } } } return (IBinding[]) preresult.toArray(new IBinding[preresult.size()]); } protected void assertInstance(Object o, Class c) { assertNotNull(o); assertTrue("Expected " + c.getName() + " but got " + o.getClass().getName(), c.isInstance(o)); } public static Pattern[] makePatternArray(String[] args) { List preresult = new ArrayList(); for (String arg : args) { preresult.add(Pattern.compile(arg)); } return (Pattern[]) preresult.toArray(new Pattern[preresult.size()]); } }