Permalink
Browse files

initial commit for organize imports action

  • Loading branch information...
1 parent ba4f8f6 commit 27cbf06e07e58e056cec2417504439a5b4eece8f @JPMoresmau committed Dec 29, 2012
View
@@ -0,0 +1,26 @@
+organize imports
+ - on current source
+ - on file(s)/folders
+
+- get module from file
+- get all references in module from usage tables
+- get current imports lines and qualifiers from outline or usage tables too!
+- do not touch preprocessor directives
+
+- check Prelude is explicitely imported or not
+- if there is import Module(), leave it (for instances) -> make it a preference?
+- order:
+ - modules from same component
+ - modules from dependent components
+ - modules for dependent projects
+ - other libraries
+ - base
+ and alphabetical in each section? -> see GHC guidelines
+
+
+- module imported, no details
+ -> only import what's used
+ -> nothing -> remove
+- module imported, details
+ -> remove what's not used
+ -> nothing left -> remove
@@ -158,7 +158,7 @@ available at http://www.eclipse.org/legal/epl-v10.html.
id="net.sf.eclipsefp.haskell.buildwrapper"
download-size="0"
install-size="0"
- version="2.4.1"
+ version="2.4.3"
unpack="false"/>
<plugin
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-SymbolicName: net.sf.eclipsefp.haskell.buildwrapper;singleton:=true
-Bundle-Version: 2.4.1
+Bundle-Version: 2.4.3
Bundle-Activator: net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin
Bundle-Vendor: %bundleVendor
Bundle-Localization: plugin
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.buildwrapper.types;
+
+import org.eclipse.core.resources.IFile;
+import org.json.JSONArray;
+import org.json.JSONException;
+
+/**
+ * A reference to something: the location and the name of the thing referenced
+ * @author JP Moresmau
+ *
+ */
+public class ReferenceLocation extends Location {
+ /**
+ * the name of the thing
+ */
+ private String reference;
+ /**
+ * are we a module?
+ */
+ private boolean module;
+
+ /**
+ * @param f
+ * @param json
+ * @throws JSONException
+ */
+ public ReferenceLocation(String reference,IFile f, JSONArray json) throws JSONException {
+ super(f, json);
+ setReference(reference);
+ }
+
+ public String getReference() {
+ return reference;
+ }
+
+ public void setReference(String reference) {
+ this.reference = reference;
+ }
+
+ /* (non-Javadoc)
+ * @see net.sf.eclipsefp.haskell.buildwrapper.types.Location#toString()
+ */
+ @Override
+ public String toString() {
+ return reference+":"+super.toString();
+ }
+
+ public boolean isModule() {
+ return module;
+ }
+
+ public void setModule(boolean module) {
+ this.module = module;
+ }
+}
@@ -11,14 +11,17 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import net.sf.eclipsefp.haskell.buildwrapper.BWFacade;
import net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin;
import net.sf.eclipsefp.haskell.buildwrapper.types.Component;
import net.sf.eclipsefp.haskell.buildwrapper.types.Module;
import net.sf.eclipsefp.haskell.buildwrapper.types.OutlineResult;
+import net.sf.eclipsefp.haskell.buildwrapper.types.ReferenceLocation;
import net.sf.eclipsefp.haskell.buildwrapper.types.SymbolDef;
import net.sf.eclipsefp.haskell.buildwrapper.types.UsageResults;
import net.sf.eclipsefp.haskell.buildwrapper.util.BWText;
@@ -112,6 +115,17 @@ public void addFile(IProject p,Component c, String relPath){
}
}
+ public Map<String,List<ReferenceLocation>> listReferencesInFile(IFile f){
+ try {
+ return db.listReferencesInFile(f);
+ } catch (SQLException sqle){
+ BuildWrapperPlugin.logError(BWText.error_db, sqle);
+ } catch (JSONException je){
+ BuildWrapperPlugin.logError(BWText.error_parsing_usage_file, je);
+ }
+ return new HashMap<String, List<ReferenceLocation>>();
+ }
+
private void buildUsage(long fileID,JSONArray arr,List<ObjectUsage> modUsages,List<ObjectUsage> objDefs,List<ObjectUsage> objUsages){
JSONObject pkgs=arr.optJSONObject(3);
if (pkgs!=null){
@@ -21,6 +21,7 @@
import net.sf.eclipsefp.haskell.buildwrapper.BuildWrapperPlugin;
import net.sf.eclipsefp.haskell.buildwrapper.types.Module;
+import net.sf.eclipsefp.haskell.buildwrapper.types.ReferenceLocation;
import net.sf.eclipsefp.haskell.buildwrapper.types.SearchResultLocation;
import net.sf.eclipsefp.haskell.buildwrapper.types.SymbolDef;
import net.sf.eclipsefp.haskell.buildwrapper.types.UsageResults;
@@ -221,6 +222,8 @@ public void clearUsageInFile(long fileid) throws SQLException{
}
}
+
+
public void setModuleUsages(long fileid,Collection<ObjectUsage> usages) throws SQLException{
checkConnection();
PreparedStatement ps=conn.prepareStatement("insert into module_usages values(?,?,?,?)");
@@ -713,4 +716,51 @@ private UsageResults getUsageResults(PreparedStatement ps,String query) throws S
}
return ret;
}
+
+ public Map<String,List<ReferenceLocation>> listReferencesInFile(IFile f)throws SQLException,JSONException{
+ checkConnection();
+ long fileid=getFileID(f);
+ Map<String,List<ReferenceLocation>> ret=new HashMap<String, List<ReferenceLocation>>();
+ PreparedStatement ps=conn.prepareStatement("select mu.section,m.module,mu.location from module_usages mu,modules m where mu.fileid=? and mu.moduleid=m.moduleid");
+ try {
+ ps.setLong(1, fileid);
+ ResultSet rs=ps.executeQuery();
+ try {
+ while(rs.next()){
+ addReference(f,ret, rs.getString(1), rs.getString(2), rs.getString(3),true);
+ }
+ } finally {
+ rs.close();
+ }
+ } finally {
+ ps.close();
+ }
+ ps=conn.prepareStatement("select su.section,m.module,s.symbol,su.location from symbol_usages su,modules m,symbols s where su.fileid=? and s.symbolid=su.symbolid and s.moduleid=m.moduleid");
+ try {
+ ps.setLong(1, fileid);
+ ResultSet rs=ps.executeQuery();
+ try {
+ while(rs.next()){
+ addReference(f,ret, rs.getString(1), rs.getString(2)+"."+rs.getString(3), rs.getString(4),false);
+ }
+ } finally {
+ rs.close();
+ }
+ } finally {
+ ps.close();
+ }
+ return ret;
+ }
+
+ private void addReference(IFile f,Map<String,List<ReferenceLocation>> m,String section,String name,String loc,boolean mod) throws JSONException{
+ List<ReferenceLocation> s=m.get(section);
+ if (s==null){
+ s=new ArrayList<ReferenceLocation>();
+ m.put(section, s);
+ }
+ ReferenceLocation rl=new ReferenceLocation(name, f, new JSONArray(loc));
+ s.add(rl);
+ rl.setModule(mod);
+
+ }
}
@@ -14,6 +14,10 @@ FormatAction.label= &Format
FormatAction.description= Format using stylish-haskell
FormatAction.name= Format
+ImportsAction.label= Organize &Imports
+ImportsAction.description= Organize Imports
+ImportsAction.name= Organize &Imports
+
CommentAction.label = &Comment line
CommentAction.description = Comments code line (Adds -- to beginning of the line)
CommentAction.name = Comment
@@ -473,6 +473,11 @@
categoryId="net.sf.eclipsefp.haskell.ui.category.source"
name="%FormatAction.name"
id="net.sf.eclipsefp.haskell.ui.editor.actions.format"/>
+ <command
+ description="%ImportsAction.description"
+ categoryId="net.sf.eclipsefp.haskell.ui.category.source"
+ name="%ImportsAction.name"
+ id="net.sf.eclipsefp.haskell.ui.editor.actions.imports"/>
<command
description="%openDefinitionCommand_desc"
categoryId="org.eclipse.ui.category.navigate"
@@ -668,6 +673,11 @@
sequence="M1+M2+F"
commandId="net.sf.eclipsefp.haskell.ui.editor.actions.format"
contextId="net.sf.eclipsefp.haskell.ui.internal.editors.haskell.HaskellEditor.context" />
+ <!-- organize imports -->
+ <key schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
+ sequence="M1+M2+O"
+ commandId="net.sf.eclipsefp.haskell.ui.editor.actions.imports"
+ contextId="net.sf.eclipsefp.haskell.ui.internal.editors.haskell.HaskellEditor.context" />
<!-- keys for navigation -->
<key schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
commandId="net.sf.eclipsefp.ui.commands.navigate.openDefinition"
@@ -1187,6 +1197,12 @@
retarget="true"
menubarPath="net.sf.eclipsefp.haskell.ui.sourceMenu/commentGroup"
id="net.sf.eclipsefp.haskell.ui.actions.Format"/>
+ <action
+ definitionId="net.sf.eclipsefp.haskell.ui.editor.actions.imports"
+ label="%ImportsAction.label"
+ retarget="true"
+ menubarPath="net.sf.eclipsefp.haskell.ui.sourceMenu/commentGroup"
+ id="net.sf.eclipsefp.haskell.ui.actions.Imports"/>
<!-- Source menu: editGroup -->
<action
definitionId="org.eclipse.ui.edit.text.shiftLeft"
@@ -45,6 +45,8 @@ public void setActiveEditor(final IEditorPart editorPart) {
getAction(textEditor, HaskellEditor.COMMENT_PRAGMA_ACTION));
actionBars.setGlobalActionHandler( IHaskellActionConstants.FORMAT,
getAction(textEditor, HaskellEditor.FORMAT_ACTION));
+ actionBars.setGlobalActionHandler( IHaskellActionConstants.IMPORTS,
+ getAction(textEditor, HaskellEditor.IMPORTS_ACTION));
actionBars.setGlobalActionHandler(IHaskellActionConstants.SHIFT_RIGHT, getAction(textEditor, "ShiftRight")); //$NON-NLS-1$
actionBars.setGlobalActionHandler(IHaskellActionConstants.SHIFT_LEFT, getAction(textEditor, "ShiftLeft")); //$NON-NLS-1$
@@ -36,4 +36,7 @@
/** Comment menu: name of Comment action */
public static final String FORMAT = ActionPrefix.concat( "Format" );
+
+ /** Comment menu: name of Comment action */
+ public static final String IMPORTS = ActionPrefix.concat( "Imports" );
}
@@ -21,4 +21,5 @@
public final static String HADDOCK_PREVIOUS = ActionPrefix.concat( "haddock_previous" ); //$NON-NLS-1$
public final static String HADDOCK_BLOCK_FOLLOWING = ActionPrefix.concat( "haddock_block_following" ); //$NON-NLS-1$
public final static String FORMAT = ActionPrefix.concat( "format" ); //$NON-NLS-1$
+ public final static String IMPORTS = ActionPrefix.concat( "imports" ); //$NON-NLS-1$
}
@@ -35,6 +35,7 @@
import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.actions.HaddockBlockDocumentFollowingAction;
import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.actions.HaddockDocumentFollowingAction;
import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.actions.HaddockDocumentPreviousAction;
+import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.actions.OrganizeImportAction;
import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.actions.PragmaCommentAction;
import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.imports.ImportsManager;
import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.text.HaskellCharacterPairMatcher;
@@ -114,6 +115,9 @@
/** Action string associated with formatting */
public static final String FORMAT_ACTION = "Format"; //$NON-NLS-1$
+ /** Action string associated with formatting */
+ public static final String IMPORTS_ACTION = "Imports"; //$NON-NLS-1$
+
/** Resource prefix used to query properties for line comments (see plugin.properties) */
public static final String commentResourcePrefix = "CommentAction"; //$NON-NLS-1$
/** Resource prefix used to query properties for line commenting */
@@ -122,6 +126,8 @@
private static final String commentPragmaResourcePrefix = "CommentPragmaAction"; //$NON-NLS-1$
/** Resource prefix used to query properties for format */
private static final String formatResourcePrefix = "FormatAction"; //$NON-NLS-1$
+ /** Resource prefix used to query properties for format */
+ private static final String importsResourcePrefix = "ImportsAction"; //$NON-NLS-1$
/** The key binding context active while the Haskell editor is active */
private static final String CONTEXT_ID = HaskellEditor.class.getName() + ".context"; //$NON-NLS-1$
@@ -290,6 +296,7 @@ public void editorContextMenuAboutToShow( final IMenuManager menu ) {
addAction( mmSource, "comments", HADDOCK_DOCUMENT_PREVIOUS_ACTION); //$NON-NLS-1$
addAction( mmSource, "comments", HADDOCK_BLOCK_DOCUMENT_FOLLOWING_ACTION); //$NON-NLS-1$
addAction( mmSource, "formatting", FORMAT_ACTION); //$NON-NLS-1$
+ addAction( mmSource, "formatting", IMPORTS_ACTION); //$NON-NLS-1$
}
}
@@ -322,6 +329,8 @@ protected void createActions() {
setAction(FORMAT_ACTION,
new FormatAction( bundle, formatResourcePrefix + ".", this ));
+ setAction(IMPORTS_ACTION,
+ new OrganizeImportAction( bundle, importsResourcePrefix + ".", this ));
setAction(COMMENT_PRAGMA_ACTION,
new PragmaCommentAction( bundle, commentPragmaResourcePrefix + ".", this ));
setAction( HADDOCK_DOCUMENT_FOLLOWING_ACTION,
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2012 by JP Moresmau
+ * This code is made available under the terms of the Eclipse Public License,
+ * version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html
+ */
+package net.sf.eclipsefp.haskell.ui.internal.editors.haskell.actions;
+
+import java.util.ResourceBundle;
+import net.sf.eclipsefp.haskell.ui.editor.actions.IEditorActionDefinitionIds;
+import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.HaskellEditor;
+import net.sf.eclipsefp.haskell.ui.internal.editors.haskell.imports.ImportCleaner;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.TextEditorAction;
+
+
+/**
+ * @author JP Moresmau
+ *
+ */
+public class OrganizeImportAction extends TextEditorAction {
+
+ /**
+ * @param bundle
+ * @param prefix
+ * @param editor
+ */
+ public OrganizeImportAction( final ResourceBundle bundle, final String prefix,
+ final ITextEditor editor ) {
+ super( bundle, prefix, editor );
+ setId( HaskellEditor.IMPORTS_ACTION );
+ setActionDefinitionId( IEditorActionDefinitionIds.IMPORTS );
+ }
+
+ /**
+ * @param bundle
+ * @param prefix
+ * @param editor
+ * @param style
+ */
+ public OrganizeImportAction( final ResourceBundle bundle, final String prefix,
+ final ITextEditor editor, final int style ) {
+ super( bundle, prefix, editor, style );
+ setId( HaskellEditor.IMPORTS_ACTION );
+ setActionDefinitionId( IEditorActionDefinitionIds.IMPORTS );
+ }
+
+ @Override
+ public void update() {
+ super.update();
+ if (!isEnabled()) {
+ return;
+ }
+ if (!canModifyEditor()) {
+ setEnabled( false );
+ return;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.jface.action.Action#run()
+ */
+ @Override
+ public void run() {
+ ITextEditor editor = getTextEditor();
+ new ImportCleaner().cleanFile( editor );
+ }
+}
Oops, something went wrong.

0 comments on commit 27cbf06

Please sign in to comment.