/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ /* * Created on 25/09/2005 */ package com.python.pydev.analysis.organizeimports; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IMarker; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.log.Log; import org.python.pydev.editor.PyEdit; import org.python.pydev.editor.actions.IOrganizeImports; import org.python.pydev.editor.codefolding.MarkerAnnotationAndPosition; import org.python.pydev.editor.codefolding.PySourceViewer; import org.python.pydev.parser.jython.SimpleNode; import org.python.pydev.parser.jython.ast.Import; import org.python.pydev.parser.jython.ast.ImportFrom; import org.python.pydev.parser.visitors.scope.ASTEntry; import org.python.pydev.parser.visitors.scope.EasyASTIteratorVisitor; import com.aptana.shared_core.structure.Tuple; import com.python.pydev.analysis.IAnalysisPreferences; import com.python.pydev.analysis.builder.AnalysisRunner; /** * Important: this class is not fully working!!! * * @author Fabio */ public class OrganizeImportsFixesUnused implements IOrganizeImports { public boolean beforePerformArrangeImports(PySelection ps, PyEdit edit) { if (true) { throw new RuntimeException("This class is not working!!!"); } SimpleNode ast = edit.getAST(); if (ast == null) { return true; //we need it to be correctly parsed with an ast to be able to do it... } EasyASTIteratorVisitor visitor = new EasyASTIteratorVisitor(); try { ast.accept(visitor); } catch (Exception e1) { Log.log(e1); return true; //just go on } List<ASTEntry> availableImports = visitor.getAsList(new Class[] { ImportFrom.class, Import.class }); PySourceViewer s = edit.getPySourceViewer(); ArrayList<Tuple<MarkerAnnotationAndPosition, ASTEntry>> unusedImportsMarkers = new ArrayList<Tuple<MarkerAnnotationAndPosition, ASTEntry>>(); ArrayList<Tuple<MarkerAnnotationAndPosition, ASTEntry>> unusedWildImportsMarkers = new ArrayList<Tuple<MarkerAnnotationAndPosition, ASTEntry>>(); ArrayList<Tuple<MarkerAnnotationAndPosition, ASTEntry>> unresolvedImportsMarkers = new ArrayList<Tuple<MarkerAnnotationAndPosition, ASTEntry>>(); ArrayList<MarkerAnnotationAndPosition> undefinedVariablesMarkers = new ArrayList<MarkerAnnotationAndPosition>(); //get the markers we are interested in and the related ast elements for (Iterator<MarkerAnnotationAndPosition> it = s.getMarkerIterator(); it.hasNext();) { MarkerAnnotationAndPosition marker = it.next(); try { String type = marker.markerAnnotation.getMarker().getType(); if (type != null && type.equals(AnalysisRunner.PYDEV_ANALYSIS_PROBLEM_MARKER)) { Integer attribute = marker.markerAnnotation.getMarker().getAttribute( AnalysisRunner.PYDEV_ANALYSIS_TYPE, -1); if (attribute != null) { if (attribute.equals(IAnalysisPreferences.TYPE_UNUSED_IMPORT)) { unusedImportsMarkers.add(new Tuple<MarkerAnnotationAndPosition, ASTEntry>(marker, getImportEntry(marker, availableImports))); } else if (attribute.equals(IAnalysisPreferences.TYPE_UNUSED_WILD_IMPORT)) { unusedWildImportsMarkers.add(new Tuple<MarkerAnnotationAndPosition, ASTEntry>(marker, getImportEntry(marker, availableImports))); } else if (attribute.equals(IAnalysisPreferences.TYPE_UNRESOLVED_IMPORT)) { unresolvedImportsMarkers.add(new Tuple<MarkerAnnotationAndPosition, ASTEntry>(marker, getImportEntry(marker, availableImports))); } else if (attribute.equals(IAnalysisPreferences.TYPE_UNDEFINED_VARIABLE)) { undefinedVariablesMarkers.add(marker); } } } } catch (Exception e) { Log.log(e); } } return true; } /** * This gives an entry correspondent to the marker. * * @param marker the marker we want to get the import from * @param availableImports the available imports * * @return the entry with the node for the import */ private ASTEntry getImportEntry(MarkerAnnotationAndPosition marker, List<ASTEntry> availableImports) { return null; } /** * In this function we have to pass through all the imports available and make sure that: * * - only the used tokens remain in the import * * - any import that imports something we don't know is removed * * - tokens that are not defined in the document should get the available tokens in the workspace and if it * exists, it should add an import for that token. * * - If more than one token has the same name, it should be presented to the user to choose which should be used * the class to look at when doing the selection is org.eclipse.jdt.internal.ui.dialogs.MultiElementListSelectionDialog * the class that uses it is org.eclipse.jdt.internal.corext.codemanipulation.OrganizeImportsOperation * * another interesting selection pane is org.eclipse.ui.dialogs.TwoPaneElementSelector, altough it is probably * not the most applicable in this case. * * the action that jdt uses for this is org.eclipse.jdt.ui.actions.OrganizeImportsAction * */ public void performArrangeImports(PySelection ps, MarkerAnnotationAndPosition markerInfo, PyEdit edit) throws BadLocationException, CoreException { SimpleNode ast = edit.getAST(); if (ast == null) { //we need the ast to look for the imports... (the generated markers will be matched against them) return; } IMarker marker = markerInfo.markerAnnotation.getMarker(); Integer attribute = marker.getAttribute(AnalysisRunner.PYDEV_ANALYSIS_TYPE, -1); // IDocument doc = ps.getDoc(); if (attribute != null && attribute.equals(IAnalysisPreferences.TYPE_UNUSED_IMPORT)) { Integer start = (Integer) marker.getAttribute(IMarker.CHAR_START); Integer end = (Integer) marker.getAttribute(IMarker.CHAR_END); ps.setSelection(start, end); ps.deleteSelection(); } } public void afterPerformArrangeImports(PySelection ps, PyEdit pyEdit) { //do nothing } }