From 8d0a12de55d693af34eda2ad208488c8175e52fc Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Fri, 14 Jan 2005 16:34:59 +0000 Subject: [PATCH] Label bindings in the new parser --- .../tests/parser2/CompleteParser2Tests.java | 35 +++++++- .../core/dom/parser/cpp/CPPFunctionScope.java | 18 +++- .../core/dom/parser/cpp/CPPLabel.java | 88 +++++++++++++++++++ .../core/dom/parser/cpp/CPPVisitor.java | 33 ++++++- 4 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLabel.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/CompleteParser2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/CompleteParser2Tests.java index 8c49b7970a6..67c71cfc526 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/CompleteParser2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/CompleteParser2Tests.java @@ -37,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; @@ -963,12 +964,42 @@ public class CompleteParser2Tests extends TestCase { public void testSimpleWhileStatement() throws Exception { - parse( "const bool T = true; void foo() { int x = 0; while( T ) { ++x; if( x == 100 ) break; } }"); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( "const bool T = true; void foo() { int x = 0; while( T ) { ++x; if( x == 100 ) break; } }"); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 6 ); + IVariable T = (IVariable) col.getName(0).resolveBinding(); + IVariable x = (IVariable) col.getName(2).resolveBinding(); + assertInstances( col, T, 2 ); + assertInstances( col, x, 3 ); } public void testSimpleSwitchStatement() throws Exception { - parse( "const int x = 5; const int y = 10; void foo() { switch( x ) { case 1: break; case 2: goto blah; case y: continue; default: break;} }"); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( "const int x = 5; const int y = 10; " + //$NON-NLS-1$ + "void foo() { " + //$NON-NLS-1$ + " while( true ) { " + //$NON-NLS-1$ + " switch( x ) { " + //$NON-NLS-1$ + " case 1: break; " + //$NON-NLS-1$ + " case 2: goto blah; " + //$NON-NLS-1$ + " case y: continue; " + //$NON-NLS-1$ + " default: break; " + //$NON-NLS-1$ + " } " + //$NON-NLS-1$ + " } " + //$NON-NLS-1$ + " blah : ; " + //$NON-NLS-1$ + "} "); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, col ); + + assertEquals( col.size(), 7 ); + IVariable x = (IVariable) col.getName(0).resolveBinding(); + IVariable y = (IVariable) col.getName(1).resolveBinding(); + ILabel blah = (ILabel) col.getName(4).resolveBinding(); + assertNotNull( blah ); + assertInstances( col, x, 2 ); + assertInstances( col, y, 2 ); + assertInstances( col, blah, 2 ); } public void testSimpleDoStatement() throws Exception diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java index f3c7924b607..95dd88bed4d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java @@ -19,15 +19,19 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; /** * @author aniefer */ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope { + private CharArrayObjectMap labels = CharArrayObjectMap.EMPTY_MAP; + /** * @param physicalNode */ @@ -35,20 +39,26 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope { super(physicalNode); } + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding) */ public void addBinding(IBinding binding) { - // TODO Auto-generated method stub - + //3.3.4 only labels have function scope + if( !( binding instanceof ILabel ) ) + return; + + if( labels == CharArrayObjectMap.EMPTY_MAP ) + labels = new CharArrayObjectMap( 2 ); + + labels.put( binding.getNameCharArray(), binding ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[]) */ public IBinding getBinding( IASTName name ) { - // TODO Auto-generated method stub - return null; + return (IBinding) labels.get( name.toCharArray() ); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLabel.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLabel.java new file mode 100644 index 00000000000..cd87e53715d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPLabel.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2004 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 Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Jan 14, 2005 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; +import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.core.dom.ast.ILabel; +import org.eclipse.cdt.core.dom.ast.IScope; + +/** + * @author aniefer + */ +public class CPPLabel implements ILabel { + private IASTStatement statement; + /** + * @param gotoStatement + */ + public CPPLabel( IASTStatement statement ) { + this.statement = statement; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.ILabel#getLabelStatement() + */ + public IASTLabelStatement getLabelStatement() { + if( statement instanceof IASTLabelStatement ) + return (IASTLabelStatement) statement; + + // TODO find label statement + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getName() + */ + public String getName() { + if( statement instanceof IASTLabelStatement ) + return ((IASTLabelStatement) statement).getName().toString(); + + return ((IASTGotoStatement) statement).getName().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray() + */ + public char[] getNameCharArray() { + if( statement instanceof IASTLabelStatement ) + return ((IASTLabelStatement) statement).getName().toCharArray(); + + return ((IASTGotoStatement) statement).getName().toCharArray(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getScope() + */ + public IScope getScope() { + return CPPVisitor.getContainingScope( statement ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() + */ + public IASTNode getPhysicalNode() { + return statement; + } + + /** + * @param labelStatement + */ + public void setLabelStatement( IASTLabelStatement labelStatement ) { + statement = labelStatement; + } + +} 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 c5a0256acf7..2d690aa829d 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 @@ -77,7 +77,6 @@ import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; -import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope; 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; @@ -107,6 +106,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; @@ -149,10 +149,39 @@ public class CPPVisitor { return createBinding( (IASTEnumerationSpecifier) parent ); } else if( parent instanceof IASTEnumerator ){ return createBinding( (IASTEnumerator) parent ); + } else if( parent instanceof IASTGotoStatement ){ + return createBinding( (IASTGotoStatement) parent ); + } else if( parent instanceof IASTLabelStatement ){ + return createBinding( (IASTLabelStatement) parent ); } + return null; } + private static IBinding createBinding( IASTGotoStatement gotoStatement ) { + ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope( gotoStatement ); + IASTName name = gotoStatement.getName(); + IBinding binding = functionScope.getBinding( name ); + if( binding == null ){ + binding = new CPPLabel( gotoStatement ); + functionScope.addBinding( binding ); + } + return binding; + } + + private static IBinding createBinding( IASTLabelStatement labelStatement ) { + ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope( labelStatement ); + IASTName name = labelStatement.getName(); + IBinding binding = functionScope.getBinding( name ); + if( binding == null ){ + binding = new CPPLabel( labelStatement ); + functionScope.addBinding( binding ); + } else { + ((CPPLabel)binding).setLabelStatement( labelStatement ); + } + return binding; + } + private static IBinding createBinding( IASTEnumerator enumerator ) { ICPPScope scope = (ICPPScope) getContainingScope( enumerator ); IBinding enumtor = scope.getBinding( enumerator.getName() ); @@ -395,7 +424,7 @@ public class CPPVisitor { if( statement instanceof IASTGotoStatement || statement instanceof IASTLabelStatement ){ //labels have function scope - while( scope != null && !(scope instanceof ICFunctionScope) ){ + while( scope != null && !(scope instanceof ICPPFunctionScope) ){ scope = scope.getParent(); } }