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];
|
IASTDeclarator d = p2m.getDeclarators()[0];
|
||||||
ICPPASTPointerToMember po = (ICPPASTPointerToMember) d
|
ICPPASTPointerToMember po = (ICPPASTPointerToMember) d
|
||||||
.getPointerOperators()[0];
|
.getPointerOperators()[0];
|
||||||
assertEquals(po.getName().toString(), "X::"); //$NON-NLS-1$
|
assertEquals("X::", po.getName().toString()); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct B {};
|
// struct B {};
|
||||||
|
@ -6150,9 +6150,11 @@ public class AST2CPPTests extends AST2BaseTest {
|
||||||
// struct B {
|
// struct B {
|
||||||
// operator ns::A(); // problems on operator ns and on A
|
// operator ns::A(); // problems on operator ns and on A
|
||||||
// };
|
// };
|
||||||
public void _testNamespaceQualifiedOperator_256840() throws Exception {
|
public void testNamespaceQualifiedOperator_256840() throws Exception {
|
||||||
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
|
final String code = getAboveComment();
|
||||||
|
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
|
||||||
bh.assertNonProblem("operator ns::A", 14);
|
bh.assertNonProblem("operator ns::A", 14);
|
||||||
|
parseAndCheckBindings(code, ParserLanguage.CPP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void f();
|
// void f();
|
||||||
|
|
|
@ -6,17 +6,14 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* Andrew Niefer (IBM Corporation) - initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
/*
|
|
||||||
* Created on Jan 17, 2005
|
|
||||||
*/
|
|
||||||
package org.eclipse.cdt.core.dom.ast;
|
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 {
|
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 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 interface ITokenDuple {
|
||||||
|
|
||||||
public abstract IToken getFirstToken();
|
public abstract IToken getFirstToken();
|
||||||
|
|
|
@ -415,17 +415,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
* @throws BacktrackException
|
* @throws BacktrackException
|
||||||
* request a backtrack
|
* request a backtrack
|
||||||
*/
|
*/
|
||||||
protected IToken identifier() throws EndOfFileException, BacktrackException {
|
protected abstract IASTName identifier() throws EndOfFileException, BacktrackException;
|
||||||
switch (LT(1)) {
|
|
||||||
case IToken.tIDENTIFIER:
|
|
||||||
case IToken.tCOMPLETION:
|
|
||||||
case IToken.tEOC:
|
|
||||||
return consume();
|
|
||||||
default:
|
|
||||||
throw backtrack;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the backtrackCount.
|
* @return Returns the backtrackCount.
|
||||||
|
@ -887,8 +877,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
protected abstract IASTExpression unaryExpression() throws BacktrackException, EndOfFileException;
|
protected abstract IASTExpression unaryExpression() throws BacktrackException, EndOfFileException;
|
||||||
protected abstract IASTExpression primaryExpression() 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 IASTTranslationUnit getTranslationUnit();
|
||||||
|
|
||||||
protected abstract void setupTranslationUnit() throws Exception;
|
protected abstract void setupTranslationUnit() throws Exception;
|
||||||
|
@ -1268,7 +1256,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
|
|
||||||
IASTName name;
|
IASTName name;
|
||||||
if (LT(1) == IToken.tIDENTIFIER) {
|
if (LT(1) == IToken.tIDENTIFIER) {
|
||||||
name= createName(identifier());
|
name= identifier();
|
||||||
} else {
|
} else {
|
||||||
name= nodeFactory.newName();
|
name= nodeFactory.newName();
|
||||||
}
|
}
|
||||||
|
@ -1308,7 +1296,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
if (needComma)
|
if (needComma)
|
||||||
throw backtrack;
|
throw backtrack;
|
||||||
|
|
||||||
final IASTName etorName= createName(identifier());
|
final IASTName etorName= identifier();
|
||||||
final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null);
|
final IASTEnumerator enumerator= nodeFactory.newEnumerator(etorName, null);
|
||||||
endOffset= calculateEndOffset(etorName);
|
endOffset= calculateEndOffset(etorName);
|
||||||
setRange(enumerator, problemOffset, endOffset);
|
setRange(enumerator, problemOffset, endOffset);
|
||||||
|
@ -1339,8 +1327,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
|
|
||||||
protected abstract IASTStatement statement() throws EndOfFileException, BacktrackException;
|
protected abstract IASTStatement statement() throws EndOfFileException, BacktrackException;
|
||||||
|
|
||||||
protected abstract IASTName createName(IToken token);
|
|
||||||
|
|
||||||
protected IASTExpression condition(boolean followedByParenthesis) throws BacktrackException, EndOfFileException {
|
protected IASTExpression condition(boolean followedByParenthesis) throws BacktrackException, EndOfFileException {
|
||||||
IToken mark= mark();
|
IToken mark= mark();
|
||||||
try {
|
try {
|
||||||
|
@ -1666,15 +1652,15 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
protected abstract IASTAmbiguousStatement createAmbiguousStatement();
|
protected abstract IASTAmbiguousStatement createAmbiguousStatement();
|
||||||
|
|
||||||
protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException {
|
protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException {
|
||||||
IToken labelName = consume(); // tIDENTIFIER
|
int offset= LA(1).getOffset();
|
||||||
consume(); // tCOLON
|
IASTName name = identifier(); // tIDENTIFIER
|
||||||
|
consume(IToken.tCOLON); // tCOLON
|
||||||
IASTStatement nestedStatement = statement();
|
IASTStatement nestedStatement = statement();
|
||||||
int lastOffset = calculateEndOffset( nestedStatement );
|
int lastOffset = calculateEndOffset( nestedStatement );
|
||||||
|
|
||||||
IASTName name = createName(labelName);
|
|
||||||
|
|
||||||
IASTLabelStatement label_statement = nodeFactory.newLabelStatement(name, nestedStatement);
|
IASTLabelStatement label_statement = nodeFactory.newLabelStatement(name, nestedStatement);
|
||||||
((ASTNode) label_statement).setOffsetAndLength(labelName.getOffset(), lastOffset - labelName.getOffset());
|
setRange(label_statement, offset, lastOffset);
|
||||||
return label_statement;
|
return label_statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1688,10 +1674,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
|
|
||||||
protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException {
|
protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException {
|
||||||
int startOffset = consume().getOffset(); // t_goto
|
int startOffset = consume().getOffset(); // t_goto
|
||||||
IToken identifier = consume(IToken.tIDENTIFIER);
|
IASTName goto_label_name = identifier();
|
||||||
int lastOffset = consume(IToken.tSEMI).getEndOffset();
|
int lastOffset = consume(IToken.tSEMI).getEndOffset();
|
||||||
|
|
||||||
IASTName goto_label_name = createName(identifier);
|
|
||||||
IASTGotoStatement goto_statement = nodeFactory.newGotoStatement(goto_label_name);
|
IASTGotoStatement goto_statement = nodeFactory.newGotoStatement(goto_label_name);
|
||||||
((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset - startOffset);
|
((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset - startOffset);
|
||||||
return goto_statement;
|
return goto_statement;
|
||||||
|
@ -1745,7 +1730,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
switch (LT(1)) {
|
switch (LT(1)) {
|
||||||
case IToken.tEOC:
|
case IToken.tEOC:
|
||||||
// We're trying to start one
|
// We're trying to start one
|
||||||
IASTName name = createName(LA(1));
|
IASTName name = identifier();
|
||||||
IASTIdExpression idExpr = nodeFactory.newIdExpression(name);
|
IASTIdExpression idExpr = nodeFactory.newIdExpression(name);
|
||||||
result = idExpr;
|
result = idExpr;
|
||||||
break;
|
break;
|
||||||
|
@ -1945,8 +1930,8 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
consume();
|
consume();
|
||||||
IASTExpression expr2= expression();
|
IASTExpression expr2= expression();
|
||||||
endOffset1= consumeOrEOC(IToken.tRPAREN).getEndOffset();
|
endOffset1= consumeOrEOC(IToken.tRPAREN).getEndOffset();
|
||||||
|
expr= nodeFactory.newTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid);
|
||||||
expr= buildTypeIdExpression(IASTTypeIdExpression.op_typeof, typeid, typeidOffset, calculateEndOffset(typeid));
|
setRange(expr, typeidOffset, calculateEndOffset(typeid));
|
||||||
|
|
||||||
IASTExpressionList expressionList = nodeFactory.newExpressionList();
|
IASTExpressionList expressionList = nodeFactory.newExpressionList();
|
||||||
((ASTNode) expressionList).setOffsetAndLength(typeidOffset, calculateEndOffset(expr2)-typeidOffset);
|
((ASTNode) expressionList).setOffsetAndLength(typeidOffset, calculateEndOffset(expr2)-typeidOffset);
|
||||||
|
@ -1989,7 +1974,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
|
|
||||||
IASTExpression result1= null;
|
IASTExpression result1= null;
|
||||||
if (typeid != null && endOffset1 >= endOffset2) {
|
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);
|
backup(typeidLA);
|
||||||
|
|
||||||
if (expr == null || endOffset1 > endOffset2)
|
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 {
|
public class ProblemBinding extends PlatformObject implements IProblemBinding, IType, IScope, IASTInternalScope {
|
||||||
protected final int id;
|
protected final int id;
|
||||||
protected final char[] arg;
|
protected char[] arg;
|
||||||
protected IASTNode node;
|
protected IASTNode node;
|
||||||
private String message = null;
|
private String message = null;
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
||||||
|
|
||||||
protected static final String[] errorMessages;
|
protected static final String[] errorMessages;
|
||||||
static {
|
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_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_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$
|
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_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_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_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)
|
/* (non-Javadoc)
|
||||||
|
@ -87,7 +88,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
||||||
if (message != null)
|
if (message != null)
|
||||||
return message;
|
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) {
|
if (arg != null) {
|
||||||
msg = MessageFormat.format(msg, new Object[] { new String(arg) });
|
msg = MessageFormat.format(msg, new Object[] { new String(arg) });
|
||||||
|
@ -224,7 +225,8 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
||||||
public int getLineNumber() {
|
public int getLineNumber() {
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
IASTFileLocation fileLoc = node.getFileLocation();
|
IASTFileLocation fileLoc = node.getFileLocation();
|
||||||
return fileLoc.getStartingLineNumber();
|
if (fileLoc != null)
|
||||||
|
return fileLoc.getStartingLineNumber();
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -245,4 +247,11 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
||||||
public IBinding getOwner() throws DOMException {
|
public IBinding getOwner() throws DOMException {
|
||||||
return null;
|
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)) {
|
switch (LT(1)) {
|
||||||
case IToken.tDOT:
|
case IToken.tDOT:
|
||||||
int offset = consume().getOffset();
|
int offset = consume().getOffset();
|
||||||
IToken id = identifier();
|
IASTName n = identifier();
|
||||||
IASTName n = createName(id);
|
|
||||||
ICASTFieldDesignator fieldDesignator = nodeFactory.newFieldDesignator(n);
|
ICASTFieldDesignator fieldDesignator = nodeFactory.newFieldDesignator(n);
|
||||||
setRange(fieldDesignator, offset, id.getEndOffset());
|
setRange(fieldDesignator, offset, calculateEndOffset(n));
|
||||||
if (designatorList == null)
|
if (designatorList == null)
|
||||||
designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
|
designatorList = new ArrayList<ICASTDesignator>(DEFAULT_DESIGNATOR_LIST_SIZE);
|
||||||
designatorList.add(fieldDesignator);
|
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
|
// 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) {
|
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();
|
int lastOffset = consume(IToken.tCOLON).getEndOffset();
|
||||||
IASTName n = createName(identifier);
|
|
||||||
ICASTFieldDesignator designator = nodeFactory.newFieldDesignator(n);
|
ICASTFieldDesignator designator = nodeFactory.newFieldDesignator(n);
|
||||||
((ASTNode) designator).setOffsetAndLength(identifier.getOffset(), lastOffset - identifier.getOffset());
|
setRange(designator, offset, lastOffset);
|
||||||
return Collections.singletonList(designator);
|
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 {
|
protected IASTExpression postfixExpression() throws EndOfFileException, BacktrackException {
|
||||||
IASTExpression firstExpression = null;
|
IASTExpression firstExpression = null;
|
||||||
switch (LT(1)) {
|
switch (LT(1)) {
|
||||||
|
@ -634,7 +624,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
case IToken.tDOT:
|
case IToken.tDOT:
|
||||||
// member access
|
// member access
|
||||||
IToken dot = consume();
|
IToken dot = consume();
|
||||||
IASTName name = createName(identifier());
|
IASTName name = identifier();
|
||||||
if (name == null)
|
if (name == null)
|
||||||
throwBacktrack(((ASTNode) firstExpression).getOffset(),
|
throwBacktrack(((ASTNode) firstExpression).getOffset(),
|
||||||
((ASTNode) firstExpression).getLength() + dot.getLength());
|
((ASTNode) firstExpression).getLength() + dot.getLength());
|
||||||
|
@ -648,7 +638,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
case IToken.tARROW:
|
case IToken.tARROW:
|
||||||
// member access
|
// member access
|
||||||
IToken arrow = consume();
|
IToken arrow = consume();
|
||||||
name = createName(identifier());
|
name = identifier();
|
||||||
if (name == null)
|
if (name == null)
|
||||||
throwBacktrack(((ASTNode) firstExpression).getOffset(),
|
throwBacktrack(((ASTNode) firstExpression).getOffset(),
|
||||||
((ASTNode) firstExpression).getLength() + arrow.getLength());
|
((ASTNode) firstExpression).getLength() + arrow.getLength());
|
||||||
|
@ -722,8 +712,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
case IToken.tEOC:
|
case IToken.tEOC:
|
||||||
int startingOffset = LA(1).getOffset();
|
int startingOffset = LA(1).getOffset();
|
||||||
IToken t1 = identifier();
|
IASTName name = identifier();
|
||||||
IASTName name = createName(t1);
|
|
||||||
IASTIdExpression idExpression = nodeFactory.newIdExpression(name);
|
IASTIdExpression idExpression = nodeFactory.newIdExpression(name);
|
||||||
((ASTNode) idExpression).setOffsetAndLength((ASTNode) name);
|
((ASTNode) idExpression).setOffsetAndLength((ASTNode) name);
|
||||||
return idExpression;
|
return idExpression;
|
||||||
|
@ -843,7 +832,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
int options= 0;
|
int options= 0;
|
||||||
int isLong= 0;
|
int isLong= 0;
|
||||||
|
|
||||||
IToken identifier= null;
|
IASTName identifier= null;
|
||||||
IASTDeclSpecifier result= null;
|
IASTDeclSpecifier result= null;
|
||||||
IASTExpression typeofExpression= null;
|
IASTExpression typeofExpression= null;
|
||||||
IASTProblem problem= null;
|
IASTProblem problem= null;
|
||||||
|
@ -1001,11 +990,11 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
|
|
||||||
IToken mark= mark();
|
IToken mark= mark();
|
||||||
try {
|
try {
|
||||||
final IToken idToken= identifier(); // for the specifier
|
final IASTName id= identifier(); // for the specifier
|
||||||
final IASTDeclarator altDtor = initDeclarator(declOption);
|
final IASTDeclarator altDtor = initDeclarator(declOption);
|
||||||
if (LA(1) == e.currToken) {
|
if (LA(1) == e.currToken) {
|
||||||
e.altDeclarator= altDtor;
|
e.altDeclarator= altDtor;
|
||||||
e.altSpec= buildNamedTypeSpecifier(idToken, storageClass, options, offset, idToken.getEndOffset());
|
e.altSpec= buildNamedTypeSpecifier(id, storageClass, options, offset, calculateEndOffset(id));
|
||||||
}
|
}
|
||||||
} catch (FoundAggregateInitializer lie) {
|
} catch (FoundAggregateInitializer lie) {
|
||||||
lie.fDeclSpec= e.declSpec;
|
lie.fDeclSpec= e.declSpec;
|
||||||
|
@ -1017,7 +1006,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
identifier = identifier();
|
identifier = identifier();
|
||||||
endOffset= identifier.getEndOffset();
|
endOffset= calculateEndOffset(identifier);
|
||||||
encounteredTypename= true;
|
encounteredTypename= true;
|
||||||
break;
|
break;
|
||||||
case IToken.t_struct:
|
case IToken.t_struct:
|
||||||
|
@ -1121,9 +1110,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
return buildSimpleDeclSpec(storageClass, simpleType, options, isLong, typeofExpression, offset, endOffset);
|
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) {
|
int options, int offset, int endOffset) {
|
||||||
IASTName name = createName(identifier);
|
|
||||||
ICASTTypedefNameSpecifier declSpec = nodeFactory.newTypedefNameSpecifier(name);
|
ICASTTypedefNameSpecifier declSpec = nodeFactory.newTypedefNameSpecifier(name);
|
||||||
configureDeclSpec(declSpec, storageClass, options);
|
configureDeclSpec(declSpec, storageClass, options);
|
||||||
declSpec.setRestrict((options & RESTRICT) != 0);
|
declSpec.setRestrict((options & RESTRICT) != 0);
|
||||||
|
@ -1218,9 +1206,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
|
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
|
||||||
|
|
||||||
// class name
|
// class name
|
||||||
IToken nameToken = null;
|
IASTName name = null;
|
||||||
if (LT(1) == IToken.tIDENTIFIER) {
|
if (LT(1) == IToken.tIDENTIFIER) {
|
||||||
nameToken = identifier();
|
name = identifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if __attribute__ or __declspec occurs after struct/union/class identifier and before the { or ;
|
// 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);
|
throwBacktrack(errorPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
IASTName name = (nameToken == null) ? nodeFactory.newName() : createName(nameToken);
|
if (name == null) {
|
||||||
|
name= nodeFactory.newName();
|
||||||
|
}
|
||||||
ICASTCompositeTypeSpecifier result = nodeFactory.newCompositeTypeSpecifier(classKind, name);
|
ICASTCompositeTypeSpecifier result = nodeFactory.newCompositeTypeSpecifier(classKind, name);
|
||||||
|
|
||||||
int endOffset= consume().getEndOffset();
|
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
|
// if __attribute__ or __declspec occurs after struct/union/class and before the identifier
|
||||||
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
|
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
|
||||||
|
|
||||||
IToken identifier = identifier();
|
IASTName name = identifier();
|
||||||
IASTName name = createName(identifier);
|
|
||||||
IASTElaboratedTypeSpecifier result = nodeFactory.newElaboratedTypeSpecifier(eck, name);
|
IASTElaboratedTypeSpecifier result = nodeFactory.newElaboratedTypeSpecifier(eck, name);
|
||||||
((ASTNode) result).setOffsetAndLength(t.getOffset(), calculateEndOffset(name) - t.getOffset());
|
((ASTNode) result).setOffsetAndLength(t.getOffset(), calculateEndOffset(name) - t.getOffset());
|
||||||
return result;
|
return result;
|
||||||
|
@ -1361,7 +1350,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
if (option.fRequireAbstract)
|
if (option.fRequireAbstract)
|
||||||
throwBacktrack(LA(1));
|
throwBacktrack(LA(1));
|
||||||
|
|
||||||
final IASTName declaratorName = createName(identifier());
|
final IASTName declaratorName = identifier();
|
||||||
endOffset= calculateEndOffset(declaratorName);
|
endOffset= calculateEndOffset(declaratorName);
|
||||||
return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, option);
|
return declarator(pointerOps, declaratorName, null, startingOffset, endOffset, option);
|
||||||
}
|
}
|
||||||
|
@ -1520,14 +1509,14 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
switch (LT(1)) {
|
switch (LT(1)) {
|
||||||
case IToken.tCOMMA:
|
case IToken.tCOMMA:
|
||||||
last = consume();
|
last = consume();
|
||||||
parmNames[i] = createName(identifier());
|
parmNames[i] = identifier();
|
||||||
seenParameter = true;
|
seenParameter = true;
|
||||||
break;
|
break;
|
||||||
case IToken.tIDENTIFIER:
|
case IToken.tIDENTIFIER:
|
||||||
if (seenParameter)
|
if (seenParameter)
|
||||||
throwBacktrack(startOffset, last.getEndOffset() - startOffset);
|
throwBacktrack(startOffset, last.getEndOffset() - startOffset);
|
||||||
|
|
||||||
parmNames[i] = createName(identifier());
|
parmNames[i] = identifier();
|
||||||
seenParameter = true;
|
seenParameter = true;
|
||||||
break;
|
break;
|
||||||
case IToken.tRPAREN:
|
case IToken.tRPAREN:
|
||||||
|
@ -1672,19 +1661,30 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IASTName createName(IToken t) {
|
protected IASTName identifier() throws EndOfFileException, BacktrackException {
|
||||||
IASTName n = nodeFactory.newName(t.getCharImage());
|
final IToken t= LA(1);
|
||||||
switch (t.getType()) {
|
IASTName n;
|
||||||
case IToken.tCOMPLETION:
|
switch (t.getType()) {
|
||||||
case IToken.tEOC:
|
case IToken.tIDENTIFIER:
|
||||||
createCompletionNode(t).addName(n);
|
consume();
|
||||||
|
n = nodeFactory.newName(t.getCharImage());
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
((ASTNode) n).setOffsetAndLength(t.getOffset(), t.getEndOffset() - t.getOffset());
|
case IToken.tCOMPLETION:
|
||||||
|
case IToken.tEOC:
|
||||||
|
consume();
|
||||||
|
n = nodeFactory.newName(t.getCharImage());
|
||||||
|
createCompletionNode(t).addName(n);
|
||||||
|
return n;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw backtrack;
|
||||||
|
}
|
||||||
|
|
||||||
|
setRange(n, t.getOffset(), t.getEndOffset());
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void consumeArrayModifiers(List<IASTArrayModifier> arrayMods) throws EndOfFileException, BacktrackException {
|
protected void consumeArrayModifiers(List<IASTArrayModifier> arrayMods) throws EndOfFileException, BacktrackException {
|
||||||
while (LT(1) == IToken.tLBRACKET) {
|
while (LT(1) == IToken.tLBRACKET) {
|
||||||
// eat the '['
|
// eat the '['
|
||||||
|
|
|
@ -112,25 +112,24 @@ public class CPPASTIfStatement extends ASTNode implements ICPPASTIfStatement, IA
|
||||||
}
|
}
|
||||||
|
|
||||||
public void replace(IASTNode child, IASTNode other) {
|
public void replace(IASTNode child, IASTNode other) {
|
||||||
if( thenClause == child )
|
if (thenClause == child) {
|
||||||
{
|
other.setParent(child.getParent());
|
||||||
other.setParent( child.getParent() );
|
other.setPropertyInParent(child.getPropertyInParent());
|
||||||
other.setPropertyInParent( child.getPropertyInParent() );
|
thenClause = (IASTStatement) other;
|
||||||
thenClause = (IASTStatement) other;
|
} else if (elseClause == child) {
|
||||||
}
|
other.setParent(child.getParent());
|
||||||
else if( elseClause == child )
|
other.setPropertyInParent(child.getPropertyInParent());
|
||||||
{
|
elseClause = (IASTStatement) other;
|
||||||
other.setParent( child.getParent() );
|
} else if (condDecl == child) {
|
||||||
other.setPropertyInParent( child.getPropertyInParent() );
|
other.setParent(child.getParent());
|
||||||
elseClause = (IASTStatement) other;
|
other.setPropertyInParent(child.getPropertyInParent());
|
||||||
}
|
condDecl = (IASTDeclaration) other;
|
||||||
if( condDecl == child )
|
} else if (condition == child) {
|
||||||
{
|
other.setParent(child.getParent());
|
||||||
other.setParent( child.getParent() );
|
other.setPropertyInParent(child.getPropertyInParent());
|
||||||
other.setPropertyInParent( child.getPropertyInParent() );
|
condition = (IASTExpression) other;
|
||||||
condDecl = (IASTDeclaration) other;
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public IASTDeclaration getConditionDeclaration() {
|
public IASTDeclaration getConditionDeclaration() {
|
||||||
return condDecl;
|
return condDecl;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
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.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
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);
|
fBinding= new RecursionResolvingBinding(this);
|
||||||
} else {
|
} else {
|
||||||
fIsFinal= false;
|
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)
|
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 numArgs = arguments.length;
|
||||||
final int numParams= parameters.length;
|
final int numParams= parameters.length;
|
||||||
if (numParams == 0 || numParams < numArgs)
|
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];
|
ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[numParams];
|
||||||
CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams);
|
CPPTemplateParameterMap map= new CPPTemplateParameterMap(numParams);
|
||||||
|
@ -176,7 +176,7 @@ public class CPPTemplates {
|
||||||
} else {
|
} else {
|
||||||
ICPPTemplateArgument defaultArg= param.getDefaultValue();
|
ICPPTemplateArgument defaultArg= param.getDefaultValue();
|
||||||
if (defaultArg == null) {
|
if (defaultArg == null) {
|
||||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
|
||||||
}
|
}
|
||||||
arg= instantiateArgument(defaultArg, map, null);
|
arg= instantiateArgument(defaultArg, map, null);
|
||||||
arg= SemanticUtil.getSimplifiedArgument(arg);
|
arg= SemanticUtil.getSimplifiedArgument(arg);
|
||||||
|
@ -186,7 +186,7 @@ public class CPPTemplates {
|
||||||
if (!hasDependentDefaultArg) {
|
if (!hasDependentDefaultArg) {
|
||||||
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
|
arg= CPPTemplates.matchTemplateParameterAndArgument(param, arg, map);
|
||||||
if (arg == null)
|
if (arg == null)
|
||||||
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_USING);
|
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
map.put(param, arg);
|
map.put(param, arg);
|
||||||
|
@ -212,19 +212,7 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBinding createProblem(ICPPClassTemplate template, int id) {
|
private static IBinding createProblem(ICPPClassTemplate template, int id) {
|
||||||
IASTNode node= null;
|
IASTNode node= new CPPASTName(template.getNameCharArray());
|
||||||
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());
|
|
||||||
}
|
|
||||||
return new ProblemBinding(node, id, 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.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.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.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}
|
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