From 9b1b4fc340b3ff13b910c5398ce91b6996baf04b Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Wed, 9 Mar 2005 19:50:55 +0000 Subject: [PATCH] patch from Devin Steffler --- .../org/eclipse/cdt/core/dom/ast/ASTUtil.java | 342 ++++++++++++++++++ .../org/eclipse/cdt/core/parser/Keywords.java | 1 + .../internal/core/dom/parser/c/CFunction.java | 2 +- .../core/dom/parser/c/CParameter.java | 7 +- .../internal/core/dom/parser/c/CTypeDef.java | 4 +- .../internal/core/dom/parser/c/CVariable.java | 4 +- .../internal/core/dom/parser/c/CVisitor.java | 21 +- .../core/dom/parser/cpp/CPPVisitor.java | 2 + .../eclipse/cdt/ui/tests/DOMAST/DOMAST.java | 22 ++ 9 files changed, 387 insertions(+), 18 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTUtil.java diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTUtil.java new file mode 100644 index 00000000000..e467919893e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTUtil.java @@ -0,0 +1,342 @@ +/******************************************************************************* + * Copyright (c) 2005 Rational Software Corp. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * Rational Software - initial implementation + ******************************************************************************/ + +package org.eclipse.cdt.core.dom.ast; + +import org.eclipse.cdt.core.dom.ast.c.ICArrayType; +import org.eclipse.cdt.core.dom.ast.c.ICBasicType; +import org.eclipse.cdt.core.dom.ast.c.ICPointerType; +import org.eclipse.cdt.core.dom.ast.c.ICQualifierType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPBasicType; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPPointerType; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPQualifierType; +import org.eclipse.cdt.core.parser.GCCKeywords; +import org.eclipse.cdt.core.parser.Keywords; +import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; +import org.eclipse.cdt.internal.core.dom.parser.c.CASTTypeId; +import org.eclipse.cdt.internal.core.dom.parser.c.CExternalFunction; +import org.eclipse.cdt.internal.core.dom.parser.c.CExternalVariable; +import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor; + +/** + * This is a utility class to help convert AST elements to Strings. + */ + +public class ASTUtil { + + private static final String COMMA_SPACE = ", "; //$NON-NLS-1$ + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + private static final String SPACE = " "; //$NON-NLS-1$ + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + private static final int DEAULT_ITYPE_SIZE = 2; + + public static String getParameterTypeString(IFunctionType type) { + StringBuffer result = new StringBuffer(); + String[] parms = getParameterTypeStringArray(type); + + result.append(Keywords.cpLPAREN); + for(int i=0; i=0; j--) { + if (types[j] != null) + result.append(getTypeString(types[j])); + + if (types[j] != null && j>0) result.append(SPACE); + } + + return result.toString(); + } + + public static String getDeclaratorType(IASTDeclarator decltor) { + // get the most nested declarator + while(decltor.getNestedDeclarator() != null) + decltor = decltor.getNestedDeclarator(); + + IBinding binding = decltor.getName().resolveBinding(); + IType type = null; + + try { + if (binding instanceof CExternalFunction) { + type = ((CExternalFunction)binding).getType(); + } else if (binding instanceof CExternalVariable) { + type = ((CExternalVariable)binding).getType(); + } else if (binding instanceof IEnumerator) { + type = ((IEnumerator)binding).getType(); + } else if (binding instanceof IFunction) { + type = ((IFunction)binding).getType(); + } else if (binding instanceof ITypedef) { + type = ((ITypedef)binding).getType(); + } else if (binding instanceof IVariable) { + type = ((IVariable)binding).getType(); + } + } catch (DOMException e) { + return EMPTY_STRING; + } + + if (type != null) { + return getType(type); + } + + return EMPTY_STRING; + } + + /** + * Return's the String representation of a node's type (if available). This is + * currently only being used for testing. + * + * TODO Remove this function when done testing if it is no longer needed + * + * @param node + * @return + */ + public static String getNodeType(IASTNode node) { + try { + if (node instanceof IASTDeclarator) + return getDeclaratorType((IASTDeclarator)node); + if (node instanceof IASTName && ((IASTName)node).resolveBinding() instanceof IVariable) + return getType(((IVariable)((IASTName)node).resolveBinding()).getType()); + if (node instanceof IASTName && ((IASTName)node).resolveBinding() instanceof IFunction) + return getType(((IFunction)((IASTName)node).resolveBinding()).getType()); + if (node instanceof IASTName && ((IASTName)node).resolveBinding() instanceof IType) + return getType((IType)((IASTName)node).resolveBinding()); + if (node instanceof IASTTypeId) + return getType((IASTTypeId)node); + } catch (DOMException e) { return EMPTY_STRING; } + + return EMPTY_STRING; + } + + public static String getType(IASTTypeId typeId) { + if (typeId instanceof CASTTypeId) + return createCType(typeId.getAbstractDeclarator()); + else if (typeId instanceof CPPASTTypeId) + return createCPPType(typeId.getAbstractDeclarator()); + + return EMPTY_STRING; + } + + private static String createCType(IASTDeclarator declarator) { + IType type = CVisitor.createType(declarator); + return getType(type); + } + + private static String createCPPType(IASTDeclarator declarator) { + IType type = CPPVisitor.createType(declarator); + return getType(type); + } + +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java index 36815a8c561..fff30b40502 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java @@ -53,6 +53,7 @@ public class Keywords { public static final String INLINE = "inline"; //$NON-NLS-1$ public static final String INT = "int"; //$NON-NLS-1$ public static final String LONG = "long"; //$NON-NLS-1$ + public static final String LONG_LONG = "long long"; //$NON-NLS-1$ public static final String MUTABLE = "mutable"; //$NON-NLS-1$ public static final String NAMESPACE = "namespace"; //$NON-NLS-1$ public static final String NEW = "new"; //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java index c3035a9ff56..52eb5b2808c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java @@ -176,7 +176,7 @@ public class CFunction implements IFunction, ICBinding { while (functionName.getNestedDeclarator() != null) functionName = functionName.getNestedDeclarator(); - IType tempType = CVisitor.createType( functionName.getName() ); + IType tempType = CVisitor.createType( functionName ); if (tempType instanceof IFunctionType) type = (IFunctionType)tempType; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CParameter.java index 7149a0cb9d6..8bf40368c25 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CParameter.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -43,6 +44,7 @@ public class CParameter implements IParameter { } private IASTName [] declarations; + private IType type = null; public CParameter( IASTName parameterName ){ this.declarations = new IASTName [] { parameterName }; @@ -53,7 +55,10 @@ public class CParameter implements IParameter { */ public IType getType() { - return CVisitor.createType( declarations[0] ); + if ( type == null && declarations[0].getParent() instanceof IASTDeclarator) + type = CVisitor.createType( (IASTDeclarator)declarations[0].getParent() ); + + return type; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java index f23515f6bda..9f8975eb23f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java @@ -38,8 +38,8 @@ public class CTypeDef implements ITypedef, ITypeContainer { * @see org.eclipse.cdt.core.dom.ast.ITypedef#getType() */ public IType getType() { - if (type == null) - type = CVisitor.createType(name); + if (type == null && name.getParent() instanceof IASTDeclarator) + type = CVisitor.createType((IASTDeclarator)name.getParent()); return type; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java index d7a02c4c7a0..f62a7a81e17 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java @@ -58,8 +58,8 @@ public class CVariable implements IVariable, ICBinding { * @see org.eclipse.cdt.core.dom.ast.IVariable#getType() */ public IType getType() { - if (type == null) - type = CVisitor.createType(declarations[0]); + if (type == null && declarations[0].getParent() instanceof IASTDeclarator) + type = CVisitor.createType((IASTDeclarator)declarations[0].getParent()); return type; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index edf3e437fc5..2a9075aabe7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -582,7 +582,7 @@ public class CVisitor { } } else if( expression instanceof IASTCastExpression ){ IASTTypeId id = ((IASTCastExpression)expression).getTypeId(); - return createType( id.getAbstractDeclarator().getName() ); + return createType( id.getAbstractDeclarator() ); } else if( expression instanceof IASTFieldReference ){ IBinding binding = ((IASTFieldReference)expression).getFieldName().resolveBinding(); if( binding instanceof IVariable ){ @@ -709,7 +709,7 @@ public class CVisitor { try{ IFunction function = (IFunction) binding; IFunctionType ftype = function.getType(); - IType type = createType( declarator.getName() ); + IType type = createType( declarator ); if( ftype.equals( type ) ){ if( parent instanceof IASTSimpleDeclaration ) ((CFunction)function).addDeclarator( (IASTFunctionDeclarator) declarator ); @@ -731,7 +731,7 @@ public class CVisitor { } else { IType t1 = null, t2 = null; if( binding != null && binding instanceof IVariable ){ - t1 = createType( declarator.getName() ); + t1 = createType( declarator ); try { t2 = ((IVariable)binding).getType(); } catch ( DOMException e1 ) { @@ -1666,16 +1666,13 @@ public class CVisitor { // } /** - * Create an IType for an IASTName. + * Create an IType for an IASTDeclarator. * - * @param name the IASTName whose IType will be created - * @return the IType of the IASTName parameter + * @param declarator the IASTDeclarator whose IType will be created + * @return the IType of the IASTDeclarator parameter */ - public static IType createType(IASTName name) { - if (!(name.getParent() instanceof IASTDeclarator)) return null; - + public static IType createType(IASTDeclarator declarator) { IASTDeclSpecifier declSpec = null; - IASTDeclarator declarator = (IASTDeclarator) name.getParent(); IASTNode node = declarator.getParent(); while( node instanceof IASTDeclarator ){ @@ -1802,7 +1799,7 @@ public class CVisitor { IType parmTypes[] = new IType[parms.length]; for( int i = 0; i < parms.length; i++ ){ - parmTypes[i] = createType( parms[i].getDeclarator().getName() ); + parmTypes[i] = createType( parms[i].getDeclarator() ); } return parmTypes; } else if ( decltor instanceof ICASTKnRFunctionDeclarator ) { @@ -1811,7 +1808,7 @@ public class CVisitor { for( int i = 0; i < parms.length; i++ ){ IASTDeclarator dtor = getKnRParameterDeclarator( (ICASTKnRFunctionDeclarator) decltor, parms[i] ); - parmTypes[i] = createType( dtor.getName() ); + parmTypes[i] = createType( dtor ); } return parmTypes; } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index a36b55ffc0e..a24548aff8f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -1707,6 +1707,8 @@ public class CPPVisitor { declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier(); else if( node instanceof IASTFunctionDefinition ) declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier(); + else if( node instanceof IASTTypeId ) + declSpec = ((IASTTypeId)node).getDeclSpecifier(); IType type = createType( declSpec ); type = createType( type, declarator ); diff --git a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java index ae7b071df77..4e6eccba8ed 100644 --- a/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java +++ b/core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.ui.tests.DOMAST; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.CDOM; import org.eclipse.cdt.core.dom.IASTServiceProvider; +import org.eclipse.cdt.core.dom.ast.ASTUtil; import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; @@ -104,6 +105,8 @@ import org.eclipse.ui.part.ViewPart; */ public class DOMAST extends ViewPart { + private static final String ASTUTIL_MENU_LABEL = "ASTUtil#"; //$NON-NLS-1$ + private static final String DISPLAY_TYPE = "getNodeType(IASTNode)"; //$NON-NLS-1$ private static final String NOT_VALID_COMPILATION_UNIT = "The active editor does not contain a valid compilation unit."; //$NON-NLS-1$ private static final String EXTENSION_CXX = "CXX"; //$NON-NLS-1$ private static final String EXTENSION_CPP = "CPP"; //$NON-NLS-1$ @@ -125,6 +128,7 @@ public class DOMAST extends ViewPart { private DrillDownAdapter drillDownAdapter; private Action openDeclarationsAction; private Action openReferencesAction; + private Action displayNodeTypeAction; private Action singleClickAction; private Action loadActiveEditorAction; private Action refreshAction; @@ -674,6 +678,11 @@ public class DOMAST extends ViewPart { manager.add(openDeclarationsAction); manager.add(openReferencesAction); manager.add(new Separator()); + // ASTUtil#... menu + MenuManager astMenu = new MenuManager(ASTUTIL_MENU_LABEL); + astMenu.add(displayNodeTypeAction); + manager.add(astMenu); + manager.add(new Separator()); drillDownAdapter.addNavigationActions(manager); // Other plug-ins can contribute there actions here manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); @@ -771,6 +780,19 @@ public class DOMAST extends ViewPart { openReferencesAction.setText(OPEN_REFERENCES); openReferencesAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages() .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); + + displayNodeTypeAction = new Action() { + public void run() { + ISelection selection = viewer.getSelection(); + if (selection instanceof IStructuredSelection && + ((IStructuredSelection)selection).getFirstElement() instanceof TreeObject && + ((TreeObject)((IStructuredSelection)selection).getFirstElement()).getNode() != null) { + showMessage("ASTUtil#getNodeType(IASTNode): \"" + ASTUtil.getNodeType(((TreeObject)((IStructuredSelection)selection).getFirstElement()).getNode()) + "\""); //$NON-NLS-1$ //$NON-NLS-2$ + } + } }; + displayNodeTypeAction.setText(DISPLAY_TYPE); + displayNodeTypeAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages() + .getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK)); singleClickAction = new ASTHighlighterAction(part); }