Community
Participate
Working Groups
20030930+JDT patches Attempting to format SearchEngine unit, I got out of memory errors, and following entries into the log: !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:18:57.646 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream without blocking. * <p>Here is an example on how to use <code>availableSize</code>.</p> * * The Loop to compute the number of bytes works as follows: * <pre> * while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * For further reference consult {@link org.eclipse.formatter}. * @param stream The file input stream to return the number of available bytes for. * @param size The current number of available bytes. * @return the number of bytes that can be read from this file input stream without blocking. * @exception IOException if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:18:57.677 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream * without blocking. * <p> * Here is an example on how to use <code>availableSize</code>. * </p> * * The Loop to compute the number of bytes works as follows: * * <pre> while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * * For further reference consult {@link org.eclipse.formatter}. * * @param stream * The file input stream to return the number of available bytes * for. * @param size * The current number of available bytes. * @return the number of bytes that can be read from this file input stream * without blocking. * @exception IOException * if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:19:22.318 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream without blocking. * <p>Here is an example on how to use <code>availableSize</code>.</p> * * The Loop to compute the number of bytes works as follows: * <pre> * while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * For further reference consult {@link org.eclipse.formatter}. * @param stream The file input stream to return the number of available bytes for. * @param size The current number of available bytes. * @return the number of bytes that can be read from this file input stream without blocking. * @exception IOException if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:19:22.349 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream * without blocking. * <p> * Here is an example on how to use <code>availableSize</code>. * </p> * * The Loop to compute the number of bytes works as follows: * * <pre> while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * * For further reference consult {@link org.eclipse.formatter}. * * @param stream * The file input stream to return the number of available bytes * for. * @param size * The current number of available bytes. * @return the number of bytes that can be read from this file input stream * without blocking. * @exception IOException * if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:19:22.974 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream without blocking. * <p>Here is an example on how to use <code>availableSize</code>.</p> * * The Loop to compute the number of bytes works as follows: * <pre> * while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * For further reference consult {@link org.eclipse.formatter}. * @param stream The file input stream to return the number of available bytes for. * @param size The current number of available bytes. * @return the number of bytes that can be read from this file input stream without blocking. * @exception IOException if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:19:22.990 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream * without blocking. * <p> * Here is an example on how to use <code>availableSize</code>. * </p> * * The Loop to compute the number of bytes works as follows: * * <pre> while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * * For further reference consult {@link org.eclipse.formatter}. * * @param stream * The file input stream to return the number of available bytes * for. * @param size * The current number of available bytes. * @return the number of bytes that can be read from this file input stream * without blocking. * @exception IOException * if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:19:24.599 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream without blocking. * <p>Here is an example on how to use <code>availableSize</code>.</p> * * The Loop to compute the number of bytes works as follows: * <pre> * while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * For further reference consult {@link org.eclipse.formatter}. * @param stream The file input stream to return the number of available bytes for. * @param size The current number of available bytes. * @return the number of bytes that can be read from this file input stream without blocking. * @exception IOException if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:19:24.646 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns * the * number * of * bytes * that * can * be * read * from * this * file * input * stream * without * blocking. * <p> * Here * is * an * example * on * how * to * use * <code>availableSize</code>. * </p> * * The * Loop * to * compute * the * number * of * bytes * works * as * follows: * * <pre> while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * * For * further * reference * consult * {@link org.eclipse.formatter}. * * @param * stream * The * file * input * stream * to * return * the * number * of * available * bytes * for. * @param * size * The * current * number * of * available * bytes. * @return * the * number * of * bytes * that * can * be * read * from * this * file * input * stream * without * blocking. * @exception * IOException * if * an * I/O * error * occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:19:25.177 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream without blocking. * <p>Here is an example on how to use <code>availableSize</code>.</p> * * The Loop to compute the number of bytes works as follows: * <pre> * while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * For further reference consult {@link org.eclipse.formatter}. * @param stream The file input stream to return the number of available bytes for. * @param size The current number of available bytes. * @return the number of bytes that can be read from this file input stream without blocking. * @exception IOException if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:19:25.193 !MESSAGE formatter returned null-edit. string: /*********************************************************************** ****** * Copyright (c) 2000, 2003 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 *****************************************************************************/ package org.eclipse.formatter.example /** * Example class showing the format of the new comment formatter * @version 1.0 */ class File { /** * Returns the number of bytes that can be read from this file input stream without blocking. * <p> * Here is an example on how to use <code>availableSize</code>. * </p> * * The Loop to compute the number of bytes works as follows: * * <pre> while ((size = availableSize(stream, size)) > 0) { System.out.println ("available"); } * </pre> * * For further reference consult {@link org.eclipse.formatter}. * * @param stream * The file input stream to return the number of available bytes for. * @param size * The current number of available bytes. * @return the number of bytes that can be read from this file input stream without blocking. * @exception IOException * if an I/O error occurs. */ public static int availableSize(FileInputStream stream, int size) { if (size < currentSize) { try { size=(long)stream.available(); } catch (IOException e) { } } else if (size == currentSize) { ++size; } else { --size; } return size; } } !ENTRY org.eclipse.ui 4 4 Oct 03, 2003 18:19:57.333 !MESSAGE Unhandled exception caught in event loop. Unhandled exception caught in event loop. Reason: !ENTRY org.eclipse.ui 4 0 Oct 03, 2003 18:19:57.349 !MESSAGE java.lang.OutOfMemoryError !STACK 0 java.lang.OutOfMemoryError java.lang.OutOfMemoryError java.lang.OutOfMemoryError
After I fixed the source for the formatter page, I get these errors: org.eclipse.jface.util.Assert$AssertionFailedException: Assertion failed: at java.lang.Throwable.<init>(Throwable.java) at java.lang.Throwable.<init>(Throwable.java) at org.eclipse.jface.util.Assert$AssertionFailedException.<init>(Assert.java:54) at org.eclipse.jface.util.Assert.isTrue(Assert.java:168) at org.eclipse.jface.util.Assert.isTrue(Assert.java) at org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java) at org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer.RangeDifferencer.findRanges(RangeDifferencer.java:291) at org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer.RangeDifferencer.findRanges(RangeDifferencer.java:276) at org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer.handleChange(DocumentLineDiffer.java:773) at org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer$1.run(DocumentLineDiffer.java:575) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:61) and: org.eclipse.jface.util.Assert$AssertionFailedException: Assertion failed: at java.lang.Throwable.<init>(Throwable.java) at java.lang.Throwable.<init>(Throwable.java) at org.eclipse.jface.util.Assert$AssertionFailedException.<init>(Assert.java:54) at org.eclipse.jface.util.Assert.isTrue(Assert.java:168) at org.eclipse.jface.util.Assert.isTrue(Assert.java) at org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer.RangeDifferencer.findDifferences(RangeDifferencer.java) at org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer.RangeDifferencer.findRanges(RangeDifferencer.java:291) at org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer.RangeDifferencer.findRanges(RangeDifferencer.java:276) at org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer.handleChange(DocumentLineDiffer.java:773) at org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer.documentChanged(DocumentLineDiffer.java:655) at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged2(AbstractDocument.java) at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged(AbstractDocument.java) at org.eclipse.jface.text.AbstractDocument.doFireDocumentChanged(AbstractDocument.java) at org.eclipse.jface.text.AbstractDocument.fireDocumentChanged(AbstractDocument.java) at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java) at org.eclipse.jdt.internal.ui.javaeditor.PartiallySynchronizedDocument.replace(PartiallySynchronizedDocument.java:61) at org.eclipse.jdt.internal.ui.text.comment.CommentRegion.applyText(CommentRegion.java) at org.eclipse.jdt.internal.ui.text.comment.CommentLine.applyLine(CommentLine.java:125) at org.eclipse.jdt.internal.ui.text.comment.CommentRegion.applyRegion(CommentRegion.java:167) at org.eclipse.jdt.internal.ui.text.comment.CommentRegion.format(CommentRegion.java:256) at org.eclipse.jdt.internal.ui.text.comment.CommentFormattingStrategy.format(CommentFormattingStrategy.java:131) at org.eclipse.jface.text.formatter.ContentFormatter.format(ContentFormatter.java:782) at org.eclipse.jface.text.formatter.ContentFormatter.formatPartitions(ContentFormatter.java:602) at org.eclipse.jface.text.formatter.ContentFormatter.format(ContentFormatter.java:491) at org.eclipse.jface.text.source.SourceViewer.doOperation(SourceViewer.java:664) at org.eclipse.jdt.internal.ui.javaeditor.JavaSourceViewer.doOperation(JavaSourceViewer.java:98) at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer.doOperation(CompilationUnitEditor.java:169) at org.eclipse.ui.texteditor.TextOperationAction$1.run(TextOperationAction.java:122) at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java) at org.eclipse.ui.texteditor.TextOperationAction.run(TextOperationAction.java:120) at org.eclipse.jface.action.Action.runWithEvent(Action.java:842) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:543) at org.eclipse.jface.action.ActionContributionItem.access$4(ActionContributionItem.java:496) at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:468) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2106) at org.eclipse.ui.internal.Workbench.run(Workbench.java:2089) at org.eclipse.core.internal.boot.InternalBootLoader.run(InternalBootLoader.java:858) at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:41) at java.lang.reflect.Method.invoke(Method.java:386) at org.eclipse.core.launcher.Main.basicRun(Main.java:298) at org.eclipse.core.launcher.Main.run(Main.java:764) at org.eclipse.core.launcher.Main.main(Main.java:598)
Formatted ouput is with line split = 120. I don't see what I could do to fix it. /******************************************************************************* * Copyright (c) 2000, 2003 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 *******************************************************************************/ package org.eclipse.jdt.core.search; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.AbstractSyntaxTreeVisitorAdapter; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; import org.eclipse.jdt.internal.compiler.ast.*; import org.eclipse.jdt.internal.compiler.ast.AnonymousLocalTypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.LocalTypeDeclaration; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.ClassScope; import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; import org.eclipse.jdt.internal.compiler.parser.Parser; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; import org.eclipse.jdt.internal.core.*; import org.eclipse.jdt.internal.core.search.*; import org.eclipse.jdt.internal.core.search.HierarchyScope; import org.eclipse.jdt.internal.core.search.IndexSearchAdapter; import org.eclipse.jdt.internal.core.search.IIndexSearchRequestor; import org.eclipse.jdt.internal.core.search.IInfoConstants; import org.eclipse.jdt.internal.core.search.JavaSearchScope; import org.eclipse.jdt.internal.core.search.JavaWorkspaceScope; import org.eclipse.jdt.internal.core.search.PatternSearchJob; import org.eclipse.jdt.internal.core.search.PathCollector; import org.eclipse.jdt.internal.core.search.Util; import org.eclipse.jdt.internal.core.search.indexing.*; import org.eclipse.jdt.internal.core.search.matching.*; import java.util.*; /** * A <code>SearchEngine</code> searches for java elements following a search pattern. * The search can be limited to a search scope. * <p> * Various search patterns can be created using the factory methods * <code>createSearchPattern(String, int, int, boolean)</code>, <code>createSearchPattern(IJavaElement, int)</code>, * <code>createOrSearchPattern(ISearchPattern, ISearchPattern)</code>. * </p> * <p>For example, one can search for references to a method in the hierarchy of a type, * or one can search for the declarations of types starting with "Abstract" in a project. * </p> * <p> * This class may be instantiated; it is not intended to be subclassed. * </p> * TODO: remove IWorkspace argument on the search methods before 3.0 */ public class SearchEngine { /* * A default parser to parse non-reconciled working copies */ private Parser parser; private CompilerOptions compilerOptions; /* * A list of working copies that take precedence over their original * compilation units. */ private ICompilationUnit[] workingCopies; /* * A working copy owner whose working copies will take precedent over * their original compilation units. */ private WorkingCopyOwner workingCopyOwner; /** * For tracing purpose. */ public static boolean VERBOSE = false; /** * Creates a new search engine. */ public SearchEngine() { // will use working copies of PRIMARY owner } /** * Creates a new search engine with a list of working copies that will take precedence over * their original compilation units in the subsequent search operations. * <p> * Note that passing an empty working copy will be as if the original compilation * unit had been deleted.</p> * <p> * Since 3.0 the given working copies take precedence over primary working copies (if any). * * @param workingCopies the working copies that take precedence over their original compilation units * @since 2.0 */ public SearchEngine(IWorkingCopy[] workingCopies) { int length = workingCopies.length; System.arraycopy(workingCopies, 0, this.workingCopies = new ICompilationUnit[length], 0, length); } /** * Creates a new search engine with the given working copy owner. * The working copies owned by this owner will take precedence over * the primary compilation units in the subsequent search operations. * * @param workingCopyOwner the owner of the working copies that take precedence over their original compilation units * @since 3.0 */ public SearchEngine(WorkingCopyOwner workingCopyOwner) { this.workingCopyOwner = workingCopyOwner; } /** * Returns a java search scope limited to the hierarchy of the given type. * The java elements resulting from a search with this scope will * be types in this hierarchy, or members of the types in this hierarchy. * * @param type the focus of the hierarchy scope * @return a new hierarchy scope * @exception JavaModelException if the hierarchy could not be computed on the given type */ public static IJavaSearchScope createHierarchyScope(IType type) throws JavaModelException { return createHierarchyScope(type, DefaultWorkingCopyOwner.PRIMARY); } /** * Returns a java search scope limited to the hierarchy of the given type. * When the hierarchy is computed, the types defined in the working copies owned * by the given owner take precedence over the original compilation units. * The java elements resulting from a search with this scope will * be types in this hierarchy, or members of the types in this hierarchy. * * @param type the focus of the hierarchy scope * @param the owner of working copies that take precedence over original compilation units * @return a new hierarchy scope * @exception JavaModelException if the hierarchy could not be computed on the given type * @since 3.0 */ public static IJavaSearchScope createHierarchyScope(IType type, WorkingCopyOwner owner) throws JavaModelException { return new HierarchyScope(type, owner); } /** * Returns a java search scope limited to the given resources. * The java elements resulting from a search with this scope will * have their underlying resource included in or equals to one of the given * resources. * <p> * Resources must not overlap, for example, one cannot include a folder and its children. * </p> * * @param resources the resources the scope is limited to * @return a new java search scope * @deprecated Use createJavaSearchScope(IJavaElement[]) instead */ public static IJavaSearchScope createJavaSearchScope(IResource[] resources) { int length = resources.length; IJavaElement[] elements = new IJavaElement[length]; for (int i = 0; i < length; i++) { elements[i] = JavaCore.create(resources[i]); } return createJavaSearchScope(elements); } /** * Returns a java search scope limited to the given java elements. * The java elements resulting from a search with this scope will * be children of the given elements. * <p> * If an element is an IJavaProject, then the project's source folders, * its jars (external and internal) and its referenced projects (with their source * folders and jars, recursively) will be included. * If an element is an IPackageFragmentRoot, then only the package fragments of * this package fragment root will be included. * If an element is an IPackageFragment, then only the compilation unit and class * files of this package fragment will be included. Subpackages will NOT be * included.</p> * <p> * In other words, this is equivalent to using SearchEngine.createJavaSearchScope(elements, true).</p> * * @param elements the java elements the scope is limited to * @return a new java search scope * @since 2.0 */ public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements) { return createJavaSearchScope(elements, true); } /** * Returns a java search scope limited to the given java elements. * The java elements resulting from a search with this scope will * be children of the given elements. * * If an element is an IJavaProject, then the project's source folders, * its jars (external and internal) and - if specified - its referenced projects * (with their source folders and jars, recursively) will be included. * If an element is an IPackageFragmentRoot, then only the package fragments of * this package fragment root will be included. * If an element is an IPackageFragment, then only the compilation unit and class * files of this package fragment will be included. Subpackages will NOT be * included. * * @param elements the java elements the scope is limited to * @param includeReferencedProjects a flag indicating if referenced projects must be * recursively included * @return a new java search scope * @since 2.0 */ public static IJavaSearchScope createJavaSearchScope(IJavaElement[] elements, boolean includeReferencedProjects) { JavaSearchScope scope = new JavaSearchScope(); HashSet visitedProjects = new HashSet(2); for (int i = 0, length = elements.length; i < length; i++) { IJavaElement element = elements[i]; if (element != null) { try { if (element instanceof IJavaProject) { scope.add((IJavaProject) element, includeReferencedProjects, visitedProjects); } else { scope.add(element); } } catch (JavaModelException e) { // ignore } } } return scope; } /** * Returns a search pattern that combines the given two patterns into a "or" pattern. * The search result will match either the left pattern or the right pattern. * * @param leftPattern the left pattern * @param rightPattern the right pattern * @return a "or" pattern */ public static ISearchPattern createOrSearchPattern(ISearchPattern leftPattern, ISearchPattern rightPattern) { return new OrPattern((SearchPattern) leftPattern, (SearchPattern) rightPattern); } /** * Returns a search pattern based on a given string pattern. The string patterns support '*' wild-cards. * The remaining parameters are used to narrow down the type of expected results. * * <br> * Examples: * <ul> * <li>search for case insensitive references to <code>Object</code>: * <code>createSearchPattern("Object", TYPE, REFERENCES, false);</code></li> * <li>search for case sensitive references to exact <code>Object()</code> constructor: * <code>createSearchPattern("java.lang.Object()", CONSTRUCTOR, REFERENCES, true);</code></li> * <li>search for implementers of <code>java.lang.Runnable</code>: * <code>createSearchPattern("java.lang.Runnable", TYPE, IMPLEMENTORS, true);</code></li> * </ul> * @param stringPattern the given pattern * @param searchFor determines the nature of the searched elements * <ul> * <li><code>IJavaSearchConstants.CLASS</code>: only look for classes</li> * <li><code>IJavaSearchConstants.INTERFACE</code>: only look for interfaces</li> * <li><code>IJavaSearchConstants.TYPE</code>: look for both classes and interfaces</li> * <li><code>IJavaSearchConstants.FIELD</code>: look for fields</li> * <li><code>IJavaSearchConstants.METHOD</code>: look for methods</li> * <li><code>IJavaSearchConstants.CONSTRUCTOR</code>: look for constructors</li> * <li><code>IJavaSearchConstants.PACKAGE</code>: look for packages</li> * </ul> * @param limitTo determines the nature of the expected matches * <ul> * <li><code>IJavaSearchConstants.DECLARATIONS</code>: will search declarations matching with the corresponding * element. In case the element is a method, declarations of matching methods in subtypes will also * be found, allowing to find declarations of abstract methods, etc.</li> * * <li><code>IJavaSearchConstants.REFERENCES</code>: will search references to the given element.</li> * * <li><code>IJavaSearchConstants.ALL_OCCURRENCES</code>: will search for either declarations or references as specified * above.</li> * * <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: for interface, will find all types which implements a given interface.</li> * </ul> * * @param isCaseSensitive indicates whether the search is case sensitive or not. * @return a search pattern on the given string pattern, or <code>null</code> if the string pattern is ill-formed. */ public static ISearchPattern createSearchPattern(String stringPattern, int searchFor, int limitTo, boolean isCaseSensitive) { int matchMode; if (stringPattern.indexOf('*') != -1 || stringPattern.indexOf('?') != -1) { matchMode = IJavaSearchConstants.PATTERN_MATCH; } else { matchMode = IJavaSearchConstants.EXACT_MATCH; } return SearchPattern.createPattern(stringPattern, searchFor, limitTo, matchMode, isCaseSensitive); } /** * Returns a search pattern based on a given Java element. * The pattern is used to trigger the appropriate search, and can be parameterized as follows: * * @param element the java element the search pattern is based on * @param limitTo determines the nature of the expected matches * <ul> * <li><code>IJavaSearchConstants.DECLARATIONS</code>: will search declarations matching with the corresponding * element. In case the element is a method, declarations of matching methods in subtypes will also * be found, allowing to find declarations of abstract methods, etc.</li> * * <li><code>IJavaSearchConstants.REFERENCES</code>: will search references to the given element.</li> * * <li><code>IJavaSearchConstants.ALL_OCCURRENCES</code>: will search for either declarations or references as specified * above.</li> * * <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: for interface, will find all types which implements a given interface.</li> * </ul> * @return a search pattern for a java element or <code>null</code> if the given element is ill-formed */ public static ISearchPattern createSearchPattern(IJavaElement element, int limitTo) { return SearchPattern.createPattern(element, limitTo); } /** * Returns a java search scope with the workspace as the only limit. * * @return a new workspace scope */ public static IJavaSearchScope createWorkspaceScope() { return new JavaWorkspaceScope(); } private Parser getParser() { if (this.parser == null) { this.compilerOptions = new CompilerOptions(JavaCore.getOptions()); ProblemReporter problemReporter = new ProblemReporter( DefaultErrorHandlingPolicies.proceedWithAllProblems(), this.compilerOptions, new DefaultProblemFactory()); this.parser = new Parser(problemReporter, true); } return this.parser; } /** * Returns the underlying resource of the given element. */ private IResource getResource(IJavaElement element) { if (element instanceof IMember) { ICompilationUnit cu = ((IMember) element).getCompilationUnit(); if (cu != null) { return cu.getResource(); } } return element.getResource(); } /* * Returns the list of working copies used by this search engine. * Returns null if none. */ private ICompilationUnit[] getWorkingCopies() { ICompilationUnit[] copies; if (this.workingCopies != null) { if (this.workingCopyOwner == null) { copies = JavaModelManager.getJavaModelManager() .getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false/*don't add primary WCs a second time*/); if (copies == null) { copies = this.workingCopies; } else { HashMap pathToCUs = new HashMap(); for (int i = 0, length = copies.length; i < length; i++) { ICompilationUnit unit = copies[i]; pathToCUs.put(unit.getPath(), unit); } for (int i = 0, length = this.workingCopies.length; i < length; i++) { ICompilationUnit unit = this.workingCopies[i]; pathToCUs.put(unit.getPath(), unit); } int length = pathToCUs.size(); copies = new ICompilationUnit[length]; pathToCUs.values().toArray(copies); } } else { copies = this.workingCopies; } } else if (this.workingCopyOwner != null) { copies = JavaModelManager.getJavaModelManager() .getWorkingCopies(this.workingCopyOwner, true/*add primary WCs*/); } else { copies = JavaModelManager.getJavaModelManager() .getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false/*don't add primary WCs a second time*/); } if (copies == null) return null; // filter out primary working copies that are saved ICompilationUnit[] result = null; int length = copies.length; int index = 0; for (int i = 0; i < length; i++) { CompilationUnit copy = (CompilationUnit) copies[i]; try { if (!copy.isPrimary() || copy.hasUnsavedChanges() || !copy.isBasedOn(copy.getResource())) { if (result == null) { result = new ICompilationUnit[length]; } result[index++] = copy; } } catch (JavaModelException e) { // copy doesn't exist: ignore } } if (index != length && result != null) { System.arraycopy(result, 0, result = new ICompilationUnit[index], 0, index); } return result; } /** * Returns the list of working copies used to do the search on the given java element. */ private ICompilationUnit[] getWorkingCopies(IJavaElement element) { if (element instanceof IMember) { ICompilationUnit cu = ((IMember) element).getCompilationUnit(); if (cu != null && cu.isWorkingCopy()) { ICompilationUnit[] copies = getWorkingCopies(); int length = copies == null ? 0 : copies.length; if (length > 0) { ICompilationUnit[] newWorkingCopies = new ICompilationUnit[length + 1]; System.arraycopy(copies, 0, newWorkingCopies, 0, length); newWorkingCopies[length] = cu; return newWorkingCopies; } else { return new ICompilationUnit[]{cu}; } } } return getWorkingCopies(); } /** * Searches for the Java element determined by the given signature. The signature * can be incomplete. For example, a call like * <code>search(ws, "run()", METHOD,REFERENCES, col)</code> * searches for all references to the method <code>run</code>. * * Note that by default the pattern will be case insensitive. For specifying case s * sensitive search, use <code>search(workspace, createSearchPattern(patternString, searchFor, limitTo, true), scope, resultCollector);</code> * * @param workspace the workspace * @param pattern the pattern to be searched for * @param searchFor a hint what kind of Java element the string pattern represents. * Look into <code>IJavaSearchConstants</code> for valid values * @param limitTo one of the following values: * <ul> * <li><code>IJavaSearchConstants.DECLARATIONS</code>: search * for declarations only </li> * <li><code>IJavaSearchConstants.REFERENCES</code>: search * for all references </li> * <li><code>IJavaSearchConstants.ALL_OCCURENCES</code>: search * for both declarations and all references </li> * <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: search for * all implementors of an interface; the value is only valid if * the Java element represents an interface</li> * </ul> * @param scope the search result has to be limited to the given scope * @param resultCollector a callback object to which each match is reported * @exception JavaModelException if the search failed. Reasons include: * <ul> * <li>the classpath is incorrectly set</li> * </ul> */ public void search(IWorkspace workspace, String patternString, int searchFor, int limitTo, IJavaSearchScope scope, IJavaSearchResultCollector resultCollector) throws JavaModelException { search(workspace, createSearchPattern(patternString, searchFor, limitTo, true), scope, resultCollector); } /** * Searches for the given Java element. * * @param workspace the workspace * @param element the Java element to be searched for * @param limitTo one of the following values: * <ul> * <li><code>IJavaSearchConstants.DECLARATIONS</code>: search * for declarations only </li> * <li><code>IJavaSearchConstants.REFERENCES</code>: search * for all references </li> * <li><code>IJavaSearchConstants.ALL_OCCURENCES</code>: search * for both declarations and all references </li> * <li><code>IJavaSearchConstants.IMPLEMENTORS</code>: search for * all implementors of an interface; the value is only valid if * the Java element represents an interface</li> * </ul> * @param scope the search result has to be limited to the given scope * @param resultCollector a callback object to which each match is reported * @exception JavaModelException if the search failed. Reasons include: * <ul> * <li>the element doesn't exist</li> * <li>the classpath is incorrectly set</li> * </ul> */ public void search(IWorkspace workspace, IJavaElement element, int limitTo, IJavaSearchScope scope, IJavaSearchResultCollector resultCollector) throws JavaModelException { search(workspace, createSearchPattern(element, limitTo), scope, resultCollector); } /** * Searches for matches of a given search pattern. Search patterns can be created using helper * methods (from a String pattern or a Java element) and encapsulate the description of what is * being searched (for example, search method declarations in a case sensitive way). * * @param workspace the workspace * @param searchPattern the pattern to be searched for * @param scope the search result has to be limited to the given scope * @param resultCollector a callback object to which each match is reported * @exception JavaModelException if the search failed. Reasons include: * <ul> * <li>the classpath is incorrectly set</li> * </ul> */ public void search(IWorkspace workspace, ISearchPattern searchPattern, IJavaSearchScope scope, IJavaSearchResultCollector resultCollector) throws JavaModelException { long start = -1; if (VERBOSE) { start = System.currentTimeMillis(); System.out.println("Searching for " + searchPattern + " in " + scope); //$NON-NLS-1$//$NON-NLS-2$ } /* search is starting */ resultCollector.aboutToStart(); MatchLocator matchLocator = null; try { if (searchPattern == null) return; /* initialize progress monitor */ IProgressMonitor progressMonitor = resultCollector.getProgressMonitor(); if (progressMonitor != null) { progressMonitor.beginTask(Util.bind("engine.searching"), 100); //$NON-NLS-1$ } /* index search */ PathCollector pathCollector = new PathCollector(); // In the case of a hierarchy scope make sure that the hierarchy is not computed. // MatchLocator will filter out elements not in the hierarchy SearchPattern pattern = (SearchPattern) searchPattern; if (scope instanceof HierarchyScope) { ((HierarchyScope) scope).needsRefresh = false; pattern.mustResolve = true; // force resolve to compute type bindings } IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); int detailLevel = IInfoConstants.PathInfo | IInfoConstants.PositionInfo; matchLocator = new MatchLocator(pattern, detailLevel, resultCollector, scope, progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 95)); indexManager.performConcurrentJob(new PatternSearchJob(pattern, scope, pattern.focus, pattern .isPolymorphicSearch(), detailLevel, pathCollector, indexManager), IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 5)); /* eliminating false matches and locating them */ if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException(); matchLocator.locateMatches(pathCollector.getPaths(), workspace, workingCopiesThatCanSeeFocus(pattern.focus, pattern.isPolymorphicSearch())); if (progressMonitor != null && progressMonitor.isCanceled()) throw new OperationCanceledException(); if (progressMonitor != null) { progressMonitor.done(); } matchLocator.locatePackageDeclarations(workspace); } finally { /* search has ended */ resultCollector.done(); if (VERBOSE) { System.out.println("Total time: " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ if (matchLocator != null) System.out.println("Time in result collector: " + matchLocator.resultCollectorTime + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ } } } /** * Searches for all top-level types and member types in the given scope. * The search can be selecting specific types (given a package or a type name * prefix and match modes). * * @param workspace the workspace to search in * @param packageName the full name of the package of the searched types, or a prefix for this * package, or a wild-carded string for this package. * @param typeName the dot-separated qualified name of the searched type (the qualification include * the enclosing types if the searched type is a member type), or a prefix * for this type, or a wild-carded string for this type. * @param matchMode one of * <ul> * <li><code>IJavaSearchConstants.EXACT_MATCH</code> if the package name and type name are the full names * of the searched types.</li> * <li><code>IJavaSearchConstants.PREFIX_MATCH</code> if the package name and type name are prefixes of the names * of the searched types.</li> * <li><code>IJavaSearchConstants.PATTERN_MATCH</code> if the package name and type name contain wild-cards.</li> * </ul> * @param isCaseSensitive whether the search should be case sensitive * @param searchFor one of * <ul> * <li><code>IJavaSearchConstants.CLASS</code> if searching for classes only</li> * <li><code>IJavaSearchConstants.INTERFACE</code> if searching for interfaces only</li> * <li><code>IJavaSearchConstants.TYPE</code> if searching for both classes and interfaces</li> * </ul> * @param scope the scope to search in * @param nameRequestor the requestor that collects the results of the search * @param waitingPolicy one of * <ul> * <li><code>IJavaSearchConstants.FORCE_IMMEDIATE_SEARCH</code> if the search should start immediately</li> * <li><code>IJavaSearchConstants.CANCEL_IF_NOT_READY_TO_SEARCH</code> if the search should be cancelled if the * underlying indexer has not finished indexing the workspace</li> * <li><code>IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH</code> if the search should wait for the * underlying indexer to finish indexing the workspace</li> * </ul> * @param progressMonitor the progress monitor to report progress to, or <code>null</code> if no progress * monitor is provided * @exception JavaModelException if the search failed. Reasons include: * <ul> * <li>the classpath is incorrectly set</li> * </ul> */ public void searchAllTypeNames(IWorkspace workspace, char[] packageName, char[] typeName, int matchMode, boolean isCaseSensitive, int searchFor, IJavaSearchScope scope, final ITypeNameRequestor nameRequestor, int waitingPolicy, IProgressMonitor progressMonitor) throws JavaModelException { IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager(); char classOrInterface; switch (searchFor) { case IJavaSearchConstants.CLASS : classOrInterface = IIndexConstants.CLASS_SUFFIX; break; case IJavaSearchConstants.INTERFACE : classOrInterface = IIndexConstants.INTERFACE_SUFFIX; break; default : classOrInterface = IIndexConstants.TYPE_SUFFIX; break; } SearchPattern pattern = new TypeDeclarationPattern(packageName, null, // do find member types typeName, classOrInterface, matchMode, isCaseSensitive); final HashSet workingCopyPaths = new HashSet(); ICompilationUnit[] copies = getWorkingCopies(); if (copies != null) { for (int i = 0, length = copies.length; i < length; i++) { ICompilationUnit workingCopy = copies[i]; workingCopyPaths.add(workingCopy.getPath().toString()); } } IIndexSearchRequestor searchRequestor = new IndexSearchAdapter() { public void acceptClassDeclaration(String resourcePath, char[] simpleTypeName, char[][] enclosingTypeNames, char[] pkgName) { if (enclosingTypeNames != IIndexConstants.ONE_ZERO_CHAR // filter out local and anonymous classes && !workingCopyPaths.contains(resourcePath)) { // filter out working copies nameRequestor.acceptClass(pkgName, simpleTypeName, enclosingTypeNames, resourcePath); } } public void acceptInterfaceDeclaration(String resourcePath, char[] simpleTypeName, char[][] enclosingTypeNames, char[] pkgName) { if (enclosingTypeNames != IIndexConstants.ONE_ZERO_CHAR // filter out local and anonymous classes && !workingCopyPaths.contains(resourcePath)) { // filter out working copies nameRequestor.acceptInterface(pkgName, simpleTypeName, enclosingTypeNames, resourcePath); } } }; try { if (progressMonitor != null) { progressMonitor.beginTask(Util.bind("engine.searching"), 100); //$NON-NLS-1$ } // add type names from indexes indexManager.performConcurrentJob( new PatternSearchJob(pattern, scope, IInfoConstants.NameInfo | IInfoConstants.PathInfo, searchRequestor, indexManager), waitingPolicy, progressMonitor == null ? null : new SubProgressMonitor(progressMonitor, 100)); // add type names from working copies if (copies != null) { for (int i = 0, length = copies.length; i < length; i++) { ICompilationUnit workingCopy = copies[i]; IPackageDeclaration[] packageDeclarations = workingCopy.getPackageDeclarations(); final String path = workingCopy.getPath().toString(); final char[] packageDeclaration = packageDeclarations.length == 0 ? CharOperation.NO_CHAR : packageDeclarations[0].getElementName().toCharArray(); if (workingCopy.isConsistent()) { IType[] allTypes = workingCopy.getAllTypes(); for (int j = 0, allTypesLength = allTypes.length; j < allTypesLength; j++) { IType type = allTypes[j]; IJavaElement parent = type.getParent(); char[][] enclosingTypeNames; if (parent instanceof IType) { char[] parentQualifiedName = ((IType) parent).getTypeQualifiedName('.').toCharArray(); enclosingTypeNames = CharOperation.splitOn('.', parentQualifiedName); } else { enclosingTypeNames = CharOperation.NO_CHAR_CHAR; } if (type.isClass()) { nameRequestor.acceptClass(packageDeclaration, type.getElementName().toCharArray(), enclosingTypeNames, path); } else { nameRequestor.acceptInterface(packageDeclaration, type.getElementName().toCharArray(), enclosingTypeNames, path); } } } else { Parser basicParser = getParser(); final char[] contents = workingCopy.getBuffer().getCharacters(); org.eclipse.jdt.internal.compiler.env.ICompilationUnit unit = new org.eclipse.jdt.internal.compiler.env.ICompilationUnit() { public char[] getContents() { return contents; } public char[] getMainTypeName() { return null; } public char[][] getPackageName() { return null; } public char[] getFileName() { return null; } }; CompilationResult compilationUnitResult = new CompilationResult(unit, 0, 0, this.compilerOptions.maxProblemsPerUnit); CompilationUnitDeclaration parsedUnit = basicParser.dietParse(unit, compilationUnitResult); if (parsedUnit != null) { class AllTypeDeclarationsVisitor extends AbstractSyntaxTreeVisitorAdapter { public boolean visit(LocalTypeDeclaration typeDeclaration, BlockScope blockScope) { return false; // no local type } public boolean visit(AnonymousLocalTypeDeclaration typeDeclaration, BlockScope blockScope) { return false; // no anonymous type } public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope compilationUnitScope) { if (!typeDeclaration.isInterface()) { nameRequestor.acceptClass(packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path); } else { nameRequestor.acceptInterface(packageDeclaration, typeDeclaration.name, CharOperation.NO_CHAR_CHAR, path); } return true; } public boolean visit(MemberTypeDeclaration memberTypeDeclaration, ClassScope classScope) { // compute encloising type names TypeDeclaration enclosing = memberTypeDeclaration.enclosingType; char[][] enclosingTypeNames = CharOperation.NO_CHAR_CHAR; while (enclosing != null) { enclosingTypeNames = CharOperation.arrayConcat(new char[][]{enclosing.name}, enclosingTypeNames); if (enclosing instanceof MemberTypeDeclaration) { enclosing = ((MemberTypeDeclaration) enclosing).enclosingType; } else { enclosing = null; } } // report if (!memberTypeDeclaration.isInterface()) { nameRequestor.acceptClass(packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path); } else { nameRequestor.acceptInterface(packageDeclaration, memberTypeDeclaration.name, enclosingTypeNames, path); } return true; } } parsedUnit.traverse(new AllTypeDeclarationsVisitor(), parsedUnit.scope); } } } } } finally { if (progressMonitor != null) { progressMonitor.done(); } } } /** * Searches for all declarations of the fields accessed in the given element. * The element can be a compilation unit, a source type, or a source method. * Reports the field declarations using the given collector. * <p> * Consider the following code: * <code> * <pre> * class A { * int field1; * } * class B extends A { * String value; * } * class X { * void test() { * B b = new B(); * System.out.println(b.value + b.field1); * }; * } * </pre> * </code> * then searching for declarations of accessed fields in method * <code>X.test()</code> would collect the fields * <code>B.value</code> and <code>A.field1</code>. * </p> * * @param workspace the workspace * @param enclosingElement the method, type, or compilation unit to be searched in * @param resultCollector a callback object to which each match is reported * @exception JavaModelException if the search failed. Reasons include: * <ul> * <li>the element doesn't exist</li> * <li>the classpath is incorrectly set</li> * </ul> */ public void searchDeclarationsOfAccessedFields(IWorkspace workspace, IJavaElement enclosingElement, IJavaSearchResultCollector resultCollector) throws JavaModelException { SearchPattern pattern = new DeclarationOfAccessedFieldsPattern(enclosingElement); IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[]{enclosingElement}); IResource resource = this.getResource(enclosingElement); if (resource instanceof IFile) { if (VERBOSE) { System.out.println("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$ } MatchLocator locator = new MatchLocator(pattern, IInfoConstants.DeclarationInfo, resultCollector, scope, resultCollector.getProgressMonitor()); locator.locateMatches(new String[]{resource.getFullPath().toString()}, workspace, this.getWorkingCopies( enclosingElement)); } else { search(workspace, pattern, scope, resultCollector); } } /** * Searches for all declarations of the types referenced in the given element. * The element can be a compilation unit, a source type, or a source method. * Reports the type declarations using the given collector. * <p> * Consider the following code: * <code> * <pre> * class A { * } * class B extends A { * } * interface I { * int VALUE = 0; * } * class X { * void test() { * B b = new B(); * this.foo(b, I.VALUE); * }; * } * </pre> * </code> * then searching for declarations of referenced types in method <code>X.test()</code> * would collect the class <code>B</code> and the interface <code>I</code>. * </p> * * @param workspace the workspace * @param enclosingElement the method, type, or compilation unit to be searched in * @param resultCollector a callback object to which each match is reported * @exception JavaModelException if the search failed. Reasons include: * <ul> * <li>the element doesn't exist</li> * <li>the classpath is incorrectly set</li> * </ul> */ public void searchDeclarationsOfReferencedTypes(IWorkspace workspace, IJavaElement enclosingElement, IJavaSearchResultCollector resultCollector) throws JavaModelException { SearchPattern pattern = new DeclarationOfReferencedTypesPattern(enclosingElement); IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[]{enclosingElement}); IResource resource = this.getResource(enclosingElement); if (resource instanceof IFile) { if (VERBOSE) { System.out.println("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$ } MatchLocator locator = new MatchLocator(pattern, IInfoConstants.DeclarationInfo, resultCollector, scope, resultCollector.getProgressMonitor()); locator.locateMatches(new String[]{resource.getFullPath().toString()}, workspace, this.getWorkingCopies( enclosingElement)); } else { search(workspace, pattern, scope, resultCollector); } } /** * Searches for all declarations of the methods invoked in the given element. * The element can be a compilation unit, a source type, or a source method. * Reports the method declarations using the given collector. * <p> * Consider the following code: * <code> * <pre> * class A { * void foo() {}; * void bar() {}; * } * class B extends A { * void foo() {}; * } * class X { * void test() { * A a = new B(); * a.foo(); * B b = (B)a; * b.bar(); * }; * } * </pre> * </code> * then searching for declarations of sent messages in method * <code>X.test()</code> would collect the methods * <code>A.foo()</code>, <code>B.foo()</code>, and <code>A.bar()</code>. * </p> * * @param workspace the workspace * @param enclosingElement the method, type, or compilation unit to be searched in * @param resultCollector a callback object to which each match is reported * @exception JavaModelException if the search failed. Reasons include: * <ul> * <li>the element doesn't exist</li> * <li>the classpath is incorrectly set</li> * </ul> */ public void searchDeclarationsOfSentMessages(IWorkspace workspace, IJavaElement enclosingElement, IJavaSearchResultCollector resultCollector) throws JavaModelException { SearchPattern pattern = new DeclarationOfReferencedMethodsPattern(enclosingElement); IJavaSearchScope scope = createJavaSearchScope(new IJavaElement[]{enclosingElement}); IResource resource = this.getResource(enclosingElement); if (resource instanceof IFile) { if (VERBOSE) { System.out.println("Searching for " + pattern + " in " + resource.getFullPath()); //$NON-NLS-1$//$NON-NLS-2$ } MatchLocator locator = new MatchLocator(pattern, IInfoConstants.DeclarationInfo, resultCollector, scope, resultCollector.getProgressMonitor()); locator.locateMatches(new String[]{resource.getFullPath().toString()}, workspace, this.getWorkingCopies( enclosingElement)); } else { search(workspace, pattern, scope, resultCollector); } } /* * Returns the working copies that cannot see the given focus. */ private ICompilationUnit[] workingCopiesThatCanSeeFocus(IJavaElement focus, boolean isPolymorphicSearch) { ICompilationUnit[] copies = getWorkingCopies(); if (focus == null || copies == null) return copies; while (!(focus instanceof IJavaProject) && !(focus instanceof JarPackageFragmentRoot)) { focus = focus.getParent(); } int length = copies.length; ICompilationUnit[] result = null; int index = -1; for (int i = 0; i < length; i++) { ICompilationUnit workingCopy = copies[i]; IPath projectOrJar = IndexSelector.getProjectOrJar(workingCopy).getPath(); if (!IndexSelector.canSeeFocus(focus, isPolymorphicSearch, projectOrJar)) { if (result == null) { result = new ICompilationUnit[length - 1]; System.arraycopy(copies, 0, result, 0, i); index = i; } } else if (result != null) { result[index++] = workingCopy; } } if (result != null) { if (result.length != index) { System.arraycopy(result, 0, result = new ICompilationUnit[index], 0, index); } return result; } else { return copies; } } }
I had enabled the new formatter (which generate edits)
I could not reproduce the problem. I never get an OutOfMemory error.
Java code formatter is Jdt Core. Comment formatting does not use edits and the error message says: !ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:18:57.646 !MESSAGE formatter returned null-edit.
The null edits where a separate issue related to a bug in the formatter page. The suspicion is that the edit application is causing grief here.
As discussed with Olivier the problem doesn't occur if the quick differences is disabled (see exception in comment #1). Moving to text for comments.
To reproduce you have to enable the new formatter.
The entry '!ENTRY org.eclipse.jdt.ui 4 10001 Oct 03, 2003 18:18:57.646 !MESSAGE formatter returned null-edit.' seen by Philippe came drom a bug in the codeformatter-example source. This is fixed (different bug report) BTW, Note that this is only a message in the log, not a stacktrace. It should help us to find incompatibilities. If the new formatter returns a null edit (source has syntax error or something else) I use the unformatted text. I improve this warning message so it does not cause more confusion (will remove the logging later when we're done with the conversion). "formatter failed to format (no edit returned). Will use unformatted text instead. kind: " + kind + ", string: " + string"
There are at least two separate issues remaining: - The failed assertion in RangeDifferencer - the code is the same as everywhere in compare and I cannot reproduce this - I assume it has to do with a concurrent modification. -> I have a fix for this, although not a very satisfying one, which I will commit shortly. - The OutOfMemory error *can* and will happen when diffing large documents with many changes. This is a shortcoming of the diff / alignment algorithm used, which is O(number of changes^2) for space. The same will happen when reformatting, say, StyledText and doing a compare with HEAD. -> Workaround is to not use compare and disable quick diff (Ctrl+Shift+Q) in such situations. -> A long term solution would be to back off to a different diffing algo (Dan Hirschberg's linear space algorithm for computing maximal common subsequences) on large files.
fixed the concurrency issue > 20031006 workaround for OutOfMemoryError described in comment 10. Closing.
*** Bug 61599 has been marked as a duplicate of this bug. ***