|
From: <caw...@us...> - 2007-03-13 18:35:27
|
Revision: 2150
http://svn.sourceforge.net/rubyeclipse/?rev=2150&view=rev
Author: cawilliams
Date: 2007-03-13 11:35:20 -0700 (Tue, 13 Mar 2007)
Log Message:
-----------
Modified Paths:
--------------
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/CharOperation.java
Added Paths:
-----------
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/IDependent.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/IRubyScript.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/HashtableOfLong.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchingNodeSet.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PossibleMatch.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PossibleMatchSet.java
Modified: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java 2007-03-13 18:22:14 UTC (rev 2149)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -317,6 +317,7 @@
private static final boolean VERBOSE = false;
+ public static final boolean DEBUG = false;
private SymbolIndex symbolIndex;
private ISymbolFinder symbolFinder;
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/IDependent.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/IDependent.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/IDependent.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.compiler.env;
+
+/**
+ * This represents the target file of a type dependency.
+ *
+ * All implementors of this interface are containers for types or types
+ * themselves which must be able to identify their source file name when file
+ * dependencies are collected.
+ */
+public interface IDependent {
+ char JAR_FILE_ENTRY_SEPARATOR = '|';
+
+ /**
+ * Answer the file name which defines the type.
+ *
+ * The path part (optional) must be separated from the actual file proper
+ * name by a separator suitable for the type (java.io.File.separator for
+ * example), e.g. "c:\\source\\com\\p\\X.java" or "/com/p/Y.java".
+ *
+ * The path to the zip or jar file (optional) must be separated from the
+ * actual path part by JAR_FILE_ENTRY_SEPARATOR, e.g.
+ * "c:\\lib\\some.jar|/com/p/X.class" or "/lib/some.zip|/com/q/Y.class".
+ *
+ * The proper file name includes the suffix extension (e.g. ".java")
+ * e.g. "c:/org/eclipse/jdt/internal/compileri/env/IDependent.java"
+ *
+ * Return null if no file defines the type.
+ */
+
+ char[] getFileName();
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/IRubyScript.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/IRubyScript.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/IRubyScript.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -0,0 +1,24 @@
+package org.rubypeople.rdt.internal.compiler.env;
+
+import org.eclipse.core.runtime.IPath;
+import org.rubypeople.rdt.core.IRubyElement;
+
+public interface IRubyScript extends IDependent {
+
+ /**
+ * Answer the name of the package according to the directory structure or
+ * null if package consistency checks should be ignored. For example, {java,
+ * lang}.
+ */
+ IPath getScriptFolder();
+
+ /**
+ * Answer the contents of the compilation unit.
+ *
+ * In normal use, the contents are requested twice. Once during the initial
+ * lite parsing step, then again for the more detailed parsing step.
+ */
+ String getSourceContents();
+
+ IRubyElement getRubyElement();
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/HashtableOfLong.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/HashtableOfLong.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/HashtableOfLong.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.compiler.util;
+
+
+ /**
+ * Hashtable for non-zero long keys.
+ */
+
+public final class HashtableOfLong {
+ // to avoid using Enumerations, walk the individual tables skipping nulls
+ public long[] keyTable;
+ public Object[] valueTable;
+
+ public int elementSize; // number of elements in the table
+ int threshold;
+public HashtableOfLong() {
+ this(13);
+}
+public HashtableOfLong(int size) {
+ this.elementSize = 0;
+ this.threshold = size; // size represents the expected number of elements
+ int extraRoom = (int) (size * 1.75f);
+ if (this.threshold == extraRoom)
+ extraRoom++;
+ this.keyTable = new long[extraRoom];
+ this.valueTable = new Object[extraRoom];
+}
+public boolean containsKey(long key) {
+ int length = keyTable.length,
+ index = ((int)(key >>> 32)) % length;
+ long currentKey;
+ while ((currentKey = keyTable[index]) != 0) {
+ if (currentKey == key)
+ return true;
+ if (++index == length) {
+ index = 0;
+ }
+ }
+ return false;
+}
+public Object get(long key) {
+ int length = keyTable.length,
+ index = ((int)(key >>> 32)) % length;
+ long currentKey;
+ while ((currentKey = keyTable[index]) != 0) {
+ if (currentKey == key) return valueTable[index];
+ if (++index == length) {
+ index = 0;
+ }
+ }
+ return null;
+}
+public Object put(long key, Object value) {
+ int length = keyTable.length,
+ index = ((int)(key >>> 32)) % length;
+ long currentKey;
+ while ((currentKey = keyTable[index]) != 0) {
+ if (currentKey == key) return valueTable[index] = value;
+ if (++index == length) {
+ index = 0;
+ }
+ }
+ keyTable[index] = key;
+ valueTable[index] = value;
+
+ // assumes the threshold is never equal to the size of the table
+ if (++elementSize > threshold)
+ rehash();
+ return value;
+}
+private void rehash() {
+ HashtableOfLong newHashtable = new HashtableOfLong(elementSize * 2); // double the number of expected elements
+ long currentKey;
+ for (int i = keyTable.length; --i >= 0;)
+ if ((currentKey = keyTable[i]) != 0)
+ newHashtable.put(currentKey, valueTable[i]);
+
+ this.keyTable = newHashtable.keyTable;
+ this.valueTable = newHashtable.valueTable;
+ this.threshold = newHashtable.threshold;
+}
+public int size() {
+ return elementSize;
+}
+public String toString() {
+ String s = ""; //$NON-NLS-1$
+ Object object;
+ for (int i = 0, length = valueTable.length; i < length; i++)
+ if ((object = valueTable[i]) != null)
+ s += keyTable[i] + " -> " + object.toString() + "\n"; //$NON-NLS-2$ //$NON-NLS-1$
+ return s;
+}
+}
Modified: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java 2007-03-13 18:22:14 UTC (rev 2149)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -41,6 +41,8 @@
// Progress information
int progressStep;
int progressWorked;
+
+ SimpleLookupTable bindings;
public static class WorkingCopyDocument extends RubySearchDocument {
public org.rubypeople.rdt.core.IRubyScript workingCopy;
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchingNodeSet.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchingNodeSet.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchingNodeSet.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.core.search.matching;
+
+import java.util.ArrayList;
+
+import org.jruby.ast.Node;
+import org.rubypeople.rdt.core.RubyCore;
+import org.rubypeople.rdt.core.search.SearchMatch;
+import org.rubypeople.rdt.core.search.SearchPattern;
+import org.rubypeople.rdt.internal.compiler.util.HashtableOfLong;
+import org.rubypeople.rdt.internal.compiler.util.SimpleLookupTable;
+import org.rubypeople.rdt.internal.compiler.util.SimpleSet;
+import org.rubypeople.rdt.internal.core.util.Util;
+
+/**
+ * A set of matches and possible matches, which need to be resolved.
+ */
+public class MatchingNodeSet {
+ /**
+ * Map of matching ast nodes that don't need to be resolved to their
+ * accuracy level. Each node is removed as it is reported.
+ */
+ public SimpleLookupTable matchingNodes = new SimpleLookupTable(3); // node ->
+ // accuracy
+ private HashtableOfLong matchingNodesKeys = new HashtableOfLong(3); // sourceRange
+ // ->
+ // node
+ static Integer EXACT_MATCH = new Integer(SearchMatch.A_ACCURATE);
+ static Integer POTENTIAL_MATCH = new Integer(SearchMatch.A_INACCURATE);
+ static Integer ERASURE_MATCH = new Integer(SearchPattern.R_ERASURE_MATCH);
+ /**
+ * Set of possible matching ast nodes. They need to be resolved to determine
+ * if they really match the search pattern.
+ */
+ public SimpleSet possibleMatchingNodesSet = new SimpleSet(7);
+ private HashtableOfLong possibleMatchingNodesKeys = new HashtableOfLong(7);
+
+ public MatchingNodeSet() {
+ super();
+ }
+
+ public int addMatch(Node node, int matchLevel) {
+ switch (matchLevel & PatternLocator.NODE_SET_MASK) {
+ case PatternLocator.INACCURATE_MATCH:
+ addTrustedMatch(node, POTENTIAL_MATCH);
+ break;
+ case PatternLocator.POSSIBLE_MATCH:
+ addPossibleMatch(node);
+ break;
+ case PatternLocator.ERASURE_MATCH:
+ addTrustedMatch(node, ERASURE_MATCH);
+ break;
+ case PatternLocator.ACCURATE_MATCH:
+ addTrustedMatch(node, EXACT_MATCH);
+ }
+ return matchLevel;
+ }
+
+ public void addPossibleMatch(Node node) {
+ // remove existing node at same position from set
+ // (case of recovery that created the same node several time
+ // see http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366)
+ long key = (((long) node.sourceStart()) << 32) + node.sourceEnd();
+ Node existing = (Node) this.possibleMatchingNodesKeys.get(key);
+ if (existing != null && existing.getClass().equals(node.getClass()))
+ this.possibleMatchingNodesSet.remove(existing);
+ // add node to set
+ this.possibleMatchingNodesSet.add(node);
+ this.possibleMatchingNodesKeys.put(key, node);
+ }
+
+ public void addTrustedMatch(Node node, boolean isExact) {
+ addTrustedMatch(node, isExact ? EXACT_MATCH : POTENTIAL_MATCH);
+ }
+
+ void addTrustedMatch(Node node, Integer level) {
+ // remove existing node at same position from set
+ // (case of recovery that created the same node several time
+ // see http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366)
+ long key = (((long) node.sourceStart()) << 32) + node.sourceEnd();
+ Node existing = (Node) this.matchingNodesKeys.get(key);
+ if (existing != null && existing.getClass().equals(node.getClass()))
+ this.matchingNodes.removeKey(existing);
+ // map node to its accuracy level
+ this.matchingNodes.put(node, level);
+ this.matchingNodesKeys.put(key, node);
+ }
+
+ protected boolean hasPossibleNodes(int start, int end) {
+ Object[] nodes = this.possibleMatchingNodesSet.values;
+ for (int i = 0, l = nodes.length; i < l; i++) {
+ Node node = (Node) nodes[i];
+ if (node != null && start <= node.sourceStart() && node.sourceEnd() <= end)
+ return true;
+ }
+ nodes = this.matchingNodes.keyTable;
+ for (int i = 0, l = nodes.length; i < l; i++) {
+ Node node = (Node) nodes[i];
+ if (node != null && start <= node.sourceStart() && node.sourceEnd() <= end)
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the matching nodes that are in the given range in the source
+ * order.
+ */
+ public Node[] matchingNodes(int start, int end) {
+ ArrayList nodes = null;
+ Object[] keyTable = this.matchingNodes.keyTable;
+ for (int i = 0, l = keyTable.length; i < l; i++) {
+ Node node = (Node) keyTable[i];
+ if (node != null && start <= node.sourceStart() && node.sourceEnd() <= end) {
+ if (nodes == null)
+ nodes = new ArrayList();
+ nodes.add(node);
+ }
+ }
+ if (nodes == null)
+ return null;
+ Node[] result = new Node[nodes.size()];
+ nodes.toArray(result);
+ // sort nodes by source starts
+ Util.Comparer comparer = new Util.Comparer() {
+ public int compare(Object o1, Object o2) {
+ return ((Node) o1).sourceStart() - ((Node) o2).sourceStart();
+ }
+ };
+ Util.sort(result, comparer);
+ return result;
+ }
+
+ public Object removePossibleMatch(Node node) {
+ long key = (((long) node.sourceStart()) << 32) + node.sourceEnd();
+ Node existing = (Node) this.possibleMatchingNodesKeys.get(key);
+ if (existing == null)
+ return null;
+ this.possibleMatchingNodesKeys.put(key, null);
+ return this.possibleMatchingNodesSet.remove(node);
+ }
+
+ public Object removeTrustedMatch(Node node) {
+ long key = (((long) node.sourceStart()) << 32) + node.sourceEnd();
+ Node existing = (Node) this.matchingNodesKeys.get(key);
+ if (existing == null)
+ return null;
+ this.matchingNodesKeys.put(key, null);
+ return this.matchingNodes.removeKey(node);
+ }
+
+ public String toString() {
+ // TODO (jerome) should show both tables
+ StringBuffer result = new StringBuffer();
+ result.append("Exact matches:"); //$NON-NLS-1$
+ Object[] keyTable = this.matchingNodes.keyTable;
+ Object[] valueTable = this.matchingNodes.valueTable;
+ for (int i = 0, l = keyTable.length; i < l; i++) {
+ Node node = (Node) keyTable[i];
+ if (node == null)
+ continue;
+ result.append("\n\t"); //$NON-NLS-1$
+ switch (((Integer) valueTable[i]).intValue()) {
+ case SearchMatch.A_ACCURATE:
+ result.append("ACCURATE_MATCH: "); //$NON-NLS-1$
+ break;
+ case SearchMatch.A_INACCURATE:
+ result.append("INACCURATE_MATCH: "); //$NON-NLS-1$
+ break;
+ case SearchPattern.R_ERASURE_MATCH:
+ result.append("ERASURE_MATCH: "); //$NON-NLS-1$
+ break;
+ }
+ //node.print(0, result);
+ if (RubyCore.DEBUG) {
+ System.err.println("TODO: Add node print...");
+ }
+ }
+ result.append("\nPossible matches:"); //$NON-NLS-1$
+ Object[] nodes = this.possibleMatchingNodesSet.values;
+ for (int i = 0, l = nodes.length; i < l; i++) {
+ Node node = (Node) nodes[i];
+ if (node == null)
+ continue;
+ result.append("\nPOSSIBLE_MATCH: "); //$NON-NLS-1$
+ //node.print(0, result);
+ if (RubyCore.DEBUG) {
+ System.err.println("TODO: Add node print...");
+ }
+ }
+ return result.toString();
+ }
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PossibleMatch.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PossibleMatch.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PossibleMatch.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.core.search.matching;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.RubyCore;
+import org.rubypeople.rdt.core.search.SearchDocument;
+import org.rubypeople.rdt.internal.compiler.env.IRubyScript;
+import org.rubypeople.rdt.internal.core.Openable;
+import org.rubypeople.rdt.internal.core.RubyScript;
+import org.rubypeople.rdt.internal.core.util.CharOperation;
+
+public class PossibleMatch implements IRubyScript {
+ public static final String NO_SOURCE_FILE_NAME = "NO SOURCE FILE NAME"; //$NON-NLS-1$
+ public IResource resource;
+ public Openable openable;
+ public MatchingNodeSet nodeSet;
+ public char[][] compoundName;
+ public ModuleDeclaration parsedUnit;
+ public SearchDocument document;
+ private String sourceFileName;
+ private String source;
+
+ public PossibleMatch(MatchLocator locator, IResource resource, Openable openable, SearchDocument document) {
+ this.resource = resource;
+ this.openable = openable;
+ this.document = document;
+ this.nodeSet = new MatchingNodeSet();
+ char[] qualifiedName = getQualifiedName();
+ if (qualifiedName != null)
+ this.compoundName = CharOperation.splitOn('.', qualifiedName);
+ }
+
+ public void cleanUp() {
+ this.source = null;
+ if (this.parsedUnit != null) {
+ //this.parsedUnit.cleanUp();
+ this.parsedUnit = null;
+ }
+ this.nodeSet = null;
+ }
+
+ public boolean equals(Object obj) {
+ if (this.compoundName == null)
+ return super.equals(obj);
+ if (!(obj instanceof PossibleMatch))
+ return false;
+ // By using the compoundName of the source file, multiple .class files
+ // (A, A$M...) are considered equal
+ // Even .class files for secondary types and their nested types
+ return CharOperation.equals(this.compoundName, ((PossibleMatch) obj).compoundName);
+ }
+
+ public String getSourceContents() {
+ if (this.source != null)
+ return this.source;
+ return this.source = new String(this.document.getCharContents());
+ }
+
+ /**
+ * The exact openable file name. In particular, will be the originating
+ * .class file for binary openable with attached source.
+ *
+ * @see org.eclipse.jdt.internal.compiler.env.IDependent#getFileName()
+ * @see PackageReferenceLocator#isDeclaringPackageFragment(IPackageFragment,
+ * org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding)
+ */
+ public char[] getFileName() {
+ return this.openable.getElementName().toCharArray();
+ }
+
+ public char[] getMainTypeName() {
+ // The file is no longer opened to get its name => remove fix for bug
+ // 32182
+ return this.compoundName[this.compoundName.length - 1];
+ }
+
+ public char[][] getPackageName() {
+ int length = this.compoundName.length;
+ if (length <= 1)
+ return CharOperation.NO_CHAR_CHAR;
+ return CharOperation.subarray(this.compoundName, 0, length - 1);
+ }
+
+ /*
+ * Returns the fully qualified name of the main type of the compilation unit
+ * or the main type of the .java file that defined the class file.
+ */
+ private char[] getQualifiedName() {
+ if (this.openable instanceof RubyScript) {
+ // get file name
+ String fileName = this.openable.getElementName(); // working copy
+ // on a .class
+ // file may not
+ // have a
+ // resource, so
+ // use the
+ // element name
+ // get main type name
+ char[] mainTypeName = fileName.toCharArray();
+ RubyScript cu = (RubyScript) this.openable;
+ return cu.getType(new String(mainTypeName)).getFullyQualifiedName().toCharArray();
+ }
+ if (RubyCore.DEBUG) {
+ System.err.println("TODO: Code review here...");
+ }
+ return null;
+ }
+
+ /*
+ * Returns the source file name of the class file. Returns
+ * NO_SOURCE_FILE_NAME if not found.
+ */
+ private String getSourceFileName() {
+ if (this.sourceFileName != null)
+ return this.sourceFileName;
+ this.sourceFileName = NO_SOURCE_FILE_NAME;
+ return this.sourceFileName;
+ }
+
+ public int hashCode() {
+ if (this.compoundName == null)
+ return super.hashCode();
+ int hashCode = 0;
+ for (int i = 0, length = this.compoundName.length; i < length; i++)
+ hashCode += CharOperation.hashCode(this.compoundName[i]);
+ return hashCode;
+ }
+
+ public String toString() {
+ return this.openable == null ? "Fake PossibleMatch" : this.openable.toString(); //$NON-NLS-1$
+ }
+
+ public IRubyElement getRubyElement() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public IPath getScriptFolder() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PossibleMatchSet.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PossibleMatchSet.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PossibleMatchSet.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.core.search.matching;
+
+import org.eclipse.core.runtime.IPath;
+import org.rubypeople.rdt.core.ISourceFolderRoot;
+import org.rubypeople.rdt.internal.compiler.util.ObjectVector;
+import org.rubypeople.rdt.internal.compiler.util.SimpleLookupTable;
+
+/**
+ * A set of PossibleMatches that is sorted by package fragment roots.
+ */
+public class PossibleMatchSet {
+
+private SimpleLookupTable rootsToPossibleMatches = new SimpleLookupTable(5);
+private int elementCount = 0;
+
+public void add(PossibleMatch possibleMatch) {
+ IPath path = possibleMatch.openable.getSourceFolderRoot().getPath();
+ ObjectVector possibleMatches = (ObjectVector) this.rootsToPossibleMatches.get(path);
+ if (possibleMatches != null) {
+ if (possibleMatches.contains(possibleMatch)) return;
+ } else {
+ this.rootsToPossibleMatches.put(path, possibleMatches = new ObjectVector());
+ }
+
+ possibleMatches.add(possibleMatch);
+ this.elementCount++;
+}
+public PossibleMatch[] getPossibleMatches(ISourceFolderRoot[] roots) {
+ PossibleMatch[] result = new PossibleMatch[this.elementCount];
+ int index = 0;
+ for (int i = 0, length = roots.length; i < length; i++) {
+ ObjectVector possibleMatches = (ObjectVector) this.rootsToPossibleMatches.get(roots[i].getPath());
+ if (possibleMatches != null) {
+ possibleMatches.copyInto(result, index);
+ index += possibleMatches.size();
+ }
+ }
+ if (index < this.elementCount)
+ System.arraycopy(result, 0, result = new PossibleMatch[index], 0, index);
+ return result;
+}
+public void reset() {
+ this.rootsToPossibleMatches = new SimpleLookupTable(5);
+ this.elementCount = 0;
+}
+}
Modified: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/CharOperation.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/CharOperation.java 2007-03-13 18:22:14 UTC (rev 2149)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/CharOperation.java 2007-03-13 18:35:20 UTC (rev 2150)
@@ -1428,4 +1428,61 @@
name.length,
isCaseSensitive);
}
+
+ /**
+ * Answers a new array which is a copy of the given array starting at the
+ * given start and ending at the given end. The given start is inclusive and
+ * the given end is exclusive. Answers null if start is greater than end, if
+ * start is lower than 0 or if end is greater than the length of the given
+ * array. If end equals -1, it is converted to the array length. <br>
+ * <br>
+ * For example:
+ * <ol>
+ * <li>
+ *
+ * <pre>
+ * array = { { 'a' } , { 'b' } }
+ * start = 0
+ * end = 1
+ * result => { { 'a' } }
+ * </pre>
+ *
+ * </li>
+ * <li>
+ *
+ * <pre>
+ * array = { { 'a' } , { 'b' } }
+ * start = 0
+ * end = -1
+ * result => { { 'a' }, { 'b' } }
+ * </pre>
+ *
+ * </li>
+ * </ol>
+ *
+ * @param array
+ * the given array
+ * @param start
+ * the given starting index
+ * @param end
+ * the given ending index
+ * @return a new array which is a copy of the given array starting at the
+ * given start and ending at the given end
+ * @throws NullPointerException
+ * if the given array is null
+ */
+ public static final char[][] subarray(char[][] array, int start, int end) {
+ if (end == -1)
+ end = array.length;
+ if (start > end)
+ return null;
+ if (start < 0)
+ return null;
+ if (end > array.length)
+ return null;
+
+ char[][] result = new char[end - start][];
+ System.arraycopy(array, start, result, 0, end - start);
+ return result;
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|