Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] porting ASTUtil to DOM


This patch includes:
- the start of a new ASTUtil for DOM so that String types can be retrieved for comparison purposes
- DOM View updated to display ASTUtil#getNodeType(IASTNode) for a selected IASTNode (for easy testing purposes)

Notes:
- Andrew, please let me know if this suits your needs and whether it is well implemented or not.
- the functions in this patch for ASTUtil should not be used for something like the Outline View... that should use the String signatures instead of String types
- I am going to start porting the old ASTUtil for retrieving String signature's now that the types are done.

Devin Steffler
IBM's Eclipse CDT
Ottawa (Palladium), Ontario, Canada


Index: src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui.tests/src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java,v
retrieving revision 1.26
diff -u -r1.26 DOMAST.java
--- src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java	8 Mar 2005 19:32:09 -0000	1.26
+++ src/org/eclipse/cdt/ui/tests/DOMAST/DOMAST.java	9 Mar 2005 15:13:10 -0000
@@ -13,6 +13,7 @@
 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 @@
  */
 
 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 @@
    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 @@
       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));
@@ -770,6 +779,19 @@
       openReferencesAction = new DisplayReferencesAction();
       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);
Index: parser/org/eclipse/cdt/core/parser/Keywords.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/Keywords.java,v
retrieving revision 1.6
diff -u -r1.6 Keywords.java
--- parser/org/eclipse/cdt/core/parser/Keywords.java	28 Sep 2004 14:51:21 -0000	1.6
+++ parser/org/eclipse/cdt/core/parser/Keywords.java	9 Mar 2005 15:12:49 -0000
@@ -53,6 +53,7 @@
 	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$
Index: parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java,v
retrieving revision 1.14
diff -u -r1.14 CFunction.java
--- parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java	22 Feb 2005 21:45:44 -0000	1.14
+++ parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java	9 Mar 2005 15:12:49 -0000
@@ -176,7 +176,7 @@
         	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;
         }
Index: parser/org/eclipse/cdt/internal/core/dom/parser/c/CParameter.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CParameter.java,v
retrieving revision 1.5
diff -u -r1.5 CParameter.java
--- parser/org/eclipse/cdt/internal/core/dom/parser/c/CParameter.java	18 Feb 2005 21:36:59 -0000	1.5
+++ parser/org/eclipse/cdt/internal/core/dom/parser/c/CParameter.java	9 Mar 2005 15:12:49 -0000
@@ -13,6 +13,7 @@
 
 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 @@
     }
     
 	private IASTName [] declarations;
+	private IType type = null;
 	
 	public CParameter( IASTName parameterName ){
 		this.declarations = new IASTName [] { parameterName };
@@ -53,7 +55,10 @@
 	 */
 	
     public IType getType() {
-        return CVisitor.createType( declarations[0] );
+		if (declarations[0].getParent() instanceof IASTDeclarator)
+			type = CVisitor.createType( (IASTDeclarator)declarations[0].getParent() );
+		
+		return type;
 	}
 
 	/* (non-Javadoc)
Index: parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java,v
retrieving revision 1.7
diff -u -r1.7 CTypeDef.java
--- parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java	17 Feb 2005 19:38:10 -0000	1.7
+++ parser/org/eclipse/cdt/internal/core/dom/parser/c/CTypeDef.java	9 Mar 2005 15:12:49 -0000
@@ -38,8 +38,8 @@
 	 * @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;
 	}
 	
Index: parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java,v
retrieving revision 1.8
diff -u -r1.8 CVariable.java
--- parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java	18 Feb 2005 21:36:59 -0000	1.8
+++ parser/org/eclipse/cdt/internal/core/dom/parser/c/CVariable.java	9 Mar 2005 15:12:49 -0000
@@ -58,8 +58,8 @@
 	 * @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;
 	}
 	
Index: parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java,v
retrieving revision 1.48
diff -u -r1.48 CVisitor.java
--- parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java	8 Mar 2005 19:32:20 -0000	1.48
+++ parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java	9 Mar 2005 15:12:49 -0000
@@ -582,7 +582,7 @@
 				}
 		    } 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 @@
 			    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 @@
 			} 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 @@
 //	}
 	
 	/**
-	 * 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 @@
 			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 @@
 			
 		    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 {
Index: parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java,v
retrieving revision 1.62
diff -u -r1.62 CPPVisitor.java
--- parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java	8 Mar 2005 22:26:35 -0000	1.62
+++ parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java	9 Mar 2005 15:12:50 -0000
@@ -1707,6 +1707,8 @@
 			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 );
Index: parser/org/eclipse/cdt/core/dom/ast/ASTUtil.java
===================================================================
RCS file: parser/org/eclipse/cdt/core/dom/ast/ASTUtil.java
diff -N parser/org/eclipse/cdt/core/dom/ast/ASTUtil.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ parser/org/eclipse/cdt/core/dom/ast/ASTUtil.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,356 @@
+/*******************************************************************************
+ * 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.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<parms.length; i++) {
+			if (parms[i] != null) {
+				result.append(parms[i]);
+				if (i<parms.length-1) result.append(COMMA_SPACE);
+			}
+		}
+		result.append(Keywords.cpRPAREN);
+		return result.toString();
+	}
+
+	public static String[] getParameterTypeStringArray(IFunctionType type) {
+		IType[] parms = null;
+		try {
+			parms = type.getParameterTypes();
+		} catch (DOMException e) { return EMPTY_STRING_ARRAY; }
+		
+		String[] result = new String[parms.length];
+		
+		for(int i=0; i<parms.length; i++) {
+			if (parms[i] != null) {
+				result[i] = getType(parms[i]);
+			}
+		}
+		
+		return result;
+	}
+	
+	private static String getTypeString(IType type) {
+		StringBuffer result = new StringBuffer();
+		boolean needSpace = false;
+		
+		if (type instanceof IArrayType) {
+			result.append(Keywords.cpLBRACKET);
+			if (type instanceof ICArrayType) {
+				try {
+					if (((ICArrayType)type).isConst()) { result.append(Keywords.CONST); needSpace=true; }
+					if (((ICArrayType)type).isRestrict()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.RESTRICT); needSpace=true; }
+					if (((ICArrayType)type).isStatic()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.STATIC); needSpace=true; }
+					if (((ICArrayType)type).isVolatile()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.VOLATILE); }
+				} catch (DOMException e) {}
+			}
+			result.append(Keywords.cpRBRACKET);
+		} else if (type instanceof IBasicType) {
+			try {
+				if (((IBasicType)type).isSigned()) { result.append(Keywords.SIGNED); needSpace = true; }
+				else if (((IBasicType)type).isUnsigned()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.UNSIGNED); needSpace=true; }
+				if (((IBasicType)type).isLong()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.LONG); needSpace = true; }
+				else if (((IBasicType)type).isShort()) { if (needSpace) { result.append(SPACE); needSpace=false; }result.append(Keywords.SHORT); needSpace = true; }
+			} catch (DOMException e) {}
+			
+			if (type instanceof IGPPBasicType) {
+				try {
+					if (((IGPPBasicType)type).isLongLong()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.LONG_LONG); needSpace=true; }
+					
+					switch (((IGPPBasicType)type).getType()) {
+						case IGPPBasicType.t_Complex:
+							result.append(Keywords.c_COMPLEX);
+							break;
+						case IGPPBasicType.t_Imaginary:
+							result.append(Keywords.c_IMAGINARY);
+							break;
+						case IGPPBasicType.t_typeof:
+							result.append(GCCKeywords.TYPEOF);
+							break;						
+					}
+				} catch (DOMException e) {}
+			} else if (type instanceof ICPPBasicType) {
+				try {
+					switch (((ICPPBasicType)type).getType()) {
+						case ICPPBasicType.t_bool:
+							result.append(Keywords.BOOL);
+							break;
+						case ICPPBasicType.t_wchar_t:
+							result.append(Keywords.WCHAR_T);
+							break;
+					}
+				} catch (DOMException e) {}
+			} else if (type instanceof ICBasicType) {
+				try {
+					switch (((ICBasicType)type).getType()) {
+						case ICBasicType.t_Bool:
+							result.append(Keywords.c_BOOL);
+							break;
+						case ICBasicType.t_Complex:
+							result.append(Keywords.c_COMPLEX);
+							break;
+						case ICBasicType.t_Imaginary:
+							result.append(Keywords.c_IMAGINARY);
+							break;
+					}
+				} catch (DOMException e) {}
+			}
+			
+			try {
+				switch (((IBasicType)type).getType()) {
+					case IBasicType.t_char:
+						result.append(Keywords.CHAR);
+						break;
+					case IBasicType.t_double:
+						result.append(Keywords.DOUBLE);
+						break;
+					case IBasicType.t_float:
+						result.append(Keywords.FLOAT);
+						break;
+					case IBasicType.t_int:
+						result.append(Keywords.INT);
+						break;
+					case IBasicType.t_void:
+						result.append(Keywords.VOID);
+						break;
+				}
+			} catch (DOMException e) {}
+			
+		} else if (type instanceof ICompositeType) {
+			if (type instanceof ICPPClassType) {
+				try {
+					switch(((ICPPClassType)type).getKey()) {
+						case ICPPClassType.k_class:
+							result.append(Keywords.CLASS);
+							break;
+					}
+				} catch (DOMException e) {}
+			}
+			
+			try {
+				switch(((ICompositeType)type).getKey()) {
+					case ICompositeType.k_struct:
+						result.append(Keywords.STRUCT);
+						break;
+					case ICompositeType.k_union:
+						result.append(Keywords.UNION);
+						break;
+				}
+			} catch (DOMException e) {}
+			
+		} else if (type instanceof ICPPReferenceType) {
+			result.append(Keywords.cpAMPER);
+		} else if (type instanceof ICPPTemplateTypeParameter) {
+			try {
+				result.append(getType(((ICPPTemplateTypeParameter)type).getDefault()));
+			} catch (DOMException e) {}
+		} else if (type instanceof IEnumeration) {
+			result.append(Keywords.ENUM);
+		} else if (type instanceof IFunctionType) {
+			try {
+				String temp = getType(((IFunctionType)type).getReturnType());
+				if (temp != null && !temp.equals(EMPTY_STRING)) { result.append(temp); needSpace=true; }
+				if (needSpace) { result.append(SPACE); needSpace=false; }
+				temp = getParameterTypeString((IFunctionType)type);
+				if (temp != null && !temp.equals(EMPTY_STRING)) { result.append(temp); needSpace=false; }
+			} catch (DOMException e) {}
+		} else if (type instanceof IPointerType) {
+			result.append(Keywords.cpSTAR); needSpace=true;
+			
+			if (type instanceof IGPPPointerType) {
+				if (((IGPPPointerType)type).isRestrict()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.RESTRICT); needSpace=true; }
+			} else if (type instanceof ICPointerType) {
+				if (((ICPointerType)type).isRestrict()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.RESTRICT); needSpace=true; }
+			}
+			
+			try {
+				if (((IPointerType)type).isConst()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.CONST); needSpace=true; }
+				if (((IPointerType)type).isVolatile()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.VOLATILE); needSpace=true; }
+			} catch (DOMException e) {}
+			
+		} else if (type instanceof IQualifierType) {
+			
+			if (type instanceof ICQualifierType) {
+				if (((ICQualifierType)type).isRestrict()) { result.append(Keywords.RESTRICT); needSpace=true; }
+			} else if (type instanceof IGPPQualifierType) {
+				if (((IGPPQualifierType)type).isRestrict()) { result.append(Keywords.RESTRICT); needSpace=true; }
+			}
+			
+			try {
+				if (((IQualifierType)type).isConst()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.CONST); needSpace=true; }
+				if (((IQualifierType)type).isVolatile()) { if (needSpace) { result.append(SPACE); needSpace=false; } result.append(Keywords.VOLATILE); needSpace=true; }
+			} catch (DOMException e) {}
+			
+		}
+		
+		return result.toString();
+	}
+	
+	private static IType[] doubleTypes(IType[] types) {
+		IType[] newTypes = new IType[types.length * 2];
+		for(int j=0; j<types.length; j++) {
+			newTypes[j] = types[j];
+		}
+		return newTypes;
+	}
+	
+	public static String getType(IType type) {
+		StringBuffer result = new StringBuffer();
+		IType[] types = new IType[DEAULT_ITYPE_SIZE];
+		int i = 0;
+		
+		// push all of the types onto the stack
+		while(type != null && type instanceof ITypeContainer) {
+			if (types.length == i) { // add more room to the stack
+				types = doubleTypes(types);
+			}
+			types[i++] = type;
+			
+			try {
+				type = ((ITypeContainer)type).getType();
+			} catch (DOMException e) {}
+		}
+		
+		if (type != null && !(type instanceof ITypeContainer)) {
+			if (types.length == i) { // add more room to the stack
+				types = doubleTypes(types);
+			}
+			types[i++] = type;
+		}
+		
+		// pop all of the types off of the stack, and build the string representation while doing so
+		for(int j=types.length-1; j>=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);
+	}
+	
+}

Back to the top