1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-02 05:45:58 +02:00

fixed bug, builder was creating qualified name nodes when unqualified name required

This commit is contained in:
Mike Kucera 2008-02-13 20:17:29 +00:00
parent 4117aeccbd
commit 8ece714199
10 changed files with 2062 additions and 2958 deletions

View file

@ -15,6 +15,8 @@ import junit.framework.AssertionFailedError;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage; import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.dom.lrparser.c99.C99Language; import org.eclipse.cdt.core.dom.lrparser.c99.C99Language;
import org.eclipse.cdt.core.dom.lrparser.cpp.ISOCPPLanguage;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.tests.ast2.AST2CSpecTest; import org.eclipse.cdt.core.parser.tests.ast2.AST2CSpecTest;
import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.core.parser.ParserException;
@ -25,26 +27,26 @@ public class C99SpecTests extends AST2CSpecTest {
public C99SpecTests(String name) { super(name); } public C99SpecTests(String name) { super(name); }
/** @Override
* Only parses it as C actually
* @throws ParserException
*/
protected void parseCandCPP( String code, boolean checkBindings, int expectedProblemBindings ) throws ParserException { protected void parseCandCPP( String code, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
parse(code, ParserLanguage.C, checkBindings, expectedProblemBindings); //parse(code, ParserLanguage.C, checkBindings, expectedProblemBindings);
parse(code, ParserLanguage.CPP, checkBindings, expectedProblemBindings); parse(code, ParserLanguage.CPP, checkBindings, expectedProblemBindings);
} }
@Override
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean checkBindings, int expectedProblemBindings ) throws ParserException { protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
if(lang == ParserLanguage.C) ILanguage language = lang.isCPP() ? getCPPLanguage() : getCLanguage();
return ParseHelper.parse(code, getLanguage(), true, checkBindings, expectedProblemBindings ); return ParseHelper.parse(code, language, true, checkBindings, expectedProblemBindings );
else
return super.parse(code, lang, checkBindings, expectedProblemBindings);
} }
protected BaseExtensibleLanguage getLanguage() { protected BaseExtensibleLanguage getCLanguage() {
return C99Language.getDefault(); return C99Language.getDefault();
} }
protected BaseExtensibleLanguage getCPPLanguage() {
return ISOCPPLanguage.getDefault();
}
//Assignment statements cannot exists outside of a function body //Assignment statements cannot exists outside of a function body
@Override @Override
public void test5_1_2_3s15() throws Exception { public void test5_1_2_3s15() throws Exception {

View file

@ -19,9 +19,10 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage; import org.eclipse.cdt.core.dom.lrparser.BaseExtensibleLanguage;
import org.eclipse.cdt.core.model.AbstractLanguage; import org.eclipse.cdt.core.model.AbstractLanguage;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.core.parser.ParserUtil;
@ -38,42 +39,48 @@ public class ParseHelper {
static int testsRun = 0; static int testsRun = 0;
private static class C99NameResolver extends ASTVisitor { private static class NameResolver extends CPPASTVisitor {
{ {
shouldVisitNames = true; shouldVisitNames = true;
} }
public int numProblemBindings = 0; public int numProblemBindings = 0;
public int numNullBindings = 0; public int numNullBindings = 0;
@Override
public int visit( IASTName name ){ public int visit( IASTName name ){
System.out.println("Visit Name: '" + name.toString() + "'");
IBinding binding = name.resolveBinding(); IBinding binding = name.resolveBinding();
if (binding instanceof IProblemBinding) if (binding instanceof IProblemBinding) {
numProblemBindings++; numProblemBindings++;
if (binding == null) System.out.println("Problem Binding: " + name);
}
if (binding == null) {
numNullBindings++; numNullBindings++;
System.out.println("Null Binding: " + name);
}
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
} }
public static IASTTranslationUnit parse(char[] code, BaseExtensibleLanguage lang, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) { public static IASTTranslationUnit parse(char[] code, ILanguage lang, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) {
CodeReader codeReader = new CodeReader(code); CodeReader codeReader = new CodeReader(code);
return parse(codeReader, lang, new ScannerInfo(), null, expectNoProblems, checkBindings, expectedProblemBindings); return parse(codeReader, lang, new ScannerInfo(), null, expectNoProblems, checkBindings, expectedProblemBindings);
} }
public static IASTTranslationUnit parse(String code, BaseExtensibleLanguage lang, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) { public static IASTTranslationUnit parse(String code, ILanguage lang, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) {
return parse(code.toCharArray(), lang, expectNoProblems, checkBindings, expectedProblemBindings); return parse(code.toCharArray(), lang, expectNoProblems, checkBindings, expectedProblemBindings);
} }
public static IASTTranslationUnit parse(String code, BaseExtensibleLanguage lang, boolean expectNoProblems) { public static IASTTranslationUnit parse(String code, ILanguage lang, boolean expectNoProblems) {
return parse(code, lang, expectNoProblems, false, 0); return parse(code, lang, expectNoProblems, false, 0);
} }
public static IASTTranslationUnit parse(CodeReader codeReader, BaseExtensibleLanguage language, IScannerInfo scanInfo, public static IASTTranslationUnit parse(CodeReader codeReader, ILanguage language, IScannerInfo scanInfo,
ICodeReaderFactory fileCreator, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) { ICodeReaderFactory fileCreator, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) {
testsRun++; testsRun++;
@ -100,7 +107,7 @@ public class ParseHelper {
// resolve all bindings // resolve all bindings
if (checkBindings) { if (checkBindings) {
C99NameResolver res = new C99NameResolver(); NameResolver res = new NameResolver();
tu.accept( res ); tu.accept( res );
if (res.numProblemBindings != expectedProblemBindings ) if (res.numProblemBindings != expectedProblemBindings )
throw new AssertionFailedError("Expected " + expectedProblemBindings + " problem(s), encountered " + res.numProblemBindings ); //$NON-NLS-1$ //$NON-NLS-2$ throw new AssertionFailedError("Expected " + expectedProblemBindings + " problem(s), encountered " + res.numProblemBindings ); //$NON-NLS-1$ //$NON-NLS-2$

View file

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2006, 2008 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
*******************************************************************************/
package org.eclipse.cdt.core.lrparser.tests.c99;
import junit.framework.Test;
import junit.framework.TestSuite;
public class ParserTestSuiteConvenient extends TestSuite {
// this test suite is just for my convenience
public static Test suite() {
TestSuite suite = new TestSuite();
// suite.addTestSuite(C99Tests.class); // has some tests that do fail
// suite.addTestSuite(C99SpecTests.class); // a couple of failures
suite.addTest(new C99SpecTests("test6_7_2_3s10"));
// suite.addTestSuite(C99KnRTests.class); // mostly fail due to ambiguities
//
// // The majority of the content assist test are in the ui tests plugin
// suite.addTestSuite(C99CompletionBasicTest.class);
// // this one still has a lot of failing tests though
// suite.addTestSuite(C99SelectionParseTest.class);
//
// suite.addTestSuite(C99DOMLocationInclusionTests.class);
// suite.addTestSuite(C99DOMLocationTests.class);
// suite.addTestSuite(C99DOMLocationMacroTests.class);
// suite.addTestSuite(C99DOMPreprocessorInformationTest.class);
// suite.addTestSuite(C99CommentTests.class);
// suite.addTestSuite(C99DigraphTrigraphTests.class);
// suite.addTestSuite(C99GCCTests.class);
// suite.addTestSuite(C99UtilOldTests.class);
// suite.addTestSuite(C99UtilTests.class);
// suite.addTestSuite(C99CompleteParser2Tests.class);
// suite.addTestSuite(C99TaskParserTest.class);
return suite;
}
}

View file

@ -11,6 +11,7 @@ Export-Package: org.eclipse.cdt.core.dom.lrparser,
org.eclipse.cdt.core.dom.lrparser.action, org.eclipse.cdt.core.dom.lrparser.action,
org.eclipse.cdt.core.dom.lrparser.action.c99, org.eclipse.cdt.core.dom.lrparser.action.c99,
org.eclipse.cdt.core.dom.lrparser.c99, org.eclipse.cdt.core.dom.lrparser.c99,
org.eclipse.cdt.core.dom.lrparser.cpp,
org.eclipse.cdt.internal.core.dom.lrparser.c99;x-internal:=true, org.eclipse.cdt.internal.core.dom.lrparser.c99;x-internal:=true,
org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings org.eclipse.cdt.internal.core.dom.lrparser.c99.bindings
Bundle-Localization: plugin Bundle-Localization: plugin

View file

@ -11,7 +11,7 @@
%options la=2 %options la=2
%options package=org.eclipse.cdt.internal.core.dom.lrparser.cpp %options package=org.eclipse.cdt.internal.core.dom.lrparser.cpp
%options template=TrialUndoParserTemplate.g %options template=btParserTemplateD.g
@ -148,7 +148,7 @@ $End
$Define $Define
-- These macros allow the template and header code to be customized by an extending parser. -- These macros allow the template and header code to be customized by an extending parser.
$ast_class /.Object./ $ast_class /.Object./
$additional_interfaces /. ./ $additional_interfaces /. , IParserActionTokenProvider, IParser ./
$build_action_class /. CPPBuildASTParserAction ./ $build_action_class /. CPPBuildASTParserAction ./
$resolve_action_class /. C99TypedefTrackerParserAction ./ $resolve_action_class /. C99TypedefTrackerParserAction ./
@ -176,9 +176,9 @@ $Define
$builder /. action.builder./ $builder /. action.builder./
-- comment out when using trial/undo -- comment out when using trial/undo
--$Action /. $BeginAction ./ $Action /. $BeginAction ./
--$BeginFinal /. ./ $BeginFinal /. ./
--$EndFinal /. ./ $EndFinal /. ./
$End $End
@ -188,8 +188,8 @@ $Headers
private $action_class action; private $action_class action;
// uncomment to use with backtracking parser // uncomment to use with backtracking parser
//public $action_type() { // constructor public $action_type() { // constructor
//} }
private void initActions(IASTTranslationUnit tu) { private void initActions(IASTTranslationUnit tu) {
// binding resolution actions need access to IASTName nodes, temporary // binding resolution actions need access to IASTName nodes, temporary
@ -199,7 +199,7 @@ $Headers
//action.builder.setTokenMap(CPPParsersym.orderedTerminalSymbols); //action.builder.setTokenMap(CPPParsersym.orderedTerminalSymbols);
// comment this line to use with backtracking parser // comment this line to use with backtracking parser
setParserAction(action); //setParserAction(action);
} }
@ -231,7 +231,7 @@ $Headers
action = null; action = null;
// Comment this line to use with backtracking parser // Comment this line to use with backtracking parser
parserAction = null; //parserAction = null;
return compNode; return compNode;
} }
@ -258,9 +258,9 @@ $Headers
// uncomment this method to use with backtracking parser // uncomment this method to use with backtracking parser
//public List getRuleTokens() { public List getRuleTokens() {
// return Collections.unmodifiableList(getTokens().subList(getLeftSpan(), getRightSpan() + 1)); return Collections.unmodifiableList(getTokens().subList(getLeftSpan(), getRightSpan() + 1));
//} }
./ ./

View file

@ -103,15 +103,13 @@ public abstract class BaseExtensibleLanguage extends AbstractLanguage implements
System.out.println(); System.out.println();
System.out.println("********************************************************"); System.out.println("********************************************************");
System.out.println("Parsing");
System.out.println("Options: " + options);
System.out.println("GPP AST:"); System.out.println("GPP AST:");
DebugUtil.printAST(gtu); DebugUtil.printAST(gtu);
System.out.println(); System.out.println();
//IParseResult parseResult = parse(reader, scanInfo, fileCreator, index, null, null);
//IASTTranslationUnit tu = parseResult.getTranslationUnit();
// TODO temporary // TODO temporary
IScannerExtensionConfiguration config = new GCCScannerExtensionConfiguration(); IScannerExtensionConfiguration config = new GCCScannerExtensionConfiguration();
@ -138,6 +136,7 @@ public abstract class BaseExtensibleLanguage extends AbstractLanguage implements
IScannerInfo scanInfo, ICodeReaderFactory fileCreator, IScannerInfo scanInfo, ICodeReaderFactory fileCreator,
IIndex index, IParserLogService log) throws CoreException { IIndex index, IParserLogService log) throws CoreException {
System.out.println("Second Method");
return getASTTranslationUnit(reader, scanInfo, fileCreator, index, 0, log); return getASTTranslationUnit(reader, scanInfo, fileCreator, index, 0, log);
} }

View file

@ -51,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement; import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointer;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression; import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
@ -73,6 +74,7 @@ import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99NoCastExpressionParser;
import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym; import org.eclipse.cdt.internal.core.dom.lrparser.c99.C99Parsersym;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTAmbiguity;
/** /**
@ -118,9 +120,6 @@ public abstract class BuildASTParserAction {
private final IASTNodeFactory nodeFactory; private final IASTNodeFactory nodeFactory;
protected static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {
{ shouldVisitStatements = true; }
};
@ -324,13 +323,35 @@ public abstract class BuildASTParserAction {
setOffsetAndLength(tu, 0, offset(d) + length(d)); setOffsetAndLength(tu, 0, offset(d) + length(d));
} }
// resolve ambiguities resolveAmbiguityNodes();
tu.accept(EMPTY_VISITOR);
if(TRACE_AST_STACK) System.out.println(astStack); if(TRACE_AST_STACK) System.out.println(astStack);
} }
/**
* Removes ambiguity nodes from the AST by resolving them.
* The ambiguity nodes resolve themselves when visited for the first time.
* All ambiguities must be resolved before the AST is returned.
*
* @see CPPASTAmbiguity.accept()
* @see CASTAmbiguity.accept()
*
* TODO Ambiguity resolution may be avoided in the case that no
* ambiguity nodes were created.
*/
private void resolveAmbiguityNodes() {
tu.accept(EMPTY_VISITOR);
}
/**
* When applied to the AST causes ambiguity nodes to be resolved.
*/
protected static final ASTVisitor EMPTY_VISITOR = new ASTVisitor() {
{ shouldVisitStatements = true; }
};
/** /**
* Consumes a single identifier token. * Consumes a single identifier token.
@ -338,9 +359,7 @@ public abstract class BuildASTParserAction {
public void consumeIdentifierName() { public void consumeIdentifierName() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
IToken token = parser.getRightIToken(); astStack.push(createName(parser.getRightIToken()));
IASTName name = createName(token);
astStack.push(name);
if(TRACE_AST_STACK) System.out.println(astStack); if(TRACE_AST_STACK) System.out.println(astStack);
} }
@ -814,7 +833,7 @@ public abstract class BuildASTParserAction {
decl = nodeFactory.newDeclarator(nodeFactory.newName()); decl = nodeFactory.newDeclarator(nodeFactory.newName());
for(Object pointer : astStack.closeScope()) for(Object pointer : astStack.closeScope())
decl.addPointerOperator((ICASTPointer)pointer); decl.addPointerOperator((IASTPointer)pointer);
setOffsetAndLength(decl); setOffsetAndLength(decl);
astStack.push(decl); astStack.push(decl);
@ -911,7 +930,7 @@ public abstract class BuildASTParserAction {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
List<Object> declarators = (hasDeclaratorList) ? astStack.closeScope() : Collections.emptyList(); List<Object> declarators = (hasDeclaratorList) ? astStack.closeScope() : Collections.emptyList();
ICASTDeclSpecifier declSpecifier = (ICASTDeclSpecifier) astStack.pop(); // may be null IASTDeclSpecifier declSpecifier = (IASTDeclSpecifier) astStack.pop(); // may be null
IASTSimpleDeclaration declaration = nodeFactory.newSimpleDeclaration(declSpecifier); IASTSimpleDeclaration declaration = nodeFactory.newSimpleDeclaration(declSpecifier);

View file

@ -88,11 +88,11 @@ import org.eclipse.cdt.core.dom.lrparser.util.DebugUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
/** /**
* Semantic actions that build the AST during the parse. These are the actions * Semantic actions that build the AST during the parse.
* that are specific to the C++ parser. * These are the actions that are specific to the C++ parser, the superclass
* contains actions that can be shared with the C99 parser.
* *
* @author Mike Kucera * @author Mike Kucera
*
*/ */
public class CPPBuildASTParserAction extends BuildASTParserAction { public class CPPBuildASTParserAction extends BuildASTParserAction {
@ -633,6 +633,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
public void consumeNestedNameSpecifierEmpty() { public void consumeNestedNameSpecifierEmpty() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
// can't use Collections.EMPTY_LIST because we need a list thats mutable
astStack.push(new LinkedList<IASTName>()); astStack.push(new LinkedList<IASTName>());
if(TRACE_AST_STACK) System.out.println(astStack); if(TRACE_AST_STACK) System.out.println(astStack);
@ -676,7 +677,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
public void consumeQualifiedId(boolean hasTemplateKeyword) { public void consumeQualifiedId(boolean hasTemplateKeyword) {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
ICPPASTQualifiedName qualifiedName = subRuleQualifiedName(hasTemplateKeyword); IASTName qualifiedName = subRuleQualifiedName(hasTemplateKeyword);
astStack.push(qualifiedName); astStack.push(qualifiedName);
if(TRACE_AST_STACK) System.out.println(astStack); if(TRACE_AST_STACK) System.out.println(astStack);
@ -688,7 +689,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
* Creates a qualified name from a list of names (that must be in reverse order). * Creates a qualified name from a list of names (that must be in reverse order).
* Does not set the offset and length. * Does not set the offset and length.
*/ */
private ICPPASTQualifiedName createQualifiedName(LinkedList<IASTName> nestedNames, boolean hasDColon) { private ICPPASTQualifiedName createQualifiedName(LinkedList<IASTName> nestedNames, boolean startsWithColonColon) {
ICPPASTQualifiedName qualifiedName = nodeFactory.newCPPQualifiedName(); ICPPASTQualifiedName qualifiedName = nodeFactory.newCPPQualifiedName();
int startOffset = offset(nestedNames.getLast()); int startOffset = offset(nestedNames.getLast());
@ -698,8 +699,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
for(IASTName name : reverseIterable(nestedNames)) for(IASTName name : reverseIterable(nestedNames))
qualifiedName.addName(name); qualifiedName.addName(name);
qualifiedName.setFullyQualified(hasDColon); qualifiedName.setFullyQualified(startsWithColonColon);
return qualifiedName; return qualifiedName;
} }
@ -713,17 +713,22 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
* Does not place the resulting node on the stack, returns it instead. * Does not place the resulting node on the stack, returns it instead.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private ICPPASTQualifiedName subRuleQualifiedName(boolean hasOptionalKeyword) { private IASTName subRuleQualifiedName(boolean hasOptionalKeyword) {
IASTName subName = (IASTName) astStack.pop(); IASTName lastName = (IASTName) astStack.pop();
if(hasOptionalKeyword) // this is usually a template keyword and can be ignored if(hasOptionalKeyword) // this is usually a template keyword and can be ignored
astStack.pop(); astStack.pop();
LinkedList<IASTName> nestedNames = (LinkedList<IASTName>) astStack.pop(); LinkedList<IASTName> nestedNames = (LinkedList<IASTName>) astStack.pop();
boolean hasDColon = astStack.pop() == PLACE_HOLDER; boolean startsWithColonColon = astStack.pop() == PLACE_HOLDER;
nestedNames.addFirst(subName); if(nestedNames.isEmpty() && !startsWithColonColon) { // then its not a qualified name
return createQualifiedName(nestedNames, hasDColon); return lastName;
}
nestedNames.addFirst(lastName); // the list of names is in reverse order
return createQualifiedName(nestedNames, startsWithColonColon);
} }
@ -784,7 +789,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
public void consumeNamespaceAliasDefinition() { public void consumeNamespaceAliasDefinition() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
ICPPASTQualifiedName qualifiedName = subRuleQualifiedName(false); IASTName qualifiedName = subRuleQualifiedName(false);
IASTName alias = createName(parser.getRuleTokens().get(1)); IASTName alias = createName(parser.getRuleTokens().get(1));
ICPPASTNamespaceAlias namespaceAlias = nodeFactory.newNamespaceAlias(alias, qualifiedName); ICPPASTNamespaceAlias namespaceAlias = nodeFactory.newNamespaceAlias(alias, qualifiedName);
@ -803,7 +808,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
public void consumeUsingDeclaration() { public void consumeUsingDeclaration() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
ICPPASTQualifiedName qualifiedName = subRuleQualifiedName(false); IASTName qualifiedName = subRuleQualifiedName(false);
boolean hasTypenameKeyword = astStack.pop() == PLACE_HOLDER; boolean hasTypenameKeyword = astStack.pop() == PLACE_HOLDER;
ICPPASTUsingDeclaration usingDeclaration = nodeFactory.newUsingDeclaration(qualifiedName); ICPPASTUsingDeclaration usingDeclaration = nodeFactory.newUsingDeclaration(qualifiedName);
@ -823,7 +828,7 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
public void consumeUsingDirective() { public void consumeUsingDirective() {
if(TRACE_ACTIONS) DebugUtil.printMethodTrace(); if(TRACE_ACTIONS) DebugUtil.printMethodTrace();
ICPPASTQualifiedName qualifiedName = subRuleQualifiedName(false); IASTName qualifiedName = subRuleQualifiedName(false);
ICPPASTUsingDirective usingDirective = nodeFactory.newUsingDirective(qualifiedName); ICPPASTUsingDirective usingDirective = nodeFactory.newUsingDirective(qualifiedName);
setOffsetAndLength(usingDirective); setOffsetAndLength(usingDirective);

View file

@ -32,6 +32,8 @@ public final class CollectionUtils {
/** /**
* Returns an iterator that iterates backwards over the given list. * Returns an iterator that iterates backwards over the given list.
* The remove() method is not implemented and will throw UnsupportedOperationException. * The remove() method is not implemented and will throw UnsupportedOperationException.
* The returned iterator does not support the remove() method.
*
* @throws NullPointerException if list is null * @throws NullPointerException if list is null
*/ */
public static <T> Iterator<T> reverseIterator(final List<T> list) { public static <T> Iterator<T> reverseIterator(final List<T> list) {
@ -93,7 +95,7 @@ public final class CollectionUtils {
* @throws NullPointerException if source or pattern is null * @throws NullPointerException if source or pattern is null
*/ */
public static boolean matchTokens(List<IToken> source, Integer ... pattern) { public static boolean matchTokens(List<IToken> source, Integer ... pattern) {
if(source.size() != pattern.length) // throws NPE if either param is null if(source.size() != pattern.length) // throws NPE if either parameter is null
return false; return false;
for(int i = 0, n = pattern.length; i < n; i++) { for(int i = 0, n = pattern.length; i < n; i++) {
@ -107,13 +109,14 @@ public final class CollectionUtils {
/** /**
* Finds the first object in the heterogeneous list that is an instance of * Finds the first object in the heterogeneous list that is an instance of
* the given class, removes it from the list, and returns it. * the given class, removes it from the list, and returns it.
* If there is not object in the list of the given type the list is left
* unmodified and null is returned.
* *
* @throws NullPointerException if list or clazz is null * @throws NullPointerException if list or clazz is null
* @throws UnsupportedOperationException if the list's Iterator does not support the remove() method * @throws UnsupportedOperationException if the list's Iterator does not support the remove() method
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> T findFirstAndRemove(List<Object> list, Class<T> clazz) { public static <T> T findFirstAndRemove(List<Object> list, Class<T> clazz) {
// There's a name somewhere on the stack, find it
for(Iterator<Object> iter = list.iterator(); iter.hasNext();) { for(Iterator<Object> iter = list.iterator(); iter.hasNext();) {
Object o = iter.next(); Object o = iter.next();
if(clazz.isInstance(o)) { if(clazz.isInstance(o)) {