|
From: <caw...@us...> - 2007-03-13 18:17:03
|
Revision: 2146
http://svn.sourceforge.net/rubyeclipse/?rev=2146&view=rev
Author: cawilliams
Date: 2007-03-13 11:16:58 -0700 (Tue, 13 Mar 2007)
Log Message:
-----------
Modified Paths:
--------------
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/BasicSearchEngine.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/RubySearchDocument.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/search/matching/PatternLocator.java
Added Paths:
-----------
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/INameEnvironment.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/NameEnvironmentAnswer.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/BlockScope.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/MethodScope.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/SourceModuleScope.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/TypeConstants.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/TypeScope.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/lookup/
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/lookup/LookupEnvironment.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/CompoundNameVector.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/SimpleNameVector.java
branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/HandleFactory.java
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/INameEnvironment.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/INameEnvironment.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/INameEnvironment.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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;
+
+
+/**
+ * The name environment provides a callback API that the compiler can use to
+ * look up types, compilation units, and packages in the current environment.
+ * The name environment is passed to the compiler on creation.
+ */
+public interface INameEnvironment {
+ /**
+ * Find a type with the given compound name. Answer the binary form of the
+ * type if it is known to be consistent. Otherwise, answer the compilation
+ * unit which defines the type or null if the type does not exist. Types in
+ * the default package are specified as {{typeName}}.
+ *
+ * It is unknown whether the package containing the type actually exists.
+ *
+ * NOTE: This method can be used to find a member type using its internal
+ * name A$B, but the source file for A is answered if the binary file is
+ * inconsistent.
+ */
+
+ NameEnvironmentAnswer findType(char[][] compoundTypeName);
+
+ /**
+ * Find a type named <typeName> in the package <packageName>. Answer the
+ * binary form of the type if it is known to be consistent. Otherwise,
+ * answer the compilation unit which defines the type or null if the type
+ * does not exist. The default package is indicated by char[0][].
+ *
+ * It is known that the package containing the type exists.
+ *
+ * NOTE: This method can be used to find a member type using its internal
+ * name A$B, but the source file for A is answered if the binary file is
+ * inconsistent.
+ */
+
+ NameEnvironmentAnswer findType(char[] typeName, char[][] packageName);
+
+ /**
+ * Answer whether packageName is the name of a known subpackage inside the
+ * package parentPackageName. A top level package is found relative to null.
+ * The default package is always assumed to exist.
+ *
+ * For example: isPackage({{java}, {awt}}, {event}); isPackage(null,
+ * {java});
+ */
+
+ boolean isPackage(char[][] parentPackageName, char[] packageName);
+
+ /**
+ * This method cleans the environment uo. It is responsible for releasing
+ * the memory and freeing resources. Passed that point, the name environment
+ * is no longer usable.
+ *
+ * A name environment can have a long life cycle, therefore it is the
+ * responsibility of the code which created it to decide when it is a good
+ * time to clean it up.
+ */
+ void cleanup();
+
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/NameEnvironmentAnswer.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/NameEnvironmentAnswer.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/NameEnvironmentAnswer.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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;
+
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.IType;
+
+public class NameEnvironmentAnswer {
+
+ // only one of the three can be set
+ IRubyScript compilationUnit;
+ IType[] sourceTypes;
+ AccessRestriction accessRestriction;
+
+ public NameEnvironmentAnswer(IRubyScript compilationUnit, AccessRestriction accessRestriction) {
+ this.compilationUnit = compilationUnit;
+ this.accessRestriction = accessRestriction;
+ }
+
+ public NameEnvironmentAnswer(IType[] sourceTypes, AccessRestriction accessRestriction) {
+ this.sourceTypes = sourceTypes;
+ this.accessRestriction = accessRestriction;
+ }
+ /**
+ * Returns the associated access restriction, or null if none.
+ */
+ public AccessRestriction getAccessRestriction() {
+ return this.accessRestriction;
+ }
+
+ /**
+ * Answer the compilation unit or null if the
+ * receiver represents a binary or source type.
+ */
+ public IRubyScript getCompilationUnit() {
+ return this.compilationUnit;
+ }
+
+ /**
+ * Answer the unresolved source forms for the type or null if the
+ * receiver represents a compilation unit or binary type.
+ *
+ * Multiple source forms can be answered in case the originating compilation unit did contain
+ * several type at once. Then the first type is guaranteed to be the requested type.
+ */
+ public IType[] getSourceTypes() {
+ return this.sourceTypes;
+ }
+
+ /**
+ * Answer whether the receiver contains the compilation unit which defines the type.
+ */
+ public boolean isCompilationUnit() {
+ return this.compilationUnit != null;
+ }
+
+ /**
+ * Answer whether the receiver contains the unresolved source form of the type.
+ */
+ public boolean isSourceType() {
+ return this.sourceTypes != null;
+ }
+
+ public boolean ignoreIfBetter() {
+ return this.accessRestriction != null && this.accessRestriction.ignoreIfBetter();
+ }
+
+ /*
+ * Returns whether this answer is better than the other awswer.
+ * (accessible is better than discouraged, which is better than
+ * non-accessible)
+ */
+ public boolean isBetter(NameEnvironmentAnswer otherAnswer) {
+ if (otherAnswer == null) return true;
+ if (this.accessRestriction == null) return true;
+ return otherAnswer.accessRestriction != null
+ && this.accessRestriction.getProblemId() < otherAnswer.accessRestriction.getProblemId();
+ }
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/BlockScope.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/BlockScope.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/BlockScope.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * 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.lookup;
+
+public class BlockScope extends Scope {
+ // Local variable management
+ public int localIndex; // position for next variable
+ public int startIndex; // start position in this scope - for ordering
+ // scopes vs. variables
+ public int offset; // for variable allocation throughout scopes
+ public int maxOffset; // for variable allocation throughout scopes
+ // finally scopes must be shifted behind respective try&catch scope(s) so as
+ // to avoid
+ // collisions of secret variables (return address, save value).
+ public BlockScope[] shiftScopes;
+ public Scope[] subscopes = new Scope[1]; // need access from code assist
+ public int subscopeCount = 0; // need access from code assist
+
+ // record the current case statement being processed (for entire switch case
+ // block).
+ public BlockScope(BlockScope parent) {
+ this(parent, true);
+ }
+
+ public BlockScope(BlockScope parent, boolean addToParentScope) {
+ this(Scope.BLOCK_SCOPE, parent);
+ if (addToParentScope)
+ parent.addSubscope(this);
+ this.startIndex = parent.localIndex;
+ }
+
+ public BlockScope(BlockScope parent, int variableCount) {
+ this(Scope.BLOCK_SCOPE, parent);
+ parent.addSubscope(this);
+ this.startIndex = parent.localIndex;
+ }
+
+ protected BlockScope(int kind, Scope parent) {
+ super(kind, parent);
+ }
+
+ public void addSubscope(Scope childScope) {
+ if (this.subscopeCount == this.subscopes.length)
+ System.arraycopy(this.subscopes, 0, (this.subscopes = new Scope[this.subscopeCount * 2]), 0, this.subscopeCount);
+ this.subscopes[this.subscopeCount++] = childScope;
+ }
+
+ String basicToString(int tab) {
+ String newLine = "\n"; //$NON-NLS-1$
+ for (int i = tab; --i >= 0;)
+ newLine += "\t"; //$NON-NLS-1$
+ String s = newLine + "--- Block Scope ---"; //$NON-NLS-1$
+ newLine += "\t"; //$NON-NLS-1$
+ s += newLine + "startIndex = " + this.startIndex; //$NON-NLS-1$
+ return s;
+ }
+
+ public int maxShiftedOffset() {
+ int max = -1;
+ if (this.shiftScopes != null) {
+ for (int i = 0, length = this.shiftScopes.length; i < length; i++) {
+ int subMaxOffset = this.shiftScopes[i].maxOffset;
+ if (subMaxOffset > max)
+ max = subMaxOffset;
+ }
+ }
+ return max;
+ }
+
+ /*
+ * Answer the index of this scope relatively to its parent. For method
+ * scope, answers -1 (not a classScope relative position)
+ */
+ public int scopeIndex() {
+ if (this instanceof MethodScope)
+ return -1;
+ BlockScope parentScope = (BlockScope) this.parent;
+ Scope[] parentSubscopes = parentScope.subscopes;
+ for (int i = 0, max = parentScope.subscopeCount; i < max; i++) {
+ if (parentSubscopes[i] == this)
+ return i;
+ }
+ return -1;
+ }
+
+ // start position in this scope - for ordering scopes vs. variables
+ int startIndex() {
+ return this.startIndex;
+ }
+
+ public String toString() {
+ return toString(0);
+ }
+
+ public String toString(int tab) {
+ String s = basicToString(tab);
+ for (int i = 0; i < this.subscopeCount; i++)
+ if (this.subscopes[i] instanceof BlockScope)
+ s += ((BlockScope) this.subscopes[i]).toString(tab + 1) + "\n"; //$NON-NLS-1$
+ return s;
+ }
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/MethodScope.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/MethodScope.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/MethodScope.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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.lookup;
+
+/**
+ * Particular block scope used for methods, constructors or clinits, representing
+ * its outermost blockscope. Note also that such a scope will be provided to enclose
+ * field initializers subscopes as well.
+ */
+public class MethodScope extends BlockScope {
+
+
+ public MethodScope(Scope parent, boolean isStatic) {
+
+ super(METHOD_SCOPE, parent);
+ this.startIndex = 0;
+ }
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/SourceModuleScope.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/SourceModuleScope.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/SourceModuleScope.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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
+ * Erling Ellingsen - patch for bug 125570
+ *******************************************************************************/
+package org.rubypeople.rdt.internal.compiler.env.lookup;
+
+import org.rubypeople.rdt.internal.compiler.lookup.LookupEnvironment;
+import org.rubypeople.rdt.internal.compiler.util.CompoundNameVector;
+import org.rubypeople.rdt.internal.compiler.util.HashtableOfObject;
+import org.rubypeople.rdt.internal.compiler.util.ObjectVector;
+import org.rubypeople.rdt.internal.compiler.util.SimpleNameVector;
+
+public class SourceModuleScope extends Scope {
+ public LookupEnvironment environment;
+ public ModuleDeclaration referenceContext;
+ public char[][] currentPackageName;
+ public HashtableOfObject typeOrPackageCache; // used in
+ // Scope.getTypeOrPackage()
+ private CompoundNameVector qualifiedReferences;
+ private SimpleNameVector simpleNameReferences;
+ private ObjectVector referencedTypes;
+ private ObjectVector referencedSuperTypes;
+ // HashtableOfType constantPoolNameUsage;
+ private int captureID = 1;
+
+ public SourceModuleScope(ModuleDeclaration unit, LookupEnvironment environment) {
+ super(COMPILATION_UNIT_SCOPE, null);
+ this.environment = environment;
+ this.referenceContext = unit;
+ unit.scope = this;
+ // this.currentPackageName = unit.currentPackage == null ?
+ // CharOperation.NO_CHAR_CHAR : unit.currentPackage.tokens;
+ // if (compilerOptions().produceReferenceInfo) {
+ this.qualifiedReferences = new CompoundNameVector();
+ this.simpleNameReferences = new SimpleNameVector();
+ this.referencedTypes = new ObjectVector();
+ this.referencedSuperTypes = new ObjectVector();
+ // } else {
+ // this.qualifiedReferences = null; // used to test if dependencies
+ // should be recorded
+ // this.simpleNameReferences = null;
+ // this.referencedTypes = null;
+ // this.referencedSuperTypes = null;
+ // }
+ }
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/TypeConstants.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/TypeConstants.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/TypeConstants.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.lookup;
+
+// TODO should rename into TypeNames (once extracted last non name constants)
+public interface TypeConstants {
+
+ // Constants used to perform bound checks
+ int OK = 0;
+ int UNCHECKED = 1;
+ int MISMATCH = 2;
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/TypeScope.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/TypeScope.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/env/lookup/TypeScope.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.lookup;
+
+public class TypeScope extends Scope {
+
+ public TypeDeclaration referenceContext;
+
+ public TypeScope(Scope parent, TypeDeclaration context) {
+ super(CLASS_SCOPE, parent);
+ this.referenceContext = context;
+ }
+
+ /* Answer the reference type of this scope.
+ * It is the nearest enclosing type of this scope.
+ */
+ public TypeDeclaration referenceType() {
+ return referenceContext;
+ }
+
+ public String toString() {
+ if (referenceContext != null)
+ return "--- Class Scope ---\n\n";
+ return "--- Class Scope ---\n\n Binding not initialized" ; //$NON-NLS-1$
+ }
+}
\ No newline at end of file
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/lookup/LookupEnvironment.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/lookup/LookupEnvironment.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/lookup/LookupEnvironment.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,17 @@
+package org.rubypeople.rdt.internal.compiler.lookup;
+
+import org.rubypeople.rdt.internal.compiler.env.AccessRestriction;
+import org.rubypeople.rdt.internal.compiler.env.lookup.SourceModuleScope;
+
+public class LookupEnvironment {
+ public LookupEnvironment(ITypeRequestor typeRequestor, INameEnvironment nameEnvironment) {
+ // TODO Auto-generated constructor stub
+ }
+
+ public void reset() {}
+
+ public void buildTypeScope(ModuleDeclaration unit, AccessRestriction accessRestriction) {
+ SourceModuleScope scope = new SourceModuleScope(unit, this);
+ //TODO: Add other bindings build..
+ }
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/CompoundNameVector.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/CompoundNameVector.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/CompoundNameVector.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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;
+
+import org.rubypeople.rdt.internal.core.util.CharOperation;
+
+public final class CompoundNameVector {
+ static int INITIAL_SIZE = 10;
+
+ public int size;
+ int maxSize;
+ char[][][] elements;
+public CompoundNameVector() {
+ maxSize = INITIAL_SIZE;
+ size = 0;
+ elements = new char[maxSize][][];
+}
+public void add(char[][] newElement) {
+ if (size == maxSize) // knows that size starts <= maxSize
+ System.arraycopy(elements, 0, (elements = new char[maxSize *= 2][][]), 0, size);
+ elements[size++] = newElement;
+}
+public void addAll(char[][][] newElements) {
+ if (size + newElements.length >= maxSize) {
+ maxSize = size + newElements.length; // assume no more elements will be added
+ System.arraycopy(elements, 0, (elements = new char[maxSize][][]), 0, size);
+ }
+ System.arraycopy(newElements, 0, elements, size, newElements.length);
+ size += newElements.length;
+}
+public boolean contains(char[][] element) {
+ for (int i = size; --i >= 0;)
+ if (CharOperation.equals(element, elements[i]))
+ return true;
+ return false;
+}
+public char[][] elementAt(int index) {
+ return elements[index];
+}
+public char[][] remove(char[][] element) {
+ // assumes only one occurrence of the element exists
+ for (int i = size; --i >= 0;)
+ if (element == elements[i]) {
+ // shift the remaining elements down one spot
+ System.arraycopy(elements, i + 1, elements, i, --size - i);
+ elements[size] = null;
+ return element;
+ }
+ return null;
+}
+public void removeAll() {
+ for (int i = size; --i >= 0;)
+ elements[i] = null;
+ size = 0;
+}
+public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < size; i++) {
+ buffer.append(CharOperation.toString(elements[i])).append("\n"); //$NON-NLS-1$
+ }
+ return buffer.toString();
+}
+}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/SimpleNameVector.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/SimpleNameVector.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/compiler/util/SimpleNameVector.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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;
+
+import org.rubypeople.rdt.internal.core.util.CharOperation;
+
+public final class SimpleNameVector {
+
+ static int INITIAL_SIZE = 10;
+
+ public int size;
+ int maxSize;
+ char[][] elements;
+
+ public SimpleNameVector() {
+
+ this.maxSize = INITIAL_SIZE;
+ this.size = 0;
+ this.elements = new char[this.maxSize][];
+ }
+
+ public void add(char[] newElement) {
+
+ if (this.size == this.maxSize) // knows that size starts <= maxSize
+ System.arraycopy(this.elements, 0, (this.elements = new char[this.maxSize *= 2][]), 0, this.size);
+ this.elements[size++] = newElement;
+ }
+
+ public void addAll(char[][] newElements) {
+
+ if (this.size + newElements.length >= this.maxSize) {
+ this.maxSize = this.size + newElements.length; // assume no more elements will be added
+ System.arraycopy(this.elements, 0, (this.elements = new char[this.maxSize][]), 0, this.size);
+ }
+ System.arraycopy(newElements, 0, this.elements, this.size, newElements.length);
+ this.size += newElements.length;
+ }
+
+ public void copyInto(Object[] targetArray){
+
+ System.arraycopy(this.elements, 0, targetArray, 0, this.size);
+ }
+
+ public boolean contains(char[] element) {
+
+ for (int i = this.size; --i >= 0;)
+ if (CharOperation.equals(element, this.elements[i]))
+ return true;
+ return false;
+ }
+
+ public char[] elementAt(int index) {
+ return this.elements[index];
+ }
+
+ public char[] remove(char[] element) {
+
+ // assumes only one occurrence of the element exists
+ for (int i = this.size; --i >= 0;)
+ if (element == this.elements[i]) {
+ // shift the remaining elements down one spot
+ System.arraycopy(this.elements, i + 1, this.elements, i, --this.size - i);
+ this.elements[this.size] = null;
+ return element;
+ }
+ return null;
+ }
+
+ public void removeAll() {
+
+ for (int i = this.size; --i >= 0;)
+ this.elements[i] = null;
+ this.size = 0;
+ }
+
+ public int size(){
+
+ return this.size;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ for (int i = 0; i < this.size; i++) {
+ buffer.append(this.elements[i]).append("\n"); //$NON-NLS-1$
+ }
+ return buffer.toString();
+ }
+}
Modified: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/BasicSearchEngine.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/BasicSearchEngine.java 2007-03-13 18:00:18 UTC (rev 2145)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/BasicSearchEngine.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -7,6 +7,8 @@
public class BasicSearchEngine {
+ public static final boolean VERBOSE = false;
+
/**
* @see SearchEngine#createWorkspaceScope() for detailed comment.
*/
Modified: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/RubySearchDocument.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/RubySearchDocument.java 2007-03-13 18:00:18 UTC (rev 2145)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/RubySearchDocument.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -1,13 +1,19 @@
package org.rubypeople.rdt.internal.core.search;
+import org.eclipse.core.resources.IFile;
import org.rubypeople.rdt.core.search.SearchDocument;
+import org.rubypeople.rdt.core.search.SearchParticipant;
public class RubySearchDocument extends SearchDocument {
- public RubySearchDocument(String documentPath, RubySearchParticipant participant) {
+ private IFile file;
+ protected byte[] byteContents;
+ protected char[] charContents;
+
+ public RubySearchDocument(String documentPath, SearchParticipant participant) {
super(documentPath, participant);
}
-
+
@Override
public byte[] getByteContents() {
// TODO Auto-generated method stub
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:00:18 UTC (rev 2145)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/MatchLocator.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -1,12 +1,28 @@
package org.rubypeople.rdt.internal.core.search.matching;
+import java.util.ArrayList;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.core.search.IRubySearchScope;
+import org.rubypeople.rdt.core.search.SearchDocument;
+import org.rubypeople.rdt.core.search.SearchParticipant;
import org.rubypeople.rdt.core.search.SearchPattern;
import org.rubypeople.rdt.core.search.SearchRequestor;
+import org.rubypeople.rdt.internal.compiler.util.SimpleLookupTable;
import org.rubypeople.rdt.internal.core.ExternalSourceFolderRoot;
+import org.rubypeople.rdt.internal.core.Openable;
+import org.rubypeople.rdt.internal.core.RubyModelManager;
+import org.rubypeople.rdt.internal.core.RubyProject;
+import org.rubypeople.rdt.internal.core.RubyScript;
+import org.rubypeople.rdt.internal.core.search.BasicSearchEngine;
+import org.rubypeople.rdt.internal.core.search.RubySearchDocument;
+import org.rubypeople.rdt.internal.core.util.Util;
public class MatchLocator {
@@ -18,6 +34,25 @@
public IRubySearchScope scope;
public IProgressMonitor progressMonitor;
+ public org.rubypeople.rdt.core.IRubyScript[] workingCopies;
+ public HandleFactory handleFactory;
+
+// Progress information
+ int progressStep;
+ int progressWorked;
+
+ public static class WorkingCopyDocument extends RubySearchDocument {
+ public org.rubypeople.rdt.core.IRubyScript workingCopy;
+ WorkingCopyDocument(org.rubypeople.rdt.core.IRubyScript workingCopy, SearchParticipant participant) {
+ super(workingCopy.getPath().toString(), participant);
+ this.charContents = ((RubyScript)workingCopy).getContents();
+ this.workingCopy = workingCopy;
+ }
+ public String toString() {
+ return "WorkingCopyDocument for " + getPath(); //$NON-NLS-1$
+ }
+ }
+
public static IRubyElement projectOrJarFocus(InternalSearchPattern pattern) {
return pattern == null || pattern.focus == null ? null : getProjectOrJar(pattern.focus);
}
@@ -47,4 +82,136 @@
this.progressMonitor = progressMonitor;
}
+ /**
+ * Locate the matches in the given files and report them using the search requestor.
+ */
+ public void locateMatches(SearchDocument[] searchDocuments) throws CoreException {
+ int docsLength = searchDocuments.length;
+ if (BasicSearchEngine.VERBOSE) {
+ System.out.println("Locating matches in documents ["); //$NON-NLS-1$
+ for (int i = 0; i < docsLength; i++)
+ System.out.println("\t" + searchDocuments[i]); //$NON-NLS-1$
+ System.out.println("]"); //$NON-NLS-1$
+ }
+
+ // init infos for progress increasing
+ int n = docsLength<1000 ? Math.min(Math.max(docsLength/200+1, 2),4) : 5 *(docsLength/1000);
+ this.progressStep = docsLength < n ? 1 : docsLength / n; // step should not be 0
+ this.progressWorked = 0;
+
+ // extract working copies
+ ArrayList copies = new ArrayList();
+ for (int i = 0; i < docsLength; i++) {
+ SearchDocument document = searchDocuments[i];
+ if (document instanceof WorkingCopyDocument) {
+ copies.add(((WorkingCopyDocument)document).workingCopy);
+ }
+ }
+ int copiesLength = copies.size();
+ this.workingCopies = new org.rubypeople.rdt.core.IRubyScript[copiesLength];
+ copies.toArray(this.workingCopies);
+
+ RubyModelManager manager = RubyModelManager.getRubyModelManager();
+ this.bindings = new SimpleLookupTable();
+ try {
+ // optimize access to zip files during search operation
+ manager.cacheZipFiles();
+
+ // initialize handle factory (used as a cache of handles so as to optimize space)
+ if (this.handleFactory == null)
+ this.handleFactory = new HandleFactory();
+
+ if (this.progressMonitor != null) {
+ this.progressMonitor.beginTask("", searchDocuments.length); //$NON-NLS-1$
+ }
+
+ // initialize pattern for polymorphic search (ie. method reference pattern)
+ this.patternLocator.initializePolymorphicSearch(this);
+
+ RubyProject previousJavaProject = null;
+ PossibleMatchSet matchSet = new PossibleMatchSet();
+ Util.sort(searchDocuments, new Util.Comparer() {
+ public int compare(Object a, Object b) {
+ return ((SearchDocument)a).getPath().compareTo(((SearchDocument)b).getPath());
+ }
+ });
+ int displayed = 0; // progress worked displayed
+ String previousPath = null;
+ for (int i = 0; i < docsLength; i++) {
+ if (this.progressMonitor != null && this.progressMonitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+
+ // skip duplicate paths
+ SearchDocument searchDocument = searchDocuments[i];
+ searchDocuments[i] = null; // free current document
+ String pathString = searchDocument.getPath();
+ if (i > 0 && pathString.equals(previousPath)) {
+ if (this.progressMonitor != null) {
+ this.progressWorked++;
+ if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
+ }
+ displayed++;
+ continue;
+ }
+ previousPath = pathString;
+
+ Openable openable;
+ org.rubypeople.rdt.core.IRubyScript workingCopy = null;
+ if (searchDocument instanceof WorkingCopyDocument) {
+ workingCopy = ((WorkingCopyDocument)searchDocument).workingCopy;
+ openable = (Openable) workingCopy;
+ } else {
+ openable = this.handleFactory.createOpenable(pathString, this.scope);
+ }
+ if (openable == null) {
+ if (this.progressMonitor != null) {
+ this.progressWorked++;
+ if ((this.progressWorked%this.progressStep)==0) this.progressMonitor.worked(this.progressStep);
+ }
+ displayed++;
+ continue; // match is outside classpath
+ }
+
+ // create new parser and lookup environment if this is a new project
+ IResource resource = null;
+ RubyProject javaProject = (RubyProject) openable.getRubyProject();
+ resource = workingCopy != null ? workingCopy.getResource() : openable.getResource();
+ if (resource == null)
+ resource = javaProject.getProject(); // case of a file in an external jar
+ if (!javaProject.equals(previousJavaProject)) {
+ // locate matches in previous project
+ if (previousJavaProject != null) {
+ try {
+ locateMatches(previousJavaProject, matchSet, i-displayed);
+ displayed = i;
+ } catch (RubyModelException e) {
+ // problem with classpath in this project -> skip it
+ }
+ matchSet.reset();
+ }
+ previousJavaProject = javaProject;
+ }
+ matchSet.add(new PossibleMatch(this, resource, openable, searchDocument, ((InternalSearchPattern) this.pattern).mustResolve));
+ }
+
+ // last project
+ if (previousJavaProject != null) {
+ try {
+ locateMatches(previousJavaProject, matchSet, docsLength-displayed);
+ } catch (RubyModelException e) {
+ // problem with classpath in last project -> ignore
+ }
+ }
+
+ if (this.progressMonitor != null)
+ this.progressMonitor.done();
+ } finally {
+ if (this.nameEnvironment != null)
+ this.nameEnvironment.cleanup();
+ manager.flushZipFiles();
+ this.bindings = null;
+ }
+ }
+
}
Modified: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PatternLocator.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PatternLocator.java 2007-03-13 18:00:18 UTC (rev 2145)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/PatternLocator.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -25,8 +25,8 @@
switch (((InternalSearchPattern)pattern).kind) {
case IIndexConstants.PKG_REF_PATTERN :
return new PackageReferenceLocator((PackageReferencePattern) pattern);
- case IIndexConstants.PKG_DECL_PATTERN :
- return new PackageDeclarationLocator((PackageDeclarationPattern) pattern);
+// case IIndexConstants.PKG_DECL_PATTERN :
+// return new PackageDeclarationLocator((PackageDeclarationPattern) pattern);
case IIndexConstants.TYPE_REF_PATTERN :
return new TypeReferenceLocator((TypeReferencePattern) pattern);
case IIndexConstants.TYPE_DECL_PATTERN :
@@ -43,8 +43,8 @@
return new OrLocator((OrPattern) pattern);
case IIndexConstants.LOCAL_VAR_PATTERN :
return new LocalVariableLocator((LocalVariablePattern) pattern);
- case IIndexConstants.TYPE_PARAM_PATTERN:
- return new TypeParameterLocator((TypeParameterPattern) pattern);
+// case IIndexConstants.TYPE_PARAM_PATTERN:
+// return new TypeParameterLocator((TypeParameterPattern) pattern);
}
return null;
}
Added: branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/HandleFactory.java
===================================================================
--- branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/HandleFactory.java (rev 0)
+++ branches/search_engine/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/HandleFactory.java 2007-03-13 18:16:58 UTC (rev 2146)
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * 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.util;
+
+import java.util.HashMap;
+import java.util.HashSet;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.rubypeople.rdt.core.ILoadpathEntry;
+import org.rubypeople.rdt.core.IMember;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.ISourceFolder;
+import org.rubypeople.rdt.core.ISourceFolderRoot;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyCore;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.core.search.IRubySearchScope;
+import org.rubypeople.rdt.internal.core.Openable;
+import org.rubypeople.rdt.internal.core.RubyModel;
+import org.rubypeople.rdt.internal.core.RubyModelManager;
+import org.rubypeople.rdt.internal.core.RubyProject;
+import org.rubypeople.rdt.internal.core.SourceFolderRoot;
+import org.rubypeople.rdt.internal.core.SourceRefElement;
+import org.rubypeople.rdt.internal.ti.Scope;
+
+import sun.reflect.generics.scope.ClassScope;
+import sun.reflect.generics.scope.MethodScope;
+
+/**
+ * Creates java element handles.
+ */
+public class HandleFactory {
+
+ /**
+ * Cache package fragment root information to optimize speed performance.
+ */
+ private String lastPkgFragmentRootPath;
+ private ISourceFolderRoot lastPkgFragmentRoot;
+
+ /**
+ * Cache package handles to optimize memory.
+ */
+ private HashtableOfArrayToObject packageHandles;
+
+ private RubyModel javaModel;
+
+ public HandleFactory() {
+ this.javaModel = RubyModelManager.getRubyModelManager().getRubyModel();
+ }
+
+
+ /**
+ * Creates an Openable handle from the given resource path.
+ * The resource path can be a path to a file in the workbench (eg. /Proj/com/ibm/jdt/core/HandleFactory.java)
+ * or a path to a file in a jar file - it then contains the path to the jar file and the path to the file in the jar
+ * (eg. c:/jdk1.2.2/jre/lib/rt.jar|java/lang/Object.class or /Proj/rt.jar|java/lang/Object.class)
+ * NOTE: This assumes that the resource path is the toString() of an IPath,
+ * in other words, it uses the IPath.SEPARATOR for file path
+ * and it uses '/' for entries in a zip file.
+ * If not null, uses the given scope as a hint for getting Ruby project handles.
+ */
+ public Openable createOpenable(String resourcePath, IRubySearchScope scope) {
+ int separatorIndex;
+ // path to a file in a directory
+ // Optimization: cache package fragment root handle and package handles
+ int rootPathLength = -1;
+ if (this.lastPkgFragmentRootPath == null
+ || !(resourcePath.startsWith(this.lastPkgFragmentRootPath)
+ && (rootPathLength = this.lastPkgFragmentRootPath.length()) > 0
+ && resourcePath.charAt(rootPathLength) == '/')) {
+ ISourceFolderRoot root= this.getPkgFragmentRoot(resourcePath);
+ if (root == null)
+ return null; // match is outside classpath
+ this.lastPkgFragmentRoot = root;
+ this.lastPkgFragmentRootPath = this.lastPkgFragmentRoot.getPath().toString();
+ this.packageHandles = new HashtableOfArrayToObject(5);
+ }
+ // create handle
+ resourcePath = resourcePath.substring(this.lastPkgFragmentRootPath.length() + 1);
+ String[] simpleNames = new Path(resourcePath).segments();
+ String[] pkgName;
+ int length = simpleNames.length-1;
+ if (length > 0) {
+ pkgName = new String[length];
+ System.arraycopy(simpleNames, 0, pkgName, 0, length);
+ } else {
+ pkgName = CharOperation.NO_STRINGS;
+ }
+ ISourceFolder pkgFragment= (ISourceFolder) this.packageHandles.get(pkgName);
+ if (pkgFragment == null) {
+ pkgFragment= ((SourceFolderRoot) this.lastPkgFragmentRoot).getSourceFolder(pkgName);
+ this.packageHandles.put(pkgName, pkgFragment);
+ }
+ String simpleName= simpleNames[length];
+ if (org.rubypeople.rdt.internal.core.util.Util.isRubyLikeFileName(simpleName)) {
+ IRubyScript unit= pkgFragment.getRubyScript(simpleName);
+ return (Openable) unit;
+ }
+ return null;
+ }
+
+ /**
+ * Returns a handle denoting the class member identified by its scope.
+ */
+ public IRubyElement createElement(ClassScope scope, IRubyScript unit, HashSet existingElements, HashMap knownScopes) {
+ return createElement(scope, scope.referenceContext.sourceStart, unit, existingElements, knownScopes);
+ }
+ /**
+ * Create handle by adding child to parent obtained by recursing into parent scopes.
+ */
+ private IRubyElement createElement(Scope scope, int elementPosition, IRubyScript unit, HashSet existingElements, HashMap knownScopes) {
+ IRubyElement newElement = (IRubyElement)knownScopes.get(scope);
+ if (newElement != null) return newElement;
+
+ switch(scope.kind) {
+ case Scope.COMPILATION_UNIT_SCOPE :
+ newElement = unit;
+ break;
+ case Scope.CLASS_SCOPE :
+ IRubyElement parentElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
+ switch (parentElement.getElementType()) {
+ case IRubyElement.COMPILATION_UNIT :
+ newElement = ((IRubyScript)parentElement).getType(new String(scope.enclosingSourceType().sourceName));
+ break;
+ case IRubyElement.TYPE :
+ newElement = ((IType)parentElement).getType(new String(scope.enclosingSourceType().sourceName));
+ break;
+ case IRubyElement.FIELD :
+ case IRubyElement.INITIALIZER :
+ case IRubyElement.METHOD :
+ IMember member = (IMember)parentElement;
+ if (member.isBinary()) {
+ return null;
+ } else {
+ newElement = member.getType(new String(scope.enclosingSourceType().sourceName), 1);
+ // increment occurrence count if collision is detected
+ if (newElement != null) {
+ while (!existingElements.add(newElement)) ((SourceRefElement)newElement).occurrenceCount++;
+ }
+ }
+ break;
+ }
+ if (newElement != null) {
+ knownScopes.put(scope, newElement);
+ }
+ break;
+ case Scope.METHOD_SCOPE :
+ IType parentType = (IType) createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
+ MethodScope methodScope = (MethodScope) scope;
+ if (methodScope.isInsideInitializer()) {
+ // inside field or initializer, must find proper one
+ TypeDeclaration type = methodScope.referenceType();
+ int occurenceCount = 1;
+ for (int i = 0, length = type.fields.length; i < length; i++) {
+ FieldDeclaration field = type.fields[i];
+ if (field.declarationSourceStart < elementPosition && field.declarationSourceEnd > elementPosition) {
+ switch (field.getKind()) {
+ case AbstractVariableDeclaration.FIELD :
+ case AbstractVariableDeclaration.ENUM_CONSTANT :
+ newElement = parentType.getField(new String(field.name));
+ break;
+ case AbstractVariableDeclaration.INITIALIZER :
+ newElement = parentType.getInitializer(occurenceCount);
+ break;
+ }
+ break;
+ } else if (field.getKind() == AbstractVariableDeclaration.INITIALIZER) {
+ occurenceCount++;
+ }
+ }
+ } else {
+ // method element
+ AbstractMethodDeclaration method = methodScope.referenceMethod();
+ newElement = parentType.getMethod(new String(method.selector), Util.typeParameterSignatures(method));
+ if (newElement != null) {
+ knownScopes.put(scope, newElement);
+ }
+ }
+ break;
+ case Scope.BLOCK_SCOPE :
+ // standard block, no element per se
+ newElement = createElement(scope.parent, elementPosition, unit, existingElements, knownScopes);
+ break;
+ }
+ return newElement;
+ }
+ /**
+ * Returns the package fragment root that corresponds to the given jar path.
+ * See createOpenable(...) for the format of the jar path string.
+ * If not null, uses the given scope as a hint for getting Ruby project handles.
+ */
+ private ISourceFolderRoot getJarPkgFragmentRoot(String jarPathString, IRubySearchScope scope) {
+
+ IPath jarPath= new Path(jarPathString);
+
+ Object target = RubyModel.getTarget(ResourcesPlugin.getWorkspace().getRoot(), jarPath, false);
+ if (target instanceof IFile) {
+ // internal jar: is it on the classpath of its project?
+ // e.g. org.eclipse.swt.win32/ws/win32/swt.jar
+ // is NOT on the classpath of org.eclipse.swt.win32
+ IFile jarFile = (IFile)target;
+ RubyProject javaProject = (RubyProject) this.javaModel.getRubyProject(jarFile);
+ ILoadpathEntry[] classpathEntries;
+ try {
+ classpathEntries = javaProject.getResolvedLoadpath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
+ for (int j= 0, entryCount= classpathEntries.length; j < entryCount; j++) {
+ if (classpathEntries[j].getPath().equals(jarPath)) {
+ return javaProject.getSourceFolderRoot(jarFile);
+ }
+ }
+ } catch (RubyModelException e) {
+ // ignore and try to find another project
+ }
+ }
+
+ // walk projects in the scope and find the first one that has the given jar path in its classpath
+ IRubyProject[] projects;
+ if (scope != null) {
+ IPath[] enclosingProjectsAndJars = scope.enclosingProjectsAndJars();
+ int length = enclosingProjectsAndJars.length;
+ projects = new IRubyProject[length];
+ int index = 0;
+ for (int i = 0; i < length; i++) {
+ IPath path = enclosingProjectsAndJars[i];
+ if (!org.rubypeople.rdt.internal.compiler.util.Util.isArchiveFileName(path.lastSegment())) {
+ projects[index++] = this.javaModel.getRubyProject(path.segment(0));
+ }
+ }
+ if (index < length) {
+ System.arraycopy(projects, 0, projects = new IRubyProject[index], 0, index);
+ }
+ ISourceFolderRoot root = getJarPkgFragmentRoot(jarPath, target, projects);
+ if (root != null) {
+ return root;
+ }
+ }
+
+ // not found in the scope, walk all projects
+ try {
+ projects = this.javaModel.getRubyProjects();
+ } catch (RubyModelException e) {
+ // java model is not accessible
+ return null;
+ }
+ return getJarPkgFragmentRoot(jarPath, target, projects);
+ }
+
+ private ISourceFolderRoot getJarPkgFragmentRoot(
+ IPath jarPath,
+ Object target,
+ IRubyProject[] projects) {
+ for (int i= 0, projectCount= projects.length; i < projectCount; i++) {
+ try {
+ RubyProject javaProject= (RubyProject)projects[i];
+ ILoadpathEntry[] classpathEntries= javaProject.getResolvedLoadpath(true/*ignoreUnresolvedEntry*/, false/*don't generateMarkerOnError*/, false/*don't returnResolutionInProgress*/);
+ for (int j= 0, entryCount= classpathEntries.length; j < entryCount; j++) {
+ if (classpathEntries[j].getPath().equals(jarPath)) {
+ if (target instanceof IFile) {
+ // internal jar
+ return javaProject.getSourceFolderRoot((IFile)target);
+ } else {
+ // external jar
+ return javaProject.getSourceFolderRoot0(jarPath);
+ }
+ }
+ }
+ } catch (RubyModelException e) {
+ // RubyModelException from getResolvedClasspath - a problem occured while accessing project: nothing we can do, ignore
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the package fragment root that contains the given resource path.
+ */
+ private ISourceFolderRoot getPkgFragmentRoot(String pathString) {
+
+ IPath path= new Path(pathString);
+ IProject[] projects= ResourcesPlugin.getWorkspace().getRoot().getProjects();
+ for (int i= 0, max= projects.length; i < max; i++) {
+ try {
+ IProject project = projects[i];
+ if (!project.isAccessible()
+ || !project.hasNature(RubyCore.NATURE_ID)) continue;
+ IRubyProject javaProject= this.javaModel.getRubyProject(project);
+ ISourceFolderRoot[] roots= javaProject.getSourceFolderRoots();
+ for (int j= 0, rootCount= roots.length; j < rootCount; j++) {
+ SourceFolderRoot root= (SourceFolderRoot)roots[j];
+ if (root.getPath().isPrefixOf(path) && !Util.isExcluded(path, root.fullInclusionPatternChars(), root.fullExclusionPatternChars(), false)) {
+ return root;
+ }
+ }
+ } catch (CoreException e) {
+ // CoreException from hasNature - should not happen since we check that the project is accessible
+ // RubyModelException from getSourceFolderRoots - a problem occured while accessing project: nothing we can do, ignore
+ }
+ }
+ return null;
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|