Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] fix bug 51260, class cast exception during content assist

Core:
- fix class cast exception in the symbol table while traversing the 
inheritance of a class.
- filter the results of the prefix lookup for content assist so that those 
symbol without attached AST nodes aren removed so that the iterator does 
not later return a null.

Tests:
- added CompletionParseTests.testBug51260

-Andrew

Index: parser/ChangeLog-parser
===================================================================
retrieving revision 1.46
diff -u -r1.46 ChangeLog-parser
--- parser/ChangeLog-parser	5 Feb 2004 04:01:24 -0000	1.46
+++ parser/ChangeLog-parser	6 Feb 2004 19:17:50 -0000
@@ -1,3 +1,7 @@
+2004-02-06 Andrew Niefer
+	fixed bug51260 - Content Assist: Completion inside a class method silently fails with a ClassCastException
+	filter symbols without attached AST nodes out of the completion results so the iterator doesn't sometimes return null.
+
 2004-02-04 John Camelon
 	Added preliminary (crude) bSelectionParser IParser implementation for SELECTION_PARSE clients.  
 
Index: parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTNode.java
===================================================================
retrieving revision 1.7
diff -u -r1.7 ASTNode.java
--- parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTNode.java	16 Jan 2004 05:09:00 -0000	1.7
+++ parser/org/eclipse/cdt/internal/core/parser/ast/complete/ASTNode.java	6 Feb 2004 19:17:54 -0000
@@ -99,10 +99,14 @@
 		if(lookupResults == null)
 			return null;
 		
+		//filter out things that are not visible and things that don't have AST nodes attached
 		ListIterator iter = lookupResults.listIterator();
 		while( iter.hasNext() ){
 			ISymbol s = (ISymbol) iter.next();
-			if( !thisContainer.isVisible( s, qualification ) ){
+			if( !thisContainer.isVisible( s, qualification ) ||
+			    s.getASTExtension() == null ||
+				s.getASTExtension().getPrimaryDeclaration() == null )
+			{
 				iter.remove();
 			}
 		}
Index: parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java
===================================================================
retrieving revision 1.37
diff -u -r1.37 ParserSymbolTable.java
--- parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java	27 Jan 2004 02:36:23 -0000	1.37
+++ parser/org/eclipse/cdt/internal/core/parser/pst/ParserSymbolTable.java	6 Feb 2004 19:17:57 -0000
@@ -611,16 +611,26 @@
 					while( iter.hasNext() ){
 						key = iter.next();
 						if( symbol.containsKey( key ) ){
-							ISymbol sym = (ISymbol) symbol.get( key );
-							if( !checkAmbiguity( sym, temp.get( key ) ) ){
-								if( data.mode == LookupMode.PREFIX ){
-									if( data.ambiguities == null ){
-										data.ambiguities = new HashSet();
-									}
-									data.ambiguities.add( sym.getName() );
+							Object obj = symbol.get( key );
+							Iterator objIter = ( obj instanceof List ) ? ((List)obj).iterator() : null;
+							ISymbol sym = (ISymbol) (( objIter != null && objIter.hasNext() ) ? objIter.next() : obj);
+							while( sym != null ){
+								if( !checkAmbiguity( sym, temp.get( key ) ) ){
+									if( data.mode == LookupMode.PREFIX ){
+										if( data.ambiguities == null ){
+											data.ambiguities = new HashSet();
+										}
+										data.ambiguities.add( sym.getName() );
+									} else {
+										throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
+									} 								
+								}
+								
+								if( objIter != null && objIter.hasNext() ){
+									sym = (ISymbol) objIter.next();
 								} else {
-									throw new ParserSymbolTableException( ParserSymbolTableException.r_Ambiguous );
-								} 								
+									sym = null;
+								}
 							}
 						} else {
 							symbol.put( key, temp.get( key ) );
Index: ChangeLog
===================================================================
retrieving revision 1.178
diff -u -r1.178 ChangeLog
--- ChangeLog	5 Feb 2004 03:57:49 -0000	1.178
+++ ChangeLog	6 Feb 2004 19:20:11 -0000
@@ -1,3 +1,6 @@
+2004-02-06 Andrew Niefer
+	Added CompletionParseTest.testBug51260
+
 2004-02-04 John Camelon
 	Added preliminary SelectionParseTests to test SELECTION_PARSE clients. 
 	Added SelectionParseTests to ParserTestSuite.  
Index: parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java
===================================================================
retrieving revision 1.1
diff -u -r1.1 CompletionParseTest.java
--- parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java	28 Jan 2004 04:00:26 -0000	1.1
+++ parser/org/eclipse/cdt/core/parser/tests/CompletionParseTest.java	6 Feb 2004 19:20:12 -0000
@@ -601,4 +601,42 @@
 		IASTField field = (IASTField) result.getNodes().next();
 		assertEquals( field.getName(), "aPrivate" );
 	}
+	
+	public void testBug51260() throws Exception{
+		StringWriter writer = new StringWriter();
+		writer.write( " class A { public: void a(); }; " );
+		writer.write( " class B : public virtual A { public: void b(); };" );
+		writer.write( " class C : public virtual A { public: void c(); };" );
+		writer.write( " class D : public B, C { public: void d(); };" );
+		
+		writer.write( " void A::a(){} ");
+		writer.write( " void B::b(){} ");
+		writer.write( " void C::c(){} ");
+		writer.write( " void D::d(){ SP }" );
+		
+		String code = writer.toString();
+		int index = code.indexOf( "SP" );
+		IASTCompletionNode node = parse( code, index );
+		
+		ILookupResult result = node.getCompletionScope().lookup( node.getCompletionPrefix(), 
+		                                                         new IASTNode.LookupKind[]{ IASTNode.LookupKind.THIS },
+																 node.getCompletionContext() );
+		
+		assertEquals( result.getResultsSize(), 4 );
+		
+		Iterator iter = result.getNodes();
+		IASTMethod d = (IASTMethod) iter.next();
+		IASTMethod b = (IASTMethod) iter.next();
+		IASTMethod a = (IASTMethod) iter.next();
+		IASTMethod c = (IASTMethod) iter.next();
+		
+		assertFalse( iter.hasNext() );
+		
+		assertEquals( a.getName(), "a" );
+		assertEquals( b.getName(), "b" );
+		assertEquals( c.getName(), "c" );
+		assertEquals( d.getName(), "d" );
+		
+	}
+	
 }

Back to the top