diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java index 9138fca461c..02d06b1c505 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.core.parser.tests.ast2; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; @@ -165,5 +166,18 @@ public class DOMLocationTests extends AST2BaseTest { IASTIdExpression expression = (IASTIdExpression) returnStatement.getReturnValue(); assertSoleLocation( expression, code.indexOf( "return ") + "return ".length(), 1 ); //$NON-NLS-1$ //$NON-NLS-2$ } + + + public void testElaboratedTypeSpecifier() throws ParserException { + String code = "/* blah */ struct A anA; /* blah */"; //$NON-NLS-1$ + for (ParserLanguage p = ParserLanguage.C; p != null; p = (p == ParserLanguage.C) ? ParserLanguage.CPP + : null) { + IASTTranslationUnit tu = parse(code, p); + IASTSimpleDeclaration declaration = (IASTSimpleDeclaration) tu.getDeclarations()[0]; + IASTElaboratedTypeSpecifier elabType = (IASTElaboratedTypeSpecifier) declaration.getDeclSpecifier(); + assertSoleLocation( elabType, code.indexOf( "struct"), "struct A".length() ); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index baceee78cf9..8a300904af8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -1672,6 +1672,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { name.setParent(result); name.setPropertyInParent(IASTElaboratedTypeSpecifier.TYPE_NAME); result.setKind(eck); + ((ASTNode)result).setOffsetAndLength( t.getOffset(), calculateEndOffset(name) - t.getOffset() ); return result; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java index b5b7a9a8460..7adc010952b 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java @@ -37,9 +37,14 @@ import org.eclipse.cdt.internal.core.dom.parser.c.GCCParserExtensionConfiguratio import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser; import org.eclipse.cdt.internal.core.dom.parser.c.ICParserExtensionConfiguration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ANSICPPParserExtensionConfiguration; -import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPParserExtensionConfiguration; import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser; +import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPParserExtensionConfiguration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPParserExtensionConfiguration; +import org.eclipse.cdt.internal.core.parser.InternalParserUtil; +import org.eclipse.cdt.internal.core.parser.scanner2.DOMScanner; +import org.eclipse.cdt.internal.core.parser.scanner2.GCCScannerExtensionConfiguration; +import org.eclipse.cdt.internal.core.parser.scanner2.GPPScannerExtensionConfiguration; +import org.eclipse.cdt.internal.core.parser.scanner2.IScannerExtensionConfiguration; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -50,7 +55,9 @@ import org.eclipse.core.runtime.CoreException; */ public class InternalASTServiceProvider implements IASTServiceProvider { - private static final String[] dialects = { "C99", //$NON-NLS-1$ + protected static final GCCScannerExtensionConfiguration C_GNU_SCANNER_EXTENSION = new GCCScannerExtensionConfiguration(); + protected static final GPPScannerExtensionConfiguration CPP_GNU_SCANNER_EXTENSION = new GPPScannerExtensionConfiguration(); + private static final String[] dialects = { "C99", //$NON-NLS-1$ "C++98", //$NON-NLS-1$ "GNUC", //$NON-NLS-1$ "GNUC++" }; //$NON-NLS-1$ @@ -110,9 +117,14 @@ public class InternalASTServiceProvider implements IASTServiceProvider { if( configuration == null ) { ParserLanguage l = getLanguage(fileToParse); - scanner = ParserFactory.createScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE, - l, NULL_REQUESTOR, - ParserUtil.getScannerLogService(), Collections.EMPTY_LIST); + IScannerExtensionConfiguration scannerExtensionConfiguration = null; + if( l == ParserLanguage.CPP ) + scannerExtensionConfiguration = CPP_GNU_SCANNER_EXTENSION; + else + scannerExtensionConfiguration = C_GNU_SCANNER_EXTENSION; + + scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE, + l, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, fileCreator ); //assume GCC if( l == ParserLanguage.C ) parser = new GNUCSourceParser( scanner, ParserMode.COMPLETE_PARSE, ParserUtil.getParserLogService(), new GCCParserExtensionConfiguration() ); 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 563e9b4ad28..9d9fe3c35ca 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 @@ -10,36 +10,8 @@ **********************************************************************/ package org.eclipse.cdt.ui.tests.DOMAST; -import java.io.IOException; -import java.util.Hashtable; -import java.util.Map; - -import org.eclipse.cdt.ui.tests.DOMAST.DOMASTPluginImages; -import org.eclipse.cdt.ui.tests.DOMAST.CPPPopulateASTViewAction; -import org.eclipse.cdt.ui.tests.DOMAST.CPopulateASTViewAction; -import org.eclipse.cdt.ui.tests.DOMAST.IPopulateDOMASTAction; -import org.eclipse.cdt.ui.tests.DOMAST.TreeObject; -import org.eclipse.cdt.ui.tests.DOMAST.TreeParent; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.ui.part.*; -import org.eclipse.jface.viewers.*; -import org.eclipse.swt.graphics.Image; -import org.eclipse.jface.action.*; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.ui.*; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.SWT; -import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.core.parser.NullLogService; -import org.eclipse.cdt.core.parser.NullSourceElementRequestor; -import org.eclipse.cdt.core.parser.ParserFactory; -import org.eclipse.cdt.core.parser.ParserLanguage; -import org.eclipse.cdt.core.parser.IScanner; -import org.eclipse.cdt.core.parser.ParserMode; -import org.eclipse.cdt.core.parser.ScannerInfo; -import org.eclipse.cdt.core.parser.ast.IASTEnumerator; import org.eclipse.cdt.core.dom.CDOM; +import org.eclipse.cdt.core.dom.IASTServiceProvider; import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; @@ -59,499 +31,522 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; -import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.ParserUtil; +import org.eclipse.cdt.core.parser.ast.IASTEnumerator; +import org.eclipse.cdt.core.resources.FileStorage; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor.CBaseVisitorAction; -import org.eclipse.cdt.internal.core.dom.parser.c.GCCParserExtensionConfiguration; -import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor.CPPBaseVisitorAction; -import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser; -import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPParserExtensionConfiguration; -import org.eclipse.cdt.internal.core.parser.InternalParserUtil; -import org.eclipse.cdt.internal.core.parser.scanner2.DOMScanner; -import org.eclipse.cdt.internal.core.parser.scanner2.GCCScannerExtensionConfiguration; -import org.eclipse.cdt.internal.core.parser.scanner2.GPPScannerExtensionConfiguration; -import org.eclipse.cdt.internal.core.parser.scanner2.IScannerExtensionConfiguration; import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.internal.ui.util.EditorUtility; import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; - +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IActionBars; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.DrillDownAdapter; +import org.eclipse.ui.part.ViewPart; /** - * This sample class demonstrates how to plug-in a new - * workbench view. The view shows data obtained from the - * model. The sample creates a dummy model on the fly, - * but a real implementation would connect to the model - * available either in this or another plug-in (e.g. the workspace). - * The view is connected to the model using a content provider. + * This sample class demonstrates how to plug-in a new workbench view. The view + * shows data obtained from the model. The sample creates a dummy model on the + * fly, but a real implementation would connect to the model available either in + * this or another plug-in (e.g. the workspace). The view is connected to the + * model using a content provider. *
- * The view uses a label provider to define how model - * objects should be presented in the view. Each - * view can present the same model objects using - * different labels and icons, if needed. Alternatively, - * a single label provider can be shared between views - * in order to ensure that objects of the same type are - * presented in the same way everywhere. + * The view uses a label provider to define how model objects should be + * presented in the view. Each view can present the same model objects using + * different labels and icons, if needed. Alternatively, a single label provider + * can be shared between views in order to ensure that objects of the same type + * are presented in the same way everywhere. *
*/
public class DOMAST extends ViewPart {
- private static final String REFRESH_DOM_AST = "Refresh DOM AST"; //$NON-NLS-1$
- private static final String VIEW_NAME = "DOM View"; //$NON-NLS-1$
- private static final String POPUPMENU = "#PopupMenu"; //$NON-NLS-1$
- private static final String OPEN_DECLARATIONS = "Open Declarations"; //$NON-NLS-1$
- private static final String OPEN_REFERENCES = "Open References"; //$NON-NLS-1$
- private TreeViewer viewer;
- private DrillDownAdapter drillDownAdapter;
- private Action action1;
- private Action action2;
- private Action singleClickAction;
- private Action refreshAction;
- private IFile file = null;
- private IEditorPart part = null;
- ParserLanguage lang = null;
-
- /*
- * The content provider class is responsible for
- * providing objects to the view. It can wrap
- * existing objects in adapters or simply return
- * objects as-is. These objects may be sensitive
- * to the current input of the view, or ignore
- * it and always show the same content
- * (like Task List, for example).
- */
-
- public class ViewContentProvider implements IStructuredContentProvider,
- ITreeContentProvider {
- private TreeParent invisibleRoot;
- private IFile aFile = null;
-
- /**
- *
- */
- public ViewContentProvider() {}
-
- /**
- *
- */
- public ViewContentProvider(IFile file) {
- this.aFile = file;
- }
+ private static final String REFRESH_DOM_AST = "Refresh DOM AST"; //$NON-NLS-1$
+ private static final String VIEW_NAME = "DOM View"; //$NON-NLS-1$
+ private static final String POPUPMENU = "#PopupMenu"; //$NON-NLS-1$
+ private static final String OPEN_DECLARATIONS = "Open Declarations"; //$NON-NLS-1$
+ private static final String OPEN_REFERENCES = "Open References"; //$NON-NLS-1$
+ TreeViewer viewer;
+ private DrillDownAdapter drillDownAdapter;
+ private Action action1;
+ private Action action2;
+ private Action singleClickAction;
+ private Action refreshAction;
+ private IFile file = null;
+ private IEditorPart part = null;
+ ParserLanguage lang = null;
- public void inputChanged(Viewer v, Object oldInput, Object newInput) {
- }
- public void dispose() {
- }
- public Object[] getElements(Object parent) {
- if (parent.equals(getViewSite())) {
- if (invisibleRoot==null) initialize();
- return getChildren(invisibleRoot);
- }
- return getChildren(parent);
- }
- public Object getParent(Object child) {
- if (child instanceof TreeObject) {
- return ((TreeObject)child).getParent();
- }
- return null;
- }
- public Object [] getChildren(Object parent) {
- if (parent instanceof TreeParent) {
- return ((TreeParent)parent).getChildren();
- }
- return new Object[0];
- }
- public boolean hasChildren(Object parent) {
- if (parent instanceof TreeParent)
- return ((TreeParent)parent).hasChildren();
- return false;
- }
-
- private void initialize() {
- if ( aFile == null || lang == null) return;
-
- IPopulateDOMASTAction action = null;
+ /*
+ * The content provider class is responsible for providing objects to the
+ * view. It can wrap existing objects in adapters or simply return objects
+ * as-is. These objects may be sensitive to the current input of the view, or
+ * ignore it and always show the same content (like Task List, for example).
+ */
- // TODO could use something like below to work with working copy... i.e. refresh button
-// IProject currentProject = aFile.getProject();
-// IWorkingCopy workingCopy = null;
-// if( editor.isDirty() ){
-// IWorkingCopy [] workingCopies = CUIPlugin.getSharedWorkingCopies();
-// if( workingCopies != null ){
-// for( int i = 0; i < workingCopies.length; i++ ){
-// if( workingCopies[i].getUnderlyingResource().equals( file ) ){
-// workingCopy = workingCopies[i];
-// break;
-// }
-// }
-// }
-// }
-
- CodeReader reader = null;
- try {
-// if( workingCopy == null )
- reader = new CodeReader(aFile.getLocation().toOSString(), aFile.getCharset() );
-// else
-// reader = new CodeReader(aFile.getLocation().toOSString(), workingCopy.getContents());
- } catch (IOException e) {
- e.printStackTrace();
- } catch ( CoreException e ) {
- e.printStackTrace();
- }
-
- // get IFile
-// IWorkspace workspace= ResourcesPlugin.getWorkspace();
-// workspace.setDescription(desc);
-// getWorkbench().getActiveWorkbenchWindow();
-
- // parse IFile
- ParserMode mode = ParserMode.COMPLETE_PARSE;
- Map definitions = new Hashtable();
-
- String [] includePaths = new String[0];
- IScannerInfo scannerInfo = new ScannerInfo( definitions, includePaths );
- IScannerExtensionConfiguration configuration = null;
- if( lang == ParserLanguage.CPP )
- configuration = new GPPScannerExtensionConfiguration();
- else
- configuration = new GCCScannerExtensionConfiguration();
-
- IScanner scanner = new DOMScanner( reader, scannerInfo, mode, lang, ParserFactory.createDefaultLogService(), configuration, CDOM.getInstance().getCodeReaderFactory( CDOM.PARSE_SAVED_RESOURCES) );
-
-// reader,
-// scannerInfo,
-// mode,
-// lang,
-// new NullSourceElementRequestor(),
-// null,
-// null );
- AbstractGNUSourceCodeParser parser = null;
- if ( lang == ParserLanguage.C ) {
- parser = new GNUCSourceParser(
- scanner,
- mode,
- new NullLogService(),
- new GCCParserExtensionConfiguration()
- );
-
- IASTTranslationUnit tu = parser.parse();
-
- action = new CPopulateASTViewAction(tu);
- CVisitor.visitTranslationUnit(tu, (CBaseVisitorAction)action);
- } else if ( lang == ParserLanguage.CPP ){
- parser = new GNUCPPSourceParser(
- scanner,
- mode,
- new NullLogService(),
- new GPPParserExtensionConfiguration()
- );
-
- IASTTranslationUnit tu = parser.parse();
-
- action = new CPPPopulateASTViewAction(tu);
- CPPVisitor.visitTranslationUnit(tu, (CPPBaseVisitorAction)action);
- }
-
- // display roots
- invisibleRoot = new TreeParent(null); //$NON-NLS-1$
- invisibleRoot.addChild(action.getTree());
-
- }
- }
-
- class ViewLabelProvider extends LabelProvider {
+ public class ViewContentProvider implements IStructuredContentProvider,
+ ITreeContentProvider {
+ private TreeParent invisibleRoot;
+ private IFile aFile = null;
- public String getText(Object obj) {
- return obj.toString();
- }
- public Image getImage(Object obj) {
- String imageKey = DOMASTPluginImages.IMG_DEFAULT;
-
- IASTNode node = null;
- if (obj instanceof TreeObject) {
- node = ((TreeObject)obj).getNode();
- }
-
- if ( node instanceof IASTArrayModifier ) {
- imageKey = DOMASTPluginImages.IMG_IASTArrayModifier;
- } else if ( node instanceof IASTDeclaration ) {
- imageKey = DOMASTPluginImages.IMG_IASTDeclaration;
- } else if ( node instanceof IASTDeclarator ) {
- imageKey = DOMASTPluginImages.IMG_IASTDeclarator;
- } else if ( node instanceof IASTDeclSpecifier ) {
- imageKey = DOMASTPluginImages.IMG_IASTDeclSpecifier;
- } else if ( node instanceof IASTEnumerator ) {
- imageKey = DOMASTPluginImages.IMG_IASTEnumerator;
- } else if ( node instanceof IASTExpression ) {
- imageKey = DOMASTPluginImages.IMG_IASTExpression;
- } else if ( node instanceof IASTInitializer ) {
- imageKey = DOMASTPluginImages.IMG_IASTInitializer;
- } else if ( node instanceof IASTName ) {
- imageKey = DOMASTPluginImages.IMG_IASTName;
- } else if ( node instanceof IASTParameterDeclaration ) {
- imageKey = DOMASTPluginImages.IMG_IASTParameterDeclaration;
- } else if ( node instanceof IASTPointerOperator ) {
- imageKey = DOMASTPluginImages.IMG_IASTPointerOperator;
- } else if ( node instanceof IASTPreprocessorStatement ) {
- imageKey = DOMASTPluginImages.IMG_IASTPreprocessorStatement;
- } else if ( node instanceof IASTProblem ) {
- imageKey = DOMASTPluginImages.IMG_IASTProblem;
- } else if ( node instanceof IASTSimpleDeclaration ) {
- imageKey = DOMASTPluginImages.IMG_IASTSimpleDeclaration;
- } else if ( node instanceof IASTStatement ) {
- imageKey = DOMASTPluginImages.IMG_IASTStatement;
- } else if ( node instanceof IASTTranslationUnit ) {
- imageKey = DOMASTPluginImages.IMG_IASTTranslationUnit;
- } else if ( node instanceof IASTTypeId ) {
- imageKey = DOMASTPluginImages.IMG_IASTTypeId;
- } else if ( node instanceof ICASTDesignator ) {
- imageKey = DOMASTPluginImages.IMG_ICASTDesignator;
- } else if ( node instanceof ICPPASTConstructorChainInitializer ) {
- imageKey = DOMASTPluginImages.IMG_ICPPASTConstructorChainInitializer;
- } else if ( node instanceof ICPPASTTemplateParameter ) {
- imageKey = DOMASTPluginImages.IMG_ICPPASTTemplateParameter;
- }
-
- return DOMASTPluginImages.get(imageKey);
- }
- }
- class NameSorter extends ViewerSorter {
- }
+ /**
+ *
+ */
+ public ViewContentProvider() {
+ }
- public DOMAST() {
-
- }
-
- /**
- * This is a callback that will allow us
- * to create the viewer and initialize it.
- */
- public void createPartControl(Composite parent) {
-
- if (part == null) {
- IWorkbenchPage[] pages = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPages();
-
- if (pages.length == 0) {
- // TODO determine how to hide view if no pages found and part==null
- }
-
- outerLoop: for(int i=0; i