You can subscribe to this list here.
| 2005 |
Jan
|
Feb
|
Mar
(41) |
Apr
(9) |
May
|
Jun
|
Jul
(39) |
Aug
(38) |
Sep
(135) |
Oct
(220) |
Nov
(75) |
Dec
(74) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2006 |
Jan
(44) |
Feb
(160) |
Mar
(49) |
Apr
(69) |
May
(40) |
Jun
(52) |
Jul
(47) |
Aug
(51) |
Sep
(19) |
Oct
(22) |
Nov
(36) |
Dec
(76) |
| 2007 |
Jan
(154) |
Feb
(165) |
Mar
(186) |
Apr
(143) |
May
(175) |
Jun
(133) |
Jul
(203) |
Aug
(177) |
Sep
(136) |
Oct
|
Nov
|
Dec
|
|
From: <caw...@us...> - 2007-07-17 16:42:40
|
Revision: 2772
http://svn.sourceforge.net/rubyeclipse/?rev=2772&view=rev
Author: cawilliams
Date: 2007-07-17 09:42:38 -0700 (Tue, 17 Jul 2007)
Log Message:
-----------
fix broken code
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyProject.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/messages.properties
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyProject.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyProject.java 2007-07-17 16:17:07 UTC (rev 2771)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyProject.java 2007-07-17 16:42:38 UTC (rev 2772)
@@ -46,6 +46,7 @@
import org.rubypeople.rdt.core.ILoadpathContainer;
import org.rubypeople.rdt.core.ILoadpathEntry;
import org.rubypeople.rdt.core.IParent;
+import org.rubypeople.rdt.core.IRegion;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IRubyModelMarker;
import org.rubypeople.rdt.core.IRubyModelStatus;
@@ -55,6 +56,7 @@
import org.rubypeople.rdt.core.ISourceFolder;
import org.rubypeople.rdt.core.ISourceFolderRoot;
import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.ITypeHierarchy;
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.core.WorkingCopyOwner;
@@ -2459,4 +2461,33 @@
protected char getHandleMementoDelimiter() {
return JEM_RUBYPROJECT;
}
+
+ /**
+ * @see IRubyProject
+ */
+ public ITypeHierarchy newTypeHierarchy(
+ IRegion region,
+ IProgressMonitor monitor)
+ throws RubyModelException {
+ return newTypeHierarchy(region, DefaultWorkingCopyOwner.PRIMARY, monitor);
+ }
+
+ /**
+ * @see IJavaProject
+ */
+ public ITypeHierarchy newTypeHierarchy(
+ IRegion region,
+ WorkingCopyOwner owner,
+ IProgressMonitor monitor)
+ throws RubyModelException {
+
+ if (region == null) {
+ throw new IllegalArgumentException(Messages.hierarchy_nullRegion);
+ }
+ IRubyScript[] workingCopies = RubyModelManager.getRubyModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
+ CreateTypeHierarchyOperation op =
+ new CreateTypeHierarchyOperation(region, workingCopies, null, true);
+ op.runOperation(monitor);
+ return op.getResult();
+ }
}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java 2007-07-17 16:17:07 UTC (rev 2771)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java 2007-07-17 16:42:38 UTC (rev 2772)
@@ -163,6 +163,7 @@
public static String engine_searching;
public static String hierarchy_creating;
public static String hierarchy_creatingOnType;
+ public static String hierarchy_nullRegion;
static {
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/messages.properties
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/messages.properties 2007-07-17 16:17:07 UTC (rev 2771)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/messages.properties 2007-07-17 16:42:38 UTC (rev 2772)
@@ -9,8 +9,10 @@
# IBM Corporation - initial API and implementation
###############################################################################
-### JavaModel messages_
+### RubyModel messages_
+hierarchy_nullRegion= Region cannot be null
+
### ruby element
element_doesNotExist = {0} does not exist
element_notOnClasspath = {0} is not on its project's build path
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-17 16:17:11
|
Revision: 2771
http://svn.sourceforge.net/rubyeclipse/?rev=2771&view=rev
Author: cawilliams
Date: 2007-07-17 09:17:07 -0700 (Tue, 17 Jul 2007)
Log Message:
-----------
nother part of fix for #5032 - set focus to gem table when RubyGems view gets focus
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/ui/gems/GemsView.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/ui/gems/GemsView.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/ui/gems/GemsView.java 2007-07-17 14:38:30 UTC (rev 2770)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/ui/gems/GemsView.java 2007-07-17 16:17:07 UTC (rev 2771)
@@ -86,7 +86,7 @@
@Override
public void setFocus() {
- // do nothing
+ gemViewer.getTable().setFocus();
}
/**
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-17 14:38:33
|
Revision: 2770
http://svn.sourceforge.net/rubyeclipse/?rev=2770&view=rev
Author: cawilliams
Date: 2007-07-17 07:38:30 -0700 (Tue, 17 Jul 2007)
Log Message:
-----------
more type hierarchy work
Added Paths:
-----------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/ITypeHierarchyLifeCycleListener.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/ITypeHierarchyLifeCycleListener.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/ITypeHierarchyLifeCycleListener.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/ITypeHierarchyLifeCycleListener.java 2007-07-17 14:38:30 UTC (rev 2770)
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.typehierarchy;
+
+import org.rubypeople.rdt.core.IType;
+
+
+/**
+ * Used by the TypeHierarchyLifeCycle to inform listeners about a change in the
+ * type hierarchy
+ */
+public interface ITypeHierarchyLifeCycleListener {
+
+ /**
+ * A Java element changed.
+ */
+ void typeHierarchyChanged(TypeHierarchyLifeCycle typeHierarchyProvider, IType[] changedTypes);
+
+}
Property changes on: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/ITypeHierarchyLifeCycleListener.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java 2007-07-17 14:38:30 UTC (rev 2770)
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui.typehierarchy;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.rubypeople.rdt.core.ElementChangedEvent;
+import org.rubypeople.rdt.core.IElementChangedListener;
+import org.rubypeople.rdt.core.IRegion;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyElementDelta;
+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.ITypeHierarchy;
+import org.rubypeople.rdt.core.ITypeHierarchyChangedListener;
+import org.rubypeople.rdt.core.RubyCore;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.corext.util.RubyModelUtil;
+import org.rubypeople.rdt.internal.ui.RubyPlugin;
+
+/**
+ * Manages a type hierarchy, to keep it refreshed, and to allow it to be shared.
+ */
+public class TypeHierarchyLifeCycle implements ITypeHierarchyChangedListener, IElementChangedListener {
+
+ private boolean fHierarchyRefreshNeeded;
+ private ITypeHierarchy fHierarchy;
+ private IRubyElement fInputElement;
+ private boolean fIsSuperTypesOnly;
+
+ private List fChangeListeners;
+
+ public TypeHierarchyLifeCycle() {
+ this(false);
+ }
+
+ public TypeHierarchyLifeCycle(boolean isSuperTypesOnly) {
+ fHierarchy= null;
+ fInputElement= null;
+ fIsSuperTypesOnly= isSuperTypesOnly;
+ fChangeListeners= new ArrayList(2);
+ }
+
+ public ITypeHierarchy getHierarchy() {
+ return fHierarchy;
+ }
+
+ public IRubyElement getInputElement() {
+ return fInputElement;
+ }
+
+
+ public void freeHierarchy() {
+ if (fHierarchy != null) {
+ fHierarchy.removeTypeHierarchyChangedListener(this);
+ RubyCore.removeElementChangedListener(this);
+ fHierarchy= null;
+ fInputElement= null;
+ }
+ }
+
+ public void removeChangedListener(ITypeHierarchyLifeCycleListener listener) {
+ fChangeListeners.remove(listener);
+ }
+
+ public void addChangedListener(ITypeHierarchyLifeCycleListener listener) {
+ if (!fChangeListeners.contains(listener)) {
+ fChangeListeners.add(listener);
+ }
+ }
+
+ private void fireChange(IType[] changedTypes) {
+ for (int i= fChangeListeners.size()-1; i>=0; i--) {
+ ITypeHierarchyLifeCycleListener curr= (ITypeHierarchyLifeCycleListener) fChangeListeners.get(i);
+ curr.typeHierarchyChanged(this, changedTypes);
+ }
+ }
+
+ public void ensureRefreshedTypeHierarchy(final IRubyElement element, IRunnableContext context) throws InvocationTargetException, InterruptedException {
+ if (element == null || !element.exists()) {
+ freeHierarchy();
+ return;
+ }
+ boolean hierachyCreationNeeded= (fHierarchy == null || !element.equals(fInputElement));
+
+ if (hierachyCreationNeeded || fHierarchyRefreshNeeded) {
+
+ IRunnableWithProgress op= new IRunnableWithProgress() {
+ public void run(IProgressMonitor pm) throws InvocationTargetException, InterruptedException {
+ try {
+ doHierarchyRefresh(element, pm);
+ } catch (RubyModelException e) {
+ throw new InvocationTargetException(e);
+ } catch (OperationCanceledException e) {
+ throw new InterruptedException();
+ }
+ }
+ };
+ fHierarchyRefreshNeeded= true;
+ context.run(true, true, op);
+ fHierarchyRefreshNeeded= false;
+ }
+ }
+
+ private ITypeHierarchy createTypeHierarchy(IRubyElement element, IProgressMonitor pm) throws RubyModelException {
+ if (element.getElementType() == IRubyElement.TYPE) {
+ IType type= (IType) element;
+ if (fIsSuperTypesOnly) {
+ return type.newSupertypeHierarchy(pm);
+ } else {
+ return type.newTypeHierarchy(pm);
+ }
+ } else {
+ IRegion region= RubyCore.newRegion();
+ if (element.getElementType() == IRubyElement.RUBY_PROJECT) {
+ // for projects only add the contained source folders
+ ISourceFolderRoot[] roots= ((IRubyProject) element).getSourceFolderRoots();
+ for (int i= 0; i < roots.length; i++) {
+ if (!roots[i].isExternal()) {
+ region.add(roots[i]);
+ }
+ }
+ } else if (element.getElementType() == IRubyElement.SOURCE_FOLDER) {
+ ISourceFolderRoot[] roots= element.getRubyProject().getSourceFolderRoots();
+ String name= element.getElementName();
+ for (int i= 0; i < roots.length; i++) {
+ ISourceFolder pack= roots[i].getSourceFolder(name);
+ if (pack.exists()) {
+ region.add(pack);
+ }
+ }
+ } else {
+ region.add(element);
+ }
+ IRubyProject jproject= element.getRubyProject();
+ return jproject.newTypeHierarchy(region, pm);
+ }
+ }
+
+
+ public synchronized void doHierarchyRefresh(IRubyElement element, IProgressMonitor pm) throws RubyModelException {
+ boolean hierachyCreationNeeded= (fHierarchy == null || !element.equals(fInputElement));
+ // to ensure the order of the two listeners always remove / add listeners on operations
+ // on type hierarchies
+ if (fHierarchy != null) {
+ fHierarchy.removeTypeHierarchyChangedListener(this);
+ RubyCore.removeElementChangedListener(this);
+ }
+ if (hierachyCreationNeeded) {
+ fHierarchy= createTypeHierarchy(element, pm);
+ if (pm != null && pm.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ fInputElement= element;
+ } else {
+ fHierarchy.refresh(pm);
+ }
+ fHierarchy.addTypeHierarchyChangedListener(this);
+ RubyCore.addElementChangedListener(this);
+ fHierarchyRefreshNeeded= false;
+ }
+
+ /*
+ * @see ITypeHierarchyChangedListener#typeHierarchyChanged
+ */
+ public void typeHierarchyChanged(ITypeHierarchy typeHierarchy) {
+ fHierarchyRefreshNeeded= true;
+ fireChange(null);
+ }
+
+ /*
+ * @see IElementChangedListener#elementChanged(ElementChangedEvent)
+ */
+ public void elementChanged(ElementChangedEvent event) {
+ if (fChangeListeners.isEmpty()) {
+ return;
+ }
+
+ if (fHierarchyRefreshNeeded) {
+ return;
+ } else {
+ ArrayList changedTypes= new ArrayList();
+ processDelta(event.getDelta(), changedTypes);
+ if (changedTypes.size() > 0) {
+ fireChange((IType[]) changedTypes.toArray(new IType[changedTypes.size()]));
+ }
+ }
+ }
+
+ /*
+ * Assume that the hierarchy is intact (no refresh needed)
+ */
+ private void processDelta(IRubyElementDelta delta, ArrayList changedTypes) {
+ IRubyElement element= delta.getElement();
+ switch (element.getElementType()) {
+ case IRubyElement.TYPE:
+ processTypeDelta((IType) element, changedTypes);
+ processChildrenDelta(delta, changedTypes); // (inner types)
+ break;
+ case IRubyElement.RUBY_MODEL:
+ case IRubyElement.RUBY_PROJECT:
+ case IRubyElement.SOURCE_FOLDER_ROOT:
+ case IRubyElement.SOURCE_FOLDER:
+ processChildrenDelta(delta, changedTypes);
+ break;
+ case IRubyElement.SCRIPT:
+ IRubyScript cu= (IRubyScript)element;
+ if (!RubyModelUtil.isPrimary(cu)) {
+ return;
+ }
+
+ if (delta.getKind() == IRubyElementDelta.CHANGED && isPossibleStructuralChange(delta.getFlags())) {
+ try {
+ if (cu.exists()) {
+ IType[] types= cu.getAllTypes();
+ for (int i= 0; i < types.length; i++) {
+ processTypeDelta(types[i], changedTypes);
+ }
+ }
+ } catch (RubyModelException e) {
+ RubyPlugin.log(e);
+ }
+ } else {
+ processChildrenDelta(delta, changedTypes);
+ }
+ break;
+ }
+ }
+
+ private boolean isPossibleStructuralChange(int flags) {
+ return (flags & (IRubyElementDelta.F_CONTENT | IRubyElementDelta.F_FINE_GRAINED)) == IRubyElementDelta.F_CONTENT;
+ }
+
+ private void processTypeDelta(IType type, ArrayList changedTypes) {
+ if (getHierarchy().contains(type)) {
+ changedTypes.add(type);
+ }
+ }
+
+ private void processChildrenDelta(IRubyElementDelta delta, ArrayList changedTypes) {
+ IRubyElementDelta[] children= delta.getAffectedChildren();
+ for (int i= 0; i < children.length; i++) {
+ processDelta(children[i], changedTypes); // recursive
+ }
+ }
+
+
+}
Property changes on: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/typehierarchy/TypeHierarchyLifeCycle.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-17 14:37:53
|
Revision: 2768
http://svn.sourceforge.net/rubyeclipse/?rev=2768&view=rev
Author: cawilliams
Date: 2007-07-17 07:37:49 -0700 (Tue, 17 Jul 2007)
Log Message:
-----------
more type hierarchy work
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IRubyProject.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IType.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyType.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyBuilder.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/CreateTypeHierarchyOperation.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IRubyProject.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IRubyProject.java 2007-07-16 17:16:44 UTC (rev 2767)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IRubyProject.java 2007-07-17 14:37:49 UTC (rev 2768)
@@ -182,4 +182,19 @@
* @since 1.0
*/
IType findType(String fullyQualifiedName, IProgressMonitor progressMonitor) throws RubyModelException;
+
+ /**
+ * Creates and returns a type hierarchy for all types in the given
+ * region, considering subtypes within that region.
+ *
+ * @param monitor the given progress monitor
+ * @param region the given region
+ * @exception RubyModelException if this element does not exist or if an
+ * exception occurs while accessing its corresponding resource
+ * @exception IllegalArgumentException if region is <code>null</code>
+ * @return a type hierarchy for all types in the given
+ * region, considering subtypes within that region
+ */
+ ITypeHierarchy newTypeHierarchy(IRegion region, IProgressMonitor monitor)
+ throws RubyModelException;
}
\ No newline at end of file
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IType.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IType.java 2007-07-16 17:16:44 UTC (rev 2767)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IType.java 2007-07-17 14:37:49 UTC (rev 2768)
@@ -25,7 +25,6 @@
package org.rubypeople.rdt.core;
import org.eclipse.core.runtime.IProgressMonitor;
-import org.rubypeople.rdt.internal.core.RubyMethod;
/**
* @author Chris
@@ -33,7 +32,7 @@
*/
public interface IType extends IRubyElement, IMember {
- public RubyMethod getMethod(String name, String[] parameterNames);
+ public IMethod getMethod(String name, String[] parameterNames);
/**
* Returns the methods and constructors declared by this type. For binary
@@ -199,4 +198,16 @@
*/
ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws RubyModelException;
+ /**
+ * Creates and returns a type hierarchy for this type containing
+ * this type, all of its supertypes, and all its subtypes in the workspace.
+ *
+ * @param monitor the given progress monitor
+ * @exception RubyModelException if this element does not exist or if an
+ * exception occurs while accessing its corresponding resource.
+ * @return a type hierarchy for this type containing
+ * this type, all of its supertypes, and all its subtypes in the workspace
+ */
+ ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws RubyModelException;
+
}
\ No newline at end of file
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java 2007-07-16 17:16:44 UTC (rev 2767)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java 2007-07-17 14:37:49 UTC (rev 2768)
@@ -47,8 +47,6 @@
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.FrameworkListener;
import org.rubypeople.rdt.core.search.IRubySearchConstants;
import org.rubypeople.rdt.core.search.SearchEngine;
import org.rubypeople.rdt.core.search.SearchMatch;
@@ -59,6 +57,7 @@
import org.rubypeople.rdt.internal.core.DefaultWorkingCopyOwner;
import org.rubypeople.rdt.internal.core.LoadpathAttribute;
import org.rubypeople.rdt.internal.core.LoadpathEntry;
+import org.rubypeople.rdt.internal.core.Region;
import org.rubypeople.rdt.internal.core.RubyCorePreferenceInitializer;
import org.rubypeople.rdt.internal.core.RubyModel;
import org.rubypeople.rdt.internal.core.RubyModelManager;
@@ -1469,4 +1468,13 @@
// ignore
}
}
+
+ /**
+ * Returns a new empty region.
+ *
+ * @return a new empty region
+ */
+ public static IRegion newRegion() {
+ return new Region();
+ }
}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/CreateTypeHierarchyOperation.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/CreateTypeHierarchyOperation.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/CreateTypeHierarchyOperation.java 2007-07-17 14:37:49 UTC (rev 2768)
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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;
+
+import org.rubypeople.rdt.core.IRegion;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyModelStatus;
+import org.rubypeople.rdt.core.IRubyModelStatusConstants;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.ITypeHierarchy;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.core.search.IRubySearchScope;
+import org.rubypeople.rdt.internal.core.hierarchy.RegionBasedTypeHierarchy;
+import org.rubypeople.rdt.internal.core.hierarchy.TypeHierarchy;
+
+/**
+ * This operation creates an <code>ITypeHierarchy</code> for a specific type within
+ * a specified region, or for all types within a region. The specified
+ * region limits the number of resolved subtypes (to the subset of
+ * types in the specified region). The resolved supertypes may go outside
+ * of the specified region in order to reach the root(s) of the type
+ * hierarchy. A Ruby Project is required to provide a context (classpath)
+ * to use while resolving supertypes and subtypes.
+ *
+ * @see ITypeHierarchy
+ */
+
+public class CreateTypeHierarchyOperation extends RubyModelOperation {
+ /**
+ * The generated type hierarchy
+ */
+ protected TypeHierarchy typeHierarchy;
+
+/**
+ * Constructs an operation to create a type hierarchy for the
+ * given type within the specified region, in the context of
+ * the given project.
+ */
+public CreateTypeHierarchyOperation(IRegion region, IRubyScript[] workingCopies, IType element, boolean computeSubtypes) {
+ super(element);
+ this.typeHierarchy = new RegionBasedTypeHierarchy(region, workingCopies, element, computeSubtypes);
+}
+/**
+ * Constructs an operation to create a type hierarchy for the
+ * given type and working copies.
+ */
+public CreateTypeHierarchyOperation(IType element, IRubyScript[] workingCopies, IRubySearchScope scope, boolean computeSubtypes) {
+ super(element);
+ IRubyScript[] copies;
+ if (workingCopies != null) {
+ int length = workingCopies.length;
+ copies = new IRubyScript[length];
+ System.arraycopy(workingCopies, 0, copies, 0, length);
+ } else {
+ copies = null;
+ }
+ this.typeHierarchy = new TypeHierarchy(element, copies, scope, computeSubtypes);
+}
+/**
+ * Constructs an operation to create a type hierarchy for the
+ * given type and working copies.
+ */
+public CreateTypeHierarchyOperation(IType element, IRubyScript[] workingCopies, IRubyProject project, boolean computeSubtypes) {
+ super(element);
+ IRubyScript[] copies;
+ if (workingCopies != null) {
+ int length = workingCopies.length;
+ copies = new IRubyScript[length];
+ System.arraycopy(workingCopies, 0, copies, 0, length);
+ } else {
+ copies = null;
+ }
+ this.typeHierarchy = new TypeHierarchy(element, copies, project, computeSubtypes);
+}
+/**
+ * Performs the operation - creates the type hierarchy
+ * @exception RubyModelException The operation has failed.
+ */
+protected void executeOperation() throws RubyModelException {
+ this.typeHierarchy.refresh(this);
+}
+/**
+ * Returns the generated type hierarchy.
+ */
+public ITypeHierarchy getResult() {
+ return this.typeHierarchy;
+}
+/**
+ * @see RubyModelOperation
+ */
+public boolean isReadOnly() {
+ return true;
+}
+/**
+ * Possible failures: <ul>
+ * <li>NO_ELEMENTS_TO_PROCESS - at least one of a type or region must
+ * be provided to generate a type hierarchy.
+ * <li>ELEMENT_NOT_PRESENT - the provided type or type's project does not exist
+ * </ul>
+ */
+public IRubyModelStatus verify() {
+ IRubyElement elementToProcess= getElementToProcess();
+ if (elementToProcess == null && !(this.typeHierarchy instanceof RegionBasedTypeHierarchy)) {
+ return new RubyModelStatus(IRubyModelStatusConstants.NO_ELEMENTS_TO_PROCESS);
+ }
+ if (elementToProcess != null && !elementToProcess.exists()) {
+ return new RubyModelStatus(IRubyModelStatusConstants.ELEMENT_DOES_NOT_EXIST, elementToProcess);
+ }
+ IRubyProject project = this.typeHierarchy.javaProject();
+ if (project != null && !project.exists()) {
+ return new RubyModelStatus(IRubyModelStatusConstants.ELEMENT_DOES_NOT_EXIST, project);
+ }
+ return RubyModelStatus.VERIFIED_OK;
+}
+}
Property changes on: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/CreateTypeHierarchyOperation.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyType.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyType.java 2007-07-16 17:16:44 UTC (rev 2767)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyType.java 2007-07-17 14:37:49 UTC (rev 2768)
@@ -38,6 +38,7 @@
import org.rubypeople.rdt.core.ITypeHierarchy;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.core.WorkingCopyOwner;
+import org.rubypeople.rdt.core.search.SearchEngine;
import org.rubypeople.rdt.internal.core.util.MementoTokenizer;
/**
@@ -112,7 +113,7 @@
return array;
}
- public RubyMethod getMethod(String name, String[] parameterNames) {
+ public IMethod getMethod(String name, String[] parameterNames) {
return new RubyMethod(this, name, parameterNames);
}
@@ -320,6 +321,15 @@
/**
* @see IType
*/
+ public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws RubyModelException {
+ CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, null, SearchEngine.createWorkspaceScope(), true);
+ op.runOperation(monitor);
+ return op.getResult();
+ }
+
+ /**
+ * @see IType
+ */
public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws RubyModelException {
return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor);
}
@@ -333,11 +343,9 @@
throws RubyModelException {
IRubyScript[] workingCopies = RubyModelManager.getRubyModelManager().getWorkingCopies(owner, true/*add primary working copies*/);
-// CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
-// op.runOperation(monitor);
-// return op.getResult();
- // XXX Implement!
- return null;
+ CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false);
+ op.runOperation(monitor);
+ return op.getResult();
}
}
\ No newline at end of file
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyBuilder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyBuilder.java 2007-07-16 17:16:44 UTC (rev 2767)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyBuilder.java 2007-07-17 14:37:49 UTC (rev 2768)
@@ -14,6 +14,8 @@
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
import org.rubypeople.rdt.core.IType;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.core.RubyElement;
@@ -165,4 +167,14 @@
this.hierarchy.addRootClass(focusType);
}
}
+
+ protected void worked(IProgressMonitor monitor, int work) {
+ if (monitor != null) {
+ if (monitor.isCanceled()) {
+ throw new OperationCanceledException();
+ } else {
+ monitor.worked(work);
+ }
+ }
+ }
}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java 2007-07-17 14:37:49 UTC (rev 2768)
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * 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.hierarchy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+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.RubyModelException;
+import org.rubypeople.rdt.internal.core.Openable;
+import org.rubypeople.rdt.internal.core.RubyProject;
+
+public class RegionBasedHierarchyBuilder extends HierarchyBuilder {
+
+ public RegionBasedHierarchyBuilder(TypeHierarchy hierarchy)
+ throws RubyModelException {
+
+ super(hierarchy);
+ }
+
+public void build(boolean computeSubtypes) {
+
+// RubyModelManager manager = RubyModelManager.getRubyModelManager();
+ try {
+ // optimize access to zip files while building hierarchy
+// manager.cacheZipFiles();
+
+ if (this.hierarchy.focusType == null || computeSubtypes) {
+ IProgressMonitor typeInRegionMonitor =
+ this.hierarchy.progressMonitor == null ?
+ null :
+ new SubProgressMonitor(this.hierarchy.progressMonitor, 30);
+ HashMap allOpenablesInRegion = determineOpenablesInRegion(typeInRegionMonitor);
+ this.hierarchy.initialize(allOpenablesInRegion.size());
+ IProgressMonitor buildMonitor =
+ this.hierarchy.progressMonitor == null ?
+ null :
+ new SubProgressMonitor(this.hierarchy.progressMonitor, 70);
+ createTypeHierarchyBasedOnRegion(allOpenablesInRegion, buildMonitor);
+ ((RegionBasedTypeHierarchy)this.hierarchy).pruneDeadBranches();
+ } else {
+ this.hierarchy.initialize(1);
+ this.buildSupertypes();
+ }
+ } finally {
+// manager.flushZipFiles();
+ }
+}
+/**
+ * Configure this type hierarchy that is based on a region.
+ */
+private void createTypeHierarchyBasedOnRegion(HashMap allOpenablesInRegion, IProgressMonitor monitor) {
+
+ int size = allOpenablesInRegion.size();
+ if (size == 0) {
+ if (monitor != null) monitor.done();
+ return;
+ }
+
+ this.infoToHandle = new HashMap(size);
+ Iterator javaProjects = allOpenablesInRegion.keySet().iterator();
+ while (javaProjects.hasNext()) {
+ RubyProject project = (RubyProject) javaProjects.next();
+ ArrayList allOpenables = (ArrayList) allOpenablesInRegion.get(project);
+ Openable[] openables = new Openable[allOpenables.size()];
+ allOpenables.toArray(openables);
+
+ try {
+ // resolve
+ if (monitor != null) monitor.beginTask("", size * 2/* 1 for build binding, 1 for connect hierarchy*/); //$NON-NLS-1$
+// SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(this.hierarchy.workingCopies);
+// this.nameLookup = searchableEnvironment.nameLookup;
+ this.hierarchyResolver.resolve(openables, null, monitor);
+// } catch (RubyModelException e) {
+ // project doesn't exit: ignore
+ } finally {
+ if (monitor != null) monitor.done();
+ }
+ }
+}
+
+ /**
+ * Returns all of the openables defined in the region of this type hierarchy.
+ * Returns a map from IRubyProject to ArrayList of Openable
+ */
+ private HashMap determineOpenablesInRegion(IProgressMonitor monitor) {
+
+ try {
+ HashMap allOpenables = new HashMap();
+ IRubyElement[] roots =
+ ((RegionBasedTypeHierarchy) this.hierarchy).region.getElements();
+ int length = roots.length;
+ if (monitor != null) monitor.beginTask("", length); //$NON-NLS-1$
+ for (int i = 0; i <length; i++) {
+ IRubyElement root = roots[i];
+ IRubyProject javaProject = root.getRubyProject();
+ ArrayList openables = (ArrayList) allOpenables.get(javaProject);
+ if (openables == null) {
+ openables = new ArrayList();
+ allOpenables.put(javaProject, openables);
+ }
+ switch (root.getElementType()) {
+ case IRubyElement.RUBY_PROJECT :
+ injectAllOpenablesForRubyProject((IRubyProject) root, openables);
+ break;
+ case IRubyElement.SOURCE_FOLDER_ROOT :
+ injectAllOpenablesForSourceFolderRoot((ISourceFolderRoot) root, openables);
+ break;
+ case IRubyElement.SOURCE_FOLDER :
+ injectAllOpenablesForSourceFolder((ISourceFolder) root, openables);
+ break;
+ case IRubyElement.SCRIPT :
+ openables.add(root);
+ break;
+ case IRubyElement.TYPE :
+ IType type = (IType)root;
+ openables.add(type.getRubyScript());
+ break;
+ default :
+ break;
+ }
+ worked(monitor, 1);
+ }
+ return allOpenables;
+ } finally {
+ if (monitor != null) monitor.done();
+ }
+ }
+
+ /**
+ * Adds all of the openables defined within this java project to the
+ * list.
+ */
+ private void injectAllOpenablesForRubyProject(
+ IRubyProject project,
+ ArrayList openables) {
+ try {
+ ISourceFolderRoot[] devPathRoots =
+ ((RubyProject) project).getSourceFolderRoots();
+ if (devPathRoots == null) {
+ return;
+ }
+ for (int j = 0; j < devPathRoots.length; j++) {
+ ISourceFolderRoot root = devPathRoots[j];
+ injectAllOpenablesForSourceFolderRoot(root, openables);
+ }
+ } catch (RubyModelException e) {
+ // ignore
+ }
+ }
+
+ /**
+ * Adds all of the openables defined within this package fragment to the
+ * list.
+ */
+ private void injectAllOpenablesForSourceFolder(
+ ISourceFolder packFrag,
+ ArrayList openables) {
+
+ try {
+ IRubyScript[] cus = packFrag.getRubyScripts();
+ for (int i = 0, length = cus.length; i < length; i++) {
+ openables.add(cus[i]);
+ }
+ } catch (RubyModelException e) {
+ // ignore
+ }
+ }
+
+ /**
+ * Adds all of the openables defined within this package fragment root to the
+ * list.
+ */
+ private void injectAllOpenablesForSourceFolderRoot(
+ ISourceFolderRoot root,
+ ArrayList openables) {
+ try {
+ IRubyElement[] packFrags = root.getChildren();
+ for (int k = 0; k < packFrags.length; k++) {
+ ISourceFolder packFrag = (ISourceFolder) packFrags[k];
+ injectAllOpenablesForSourceFolder(packFrag, openables);
+ }
+ } catch (RubyModelException e) {
+ return;
+ }
+ }
+
+}
Property changes on: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedHierarchyBuilder.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java 2007-07-17 14:37:49 UTC (rev 2768)
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 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.hierarchy;
+
+import java.util.ArrayList;
+
+import org.eclipse.core.runtime.CoreException;
+import org.rubypeople.rdt.core.IOpenable;
+import org.rubypeople.rdt.core.IRegion;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyElementDelta;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.ISourceFolderRoot;
+import org.rubypeople.rdt.core.IType;
+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.Region;
+import org.rubypeople.rdt.internal.core.RubyElement;
+import org.rubypeople.rdt.internal.core.RubyScript;
+import org.rubypeople.rdt.internal.core.TypeVector;
+
+public class RegionBasedTypeHierarchy extends TypeHierarchy {
+ /**
+ * The region of types for which to build the hierarchy
+ */
+ protected IRegion region;
+
+/**
+ * Creates a TypeHierarchy on the types in the specified region,
+ * considering first the given working copies,
+ * using the projects in the given region for a name lookup context. If a specific
+ * type is also specified, the type hierarchy is pruned to only
+ * contain the branch including the specified type.
+ */
+public RegionBasedTypeHierarchy(IRegion region, IRubyScript[] workingCopies, IType type, boolean computeSubtypes) {
+ super(type, workingCopies, (IRubySearchScope)null, computeSubtypes);
+
+ Region newRegion = new Region() {
+ public void add(IRubyElement element) {
+ if (!contains(element)) {
+ //"new" element added to region
+ removeAllChildren(element);
+ fRootElements.add(element);
+ if (element.getElementType() == IRubyElement.RUBY_PROJECT) {
+ // add jar roots as well so that jars don't rely on their parent to know
+ // if they are contained in the region
+ // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=146615)
+ try {
+ ISourceFolderRoot[] roots = ((IRubyProject) element).getSourceFolderRoots();
+ for (int i = 0, length = roots.length; i < length; i++) {
+ if (roots[i].isArchive() && !fRootElements.contains(roots[i]))
+ fRootElements.add(roots[i]);
+ }
+ } catch (RubyModelException e) {
+ // project doesn't exist
+ }
+ }
+ fRootElements.trimToSize();
+ }
+ }
+ };
+ IRubyElement[] elements = region.getElements();
+ for (int i = 0, length = elements.length; i < length; i++) {
+ newRegion.add(elements[i]);
+
+ }
+ this.region = newRegion;
+ if (elements.length > 0)
+ this.project = elements[0].getRubyProject();
+}
+/*
+ * @see TypeHierarchy#initializeRegions
+ */
+protected void initializeRegions() {
+ super.initializeRegions();
+ IRubyElement[] roots = this.region.getElements();
+ for (int i = 0; i < roots.length; i++) {
+ IRubyElement root = roots[i];
+ if (root instanceof IOpenable) {
+ this.files.put(root, new ArrayList());
+ } else {
+ Openable o = (Openable) ((RubyElement) root).getOpenableParent();
+ if (o != null) {
+ this.files.put(o, new ArrayList());
+ }
+ }
+ checkCanceled();
+ }
+}
+/**
+ * Compute this type hierarchy.
+ */
+protected void compute() throws RubyModelException, CoreException {
+ HierarchyBuilder builder = new RegionBasedHierarchyBuilder(this);
+ builder.build(this.computeSubtypes);
+}
+protected boolean isAffectedByOpenable(IRubyElementDelta delta, IRubyElement element) {
+ // change to working copy
+ if (element instanceof RubyScript && ((RubyScript)element).isWorkingCopy()) {
+ return super.isAffectedByOpenable(delta, element);
+ }
+
+ // if no focus, hierarchy is affected if the element is part of the region
+ if (this.focusType == null) {
+ return this.region.contains(element);
+ } else {
+ return super.isAffectedByOpenable(delta, element);
+ }
+}
+/**
+ * Returns the java project this hierarchy was created in.
+ */
+public IRubyProject javaProject() {
+ return this.project;
+}
+public void pruneDeadBranches() {
+ pruneDeadBranches(getRootClasses());
+ pruneDeadBranches(getRootInterfaces());
+}
+/*
+ * Returns whether all subtypes of the given type have been pruned.
+ */
+private boolean pruneDeadBranches(IType type) {
+ TypeVector subtypes = (TypeVector)this.typeToSubtypes.get(type);
+ if (subtypes == null) return true;
+ pruneDeadBranches(subtypes.copy().elements());
+ subtypes = (TypeVector)this.typeToSubtypes.get(type);
+ return (subtypes == null || subtypes.size == 0);
+}
+private void pruneDeadBranches(IType[] types) {
+ for (int i = 0, length = types.length; i < length; i++) {
+ IType type = types[i];
+ if (pruneDeadBranches(type) && !this.region.contains(type)) {
+ removeType(type);
+ }
+ }
+}
+/**
+ * Removes all the subtypes of the given type from the type hierarchy,
+ * removes its superclass entry and removes the references from its super types.
+ */
+protected void removeType(IType type) {
+ IType[] subtypes = this.getSubtypes(type);
+ this.typeToSubtypes.remove(type);
+ if (subtypes != null) {
+ for (int i= 0; i < subtypes.length; i++) {
+ this.removeType(subtypes[i]);
+ }
+ }
+ IType superclass = (IType)this.classToSuperclass.remove(type);
+ if (superclass != null) {
+ TypeVector types = (TypeVector)this.typeToSubtypes.get(superclass);
+ if (types != null) types.remove(type);
+ }
+ IType[] superinterfaces = (IType[])this.typeToSuperInterfaces.remove(type);
+ if (superinterfaces != null) {
+ for (int i = 0, length = superinterfaces.length; i < length; i++) {
+ IType superinterface = superinterfaces[i];
+ TypeVector types = (TypeVector)this.typeToSubtypes.get(superinterface);
+ if (types != null) types.remove(type);
+ }
+ }
+ this.interfaces.remove(type);
+}
+
+}
Property changes on: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/RegionBasedTypeHierarchy.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-17 14:37:51
|
Revision: 2769
http://svn.sourceforge.net/rubyeclipse/?rev=2769&view=rev
Author: cawilliams
Date: 2007-07-17 07:37:49 -0700 (Tue, 17 Jul 2007)
Log Message:
-----------
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java 2007-07-17 14:37:49 UTC (rev 2768)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java 2007-07-17 14:37:49 UTC (rev 2769)
@@ -49,7 +49,6 @@
import org.eclipse.ui.texteditor.MarkerUtilities;
import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
import org.rubypeople.rdt.core.IProblemRequestor;
-import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.core.RubyModelException;
@@ -212,8 +211,7 @@
extension.setIsActive(false);
extension.setIsHandlingTemporaryProblems(isHandlingTemporaryProblems());
}
- // FIXME If project doesn't have ruby nature, add it here
- IRubyProject project = original.getRubyProject();
+ // If project doesn't have ruby nature, add it here
IProject iProject = input.getFile().getProject();
if (!RubyProject.hasRubyNature(iProject)) {
RubyCore.addRubyNature(iProject, null);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-16 17:16:45
|
Revision: 2767
http://svn.sourceforge.net/rubyeclipse/?rev=2767&view=rev
Author: cawilliams
Date: 2007-07-16 10:16:44 -0700 (Mon, 16 Jul 2007)
Log Message:
-----------
close #5149 - No RubyScript element for classes in same file
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-16 15:59:10 UTC (rev 2766)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-16 17:16:44 UTC (rev 2767)
@@ -186,7 +186,7 @@
Node scoping = findNearestScope(typeNode, methodNode.getPosition().getStartOffset() - 1);
if (!scoping.equals(typeNode)) continue;
MethodDefNode methodDef = (MethodDefNode) methodNode;
- NodeMethod method = new NodeMethod(methodDef);
+ NodeMethod method = new NodeMethod(methodDef, fContext.getScript());
CompletionProposal proposal = suggestMethod(method, name, 100);
if (proposal == null) continue;
list.add(proposal);
@@ -652,7 +652,7 @@
}
if (!fContext.prefixStartsWith(name))
continue;
- NodeMethod method = new NodeMethod((MethodDefNode)methodDefinition);
+ NodeMethod method = new NodeMethod((MethodDefNode)methodDefinition, fContext.getScript());
suggestMethod(method, typeName, 100);
}
addTypesVariables(typeNode);
@@ -787,9 +787,11 @@
private class NodeMethod implements IMethod {
private MethodDefNode node;
+ private IRubyScript fScript;
- public NodeMethod(MethodDefNode methodDefinition) {
+ public NodeMethod(MethodDefNode methodDefinition, IRubyScript script) {
this.node = methodDefinition;
+ this.fScript = script;
}
public String[] getParameterNames() throws RubyModelException {
@@ -833,7 +835,7 @@
}
public IOpenable getOpenable() {
- return null;
+ return fScript;
}
public IRubyElement getParent() {
@@ -889,7 +891,7 @@
}
public IRubyScript getRubyScript() {
- return null;
+ return fScript;
}
public IType getType(String name, int occurrenceCount) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-16 15:59:15
|
Revision: 2766
http://svn.sourceforge.net/rubyeclipse/?rev=2766&view=rev
Author: cawilliams
Date: 2007-07-16 08:59:10 -0700 (Mon, 16 Jul 2007)
Log Message:
-----------
fix up creation of super reference index key
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/SuperTypeReferencePattern.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/SuperTypeReferencePattern.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/SuperTypeReferencePattern.java 2007-07-16 15:12:48 UTC (rev 2765)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/SuperTypeReferencePattern.java 2007-07-16 15:59:10 UTC (rev 2766)
@@ -54,7 +54,7 @@
superTypeName = OBJECT;
char[] superSimpleName = CharOperation.lastSegment(superTypeName, "::");
char[] superQualification = null;
- if (superSimpleName != superTypeName) {
+ if (!CharOperation.equals(superSimpleName, superTypeName)) {
int length = superTypeName.length - superSimpleName.length - 1;
superQualification = new char[length];
System.arraycopy(superTypeName, 0, superQualification, 0, length);
@@ -63,7 +63,7 @@
// if the supertype name contains a $, then split it into: source name and append the $ prefix to the qualification
// e.g. p.A$B ---> p.A$ + B
char[] superTypeSourceName = CharOperation.lastSegment(superSimpleName, "::");
- if (superTypeSourceName != superSimpleName) {
+ if (!CharOperation.equals(superSimpleName, superTypeSourceName)) {
int start = superQualification == null ? 0 : superQualification.length + 1;
int prefixLength = superSimpleName.length - superTypeSourceName.length;
char[] mangledQualification = new char[start + prefixLength];
@@ -82,7 +82,7 @@
packageName = ONE_ZERO; // save some space
- // superSimpleName / superQualification / simpleName / enclosingTypeName / typeParameters / packageName / superClassOrInterface classOrInterface modifiers
+ // superSimpleName / superQualification / simpleName / enclosingTypeName / packageName / superClassOrModule classOrModule modifiers
int superLength = superSimpleName == null ? 0 : superSimpleName.length;
int superQLength = superQualification == null ? 0 : superQualification.length;
int simpleLength = simpleName == null ? 0 : simpleName.length;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-16 15:12:49
|
Revision: 2765
http://svn.sourceforge.net/rubyeclipse/?rev=2765&view=rev
Author: cawilliams
Date: 2007-07-16 08:12:48 -0700 (Mon, 16 Jul 2007)
Log Message:
-----------
fix #5182 - Heredocs with variable substitution breaks syntax highlighting
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-07-16 14:47:09 UTC (rev 2764)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-07-16 15:12:48 UTC (rev 2765)
@@ -301,9 +301,11 @@
return new Token(fContentType);
case Tokens.tSTRING_BEG:
fOpeningString = fContents.substring(fOffset - origOffset, lexerSource.getOffset()).trim();
- if (fOpeningString.equals("'")) {
+ if (fOpeningString.equals("'") || fOpeningString.startsWith("%q")) {
inSingleQuote = true;
- }
+ } else if (fOpeningString.startsWith("<<")) { // here-doc
+ fOpeningString += "\n";
+ }
fContentType = RUBY_STRING;
return new Token(RUBY_STRING);
case Tokens.tXSTRING_BEG:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-16 14:47:14
|
Revision: 2764
http://svn.sourceforge.net/rubyeclipse/?rev=2764&view=rev
Author: cawilliams
Date: 2007-07-16 07:47:09 -0700 (Mon, 16 Jul 2007)
Log Message:
-----------
test and fix for #5211 - Ruby code colorization goes wrong till the end of file on some text patterns. (We didn't properly handle the % form of strings/regexp/commands)
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-07-16 13:45:35 UTC (rev 2763)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-07-16 14:47:09 UTC (rev 2764)
@@ -67,6 +67,7 @@
private List<QueuedToken> fQueue = new ArrayList<QueuedToken>();
private String fContentType = RUBY_DEFAULT;
private boolean inSingleQuote;
+ private String fOpeningString;
public final static String RUBY_MULTI_LINE_COMMENT = IRubyPartitions.RUBY_MULTI_LINE_COMMENT;
@@ -254,17 +255,11 @@
private void setLexerPastDynamicSectionOfString() throws IOException {
IDocument document;
StringBuffer fakeContents = new StringBuffer();
- int start = fOffset - 1;
+ int start = fOffset - fOpeningString.length();
for (int i = 0; i < start; i++) {
fakeContents.append(" ");
}
- if (fContentType.equals(RUBY_REGULAR_EXPRESSION)) {
- fakeContents.append('/');
- } else if (fContentType.equals(RUBY_COMMAND)) {
- fakeContents.append('`');
- } else {
- fakeContents.append('"');
- }
+ fakeContents.append(fOpeningString);
if ((fOffset - origOffset) < origLength) {
fakeContents.append(new String(fContents.substring((fOffset - origOffset)))); // BLAH removed + 1 from end here
}
@@ -305,16 +300,18 @@
case Tokens.tSTRING_CONTENT:
return new Token(fContentType);
case Tokens.tSTRING_BEG:
- String token = fContents.substring(fOffset - origOffset, lexerSource.getOffset());
- if (token.trim().equals("'")) {
+ fOpeningString = fContents.substring(fOffset - origOffset, lexerSource.getOffset()).trim();
+ if (fOpeningString.equals("'")) {
inSingleQuote = true;
- }
- fContentType = RUBY_STRING;
+ }
+ fContentType = RUBY_STRING;
return new Token(RUBY_STRING);
case Tokens.tXSTRING_BEG:
+ fOpeningString = fContents.substring(fOffset - origOffset, lexerSource.getOffset()).trim();
fContentType = RUBY_COMMAND;
return new Token(RUBY_COMMAND);
case Tokens.tQWORDS_BEG:
+ fOpeningString = fContents.substring(fOffset - origOffset, lexerSource.getOffset()).trim();
fContentType = RUBY_STRING;
return new Token(RUBY_STRING);
case Tokens.tSTRING_END:
@@ -323,6 +320,7 @@
inSingleQuote = false;
return new Token(oldContentType);
case Tokens.tREGEXP_BEG:
+ fOpeningString = fContents.substring(fOffset - origOffset, lexerSource.getOffset()).trim();
fContentType = RUBY_REGULAR_EXPRESSION;
return new Token(RUBY_REGULAR_EXPRESSION);
case Tokens.tREGEXP_END:
Modified: trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java 2007-07-16 13:45:35 UTC (rev 2763)
+++ trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java 2007-07-16 14:47:09 UTC (rev 2764)
@@ -301,5 +301,18 @@
assertEquals(RubyPartitionScanner.RUBY_COMMAND, this.getContentType(code, 63));
assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 65));
}
+
+ public void testPercentXCommand() {
+ String code = "if (@options.do_it)\n" +
+ " %x{#{cmd}}\n" +
+ "end\n";
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 1)); // i'f'
+ assertEquals(RubyPartitionScanner.RUBY_COMMAND, this.getContentType(code, 22)); // '%'x
+ assertEquals(RubyPartitionScanner.RUBY_COMMAND, this.getContentType(code, 24)); // %x'{'
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 27)); //'c'md
+ assertEquals(RubyPartitionScanner.RUBY_COMMAND, this.getContentType(code, 30)); // cmd'}'
+ assertEquals(RubyPartitionScanner.RUBY_COMMAND, this.getContentType(code, 31)); // cmd}'}'
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 33)); //'e'nd
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-16 13:45:38
|
Revision: 2763
http://svn.sourceforge.net/rubyeclipse/?rev=2763&view=rev
Author: cawilliams
Date: 2007-07-16 06:45:35 -0700 (Mon, 16 Jul 2007)
Log Message:
-----------
when trying to open a ruby file, if project doesn't have ruby nature, add it first. This basically automatically makes any project where a user opens a.rb file into a ruby project automatically under the hood.
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java 2007-07-13 14:10:00 UTC (rev 2762)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/rubyeditor/RubyDocumentProvider.java 2007-07-16 13:45:35 UTC (rev 2763)
@@ -6,6 +6,7 @@
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -48,11 +49,13 @@
import org.eclipse.ui.texteditor.MarkerUtilities;
import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
import org.rubypeople.rdt.core.IProblemRequestor;
+import org.rubypeople.rdt.core.IRubyProject;
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyCore;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.core.compiler.CategorizedProblem;
import org.rubypeople.rdt.core.compiler.IProblem;
+import org.rubypeople.rdt.internal.core.RubyProject;
import org.rubypeople.rdt.internal.ui.RubyPlugin;
import org.rubypeople.rdt.internal.ui.RubyPluginImages;
import org.rubypeople.rdt.internal.ui.text.ruby.IProblemRequestorExtension;
@@ -209,7 +212,12 @@
extension.setIsActive(false);
extension.setIsHandlingTemporaryProblems(isHandlingTemporaryProblems());
}
-
+ // FIXME If project doesn't have ruby nature, add it here
+ IRubyProject project = original.getRubyProject();
+ IProject iProject = input.getFile().getProject();
+ if (!RubyProject.hasRubyNature(iProject)) {
+ RubyCore.addRubyNature(iProject, null);
+ }
original.becomeWorkingCopy(requestor, getProgressMonitor());
cuInfo.fCopy = original;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-13 14:10:02
|
Revision: 2762
http://svn.sourceforge.net/rubyeclipse/?rev=2762&view=rev
Author: cawilliams
Date: 2007-07-13 07:10:00 -0700 (Fri, 13 Jul 2007)
Log Message:
-----------
implement #5179 - Detect if user has no ruby interpreter installed and prompt to install one
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/plugin.xml
Added Paths:
-----------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyInstalledDetector.java
Modified: trunk/org.rubypeople.rdt.ui/plugin.xml
===================================================================
--- trunk/org.rubypeople.rdt.ui/plugin.xml 2007-07-12 18:53:28 UTC (rev 2761)
+++ trunk/org.rubypeople.rdt.ui/plugin.xml 2007-07-13 14:10:00 UTC (rev 2762)
@@ -1119,5 +1119,6 @@
<extension
point="org.eclipse.ui.startup">
<startup class="org.rubypeople.rdt.internal.ui.ForceIndexer"/>
+ <startup class="org.rubypeople.rdt.internal.ui.RubyInstalledDetector"/>
</extension>
</plugin>
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyInstalledDetector.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyInstalledDetector.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/RubyInstalledDetector.java 2007-07-13 14:10:00 UTC (rev 2762)
@@ -0,0 +1,67 @@
+package org.rubypeople.rdt.internal.ui;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IStartup;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.browser.IWebBrowser;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+import org.eclipse.ui.dialogs.PreferencesUtil;
+import org.rubypeople.rdt.launching.IVMInstall;
+import org.rubypeople.rdt.launching.RubyRuntime;
+
+public class RubyInstalledDetector implements IStartup {
+
+ private static final String RUBY_BROWSER_ID = RubyPlugin.getPluginId() + ".ruby.download.browser";
+ private static final String INTERPRETER_PREF_PAGE_ID = "org.rubypeople.rdt.debug.ui.preferences.PreferencePageRubyInterpreter";
+ private static final String RUBY_DOWNLOAD_PAGE = "http://www.ruby-lang.org/en/downloads/";
+
+ private static final String SETUP_PREFERENCES = "Setup preferences";
+ private static final String CANCEL = "Cancel";
+ private static final String DOWNLOAD_RUBY = "Download Ruby";
+
+ private static final String MSG = "We were unable to detect a ruby installation. If you do not have ruby installed, please click the \"" + DOWNLOAD_RUBY + "\" button below. If you have ruby installed and we were simply unable to detect it, please add it to your Installed Interpreter preference page. You can begin by clicking the \"" + SETUP_PREFERENCES + "\" button below";
+ private static final String TITLE = "Unable to detect Ruby install";
+
+ public void earlyStartup() {
+ IVMInstall vm = RubyRuntime.getDefaultVMInstall();
+ if (vm != null) return;
+ Display.getDefault().asyncExec(new Runnable() {
+
+ public void run() {
+ MessageDialog dialog = new MessageDialog(Display.getDefault().getActiveShell(), TITLE, null, MSG, MessageDialog.WARNING, new String[]{ DOWNLOAD_RUBY, SETUP_PREFERENCES, CANCEL }, 0);
+ int result = dialog.open();
+ if (result == 0) { // download ruby
+ openBrowser(RUBY_DOWNLOAD_PAGE);
+ } else if (result == 1) { // send to interpreter pref page
+ openPreferencePage(INTERPRETER_PREF_PAGE_ID);
+ }
+ }
+
+ private void openPreferencePage(String pageId) {
+ PreferenceDialog prefDialog = PreferencesUtil.createPreferenceDialogOn(Display.getDefault().getActiveShell(), pageId, null, null);
+ prefDialog.open();
+ }
+
+ private void openBrowser(String url) {
+ try {
+ IWorkbenchBrowserSupport support =
+ PlatformUI.getWorkbench().getBrowserSupport();
+ IWebBrowser browser = support.createBrowser(RUBY_BROWSER_ID);
+ browser.openURL(new URL(url));
+ } catch (PartInitException e) {
+ RubyPlugin.log(e);
+ } catch (MalformedURLException e) {
+ RubyPlugin.log(e);
+ }
+ }
+
+ });
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 18:53:30
|
Revision: 2761
http://svn.sourceforge.net/rubyeclipse/?rev=2761&view=rev
Author: cawilliams
Date: 2007-07-12 11:53:28 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
move initialization of ruby gems manager to new class. Apparently listening for STARTED FrameworkEvent just made it never happen!
Modified Paths:
--------------
trunk/com.aptana.rdt/plugin.xml
trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java
Added Paths:
-----------
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/core/gems/RubyGemsInitializer.java
Modified: trunk/com.aptana.rdt/plugin.xml
===================================================================
--- trunk/com.aptana.rdt/plugin.xml 2007-07-12 18:52:21 UTC (rev 2760)
+++ trunk/com.aptana.rdt/plugin.xml 2007-07-12 18:53:28 UTC (rev 2761)
@@ -197,4 +197,9 @@
point="org.eclipse.core.runtime.preferences">
<initializer class="com.aptana.rdt.internal.core.RubyRedPreferenceInitializer"/>
</extension>
+
+ <extension
+ point="org.eclipse.ui.startup">
+ <startup class="com.aptana.rdt.internal.core.gems.RubyGemsInitializer"/>
+ </extension>
</plugin>
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java 2007-07-12 18:52:21 UTC (rev 2760)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/AptanaRDTPlugin.java 2007-07-12 18:53:28 UTC (rev 2761)
@@ -21,8 +21,6 @@
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkEvent;
-import org.osgi.framework.FrameworkListener;
import org.rubypeople.rdt.internal.core.RubyModelManager.EclipsePreferencesListener;
import org.rubypeople.rdt.internal.launching.LaunchingPlugin;
import org.rubypeople.rdt.internal.ui.IRubyStatusConstants;
@@ -239,16 +237,7 @@
initializePreferences();
context.registerService(IGemManager.class.getName(), getGemManager(), null);
- context.addFrameworkListener(new FrameworkListener() {
-
- public void frameworkEvent(FrameworkEvent event) {
- if (event.getType() == FrameworkEvent.STARTED) {
- GemManager.getInstance().initialize();
- }
-
- }
-
- });
+
getGemManager().addGemListener(new GemListener() {
public void managerInitialized() {
Added: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/core/gems/RubyGemsInitializer.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/core/gems/RubyGemsInitializer.java (rev 0)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/core/gems/RubyGemsInitializer.java 2007-07-12 18:53:28 UTC (rev 2761)
@@ -0,0 +1,11 @@
+package com.aptana.rdt.internal.core.gems;
+
+import org.eclipse.ui.IStartup;
+
+public class RubyGemsInitializer implements IStartup {
+
+ public void earlyStartup() {
+ GemManager.getInstance().initialize();
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 18:52:25
|
Revision: 2760
http://svn.sourceforge.net/rubyeclipse/?rev=2760&view=rev
Author: cawilliams
Date: 2007-07-12 11:52:21 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
add actual code that does the forced indexing via a search
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java 2007-07-12 18:51:48 UTC (rev 2759)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/RubyCore.java 2007-07-12 18:52:21 UTC (rev 2760)
@@ -47,6 +47,14 @@
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.rubypeople.rdt.core.search.IRubySearchConstants;
+import org.rubypeople.rdt.core.search.SearchEngine;
+import org.rubypeople.rdt.core.search.SearchMatch;
+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.core.BatchOperation;
import org.rubypeople.rdt.internal.core.DefaultWorkingCopyOwner;
import org.rubypeople.rdt.internal.core.LoadpathAttribute;
@@ -276,6 +284,8 @@
public static final String USER_LIBRARY_CONTAINER_ID= "org.rubypeople.rdt.USER_LIBRARY"; //$NON-NLS-1$
private static final boolean VERBOSE = false;
+
+ private RubyProjectListener fProjectListener;
public RubyCore() {
super();
@@ -303,8 +313,9 @@
public void start(BundleContext context) throws Exception {
super.start(context);
RubyModelManager.getRubyModelManager().startup();
-
- ResourcesPlugin.getWorkspace().addResourceChangeListener(new RubyProjectListener(), IResourceChangeEvent.POST_CHANGE);
+
+ fProjectListener = new RubyProjectListener();
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(fProjectListener, IResourceChangeEvent.POST_CHANGE);
}
/*
@@ -315,6 +326,7 @@
*/
public void stop(BundleContext context) throws Exception {
try {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(fProjectListener);
RubyModelManager.getRubyModelManager().shutdown();
} finally {
// ensure we call super.stop as the last thing
@@ -1437,4 +1449,24 @@
}
}
}
+
+
+ public static void forceIndexing() {
+ SearchEngine engine = new SearchEngine();
+ SearchParticipant[] participants = new SearchParticipant[] { SearchEngine.getDefaultSearchParticipant() };
+ SearchPattern pattern = SearchPattern.createPattern(IRubyElement.TYPE, "*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
+ SearchRequestor requestor = new SearchRequestor() {
+
+ @Override
+ public void acceptSearchMatch(SearchMatch match) throws CoreException {
+ // do nothing
+ }
+
+ };
+ try {
+ engine.search(pattern, participants, SearchEngine.createWorkspaceScope(), requestor, null);
+ } catch (CoreException e) {
+ // ignore
+ }
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 18:51:52
|
Revision: 2759
http://svn.sourceforge.net/rubyeclipse/?rev=2759&view=rev
Author: cawilliams
Date: 2007-07-12 11:51:48 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
fix #5087 - Editor hangs on typing <%= . We now force the indexer to run in the background at startup, which should avoid the "freezing" happening on first code compeltion. (though this may still "freeze" at startup the very first time)
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/plugin.xml
Added Paths:
-----------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/ForceIndexer.java
Modified: trunk/org.rubypeople.rdt.ui/plugin.xml
===================================================================
--- trunk/org.rubypeople.rdt.ui/plugin.xml 2007-07-12 17:15:21 UTC (rev 2758)
+++ trunk/org.rubypeople.rdt.ui/plugin.xml 2007-07-12 18:51:48 UTC (rev 2759)
@@ -1115,4 +1115,9 @@
class="org.rubypeople.rdt.internal.ui.search.OccurrencesSearchResultPage">
</viewPage>
</extension>
+
+ <extension
+ point="org.eclipse.ui.startup">
+ <startup class="org.rubypeople.rdt.internal.ui.ForceIndexer"/>
+ </extension>
</plugin>
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/ForceIndexer.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/ForceIndexer.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/ForceIndexer.java 2007-07-12 18:51:48 UTC (rev 2759)
@@ -0,0 +1,12 @@
+package org.rubypeople.rdt.internal.ui;
+
+import org.eclipse.ui.IStartup;
+import org.rubypeople.rdt.core.RubyCore;
+
+public class ForceIndexer implements IStartup {
+
+ public void earlyStartup() {
+ RubyCore.forceIndexing();
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 17:15:23
|
Revision: 2758
http://svn.sourceforge.net/rubyeclipse/?rev=2758&view=rev
Author: cawilliams
Date: 2007-07-12 10:15:21 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
Added Paths:
-----------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/ITypeHierarchyViewPart.java
Added: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/ITypeHierarchyViewPart.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/ITypeHierarchyViewPart.java (rev 0)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/ITypeHierarchyViewPart.java 2007-07-12 17:15:21 UTC (rev 2758)
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 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.ui;
+
+
+import org.eclipse.ui.IViewPart;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IType;
+
+/**
+ * The standard type hierarchy view presents a type hierarchy for a given input class
+ * or interface. Visually, this view consists of a pair of viewers, one showing the type
+ * hierarchy, the other showing the members of the type selected in the first.
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * </p>
+ *
+ * @see RubyUI#ID_TYPE_HIERARCHY
+ */
+public interface ITypeHierarchyViewPart extends IViewPart {
+
+ /**
+ * Sets the input element of this type hierarchy view to a type.
+ *
+ * @param type the input element of this type hierarchy view, or <code>null</code>
+ * to clear any input element
+ * @deprecated use setInputElement instead
+ */
+ public void setInput(IType type);
+
+ /**
+ * Sets the input element of this type hierarchy view. The following input types are possible
+ * <code>IMember</code> (types, methods, fields..), <code>IPackageFragment</code>, <code>IPackageFragmentRoot</code>
+ * and <code>IRubyProject</code>.
+ *
+ * @param element the input element of this type hierarchy view, or <code>null</code>
+ * to clear any input
+ *
+ * @since 2.0
+ */
+ public void setInputElement(IRubyElement element);
+
+ /**
+ * Returns the input element of this type hierarchy view.
+ *
+ * @return the input element, or <code>null</code> if no input element is set
+ * @see #setInput(IType)
+ * @deprecated use getInputElement instead
+ */
+ public IType getInput();
+
+
+ /**
+ * Returns the input element of this type hierarchy view.
+ *
+ * @return the input element, or <code>null</code> if no input element is set
+ * @see #setInputElement(IRubyElement)
+ *
+ * @since 2.0
+ */
+ public IRubyElement getInputElement();
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 17:14:36
|
Revision: 2757
http://svn.sourceforge.net/rubyeclipse/?rev=2757&view=rev
Author: cawilliams
Date: 2007-07-12 10:14:33 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
fix #5006 - Wrap creation of embedded browers to give nicer error messages
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RailsAPIView.java
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RubyCoreAPIView.java
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RubyStdLibAPIView.java
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/infoviews/RIView.java
Added Paths:
-----------
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/BrowserView.java
Added: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/BrowserView.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/BrowserView.java (rev 0)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/BrowserView.java 2007-07-12 17:14:33 UTC (rev 2757)
@@ -0,0 +1,38 @@
+package com.aptana.rdt.internal.ui.infoviews;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.part.ViewPart;
+
+public class BrowserView extends ViewPart {
+
+ private Browser fBrowser;
+ private String fUrl;
+
+ public BrowserView(String url) {
+ this.fUrl = url;
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ try {
+ fBrowser = new Browser(parent, SWT.BORDER);
+ fBrowser.setUrl(fUrl);
+ } catch (Exception e) {
+ MessageDialog
+ .openError(
+ Display.getDefault().getActiveShell(),
+ "Unable to create embedded browser",
+ "It appears that you do not have an embeddable browser. Please see http://www.eclipse.org/swt/faq.php#browserlinux for more information if you are on Linux.");
+ }
+ }
+
+ @Override
+ public void setFocus() {
+ fBrowser.setFocus();
+ }
+
+}
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RailsAPIView.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RailsAPIView.java 2007-07-12 16:09:12 UTC (rev 2756)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RailsAPIView.java 2007-07-12 17:14:33 UTC (rev 2757)
@@ -1,24 +1,11 @@
package com.aptana.rdt.internal.ui.infoviews;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.part.ViewPart;
+public class RailsAPIView extends BrowserView {
-public class RailsAPIView extends ViewPart {
-
private static final String URL = "http://api.rubyonrails.org/";
- private Browser browser;
- @Override
- public void createPartControl(Composite parent) {
- browser = new Browser(parent, SWT.BORDER);
- browser.setUrl(URL);
+ public RailsAPIView() {
+ super(URL);
}
- @Override
- public void setFocus() {
- browser.setFocus();
- }
-
}
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RubyCoreAPIView.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RubyCoreAPIView.java 2007-07-12 16:09:12 UTC (rev 2756)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RubyCoreAPIView.java 2007-07-12 17:14:33 UTC (rev 2757)
@@ -1,24 +1,11 @@
package com.aptana.rdt.internal.ui.infoviews;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.part.ViewPart;
+public class RubyCoreAPIView extends BrowserView {
-public class RubyCoreAPIView extends ViewPart {
-
private static final String URL = "http://www.ruby-doc.org/core/";
- private Browser browser;
- @Override
- public void createPartControl(Composite parent) {
- browser = new Browser(parent, SWT.BORDER);
- browser.setUrl(URL);
+ public RubyCoreAPIView() {
+ super(URL);
}
- @Override
- public void setFocus() {
- browser.setFocus();
- }
-
}
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RubyStdLibAPIView.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RubyStdLibAPIView.java 2007-07-12 16:09:12 UTC (rev 2756)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/ui/infoviews/RubyStdLibAPIView.java 2007-07-12 17:14:33 UTC (rev 2757)
@@ -1,24 +1,11 @@
package com.aptana.rdt.internal.ui.infoviews;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.browser.Browser;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.ui.part.ViewPart;
+public class RubyStdLibAPIView extends BrowserView {
-public class RubyStdLibAPIView extends ViewPart {
-
private static final String URL = "http://www.ruby-doc.org/stdlib/";
- private Browser browser;
- @Override
- public void createPartControl(Composite parent) {
- browser = new Browser(parent, SWT.BORDER);
- browser.setUrl(URL);
+ public RubyStdLibAPIView() {
+ super(URL);
}
- @Override
- public void setFocus() {
- browser.setFocus();
- }
-
}
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/infoviews/RIView.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/infoviews/RIView.java 2007-07-12 16:09:12 UTC (rev 2756)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/infoviews/RIView.java 2007-07-12 17:14:33 UTC (rev 2757)
@@ -15,6 +15,7 @@
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
@@ -125,7 +126,11 @@
});
// search result
- searchResult = new Browser(form, SWT.BORDER);
+ try {
+ searchResult = new Browser(form, SWT.BORDER);
+ } catch (Exception e) {
+ MessageDialog.openError(Display.getDefault().getActiveShell(), "Unable to create embedded browser", "It appears that you do not have an embeddable browser. Please see http://www.eclipse.org/swt/faq.php#browserlinux for more information if you are on Linux.");
+ }
form.setWeights(new int[]{1, 3});
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 16:53:02
|
Revision: 2756
http://svn.sourceforge.net/rubyeclipse/?rev=2756&view=rev
Author: cawilliams
Date: 2007-07-12 09:09:12 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
fix #5178
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyElementLabels.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyElementLabels.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyElementLabels.java 2007-07-12 16:02:39 UTC (rev 2755)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyElementLabels.java 2007-07-12 16:09:12 UTC (rev 2756)
@@ -546,7 +546,7 @@
buf.append(CONCAT_STRING);
IType declaringType = type.getDeclaringType();
if (declaringType != null) {
- getTypeLabel(declaringType, T_FULLY_QUALIFIED | (flags & QUALIFIER_FLAGS), buf);
+ getTypeLabel(declaringType, T_CONTAINER_QUALIFIED | (flags & QUALIFIER_FLAGS), buf);
int parentType = type.getParent().getElementType();
if (parentType == IRubyElement.METHOD || parentType == IRubyElement.FIELD) { // anonymous
// or
@@ -554,36 +554,37 @@
buf.append('.');
getElementLabel(type.getParent(), 0, buf);
}
- } else { // FIXME This ends up happening before the enclosing types get spit out
- ISourceFolder folder = type.getSourceFolder();
- if (!folder.isDefaultPackage()) {
- getSourceFolderLabel(folder, flags & QUALIFIER_FLAGS, buf);
- buf.append('/');
- }
- getRubyScriptLabel(type.getRubyScript(), (flags & QUALIFIER_FLAGS), buf);
- try {
- int offset = type.getNameRange().getOffset();
- buf.append(", offset: ");
- buf.append(offset);
- } catch (RubyModelException e) {
- RubyPlugin.log(e);
- }
- }
+ buf.append(CONCAT_STRING);
+ }
+ ISourceFolder folder = type.getSourceFolder();
+ if (!folder.isDefaultPackage()) {
+ getSourceFolderLabel(folder, flags & QUALIFIER_FLAGS, buf);
+ buf.append('/');
+ }
+ getRubyScriptLabel(type.getRubyScript(), (flags & QUALIFIER_FLAGS),
+ buf);
+ try {
+ int offset = type.getNameRange().getOffset();
+ buf.append(", offset: ");
+ buf.append(offset);
+ } catch (RubyModelException e) {
+ RubyPlugin.log(e);
+ }
}
}
/**
- * Appends the label for a import container, import or package declaration
- * to a {@link StringBuffer}. Considers the D_* flags.
- *
- * @param declaration
- * The element to render.
- * @param flags
- * The rendering flags. Flags with names starting with 'D_' are
- * considered.
- * @param buf
- * The buffer to append the resulting label to.
- */
+ * Appends the label for a import container, import or package declaration
+ * to a {@link StringBuffer}. Considers the D_* flags.
+ *
+ * @param declaration
+ * The element to render.
+ * @param flags
+ * The rendering flags. Flags with names starting with 'D_' are
+ * considered.
+ * @param buf
+ * The buffer to append the resulting label to.
+ */
public static void getDeclarationLabel(IRubyElement declaration, long flags, StringBuffer buf) {
if (getFlag(flags, D_QUALIFIED)) {
IRubyElement openable = (IRubyElement) declaration.getOpenable();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 16:51:33
|
Revision: 2753
http://svn.sourceforge.net/rubyeclipse/?rev=2753&view=rev
Author: cawilliams
Date: 2007-07-12 08:26:00 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
filter out duplicate global completions, suggest globals on empty prefix completions, limit global search by forcing $ at front (for some reason it's picking up all fields otherwise).
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-12 15:17:58 UTC (rev 2752)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-12 15:26:00 UTC (rev 2753)
@@ -90,6 +90,7 @@
if (fContext.emptyPrefix()) { // no prefix, so we could suggest anything
suggestMethodsForEnclosingType(script);
getDocumentsRubyElementsInScope();
+ suggestGlobals();
} else {
if (fContext.isDoubleSemiColon()) {
String prefix = fContext.getFullPrefix();
@@ -117,6 +118,10 @@
suggestConstantNames();
return;
}
+ if (fContext.isGlobal()) { // looks like a global
+ suggestGlobals();
+ return;
+ }
if (fContext.isExplicitMethodInvokation()) {
ITypeInferrer inferrer = new DefaultTypeInferrer();
List<ITypeGuess> guesses = inferrer.infer(fContext.getCorrectedSource(), fContext.getOffset());
@@ -162,9 +167,6 @@
}
getDocumentsRubyElementsInScope();
}
- if (fContext.isGlobal()) { // looks like a global
- suggestGlobals();
- }
}
this.fRequestor.endReporting();
fContext = null;
@@ -315,14 +317,15 @@
}
private void suggestGlobals() {
- SearchPattern pattern = SearchPattern.createPattern(IRubyElement.GLOBAL, "*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
+ SearchPattern pattern = SearchPattern.createPattern(IRubyElement.GLOBAL, "$*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
IRubySearchScope scope = BasicSearchEngine.createRubySearchScope(new IRubyElement[] {fContext.getScript().getRubyProject()});
List<SearchMatch> results = search(pattern, scope);
+ Set<String> names = new HashSet<String>();
for (SearchMatch match: results) {
IRubyElement element = (IRubyElement) match.getElement();
String name = element.getElementName();
- if (!fContext.prefixStartsWith(name))
- continue;
+ if (names.contains(name)) continue;
+ names.add(name);
CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.CONSTANT_REF, name, element);
proposal.setType(name);
fRequestor.accept(proposal);
@@ -372,14 +375,12 @@
}
private void suggestConstantNames() {
- SearchPattern pattern = SearchPattern.createPattern(IRubyElement.CONSTANT, "*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
+ SearchPattern pattern = SearchPattern.createPattern(IRubyElement.CONSTANT, fContext.getPartialPrefix()+ "*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
IRubySearchScope scope = BasicSearchEngine.createRubySearchScope(new IRubyElement[] {fContext.getScript()});
List<SearchMatch> results = search(pattern, scope);
for (SearchMatch match: results) {
IRubyElement element = (IRubyElement) match.getElement();
String name = element.getElementName();
- if (!fContext.prefixStartsWith(name))
- continue;
CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.CONSTANT_REF, name, element);
proposal.setType(name);
fRequestor.accept(proposal);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 16:42:28
|
Revision: 2754
http://svn.sourceforge.net/rubyeclipse/?rev=2754&view=rev
Author: cawilliams
Date: 2007-07-12 08:27:34 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
when suggesting globals, actually say they're global reference proposals and not refs to constants so we get teh global icon (and not the constant one).
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-12 15:26:00 UTC (rev 2753)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-12 15:27:34 UTC (rev 2754)
@@ -326,7 +326,7 @@
String name = element.getElementName();
if (names.contains(name)) continue;
names.add(name);
- CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.CONSTANT_REF, name, element);
+ CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.GLOBAL_REF, name, element);
proposal.setType(name);
fRequestor.accept(proposal);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 16:38:52
|
Revision: 2755
http://svn.sourceforge.net/rubyeclipse/?rev=2755&view=rev
Author: cawilliams
Date: 2007-07-12 09:02:39 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
add '/' between folder names and script name in type label
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyElementLabels.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyElementLabels.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyElementLabels.java 2007-07-12 15:27:34 UTC (rev 2754)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/ui/RubyElementLabels.java 2007-07-12 16:02:39 UTC (rev 2755)
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.rubypeople.rdt.ui;
+import java.io.File;
+
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IAdaptable;
@@ -552,10 +554,11 @@
buf.append('.');
getElementLabel(type.getParent(), 0, buf);
}
- } else {
+ } else { // FIXME This ends up happening before the enclosing types get spit out
ISourceFolder folder = type.getSourceFolder();
if (!folder.isDefaultPackage()) {
- getSourceFolderLabel(type.getSourceFolder(), flags & QUALIFIER_FLAGS, buf);
+ getSourceFolderLabel(folder, flags & QUALIFIER_FLAGS, buf);
+ buf.append('/');
}
getRubyScriptLabel(type.getRubyScript(), (flags & QUALIFIER_FLAGS), buf);
try {
@@ -665,7 +668,8 @@
}
buf.append(name.substring(start));
} else {
- buf.append(pack.getElementName());
+ String name = pack.getElementName();
+ buf.append(name.replace(File.separatorChar, '/'));
}
if (getFlag(flags, P_POST_QUALIFIED)) {
buf.append(CONCAT_STRING);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 15:18:01
|
Revision: 2752
http://svn.sourceforge.net/rubyeclipse/?rev=2752&view=rev
Author: cawilliams
Date: 2007-07-12 08:17:58 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
significantly speed up searching for all type names that match prefix. Build it into search query, rather than filtering after the fact. (should have done this before, but the search didn't properly filter before).
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-12 15:15:55 UTC (rev 2751)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-12 15:17:58 UTC (rev 2752)
@@ -330,15 +330,13 @@
}
private void suggestTypeNames() {
- SearchPattern pattern = SearchPattern.createPattern(IRubyElement.TYPE, "*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
+ SearchPattern pattern = SearchPattern.createPattern(IRubyElement.TYPE, fContext.getPartialPrefix() + "*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
IRubySearchScope scope = BasicSearchEngine.createRubySearchScope(new IRubyElement[] {fContext.getScript().getRubyProject()});
List<SearchMatch> results = search(pattern, scope);
Set<String> names = new HashSet<String>();
for (SearchMatch match: results) {
IRubyElement element = (IRubyElement) match.getElement();
String name = element.getElementName();
- if (!fContext.prefixStartsWith(name))
- continue;
if (names.contains(name)) continue;
names.add(name);
CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.TYPE_REF, name, element);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 15:15:56
|
Revision: 2751
http://svn.sourceforge.net/rubyeclipse/?rev=2751&view=rev
Author: cawilliams
Date: 2007-07-12 08:15:55 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
when suggesting type names, only suggest unique names (remove duplicates)
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-12 13:50:45 UTC (rev 2750)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/codeassist/CompletionEngine.java 2007-07-12 15:15:55 UTC (rev 2751)
@@ -52,7 +52,6 @@
import org.rubypeople.rdt.core.search.SearchParticipant;
import org.rubypeople.rdt.core.search.SearchPattern;
import org.rubypeople.rdt.internal.core.RubyElement;
-import org.rubypeople.rdt.internal.core.RubyScript;
import org.rubypeople.rdt.internal.core.RubyType;
import org.rubypeople.rdt.internal.core.parser.RubyParser;
import org.rubypeople.rdt.internal.core.search.BasicSearchEngine;
@@ -334,11 +333,14 @@
SearchPattern pattern = SearchPattern.createPattern(IRubyElement.TYPE, "*", IRubySearchConstants.DECLARATIONS, SearchPattern.R_PATTERN_MATCH);
IRubySearchScope scope = BasicSearchEngine.createRubySearchScope(new IRubyElement[] {fContext.getScript().getRubyProject()});
List<SearchMatch> results = search(pattern, scope);
+ Set<String> names = new HashSet<String>();
for (SearchMatch match: results) {
IRubyElement element = (IRubyElement) match.getElement();
String name = element.getElementName();
if (!fContext.prefixStartsWith(name))
continue;
+ if (names.contains(name)) continue;
+ names.add(name);
CompletionProposal proposal = createProposal(fContext.getReplaceStart(), CompletionProposal.TYPE_REF, name, element);
proposal.setType(name);
fRequestor.accept(proposal);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-12 13:50:50
|
Revision: 2750
http://svn.sourceforge.net/rubyeclipse/?rev=2750&view=rev
Author: cawilliams
Date: 2007-07-12 06:50:45 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
wrap the two jobs that load local and remote gems to catch all exceptions, log them, and return a valid status of cancel (so users don't get the popup dialog saying something just broke).
Modified Paths:
--------------
trunk/com.aptana.rdt/src/com/aptana/rdt/internal/core/gems/GemManager.java
Modified: trunk/com.aptana.rdt/src/com/aptana/rdt/internal/core/gems/GemManager.java
===================================================================
--- trunk/com.aptana.rdt/src/com/aptana/rdt/internal/core/gems/GemManager.java 2007-07-11 20:32:07 UTC (rev 2749)
+++ trunk/com.aptana.rdt/src/com/aptana/rdt/internal/core/gems/GemManager.java 2007-07-12 13:50:45 UTC (rev 2750)
@@ -663,21 +663,26 @@
@Override
protected IStatus run(IProgressMonitor monitor) {
- gems = loadLocalCache(getConfigFile(LOCAL_GEMS_CACHE_FILE));
- if (gems.isEmpty()) {
- gems = loadLocalGems();
- storeGemCache(gems, getConfigFile(LOCAL_GEMS_CACHE_FILE));
- }
- isInitialized = true;
- synchronized (listeners) {
- for (GemListener listener : listeners) {
- listener.managerInitialized();
+ try {
+ gems = loadLocalCache(getConfigFile(LOCAL_GEMS_CACHE_FILE));
+ if (gems.isEmpty()) {
+ gems = loadLocalGems();
+ storeGemCache(gems, getConfigFile(LOCAL_GEMS_CACHE_FILE));
}
- }
- synchronized (listeners) {
- for (GemListener listener : listeners) {
- listener.gemsRefreshed();
+ isInitialized = true;
+ synchronized (listeners) {
+ for (GemListener listener : listeners) {
+ listener.managerInitialized();
+ }
}
+ synchronized (listeners) {
+ for (GemListener listener : listeners) {
+ listener.gemsRefreshed();
+ }
+ }
+ } catch (Exception e) {
+ AptanaRDTPlugin.log(e);
+ return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
@@ -691,11 +696,16 @@
@Override
protected IStatus run(IProgressMonitor monitor) {
- remoteGems = loadLocalCache(getConfigFile(REMOTE_GEMS_CACHE_FILE));
- if (remoteGems.isEmpty()) {
- remoteGems = loadRemoteGems();
- storeGemCache(remoteGems,
- getConfigFile(REMOTE_GEMS_CACHE_FILE));
+ try {
+ remoteGems = loadLocalCache(getConfigFile(REMOTE_GEMS_CACHE_FILE));
+ if (remoteGems.isEmpty()) {
+ remoteGems = loadRemoteGems();
+ storeGemCache(remoteGems,
+ getConfigFile(REMOTE_GEMS_CACHE_FILE));
+ }
+ } catch (Exception e) {
+ AptanaRDTPlugin.log(e);
+ return Status.CANCEL_STATUS;
}
return Status.OK_STATUS;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <caw...@us...> - 2007-07-11 20:32:09
|
Revision: 2749
http://svn.sourceforge.net/rubyeclipse/?rev=2749&view=rev
Author: cawilliams
Date: 2007-07-11 13:32:07 -0700 (Wed, 11 Jul 2007)
Log Message:
-----------
first stab at the core code for type hierarchy stuff
Modified Paths:
--------------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyElement.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/SourceIndexer.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/indexing/SourceIndexerRequestor.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Messages.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/util/Util.java
Added Paths:
-----------
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IRegion.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/IPathRequestor.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/LogicalType.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/Region.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/TypeVector.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/ChangeCollector.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyBuilder.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyResolver.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/TypeHierarchy.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/SubTypeSearchJob.java
trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/search/matching/SuperTypeReferencePattern.java
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IRegion.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IRegion.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/core/IRegion.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * 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.core;
+
+/**
+ * A Ruby model region describes a hierarchical set of elements.
+ * Regions are often used to describe a set of elements to be considered
+ * when performing operations; for example, the set of elements to be
+ * considered during a search. A region may include elements from different
+ * projects.
+ * <p>
+ * When an element is included in a region, all of its children
+ * are considered to be included. Children of an included element
+ * <b>cannot</b> be selectively excluded.
+ * </p>
+ * <p>
+ * This interface is not intended to be implemented by clients.
+ * Instances can be created via the <code>RubyCore.newRegion</code>.
+ * </p>
+ *
+ * @see RubyCore#newRegion()
+ */
+public interface IRegion {
+ /**
+ * Adds the given element and all of its descendents to this region.
+ * If the specified element is already included, or one of its
+ * ancestors is already included, this has no effect. If the element
+ * being added is an ancestor of an element already contained in this
+ * region, the ancestor subsumes the descendent.
+ *
+ * @param element the given element
+ */
+ void add(IRubyElement element);
+ /**
+ * Returns whether the given element is contained in this region.
+ *
+ * @param element the given element
+ * @return true if the given element is contained in this region, false otherwise
+ */
+ boolean contains(IRubyElement element);
+ /**
+ * Returns the top level elements in this region.
+ * All descendents of these elements are also included in this region.
+ *
+ * @return the top level elements in this region
+ */
+ IRubyElement[] getElements();
+ /**
+ * Removes the specified element from the region and returns
+ * <code>true</code> if successful, <code>false</code> if the remove
+ * fails. If an ancestor of the given element is included, the
+ * remove fails (in other words, it is not possible to selectively
+ * exclude descendants of included ancestors).
+ *
+ * @param element the given element
+ * @return <code>true</code> if successful, <code>false</code> if the remove fails
+ */
+ boolean remove(IRubyElement element);
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/IPathRequestor.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/IPathRequestor.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/IPathRequestor.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * 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;
+
+public interface IPathRequestor {
+ void acceptPath(String path, boolean containsLocalTypes);
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/LogicalType.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/LogicalType.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/LogicalType.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,39 @@
+package org.rubypeople.rdt.internal.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyModelException;
+
+public class LogicalType extends RubyType implements IType {
+
+ private IType[] types;
+
+ public LogicalType(IType[] types) {
+ super(null, types[0].getElementName());
+ this.types = types;
+ }
+
+ @Override
+ public IRubyElement[] getChildren() throws RubyModelException {
+ List<IRubyElement> children = new ArrayList<IRubyElement>();
+ for (int i = 0; i < types.length; i++) {
+ IRubyElement[] subchildren = types[i].getChildren();
+ for (int j = 0; j < subchildren.length; j++) {
+ children.add(subchildren[j]);
+ }
+ }
+ return (IRubyElement[]) children.toArray(new IRubyElement[children.size()]);
+ }
+
+ @Override
+ public boolean hasChildren() throws RubyModelException {
+ for (int i = 0; i < types.length; i++) {
+ if (types[i].hasChildren()) return true;
+ }
+ return false;
+ }
+
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/Region.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/Region.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/Region.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * 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;
+
+import java.util.ArrayList;
+
+import org.rubypeople.rdt.core.IParent;
+import org.rubypeople.rdt.core.IRegion;
+import org.rubypeople.rdt.core.IRubyElement;
+
+
+/**
+ * @see IRegion
+ */
+
+public class Region implements IRegion {
+
+ /**
+ * A collection of the top level elements
+ * that have been added to the region
+ */
+ protected ArrayList fRootElements;
+/**
+ * Creates an empty region.
+ *
+ * @see IRegion
+ */
+public Region() {
+ fRootElements = new ArrayList(1);
+}
+/**
+ * @see IRegion#add(IRubyElement)
+ */
+public void add(IRubyElement element) {
+ if (!contains(element)) {
+ //"new" element added to region
+ removeAllChildren(element);
+ fRootElements.add(element);
+ fRootElements.trimToSize();
+ }
+}
+/**
+ * @see IRegion
+ */
+public boolean contains(IRubyElement element) {
+
+ int size = fRootElements.size();
+ ArrayList parents = getAncestors(element);
+
+ for (int i = 0; i < size; i++) {
+ IRubyElement aTop = (IRubyElement) fRootElements.get(i);
+ if (aTop.equals(element)) {
+ return true;
+ }
+ for (int j = 0, pSize = parents.size(); j < pSize; j++) {
+ if (aTop.equals(parents.get(j))) {
+ //an ancestor is already included
+ return true;
+ }
+ }
+ }
+ return false;
+}
+/**
+ * Returns a collection of all the parents of this element
+ * in bottom-up order.
+ *
+ */
+private ArrayList getAncestors(IRubyElement element) {
+ ArrayList parents = new ArrayList();
+ IRubyElement parent = element.getParent();
+ while (parent != null) {
+ parents.add(parent);
+ parent = parent.getParent();
+ }
+ parents.trimToSize();
+ return parents;
+}
+/**
+ * @see IRegion
+ */
+public IRubyElement[] getElements() {
+ int size= fRootElements.size();
+ IRubyElement[] roots= new IRubyElement[size];
+ for (int i = 0; i < size; i++) {
+ roots[i]= (IRubyElement) fRootElements.get(i);
+ }
+
+ return roots;
+}
+/**
+ * @see IRegion#remove(IRubyElement)
+ */
+public boolean remove(IRubyElement element) {
+
+ removeAllChildren(element);
+ return fRootElements.remove(element);
+}
+/**
+ * Removes any children of this element that are contained within this
+ * region as this parent is about to be added to the region.
+ *
+ * <p>Children are all children, not just direct children.
+ */
+protected void removeAllChildren(IRubyElement element) {
+ if (element instanceof IParent) {
+ ArrayList newRootElements = new ArrayList();
+ for (int i = 0, size = fRootElements.size(); i < size; i++) {
+ IRubyElement currentRoot = (IRubyElement)fRootElements.get(i);
+ //walk the current root hierarchy
+ IRubyElement parent = currentRoot.getParent();
+ boolean isChild= false;
+ while (parent != null) {
+ if (parent.equals(element)) {
+ isChild= true;
+ break;
+ }
+ parent = parent.getParent();
+ }
+ if (!isChild) {
+ newRootElements.add(currentRoot);
+ }
+ }
+ fRootElements= newRootElements;
+ }
+}
+/**
+ * Returns a printable representation of this region.
+ */
+public String toString() {
+ StringBuffer buffer= new StringBuffer();
+ IRubyElement[] roots= getElements();
+ buffer.append('[');
+ for (int i= 0; i < roots.length; i++) {
+ buffer.append(roots[i].getElementName());
+ if (i < (roots.length - 1)) {
+ buffer.append(", "); //$NON-NLS-1$
+ }
+ }
+ buffer.append(']');
+ return buffer.toString();
+}
+}
Modified: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyElement.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyElement.java 2007-07-11 16:52:44 UTC (rev 2748)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/RubyElement.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -627,4 +627,8 @@
buffer.append(character);
}
}
+
+ public IRubyElement unresolved() {
+ return this;
+ }
}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/TypeVector.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/TypeVector.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/TypeVector.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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;
+
+import org.rubypeople.rdt.core.IType;
+
+
+public final class TypeVector {
+ static int INITIAL_SIZE = 10;
+
+ public int size;
+ int maxSize;
+ IType[] elements;
+
+ public final static IType[] NoElements = new IType[0];
+
+public TypeVector() {
+ maxSize = INITIAL_SIZE;
+ size = 0;
+ elements = new IType[maxSize];
+}
+public TypeVector(IType[] types) {
+ this.size = types.length;
+ this.maxSize = this.size + 1; // when an element is added, it assumes that the length is > 0
+ elements = new IType[this.maxSize];
+ System.arraycopy(types, 0, elements, 0, this.size);
+}
+public TypeVector(IType type) {
+ this.maxSize = INITIAL_SIZE;
+ this.size = 1;
+ elements = new IType[this.maxSize];
+ elements[0] = type;
+}
+public void add(IType newElement) {
+ if (size == maxSize) // knows that size starts <= maxSize
+ System.arraycopy(elements, 0, (elements = new IType[maxSize *= 2]), 0, size);
+ elements[size++] = newElement;
+}
+public void addAll(IType[] newElements) {
+ if (size + newElements.length >= maxSize) {
+ maxSize = size + newElements.length; // assume no more elements will be added
+ System.arraycopy(elements, 0, (elements = new IType[maxSize]), 0, size);
+ }
+ System.arraycopy(newElements, 0, elements, size, newElements.length);
+ size += newElements.length;
+}
+public boolean contains(IType element) {
+ for (int i = size; --i >= 0;)
+ if (element.equals(elements[i]))
+ return true;
+ return false;
+}
+public TypeVector copy() {
+ TypeVector clone = new TypeVector();
+ int length = this.elements.length;
+ System.arraycopy(this.elements, 0, clone.elements = new IType[length], 0, length);
+ clone.size = this.size;
+ clone.maxSize = this.maxSize;
+ return clone;
+}
+public IType elementAt(int index) {
+ return elements[index];
+}
+public IType[] elements() {
+
+ // do not resize to 0 if empty since may add more elements later
+ if (this.size == 0) return NoElements;
+
+ if (this.size < this.maxSize) {
+ maxSize = size;
+ System.arraycopy(this.elements, 0, (this.elements = new IType[maxSize]), 0, size);
+ }
+ return this.elements;
+}
+public IType find(IType element) {
+ for (int i = size; --i >= 0;)
+ if (element == elements[i])
+ return elements[i];
+ return null;
+}
+public IType remove(IType 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("["); //$NON-NLS-1$
+ for (int i = 0; i < size; i++) {
+ buffer.append("\n"); //$NON-NLS-1$
+ buffer.append(elements[i]);
+ }
+ buffer.append("\n]"); //$NON-NLS-1$
+ return buffer.toString();
+}
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/ChangeCollector.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/ChangeCollector.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/ChangeCollector.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,448 @@
+/*******************************************************************************
+ * 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.hierarchy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.rubypeople.rdt.core.IImportContainer;
+import org.rubypeople.rdt.core.IImportDeclaration;
+import org.rubypeople.rdt.core.IMember;
+import org.rubypeople.rdt.core.IRubyElement;
+import org.rubypeople.rdt.core.IRubyElementDelta;
+import org.rubypeople.rdt.core.IRubyScript;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.core.RubyElement;
+import org.rubypeople.rdt.internal.core.SimpleDelta;
+
+/*
+ * Collects changes (reported through fine-grained deltas) that can affect a type hierarchy.
+ */
+public class ChangeCollector {
+
+ /*
+ * A table from ITypes to TypeDeltas
+ */
+ HashMap changes = new HashMap();
+
+ TypeHierarchy hierarchy;
+
+ public ChangeCollector(TypeHierarchy hierarchy) {
+ this.hierarchy = hierarchy;
+ }
+
+ /*
+ * Adds the children of the given delta to the list of changes.
+ */
+ private void addAffectedChildren(IRubyElementDelta delta) throws RubyModelException {
+ IRubyElementDelta[] children = delta.getAffectedChildren();
+ for (int i = 0, length = children.length; i < length; i++) {
+ IRubyElementDelta child = children[i];
+ IRubyElement childElement = child.getElement();
+ switch (childElement.getElementType()) {
+ case IRubyElement.IMPORT_CONTAINER:
+ addChange((IImportContainer)childElement, child);
+ break;
+ case IRubyElement.IMPORT_DECLARATION:
+ addChange((IImportDeclaration)childElement, child);
+ break;
+ case IRubyElement.TYPE:
+ addChange((IType)childElement, child);
+ break;
+// case IRubyElement.INITIALIZER:
+ case IRubyElement.FIELD:
+ case IRubyElement.METHOD:
+ addChange((IMember)childElement, child);
+ break;
+ }
+ }
+ }
+
+ /*
+ * Adds the given delta on a compilation unit to the list of changes.
+ */
+ public void addChange(IRubyScript cu, IRubyElementDelta newDelta) throws RubyModelException {
+ int newKind = newDelta.getKind();
+ switch (newKind) {
+ case IRubyElementDelta.ADDED:
+ ArrayList allTypes = new ArrayList();
+ getAllTypesFromElement(cu, allTypes);
+ for (int i = 0, length = allTypes.size(); i < length; i++) {
+ IType type = (IType)allTypes.get(i);
+ addTypeAddition(type, (SimpleDelta)this.changes.get(type));
+ }
+ break;
+ case IRubyElementDelta.REMOVED:
+ allTypes = new ArrayList();
+ getAllTypesFromHierarchy((RubyElement)cu, allTypes);
+ for (int i = 0, length = allTypes.size(); i < length; i++) {
+ IType type = (IType)allTypes.get(i);
+ addTypeRemoval(type, (SimpleDelta)this.changes.get(type));
+ }
+ break;
+ case IRubyElementDelta.CHANGED:
+ addAffectedChildren(newDelta);
+ break;
+ }
+ }
+
+ private void addChange(IImportContainer importContainer, IRubyElementDelta newDelta) throws RubyModelException {
+ int newKind = newDelta.getKind();
+ if (newKind == IRubyElementDelta.CHANGED) {
+ addAffectedChildren(newDelta);
+ return;
+ }
+ SimpleDelta existingDelta = (SimpleDelta)this.changes.get(importContainer);
+ if (existingDelta != null) {
+ switch (newKind) {
+ case IRubyElementDelta.ADDED:
+ if (existingDelta.getKind() == IRubyElementDelta.REMOVED) {
+ // REMOVED then ADDED
+ this.changes.remove(importContainer);
+ }
+ break;
+ case IRubyElementDelta.REMOVED:
+ if (existingDelta.getKind() == IRubyElementDelta.ADDED) {
+ // ADDED then REMOVED
+ this.changes.remove(importContainer);
+ }
+ break;
+ // CHANGED handled above
+ }
+ } else {
+ SimpleDelta delta = new SimpleDelta();
+ switch (newKind) {
+ case IRubyElementDelta.ADDED:
+ delta.added();
+ break;
+ case IRubyElementDelta.REMOVED:
+ delta.removed();
+ break;
+ }
+ this.changes.put(importContainer, delta);
+ }
+ }
+
+ private void addChange(IImportDeclaration importDecl, IRubyElementDelta newDelta) {
+ SimpleDelta existingDelta = (SimpleDelta)this.changes.get(importDecl);
+ int newKind = newDelta.getKind();
+ if (existingDelta != null) {
+ switch (newKind) {
+ case IRubyElementDelta.ADDED:
+ if (existingDelta.getKind() == IRubyElementDelta.REMOVED) {
+ // REMOVED then ADDED
+ this.changes.remove(importDecl);
+ }
+ break;
+ case IRubyElementDelta.REMOVED:
+ if (existingDelta.getKind() == IRubyElementDelta.ADDED) {
+ // ADDED then REMOVED
+ this.changes.remove(importDecl);
+ }
+ break;
+ // CHANGED cannot happen for import declaration
+ }
+ } else {
+ SimpleDelta delta = new SimpleDelta();
+ switch (newKind) {
+ case IRubyElementDelta.ADDED:
+ delta.added();
+ break;
+ case IRubyElementDelta.REMOVED:
+ delta.removed();
+ break;
+ }
+ this.changes.put(importDecl, delta);
+ }
+ }
+
+ /*
+ * Adds a change for the given member (a method, a field or an initializer) and the types it defines.
+ */
+ private void addChange(IMember member, IRubyElementDelta newDelta) throws RubyModelException {
+ int newKind = newDelta.getKind();
+ switch (newKind) {
+ case IRubyElementDelta.ADDED:
+ ArrayList allTypes = new ArrayList();
+ getAllTypesFromElement(member, allTypes);
+ for (int i = 0, length = allTypes.size(); i < length; i++) {
+ IType innerType = (IType)allTypes.get(i);
+ addTypeAddition(innerType, (SimpleDelta)this.changes.get(innerType));
+ }
+ break;
+ case IRubyElementDelta.REMOVED:
+ allTypes = new ArrayList();
+ getAllTypesFromHierarchy((RubyElement)member, allTypes);
+ for (int i = 0, length = allTypes.size(); i < length; i++) {
+ IType type = (IType)allTypes.get(i);
+ addTypeRemoval(type, (SimpleDelta)this.changes.get(type));
+ }
+ break;
+ case IRubyElementDelta.CHANGED:
+ addAffectedChildren(newDelta);
+ break;
+ }
+ }
+
+ /*
+ * Adds a change for the given type and the types it defines.
+ */
+ private void addChange(IType type, IRubyElementDelta newDelta) throws RubyModelException {
+ int newKind = newDelta.getKind();
+ SimpleDelta existingDelta = (SimpleDelta)this.changes.get(type);
+ switch (newKind) {
+ case IRubyElementDelta.ADDED:
+ addTypeAddition(type, existingDelta);
+ ArrayList allTypes = new ArrayList();
+ getAllTypesFromElement(type, allTypes);
+ for (int i = 0, length = allTypes.size(); i < length; i++) {
+ IType innerType = (IType)allTypes.get(i);
+ addTypeAddition(innerType, (SimpleDelta)this.changes.get(innerType));
+ }
+ break;
+ case IRubyElementDelta.REMOVED:
+ addTypeRemoval(type, existingDelta);
+ allTypes = new ArrayList();
+ getAllTypesFromHierarchy((RubyElement)type, allTypes);
+ for (int i = 0, length = allTypes.size(); i < length; i++) {
+ IType innerType = (IType)allTypes.get(i);
+ addTypeRemoval(innerType, (SimpleDelta)this.changes.get(innerType));
+ }
+ break;
+ case IRubyElementDelta.CHANGED:
+ addTypeChange(type, newDelta.getFlags(), existingDelta);
+ addAffectedChildren(newDelta);
+ break;
+ }
+ }
+
+ private void addTypeAddition(IType type, SimpleDelta existingDelta) throws RubyModelException {
+ if (existingDelta != null) {
+ switch (existingDelta.getKind()) {
+ case IRubyElementDelta.REMOVED:
+ // REMOVED then ADDED
+ boolean hasChange = false;
+ if (hasSuperTypeChange(type)) {
+ existingDelta.superTypes();
+ hasChange = true;
+ }
+ if (hasVisibilityChange(type)) {
+ existingDelta.modifiers();
+ hasChange = true;
+ }
+ if (!hasChange) {
+ this.changes.remove(type);
+ }
+ break;
+ // CHANGED then ADDED
+ // or ADDED then ADDED: should not happen
+ }
+ } else {
+ // check whether the type addition affects the hierarchy
+ String typeName = type.getElementName();
+ if (this.hierarchy.hasSupertype(typeName)
+ || this.hierarchy.subtypesIncludeSupertypeOf(type)
+ || this.hierarchy.missingTypes.contains(typeName)) {
+ SimpleDelta delta = new SimpleDelta();
+ delta.added();
+ this.changes.put(type, delta);
+ }
+ }
+ }
+
+ private void addTypeChange(IType type, int newFlags, SimpleDelta existingDelta) throws RubyModelException {
+ if (existingDelta != null) {
+ switch (existingDelta.getKind()) {
+ case IRubyElementDelta.CHANGED:
+ // CHANGED then CHANGED
+ int existingFlags = existingDelta.getFlags();
+ boolean hasChange = false;
+ if ((existingFlags & IRubyElementDelta.F_SUPER_TYPES) != 0
+ && hasSuperTypeChange(type)) {
+ existingDelta.superTypes();
+ hasChange = true;
+ }
+ if ((existingFlags & IRubyElementDelta.F_MODIFIERS) != 0
+ && hasVisibilityChange(type)) {
+ existingDelta.modifiers();
+ hasChange = true;
+ }
+ if (!hasChange) {
+ // super types and visibility are back to the ones in the existing hierarchy
+ this.changes.remove(type);
+ }
+ break;
+ // ADDED then CHANGED: leave it as ADDED
+ // REMOVED then CHANGED: should not happen
+ }
+ } else {
+ // check whether the type change affects the hierarchy
+ SimpleDelta typeDelta = null;
+ if ((newFlags & IRubyElementDelta.F_SUPER_TYPES) != 0
+ && this.hierarchy.includesTypeOrSupertype(type)) {
+ typeDelta = new SimpleDelta();
+ typeDelta.superTypes();
+ }
+ if ((newFlags & IRubyElementDelta.F_MODIFIERS) != 0
+ && (this.hierarchy.hasSupertype(type.getElementName())
+ || type.equals(this.hierarchy.focusType))) {
+ if (typeDelta == null) {
+ typeDelta = new SimpleDelta();
+ }
+ typeDelta.modifiers();
+ }
+ if (typeDelta != null) {
+ this.changes.put(type, typeDelta);
+ }
+ }
+ }
+
+ private void addTypeRemoval(IType type, SimpleDelta existingDelta) {
+ if (existingDelta != null) {
+ switch (existingDelta.getKind()) {
+ case IRubyElementDelta.ADDED:
+ // ADDED then REMOVED
+ this.changes.remove(type);
+ break;
+ case IRubyElementDelta.CHANGED:
+ // CHANGED then REMOVED
+ existingDelta.removed();
+ break;
+ // REMOVED then REMOVED: should not happen
+ }
+ } else {
+ // check whether the type removal affects the hierarchy
+ if (this.hierarchy.contains(type)) {
+ SimpleDelta typeDelta = new SimpleDelta();
+ typeDelta.removed();
+ this.changes.put(type, typeDelta);
+ }
+ }
+ }
+
+ /*
+ * Returns all types defined in the given element excluding the given element.
+ */
+ private void getAllTypesFromElement(IRubyElement element, ArrayList allTypes) throws RubyModelException {
+ switch (element.getElementType()) {
+ case IRubyElement.SCRIPT:
+ IType[] types = ((IRubyScript)element).getTypes();
+ for (int i = 0, length = types.length; i < length; i++) {
+ IType type = types[i];
+ allTypes.add(type);
+ getAllTypesFromElement(type, allTypes);
+ }
+ break;
+ case IRubyElement.TYPE:
+ types = ((IType)element).getTypes();
+ for (int i = 0, length = types.length; i < length; i++) {
+ IType type = types[i];
+ allTypes.add(type);
+ getAllTypesFromElement(type, allTypes);
+ }
+ break;
+// case IRubyElement.INITIALIZER:
+ case IRubyElement.FIELD:
+ case IRubyElement.METHOD:
+ IRubyElement[] children = ((IMember)element).getChildren();
+ for (int i = 0, length = children.length; i < length; i++) {
+ IType type = (IType)children[i];
+ allTypes.add(type);
+ getAllTypesFromElement(type, allTypes);
+ }
+ break;
+ }
+ }
+
+ /*
+ * Returns all types in the existing hierarchy that have the given element as a parent.
+ */
+ private void getAllTypesFromHierarchy(RubyElement element, ArrayList allTypes) {
+ switch (element.getElementType()) {
+ case IRubyElement.SCRIPT:
+ ArrayList types = (ArrayList)this.hierarchy.files.get(element);
+ if (types != null) {
+ allTypes.addAll(types);
+ }
+ break;
+ case IRubyElement.TYPE:
+// case IRubyElement.INITIALIZER:
+ case IRubyElement.FIELD:
+ case IRubyElement.METHOD:
+ types = (ArrayList)this.hierarchy.files.get(((IMember)element).getRubyScript());
+ if (types != null) {
+ for (int i = 0, length = types.size(); i < length; i++) {
+ IType type = (IType)types.get(i);
+ if (element.isAncestorOf(type)) {
+ allTypes.add(type);
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ private boolean hasSuperTypeChange(IType type) throws RubyModelException {
+ // check super class
+ IType superclass = this.hierarchy.getSuperclass(type);
+ String existingSuperclassName = superclass == null ? null : superclass.getElementName();
+ String newSuperclassName = type.getSuperclassName();
+ if (existingSuperclassName != null && !existingSuperclassName.equals(newSuperclassName)) {
+ return true;
+ }
+
+ // check super interfaces
+ IType[] existingSuperInterfaces = this.hierarchy.getSuperInterfaces(type);
+ String[] newSuperInterfaces = type.getIncludedModuleNames();
+ if (existingSuperInterfaces.length != newSuperInterfaces.length) {
+ return true;
+ }
+ for (int i = 0, length = newSuperInterfaces.length; i < length; i++) {
+ String superInterfaceName = newSuperInterfaces[i];
+ if (!superInterfaceName.equals(newSuperInterfaces[i])) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean hasVisibilityChange(IType type) throws RubyModelException {
+// int existingFlags = this.hierarchy.getCachedFlags(type);
+// int newFlags = type.getFlags();
+// return existingFlags != newFlags;
+ return false; // FIXME Types don't have visibility options in Ruby! We shouldn't even ask this.
+ }
+
+ /*
+ * Whether the hierarchy needs refresh according to the changes collected so far.
+ */
+ public boolean needsRefresh() {
+ return changes.size() != 0;
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ Iterator iterator = this.changes.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = (Map.Entry)iterator.next();
+ buffer.append(((RubyElement)entry.getKey()).toDebugString());
+ buffer.append(entry.getValue());
+ if (iterator.hasNext()) {
+ buffer.append('\n');
+ }
+ }
+ return buffer.toString();
+ }
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyBuilder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyBuilder.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyBuilder.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * 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.hierarchy;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.core.RubyElement;
+import org.rubypeople.rdt.internal.core.RubyProject;
+
+
+
+public abstract class HierarchyBuilder {
+ /**
+ * The hierarchy being built.
+ */
+ protected TypeHierarchy hierarchy;
+
+ /**
+ * A temporary cache of infos to handles to speed info
+ * to handle translation - it only contains the entries
+ * for the types in the region (in other words, it contains
+ * no supertypes outside the region).
+ */
+ protected Map infoToHandle;
+ /*
+ * The dot-separated fully qualified name of the focus type, or null of none.
+ */
+ protected String focusQualifiedName;
+
+ protected HierarchyResolver hierarchyResolver;
+
+ public HierarchyBuilder(TypeHierarchy hierarchy) throws RubyModelException {
+
+ this.hierarchy = hierarchy;
+ RubyProject project = (RubyProject) hierarchy.javaProject();
+
+ IType focusType = hierarchy.getType();
+ org.rubypeople.rdt.core.IRubyScript unitToLookInside = focusType == null ? null : focusType.getRubyScript();
+ org.rubypeople.rdt.core.IRubyScript[] workingCopies = this.hierarchy.workingCopies;
+ org.rubypeople.rdt.core.IRubyScript[] unitsToLookInside;
+ if (unitToLookInside != null) {
+ int wcLength = workingCopies == null ? 0 : workingCopies.length;
+ if (wcLength == 0) {
+ unitsToLookInside = new org.rubypeople.rdt.core.IRubyScript[] {unitToLookInside};
+ } else {
+ unitsToLookInside = new org.rubypeople.rdt.core.IRubyScript[wcLength+1];
+ unitsToLookInside[0] = unitToLookInside;
+ System.arraycopy(workingCopies, 0, unitsToLookInside, 1, wcLength);
+ }
+ } else {
+ unitsToLookInside = workingCopies;
+ }
+ if (project != null) {
+// SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(unitsToLookInside);
+// this.nameLookup = searchableEnvironment.nameLookup;
+ this.hierarchyResolver =
+ new HierarchyResolver(
+// searchableEnvironment,
+ project.getOptions(true),
+ this
+ );
+// new DefaultProblemFactory());
+ }
+ this.infoToHandle = new HashMap(5);
+ this.focusQualifiedName = focusType == null ? null : focusType.getFullyQualifiedName();
+ }
+
+ public abstract void build(boolean computeSubtypes)
+ throws RubyModelException, CoreException;
+
+ /**
+ * Connect the supplied type to its superclass & superinterfaces.
+ * The superclass & superinterfaces are the identical binary or source types as
+ * supplied by the name environment.
+ */
+ public void connect(
+ IType typeHandle,
+ IType superclassHandle,
+ IType[] superinterfaceHandles) {
+
+ /*
+ * Temporary workaround for 1G2O5WK: ITPJCORE:WINNT - NullPointerException when selecting "Show in Type Hierarchy" for a inner class
+ */
+ if (typeHandle == null)
+ return;
+ if (TypeHierarchy.DEBUG) {
+ System.out.println(
+ "Connecting: " + ((RubyElement) typeHandle).toStringWithAncestors()); //$NON-NLS-1$
+ System.out.println(
+ " to superclass: " //$NON-NLS-1$
+ + (superclassHandle == null
+ ? "<None>" //$NON-NLS-1$
+ : ((RubyElement) superclassHandle).toStringWithAncestors()));
+ System.out.print(" and superinterfaces:"); //$NON-NLS-1$
+ if (superinterfaceHandles == null || superinterfaceHandles.length == 0) {
+ System.out.println(" <None>"); //$NON-NLS-1$
+ } else {
+ System.out.println();
+ for (int i = 0, length = superinterfaceHandles.length; i < length; i++) {
+ if (superinterfaceHandles[i] == null) continue;
+ System.out.println(
+ " " + ((RubyElement) superinterfaceHandles[i]).toStringWithAncestors()); //$NON-NLS-1$
+ }
+ }
+ }
+ // now do the caching
+ if (typeHandle.isModule()) {
+ this.hierarchy.addInterface(typeHandle);
+ } else {
+ if (superclassHandle == null) {
+ this.hierarchy.addRootClass(typeHandle);
+ } else {
+ this.hierarchy.cacheSuperclass(typeHandle, superclassHandle);
+ }
+ }
+ if (superinterfaceHandles == null) {
+ superinterfaceHandles = TypeHierarchy.NO_TYPE;
+ }
+ this.hierarchy.cacheSuperInterfaces(typeHandle, superinterfaceHandles);
+
+ // record flags
+ this.hierarchy.cacheFlags(typeHandle, /*type.getModifiers()*/ 0 );
+ }
+
+ protected IType getType() {
+ return this.hierarchy.getType();
+ }
+
+
+ /**
+ * Configure this type hierarchy by computing the supertypes only.
+ */
+ protected void buildSupertypes() {
+ IType focusType = this.getType();
+ if (focusType == null)
+ return;
+ // get generic type from focus type
+// IGenericType type;
+// try {
+// type = (IGenericType) ((JavaElement) focusType).getElementInfo();
+// } catch (JavaModelException e) {
+// // if the focus type is not present, or if cannot get workbench path
+// // we cannot create the hierarchy
+// return;
+// }
+ //NB: no need to set focus type on hierarchy resolver since no other type is injected
+ // in the hierarchy resolver, thus there is no need to check that a type is
+ // a sub or super type of the focus type.
+ this.hierarchyResolver.resolve(focusType);
+
+ // Add focus if not already in (case of a type with no explicit super type)
+ if (!this.hierarchy.contains(focusType)) {
+ this.hierarchy.addRootClass(focusType);
+ }
+ }
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyResolver.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyResolver.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/HierarchyResolver.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,114 @@
+package org.rubypeople.rdt.internal.core.hierarchy;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.internal.codeassist.RubyElementRequestor;
+import org.rubypeople.rdt.internal.core.LogicalType;
+import org.rubypeople.rdt.internal.core.Openable;
+
+public class HierarchyResolver {
+
+ private boolean superTypesOnly;
+ private HierarchyBuilder builder;
+
+ public HierarchyResolver(Map options, HierarchyBuilder builder) {
+ this.builder = builder;
+ }
+
+ public void resolve(Openable[] openables, HashSet localTypes, IProgressMonitor monitor) {
+ try {
+ int openablesLength = openables.length;
+ boolean[] hasLocalType = new boolean[openablesLength];
+ org.rubypeople.rdt.core.IRubyScript[] cus = new org.rubypeople.rdt.core.IRubyScript[openablesLength];
+ int unitsIndex = 0;
+
+ IType focus = this.builder.getType();
+ Openable focusOpenable = null;
+ if (focus != null) {
+ focusOpenable = (Openable)focus.getRubyScript();
+ }
+
+ for (int i = 0; i < openablesLength; i++) {
+ Openable openable = openables[i];
+ if (openable instanceof org.rubypeople.rdt.core.IRubyScript) {
+ org.rubypeople.rdt.core.IRubyScript cu = (org.rubypeople.rdt.core.IRubyScript)openable;
+
+ // contains a potential subtype as a local or anonymous type?
+ boolean containsLocalType = false;
+ if (localTypes == null) { // case of hierarchy on region
+ containsLocalType = true;
+ } else {
+ IPath path = cu.getPath();
+ containsLocalType = localTypes.contains(path.toString());
+ }
+
+ // Grab the types from the script and then connect them up!
+ IType[] types = cu.getAllTypes();
+ for (int j = 0; j < types.length; j++) {
+ try {
+ reportHierarchy(types[i]);
+ } catch (RubyModelException e) {
+ // ignore
+ }
+ }
+ }
+ }
+ } catch (ClassCastException e){ // work-around for 1GF5W1S - can happen in case duplicates are fed to the hierarchy with binaries hiding sources
+ } catch (RubyModelException e){
+ } finally {
+ reset();
+ }
+ }
+
+ private void reportHierarchy(IType type) throws RubyModelException {
+ IType superclass;
+ if (type.isModule()){ // do not connect interfaces to Object
+ superclass = null;
+ } else {
+ superclass = findSuperClass(type);
+ }
+ IType[] superinterfaces = findSuperInterfaces(type);
+
+ this.builder.connect(type, superclass, superinterfaces);
+ }
+
+ private IType[] findSuperInterfaces(IType type) throws RubyModelException {
+ String[] names = type.getIncludedModuleNames();
+ List<IType> types = new ArrayList<IType>();
+ for (int i = 0; i < names.length; i++) {
+ types.add(getLogicalType(type, names[i]));
+ }
+ return (IType[]) types.toArray(new IType[types.size()]);
+ }
+
+ private IType findSuperClass(IType type) throws RubyModelException {
+ String name = type.getSuperclassName();
+ return getLogicalType(type, name);
+ }
+
+ private IType getLogicalType(IType type, String name) {
+ RubyElementRequestor requestor = new RubyElementRequestor(type.getRubyScript());
+ return new LogicalType(requestor.findType(name));
+ }
+
+ private void reset() {
+// this.focusType = null;
+ this.superTypesOnly = false;
+ }
+
+ public void resolve(IType type) {
+ org.rubypeople.rdt.core.IRubyScript cu = type.getRubyScript();
+ HashSet localTypes = new HashSet();
+ localTypes.add(cu.getPath().toString());
+ this.superTypesOnly = true;
+ resolve(new Openable[] {(Openable)cu}, localTypes, null);
+ }
+
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/IndexBasedHierarchyBuilder.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,430 @@
+package org.rubypeople.rdt.internal.core.hierarchy;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.rubypeople.rdt.core.IRubyProject;
+import org.rubypeople.rdt.core.IType;
+import org.rubypeople.rdt.core.RubyModelException;
+import org.rubypeople.rdt.core.search.IRubySearchConstants;
+import org.rubypeople.rdt.core.search.IRubySearchScope;
+import org.rubypeople.rdt.core.search.SearchParticipant;
+import org.rubypeople.rdt.core.search.SearchPattern;
+import org.rubypeople.rdt.internal.compiler.util.HashtableOfObject;
+import org.rubypeople.rdt.internal.core.IPathRequestor;
+import org.rubypeople.rdt.internal.core.Member;
+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.SourceFolder;
+import org.rubypeople.rdt.internal.core.search.HandleFactory;
+import org.rubypeople.rdt.internal.core.search.IndexQueryRequestor;
+import org.rubypeople.rdt.internal.core.search.RubySearchParticipant;
+import org.rubypeople.rdt.internal.core.search.SubTypeSearchJob;
+import org.rubypeople.rdt.internal.core.search.indexing.IIndexConstants;
+import org.rubypeople.rdt.internal.core.search.indexing.IndexManager;
+import org.rubypeople.rdt.internal.core.search.matching.MatchLocator;
+import org.rubypeople.rdt.internal.core.search.matching.SuperTypeReferencePattern;
+import org.rubypeople.rdt.internal.core.util.CharOperation;
+
+public class IndexBasedHierarchyBuilder extends HierarchyBuilder {
+ public static final int MAXTICKS = 800; // heuristic so that there still progress for deep hierachies
+
+ private IRubySearchScope scope;
+ private HashMap binariesFromIndexMatches;
+
+ public IndexBasedHierarchyBuilder(TypeHierarchy hierarchy, IRubySearchScope scope) throws RubyModelException {
+ super(hierarchy);
+ this.binariesFromIndexMatches = new HashMap(10);
+ this.scope = scope;
+ }
+
+ @Override
+ public void build(boolean computeSubtypes) throws RubyModelException,
+ CoreException {
+
+ if (computeSubtypes) {
+ // Note by construction there always is a focus type here
+ IType focusType = getType();
+ boolean focusIsObject = focusType.getElementName().equals(new String(IIndexConstants.OBJECT));
+ int amountOfWorkForSubtypes = focusIsObject ? 5 : 80; // percentage of work needed to get possible subtypes
+ IProgressMonitor possibleSubtypesMonitor =
+ this.hierarchy.progressMonitor == null ?
+ null :
+ new SubProgressMonitor(this.hierarchy.progressMonitor, amountOfWorkForSubtypes);
+ HashSet localTypes = new HashSet(10); // contains the paths that have potential subtypes that are local/anonymous types
+ String[] allPossibleSubtypes;
+ if (((Member)focusType).getOuterMostLocalContext() == null) {
+ // top level or member type
+ allPossibleSubtypes = this.determinePossibleSubTypes(localTypes, possibleSubtypesMonitor);
+ } else {
+ // local or anonymous type
+ allPossibleSubtypes = new String[0];
+ }
+ if (allPossibleSubtypes != null) {
+ IProgressMonitor buildMonitor =
+ this.hierarchy.progressMonitor == null ?
+ null :
+ new SubProgressMonitor(this.hierarchy.progressMonitor, 100 - amountOfWorkForSubtypes);
+ this.hierarchy.initialize(allPossibleSubtypes.length);
+ buildFromPotentialSubtypes(allPossibleSubtypes, localTypes, buildMonitor);
+ }
+ } else {
+ this.hierarchy.initialize(1);
+ this.buildSupertypes();
+ }
+ }
+
+ /**
+ * Configure this type hierarchy based on the given potential subtypes.
+ */
+ private void buildFromPotentialSubtypes(String[] allPotentialSubTypes, HashSet localTypes, IProgressMonitor monitor) {
+ IType focusType = this.getType();
+
+ // substitute compilation units with working copies
+ HashMap wcPaths = new HashMap(); // a map from path to working copies
+ int wcLength;
+ org.rubypeople.rdt.core.IRubyScript[] workingCopies = this.hierarchy.workingCopies;
+ if (workingCopies != null && (wcLength = workingCopies.length) > 0) {
+ String[] newPaths = new String[wcLength];
+ for (int i = 0; i < wcLength; i++) {
+ org.rubypeople.rdt.core.IRubyScript workingCopy = workingCopies[i];
+ String path = workingCopy.getPath().toString();
+ wcPaths.put(path, workingCopy);
+ newPaths[i] = path;
+ }
+ int potentialSubtypesLength = allPotentialSubTypes.length;
+ System.arraycopy(allPotentialSubTypes, 0, allPotentialSubTypes = new String[potentialSubtypesLength+wcLength], 0, potentialSubtypesLength);
+ System.arraycopy(newPaths, 0, allPotentialSubTypes, potentialSubtypesLength, wcLength);
+ }
+
+ int length = allPotentialSubTypes.length;
+
+ // inject the compilation unit of the focus type (so that types in
+ // this cu have special visibility permission (this is also usefull
+ // when the cu is a working copy)
+ Openable focusCU = (Openable)focusType.getRubyScript();
+ String focusPath = null;
+ if (focusCU != null) {
+ focusPath = focusCU.getPath().toString();
+ if (length > 0) {
+ System.arraycopy(allPotentialSubTypes, 0, allPotentialSubTypes = new String[length+1], 0, length);
+ allPotentialSubTypes[length] = focusPath;
+ } else {
+ allPotentialSubTypes = new String[] {focusPath};
+ }
+ length++;
+ }
+
+ // sort by projects
+ /*
+ * NOTE: To workaround pb with hierarchy resolver that requests top
+ * level types in the process of caching an enclosing type, this needs to
+ * be sorted in reverse alphabetical order so that top level types are cached
+ * before their inner types.
+ */
+ org.rubypeople.rdt.internal.core.util.Util.sortReverseOrder(allPotentialSubTypes);
+
+ ArrayList potentialSubtypes = new ArrayList();
+
+ try {
+ // create element infos for subtypes
+ HandleFactory factory = new HandleFactory();
+ IRubyProject currentProject = null;
+ if (monitor != null) monitor.beginTask("", length*2 /* 1 for build binding, 1 for connect hierarchy*/); //$NON-NLS-1$
+ for (int i = 0; i < length; i++) {
+ try {
+ String resourcePath = allPotentialSubTypes[i];
+
+ // skip duplicate paths (e.g. if focus path was injected when it was already a potential subtype)
+ if (i > 0 && resourcePath.equals(allPotentialSubTypes[i-1])) continue;
+
+ Openable handle;
+ org.rubypeople.rdt.core.IRubyScript workingCopy = (org.rubypeople.rdt.core.IRubyScript)wcPaths.get(resourcePath);
+ if (workingCopy != null) {
+ handle = (Openable)workingCopy;
+ } else {
+ handle =
+ resourcePath.equals(focusPath) ?
+ focusCU :
+ factory.createOpenable(resourcePath);
+ if (handle == null) continue; // match is outside loadpath
+ }
+
+ IRubyProject project = handle.getRubyProject();
+ if (currentProject == null) {
+ currentProject = project;
+ potentialSubtypes = new ArrayList(5);
+ } else if (!currentProject.equals(project)) {
+ // build current project
+ this.buildForProject((RubyProject)currentProject, potentialSubtypes, workingCopies, localTypes, monitor);
+ currentProject = project;
+ potentialSubtypes = new ArrayList(5);
+ }
+
+ potentialSubtypes.add(handle);
+ } catch (RubyModelException e) {
+ continue;
+ }
+ }
+
+ // build last project
+ try {
+ if (currentProject == null) {
+ // case of no potential subtypes
+ currentProject = focusType.getRubyProject();
+ potentialSubtypes.add(focusType.getRubyScript());
+ }
+ this.buildForProject((RubyProject)currentProject, potentialSubtypes, workingCopies, localTypes, monitor);
+ } catch (RubyModelException e) {
+ // ignore
+ }
+
+ // Compute hierarchy of focus type if not already done (case of a type with potential subtypes that are not real subtypes)
+ if (!this.hierarchy.contains(focusType)) {
+ try {
+ currentProject = focusType.getRubyProject();
+ potentialSubtypes = new ArrayList();
+ potentialSubtypes.add(focusType.getRubyScript());
+
+ this.buildForProject((RubyProject)currentProject, potentialSubtypes, workingCopies, localTypes, monitor);
+ } catch (RubyModelException e) {
+ // ignore
+ }
+ }
+
+ // Add focus if not already in (case of a type with no explicit super type)
+ if (!this.hierarchy.contains(focusType)) {
+ this.hierarchy.addRootClass(focusType);
+ }
+ } finally {
+ if (monitor != null) monitor.done();
+ }
+ }
+
+ private void buildForProject(RubyProject project, ArrayList potentialSubtypes, org.rubypeople.rdt.core.IRubyScript[] workingCopies, HashSet localTypes, IProgressMonitor monitor) throws RubyModelException {
+ // copy vectors into arrays
+ int openablesLength = potentialSubtypes.size();
+ Openable[] openables = new Openable[openablesLength];
+ potentialSubtypes.toArray(openables);
+
+ // resolve
+ if (openablesLength > 0) {
+ IType focusType = this.getType();
+ boolean inProjectOfFocusType = focusType != null && focusType.getRubyProject().equals(project);
+ org.rubypeople.rdt.core.IRubyScript[] unitsToLookInside = null;
+ if (inProjectOfFocusType) {
+ org.rubypeople.rdt.core.IRubyScript unitToLookInside = focusType.getRubyScript();
+ if (unitToLookInside != null) {
+ int wcLength = workingCopies == null ? 0 : workingCopies.length;
+ if (wcLength == 0) {
+ unitsToLookInside = new org.rubypeople.rdt.core.IRubyScript[] {unitToLookInside};
+ } else {
+ unitsToLookInside = new org.rubypeople.rdt.core.IRubyScript[wcLength+1];
+ unitsToLookInside[0] = unitToLookInside;
+ System.arraycopy(workingCopies, 0, unitsToLookInside, 1, wcLength);
+ }
+ } else {
+ unitsToLookInside = workingCopies;
+ }
+ }
+
+// SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(unitsToLookInside);
+// this.nameLookup = searchableEnvironment.nameLookup;
+// Map options = project.getOptions(true);
+// // disable task tags to speed up parsing
+// options.put(RubyCore.COMPILER_TASK_TAGS, ""); //$NON-NLS-1$
+// this.hierarchyResolver =
+// new HierarchyResolver(searchableEnvironment, options, this, new DefaultProblemFactory());
+ if (focusType != null) {
+ Member declaringMember = ((Member)focusType).getOuterMostLocalContext();
+ if (declaringMember == null) {
+ // top level or member type
+ if (!inProjectOfFocusType) {
+ char[] typeQualifiedName = focusType.getTypeQualifiedName("::").toCharArray();
+ String[] packageName = ((SourceFolder) focusType.getSourceFolder()).names;
+// if (searchableEnvironment.findType(typeQualifiedName, Util.toCharArrays(packageName)) == null) {
+// // focus type is not visible in this project: no need to go further
+// return;
+// }
+ }
+ } else {
+ // local or anonymous type
+ Openable openable;
+ openable = (Openable)declaringMember.getRubyScript();
+
+ localTypes = new HashSet();
+ localTypes.add(openable.getPath().toString());
+ this.hierarchyResolver.resolve(new Openable[] {openable}, localTypes, monitor);
+ return;
+ }
+ }
+ this.hierarchyResolver.resolve(openables, localTypes, monitor);
+ }
+ }
+
+ /**
+ * Returns all of the possible subtypes of this type hierarchy.
+ * Returns null if they could not be determine.
+ */
+ private String[] determinePossibleSubTypes(final HashSet localTypes, IProgressMonitor monitor) {
+
+ class PathCollector implements IPathRequestor {
+ HashSet paths = new HashSet(10);
+ public void acceptPath(String path, boolean containsLocalTypes) {
+ this.paths.add(path);
+ if (containsLocalTypes) {
+ localTypes.add(path);
+ }
+ }
+ }
+ PathCollector collector = new PathCollector();
+
+ try {
+ if (monitor != null) monitor.beginTask("", MAXTICKS); //$NON-NLS-1$
+ searchAllPossibleSubTypes(
+ this.getType(),
+ this.scope,
+ this.binariesFromIndexMatches,
+ collector,
+ IRubySearchConstants.WAIT_UNTIL_READY_TO_SEARCH,
+ monitor);
+ } finally {
+ if (monitor != null) monitor.done();
+ }
+
+ HashSet paths = collector.paths;
+ int length = paths.size();
+ String[] result = new String[length];
+ int count = 0;
+ for (Iterator iter = paths.iterator(); iter.hasNext();) {
+ result[count++] = (String) iter.next();
+ }
+ return result;
+ }
+
+ /**
+ * Collection used to queue subtype index queries
+ */
+ static class Queue {
+ public char[][] names = new char[10][];
+ public int start = 0;
+ public int end = -1;
+ public void add(char[] name){
+ if (++this.end == this.names.length){
+ this.end -= this.start;
+ System.arraycopy(this.names, this.start, this.names = new char[this.end*2][], 0, this.end);
+ this.start = 0;
+ }
+ this.names[this.end] = name;
+ }
+ public char[] retrieve(){
+ if (this.start > this.end) return null; // none
+
+ char[] name = this.names[this.start++];
+ if (this.start > this.end){
+ this.start = 0;
+ this.end = -1;
+ }
+ return name;
+ }
+ public String toString(){
+ StringBuffer buffer = new StringBuffer("Queue:\n"); //$NON-NLS-1$
+ for (int i = this.start; i <= this.end; i++){
+ buffer.append(this.names[i]).append('\n');
+ }
+ return buffer.toString();
+ }
+ }
+
+ /**
+ * Find the set of candidate subtypes of a given type.
+ *
+ * The requestor is notified of super type references (with actual path of
+ * its occurrence) for all types which are potentially involved inside a particular
+ * hierarchy.
+ * The match locator is not used here to narrow down the results, the type hierarchy
+ * resolver is rather used to compute the whole hierarchy at once.
+ * @param type
+ * @param scope
+ * @param binariesFromIndexMatches
+ * @param pathRequestor
+ * @param waitingPolicy
+ * @param progressMonitor
+ */
+ public static void searchAllPossibleSubTypes(
+ IType type,
+ IRubySearchScope scope,
+ final Map binariesFromIndexMatches,
+ final IPathRequestor pathRequestor,
+ int waitingPolicy, // WaitUntilReadyToSearch | ForceImmediateSearch | CancelIfNotReadyToSearch
+ IProgressMonitor progressMonitor) {
+
+ /* embed constructs inside arrays so as to pass them to (inner) collector */
+ final Queue queue = new Queue();
+ final HashtableOfObject foundSuperNames = new HashtableOfObject(5);
+
+ IndexManager indexManager = RubyModelManager.getRubyModelManager().getIndexManager();
+
+ /* use a special collector to collect paths and queue new subtype names */
+ IndexQueryRequestor searchRequestor = new IndexQueryRequestor() {
+ public boolean acceptIndexMatch(String documentPath, SearchPattern indexRecord, SearchParticipant participant) {
+ SuperTypeReferencePattern record = (SuperTypeReferencePattern)indexRecord;
+ boolean isLocalOrAnonymous = record.enclosingTypeName == IIndexConstants.ONE_ZERO;
+ pathRequestor.acceptPath(documentPath, isLocalOrAnonymous);
+ char[] typeName = record.simpleName;
+ if (!isLocalOrAnonymous // local or anonymous types cannot have subtypes outside the cu that define them
+ && !foundSuperNames.containsKey(typeName)){
+ foundSuperNames.put(typeName, typeName);
+ queue.add(typeName);
+ }
+ return true;
+ }
+ };
+
+ int superRefKind;
+// try {
+ superRefKind = type.isClass() ? SuperTypeReferencePattern.ONLY_SUPER_CLASSES : SuperTypeReferencePattern.ALL_SUPER_TYPES;
+// } catch (RubyModelException e) {
+// superRefKind = SuperTypeReferencePattern.ALL_SUPER_TYPES;
+// }
+ SuperTypeReferencePattern pattern =
+ new SuperTypeReferencePattern(null, null, superRefKind, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
+ MatchLocator.setFocus(pattern, type);
+ SubTypeSearchJob job = new SubTypeSearchJob(
+ pattern,
+ new RubySearchParticipant(), // ruby search only
+ scope,
+ searchRequestor);
+
+ int ticks = 0;
+ queue.add(type.getElementName().toCharArray());
+ try {
+ while (queue.start <= queue.end) {
+ if (progressMonitor != null && progressMonitor.isCanceled()) return;
+
+ // all subclasses of OBJECT are actually all types
+ char[] currentTypeName = queue.retrieve();
+ if (CharOperation.equals(currentTypeName, IIndexConstants.OBJECT))
+ currentTypeName = null;
+
+ // search all index references to a given supertype
+ pattern.superSimpleName = currentTypeName;
+ indexManager.performConcurrentJob(job, waitingPolicy, null); // no sub progress monitor since its too costly for deep hierarchies
+ if (progressMonitor != null && ++ticks <= MAXTICKS)
+ progressMonitor.worked(1);
+
+ // in case, we search all subtypes, no need to search further
+ if (currentTypeName == null) break;
+ }
+ } finally {
+ job.finished();
+ }
+ }
+}
Added: trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/TypeHierarchy.java
===================================================================
--- trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/TypeHierarchy.java (rev 0)
+++ trunk/org.rubypeople.rdt.core/src/org/rubypeople/rdt/internal/core/hierarchy/TypeHierarchy.java 2007-07-11 20:32:07 UTC (rev 2749)
@@ -0,0 +1,1522 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. Thi...
[truncated message content] |
|
From: <caw...@us...> - 2007-07-11 16:52:49
|
Revision: 2748
http://svn.sourceforge.net/rubyeclipse/?rev=2748&view=rev
Author: cawilliams
Date: 2007-07-11 09:52:44 -0700 (Wed, 11 Jul 2007)
Log Message:
-----------
improve test, fix tertiary conditional with no spaces
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyTokenScanner.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/ruby/TC_RubyTokenScanner.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyTokenScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyTokenScanner.java 2007-07-11 16:08:23 UTC (rev 2747)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/ruby/RubyTokenScanner.java 2007-07-11 16:52:44 UTC (rev 2748)
@@ -44,15 +44,17 @@
private RubyYaccLexer lexer;
private LexerSource lexerSource;
private ParserSupport parserSupport;
- private int tokenLength;
- private int oldOffset;
+
+ private int fTokenLength;
+ private int fOffset;
+
private boolean isInRegexp;
private boolean isInSymbol;
private boolean inAlias;
private RubyParserResult result;
private int origOffset;
private int origLength;
- private String contents;
+ private String fContents;
public RubyTokenScanner(IColorManager manager, IPreferenceStore store) {
super(manager, store);
@@ -67,16 +69,16 @@
}
public int getTokenLength() {
- return tokenLength;
+ return fTokenLength;
}
public int getTokenOffset() {
- return oldOffset;
+ return fOffset;
}
public IToken nextToken() {
- oldOffset = getOffset();
- tokenLength = 0;
+ fOffset = getOffset();
+ fTokenLength = 0;
IToken returnValue = getToken(IRubyColorConstants.RUBY_DEFAULT);
boolean isEOF = false;
try {
@@ -84,22 +86,22 @@
if (isEOF) {
returnValue = Token.EOF;
} else {
+ fTokenLength = getOffset() - fOffset;
returnValue = token(lexer.token());
}
} catch (SyntaxException se) {
if (lexerSource.getOffset() - origLength == 0)
return Token.EOF; // return eof if we hit a problem found at
// end of parsing
- tokenLength = getOffset() - oldOffset;
+ fTokenLength = getOffset() - fOffset;
return getToken(IRubyColorConstants.RUBY_ERROR);
} catch (NumberFormatException nfe) {
- tokenLength = getOffset() - oldOffset;
+ fTokenLength = getOffset() - fOffset;
return returnValue;
} catch (IOException e) {
RubyPlugin.log(e);
}
- if (!isEOF)
- tokenLength = getOffset() - oldOffset;
+
return returnValue;
}
@@ -109,10 +111,10 @@
private Token doGetToken(String key) {
if (isInSymbol)
- return super.getToken(IRubyColorConstants.RUBY_SYMBOL);
+ return getToken(IRubyColorConstants.RUBY_SYMBOL);
if (isInRegexp)
- return super.getToken(IRubyColorConstants.RUBY_REGEXP);
- return super.getToken(key);
+ return getToken(IRubyColorConstants.RUBY_REGEXP);
+ return getToken(key);
}
private IToken token(int i) {
@@ -137,7 +139,10 @@
if (isKeyword(i))
return doGetToken(IRubyColorConstants.RUBY_KEYWORD);
switch (i) {
- case Tokens.tSYMBEG:
+ case Tokens.tSYMBEG:
+ if (looksLikeTertiaryConditionalWithNoSpaces()) {
+ return doGetToken(IRubyColorConstants.RUBY_DEFAULT);
+ }
isInSymbol = true;
return doGetToken(IRubyColorConstants.RUBY_SYMBOL);
case Tokens.tGVAR:
@@ -148,7 +153,7 @@
case Tokens.tFLOAT:
case Tokens.tINTEGER:
// A character is marked as an integer, lets check for that special case...
- if ((((oldOffset - origOffset) + 1) < contents.length()) && (contents.charAt((oldOffset - origOffset) + 1) == '?'))
+ if ((((fOffset - origOffset) + 1) < fContents.length()) && (fContents.charAt((fOffset - origOffset) + 1) == '?'))
return doGetToken(IRubyColorConstants.RUBY_CHARACTER);
return doGetToken(IRubyColorConstants.RUBY_FIXNUM);
case Tokens.tREGEXP_BEG:
@@ -162,6 +167,12 @@
}
}
+ private boolean looksLikeTertiaryConditionalWithNoSpaces() {
+ if (fTokenLength > 1) return false;
+ char c = fContents.charAt((fOffset - origOffset) - 1);
+ return !Character.isWhitespace(c) && Character.isUnicodeIdentifierPart(c);
+ }
+
private boolean shouldReturnDefault(int i) {
switch (i) {
case NEWLINE:
@@ -221,8 +232,8 @@
isInRegexp = false;
}
try {
- contents = document.get(offset, length);
- lexerSource = new LexerSource("filename", new StringReader(contents), 0, true);
+ fContents = document.get(offset, length);
+ lexerSource = new LexerSource("filename", new StringReader(fContents), 0, true);
lexer.setSource(lexerSource);
} catch (BadLocationException e) {
lexerSource = new LexerSource("filename", new StringReader(""), 0, true);
Modified: trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/ruby/TC_RubyTokenScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/ruby/TC_RubyTokenScanner.java 2007-07-11 16:08:23 UTC (rev 2747)
+++ trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/ruby/TC_RubyTokenScanner.java 2007-07-11 16:52:44 UTC (rev 2748)
@@ -4,6 +4,7 @@
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.Token;
import org.rubypeople.rdt.internal.ui.RubyPlugin;
import org.rubypeople.rdt.internal.ui.text.IRubyColorConstants;
import org.rubypeople.rdt.internal.ui.text.RubyColorManager;
@@ -16,7 +17,14 @@
protected void setUp() throws Exception {
super.setUp();
RubyColorManager colorManager = new RubyColorManager(false);
- fScanner = new RubyTokenScanner(colorManager, RubyPlugin.getDefault().getPreferenceStore());
+ fScanner = new RubyTokenScanner(colorManager, RubyPlugin.getDefault().getPreferenceStore()) {
+
+ @Override
+ public Token getToken(String key) {
+ return new Token(key);
+ }
+
+ };
}
private void setUpScanner(String code) {
@@ -32,7 +40,7 @@
IToken token = fScanner.nextToken();
assertEquals("Offsets don't match", offset, fScanner.getTokenOffset());
assertEquals("Lengths don't match", length, fScanner.getTokenLength());
- assertEquals("Colors don't match", fScanner.getToken(color), token); // call getToken so we bypass the scanner's overriding in doGetToken
+ assertEquals("Colors don't match", color, token.getData()); // call getToken so we bypass the scanner's overriding in doGetToken
}
public void testSimpleClassDefinition() {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|