/********************************************************************** * Copyright (c) 2004, 2009 IBM Corporation 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: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.core.parser.tests.prefix; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import java.util.List; import junit.framework.AssertionFailedError; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; 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.parser.ISourceCodeParser; import org.eclipse.cdt.core.dom.parser.c.ANSICParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.c.GCCParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.c.ICParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.ANSICPPParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.GPPParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration; import org.eclipse.cdt.core.parser.FileContent; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.NullLogService; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.core.parser.tests.ast2.AST2BaseTest; 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.dom.parser.c.GNUCSourceParser; import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser; import org.eclipse.cdt.internal.core.parser.ParserException; public class CompletionTestBase extends BaseTestCase { private static final IParserLogService NULL_LOG = new NullLogService(); protected IASTCompletionNode getCompletionNode(String code, ParserLanguage lang, boolean useGNUExtensions) throws ParserException { FileContent codeReader = FileContent.create("<test-code>", code.trim().toCharArray()); ScannerInfo scannerInfo = new ScannerInfo(); IScanner scanner= AST2BaseTest.createScanner(codeReader, lang, ParserMode.COMPLETE_PARSE, scannerInfo); ISourceCodeParser parser = null; if( lang == ParserLanguage.CPP ) { ICPPParserExtensionConfiguration config = null; if (useGNUExtensions) config = new GPPParserExtensionConfiguration(); else config = new ANSICPPParserExtensionConfiguration(); parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config ); } else { ICParserExtensionConfiguration config = null; if (useGNUExtensions) config = new GCCParserExtensionConfiguration(); else config = new ANSICParserExtensionConfiguration(); parser = new GNUCSourceParser( scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config ); } scanner.setContentAssistMode(code.length()); parser.parse(); return parser.getCompletionNode(); } protected IASTCompletionNode getGPPCompletionNode(String code) throws ParserException { return getCompletionNode(code, ParserLanguage.CPP, true); } protected IASTCompletionNode getGCCCompletionNode(String code) throws ParserException { return getCompletionNode(code, ParserLanguage.C, true); } protected void checkCompletion(String code, boolean isCpp, String[] expected) throws ParserException { checkCompletion(code, true, isCpp, expected); } protected void checkNonPrefixCompletion(String code, boolean isCpp, String[] expected) throws ParserException { checkCompletion(code, false, isCpp, expected); } private void checkCompletion(String code, boolean isPrefix, boolean isCpp, String[] expected) throws ParserException { IASTCompletionNode node = isCpp ? getGPPCompletionNode(code) : getGCCCompletionNode(code); assertNotNull(node); List<IBinding> bindings= proposeBindings(node, isPrefix); String[] names= getSortedNames(bindings); int len= Math.min(expected.length, names.length); for (int i = 0; i < len; i++) { assertEquals(expected[i], names[i]); } assertEquals(expected.length, names.length); } private static class BindingsComparator implements Comparator { public int compare(Object o1, Object o2) { IBinding b1 = (IBinding)o1; IBinding b2 = (IBinding)o2; return b1.getName().compareTo(b2.getName()); } } private static BindingsComparator bindingsComparator = new BindingsComparator(); protected IBinding[] sortBindings(IBinding[] bindings) { Arrays.sort(bindings, bindingsComparator); return bindings; } protected String getAboveComment() throws IOException { return getContents(1)[0].toString(); } protected StringBuilder[] getContents(int sections) throws IOException { CTestPlugin plugin = CTestPlugin.getDefault(); if (plugin == null) throw new AssertionFailedError("This test must be run as a JUnit plugin test"); return TestSourceReader.getContentsForTest(plugin.getBundle(), "parser", getClass(), getName(), sections); } protected List<IBinding> proposeBindings(IASTCompletionNode completionNode, boolean isPrefix) { List<IBinding> proposals = new ArrayList<IBinding>(); boolean handleMacros= false; IASTName[] names = completionNode.getNames(); for (int i = 0; i < names.length; ++i) { if (names[i].getTranslationUnit() == null) // The node isn't properly hooked up, must have backtracked out of this node continue; IASTCompletionContext astContext = names[i].getCompletionContext(); if (astContext == null) { continue; } IBinding[] bindings = astContext.findBindings(names[i], isPrefix); if (bindings != null) for (int j = 0; j < bindings.length; ++j) proposals.add(bindings[j]); } return proposals; } protected String[] getSortedNames(List<IBinding> bindings) { String[] result= new String[bindings.size()]; Iterator<IBinding> it= bindings.iterator(); for (int i = 0; i < result.length; i++) { result[i]= it.next().getName(); } Arrays.sort(result); return result; } }