1a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye/* 2a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * Copyright (C) 2011 The Android Open Source Project 3a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * 4a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * you may not use this file except in compliance with the License. 6a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * You may obtain a copy of the License at 7a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * 8a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * http://www.eclipse.org/org/documents/epl-v10.php 9a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * 10a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * Unless required by applicable law or agreed to in writing, software 11a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * distributed under the License is distributed on an "AS IS" BASIS, 12a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * See the License for the specific language governing permissions and 14a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye * limitations under the License. 15a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye */ 16a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye 17a85107f7d763276a5a040cf68e2046ac54202015Tor Norbyepackage com.android.ide.eclipse.adt.internal.lint; 18a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye 1912d4581faa6438941e65a9dc83213be34c6ca970Tor Norbyeimport static com.android.SdkConstants.DOT_XML; 204c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 21bc32af8dc9e20135c29ba7444ae162761774cdb5Tor Norbyeimport com.android.ide.eclipse.adt.AdtPlugin; 22bc32af8dc9e20135c29ba7444ae162761774cdb5Tor Norbyeimport com.android.ide.eclipse.adt.AdtUtils; 234c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.IconFactory; 244c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport com.android.tools.lint.detector.api.LintUtils; 25bc32af8dc9e20135c29ba7444ae162761774cdb5Tor Norbye 26bc32af8dc9e20135c29ba7444ae162761774cdb5Tor Norbyeimport org.eclipse.core.resources.IFile; 27a85107f7d763276a5a040cf68e2046ac54202015Tor Norbyeimport org.eclipse.core.resources.IProject; 28c1a2b096df38e7b9e6bcac0cc217357f95d0dd3fTor Norbyeimport org.eclipse.core.resources.IResource; 29bc32af8dc9e20135c29ba7444ae162761774cdb5Tor Norbyeimport org.eclipse.jdt.core.IJavaProject; 304c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.jdt.ui.JavaElementLabelProvider; 314c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.jface.action.Action; 324c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.jface.action.ActionContributionItem; 33a85107f7d763276a5a040cf68e2046ac54202015Tor Norbyeimport org.eclipse.jface.action.IAction; 344c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.jface.action.IMenuCreator; 354c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.jface.action.Separator; 36bc32af8dc9e20135c29ba7444ae162761774cdb5Tor Norbyeimport org.eclipse.jface.dialogs.MessageDialog; 374c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.jface.resource.ImageDescriptor; 384c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.jface.viewers.ILabelProvider; 39a85107f7d763276a5a040cf68e2046ac54202015Tor Norbyeimport org.eclipse.jface.viewers.ISelection; 404c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.swt.widgets.Control; 414c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.swt.widgets.Menu; 42229581314076be1b6f82fe1efed2bd00da340899Tor Norbyeimport org.eclipse.ui.IObjectActionDelegate; 434c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.ui.ISharedImages; 44229581314076be1b6f82fe1efed2bd00da340899Tor Norbyeimport org.eclipse.ui.IWorkbenchPart; 45229581314076be1b6f82fe1efed2bd00da340899Tor Norbyeimport org.eclipse.ui.IWorkbenchWindow; 464c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.ui.IWorkbenchWindowPulldownDelegate; 474c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.ui.PlatformUI; 484c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport org.eclipse.ui.texteditor.ITextEditor; 494c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 504c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport java.util.ArrayList; 514c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyeimport java.util.List; 52a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye 534c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye/** 544c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * Action which runs Lint on the currently projects (and also provides a 554c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * pulldown menu in the toolbar for selecting specifically which projects to 564c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * check) 574c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye */ 584c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbyepublic class RunLintAction implements IObjectActionDelegate, IMenuCreator, 594c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye IWorkbenchWindowPulldownDelegate { 60a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye 61229581314076be1b6f82fe1efed2bd00da340899Tor Norbye private ISelection mSelection; 624c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye private Menu mMenu; 63a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye 64ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye @Override 65a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye public void selectionChanged(IAction action, ISelection selection) { 66a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye mSelection = selection; 67a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye } 68a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye 69ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye @Override 70a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye public void run(IAction action) { 714c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye List<IProject> projects = getProjects(mSelection, true /* warn */); 72a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye 734c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye if (!projects.isEmpty()) { 74d02dad911cea4f854e32cc99e10cdd31ab89a795Tor Norbye EclipseLintRunner.startLint(projects, null, null, false /*fatalOnly*/, true /*show*/); 75a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye } 76a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye } 77a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye 784c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye /** Returns the Android project(s) to apply a lint run to. */ 794c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye static List<IProject> getProjects(ISelection selection, boolean warn) { 807dd444ea0125e50a5e88604afb6de43e80b7c270Tor Norbye List<IProject> projects = AdtUtils.getSelectedProjects(selection); 814c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 824c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye if (projects.isEmpty() && warn) { 834c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye MessageDialog.openWarning(AdtPlugin.getDisplay().getActiveShell(), "Lint", 847dd444ea0125e50a5e88604afb6de43e80b7c270Tor Norbye "Could not run Lint: Select an Android project first."); 854c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 864c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 874c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye return projects; 88a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye } 89229581314076be1b6f82fe1efed2bd00da340899Tor Norbye 90ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye @Override 91229581314076be1b6f82fe1efed2bd00da340899Tor Norbye public void setActivePart(IAction action, IWorkbenchPart targetPart) { 92229581314076be1b6f82fe1efed2bd00da340899Tor Norbye } 93229581314076be1b6f82fe1efed2bd00da340899Tor Norbye 94ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye @Override 95229581314076be1b6f82fe1efed2bd00da340899Tor Norbye public void dispose() { 964c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye if (mMenu != null) { 974c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye mMenu.dispose(); 984c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 99229581314076be1b6f82fe1efed2bd00da340899Tor Norbye } 100229581314076be1b6f82fe1efed2bd00da340899Tor Norbye 101ab36f4e7488358dea4ab6b54ee2b7bef3da0232bTor Norbye @Override 102229581314076be1b6f82fe1efed2bd00da340899Tor Norbye public void init(IWorkbenchWindow window) { 103229581314076be1b6f82fe1efed2bd00da340899Tor Norbye } 1044c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1054c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye // ---- IMenuCreator ---- 1064c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1074c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye @Override 1084c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye public Menu getMenu(Control parent) { 1094c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye mMenu = new Menu(parent); 1104c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1114c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye IconFactory iconFactory = IconFactory.getInstance(); 1124c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye ImageDescriptor allIcon = iconFactory.getImageDescriptor("lintrun"); //$NON-NLS-1$ 1134c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye LintMenuAction allAction = new LintMenuAction("Check All Projects", allIcon, false, null); 1144c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1154c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye addAction(allAction); 1164c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye addSeparator(); 1174c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye IJavaProject[] projects = AdtUtils.getOpenAndroidProjects(); 1184c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye ILabelProvider provider = new JavaElementLabelProvider( 1194c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye JavaElementLabelProvider.SHOW_DEFAULT); 1204c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye for (IJavaProject project : projects) { 1214c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye IProject p = project.getProject(); 1224c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye ImageDescriptor icon = ImageDescriptor.createFromImage(provider.getImage(p)); 1234c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye String label = String.format("Check %1$s", p.getName()); 1244c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye LintMenuAction projectAction = new LintMenuAction(label, icon, false, p); 1254c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye addAction(projectAction); 1264c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1274c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1284c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye ITextEditor textEditor = AdtUtils.getActiveTextEditor(); 1294c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye if (textEditor != null) { 1304c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye IFile file = AdtUtils.getActiveFile(); 1314c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye // Currently only supported for XML files 1324c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye if (file != null && LintUtils.endsWith(file.getName(), DOT_XML)) { 1334c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye ImageDescriptor icon = ImageDescriptor.createFromImage(provider.getImage(file)); 1344c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye IAction fileAction = new LintMenuAction("Check Current File", icon, false, file); 1354c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1364c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye addSeparator(); 1374c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye addAction(fileAction); 1384c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1394c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1404c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1414c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye ISharedImages images = PlatformUI.getWorkbench().getSharedImages(); 1424c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye ImageDescriptor clear = images.getImageDescriptor(ISharedImages.IMG_ELCL_REMOVEALL); 143d02dad911cea4f854e32cc99e10cdd31ab89a795Tor Norbye LintMenuAction clearAction = new LintMenuAction("Clear Lint Warnings", clear, true, null); 1444c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye addSeparator(); 1454c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye addAction(clearAction); 1464c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1474c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye return mMenu; 1484c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1494c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1504c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye private void addAction(IAction action) { 1514c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye ActionContributionItem item = new ActionContributionItem(action); 1524c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye item.fill(mMenu, -1); 1534c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1544c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1554c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye private void addSeparator() { 1564c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye new Separator().fill(mMenu, -1); 1574c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1584c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1594c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye @Override 1604c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye public Menu getMenu(Menu parent) { 1614c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye return null; 1624c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1634c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1644c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye /** 1654c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * Actions in the pulldown context menu: run lint or clear lint markers on 1664c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * the given resource 1674c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye */ 1684c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye private static class LintMenuAction extends Action { 1694c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye private final boolean mClear; 1704c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye private final IResource mResource; 1714c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1724c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye /** 1734c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * Creates a new context menu action 1744c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * 1754c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * @param text the label 1764c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * @param descriptor the icon 1774c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * @param clear if true, clear lint markers otherwise check the resource 1784c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * @param resource the resource to check or clear markers for, where 1794c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye * null means all projects 1804c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye */ 1814c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye private LintMenuAction(String text, ImageDescriptor descriptor, boolean clear, 1824c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye IResource resource) { 1834c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye super(text, descriptor); 1844c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye mClear = clear; 1854c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye mResource = resource; 1864c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1874c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye 1884c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye @Override 1894c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye public void run() { 1904c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye List<IResource> resources = new ArrayList<IResource>(); 1914c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye if (mResource == null) { 1924c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye // All projects 1934c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye IJavaProject[] open = AdtUtils.getOpenAndroidProjects(); 1944c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye for (IJavaProject project : open) { 1954c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye resources.add(project.getProject()); 1964c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 1974c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } else { 1984c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye resources.add(mResource); 1994c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 200d6124a176326169bc87cb29823ca2dc906689680Tor Norbye EclipseLintRunner.cancelCurrentJobs(false); 2014c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye if (mClear) { 2024c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye EclipseLintClient.clearMarkers(resources); 2034c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } else { 204d02dad911cea4f854e32cc99e10cdd31ab89a795Tor Norbye EclipseLintRunner.startLint(resources, null, null, false /*fatalOnly*/, 205d02dad911cea4f854e32cc99e10cdd31ab89a795Tor Norbye true /*show*/); 2064c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 2074c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 2084c68f3dc9f10b76f1a32ff9c86587adca385a6d7Tor Norbye } 209a85107f7d763276a5a040cf68e2046ac54202015Tor Norbye} 210