mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Cleanup parsing of qualified names, fixes bug 256840.
This commit is contained in:
parent
66e2ae5119
commit
b66d33d52d
16 changed files with 665 additions and 2178 deletions
|
@ -4397,7 +4397,7 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
IASTDeclarator d = p2m.getDeclarators()[0];
|
||||
ICPPASTPointerToMember po = (ICPPASTPointerToMember) d
|
||||
.getPointerOperators()[0];
|
||||
assertEquals(po.getName().toString(), "X::"); //$NON-NLS-1$
|
||||
assertEquals("X::", po.getName().toString()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// struct B {};
|
||||
|
@ -6150,9 +6150,11 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
// struct B {
|
||||
// operator ns::A(); // problems on operator ns and on A
|
||||
// };
|
||||
public void _testNamespaceQualifiedOperator_256840() throws Exception {
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
||||
public void testNamespaceQualifiedOperator_256840() throws Exception {
|
||||
final String code = getAboveComment();
|
||||
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||
bh.assertNonProblem("operator ns::A", 14);
|
||||
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||
}
|
||||
|
||||
// void f();
|
||||
|
|
|
@ -6,17 +6,14 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Created on Jan 17, 2005
|
||||
*/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
* Interface for problem bindings.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IProblemBinding extends IBinding, IScope, IType {
|
||||
|
||||
|
@ -123,5 +120,15 @@ public interface IProblemBinding extends IBinding, IScope, IType {
|
|||
|
||||
public static final int SEMANTIC_RECURSION_IN_LOOKUP = 0x00E;
|
||||
|
||||
public static final int LAST_PROBLEM = SEMANTIC_RECURSION_IN_LOOKUP;
|
||||
/**
|
||||
* @deprecated, there may be additional problems.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int LAST_PROBLEM = 0x00E;
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public static final int SEMANTIC_INVALID_TEMPLATE_ARGUMENTS = 0x00F;
|
||||
|
||||
}
|
||||
|
|
|
@ -18,8 +18,9 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
public interface ITokenDuple {
|
||||
|
||||
public abstract IToken getFirstToken();
|
||||
|
|
|
@ -415,17 +415,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
* @throws BacktrackException
|
||||
* request a backtrack
|
||||
*/
|
||||
protected IToken identifier() throws EndOfFileException, BacktrackException {
|
||||
switch (LT(1)) {
|
||||
case IToken.tIDENTIFIER:
|
||||
case IToken.tCOMPLETION:
|
||||
case IToken.tEOC:
|
||||
return consume();
|
||||
default:
|
||||
throw backtrack;
|
||||
}
|
||||
|
||||
}
|
||||
protected abstract IASTName identifier() throws EndOfFileException, BacktrackException;
|
||||
|
||||
/**
|
||||
* @return Returns the backtrackCount.
|
||||
|
@ -887,8 +877,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
protected abstract IASTExpression unaryExpression() throws BacktrackException, EndOfFileException;
|
||||
protected abstract IASTExpression primaryExpression() throws BacktrackException, EndOfFileException;
|
||||
|
||||
protected abstract IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId, int startingOffset, int endingOffset);
|
||||
|
||||
protected abstract IASTTranslationUnit getTranslationUnit();
|
||||
|
||||
protected abstract void setupTranslationUnit() throws Exception;
|
||||
|
@ -1268,7 +1256,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
|
||||
IASTName name;
|
||||
if (LT(1) == IToken.tIDENTIFIER) {
|
||||
name= createName(identifier());
|
||||
name= identifier();
|
||||
} else {
|
||||
name= nodeFactory.newName();
|
||||
}
|
||||
|
@ -1308,7 +1296,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
if (needComma)
|
||||
throw backtrack;
|
||||
|
||||
final IASTName etorName= createName(identifier());
|
||||
final IASTName etorName= identifier();
|
||||
final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null);
|
||||
endOffset= calculateEndOffset(etorName);
|
||||
setRange(enumerator, problemOffset, endOffset);
|
||||
|
@ -1339,8 +1327,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
|
||||
protected abstract IASTStatement statement() throws EndOfFileException, BacktrackException;
|
||||
|
||||
protected abstract IASTName createName(IToken token);
|
||||
|
||||
protected IASTExpression condition(boolean followedByParenthesis) throws BacktrackException, EndOfFileException {
|
||||
IToken mark= mark();
|
||||
try {
|
||||
|
@ -1666,15 +1652,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
protected abstract IASTAmbiguousStatement createAmbiguousStatement();
|
||||
|
||||
protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException {
|
||||
IToken labelName = consume(); // tIDENTIFIER
|
||||
consume(); // tCOLON
|
||||
int offset= LA(1).getOffset();
|
||||
IASTName name = identifier(); // tIDENTIFIER
|
||||
consume(IToken.tCOLON); // tCOLON
|
||||
IASTStatement nestedStatement = statement();
|
||||
int lastOffset = calculateEndOffset( nestedStatement );
|
||||
|
||||
IASTName name = createName(labelName);
|
||||
|
||||
IASTLabelStatement label_statement = nodeFactory.newLabelStatement(name, nestedStatement);
|
||||
((ASTNode) label_statement).setOffsetAndLength(labelName.getOffset(), lastOffset - labelName.getOffset());
|
||||
setRange(label_statement, offset, lastOffset);
|
||||
return label_statement;
|
||||
}
|
||||
|
||||
|
@ -1688,10 +1674,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
|
||||
protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException {
|
||||
int startOffset = consume().getOffset(); // t_goto
|
||||
IToken identifier = consume(IToken.tIDENTIFIER);
|
||||
IASTName goto_label_name = identifier();
|
||||
int lastOffset = consume(IToken.tSEMI).getEndOffset();
|
||||
|
||||
IASTName goto_label_name = createName(identifier);
|
||||
IASTGotoStatement goto_statement = nodeFactory.newGotoStatement(goto_label_name);
|
||||
((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset - startOffset);
|
||||
return goto_statement;
|
||||
|
@ -1745,7 +1730,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
switch (LT(1)) {
|
||||
case IToken.tEOC:
|
||||
// We're trying to start one
|
||||
IASTName name = createName(LA(1));
|
||||
IASTName name = identifier();
|
||||
IASTIdExpression idExpr = nodeFactory.newIdExpression(name);
|
||||
result = idExpr;
|
||||
break;
|
||||
|
@ -1945,8 +1930,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
consume();
|
||||
IASTExpression expr2= expression();
|
||||
endOffset1= consumeOrEOC(IToken.tRPAREN).getEndOffset();
|
||||
|
||||
expr= buildTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid, typeidOffset, calculateEndOffset(typeid));
|
||||
expr= nodeFactory.newTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid);
|
||||
setRange(expr, typeidOffset, calculateEndOffset(typeid));
|
||||
|
||||
IASTExpressionList expressionList = nodeFactory.newExpressionList();
|
||||
((ASTNode) expressionList).setOffsetAndLength(typeidOffset, calculateEndOffset(expr2)-typeidOffset);
|
||||
|
@ -1989,7 +1974,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
|||
|
||||
IASTExpression result1= null;
|
||||
if (typeid != null && endOffset1 >= endOffset2) {
|
||||
result1= buildTypeIdExpression(typeExprKind, typeid, offset, endOffset1);
|
||||
IASTTypeIdExpression typeIdExpression = nodeFactory.newTypeIdExpression(typeExprKind, typeid);
|
||||
setRange(typeIdExpression, offset, endOffset1);
|
||||
result1= typeIdExpression;
|
||||
backup(typeidLA);
|
||||
|
||||
if (expr == null || endOffset1 > endOffset2)
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.eclipse.core.runtime.PlatformObject;
|
|||
*/
|
||||
public class ProblemBinding extends PlatformObject implements IProblemBinding, IType, IScope, IASTInternalScope {
|
||||
protected final int id;
|
||||
protected final char[] arg;
|
||||
protected char[] arg;
|
||||
protected IASTNode node;
|
||||
private String message = null;
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
|
||||
protected static final String[] errorMessages;
|
||||
static {
|
||||
errorMessages = new String[IProblemBinding.LAST_PROBLEM];
|
||||
errorMessages = new String[IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS];
|
||||
errorMessages[SEMANTIC_NAME_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.nameNotFound"); //$NON-NLS-1$
|
||||
errorMessages[SEMANTIC_AMBIGUOUS_LOOKUP - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.ambiguousLookup"); //$NON-NLS-1$
|
||||
errorMessages[SEMANTIC_INVALID_TYPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.pst.invalidType"); //$NON-NLS-1$
|
||||
|
@ -71,6 +71,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
errorMessages[SEMANTIC_BAD_SCOPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.badScope"); //$NON-NLS-1$
|
||||
errorMessages[SEMANTIC_RECURSION_IN_LOOKUP - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.recursionInResolution"); //$NON-NLS-1$
|
||||
errorMessages[SEMANTIC_MEMBER_DECLARATION_NOT_FOUND - 1]= ParserMessages.getString("ASTProblemFactory.error.semantic.dom.memberDeclNotFound"); //$NON-NLS-1$
|
||||
errorMessages[SEMANTIC_INVALID_TEMPLATE_ARGUMENTS - 1]= ParserMessages.getString("ASTProblemFactory.error.semantic.dom.invalidTemplateArgs"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -87,7 +88,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
if (message != null)
|
||||
return message;
|
||||
|
||||
String msg = (id >= 0 && id <= LAST_PROBLEM) ? errorMessages[id - 1] : ""; //$NON-NLS-1$
|
||||
String msg = (id > 0 && id <= errorMessages.length) ? errorMessages[id - 1] : ""; //$NON-NLS-1$
|
||||
|
||||
if (arg != null) {
|
||||
msg = MessageFormat.format(msg, new Object[] { new String(arg) });
|
||||
|
@ -224,6 +225,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
public int getLineNumber() {
|
||||
if (node != null) {
|
||||
IASTFileLocation fileLoc = node.getFileLocation();
|
||||
if (fileLoc != null)
|
||||
return fileLoc.getStartingLineNumber();
|
||||
}
|
||||
return -1;
|
||||
|
@ -245,4 +247,11 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
|||
public IBinding getOwner() throws DOMException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setASTNode(IASTNode node, char[] arg) {
|
||||
if (node != null)
|
||||
this.node= node;
|
||||
if (arg != null)
|
||||
this.arg= arg;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,10 +227,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
switch (LT(1)) {
|
||||
case IToken.tDOT:
|
||||
int offset = consume().getOffset();
|
||||
IToken id = identifier();
|
||||
IASTName n = createName(id);
|
||||
IASTName n = identifier();
|
||||
ICASTFieldDesignator fieldDesignator = nodeFactory.newFieldDesignator(n);
|
||||
setRange(fieldDesignator, offset, id.getEndOffset());
|
||||
setRange(fieldDesignator, offset, calculateEndOffset(n));
|
||||
if (designatorList == null)
|
||||
designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
|
||||
designatorList.add(fieldDesignator);
|
||||
|
@ -266,11 +265,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
// fix for 84176: if reach identifier and it's not a designator then return empty designator list
|
||||
if (supportGCCStyleDesignators && lt1 == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) {
|
||||
IToken identifier = identifier();
|
||||
int offset= LA(1).getOffset();
|
||||
IASTName n = identifier();
|
||||
int lastOffset = consume(IToken.tCOLON).getEndOffset();
|
||||
IASTName n = createName(identifier);
|
||||
ICASTFieldDesignator designator = nodeFactory.newFieldDesignator(n);
|
||||
((ASTNode) designator).setOffsetAndLength(identifier.getOffset(), lastOffset - identifier.getOffset());
|
||||
setRange(designator, offset, lastOffset);
|
||||
return Collections.singletonList(designator);
|
||||
}
|
||||
|
||||
|
@ -542,15 +541,6 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IASTExpression buildTypeIdExpression(int op, IASTTypeId typeId,
|
||||
int startingOffset, int endingOffset) {
|
||||
IASTTypeIdExpression result = nodeFactory.newTypeIdExpression(op, typeId);
|
||||
((ASTNode) result).setOffsetAndLength(startingOffset, endingOffset - startingOffset);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
protected IASTExpression postfixExpression() throws EndOfFileException, BacktrackException {
|
||||
IASTExpression firstExpression = null;
|
||||
switch (LT(1)) {
|
||||
|
@ -634,7 +624,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
case IToken.tDOT:
|
||||
// member access
|
||||
IToken dot = consume();
|
||||
IASTName name = createName(identifier());
|
||||
IASTName name = identifier();
|
||||
if (name == null)
|
||||
throwBacktrack(((ASTNode) firstExpression).getOffset(),
|
||||
((ASTNode) firstExpression).getLength() + dot.getLength());
|
||||
|
@ -648,7 +638,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
case IToken.tARROW:
|
||||
// member access
|
||||
IToken arrow = consume();
|
||||
name = createName(identifier());
|
||||
name = identifier();
|
||||
if (name == null)
|
||||
throwBacktrack(((ASTNode) firstExpression).getOffset(),
|
||||
((ASTNode) firstExpression).getLength() + arrow.getLength());
|
||||
|
@ -722,8 +712,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
case IToken.tCOMPLETION:
|
||||
case IToken.tEOC:
|
||||
int startingOffset = LA(1).getOffset();
|
||||
IToken t1 = identifier();
|
||||
IASTName name = createName(t1);
|
||||
IASTName name = identifier();
|
||||
IASTIdExpression idExpression = nodeFactory.newIdExpression(name);
|
||||
((ASTNode) idExpression).setOffsetAndLength((ASTNode) name);
|
||||
return idExpression;
|
||||
|
@ -843,7 +832,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
int options= 0;
|
||||
int isLong= 0;
|
||||
|
||||
IToken identifier= null;
|
||||
IASTName identifier= null;
|
||||
IASTDeclSpecifier result= null;
|
||||
IASTExpression typeofExpression= null;
|
||||
IASTProblem problem= null;
|
||||
|
@ -1001,11 +990,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
IToken mark= mark();
|
||||
try {
|
||||
final IToken idToken= identifier(); // for the specifier
|
||||
final IASTName id= identifier(); // for the specifier
|
||||
final IASTDeclarator altDtor = initDeclarator(declOption);
|
||||
if (LA(1) == e.currToken) {
|
||||
e.altDeclarator= altDtor;
|
||||
e.altSpec= buildNamedTypeSpecifier(idToken, storageClass, options, offset, idToken.getEndOffset());
|
||||
e.altSpec= buildNamedTypeSpecifier(id, storageClass, options, offset, calculateEndOffset(id));
|
||||
}
|
||||
} catch (FoundAggregateInitializer lie) {
|
||||
lie.fDeclSpec= e.declSpec;
|
||||
|
@ -1017,7 +1006,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
throw e;
|
||||
}
|
||||
identifier = identifier();
|
||||
endOffset= identifier.getEndOffset();
|
||||
endOffset= calculateEndOffset(identifier);
|
||||
encounteredTypename= true;
|
||||
break;
|
||||
case IToken.t_struct:
|
||||
|
@ -1121,9 +1110,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return buildSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
|
||||
}
|
||||
|
||||
private ICASTTypedefNameSpecifier buildNamedTypeSpecifier(IToken identifier, int storageClass,
|
||||
private ICASTTypedefNameSpecifier buildNamedTypeSpecifier(IASTName name, int storageClass,
|
||||
int options, int offset, int endOffset) {
|
||||
IASTName name = createName(identifier);
|
||||
ICASTTypedefNameSpecifier declSpec = nodeFactory.newTypedefNameSpecifier(name);
|
||||
configureDeclSpec(declSpec, storageClass, options);
|
||||
declSpec.setRestrict((options & RESTRICT) != 0);
|
||||
|
@ -1218,9 +1206,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
|
||||
|
||||
// class name
|
||||
IToken nameToken = null;
|
||||
IASTName name = null;
|
||||
if (LT(1) == IToken.tIDENTIFIER) {
|
||||
nameToken = identifier();
|
||||
name = identifier();
|
||||
}
|
||||
|
||||
// if __attribute__ or __declspec occurs after struct/union/class identifier and before the { or ;
|
||||
|
@ -1232,7 +1220,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
throwBacktrack(errorPoint);
|
||||
}
|
||||
|
||||
IASTName name = (nameToken == null) ? nodeFactory.newName() : createName(nameToken);
|
||||
if (name == null) {
|
||||
name= nodeFactory.newName();
|
||||
}
|
||||
ICASTCompositeTypeSpecifier result = nodeFactory.newCompositeTypeSpecifier(classKind, name);
|
||||
|
||||
int endOffset= consume().getEndOffset();
|
||||
|
@ -1303,8 +1293,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
// if __attribute__ or __declspec occurs after struct/union/class and before the identifier
|
||||
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
|
||||
|
||||
IToken identifier = identifier();
|
||||
IASTName name = createName(identifier);
|
||||
IASTName name = identifier();
|
||||
IASTElaboratedTypeSpecifier result = nodeFactory.newElaboratedTypeSpecifier(eck, name);
|
||||
((ASTNode) result).setOffsetAndLength(t.getOffset(), calculateEndOffset(name) - t.getOffset());
|
||||
return result;
|
||||
|
@ -1361,7 +1350,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if (option.fRequireAbstract)
|
||||
throwBacktrack(LA(1));
|
||||
|
||||
final IASTName declaratorName = createName(identifier());
|
||||
final IASTName declaratorName = identifier();
|
||||
endOffset= calculateEndOffset(declaratorName);
|
||||
return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, option);
|
||||
}
|
||||
|
@ -1520,14 +1509,14 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
switch (LT(1)) {
|
||||
case IToken.tCOMMA:
|
||||
last = consume();
|
||||
parmNames[i] = createName(identifier());
|
||||
parmNames[i] = identifier();
|
||||
seenParameter = true;
|
||||
break;
|
||||
case IToken.tIDENTIFIER:
|
||||
if (seenParameter)
|
||||
throwBacktrack(startOffset, last.getEndOffset() - startOffset);
|
||||
|
||||
parmNames[i] = createName(identifier());
|
||||
parmNames[i] = identifier();
|
||||
seenParameter = true;
|
||||
break;
|
||||
case IToken.tRPAREN:
|
||||
|
@ -1672,18 +1661,29 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
|
||||
@Override
|
||||
protected IASTName createName(IToken t) {
|
||||
IASTName n = nodeFactory.newName(t.getCharImage());
|
||||
protected IASTName identifier() throws EndOfFileException, BacktrackException {
|
||||
final IToken t= LA(1);
|
||||
IASTName n;
|
||||
switch (t.getType()) {
|
||||
case IToken.tIDENTIFIER:
|
||||
consume();
|
||||
n = nodeFactory.newName(t.getCharImage());
|
||||
break;
|
||||
|
||||
case IToken.tCOMPLETION:
|
||||
case IToken.tEOC:
|
||||
consume();
|
||||
n = nodeFactory.newName(t.getCharImage());
|
||||
createCompletionNode(t).addName(n);
|
||||
break;
|
||||
}
|
||||
((ASTNode) n).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset());
|
||||
return n;
|
||||
|
||||
default:
|
||||
throw backtrack;
|
||||
}
|
||||
|
||||
setRange(n, t.getOffset(), t.getEndOffset());
|
||||
return n;
|
||||
}
|
||||
|
||||
protected void consumeArrayModifiers(List<IASTArrayModifier> arrayMods) throws EndOfFileException, BacktrackException {
|
||||
while (LT(1) == IToken.tLBRACKET) {
|
||||
|
|
|
@ -112,23 +112,22 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA
|
|||
}
|
||||
|
||||
public void replace(IASTNode child, IASTNode other) {
|
||||
if( thenClause == child )
|
||||
{
|
||||
other.setParent( child.getParent() );
|
||||
other.setPropertyInParent( child.getPropertyInParent() );
|
||||
if (thenClause == child) {
|
||||
other.setParent(child.getParent());
|
||||
other.setPropertyInParent(child.getPropertyInParent());
|
||||
thenClause = (IASTStatement) other;
|
||||
}
|
||||
else if( elseClause == child )
|
||||
{
|
||||
other.setParent( child.getParent() );
|
||||
other.setPropertyInParent( child.getPropertyInParent() );
|
||||
} else if (elseClause == child) {
|
||||
other.setParent(child.getParent());
|
||||
other.setPropertyInParent(child.getPropertyInParent());
|
||||
elseClause = (IASTStatement) other;
|
||||
}
|
||||
if( condDecl == child )
|
||||
{
|
||||
other.setParent( child.getParent() );
|
||||
other.setPropertyInParent( child.getPropertyInParent() );
|
||||
} else if (condDecl == child) {
|
||||
other.setParent(child.getParent());
|
||||
other.setPropertyInParent(child.getPropertyInParent());
|
||||
condDecl = (IASTDeclaration) other;
|
||||
} else if (condition == child) {
|
||||
other.setParent(child.getParent());
|
||||
other.setPropertyInParent(child.getPropertyInParent());
|
||||
condition = (IASTExpression) other;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
|
@ -97,7 +98,15 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName {
|
|||
fBinding= new RecursionResolvingBinding(this);
|
||||
} else {
|
||||
fIsFinal= false;
|
||||
fBinding= createIntermediateBinding();
|
||||
final IBinding b= createIntermediateBinding();
|
||||
if (b instanceof ProblemBinding) {
|
||||
ProblemBinding pb= (ProblemBinding) b;
|
||||
final IASTNode node= pb.getASTNode();
|
||||
if (node == null || node.getParent() == null) {
|
||||
pb.setASTNode(this, toCharArray());
|
||||
}
|
||||
}
|
||||
fBinding= b;
|
||||
}
|
||||
}
|
||||
if (!fIsFinal)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -162,7 +162,7 @@ public class CPPTemplates {
|
|||
final int numArgs = arguments.length;
|
||||
final int numParams= parameters.length;
|
||||
if (numParams == 0 || numParams < numArgs)
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
|
||||
|
||||
ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[numParams];
|
||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams);
|
||||
|
@ -176,7 +176,7 @@ public class CPPTemplates {
|
|||
} else {
|
||||
ICPPTemplateArgument defaultArg= param.getDefaultValue();
|
||||
if (defaultArg == null) {
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
|
||||
}
|
||||
arg= instantiateArgument(defaultArg, map, null);
|
||||
arg= SemanticUtil.getSimplifiedArgument(arg);
|
||||
|
@ -186,7 +186,7 @@ public class CPPTemplates {
|
|||
if (!hasDependentDefaultArg) {
|
||||
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
|
||||
if (arg == null)
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
|
||||
}
|
||||
|
||||
map.put(param, arg);
|
||||
|
@ -212,19 +212,7 @@ public class CPPTemplates {
|
|||
}
|
||||
|
||||
private static IBinding createProblem(ICPPClassTemplate template, int id) {
|
||||
IASTNode node= null;
|
||||
if (template instanceof ICPPInternalBinding) {
|
||||
ICPPInternalBinding internal= (ICPPInternalBinding) template;
|
||||
node= internal.getDefinition();
|
||||
if (node == null) {
|
||||
IASTNode[] decls= internal.getDeclarations();
|
||||
if (decls != null && decls.length > 0)
|
||||
node= decls[0];
|
||||
}
|
||||
}
|
||||
if (node == null) {
|
||||
node= new CPPASTName(template.getNameCharArray());
|
||||
}
|
||||
IASTNode node= new CPPASTName(template.getNameCharArray());
|
||||
return new ProblemBinding(node, id, template.getNameCharArray());
|
||||
}
|
||||
|
||||
|
|
|
@ -75,4 +75,5 @@ ASTProblemFactory.error.semantic.dom.invalidRedeclaration=Invalid redeclaration
|
|||
ASTProblemFactory.error.semantic.dom.recursionInResolution=Recursion while looking up ''{0}''
|
||||
ASTProblemFactory.error.semantic.dom.badScope=A scope could not be created to represent the name {0}
|
||||
ASTProblemFactory.error.semantic.dom.memberDeclNotFound=A declaration could not be found for this member definition: {0}
|
||||
ASTProblemFactory.error.semantic.dom.invalidTemplateArgs=A template id provides illegal arguments for the instantiation: {0}
|
||||
CPPASTAmbiguousTemplateArgument_InvalidConstruction=Internal parser error: Template argument ambiguity constructed with {0}
|
||||
|
|
|
@ -1,105 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 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 Rational Software - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
|
||||
/**
|
||||
* Manages lists of template parameter nodes during the parsing
|
||||
* of names. The purpose of this class is performance, as these
|
||||
* lists are managed using lazy initialization and object pooling.
|
||||
* This class is basically as substitute for List<List<IASTNode>>.
|
||||
*
|
||||
* When using the object pool code must be wrapped in a try-finally
|
||||
* block to ensure the object is returned to the pool.
|
||||
*
|
||||
* TODO: How much of a performance improvement are we talking about here?
|
||||
* It might make sense just to get rid of this class. The extra complexity
|
||||
* might not be worth it.
|
||||
*/
|
||||
public final class TemplateParameterManager {
|
||||
|
||||
protected void reset() {
|
||||
list = Collections.emptyList();
|
||||
emptySegmentCount = 0;
|
||||
}
|
||||
|
||||
private TemplateParameterManager(int i) {
|
||||
reset();
|
||||
counterId = i;
|
||||
}
|
||||
|
||||
private final int counterId;
|
||||
private List<List<IASTNode>> list;
|
||||
private int emptySegmentCount;
|
||||
|
||||
public List<List<IASTNode>> getTemplateArgumentsList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void addSegment(List<IASTNode> inputSegment) {
|
||||
// avoid creating an actual ArrayList instance for as long as possible
|
||||
if(inputSegment == null) {
|
||||
if(list.isEmpty())
|
||||
++emptySegmentCount;
|
||||
else
|
||||
list.add( null );
|
||||
}
|
||||
else {
|
||||
if(list.isEmpty()) {
|
||||
list = new ArrayList<List<IASTNode>>();
|
||||
for( int i = 0; i < emptySegmentCount; ++i )
|
||||
list.add( null );
|
||||
}
|
||||
list.add( inputSegment );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// An object pool
|
||||
|
||||
private static final int NUMBER_OF_INSTANCES = 8;
|
||||
private static final boolean [] instancesUsed = new boolean[ NUMBER_OF_INSTANCES ];
|
||||
private static final TemplateParameterManager [] counters = new TemplateParameterManager[ NUMBER_OF_INSTANCES ];
|
||||
private static int counter = 8;
|
||||
static {
|
||||
for( int i = 0; i < NUMBER_OF_INSTANCES; ++i ) {
|
||||
counters[ i ] = new TemplateParameterManager( i );
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static TemplateParameterManager getInstance() {
|
||||
int index = findFreeCounter();
|
||||
if( index == -1 )
|
||||
return new TemplateParameterManager(++counter);
|
||||
instancesUsed[ index ] = true;
|
||||
return counters[ index ];
|
||||
}
|
||||
|
||||
public synchronized static void returnInstance( TemplateParameterManager c ) {
|
||||
if( c.counterId > 0 && c.counterId < NUMBER_OF_INSTANCES )
|
||||
instancesUsed[ c.counterId ] = false;
|
||||
c.reset();
|
||||
}
|
||||
|
||||
|
||||
private static int findFreeCounter() {
|
||||
for( int i = 0; i < NUMBER_OF_INSTANCES; ++i )
|
||||
if( instancesUsed[i] == false )
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,607 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2002, 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 Rational Software - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.ITokenDuple;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*
|
||||
*/
|
||||
public class BasicTokenDuple implements ITokenDuple {
|
||||
|
||||
BasicTokenDuple( IToken first, IToken last )
|
||||
{
|
||||
// assert ( first != null && last != null ) : this;
|
||||
firstToken = first;
|
||||
lastToken = last;
|
||||
}
|
||||
|
||||
protected int numSegments = -1;
|
||||
|
||||
BasicTokenDuple( ITokenDuple firstDuple, ITokenDuple secondDuple ){
|
||||
this( firstDuple.getFirstToken(), secondDuple.getLastToken() );
|
||||
}
|
||||
|
||||
protected final IToken firstToken, lastToken;
|
||||
|
||||
|
||||
public IToken getFirstToken() {
|
||||
return firstToken;
|
||||
}
|
||||
|
||||
public IToken getLastToken() {
|
||||
return lastToken;
|
||||
}
|
||||
|
||||
public Iterator<IToken> iterator()
|
||||
{
|
||||
return new TokenIterator();
|
||||
}
|
||||
|
||||
|
||||
public ITokenDuple getLastSegment()
|
||||
{
|
||||
IToken first = null, last = null, token = null;
|
||||
for( ; ; ){
|
||||
if( token == getLastToken() )
|
||||
break;
|
||||
token = ( token != null ) ? token.getNext() : getFirstToken();
|
||||
if( first == null )
|
||||
first = token;
|
||||
if( token.getType() == IToken.tLT )
|
||||
token = TokenFactory.consumeTemplateIdArguments( token, getLastToken() );
|
||||
else if( token.getType() == IToken.tCOLONCOLON ){
|
||||
first = null;
|
||||
continue;
|
||||
}
|
||||
last = token;
|
||||
}
|
||||
|
||||
List<IASTNode> [] args = getTemplateIdArgLists();
|
||||
if( args != null && args[ args.length - 1 ] != null ){
|
||||
List<List<IASTNode>> newArgs = new ArrayList<List<IASTNode>>( 1 );
|
||||
newArgs.add( args[ args.length - 1 ] );
|
||||
return TokenFactory.createTokenDuple( first, last, newArgs );
|
||||
}
|
||||
return TokenFactory.createTokenDuple( first, last );
|
||||
}
|
||||
|
||||
public ITokenDuple[] getSegments()
|
||||
{
|
||||
|
||||
List<ITokenDuple> r = new ArrayList<ITokenDuple>();
|
||||
IToken token = null;
|
||||
IToken prev = null;
|
||||
IToken last = getLastToken();
|
||||
IToken startOfSegment = getFirstToken();
|
||||
for( ;; ){
|
||||
if( token == last )
|
||||
break;
|
||||
if( startOfSegment == last.getNext() && startOfSegment.getType() != IToken.tEOC ) // for the EOC token, next points to itself
|
||||
{
|
||||
startOfSegment = null;
|
||||
break;
|
||||
}
|
||||
prev = token;
|
||||
token = ( token != null ) ? token.getNext() : getFirstToken();
|
||||
if( token.getType() == IToken.tLT )
|
||||
token = TokenFactory.consumeTemplateIdArguments( token, last );
|
||||
if( token.getType() == IToken.tCOLONCOLON ){
|
||||
if( startOfSegment == token ){
|
||||
//an empty segment, prev is not valid (and neither is the code)
|
||||
prev = null;
|
||||
}
|
||||
ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, ( prev == null ) ? startOfSegment : prev );
|
||||
r.add( d );
|
||||
startOfSegment = token.getNext();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( startOfSegment != null )
|
||||
{
|
||||
ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, last );
|
||||
r.add( d );
|
||||
}
|
||||
return r.toArray( new ITokenDuple[ r.size() ]);
|
||||
|
||||
}
|
||||
|
||||
public ITokenDuple getLeadingSegments(){
|
||||
if( getFirstToken() == null )
|
||||
return null;
|
||||
|
||||
int num = getSegmentCount();
|
||||
|
||||
if( num <= 1 )
|
||||
return null;
|
||||
|
||||
IToken first = null, last = null;
|
||||
IToken previous = null, token = null;
|
||||
|
||||
for( ; ; ){
|
||||
if( token == getLastToken() )
|
||||
break;
|
||||
token = ( token != null ) ? token.getNext() : getFirstToken();
|
||||
if( first == null )
|
||||
first = token;
|
||||
if( token.getType() == IToken.tLT )
|
||||
token = TokenFactory.consumeTemplateIdArguments( token, getLastToken() );
|
||||
else if( token.getType() == IToken.tCOLONCOLON ){
|
||||
last = previous;
|
||||
continue;
|
||||
}
|
||||
previous = token;
|
||||
}
|
||||
|
||||
if( last == null ){
|
||||
//"::A"
|
||||
return null;
|
||||
}
|
||||
|
||||
if( getTemplateIdArgLists() != null ){
|
||||
List<IASTNode>[] args = getTemplateIdArgLists();
|
||||
List<List<IASTNode>> newArgs = new ArrayList<List<IASTNode>>( args.length - 1 );
|
||||
boolean foundArgs = false;
|
||||
for( int i = 0; i < args.length - 1; i++ ){
|
||||
newArgs.add( args[i] );
|
||||
if( args[i] != null )
|
||||
foundArgs = true;
|
||||
}
|
||||
return TokenFactory.createTokenDuple( first, last, ( foundArgs ? newArgs : null ) );
|
||||
}
|
||||
return TokenFactory.createTokenDuple( first, last );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSegmentCount()
|
||||
*/
|
||||
public int getSegmentCount() {
|
||||
if( numSegments == -1 )
|
||||
numSegments = calculateSegmentCount();
|
||||
return numSegments;
|
||||
}
|
||||
|
||||
private static final char[] EMPTY_STRING = "".toCharArray(); //$NON-NLS-1$
|
||||
private char[] stringRepresentation = null;
|
||||
|
||||
private class TokenIterator implements Iterator<IToken>
|
||||
{
|
||||
private IToken iter = firstToken;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Iterator#hasNext()
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return ( iter != null );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Iterator#next()
|
||||
*/
|
||||
public IToken next() {
|
||||
if( ! hasNext() )
|
||||
throw new NoSuchElementException();
|
||||
IToken temp = iter;
|
||||
if( iter == lastToken )
|
||||
iter = null;
|
||||
else
|
||||
iter = iter.getNext();
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.util.Iterator#remove()
|
||||
*/
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static int getCharArrayLength( IToken f, IToken l ){
|
||||
if( f == l )
|
||||
return f.getCharImage().length;
|
||||
|
||||
IToken prev = null;
|
||||
IToken iter = f;
|
||||
|
||||
int length = 0;
|
||||
for( ; ; ){
|
||||
if( iter == null ) return 0;
|
||||
if( prev != null && prev.getType() != IToken.tCOLONCOLON &&
|
||||
prev.getType() != IToken.tIDENTIFIER &&
|
||||
prev.getType() != IToken.tLT &&
|
||||
prev.getType() != IToken.tBITCOMPLEMENT &&
|
||||
iter.getType() != IToken.tGT &&
|
||||
prev.getType() != IToken.tLBRACKET &&
|
||||
iter.getType() != IToken.tRBRACKET &&
|
||||
iter.getType() != IToken.tCOLONCOLON )
|
||||
{
|
||||
length++;
|
||||
}
|
||||
length += iter.getCharImage().length;
|
||||
if( iter == l ) break;
|
||||
prev = iter;
|
||||
iter = iter.getNext();
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
public static char[] createCharArrayRepresentation( IToken f, IToken l)
|
||||
{
|
||||
if( f == l ) return f.getCharImage();
|
||||
|
||||
IToken prev = null;
|
||||
IToken iter = f;
|
||||
|
||||
int length = getCharArrayLength( f, l );
|
||||
|
||||
char[] buff = new char[ length ];
|
||||
|
||||
for( int i = 0; i < length; )
|
||||
{
|
||||
if( prev != null &&
|
||||
prev.getType() != IToken.tCOLONCOLON &&
|
||||
prev.getType() != IToken.tIDENTIFIER &&
|
||||
prev.getType() != IToken.tLT &&
|
||||
prev.getType() != IToken.tBITCOMPLEMENT &&
|
||||
iter.getType() != IToken.tGT &&
|
||||
prev.getType() != IToken.tLBRACKET &&
|
||||
iter.getType() != IToken.tRBRACKET &&
|
||||
iter.getType() != IToken.tCOLONCOLON )
|
||||
buff[i++] = ' ';
|
||||
|
||||
if( iter == null ) return EMPTY_STRING;
|
||||
CharArrayUtils.overWrite( buff, i, iter.getCharImage() );
|
||||
i+= iter.getCharImage().length;
|
||||
if( iter == l ) break;
|
||||
prev = iter;
|
||||
iter = iter.getNext();
|
||||
}
|
||||
return buff;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
if( stringRepresentation == null )
|
||||
stringRepresentation = createCharArrayRepresentation(firstToken, lastToken);
|
||||
return String.valueOf(stringRepresentation);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#length()
|
||||
*/
|
||||
public int length()
|
||||
{
|
||||
int count = 1;
|
||||
IToken i = firstToken;
|
||||
while( i != lastToken )
|
||||
{
|
||||
++count;
|
||||
i = i.getNext();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSubDuple(int, int)
|
||||
*/
|
||||
public ITokenDuple getSubrange(int startIndex, int endIndex)
|
||||
{
|
||||
return TokenFactory.createTokenDuple( getToken( startIndex ), getToken( endIndex) );
|
||||
}
|
||||
|
||||
public IToken getToken(int index)
|
||||
{
|
||||
if( index < 0 ) return null;
|
||||
|
||||
IToken iter = firstToken;
|
||||
int count = 0;
|
||||
while( iter != lastToken )
|
||||
{
|
||||
iter = iter.getNext();
|
||||
if( count == index )
|
||||
return iter;
|
||||
++count;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#findLastTokenType(int)
|
||||
*/
|
||||
public int findLastTokenType(int type)
|
||||
{
|
||||
int count = 0;
|
||||
int lastFound = -1;
|
||||
IToken i = firstToken;
|
||||
while( i != lastToken )
|
||||
{
|
||||
if( i.getType() == type )
|
||||
lastFound = count;
|
||||
++count;
|
||||
i = i.getNext();
|
||||
}
|
||||
|
||||
return lastFound;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getEndOffset()
|
||||
*/
|
||||
public int getEndOffset() {
|
||||
return getLastToken().getEndOffset();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getStartOffset()
|
||||
*/
|
||||
public int getStartOffset() {
|
||||
return getFirstToken().getOffset();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getTemplateIdArgLists()
|
||||
*/
|
||||
public List<IASTNode>[] getTemplateIdArgLists() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#syntaxOfName()
|
||||
*/
|
||||
public boolean syntaxOfName() {
|
||||
IToken iter = firstToken;
|
||||
while( iter != lastToken)
|
||||
{
|
||||
if( iter.getType() == IToken.tLT ){
|
||||
iter = TokenFactory.consumeTemplateIdArguments( iter, lastToken );
|
||||
if( iter.getType() == IToken.tGT ){
|
||||
if( iter == lastToken ) break;
|
||||
iter = iter.getNext();
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if( iter.isOperator() )
|
||||
{
|
||||
iter = iter.getNext();
|
||||
continue;
|
||||
}
|
||||
switch( iter.getType() )
|
||||
{
|
||||
case IToken.tBITCOMPLEMENT:
|
||||
case IToken.tIDENTIFIER:
|
||||
case IToken.tCOLONCOLON:
|
||||
case IToken.t_operator:
|
||||
iter = iter.getNext();
|
||||
continue;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if( !(other instanceof ITokenDuple ) ) return false;
|
||||
if( ((ITokenDuple) other).getFirstToken().equals( getFirstToken() ) &&
|
||||
((ITokenDuple) other).getLastToken().equals( getLastToken() ) )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public ITokenDuple getTemplateIdNameTokenDuple() {
|
||||
ITokenDuple nameDuple = getLastSegment();
|
||||
|
||||
List<IASTNode>[] argLists = getTemplateIdArgLists();
|
||||
if( argLists == null || argLists[ argLists.length - 1 ] == null )
|
||||
return nameDuple;
|
||||
|
||||
IToken i = nameDuple.getFirstToken();
|
||||
IToken last = nameDuple.getLastToken();
|
||||
|
||||
if( i.getType() == IToken.t_template )
|
||||
i = i.getNext();
|
||||
|
||||
if( i == last )
|
||||
return TokenFactory.createTokenDuple(i, i);
|
||||
|
||||
IToken first= i;
|
||||
|
||||
//destructors
|
||||
if( i.getType() == IToken.tBITCOMPLEMENT ){
|
||||
i = i.getNext();
|
||||
}
|
||||
//operators
|
||||
else if( i.getType() == IToken.t_operator ){
|
||||
i = i.getNext();
|
||||
IToken temp = null;
|
||||
while( i != last ){
|
||||
temp = i.getNext();
|
||||
if( temp.getType() != IToken.tLT )
|
||||
i = temp;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return TokenFactory.createTokenDuple(first, i);
|
||||
}
|
||||
|
||||
public char[] extractNameFromTemplateId(){
|
||||
ITokenDuple nameDuple = getLastSegment();
|
||||
|
||||
List<IASTNode>[] argLists = getTemplateIdArgLists();
|
||||
if( argLists == null || argLists[ argLists.length - 1 ] == null )
|
||||
return nameDuple.toCharArray();
|
||||
|
||||
IToken i = nameDuple.getFirstToken();
|
||||
IToken last = nameDuple.getLastToken();
|
||||
|
||||
if( i == null )
|
||||
return EMPTY_STRING;
|
||||
else if( i.getType() == IToken.t_template )
|
||||
i = i.getNext();
|
||||
|
||||
char[] tempArray = i.getCharImage();
|
||||
|
||||
if( i == last )
|
||||
return tempArray;
|
||||
|
||||
|
||||
char[] nameBuffer = new char[ getCharArrayLength( i, lastToken ) ];
|
||||
|
||||
CharArrayUtils.overWrite( nameBuffer, 0, tempArray );
|
||||
int idx = tempArray.length;
|
||||
|
||||
//appending of spaces needs to be the same as in toString()
|
||||
|
||||
//destructors
|
||||
if( i.getType() == IToken.tBITCOMPLEMENT ){
|
||||
i = i.getNext();
|
||||
tempArray = i.getCharImage();
|
||||
CharArrayUtils.overWrite( nameBuffer, idx, tempArray );
|
||||
idx += tempArray.length;
|
||||
}
|
||||
//operators
|
||||
else if( i.getType() == IToken.t_operator ){
|
||||
i = i.getNext();
|
||||
nameBuffer[ idx++ ] = ' ';
|
||||
|
||||
IToken first = i;
|
||||
IToken temp = null;
|
||||
while( i != last ){
|
||||
temp = i.getNext();
|
||||
if( temp.getType() != IToken.tLT )
|
||||
i = temp;
|
||||
else
|
||||
break;
|
||||
}
|
||||
CharArrayUtils.overWrite( nameBuffer, idx, createCharArrayRepresentation( first, i ) );
|
||||
idx += getCharArrayLength( first, i );
|
||||
}
|
||||
|
||||
return CharArrayUtils.extract( nameBuffer, 0, idx );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#contains(org.eclipse.cdt.core.parser.ITokenDuple)
|
||||
*/
|
||||
public boolean contains(ITokenDuple duple) {
|
||||
if( duple == null ) return false;
|
||||
boolean foundFirst = false;
|
||||
boolean foundLast = false;
|
||||
for( IToken current = getFirstToken(); current != null; current = current.getNext() )
|
||||
{
|
||||
if( current == duple.getFirstToken() ) foundFirst = true;
|
||||
if( current == duple.getLastToken() ) foundLast = true;
|
||||
if( foundFirst && foundLast ) break;
|
||||
if( current == getLastToken() ) break;
|
||||
}
|
||||
|
||||
return ( foundFirst && foundLast );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#toQualifiedName()
|
||||
*/
|
||||
public String[] toQualifiedName() {
|
||||
return generateQualifiedName();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String [] generateQualifiedName() {
|
||||
List<String> qn = new ArrayList<String>();
|
||||
IToken i = firstToken;
|
||||
while( i != lastToken )
|
||||
{
|
||||
boolean compl = false;
|
||||
if( i.getType() == IToken.tCOLONCOLON )
|
||||
{
|
||||
i = i.getNext();
|
||||
continue;
|
||||
}
|
||||
if( i.getType() == IToken.tBITCOMPLEMENT )
|
||||
{
|
||||
compl = true;
|
||||
i = i.getNext();
|
||||
}
|
||||
if( i.getType() == IToken.tIDENTIFIER )
|
||||
{
|
||||
if( compl )
|
||||
{
|
||||
StringBuffer buff = new StringBuffer( "~" ); //$NON-NLS-1$
|
||||
buff.append( i.getImage() );
|
||||
qn.add( buff.toString() );
|
||||
}
|
||||
else
|
||||
qn.add( i.getImage() );
|
||||
}
|
||||
i = i.getNext();
|
||||
}
|
||||
if( i.getType() == IToken.tIDENTIFIER ){
|
||||
qn.add( i.getImage() );
|
||||
}
|
||||
String [] qualifiedName = new String[ qn.size() ];
|
||||
return qn.toArray( qualifiedName );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected int calculateSegmentCount() {
|
||||
int n = 1;
|
||||
|
||||
IToken token = null;
|
||||
IToken last = getLastToken();
|
||||
for( ;; ){
|
||||
if( token == last )
|
||||
break;
|
||||
token = ( token != null ) ? token.getNext() : getFirstToken();
|
||||
if( token == null ) break;
|
||||
if( token.getType() == IToken.tLT )
|
||||
token = TokenFactory.consumeTemplateIdArguments( token, last );
|
||||
if( token.getType() == IToken.tCOLONCOLON ){
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#toCharArray()
|
||||
*/
|
||||
public char[] toCharArray() {
|
||||
if( stringRepresentation == null )
|
||||
stringRepresentation = createCharArrayRepresentation(firstToken, lastToken);
|
||||
return stringRepresentation;
|
||||
}
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 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 - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.token;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.ITokenDuple;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||
|
||||
/**
|
||||
* This class is used by the GNUCPPSourceParser as an intermediate determinant of whether a
|
||||
* BasicTokenDuple represents an IASTConversionFunction or an IASTOperatorFunction.
|
||||
*
|
||||
* @author dsteffle
|
||||
*/
|
||||
public class OperatorTokenDuple implements ITokenDuple {
|
||||
|
||||
private ITokenDuple token = null;
|
||||
private IASTTypeId typeId = null;
|
||||
private boolean isConversionOperator=false;
|
||||
private OverloadableOperator op = null;
|
||||
|
||||
/**
|
||||
* Simple constructor. token is wrapped by this class.
|
||||
* @param token
|
||||
*/
|
||||
public OperatorTokenDuple(ITokenDuple token, OverloadableOperator op) {
|
||||
this.token=token;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
// below are functions used by GNUCPPSourceParser, see IOperatorTokenDuple
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#isConversionOperator()
|
||||
*/
|
||||
public boolean isConversionOperator() {
|
||||
return isConversionOperator;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#setConversionOperator(boolean)
|
||||
*/
|
||||
public void setConversionOperator(boolean isConversionOperator) {
|
||||
this.isConversionOperator = isConversionOperator;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#getTypeId()
|
||||
*/
|
||||
public IASTTypeId getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.internal.core.parser.token.IOperatorTokenDuple#
|
||||
* isConversionOperator(org.eclipse.cdt.core.dom.ast.IASTTypeId)
|
||||
*/
|
||||
public void setTypeId(IASTTypeId typeId) {
|
||||
this.typeId = typeId;
|
||||
}
|
||||
|
||||
public OverloadableOperator getOperator() {
|
||||
return op;
|
||||
}
|
||||
|
||||
// below are ITokenDuple functions
|
||||
public IToken getFirstToken() {
|
||||
return token.getFirstToken();
|
||||
}
|
||||
|
||||
public IToken getLastToken() {
|
||||
return token.getLastToken();
|
||||
}
|
||||
|
||||
public List<IASTNode>[] getTemplateIdArgLists() {
|
||||
return token.getTemplateIdArgLists();
|
||||
}
|
||||
|
||||
public ITokenDuple getLastSegment() {
|
||||
return token.getLastSegment();
|
||||
}
|
||||
|
||||
public ITokenDuple getLeadingSegments() {
|
||||
return token.getLeadingSegments();
|
||||
}
|
||||
|
||||
public int getSegmentCount() {
|
||||
return token.getSegmentCount();
|
||||
}
|
||||
|
||||
public Iterator<IToken> iterator() {
|
||||
return token.iterator();
|
||||
}
|
||||
|
||||
public char[] toCharArray() {
|
||||
return token.toCharArray();
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return token.length();
|
||||
}
|
||||
|
||||
public IToken getToken(int index) {
|
||||
return token.getToken(index);
|
||||
}
|
||||
|
||||
public ITokenDuple[] getSegments() {
|
||||
return token.getSegments();
|
||||
}
|
||||
|
||||
public int getStartOffset() {
|
||||
return token.getStartOffset();
|
||||
}
|
||||
|
||||
public int getEndOffset() {
|
||||
return token.getEndOffset();
|
||||
}
|
||||
|
||||
public char[] extractNameFromTemplateId() {
|
||||
return token.extractNameFromTemplateId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return token.toString();
|
||||
}
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 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 Rational Software - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.token;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.ITokenDuple;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*
|
||||
*/
|
||||
public class TemplateTokenDuple extends BasicTokenDuple {
|
||||
|
||||
protected final List<IASTNode>[] argLists;
|
||||
|
||||
/**
|
||||
* @param first
|
||||
* @param last
|
||||
* @param templateArgLists
|
||||
*/
|
||||
public TemplateTokenDuple(IToken first, IToken last, List<List<IASTNode>> templateArgLists) {
|
||||
super(first, last);
|
||||
argLists = toArray(templateArgLists);
|
||||
numSegments = calculateSegmentCount();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> List<T>[] toArray(List<List<T>> templateArgLists) {
|
||||
return templateArgLists.toArray( new List[templateArgLists.size()] );
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> List<T>[] newArrayOfLists(int size) {
|
||||
return new List[size];
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSegmentCount()
|
||||
*/
|
||||
@Override
|
||||
public int getSegmentCount() {
|
||||
return numSegments;
|
||||
}
|
||||
@Override
|
||||
public ITokenDuple getLastSegment()
|
||||
{
|
||||
IToken first = null, last = null, token = null;
|
||||
for( ; ; ){
|
||||
if( token == getLastToken() )
|
||||
break;
|
||||
token = ( token != null ) ? token.getNext() : getFirstToken();
|
||||
if( first == null )
|
||||
first = token;
|
||||
if( token.getType() == IToken.tLT )
|
||||
token = TokenFactory.consumeTemplateIdArguments( token, getLastToken() );
|
||||
else if( token.getType() == IToken.tCOLONCOLON ){
|
||||
first = null;
|
||||
continue;
|
||||
}
|
||||
last = token;
|
||||
}
|
||||
|
||||
List<IASTNode>[] args = getTemplateIdArgLists();
|
||||
if( args != null && args[ args.length - 1 ] != null ){
|
||||
List<List<IASTNode>> newArgs = new ArrayList<List<IASTNode>>( 1 );
|
||||
newArgs.add( args[ args.length - 1 ] );
|
||||
return TokenFactory.createTokenDuple( first, last, newArgs );
|
||||
}
|
||||
return TokenFactory.createTokenDuple( first, last );
|
||||
|
||||
}
|
||||
|
||||
public TemplateTokenDuple( ITokenDuple first, ITokenDuple last )
|
||||
{
|
||||
super( first, last );
|
||||
List<IASTNode>[] a1 = first.getTemplateIdArgLists();
|
||||
List<IASTNode>[] a2 = last.getTemplateIdArgLists();
|
||||
|
||||
int l1 = ( a1 != null ) ? a1.length : first.getSegmentCount();
|
||||
int l2 = ( a2 != null ) ? a2.length : first.getSegmentCount();
|
||||
argLists = newArrayOfLists(l1 + l2);
|
||||
if( a1 != null )
|
||||
System.arraycopy( a1, 0, argLists, 0, l1 );
|
||||
if( a2 != null )
|
||||
System.arraycopy( a2, 0, argLists, l1, l2 );
|
||||
numSegments = calculateSegmentCount();
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getTemplateIdArgLists()
|
||||
*/
|
||||
@Override
|
||||
public List<IASTNode>[] getTemplateIdArgLists() {
|
||||
return argLists;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITokenDuple[] getSegments()
|
||||
{
|
||||
List<ITokenDuple> r = new ArrayList<ITokenDuple>();
|
||||
IToken token = null;
|
||||
IToken prev = null;
|
||||
IToken last = getLastToken();
|
||||
IToken startOfSegment = getFirstToken();
|
||||
int count = 0;
|
||||
for( ;; ){
|
||||
if( token == last )
|
||||
break;
|
||||
prev = token;
|
||||
token = ( token != null ) ? token.getNext() : getFirstToken();
|
||||
if( token.getType() == IToken.tLT )
|
||||
token = TokenFactory.consumeTemplateIdArguments( token, last );
|
||||
if( token.getType() == IToken.tCOLONCOLON ){
|
||||
List<List<IASTNode>> newArgs = null;
|
||||
if( argLists[count] != null )
|
||||
{
|
||||
newArgs = new ArrayList<List<IASTNode>>(1);
|
||||
newArgs.add( argLists[count]);
|
||||
}
|
||||
ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, prev != null ? prev : startOfSegment, newArgs );
|
||||
r.add( d );
|
||||
startOfSegment = (token != last ) ? token.getNext() : last;
|
||||
++count;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
List<List<IASTNode>> newArgs = null;
|
||||
//pointer to members could have a A::B<int>::
|
||||
if( count < argLists.length && argLists[count] != null )
|
||||
{
|
||||
newArgs = new ArrayList<List<IASTNode>>(1);
|
||||
newArgs.add(argLists[count]);
|
||||
}
|
||||
ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, last, newArgs);
|
||||
r.add( d );
|
||||
return r.toArray( new ITokenDuple[ r.size() ]);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,275 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 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 Rational Software - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser.token;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.ITokenDuple;
|
||||
|
||||
/**
|
||||
* @author johnc
|
||||
*/
|
||||
public class TokenFactory {
|
||||
protected static final char[] EMPTY_CHAR_ARRAY = "".toCharArray(); //$NON-NLS-1$
|
||||
|
||||
private static class TokenWrapper implements ITokenDuple {
|
||||
private final IToken fToken;
|
||||
|
||||
public TokenWrapper(IToken t) {
|
||||
fToken= t;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return fToken.toString();
|
||||
}
|
||||
public char[] extractNameFromTemplateId(){
|
||||
return fToken.getCharImage();
|
||||
}
|
||||
public IToken getFirstToken() {
|
||||
return fToken;
|
||||
}
|
||||
public ITokenDuple getLastSegment() {
|
||||
return this;
|
||||
}
|
||||
public IToken getLastToken() {
|
||||
return fToken;
|
||||
}
|
||||
public ITokenDuple getLeadingSegments() {
|
||||
return null;
|
||||
}
|
||||
public int getSegmentCount() {
|
||||
return 1;
|
||||
}
|
||||
public int getStartOffset() {
|
||||
return fToken.getOffset();
|
||||
}
|
||||
public List<IASTNode>[] getTemplateIdArgLists() {
|
||||
return null;
|
||||
}
|
||||
public IToken getToken(int index) {
|
||||
if( index == 0 ) return fToken;
|
||||
return null;
|
||||
}
|
||||
public Iterator<IToken> iterator() {
|
||||
return new Iterator<IToken>() {
|
||||
private boolean hasNext = true;
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean hasNext() {
|
||||
return hasNext;
|
||||
}
|
||||
public IToken next() {
|
||||
hasNext = false;
|
||||
return fToken;
|
||||
}
|
||||
};
|
||||
}
|
||||
public int length() {
|
||||
return 1;
|
||||
}
|
||||
public ITokenDuple[] getSegments() {
|
||||
return new ITokenDuple[] {this};
|
||||
}
|
||||
public int getEndOffset() {
|
||||
return fToken.getEndOffset();
|
||||
}
|
||||
public char[] toCharArray() {
|
||||
return fToken.getCharImage();
|
||||
}
|
||||
}
|
||||
|
||||
public static ITokenDuple createTokenDuple(IToken first, IToken last) {
|
||||
if (first == last) {
|
||||
if (first instanceof ITokenDuple) {
|
||||
return (ITokenDuple) first;
|
||||
}
|
||||
return new TokenWrapper(first);
|
||||
}
|
||||
return new BasicTokenDuple( first, last );
|
||||
}
|
||||
|
||||
public static ITokenDuple createTokenDuple(IToken first, IToken last, List<List<IASTNode>> templateArgLists) {
|
||||
if (templateArgLists == null || templateArgLists.isEmpty()) {
|
||||
return createTokenDuple(first, last);
|
||||
}
|
||||
return new TemplateTokenDuple( first, last, templateArgLists );
|
||||
}
|
||||
|
||||
public static ITokenDuple createTokenDuple( ITokenDuple firstDuple, ITokenDuple secondDuple ){
|
||||
if( secondDuple == null ) return firstDuple;
|
||||
if( firstDuple == null ) return secondDuple;
|
||||
List<IASTNode>[] f1 = firstDuple.getTemplateIdArgLists();
|
||||
List<IASTNode>[] f2 = secondDuple.getTemplateIdArgLists();
|
||||
if( f1 == null && f2 == null )
|
||||
return new BasicTokenDuple( firstDuple, secondDuple );
|
||||
return new TemplateTokenDuple( firstDuple, secondDuple );
|
||||
}
|
||||
|
||||
public static IToken consumeTemplateIdArguments( IToken name, IToken last ){
|
||||
IToken token = name;
|
||||
|
||||
if( token.getType() == IToken.tLT )
|
||||
{
|
||||
if( token == last )
|
||||
return token;
|
||||
|
||||
BraceCounter scopes = BraceCounter.getCounter();
|
||||
try
|
||||
{
|
||||
scopes.addValue( IToken.tLT );
|
||||
|
||||
while (!scopes.isEmpty() && token != last )
|
||||
{
|
||||
int top;
|
||||
|
||||
token = token.getNext();
|
||||
switch( token.getType() ){
|
||||
case IToken.tGT:
|
||||
if( scopes.getLast() == IToken.tLT ) {
|
||||
scopes.removeValue();
|
||||
}
|
||||
break;
|
||||
case IToken.tRBRACKET :
|
||||
do {
|
||||
top = scopes.removeValue();
|
||||
} while (!scopes.isEmpty() && top == IToken.tLT);
|
||||
break;
|
||||
case IToken.tRPAREN :
|
||||
do {
|
||||
top = scopes.removeValue();
|
||||
} while (!scopes.isEmpty() && top == IToken.tLT);
|
||||
break;
|
||||
case IToken.tLT: scopes.addValue( IToken.tLT ); break;
|
||||
case IToken.tLBRACKET: scopes.addValue( IToken.tLBRACKET ); break;
|
||||
case IToken.tLPAREN: scopes.addValue( IToken.tLPAREN ); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
BraceCounter.returnCounter(scopes);
|
||||
}
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
protected static class BraceCounter
|
||||
{
|
||||
private static final int POOLSIZE = 8;
|
||||
private static final BraceCounter [] pool;
|
||||
private static final boolean [] free;
|
||||
private static int newObjectCount = POOLSIZE;
|
||||
|
||||
static
|
||||
{
|
||||
pool = new BraceCounter[ POOLSIZE ];
|
||||
free = new boolean[8];
|
||||
for( int i = 0; i < POOLSIZE; ++i )
|
||||
{
|
||||
pool[i] = new BraceCounter(i);
|
||||
free[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized BraceCounter getCounter()
|
||||
{
|
||||
for( int i = 0; i < POOLSIZE; ++i )
|
||||
{
|
||||
if( free[i] )
|
||||
{
|
||||
free[i] = false;
|
||||
return pool[i];
|
||||
}
|
||||
}
|
||||
//if there is nothing free, allocate a new one and return it
|
||||
return new BraceCounter(newObjectCount++);
|
||||
}
|
||||
|
||||
public static synchronized void returnCounter( BraceCounter c )
|
||||
{
|
||||
if( c.getKey() > 0 && c.getKey() < POOLSIZE )
|
||||
{
|
||||
free[ c.getKey() ] = true;
|
||||
c.clear();
|
||||
}
|
||||
// otherwise, the object shall get garbage collected
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void clear() {
|
||||
currentIndex = 0;
|
||||
Arrays.fill( array, 0, array.length, -1 );
|
||||
}
|
||||
|
||||
private final int key;
|
||||
private int [] array = new int[ 8 ];
|
||||
int currentIndex = 0;
|
||||
|
||||
private void resizeArray()
|
||||
{
|
||||
int [] newArray = new int[ (array.length * 2) ];
|
||||
System.arraycopy( array, 0, newArray, 0, array.length );
|
||||
array = newArray;
|
||||
}
|
||||
|
||||
public void addValue( int value )
|
||||
{
|
||||
if( currentIndex == array.length )
|
||||
resizeArray();
|
||||
array[currentIndex] = value;
|
||||
++currentIndex;
|
||||
}
|
||||
|
||||
public int removeValue()
|
||||
{
|
||||
int result = array[--currentIndex];
|
||||
array[currentIndex] = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getLast()
|
||||
{
|
||||
if( isEmpty() ) return -1;
|
||||
return array[ currentIndex - 1 ];
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (currentIndex == 0 );
|
||||
}
|
||||
|
||||
public BraceCounter(int i) {
|
||||
key = i;
|
||||
clear();
|
||||
}
|
||||
/**
|
||||
* @return Returns the key.
|
||||
*/
|
||||
public int getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static char[] createCharArrayRepresentation(IToken first, IToken last) {
|
||||
return BasicTokenDuple.createCharArrayRepresentation(first, last);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue