mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-25 09:55:29 +02:00
Patch for Devin Steffler.
This patch includes: - ICPPASTConversionName that represents C++ conversion member functions -> also keeps track of the IASTTypeId for the conversion member function - ICPPASTOperatorName that represents C++ overloaded operator member function - a couple tests
This commit is contained in:
parent
cb199fd44a
commit
26b0ae693a
13 changed files with 590 additions and 105 deletions
|
@ -28,8 +28,10 @@ import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
|
@ -49,6 +51,8 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
|||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
||||
|
@ -3194,5 +3198,75 @@ public class AST2CPPTests extends AST2BaseTest {
|
|||
IEnumerator one = (IEnumerator) col.getName(3).resolveBinding();
|
||||
assertSame( one.getType(), e );
|
||||
}
|
||||
|
||||
|
||||
public void testOperatorConversionNames() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("class Foo {\n"); //$NON-NLS-1$
|
||||
buffer.append("public:\n"); //$NON-NLS-1$
|
||||
buffer.append("operator int();\n"); //$NON-NLS-1$
|
||||
buffer.append("char& operator[](unsigned int);\n"); //$NON-NLS-1$
|
||||
buffer.append("};\n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept( col );
|
||||
|
||||
IASTName name1 = col.getName(1);
|
||||
IASTName name2 = col.getName(2);
|
||||
|
||||
assertNotNull(name1);
|
||||
assertNotNull(name2);
|
||||
|
||||
assertTrue(name1 instanceof ICPPASTConversionName);
|
||||
assertTrue(name2 instanceof ICPPASTOperatorName);
|
||||
|
||||
IASTTypeId typeId = ((ICPPASTConversionName)name1).getTypeId();
|
||||
assertNotNull(typeId);
|
||||
assertEquals( ((IASTSimpleDeclSpecifier)typeId.getDeclSpecifier()).getType(), IASTSimpleDeclSpecifier.t_int );
|
||||
|
||||
}
|
||||
|
||||
public void testBug36769B() throws Exception {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("class X { operator int(); }; \n"); //$NON-NLS-1$
|
||||
buffer.append("X::operator int() { } \n"); //$NON-NLS-1$
|
||||
buffer.append("template <class A,B> class X<A,C> { operator int(); }; \n"); //$NON-NLS-1$
|
||||
buffer.append("template <class A,B> X<A,C>::operator int() { } \n"); //$NON-NLS-1$
|
||||
|
||||
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); //$NON-NLS-1$
|
||||
CPPNameCollector col = new CPPNameCollector();
|
||||
tu.accept( col );
|
||||
|
||||
// 1,4,12,21 - conversion
|
||||
// 2, 16 .isConversion
|
||||
|
||||
assertEquals(col.size(), 22);
|
||||
|
||||
assertNotNull(col.getName(1));
|
||||
assertNotNull(col.getName(4));
|
||||
assertNotNull(col.getName(12));
|
||||
assertNotNull(col.getName(21));
|
||||
assertNotNull(col.getName(2));
|
||||
assertNotNull(col.getName(16));
|
||||
|
||||
// ensure the conversions are conversions
|
||||
assertTrue(col.getName(1) instanceof ICPPASTConversionName);
|
||||
assertTrue(col.getName(4) instanceof ICPPASTConversionName);
|
||||
assertTrue(col.getName(12) instanceof ICPPASTConversionName);
|
||||
assertTrue(col.getName(21) instanceof ICPPASTConversionName);
|
||||
assertNotNull(((ICPPASTConversionName)col.getName(1)).getTypeId());
|
||||
assertNotNull(((ICPPASTConversionName)col.getName(4)).getTypeId());
|
||||
assertNotNull(((ICPPASTConversionName)col.getName(12)).getTypeId());
|
||||
assertNotNull(((ICPPASTConversionName)col.getName(21)).getTypeId());
|
||||
|
||||
// ensure qualified name isConversionOrOperator
|
||||
assertTrue(col.getName(2) instanceof ICPPASTQualifiedName);
|
||||
assertTrue(col.getName(16) instanceof ICPPASTQualifiedName);
|
||||
assertTrue(((ICPPASTQualifiedName)col.getName(2)).isConversionOrOperator());
|
||||
assertTrue(((ICPPASTQualifiedName)col.getName(16)).isConversionOrOperator());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2005 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
|
||||
/**
|
||||
* This interface represents a C++ conversion member function.
|
||||
*
|
||||
* @author dsteffle
|
||||
*/
|
||||
public interface ICPPASTConversionName extends IASTName {
|
||||
public static final ASTNodeProperty TYPE_ID=new ASTNodeProperty(
|
||||
"IASTArrayDeclarator.TYPE_ID - IASTTypeId for ICPPASTConversionName"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Returns the IASTTypeId for the ICPPASTConversionName.
|
||||
*
|
||||
* i.e. getTypeId() on operator int(); would return the IASTTypeId for "int"
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IASTTypeId getTypeId();
|
||||
|
||||
/**
|
||||
* Sets the IASTTypeId for the ICPPASTConversionName.
|
||||
*
|
||||
* @param typeId
|
||||
*/
|
||||
public void setTypeId(IASTTypeId typeId);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2005 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
|
||||
/**
|
||||
* This interface represents a C++ overloaded operator member function.
|
||||
*
|
||||
* @author dsteffle
|
||||
*/
|
||||
public interface ICPPASTOperatorName extends IASTName {
|
||||
|
||||
}
|
|
@ -56,4 +56,12 @@ public interface ICPPASTQualifiedName extends IASTName, IASTNameOwner {
|
|||
* boolean
|
||||
*/
|
||||
public void setFullyQualified(boolean value);
|
||||
|
||||
/**
|
||||
* This is used to check if the ICPPASTQualifiedName's last segment is
|
||||
* an ICPPASTConversionName or an ICPPASTOperatorName.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isConversionOrOperator();
|
||||
}
|
||||
|
|
|
@ -69,8 +69,4 @@ public interface ITokenDuple {
|
|||
|
||||
public void freeReferences( );
|
||||
public void acceptElement( ISourceElementRequestor requestor );
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean isConversion();
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2005 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
|
||||
/**
|
||||
* The implemented ICPPASTConversionName.
|
||||
*
|
||||
* @author dsteffle
|
||||
*/
|
||||
public class CPPASTConversionName extends CPPASTName implements ICPPASTConversionName {
|
||||
private IASTTypeId typeId=null;
|
||||
|
||||
public CPPASTConversionName() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CPPASTConversionName(char[] name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public IASTTypeId getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
|
||||
public void setTypeId(IASTTypeId typeId) {
|
||||
this.typeId=typeId;
|
||||
}
|
||||
|
||||
public boolean accept(ASTVisitor action) {
|
||||
boolean why = super.accept(action);
|
||||
if( why && typeId != null )
|
||||
return typeId.accept( action );
|
||||
return why;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2005 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
**********************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
|
||||
/**
|
||||
* The imlemented ICPPASTOperatorName.
|
||||
*
|
||||
* @author dsteffle
|
||||
*/
|
||||
public class CPPASTOperatorName extends CPPASTName implements ICPPASTOperatorName {
|
||||
public CPPASTOperatorName() {
|
||||
super();
|
||||
}
|
||||
|
||||
public CPPASTOperatorName(char[] name) {
|
||||
super(name);
|
||||
}
|
||||
}
|
|
@ -15,7 +15,10 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
|
@ -259,4 +262,22 @@ public class CPPASTQualifiedName extends CPPASTNode implements
|
|||
names[names.length - 1].setBinding( binding );
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName#isConversionOrOperator()
|
||||
*/
|
||||
public boolean isConversionOrOperator() {
|
||||
IASTName[] nonNullNames = getNames(); // ensure no null names
|
||||
|
||||
int len=nonNullNames.length;
|
||||
if (nonNullNames[len-1] instanceof ICPPASTConversionName || nonNullNames[len-1] instanceof ICPPASTOperatorName) return true;
|
||||
|
||||
// check templateId's name
|
||||
if (nonNullNames[len-1] instanceof ICPPASTTemplateId) {
|
||||
IASTName tempName = ((ICPPASTTemplateId)nonNullNames[len-1]).getTemplateName();
|
||||
if (tempName instanceof ICPPASTConversionName || tempName instanceof ICPPASTOperatorName) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -22,8 +22,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
|||
* @author jcamelon
|
||||
*/
|
||||
public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId {
|
||||
private static final char[] EMPTY_CHAR_ARRAY = { };
|
||||
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||
// private static final char[] EMPTY_CHAR_ARRAY = { };
|
||||
// private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||
private IASTName templateName;
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -81,6 +81,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
|
@ -130,12 +131,12 @@ import org.eclipse.cdt.core.parser.IToken;
|
|||
import org.eclipse.cdt.core.parser.ITokenDuple;
|
||||
import org.eclipse.cdt.core.parser.ParseError;
|
||||
import org.eclipse.cdt.core.parser.ParserMode;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.BacktrackException;
|
||||
import org.eclipse.cdt.internal.core.parser.SimpleDeclarationStrategy;
|
||||
import org.eclipse.cdt.internal.core.parser.TemplateParameterManager;
|
||||
import org.eclipse.cdt.internal.core.parser.token.OperatorTokenDuple;
|
||||
import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
|
||||
|
||||
/**
|
||||
|
@ -148,6 +149,7 @@ import org.eclipse.cdt.internal.core.parser.token.TokenFactory;
|
|||
*/
|
||||
public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
||||
|
||||
private static final String COMPL = "~"; //$NON-NLS-1$
|
||||
private static final String CONST_CAST = "const_cast"; //$NON-NLS-1$
|
||||
private static final String REINTERPRET_CAST = "reinterpret_cast"; //$NON-NLS-1$
|
||||
private static final String STATIC_CAST = "static_cast"; //$NON-NLS-1$
|
||||
|
@ -422,12 +424,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return last;
|
||||
}
|
||||
|
||||
protected ITokenDuple operatorId(IToken originalToken,
|
||||
protected IASTName operatorId(IToken originalToken,
|
||||
TemplateParameterManager templateArgs) throws BacktrackException,
|
||||
EndOfFileException {
|
||||
// we know this is an operator
|
||||
IToken operatorToken = consume(IToken.t_operator);
|
||||
IToken toSend = null;
|
||||
IASTTypeId typeId = null;
|
||||
if (LA(1).isOperator() || LT(1) == IToken.tLPAREN
|
||||
|| LT(1) == IToken.tLBRACKET) {
|
||||
if ((LT(1) == IToken.t_new || LT(1) == IToken.t_delete)
|
||||
|
@ -452,7 +455,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
} else {
|
||||
// must be a conversion function
|
||||
IToken t = LA(1);
|
||||
typeId(true, false);
|
||||
typeId = typeId(true, false);
|
||||
if (t != LA(1)) {
|
||||
while (t.getNext() != LA(1)) {
|
||||
t = t.getNext();
|
||||
|
@ -474,12 +477,18 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
hasTemplateId = true;
|
||||
}
|
||||
|
||||
ITokenDuple duple = TokenFactory
|
||||
ITokenDuple duple = TokenFactory
|
||||
.createTokenDuple(originalToken == null ? operatorToken
|
||||
: originalToken, toSend, (hasTemplateId ? templateArgs
|
||||
.getTemplateArgumentsList() : null));
|
||||
|
||||
return duple;
|
||||
OperatorTokenDuple operator= new OperatorTokenDuple(duple);
|
||||
if (typeId!=null) { // if it's a conversion operator
|
||||
operator.setConversionOperator(true);
|
||||
operator.setTypeId(typeId);
|
||||
}
|
||||
|
||||
return createName(operator);
|
||||
} finally {
|
||||
if (grabbedNewInstance)
|
||||
TemplateParameterManager.returnInstance(templateArgs);
|
||||
|
@ -1528,7 +1537,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
isTemplate = true;
|
||||
}
|
||||
|
||||
IASTName name = createName(idExpression());
|
||||
IASTName name = idExpression();
|
||||
|
||||
ICPPASTFieldReference fieldReference = createFieldReference();
|
||||
((ASTNode) fieldReference).setOffsetAndLength(
|
||||
|
@ -1556,7 +1565,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
isTemplate = true;
|
||||
}
|
||||
|
||||
name = createName(idExpression());
|
||||
name = idExpression();
|
||||
|
||||
fieldReference = createFieldReference();
|
||||
((ASTNode) fieldReference).setOffsetAndLength(
|
||||
|
@ -1728,11 +1737,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
case IToken.t_operator:
|
||||
case IToken.tCOMPL:
|
||||
{
|
||||
ITokenDuple duple = idExpression();
|
||||
IASTName name = createName(duple);
|
||||
IASTName name = idExpression();
|
||||
IASTIdExpression idExpression = createIdExpression();
|
||||
((ASTNode) idExpression).setOffsetAndLength(duple.getStartOffset(),
|
||||
duple.getEndOffset() - duple.getStartOffset());
|
||||
((ASTNode) idExpression).setOffsetAndLength(((ASTNode)name).getOffset(),
|
||||
((ASTNode)name).getOffset() + ((ASTNode)name).getLength() - ((ASTNode)name).getOffset());
|
||||
idExpression.setName(name);
|
||||
name.setParent(idExpression);
|
||||
name.setPropertyInParent(IASTIdExpression.ID_NAME);
|
||||
|
@ -1772,11 +1780,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return new CPPASTIdExpression();
|
||||
}
|
||||
|
||||
protected ITokenDuple idExpression() throws EndOfFileException,
|
||||
protected IASTName idExpression() throws EndOfFileException,
|
||||
BacktrackException {
|
||||
ITokenDuple duple = null;
|
||||
IASTName name = null;
|
||||
try {
|
||||
duple = name();
|
||||
name = createName(name());
|
||||
} catch (BacktrackException bt) {
|
||||
IToken mark = mark();
|
||||
if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
|
||||
|
@ -1791,16 +1799,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
}
|
||||
|
||||
if (LT(1) == IToken.t_operator)
|
||||
duple = operatorId(start, null);
|
||||
name = operatorId(start, null);
|
||||
else {
|
||||
backup(mark);
|
||||
throwBacktrack(start.getOffset(), end.getEndOffset()
|
||||
- start.getOffset());
|
||||
}
|
||||
} else if (LT(1) == IToken.t_operator)
|
||||
duple = operatorId(null, null);
|
||||
name = operatorId(null, null);
|
||||
}
|
||||
return duple;
|
||||
return name;
|
||||
|
||||
}
|
||||
|
||||
|
@ -2543,6 +2551,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
else
|
||||
// templateID
|
||||
subName = createTemplateID(segments[i]);
|
||||
|
||||
if (i==segments.length-1 &&
|
||||
duple instanceof OperatorTokenDuple) { // make sure the last segment is an OperatorName/ConversionName
|
||||
subName = createOperatorName((OperatorTokenDuple)duple, subName);
|
||||
}
|
||||
|
||||
subName.setParent(result);
|
||||
subName.setPropertyInParent(ICPPASTQualifiedName.SEGMENT_NAME);
|
||||
((ASTNode) subName).setOffsetAndLength(segments[i].getStartOffset(),
|
||||
|
@ -2598,8 +2612,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if( duple.getTemplateIdArgLists() != null )
|
||||
return createTemplateID( duple );
|
||||
|
||||
// We're a single token
|
||||
CPPASTName name = new CPPASTName(duple.toCharArray());
|
||||
// We're a single name
|
||||
IASTName name = new CPPASTName(duple.toCharArray());
|
||||
if (duple instanceof OperatorTokenDuple) {
|
||||
name = createOperatorName((OperatorTokenDuple)duple, name);
|
||||
}
|
||||
|
||||
IToken token = duple.getFirstToken();
|
||||
switch (token.getType()) {
|
||||
case IToken.tCOMPLETION:
|
||||
|
@ -2608,10 +2626,32 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
break;
|
||||
}
|
||||
|
||||
name.setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset()
|
||||
- duple.getStartOffset());
|
||||
((ASTNode)name).setOffsetAndLength(duple.getStartOffset(), duple.getEndOffset()
|
||||
- duple.getStartOffset());
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
protected IASTName createOperatorName(OperatorTokenDuple duple, IASTName name) {
|
||||
IASTName aName=null;
|
||||
|
||||
if (duple.isConversionOperator()) {
|
||||
aName = new CPPASTConversionName(name.toCharArray());
|
||||
IASTTypeId typeId = duple.getTypeId();
|
||||
typeId.setParent(aName);
|
||||
typeId.setPropertyInParent(ICPPASTConversionName.TYPE_ID);
|
||||
((CPPASTConversionName)aName).setTypeId(typeId);
|
||||
} else {
|
||||
aName = new CPPASTOperatorName(name.toCharArray());
|
||||
}
|
||||
|
||||
if (name instanceof ICPPASTTemplateId) {
|
||||
((ICPPASTTemplateId)name).setTemplateName(aName);
|
||||
return name;
|
||||
}
|
||||
|
||||
return aName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
|
@ -2923,7 +2963,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
* @throws EndOfFileException
|
||||
* we could encounter EOF while looking ahead
|
||||
*/
|
||||
protected boolean lookAheadForConstructorOrConversion(Flags flags)
|
||||
protected boolean lookAheadForConstructorOrOperator(Flags flags)
|
||||
throws EndOfFileException {
|
||||
if (flags.isForParameterDeclaration())
|
||||
return false;
|
||||
|
@ -2931,9 +2971,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return true;
|
||||
|
||||
IToken mark = mark();
|
||||
ITokenDuple duple = null;
|
||||
IASTName name = null;
|
||||
try {
|
||||
duple = consumeTemplatedOperatorName();
|
||||
name = consumeTemplatedOperatorName();
|
||||
} catch (BacktrackException e) {
|
||||
backup(mark);
|
||||
return false;
|
||||
|
@ -2942,50 +2982,48 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (duple == null) {
|
||||
if (name == null) {
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
|
||||
ITokenDuple leadingSegments = duple.getLeadingSegments();
|
||||
if (leadingSegments == null) {
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
ITokenDuple lastSegment = duple.getLastSegment();
|
||||
char[] className = lastSegment.extractNameFromTemplateId();
|
||||
if (className == null || CharArrayUtils.equals(className, EMPTY_STRING)) {
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
|
||||
ITokenDuple secondlastSegment = leadingSegments.getLastSegment();
|
||||
if (secondlastSegment == null) {
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
char[] otherName = secondlastSegment.extractNameFromTemplateId();
|
||||
if (otherName == null || CharArrayUtils.equals(otherName, EMPTY_STRING)) {
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lastSegment.isConversion()) {
|
||||
backup(mark);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CharArrayUtils.equals(className, otherName)) {
|
||||
backup(mark);
|
||||
return true;
|
||||
}
|
||||
char[] destructorName = CharArrayUtils.concat(
|
||||
"~".toCharArray(), otherName); //$NON-NLS-1$
|
||||
if (CharArrayUtils.equals(destructorName, className)) {
|
||||
backup(mark);
|
||||
return true;
|
||||
}
|
||||
|
||||
// constructor/conversion must be an ICPPASTQualifiedName (i.e. can't be defined for the global scope)
|
||||
if (name instanceof ICPPASTQualifiedName) {
|
||||
IASTName[] segments = ((ICPPASTQualifiedName)name).getNames();
|
||||
|
||||
int len = segments.length;
|
||||
if (len >= 2) {
|
||||
if (segments[0].toString().length() == 0) {
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (((ICPPASTQualifiedName)name).isConversionOrOperator()) { // conversion or operator
|
||||
backup(mark);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (segments[len-1].toString().equals(segments[len-2].toString())) { // constructor
|
||||
backup(mark);
|
||||
return true;
|
||||
}
|
||||
|
||||
StringBuffer destructorName = new StringBuffer();
|
||||
destructorName.append(COMPL);
|
||||
destructorName.append(segments[len-2]);
|
||||
if (segments[len-1].toString().equals(destructorName.toString())) { // destructor
|
||||
backup(mark);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
|
||||
backup(mark);
|
||||
return false;
|
||||
}
|
||||
|
@ -3185,7 +3223,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if (parm && flags.haveEncounteredTypename())
|
||||
break declSpecifiers;
|
||||
|
||||
if (lookAheadForConstructorOrConversion(flags))
|
||||
if (lookAheadForConstructorOrOperator(flags))
|
||||
break declSpecifiers;
|
||||
|
||||
if (lookAheadForDeclarator(flags))
|
||||
|
@ -3600,10 +3638,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
declaratorName = createName();
|
||||
} else {
|
||||
try {
|
||||
ITokenDuple d = consumeTemplatedOperatorName();
|
||||
declaratorName = createName(d);
|
||||
declaratorName = consumeTemplatedOperatorName();
|
||||
finalOffset = calculateEndOffset(declaratorName);
|
||||
if (d.isConversion())
|
||||
if (declaratorName instanceof ICPPASTQualifiedName && ((ICPPASTQualifiedName)declaratorName).isConversionOrOperator())
|
||||
isFunction = true;
|
||||
} catch (BacktrackException bt) {
|
||||
declaratorName = createName();
|
||||
|
@ -3899,7 +3936,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return new CPPASTDeclarator();
|
||||
}
|
||||
|
||||
protected ITokenDuple consumeTemplatedOperatorName()
|
||||
protected IASTName consumeTemplatedOperatorName()
|
||||
throws EndOfFileException, BacktrackException {
|
||||
TemplateParameterManager argumentList = TemplateParameterManager
|
||||
.getInstance();
|
||||
|
@ -3908,13 +3945,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
return operatorId(null, null);
|
||||
|
||||
try {
|
||||
return name();
|
||||
return createName(name());
|
||||
} catch (BacktrackException bt) {
|
||||
}
|
||||
IToken start = null;
|
||||
|
||||
boolean hasTemplateId = false;
|
||||
|
||||
IToken mark = mark();
|
||||
if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
|
||||
start = consume();
|
||||
|
@ -3922,28 +3957,22 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
if (start.getType() == IToken.tIDENTIFIER) {
|
||||
end = consumeTemplateArguments(end, argumentList);
|
||||
if (end != null && end.getType() == IToken.tGT)
|
||||
hasTemplateId = true;
|
||||
}
|
||||
|
||||
while (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {
|
||||
end = consume();
|
||||
if (end.getType() == IToken.tIDENTIFIER) {
|
||||
end = consumeTemplateArguments(end, argumentList);
|
||||
if (end.getType() == IToken.tGT)
|
||||
hasTemplateId = true;
|
||||
}
|
||||
}
|
||||
if (LT(1) == IToken.t_operator)
|
||||
end = operatorId(start, (hasTemplateId ? argumentList : null))
|
||||
.getLastToken();
|
||||
else {
|
||||
int endOffset = (end != null) ? end.getEndOffset() : 0;
|
||||
backup(mark);
|
||||
throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
|
||||
|
||||
if (LT(1) == IToken.t_operator) {
|
||||
return operatorId(start, argumentList );
|
||||
}
|
||||
return TokenFactory.createTokenDuple(start, end, argumentList
|
||||
.getTemplateArgumentsList());
|
||||
|
||||
int endOffset = (end != null) ? end.getEndOffset() : 0;
|
||||
backup(mark);
|
||||
throwBacktrack(mark.getOffset(), endOffset - mark.getOffset());
|
||||
}
|
||||
int endOffset = (mark != null) ? mark.getEndOffset() : 0;
|
||||
backup(mark);
|
||||
|
@ -4533,15 +4562,23 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
* @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createName(org.eclipse.cdt.core.parser.IToken)
|
||||
*/
|
||||
protected IASTName createName(IToken token) {
|
||||
CPPASTName n = new CPPASTName(token.getCharImage());
|
||||
IASTName n = null;
|
||||
|
||||
if (token instanceof OperatorTokenDuple) {
|
||||
n = createOperatorName((OperatorTokenDuple)token, n);
|
||||
} else {
|
||||
n = new CPPASTName(token.getCharImage());
|
||||
}
|
||||
|
||||
switch (token.getType()) {
|
||||
case IToken.tCOMPLETION:
|
||||
case IToken.tEOC:
|
||||
createCompletionNode(token).addName(n);
|
||||
break;
|
||||
}
|
||||
n.setOffsetAndLength(token.getOffset(), token.getLength());
|
||||
return n;
|
||||
((ASTNode)n).setOffsetAndLength(token.getOffset(), token.getLength());
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -598,15 +598,4 @@ public class BasicTokenDuple implements ITokenDuple {
|
|||
public char[] getFilename() {
|
||||
return firstToken.getFilename();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#isConversion()
|
||||
*/
|
||||
public boolean isConversion() {
|
||||
int index = findLastTokenType( IToken.t_operator );
|
||||
if( index == -1 ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2005 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Common Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/cpl-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.IASTTypeId;
|
||||
import org.eclipse.cdt.core.parser.ISourceElementRequestor;
|
||||
import org.eclipse.cdt.core.parser.IToken;
|
||||
import org.eclipse.cdt.core.parser.ITokenDuple;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Simple constructor. token is wrapped by this class.
|
||||
* @param token
|
||||
*/
|
||||
public OperatorTokenDuple(ITokenDuple token) {
|
||||
this.token=token;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// below are ITokenDuple functions
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getFirstToken()
|
||||
*/
|
||||
public IToken getFirstToken() {
|
||||
return token.getFirstToken();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getLastToken()
|
||||
*/
|
||||
public IToken getLastToken() {
|
||||
return token.getLastToken();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getTemplateIdArgLists()
|
||||
*/
|
||||
public List[] getTemplateIdArgLists() {
|
||||
return token.getTemplateIdArgLists();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getLastSegment()
|
||||
*/
|
||||
public ITokenDuple getLastSegment() {
|
||||
return token.getLastSegment();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getLeadingSegments()
|
||||
*/
|
||||
public ITokenDuple getLeadingSegments() {
|
||||
return token.getLeadingSegments();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSegmentCount()
|
||||
*/
|
||||
public int getSegmentCount() {
|
||||
return token.getSegmentCount();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#iterator()
|
||||
*/
|
||||
public Iterator iterator() {
|
||||
return token.iterator();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#toCharArray()
|
||||
*/
|
||||
public char[] toCharArray() {
|
||||
return token.toCharArray();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getFilename()
|
||||
*/
|
||||
public char[] getFilename() {
|
||||
return token.getFilename();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#isIdentifier()
|
||||
*/
|
||||
public boolean isIdentifier() {
|
||||
return token.isIdentifier();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#length()
|
||||
*/
|
||||
public int length() {
|
||||
return token.length();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSubrange(int, int)
|
||||
*/
|
||||
public ITokenDuple getSubrange(int startIndex, int endIndex) {
|
||||
return token.getSubrange(startIndex, endIndex);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getToken(int)
|
||||
*/
|
||||
public IToken getToken(int index) {
|
||||
return token.getToken(index);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getSegments()
|
||||
*/
|
||||
public ITokenDuple[] getSegments() {
|
||||
return token.getSegments();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#findLastTokenType(int)
|
||||
*/
|
||||
public int findLastTokenType(int type) {
|
||||
return token.findLastTokenType(type);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getStartOffset()
|
||||
*/
|
||||
public int getStartOffset() {
|
||||
return token.getStartOffset();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getEndOffset()
|
||||
*/
|
||||
public int getEndOffset() {
|
||||
return token.getEndOffset();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#getLineNumber()
|
||||
*/
|
||||
public int getLineNumber() {
|
||||
return token.getLineNumber();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#syntaxOfName()
|
||||
*/
|
||||
public boolean syntaxOfName() {
|
||||
return token.syntaxOfName();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#extractNameFromTemplateId()
|
||||
*/
|
||||
public char[] extractNameFromTemplateId() {
|
||||
return token.extractNameFromTemplateId();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#contains(org.eclipse.cdt.core.parser.ITokenDuple)
|
||||
*/
|
||||
public boolean contains(ITokenDuple duple) {
|
||||
return token.contains(duple);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#toQualifiedName()
|
||||
*/
|
||||
public String[] toQualifiedName() {
|
||||
return token.toQualifiedName();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#freeReferences()
|
||||
*/
|
||||
public void freeReferences() {
|
||||
token.freeReferences();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.parser.ITokenDuple#
|
||||
* acceptElement(org.eclipse.cdt.core.parser.ISourceElementRequestor)
|
||||
*/
|
||||
public void acceptElement(ISourceElementRequestor requestor) {
|
||||
token.acceptElement(requestor);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
return token.toString();
|
||||
}
|
||||
}
|
|
@ -309,6 +309,7 @@ public class DOMASTNodeLeaf implements IAdaptable {
|
|||
}
|
||||
|
||||
private static class ASTPropertySource implements IPropertySource {
|
||||
private static final IPropertyDescriptor[] BLANK_DESCRIPTORS = new IPropertyDescriptor[0];
|
||||
private static final String OPEN_PAREN = " ("; //$NON-NLS-1$
|
||||
private static final String CLOSE_PAREN = ")"; //$NON-NLS-1$
|
||||
private static final String L_BRACKET_STRING = "["; //$NON-NLS-1$
|
||||
|
@ -360,6 +361,7 @@ public class DOMASTNodeLeaf implements IAdaptable {
|
|||
|
||||
private IPropertyDescriptor[] getPropertyDescriptors(Object obj) {
|
||||
IPropertyDescriptor[] desc = new IPropertyDescriptor[DEFAULT_DESCRIPTOR_SIZE];
|
||||
if (obj==null) return BLANK_DESCRIPTORS;
|
||||
Class objClass = obj.getClass();
|
||||
Class[] interfaces = objClass.getInterfaces();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue