Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Adding HLint builder + Loading database #22

Merged
merged 6 commits into from

2 participants

This page is out of date. Refresh to see the latest.
Showing with 525 additions and 92 deletions.
  1. +22 −0 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/BrowserEvent.java
  2. +67 −1 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/BrowserPlugin.java
  3. +26 −0 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/BrowserServer.java
  4. +2 −12 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/DatabaseLoadedEvent.java
  5. +2 −0  net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/IDatabaseLoadedListener.java
  6. +12 −0 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/IHoogleLoadedListener.java
  7. +16 −0 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/client/NullBrowserServer.java
  8. +59 −12 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/client/StreamBrowserServer.java
  9. +3 −0  net.sf.eclipsefp.haskell.core/plugin.properties
  10. +28 −1 net.sf.eclipsefp.haskell.core/plugin.xml
  11. +64 −0 net.sf.eclipsefp.haskell.core/src/net/sf/eclipsefp/haskell/core/hlint/AddNatureActionDelegate.java
  12. +24 −1 net.sf.eclipsefp.haskell.core/src/net/sf/eclipsefp/haskell/core/project/HaskellResource.java
  13. +1 −1  ...kell.debug.core/src/net/sf/eclipsefp/haskell/debug/core/internal/launch/TestSuiteHaskellLaunchDelegate.java
  14. +1 −0  net.sf.eclipsefp.haskell.hlint/META-INF/MANIFEST.MF
  15. +4 −2 net.sf.eclipsefp.haskell.hlint/build.properties
  16. +5 −0 net.sf.eclipsefp.haskell.hlint/plugin.xml
  17. +33 −0 net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/NoDatabaseContentProvider.java
  18. +44 −0 net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/NoDatabaseLabelProvider.java
  19. +6 −0 net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/NoDatabaseRoot.java
  20. +1 −1  net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/hoogle/HoogleContentProvider.java
  21. +54 −12 net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/hoogle/HoogleView.java
  22. +39 −12 net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/packages/PackagesView.java
  23. +5 −36 net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/scion/ScionManager.java
  24. +3 −0  net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/util/UITexts.java
  25. +3 −0  net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/util/uitexts.properties
  26. +1 −1  net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/sourcegraph/RunActionDelegate.java
View
22 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/BrowserEvent.java
@@ -0,0 +1,22 @@
+/**
+ * (c) 2011, Alejandro Serrano
+ * Released under the condidtions of the EPL.
+ */
+package net.sf.eclipsefp.haskell.browser;
+
+public class BrowserEvent {
+ BrowserServer server;
+
+ public BrowserEvent(BrowserServer server) {
+ this.server = server;
+ }
+
+ /**
+ * Returns the scion-browser instance creating this event
+ *
+ * @return
+ */
+ public BrowserServer getServer() {
+ return this.server;
+ }
+}
View
68 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/BrowserPlugin.java
@@ -24,7 +24,7 @@
/**
* The activator class controls the plug-in life cycle
*/
-public class BrowserPlugin extends AbstractUIPlugin implements IDatabaseLoadedListener {
+public class BrowserPlugin extends AbstractUIPlugin implements IDatabaseLoadedListener, IHoogleLoadedListener {
// The plug-in ID
public static final String PLUGIN_ID = "net.sf.eclipsefp.haskell.browser"; //$NON-NLS-1$
public static final String BROWSER_VERSION = "0.1";
@@ -43,6 +43,7 @@
// Listeners for loading new databases
private ArrayList<IDatabaseLoadedListener> dbLoadedListeners;
+ private ArrayList<IHoogleLoadedListener> hoogleLoadedListeners;
/**
* The constructor
@@ -51,6 +52,7 @@ public BrowserPlugin() {
this.server = new NullBrowserServer();
this.logStream = null;
this.dbLoadedListeners = new ArrayList<IDatabaseLoadedListener>();
+ this.hoogleLoadedListeners = new ArrayList<IHoogleLoadedListener>();
}
/*
@@ -163,6 +165,7 @@ public void changeInstance(IPath path) {
try {
this.server = new StreamBrowserServer(path);
this.server.addDatabaseLoadedListener(this);
+ this.server.addHoogleLoadedListener(this);
this.server.setLogStream(this.logStream);
} catch (Throwable ex) {
this.server = new NullBrowserServer();
@@ -265,6 +268,15 @@ public void addDatabaseLoadedListener(IDatabaseLoadedListener listener) {
}
/**
+ * Adds a new listener for Hoogle changes
+ *
+ * @param listener
+ */
+ public void addHoogleLoadedListener(IHoogleLoadedListener listener) {
+ hoogleLoadedListeners.add(listener);
+ }
+
+ /**
* Raises an event for all listeners currently registered
*
* @param e
@@ -273,11 +285,65 @@ protected void notifyDatabaseLoaded(DatabaseLoadedEvent e) {
for (IDatabaseLoadedListener listener : dbLoadedListeners)
listener.databaseLoaded(e);
}
+
+ /**
+ * Raises an event for all listeners currently registered
+ *
+ * @param e
+ */
+ protected void notifyDatabaseUnloaded(BrowserEvent e) {
+ for (IDatabaseLoadedListener listener : dbLoadedListeners)
+ listener.databaseUnloaded(e);
+ }
+
+ /**
+ * Raises an event for all listeners currently registered
+ *
+ * @param e
+ */
+ protected void notifyHoogleLoaded(BrowserEvent e) {
+ for (IHoogleLoadedListener listener : hoogleLoadedListeners)
+ listener.hoogleLoaded(e);
+ }
+
+ /**
+ * Raises an event for all listeners currently registered
+ *
+ * @param e
+ */
+ protected void notifyHoogleUnloaded(BrowserEvent e) {
+ for (IHoogleLoadedListener listener : hoogleLoadedListeners)
+ listener.hoogleUnloaded(e);
+ }
public void databaseLoaded(DatabaseLoadedEvent e) {
notifyDatabaseLoaded(e);
}
+ public void databaseUnloaded(BrowserEvent e) {
+ notifyDatabaseUnloaded(e);
+ }
+
+ public void hoogleLoaded(BrowserEvent e) {
+ notifyHoogleLoaded(e);
+ }
+
+ public void hoogleUnloaded(BrowserEvent e) {
+ notifyHoogleUnloaded(e);
+ }
+
+ public boolean isDatabaseLoaded() {
+ if (this.server == null)
+ return false;
+ return this.server.isDatabaseLoaded();
+ }
+
+ public boolean isHoogleLoaded() {
+ if (this.server == null)
+ return false;
+ return this.server.isHoogleLoaded();
+ }
+
/**
* Generate the built-in Scion server's build area directory path.
*
View
26 net.sf.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/BrowserServer.java
@@ -26,6 +26,7 @@
protected Writer logStream = null;
protected ArrayList<IDatabaseLoadedListener> dbLoadedListeners = new ArrayList<IDatabaseLoadedListener>();
+ protected ArrayList<IHoogleLoadedListener> hoogleLoadedListeners = new ArrayList<IHoogleLoadedListener>();
/**
* Sets the stream where log messages will be sent
@@ -57,11 +58,34 @@ protected void log(String msg) {
public void addDatabaseLoadedListener(IDatabaseLoadedListener listener) {
dbLoadedListeners.add(listener);
}
+
+ public void addHoogleLoadedListener(IHoogleLoadedListener listener) {
+ hoogleLoadedListeners.add(listener);
+ }
protected void notifyDatabaseLoaded(DatabaseLoadedEvent e) {
for (IDatabaseLoadedListener listener : dbLoadedListeners)
listener.databaseLoaded(e);
}
+
+ protected void notifyDatabaseUnloaded(BrowserEvent e) {
+ for (IDatabaseLoadedListener listener : dbLoadedListeners)
+ listener.databaseUnloaded(e);
+ }
+
+ protected void notifyHoogleLoaded(BrowserEvent e) {
+ for (IHoogleLoadedListener listener : hoogleLoadedListeners)
+ listener.hoogleLoaded(e);
+ }
+
+ protected void notifyHoogleUnloaded(BrowserEvent e) {
+ for (IHoogleLoadedListener listener : hoogleLoadedListeners)
+ listener.hoogleUnloaded(e);
+ }
+
+ public abstract boolean isDatabaseLoaded();
+
+ public abstract boolean isHoogleLoaded();
public abstract void loadLocalDatabase(String path, boolean rebuild) throws IOException,
JSONException;
@@ -80,6 +104,8 @@ public abstract void setCurrentDatabase(DatabaseType current, PackageIdentifier
public abstract HoogleResult[] queryHoogle(String query) throws Exception;
public abstract void downloadHoogleData() throws IOException, JSONException;
+
+ public abstract boolean checkHoogle() throws Exception;
public abstract void stop();
}
View
14 ...f.eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/DatabaseLoadedEvent.java
@@ -4,27 +4,17 @@
*/
package net.sf.eclipsefp.haskell.browser;
-public class DatabaseLoadedEvent {
- BrowserServer server;
+public class DatabaseLoadedEvent extends BrowserEvent {
String db_path;
DatabaseType ty;
public DatabaseLoadedEvent(BrowserServer server, String db_path, DatabaseType ty) {
- this.server = server;
+ super(server);
this.db_path = db_path;
this.ty = ty;
}
/**
- * Returns the scion-browser instance creating this event
- *
- * @return
- */
- public BrowserServer getServer() {
- return this.server;
- }
-
- /**
* Returns the path to the database being loaded
*
* @return
View
2  ...lipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/IDatabaseLoadedListener.java
@@ -7,4 +7,6 @@
public interface IDatabaseLoadedListener {
void databaseLoaded(DatabaseLoadedEvent e);
+
+ void databaseUnloaded(BrowserEvent e);
}
View
12 ...eclipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/IHoogleLoadedListener.java
@@ -0,0 +1,12 @@
+/**
+ * (c) 2011, Alejandro Serrano
+ * Released under the condidtions of the EPL.
+ */
+package net.sf.eclipsefp.haskell.browser;
+
+public interface IHoogleLoadedListener {
+
+ void hoogleLoaded(BrowserEvent e);
+
+ void hoogleUnloaded(BrowserEvent e);
+}
View
16 ...ipsefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/client/NullBrowserServer.java
@@ -29,6 +29,16 @@
public NullBrowserServer() {
// Do nothing
}
+
+ @Override
+ public boolean isDatabaseLoaded() {
+ return true;
+ }
+
+ @Override
+ public boolean isHoogleLoaded() {
+ return true;
+ }
@Override
public void loadLocalDatabase(String path, boolean rebuild) throws IOException, JSONException {
@@ -75,6 +85,12 @@ public void setCurrentDatabase(DatabaseType current, PackageIdentifier id) throw
public void downloadHoogleData() {
// Do nothing
}
+
+ @Override
+ public boolean checkHoogle() {
+ // Do nothing
+ return true;
+ }
@Override
public void stop() {
View
71 ...sefp.haskell.browser/src/net/sf/eclipsefp/haskell/browser/client/StreamBrowserServer.java
@@ -10,6 +10,8 @@
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
+import net.sf.eclipsefp.haskell.browser.BrowserEvent;
+import net.sf.eclipsefp.haskell.browser.BrowserPlugin;
import net.sf.eclipsefp.haskell.browser.BrowserServer;
import net.sf.eclipsefp.haskell.browser.DatabaseLoadedEvent;
import net.sf.eclipsefp.haskell.browser.DatabaseType;
@@ -36,6 +38,8 @@
private Process process = null;
private BufferedWriter in = null;
private BufferedReader out = null;
+ private boolean dbLoaded = false;
+ private boolean hoogleLoaded = false;
public StreamBrowserServer(IPath serverExecutable) throws Exception {
this.serverExecutable = serverExecutable;
@@ -43,19 +47,23 @@ public StreamBrowserServer(IPath serverExecutable) throws Exception {
}
public void startServer() throws Exception {
- ProcessBuilder builder = new ProcessBuilder(serverExecutable.toOSString());
+ ProcessBuilder builder = new ProcessBuilder(
+ serverExecutable.toOSString());
builder.redirectErrorStream(true);
try {
process = builder.start();
- out = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF8"));
- in = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(), "UTF8"));
+ out = new BufferedReader(new InputStreamReader(
+ process.getInputStream(), "UTF8"));
+ in = new BufferedWriter(new OutputStreamWriter(
+ process.getOutputStream(), "UTF8"));
} catch (Throwable ex) {
throw new Exception("Could not load");
}
}
- public synchronized String sendAndReceive(JSONObject input) throws IOException {
+ public synchronized String sendAndReceive(JSONObject input)
+ throws IOException {
String jsonInput = input.toString();
log(">> " + jsonInput);
in.write(jsonInput + "\n");
@@ -65,7 +73,8 @@ public synchronized String sendAndReceive(JSONObject input) throws IOException {
return response;
}
- public synchronized void sendAndReceiveOk(JSONObject input) throws IOException {
+ public synchronized void sendAndReceiveOk(JSONObject input)
+ throws IOException {
String jsonInput = input.toString();
log(">> " + jsonInput);
in.write(jsonInput + "\n");
@@ -77,12 +86,25 @@ public synchronized void sendAndReceiveOk(JSONObject input) throws IOException {
log(response);
} while (!response.equals("\"ok\""));
}
+
+ @Override
+ public boolean isDatabaseLoaded() {
+ return dbLoaded;
+ }
+
+ @Override
+ public boolean isHoogleLoaded() {
+ return hoogleLoaded;
+ }
@Override
- public void loadLocalDatabase(String path, boolean rebuild) throws IOException, JSONException {
+ public void loadLocalDatabase(String path, boolean rebuild)
+ throws IOException, JSONException {
sendAndReceiveOk(Commands.createLoadLocalDatabase(path, rebuild));
// Notify listeners
- DatabaseLoadedEvent e = new DatabaseLoadedEvent(this, path, DatabaseType.LOCAL);
+ DatabaseLoadedEvent e = new DatabaseLoadedEvent(this, path,
+ DatabaseType.LOCAL);
+ dbLoaded = true;
notifyDatabaseLoaded(e);
}
@@ -111,25 +133,50 @@ public void setCurrentDatabase(DatabaseType current, PackageIdentifier id)
}
@Override
- public Packaged<Declaration>[] getDeclarations(String module) throws Exception {
+ public Packaged<Declaration>[] getDeclarations(String module)
+ throws Exception {
String response = sendAndReceive(Commands.createGetDeclarations(module));
return Commands.responseGetDeclarations(response);
}
-
+
@Override
public HoogleResult[] queryHoogle(String query) throws Exception {
String response = sendAndReceive(Commands.createHoogleQuery(query));
return Commands.responseHoogleQuery(response);
}
-
+
@Override
public void downloadHoogleData() throws IOException, JSONException {
sendAndReceiveOk(Commands.createDownloadHoogleData());
}
-
+
+ @Override
+ public boolean checkHoogle() throws Exception {
+ this.setCurrentDatabase(DatabaseType.ALL, null);
+ // We know that "fmap" is always present
+ HoogleResult[] mapResults = this.queryHoogle("fmap");
+ boolean isPresent = mapResults.length > 0;
+ // If is present, notify the views
+ if (isPresent) {
+ hoogleLoaded = true;
+ notifyHoogleLoaded(new BrowserEvent(this));
+ }
+ return isPresent;
+ }
+
@Override
public void stop() {
- if (process != null)
+ if (process != null) {
+ // Nothing is loaded
+ dbLoaded = false;
+ hoogleLoaded = false;
+ // Tell we no longer have a database
+ BrowserEvent e = new BrowserEvent(this);
+ notifyDatabaseUnloaded(e);
+ // Nor a Hoogle connection
+ notifyHoogleUnloaded(e);
+ // Close connection with the process
process.destroy();
+ }
}
}
View
3  net.sf.eclipsefp.haskell.core/plugin.properties
@@ -27,3 +27,6 @@ rename_name = Rename
# content types and file types
contenttype_literate_name = Literate Haskell
contenttype_haskell_name = Haskell
+
+# HLint
+hlint_addNature = Add HLint builder
View
29 net.sf.eclipsefp.haskell.core/plugin.xml
@@ -56,7 +56,7 @@
<extension
point="org.eclipse.core.expressions.propertyTesters">
<propertyTester
- properties="isProjectExecutable, isSourceFolder, isHaskellFile, isProjectTestSuite"
+ properties="isProjectExecutable, isSourceFolder, isHaskellFile, isProjectTestSuite, hasProjectHLintBuilder, needsProjectHLintBuilder"
namespace="net.sf.eclipsefp.haskell.core"
type="org.eclipse.core.resources.IResource"
class="net.sf.eclipsefp.haskell.core.expressions.HaskellPropertyTester"
@@ -113,4 +113,31 @@
type="net.sf.eclipsefp.haskell.core.problem">
</super>
</extension>
+ <extension
+ point="org.eclipse.ui.popupMenus">
+ <objectContribution
+ adaptable="false"
+ id="net.sf.eclipsefp.haskell.core.hlint.addNature"
+ objectClass="org.eclipse.core.resources.IProject">
+ <action
+ class="net.sf.eclipsefp.haskell.core.hlint.AddNatureActionDelegate"
+ enablesFor="1"
+ id="net.sf.eclipsefp.haskell.core.hlint.addNatureAction"
+ label="%hlint_addNature"
+ menubarPath="org.eclipse.ui.projectConfigure/additions">
+ </action>
+ <enablement>
+ <adapt
+ type="org.eclipse.core.resources.IProject">
+ <test
+ property="org.eclipse.core.resources.projectNature"
+ value="net.sf.eclipsefp.haskell.core.project.HaskellNature">
+ </test>
+ <test
+ property="net.sf.eclipsefp.haskell.core.needsProjectHLintBuilder">
+ </test>
+ </adapt>
+ </enablement>
+ </objectContribution>
+ </extension>
</plugin>
View
64 ...lipsefp.haskell.core/src/net/sf/eclipsefp/haskell/core/hlint/AddNatureActionDelegate.java
@@ -0,0 +1,64 @@
+package net.sf.eclipsefp.haskell.core.hlint;
+
+import java.util.Collection;
+import net.sf.eclipsefp.haskell.core.HaskellCorePlugin;
+import net.sf.eclipsefp.haskell.core.util.ResourceUtil;
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+
+
+public class AddNatureActionDelegate implements IObjectActionDelegate {
+
+ // private Shell currentShell;
+ private IProject project;
+
+ public AddNatureActionDelegate() {
+ // Do nothing
+ }
+
+ @Override
+ public void run( final IAction action ) {
+ if( project != null ) {
+ try {
+ IProjectDescription desc = project.getDescription();
+ ICommand[] commands = desc.getBuildSpec();
+ for( int i = 0; i < commands.length; ++i ) {
+ if( commands[ i ].getBuilderName().equals( HLintBuilder.BUILDER_ID ) ) {
+ return;
+ }
+ }
+ // add builder to project
+ ICommand command = desc.newCommand();
+ command.setBuilderName( HLintBuilder.BUILDER_ID );
+ ICommand[] nc = new ICommand[ commands.length + 1 ];
+ // Add it before other builders.
+ System.arraycopy( commands, 0, nc, 1, commands.length );
+ nc[ 0 ] = command;
+ desc.setBuildSpec( nc );
+ project.setDescription( desc, null );
+ } catch( CoreException e ) {
+ HaskellCorePlugin.log( e );
+ }
+ }
+ }
+
+ @Override
+ public void selectionChanged( final IAction action, final ISelection selection ) {
+ Collection<IProject> prjs = ResourceUtil.getProjects( selection );
+ if( prjs.size() > 0 ) {
+ project = prjs.iterator().next();
+ }
+ }
+
+ @Override
+ public void setActivePart( final IAction action,
+ final IWorkbenchPart targetPart ) {
+ // currentShell = targetPart.getSite().getShell();
+ }
+}
View
25 net.sf.eclipsefp.haskell.core/src/net/sf/eclipsefp/haskell/core/project/HaskellResource.java
@@ -1,11 +1,14 @@
package net.sf.eclipsefp.haskell.core.project;
import net.sf.eclipsefp.haskell.core.HaskellCorePlugin;
+import net.sf.eclipsefp.haskell.core.hlint.HLintBuilder;
import net.sf.eclipsefp.haskell.core.util.ResourceUtil;
import net.sf.eclipsefp.haskell.util.FileUtil;
+import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
@@ -39,7 +42,6 @@ public boolean isProjectExecutable(){
} catch (CoreException ce){
HaskellCorePlugin.log( ce );
}
-
}
return false;
}
@@ -52,8 +54,29 @@ public boolean isProjectTestSuite(){
} catch (CoreException ce){
HaskellCorePlugin.log( ce );
}
+ }
+ return false;
+ }
+ public boolean hasProjectHLintBuilder(){
+ if (fResource instanceof IProject){
+ IProject project=(IProject)fResource;
+ try {
+ IProjectDescription desc = project.getDescription();
+ ICommand[] commands = desc.getBuildSpec();
+ for( int i = 0; i < commands.length; ++i ) {
+ if( commands[ i ].getBuilderName().equals( HLintBuilder.BUILDER_ID ) ) {
+ return true;
+ }
+ }
+ } catch (CoreException ce){
+ HaskellCorePlugin.log( ce );
+ }
}
return false;
}
+
+ public boolean needsProjectHLintBuilder(){
+ return !hasProjectHLintBuilder();
+ }
}
View
2  ...c/net/sf/eclipsefp/haskell/debug/core/internal/launch/TestSuiteHaskellLaunchDelegate.java
@@ -38,7 +38,7 @@ private String getFilename() {
@Override
protected String getExtraArguments() {
- return "--plain --jxml=\"" + getFilename() + "\""; //$NON-NLS-1$ //$NON-NLS-2$
+ return "--plain --jxml=\"" + getFilename() + "\" --jxml-nested"; //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
View
1  net.sf.eclipsefp.haskell.hlint/META-INF/MANIFEST.MF
@@ -11,3 +11,4 @@ Bundle-RequiredExecutionEnvironment: J2SE-1.5
Bundle-Vendor: %bundleVendor
Bundle-ClassPath: .
Export-Package: net.sf.eclipsefp.haskell.hlint
+Bundle-Localization: plugin
View
6 net.sf.eclipsefp.haskell.hlint/build.properties
@@ -1,5 +1,7 @@
source.. = src/
output.. = bin/
-bin.includes = META-INF/,\
- .
+bin.includes = plugin.xml,\
+ .,\
+ META-INF/,\
+ plugin.properties
View
5 net.sf.eclipsefp.haskell.hlint/plugin.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+
+</plugin>
View
33 ...sefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/NoDatabaseContentProvider.java
@@ -0,0 +1,33 @@
+package net.sf.eclipsefp.haskell.browser.views;
+
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+
+
+public class NoDatabaseContentProvider implements ITreeContentProvider {
+
+ public void dispose() {
+ // Do nothing
+ }
+
+ public void inputChanged( final Viewer viewer, final Object oldInput, final Object newInput ) {
+ // Do nothing
+ }
+
+ public Object[] getElements( final Object inputElement ) {
+ return new Object[] { NoDatabaseRoot.ROOT };
+ }
+
+ public Object[] getChildren( final Object parentElement ) {
+ return new Object[0];
+ }
+
+ public Object getParent( final Object element ) {
+ return null;
+ }
+
+ public boolean hasChildren( final Object element ) {
+ return false;
+ }
+
+}
View
44 ...ipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/NoDatabaseLabelProvider.java
@@ -0,0 +1,44 @@
+package net.sf.eclipsefp.haskell.browser.views;
+
+import net.sf.eclipsefp.haskell.browser.util.ImageCache;
+import net.sf.eclipsefp.haskell.ui.internal.util.UITexts;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.swt.graphics.Image;
+
+
+public class NoDatabaseLabelProvider implements ILabelProvider {
+
+ boolean isHoogle;
+
+ public NoDatabaseLabelProvider(final boolean isHoogle) {
+ this.isHoogle = isHoogle;
+ }
+
+ public Image getImage( final Object element ) {
+ return ImageCache.DATABASE;
+ }
+
+ public String getText( final Object element ) {
+ return isHoogle ? UITexts.scionBrowserNoDatabaseLoadedOrHoogleNotPresent :
+ UITexts.scionBrowserNoDatabaseLoaded;
+ }
+
+ public void addListener( final ILabelProviderListener listener ) {
+ // Do nothing
+ }
+
+ public void removeListener( final ILabelProviderListener listener ) {
+ // Do nothing
+ }
+
+ public void dispose() {
+ // Do nothing
+ }
+
+ public boolean isLabelProperty( final Object element, final String property ) {
+ // Do nothing
+ return false;
+ }
+
+}
View
6 net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/NoDatabaseRoot.java
@@ -0,0 +1,6 @@
+package net.sf.eclipsefp.haskell.browser.views;
+
+
+public class NoDatabaseRoot {
+ public static NoDatabaseRoot ROOT = new NoDatabaseRoot();
+}
View
2  ...p.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/hoogle/HoogleContentProvider.java
@@ -20,7 +20,7 @@
public void inputChanged( final Viewer viewer, final Object oldInput,
final Object newInput ) {
- if( newInput == null ) {
+ if( newInput == null || !(newInput instanceof String) ) {
results = null;
shownElements = null;
return;
View
66 ...sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/hoogle/HoogleView.java
@@ -7,6 +7,9 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.Map;
+import net.sf.eclipsefp.haskell.browser.BrowserEvent;
+import net.sf.eclipsefp.haskell.browser.BrowserPlugin;
+import net.sf.eclipsefp.haskell.browser.IHoogleLoadedListener;
import net.sf.eclipsefp.haskell.browser.items.DeclarationType;
import net.sf.eclipsefp.haskell.browser.items.HaskellPackage;
import net.sf.eclipsefp.haskell.browser.items.HoogleResult;
@@ -15,8 +18,12 @@
import net.sf.eclipsefp.haskell.browser.items.HoogleResultModule;
import net.sf.eclipsefp.haskell.browser.items.HoogleResultPackage;
import net.sf.eclipsefp.haskell.browser.util.HtmlUtil;
+import net.sf.eclipsefp.haskell.browser.views.NoDatabaseContentProvider;
+import net.sf.eclipsefp.haskell.browser.views.NoDatabaseLabelProvider;
+import net.sf.eclipsefp.haskell.browser.views.NoDatabaseRoot;
import net.sf.eclipsefp.haskell.ui.internal.util.UITexts;
import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
@@ -31,6 +38,7 @@
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
@@ -38,7 +46,7 @@
public class HoogleView extends ViewPart implements SelectionListener,
- ISelectionChangedListener, IDoubleClickListener {
+ ISelectionChangedListener, IDoubleClickListener, IHoogleLoadedListener {
/**
* The ID of the view as specified by the extension.
@@ -48,7 +56,7 @@
Text text;
TreeViewer viewer;
Browser doc;
- HoogleContentProvider provider;
+ IContentProvider provider;
@Override
public void createPartControl( final Composite parent ) {
@@ -74,16 +82,48 @@ public void createPartControl( final Composite parent ) {
formData.grabExcessHorizontalSpace = true;
form.setLayoutData( formData );
viewer = new TreeViewer( form );
- provider = new HoogleContentProvider();
- viewer.setContentProvider( provider );
- viewer.setLabelProvider( new HoogleLabelProvider() );
- viewer.setInput( "" );
+
+ // Load if needed
+ if (BrowserPlugin.getDefault().isHoogleLoaded()) {
+ hoogleLoaded( null );
+ } else {
+ hoogleUnloaded( null );
+ }
+
doc = new Browser( form, SWT.NONE );
form.setWeights( new int[] { 70, 30 } );
// Hook for double clicking
viewer.addDoubleClickListener( this );
// Hook for changes in selection
viewer.addPostSelectionChangedListener( this );
+ // Wait the Hoogle database to be ready
+ BrowserPlugin.getDefault().addHoogleLoadedListener( this );
+ }
+
+ public void hoogleLoaded( final BrowserEvent e ) {
+ Display.getDefault().asyncExec( new Runnable() {
+
+ public void run() {
+ provider = new HoogleContentProvider();
+ viewer.setContentProvider( provider );
+ viewer.setLabelProvider( new HoogleLabelProvider() );
+ viewer.setInput( "" );
+ viewer.refresh();
+ }
+ } );
+ }
+
+ public void hoogleUnloaded( final BrowserEvent e ) {
+ Display.getDefault().asyncExec( new Runnable() {
+
+ public void run() {
+ provider = new NoDatabaseContentProvider();
+ viewer.setContentProvider( provider );
+ viewer.setLabelProvider( new NoDatabaseLabelProvider( true ) );
+ viewer.setInput( NoDatabaseRoot.ROOT );
+ viewer.refresh();
+ }
+ } );
}
@Override
@@ -102,10 +142,12 @@ public void widgetDefaultSelected( final SelectionEvent e ) {
} else {
viewer.setInput( text.getText() );
viewer.refresh();
- Object first = provider.getFirstElement();
- if( first != null ) {
- viewer.setSelection( new StructuredSelection( first ), true );
- viewer.getControl().setFocus();
+ if (provider instanceof HoogleContentProvider) {
+ Object first = ((HoogleContentProvider)provider).getFirstElement();
+ if( first != null ) {
+ viewer.setSelection( new StructuredSelection( first ), true );
+ viewer.getControl().setFocus();
+ }
}
}
}
@@ -115,7 +157,7 @@ public void selectionChanged( final SelectionChangedEvent event ) {
TreeSelection selection = ( TreeSelection )event.getSelection();
Object o = selection.getFirstElement();
- if( o == null ) {
+ if( o == null || o instanceof NoDatabaseRoot ) {
doc.setText( "" );
return;
}
@@ -169,7 +211,7 @@ public void selectionChanged( final SelectionChangedEvent event ) {
public void doubleClick( final DoubleClickEvent event ) {
TreeSelection selection = ( TreeSelection )event.getSelection();
Object o = selection.getFirstElement();
- if( o == null ) {
+ if( o == null || o instanceof NoDatabaseRoot ) {
return;
}
View
51 ...clipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/browser/views/packages/PackagesView.java
@@ -5,17 +5,22 @@
package net.sf.eclipsefp.haskell.browser.views.packages;
import java.net.URL;
+import net.sf.eclipsefp.haskell.browser.BrowserEvent;
import net.sf.eclipsefp.haskell.browser.BrowserPlugin;
import net.sf.eclipsefp.haskell.browser.DatabaseLoadedEvent;
-import net.sf.eclipsefp.haskell.browser.DatabaseType;
import net.sf.eclipsefp.haskell.browser.IDatabaseLoadedListener;
import net.sf.eclipsefp.haskell.browser.util.HtmlUtil;
+import net.sf.eclipsefp.haskell.browser.views.NoDatabaseContentProvider;
+import net.sf.eclipsefp.haskell.browser.views.NoDatabaseLabelProvider;
+import net.sf.eclipsefp.haskell.browser.views.NoDatabaseRoot;
import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.SashForm;
@@ -35,7 +40,7 @@
TreeViewer viewer;
Browser doc;
- PackagesContentProvider provider;
+ IContentProvider provider;
@Override
public void createPartControl( final Composite parent ) {
@@ -45,13 +50,12 @@ public void createPartControl( final Composite parent ) {
doc.setFont( viewer.getControl().getFont() );
form.setWeights( new int[] { 75, 25 } );
- // Set label provider and sorter
- viewer.setLabelProvider( new PackagesLabelProvider() );
- viewer.setSorter( new PackagesSorter() );
- // Set initial content provider
- provider = new PackagesContentProvider();
- viewer.setContentProvider( provider );
- viewer.setInput( PackagesRoot.ROOT );
+ // Set database
+ if (BrowserPlugin.getDefault().isDatabaseLoaded()) {
+ databaseLoaded( null );
+ } else {
+ databaseUnloaded( null );
+ }
// Hook for listeners
BrowserPlugin.getDefault().addDatabaseLoadedListener( this );
// Hook for changes in selection
@@ -71,8 +75,31 @@ public void databaseLoaded( final DatabaseLoadedEvent e ) {
Display.getDefault().asyncExec( new Runnable() {
public void run() {
+ // Set real content provider
+ PackagesContentProvider daProvider = new PackagesContentProvider();
+ provider = daProvider;
+ viewer.setContentProvider( provider );
+ viewer.setLabelProvider( new PackagesLabelProvider() );
+ viewer.setSorter( new PackagesSorter() );
+ // Refresh with the items
+ viewer.setInput( PackagesRoot.ROOT );
// Use the new provider
- provider.uncache();
+ daProvider.uncache();
+ viewer.refresh();
+ }
+ } );
+ }
+
+ public void databaseUnloaded( final BrowserEvent e ) {
+ Display.getDefault().asyncExec( new Runnable() {
+
+ public void run() {
+ // Put the "no database" content and label
+ viewer.setLabelProvider( new NoDatabaseLabelProvider( false ) );
+ viewer.setSorter( new ViewerSorter() );
+ provider = new NoDatabaseContentProvider();
+ viewer.setContentProvider( provider );
+ viewer.setInput( NoDatabaseRoot.ROOT );
viewer.refresh();
}
} );
@@ -81,7 +108,7 @@ public void run() {
public void selectionChanged( final SelectionChangedEvent event ) {
TreeSelection selection = ( TreeSelection )event.getSelection();
Object o = selection.getFirstElement();
- if( o == null || o instanceof DatabaseType ) {
+ if( o == null || !( o instanceof PackagesItem ) ) {
doc.setText( "" );
} else {
PackagesItem item = ( PackagesItem )o;
@@ -92,7 +119,7 @@ public void selectionChanged( final SelectionChangedEvent event ) {
public void doubleClick( final DoubleClickEvent event ) {
TreeSelection selection = ( TreeSelection )event.getSelection();
Object o = selection.getFirstElement();
- if( o == null || o instanceof DatabaseType ) {
+ if( o == null || !( o instanceof PackagesItem ) ) {
return;
}
View
41 net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/scion/ScionManager.java
@@ -6,8 +6,6 @@
import java.util.List;
import java.util.Set;
import net.sf.eclipsefp.haskell.browser.BrowserPlugin;
-import net.sf.eclipsefp.haskell.browser.DatabaseType;
-import net.sf.eclipsefp.haskell.browser.items.HoogleResult;
import net.sf.eclipsefp.haskell.core.HaskellCorePlugin;
import net.sf.eclipsefp.haskell.core.cabal.CabalImplementation;
import net.sf.eclipsefp.haskell.core.cabal.CabalImplementationManager;
@@ -424,9 +422,8 @@ private synchronized void browserSetup() {
display.asyncExec( new Runnable() {
public void run() {
Job builder = new BrowserDatabaseRebuildJob(UITexts.scionBrowserRebuildingDatabase);
- builder.setPriority( Job.BUILD );
builder.setRule( ResourcesPlugin.getWorkspace().getRoot() );
- builder.setUser(true);
+ builder.setPriority( Job.DECORATE );
builder.schedule();
}
} );
@@ -441,9 +438,8 @@ public void run() {
display.asyncExec( new Runnable() {
public void run() {
Job builder = new BrowserDatabaseRebuildJob(UITexts.scionBrowserRebuildingDatabase);
- builder.setPriority( Job.BUILD );
builder.setRule( ResourcesPlugin.getWorkspace().getRoot() );
- builder.setUser(true);
+ builder.setPriority( Job.DECORATE );
builder.schedule();
}
} );
@@ -465,12 +461,7 @@ public void run() {
void checkHoogleDataIsPresent() {
boolean rebuild = false;
try {
- BrowserPlugin.getSharedInstance().setCurrentDatabase( DatabaseType.ALL,
- null );
- // We know that "fmap" is always present
- HoogleResult[] mapResults = BrowserPlugin.getSharedInstance()
- .queryHoogle( "fmap" );
- rebuild = mapResults.length == 0;
+ rebuild = !BrowserPlugin.getSharedInstance().checkHoogle();
} catch( Exception e ) {
rebuild = true;
}
@@ -493,9 +484,8 @@ public void run() {
public void run() {
Job builder = new HoogleDownloadDataJob(
UITexts.hoogle_downloadingData );
- builder.setPriority( Job.BUILD );
builder.setRule( ResourcesPlugin.getWorkspace().getRoot() );
- builder.setUser( true );
+ builder.setPriority( Job.DECORATE );
builder.schedule();
}
} );
@@ -1105,28 +1095,6 @@ public void run() {
}
}
- /** Specialized Job class that manages loading the Browser databases.
- * Based in the work of B. Scott Michel.
- *
- * @author B. Alejandro Serrano
- */
- public class BrowserDatabaseLoadJob extends Job {
- IStatus status;
-
- public BrowserDatabaseLoadJob(final String jobTitle) {
- super(jobTitle);
- }
-
- @Override
- protected IStatus run( final IProgressMonitor monitor ) {
- monitor.beginTask( UITexts.scionBrowserLoadingDatabases, IProgressMonitor.UNKNOWN );
- status = BrowserPlugin.loadLocalDatabase( false );
- monitor.done();
-
- return status;
- }
- }
-
/** Specialized Job class that manages rebuilding the Browser database.
* Based in the work of B. Scott Michel.
*
@@ -1185,6 +1153,7 @@ protected IStatus run( final IProgressMonitor monitor ) {
monitor.beginTask( UITexts.hoogle_downloadingData, IProgressMonitor.UNKNOWN );
try {
BrowserPlugin.getSharedInstance().downloadHoogleData();
+ BrowserPlugin.getSharedInstance().checkHoogle();
} catch( Exception e ) {
// Do nothing if fails
}
View
3  net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/util/UITexts.java
@@ -158,6 +158,9 @@
public static String scionBrowserRebuildingDatabaseError_title;
public static String scionBrowserRebuildingDatabaseError_message;
+ public static String scionBrowserNoDatabaseLoaded;
+ public static String scionBrowserNoDatabaseLoadedOrHoogleNotPresent;
+
public static String scionServerInstallError;
public static String scionServerInstallFailed;
public static String browserServerInstallError;
View
3  net.sf.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/internal/util/uitexts.properties
@@ -161,6 +161,9 @@ scionBrowserRebuildingDatabase = Rebuilding local database
scionBrowserRebuildingDatabaseError_title = Error rebuilding local database
scionBrowserRebuildingDatabaseError_message = Error rebuilding local database. Check the console log for more details.
+scionBrowserNoDatabaseLoaded = No database loaded
+scionBrowserNoDatabaseLoadedOrHoogleNotPresent = No database loaded or Hoogle not present
+
scionVersionMismatch_title = Wrong scion-server version
scionVersionMismatch_message = Unexpected scion-server protocol version number received.\n\n\
You can attempt to continue working using this scion-server, however,\n\
View
2  ...f.eclipsefp.haskell.ui/src/net/sf/eclipsefp/haskell/ui/sourcegraph/RunActionDelegate.java
@@ -90,7 +90,7 @@ public void run() {
}
}
- public void selectionChanged( final IAction action , final ISelection selection ) {
+ public void selectionChanged( final IAction action, final ISelection selection ) {
Collection<IProject> prjs = ResourceUtil.getProjects( selection );
if (prjs.size() > 0){
project = prjs.iterator().next();
Something went wrong with that request. Please try again.