Merge remote-tracking branch 'origin/master'

This commit is contained in:
Alexander Lobas
2012-04-02 21:56:03 +04:00
70 changed files with 1064 additions and 316 deletions
@@ -1552,7 +1552,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
markDirtyIfSource(event.getFile(), true);
}
private void markDirtyIfSource(final VirtualFile file, boolean fromMove) {
private void markDirtyIfSource(final VirtualFile file, final boolean fromMove) {
final Set<String> pathsToMark = new HashSet<String>();
processRecursively(file, false, new FileProcessor() {
public void execute(final VirtualFile file) {
@@ -1568,6 +1568,12 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
}
else {
addSourceForRecompilation(projectId, file, srcInfo);
// when the file is moved to a new location, we should 'forget' previous associations
if (fromMove) {
if (srcInfo.clearPaths(projectId)) {
saveSourceInfo(file, srcInfo);
}
}
}
}
}
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.navigation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.PsiElementProcessor;
@@ -33,6 +34,7 @@ public class ClassImplementationsSearch implements QueryExecutor<PsiElement, Psi
}
public static boolean processImplementations(final PsiClass psiClass, final Processor<? super PsiClass> processor) {
final boolean showInterfaces = Registry.is("ide.goto.implementation.show.interfaces");
return ClassInheritorsSearch.search(psiClass, ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() {
@Override
public SearchScope compute() {
@@ -40,7 +42,10 @@ public class ClassImplementationsSearch implements QueryExecutor<PsiElement, Psi
}
}), true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
public boolean execute(@NotNull PsiClass element) {
return element.isInterface() || processor.process(element);
if (!showInterfaces && element.isInterface()) {
return true;
}
return processor.process(element);
}
}));
}
@@ -114,7 +114,7 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends DialogWrapper {
for (PsiDirectory psiDirectory : ((PsiPackage)element).getDirectories()) {
final VirtualFile virtualFile = psiDirectory.getVirtualFile();
sourceRoots.add(fileIndex.getSourceRootForFile(virtualFile));
sameModule &= destinationModule == fileIndex.getModuleForFile(virtualFile);
//sameModule &= destinationModule == fileIndex.getModuleForFile(virtualFile);
}
} else if (element instanceof PsiClass) {
final VirtualFile virtualFile = element.getContainingFile().getVirtualFile();
@@ -160,7 +160,9 @@ public class TestIntegrationUtils {
if (el != null) {
PsiMethod method = PsiTreeUtil.getParentOfType(el, PsiMethod.class, false);
if (method != null) {
GenerateMembersUtil.setupGeneratedMethod(method);
if (method.findDeepestSuperMethods().length > 0) {
GenerateMembersUtil.setupGeneratedMethod(method);
}
CreateFromUsageUtils.setupEditor(method, editor);
}
}
@@ -24,16 +24,21 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.NotNullLazyKey;
import com.intellij.psi.*;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
import com.intellij.psi.impl.AnyPsiChangeListener;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.reference.SoftReference;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -64,16 +69,23 @@ public class JavaResolveCache {
myVarToConstValueMapNonPhysical = new ConcurrentWeakHashMap<PsiVariable, Object>();
if (messageBus != null) {
messageBus.connect().subscribe(PsiManagerImpl.ANY_PSI_CHANGE_TOPIC, new AnyPsiChangeListener() {
final MessageBusConnection connection = messageBus.connect();
connection.subscribe(PsiManagerImpl.ANY_PSI_CHANGE_TOPIC, new AnyPsiChangeListener() {
@Override
public void beforePsiChanged(boolean isPhysical) {
clearCaches(isPhysical);
}
@Override
public void afterPsiChanged(boolean isPhysical) {
}
});
connection.subscribe(PsiModificationTracker.TOPIC, new PsiModificationTracker.Listener() {
@Override
public void modificationCountChanged() {
clearCaches(true);
}
});
}
}
@@ -197,7 +197,7 @@ public class HectorComponent extends JPanel {
slider.setOrientation(SwingConstants.HORIZONTAL);
slider.setPreferredSize(new Dimension(200, 40));
panel.add(slider, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
new Insets(5, 0, 5, 0), 0, 0));
}
}
@@ -205,11 +205,11 @@ public class HectorComponent extends JPanel {
for (Language language : mySliders.keySet()) {
JSlider slider = mySliders.get(language);
JPanel borderPanel = new JPanel(new BorderLayout());
slider.setPreferredSize(new Dimension(80, 100));
slider.setPreferredSize(new Dimension(100, 100));
borderPanel.add(new JLabel(language.getID()), BorderLayout.NORTH);
borderPanel.add(slider, BorderLayout.CENTER);
panel.add(borderPanel, new GridBagConstraints(GridBagConstraints.RELATIVE, 1, 1, 1, 0, 1, GridBagConstraints.CENTER, GridBagConstraints.VERTICAL,
new Insets(0, 0, 0, 0), 0, 0));
new Insets(0, 5, 0, 5), 0, 0));
}
}
@@ -110,11 +110,13 @@ public abstract class GotoActionBase extends AnAction {
}
protected static Pair<String, Integer> getInitialText(boolean useEditorSelection, AnActionEvent e) {
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (editor != null) {
final String selectedText = editor.getSelectionModel().getSelectedText();
if (selectedText != null && !selectedText.contains("\n")) {
return Pair.create(selectedText, 0);
if (useEditorSelection) {
final Editor editor = e.getData(PlatformDataKeys.EDITOR);
if (editor != null) {
final String selectedText = editor.getSelectionModel().getSelectedText();
if (selectedText != null && !selectedText.contains("\n")) {
return Pair.create(selectedText, 0);
}
}
}
@@ -52,10 +52,13 @@ import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.ex.VirtualFileManagerAdapter;
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerListener;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.PsiModificationTrackerImpl;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.*;
import com.intellij.util.containers.ConcurrentHashMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import com.intellij.util.messages.MessageBusConnection;
@@ -525,6 +528,8 @@ public class ProjectRootManagerImpl extends ProjectRootManagerEx implements Proj
myModificationCount++;
((PsiModificationTrackerImpl)PsiManager.getInstance(myProject).getModificationTracker()).incCounter();
isFiringEvent = true;
try {
myProject.getMessageBus()
@@ -89,6 +89,7 @@ public class ChangeListsScopesProvider extends CustomScopesProviderEx {
@Override
public boolean isVetoed(NamedScope scope, ScopePlace place) {
if (place == ScopePlace.SETTING) {
if (myProject.isDefault()) return false;
final ChangeListManager changeListManager = ChangeListManager.getInstance(myProject);
return changeListManager.findChangeList(scope.getName()) != null;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -236,7 +236,7 @@ public class AboutDialog extends JDialog {
g2.setColor(col);
TextRenderer renderer = new TextRenderer(0, 145, 398, 120, g2);
g2.setComposite(AlphaComposite.Src);
UIUtil.setupComposite(g2);
myFont = labelFont.deriveFont(Font.PLAIN, labelSize);
myBoldFont = labelFont.deriveFont(Font.BOLD, labelSize + 1);
try {
@@ -97,7 +97,7 @@ class AvailablePluginColumnInfo extends PluginManagerColumnInfo {
}
final IdeaPluginDescriptor installed = PluginManager.getPlugin(pluginNode.getPluginId());
if (isDownloaded(pluginNode) || (installed != null && InstalledPluginsTableModel.wasUpdated(installed.getPluginId()))) {
if (!isSelected) myNameLabel.setForeground(FileStatus.COLOR_ADDED);
if (!isSelected) myNameLabel.setForeground(FileStatus.ADDED.getColor());
myStatusLabel.setText("[Downloaded]");
myPanel.setToolTipText(IdeBundle.message("plugin.download.status.tooltip"));
myStatusLabel.setBorder(BorderFactory.createEmptyBorder(0, LEFT_MARGIN, 0, 0));
@@ -105,7 +105,7 @@ class AvailablePluginColumnInfo extends PluginManagerColumnInfo {
else if (pluginNode.getStatus() == PluginNode.STATUS_INSTALLED) {
PluginId pluginId = pluginNode.getPluginId();
final boolean hasNewerVersion = InstalledPluginsTableModel.hasNewerVersion(pluginId);
if (!isSelected) myNameLabel.setForeground(FileStatus.COLOR_MODIFIED);
if (!isSelected) myNameLabel.setForeground(FileStatus.MODIFIED.getColor());
if (hasNewerVersion) {
if (!isSelected){
myNameLabel.setForeground(Color.RED);
@@ -93,8 +93,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
final PluginId descrId = descriptor.getPluginId();
final IdeaPluginDescriptor existing = PluginManager.getPlugin(descrId);
if (existing != null) {
updateExistingPluginInfo(descriptor, existing);
updatedPlugins.add(existing.getPluginId());
updateExistingPlugin(descriptor, existing);
} else {
myInstalled.add(descriptor);
view.add(descriptor);
@@ -103,6 +102,11 @@ public class InstalledPluginsTableModel extends PluginTableModel {
}
}
public static void updateExistingPlugin(IdeaPluginDescriptor descriptor, IdeaPluginDescriptor existing) {
updateExistingPluginInfo(descriptor, existing);
updatedPlugins.add(existing.getPluginId());
}
public String getPluginHostUrl(String idString) {
return myPlugin2host.get(idString);
}
@@ -136,7 +140,7 @@ public class InstalledPluginsTableModel extends PluginTableModel {
for (String host : pluginHosts) {
try {
final ArrayList<PluginDownloader> downloaded = new ArrayList<PluginDownloader>();
UpdateChecker.checkPluginsHost(host, downloaded, false);
UpdateChecker.checkPluginsHost(host, downloaded, false, null);
for (PluginDownloader downloader : downloaded) {
myPlugin2host.put(downloader.getPluginId(), host);
}
@@ -637,6 +641,14 @@ public class InstalledPluginsTableModel extends PluginTableModel {
@Override
public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
if (isSortByStatus()) {
final boolean incompatible1 = PluginManager.isIncompatible(o1);
final boolean incompatible2 = PluginManager.isIncompatible(o2);
if (incompatible1) {
if (incompatible2) return comparator.compare(o1, o2);
return -1;
}
if (incompatible2) return 1;
final boolean hasNewerVersion1 = hasNewerVersion(o1.getPluginId());
final boolean hasNewerVersion2 = hasNewerVersion(o2.getPluginId());
if (hasNewerVersion1) {
@@ -669,6 +681,11 @@ public class InstalledPluginsTableModel extends PluginTableModel {
return -1;
}
if (deleted2) return 1;
final boolean enabled1 = isEnabled(o1.getPluginId());
final boolean enabled2 = isEnabled(o2.getPluginId());
if (enabled1 && !enabled2) return -1;
if (enabled2 && !enabled1) return 1;
}
return comparator.compare(o1, o2);
}
@@ -126,35 +126,37 @@ class PluginManagerColumnInfo extends ColumnInfo<IdeaPluginDescriptor, String> {
public Comparator<IdeaPluginDescriptor> getComparator() {
final Comparator<IdeaPluginDescriptor> comparator = getColumnComparator();
if (isSortByStatus()) {
final RowSorter.SortKey defaultSortKey = myModel.getDefaultSortKey();
final int up = defaultSortKey != null && defaultSortKey.getSortOrder() == SortOrder.ASCENDING ? -1 : 1;
return new Comparator<IdeaPluginDescriptor>() {
public int compare(IdeaPluginDescriptor o1, IdeaPluginDescriptor o2) {
if (o1 instanceof PluginNode && o2 instanceof PluginNode) {
final int status1 = ((PluginNode)o1).getStatus();
final int status2 = ((PluginNode)o2).getStatus();
if (isDownloaded((PluginNode)o1)){
if (!isDownloaded((PluginNode)o2)) return -1;
if (!isDownloaded((PluginNode)o2)) return up;
return comparator.compare(o1, o2);
}
if (isDownloaded((PluginNode)o2)) return 1;
if (isDownloaded((PluginNode)o2)) return -up;
if (status1 == PluginNode.STATUS_DELETED) {
if (status2 != PluginNode.STATUS_DELETED) return -1;
if (status2 != PluginNode.STATUS_DELETED) return up;
return comparator.compare(o1, o2);
}
if (status2 == PluginNode.STATUS_DELETED) return 1;
if (status2 == PluginNode.STATUS_DELETED) return -up;
if (status1 == PluginNode.STATUS_INSTALLED) {
if (status2 !=PluginNode.STATUS_INSTALLED) return -1;
if (status2 !=PluginNode.STATUS_INSTALLED) return up;
final boolean hasNewerVersion1 = InstalledPluginsTableModel.hasNewerVersion(o1.getPluginId());
final boolean hasNewerVersion2 = InstalledPluginsTableModel.hasNewerVersion(o2.getPluginId());
if (hasNewerVersion1 != hasNewerVersion2) {
if (hasNewerVersion1) return -1;
return 1;
if (hasNewerVersion1) return up;
return -up;
}
return comparator.compare(o1, o2);
}
if (status2 == PluginNode.STATUS_INSTALLED) {
return 1;
return -up;
}
}
return comparator.compare(o1, o2);
@@ -25,6 +25,7 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
@@ -219,7 +220,7 @@ public abstract class PluginManagerMain implements Disposable {
for (String host : UpdateSettings.getInstance().myPluginHosts) {
final ArrayList<PluginDownloader> downloaded = new ArrayList<PluginDownloader>();
try {
UpdateChecker.checkPluginsHost(host, downloaded, false);
UpdateChecker.checkPluginsHost(host, downloaded, false, null);
for (PluginDownloader downloader : downloaded) {
final PluginNode pluginNode = PluginDownloader.createPluginNode(host, downloader);
if (pluginNode != null) {
@@ -228,6 +229,8 @@ public abstract class PluginManagerMain implements Disposable {
}
}
}
catch (ProcessCanceledException ignore) {
}
catch (Exception e) {
LOG.info(e);
errorMessages.add(e.getMessage());
@@ -23,6 +23,9 @@ import com.intellij.util.ui.ColumnInfo;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import java.util.List;
/**
* Created by IntelliJ IDEA.
@@ -59,6 +62,19 @@ public class PluginTable extends JBTable {
column.setMaxWidth(width);
}
@Override
protected TableRowSorter<TableModel> createRowSorter(TableModel model) {
return new DefaultColumnInfoBasedRowSorter(model){
@Override
public void setSortKeys(List<? extends SortKey> sortKeys) {
if (sortKeys != null && !sortKeys.isEmpty()) {
((PluginTableModel)getModel()).setSortKey(sortKeys.get(0));
}
super.setSortKeys(sortKeys);
}
};
}
@Override
protected boolean isSortOnUpdates() {
return false;
@@ -19,6 +19,8 @@ import com.intellij.ide.IdeBundle;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.net.HttpConfigurable;
@@ -53,31 +55,39 @@ public class RepositoryHelper {
@NonNls private static final String FILENAME = "filename=";
@NonNls public static final String extPluginsFile = "availables.xml";
public static ArrayList<IdeaPluginDescriptor> process(@Nullable JLabel label) throws IOException, ParserConfigurationException, SAXException {
public static ArrayList<IdeaPluginDescriptor> process(@Nullable ProgressIndicator indicator) throws IOException, ParserConfigurationException, SAXException {
ArrayList<IdeaPluginDescriptor> plugins = null;
try {
BuildNumber buildNumber = ApplicationInfo.getInstance().getBuild();
@NonNls String url = getListUrl() + "?build=" + buildNumber.asString();
setLabelText(label, IdeBundle.message("progress.connecting.to.plugin.manager", getRepositoryHost()));
if (indicator != null) {
indicator.setText2(IdeBundle.message("progress.connecting.to.plugin.manager", getRepositoryHost()));
}
HttpConfigurable.getInstance().prepareURL(getRepositoryHost());
// if( !pi.isCanceled() )
{
RepositoryContentHandler handler = new RepositoryContentHandler();
HttpURLConnection connection = (HttpURLConnection)new URL(url).openConnection();
setLabelText(label, IdeBundle.message("progress.waiting.for.reply.from.plugin.manager", getRepositoryHost()));
if (indicator != null) {
indicator.setText2(IdeBundle.message("progress.waiting.for.reply.from.plugin.manager", getRepositoryHost()));
}
InputStream is = getConnectionInputStream(connection);
if (is != null) {
setLabelText(label, IdeBundle.message("progress.downloading.list.of.plugins"));
File temp = createLocalPluginsDescriptions();
readPluginsStream(temp, is, handler);
if (indicator != null) {
indicator.setText2(IdeBundle.message("progress.downloading.list.of.plugins"));
}
readPluginsStream( is, handler, indicator, extPluginsFile);
plugins = handler.getPluginsList();
}
}
}
catch (ProcessCanceledException e) {
throw e;
}
catch (RuntimeException e) {
e.printStackTrace();
if (e.getCause() == null || !(e.getCause() instanceof InterruptedException)) {
@@ -105,11 +115,11 @@ public class RepositoryHelper {
}
}
public static File createLocalPluginsDescriptions() throws IOException {
private static File createLocalPluginsDescriptions(final String file) throws IOException {
File basePath = new File(PathManager.getPluginsPath());
basePath.mkdirs();
File temp = new File(basePath, extPluginsFile);
File temp = new File(basePath, file);
if (temp.exists()) {
FileUtil.delete(temp);
}
@@ -117,8 +127,9 @@ public class RepositoryHelper {
return temp;
}
public static void readPluginsStream(File temp, InputStream is, RepositoryContentHandler handler)
throws SAXException, IOException, ParserConfigurationException {
private static void readPluginsStream(InputStream is, RepositoryContentHandler handler, ProgressIndicator indicator, final String file)
throws SAXException, IOException, ParserConfigurationException, ProcessCanceledException {
File temp = createLocalPluginsDescriptions(file);
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
FileOutputStream fos = null;
try {
@@ -128,6 +139,10 @@ public class RepositoryHelper {
int size = is.read(buffer);
if (size == -1) break;
fos.write(buffer, 0, size);
if (indicator != null) {
indicator.checkCanceled();
}
}
while (true);
fos.close();
@@ -142,11 +157,10 @@ public class RepositoryHelper {
}
}
public static ArrayList<IdeaPluginDescriptor> loadPluginsFromDescription(InputStream inputStream) throws SAXException, IOException, ParserConfigurationException {
public static ArrayList<IdeaPluginDescriptor> loadPluginsFromDescription(InputStream inputStream, ProgressIndicator indicator) throws SAXException, IOException, ParserConfigurationException {
try {
RepositoryContentHandler handler = new RepositoryContentHandler();
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(inputStream, handler);
readPluginsStream(inputStream, handler, indicator, "host.xml");
return handler.getPluginsList();
}
finally {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@ import java.awt.im.InputMethodRequests;
import java.util.Map;
public class EditorComponentImpl extends JComponent implements Scrollable, DataProvider, Queryable, TypingTarget {
private final EditorImpl myEditor;
public EditorComponentImpl(EditorImpl editor) {
@@ -144,7 +145,7 @@ public class EditorComponentImpl extends JComponent implements Scrollable, DataP
((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart();
try {
((Graphics2D)g).setComposite(AlphaComposite.Src);
UIUtil.setupComposite((Graphics2D)g);
UISettings.setupAntialiasing(g);
myEditor.paint((Graphics2D)g);
@@ -46,13 +46,14 @@ public class CheckForUpdateAction extends AnAction implements DumbAware {
final boolean enableLink,
final @Nullable PluginHostsConfigurable hostsConfigurable,
final UpdateSettings instance) {
ProgressManager.getInstance().run(new Task.Modal(project, "Checking for updates", false) {
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Checking for updates", true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
indicator.setIndeterminate(true);
final CheckForUpdateResult result = UpdateChecker.checkForUpdates(instance, true);
final List<PluginDownloader> updatedPlugins = UpdateChecker.updatePlugins(true, hostsConfigurable);
final List<PluginDownloader> updatedPlugins = UpdateChecker.updatePlugins(true, hostsConfigurable, indicator);
if (updatedPlugins == null) return;
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
@@ -127,6 +127,7 @@ public class PluginDownloader {
IdeaPluginDescriptorImpl descriptor = loadDescriptionFromJar(myFile);
if (descriptor != null) {
if (InstalledPluginsTableModel.wasUpdated(descriptor.getPluginId())) return false; //already updated
myPluginVersion = descriptor.getVersion();
if (ideaPluginDescriptor != null && StringUtil.compareVersionNumbers(ideaPluginDescriptor.getVersion(), descriptor.getVersion()) >= 0) {
LOG.info("Plugin " + myPluginId + ": current version (max) " + myPluginVersion);
@@ -160,7 +160,7 @@ public final class UpdateChecker {
public void run() {
final CheckForUpdateResult checkForUpdateResult = checkForUpdates(updateSettings, false);
final List<PluginDownloader> updatedPlugins = updatePlugins(false, null);
final List<PluginDownloader> updatedPlugins = updatePlugins(false, null, null);
app.invokeLater(new Runnable() {
@Override
public void run() {
@@ -174,12 +174,16 @@ public final class UpdateChecker {
}
public static List<PluginDownloader> updatePlugins(final boolean showErrorDialog,
final @Nullable PluginHostsConfigurable hostsConfigurable) {
final @Nullable PluginHostsConfigurable hostsConfigurable,
@Nullable ProgressIndicator indicator) {
final List<PluginDownloader> downloaded = new ArrayList<PluginDownloader>();
final Set<String> failed = new HashSet<String>();
for (String host : getPluginHosts(hostsConfigurable)) {
try {
checkPluginsHost(host, downloaded);
checkPluginsHost(host, downloaded, true, indicator);
}
catch (ProcessCanceledException e) {
return null;
}
catch (Exception e) {
LOG.info(e);
@@ -198,7 +202,7 @@ public final class UpdateChecker {
updateSettings.myOutdatedPlugins.clear();
if (!toUpdate.isEmpty()) {
try {
final ArrayList<IdeaPluginDescriptor> process = RepositoryHelper.process(null);
final ArrayList<IdeaPluginDescriptor> process = RepositoryHelper.process(indicator);
for (IdeaPluginDescriptor loadedPlugin : process) {
final String idString = loadedPlugin.getPluginId().getIdString();
final IdeaPluginDescriptor installedPlugin = toUpdate.get(idString);
@@ -215,6 +219,9 @@ public final class UpdateChecker {
}
}
}
catch (ProcessCanceledException ignore) {
return null;
}
catch (Exception e) {
showErrorMessage(showErrorDialog, e.getMessage());
}
@@ -256,12 +263,17 @@ public final class UpdateChecker {
}
public static boolean checkPluginsHost(final String host, final List<PluginDownloader> downloaded) throws Exception {
return checkPluginsHost(host, downloaded, true);
try {
return checkPluginsHost(host, downloaded, true, null);
}
catch (ProcessCanceledException e) {
return false;
}
}
public static boolean checkPluginsHost(final String host,
final List<PluginDownloader> downloaded,
final boolean collectToUpdate) throws Exception {
final boolean collectToUpdate, @Nullable ProgressIndicator indicator) throws Exception {
InputStream inputStream = loadVersionInfo(host);
if (inputStream == null) return false;
final Document document;
@@ -274,7 +286,7 @@ public final class UpdateChecker {
inputStream = loadVersionInfo(host);
if (inputStream == null) return false;
final ArrayList<IdeaPluginDescriptor> descriptors = RepositoryHelper.loadPluginsFromDescription(inputStream);
final ArrayList<IdeaPluginDescriptor> descriptors = RepositoryHelper.loadPluginsFromDescription(inputStream, indicator);
for (IdeaPluginDescriptor descriptor : descriptors) {
((PluginNode)descriptor).setRepositoryName(host);
downloaded.add(PluginDownloader.createDownloader(descriptor));
@@ -535,6 +547,8 @@ public final class UpdateChecker {
for (PluginDownloader downloader : downloaders) {
if (getDisabledToUpdatePlugins().contains(downloader.getPluginId())) continue;
try {
final IdeaPluginDescriptor descriptor = downloader.getDescriptor();
InstalledPluginsTableModel.updateExistingPlugin(descriptor, PluginManager.getPlugin(descriptor.getPluginId()));
downloader.install();
installed = true;
}
@@ -206,3 +206,6 @@ python.exported.names.local.cache=false
ide.use.nautilus3=true
ide.use.nautilus3.description=Use Nautilus if available
ide.goto.implementation.show.interfaces=false
ide.goto.implementation.show.interfaces.description=Whether to show sub-interfaces when invoking Goto Implementation (Ctrl+Alt+B) on an interface
@@ -372,6 +372,11 @@
<category>XML</category>
<className>com.intellij.codeInsight.daemon.impl.analysis.ConvertSchemaPrefixToDefaultIntention</className>
</intentionAction>
<intentionAction>
<category>XML</category>
<className>com.intellij.codeInsight.intentions.XmlChooseColorIntentionAction</className>
</intentionAction>
<lang.implementationTextSelectioner language="XML"
implementationClass="com.intellij.codeInsight.hint.XmlImplementationTextSelectioner"/>
<basicWordSelectionFilter implementation="com.intellij.codeInsight.editorActions.XmlBasicWordSelectionFilter"/>
@@ -72,6 +72,24 @@ import java.util.regex.Pattern;
public class UIUtil {
private static final String TABLE_DECORATION_KEY = "TABLE_DECORATION_KEY";
private static final Color DECORATED_ROW_BG_COLOR = new Color(242, 245, 249);
private static final AtomicNotNullLazyValue<Boolean> X_RENDER_ACTIVE = new AtomicNotNullLazyValue<Boolean>() {
@NotNull
@Override
protected Boolean compute() {
if (!SystemInfo.isLinux) {
return false;
}
try {
final Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass("sun.awt.X11GraphicsEnvironment");
final Method method = clazz.getMethod("isXRenderAvailable");
return (Boolean)method.invoke(null);
}
catch (Throwable e) {
return false;
}
}
};
public static void applyStyle(@NotNull ComponentStyle componentStyle, @NotNull Component comp) {
if (!(comp instanceof JComponent)) return;
@@ -1228,6 +1246,18 @@ public class UIUtil {
}
}
/**
* Configures composite to use for drawing text with the given graphics container.
* <p/>
* The whole idea is that <a href="http://en.wikipedia.org/wiki/X_Rendering_Extension">XRender-based</a> pipeline doesn't support
* {@link AlphaComposite#SRC} and we should use {@link AlphaComposite#SRC_OVER} instead.
*
* @param g target graphics container
*/
public static void setupComposite(@NotNull Graphics2D g) {
g.setComposite(X_RENDER_ACTIVE.getValue() ? AlphaComposite.SrcOver : AlphaComposite.Src);
}
@TestOnly
public static void dispatchAllInvocationEvents() {
assert SwingUtilities.isEventDispatchThread() : Thread.currentThread();
@@ -56,10 +56,6 @@ public interface VcsFileRevision extends VcsFileContent, VcsRevisionDescription
public byte[] getContent() throws IOException, VcsException {
return ArrayUtil.EMPTY_BYTE_ARRAY;
}
public int compareTo(VcsFileRevision vcsFileRevision) {
return 0;
}
};
String getBranchName();
@@ -59,7 +59,7 @@ public class LineStatusTrackerDrawing {
}
static TextAttributes getAttributesFor(final Range range) {
final Color stripeColor = getDiffColor(range);
final Color stripeColor = getDiffColor(range, false);
final TextAttributes textAttributes = new TextAttributes(null, stripeColor, null, EffectType.BOXED, Font.PLAIN);
textAttributes.setErrorStripeColor(stripeColor);
return textAttributes;
@@ -117,7 +117,7 @@ public class LineStatusTrackerDrawing {
public static LineMarkerRenderer createRenderer(final Range range, final LineStatusTracker tracker) {
return new ActiveGutterRenderer() {
public void paint(final Editor editor, final Graphics g, final Rectangle r) {
paintGutterFragment(editor, g, r, getDiffColor(range));
paintGutterFragment(editor, g, r, getDiffColor(range, true));
}
public void doAction(final Editor editor, final MouseEvent e) {
@@ -258,15 +258,17 @@ public class LineStatusTrackerDrawing {
});
}
private static Color getDiffColor(Range range) {
private static Color getDiffColor(Range range, boolean gutter) {
final EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme();
switch (range.getType()) {
case Range.INSERTED:
return globalScheme.getColor(EditorColors.ADDED_LINES_COLOR);
return gutter ? globalScheme.getColor(EditorColors.ADDED_LINES_COLOR)
: globalScheme.getAttributes(DiffColors.DIFF_INSERTED).getErrorStripeColor();
case Range.DELETED:
return globalScheme.getAttributes(DiffColors.DIFF_DELETED).getEffectColor();
return globalScheme.getAttributes(DiffColors.DIFF_DELETED).getErrorStripeColor();
case Range.MODIFIED:
return globalScheme.getColor(EditorColors.MODIFIED_LINES_COLOR);
return gutter ? globalScheme.getColor(EditorColors.MODIFIED_LINES_COLOR)
: globalScheme.getAttributes(DiffColors.DIFF_MODIFIED).getErrorStripeColor();
default:
assert false;
return null;
@@ -402,4 +402,5 @@ android.launch.ddms.already.launched.error=DDMS is already launched
android.disable.adb.service.title=Disable ADB service
android.launch.hierarchy.viewer.action=Hierarchy Viewer
android.launch.draw.9.patch.action=Draw 9 Patch
android.facet.settings.include.system.proguard=Include system proguard file
android.facet.settings.include.system.proguard=Include system proguard file
file.already.exists.error=File {0} already exists
@@ -47,7 +47,25 @@ public class AndroidAutogenerator {
private AndroidAutogenerator() {
}
private static boolean toRun(@NotNull AndroidAutogeneratorMode mode, @NotNull AndroidFacet facet) {
switch (mode) {
case AAPT:
return facet.getConfiguration().REGENERATE_R_JAVA &&
AndroidAptCompiler.isToCompileModule(facet.getModule(), facet.getConfiguration());
case AIDL:
return facet.getConfiguration().REGENERATE_JAVA_BY_AIDL;
case RENDERSCRIPT:
return true;
default:
LOG.error("Unknown autogenerator mode " + mode);
return false;
}
}
public static void run(@NotNull AndroidAutogeneratorMode mode, @NotNull AndroidFacet facet, @NotNull CompileContext context) {
if (!toRun(mode, facet)) {
return;
}
final Set<String> obsoleteFiles = new HashSet<String>(facet.getAutogeneratedFiles(mode));
switch (mode) {
@@ -40,6 +40,7 @@ import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
@@ -652,18 +653,38 @@ public class AndroidCompileUtil {
final Module module = facet.getModule();
final GlobalSearchScope moduleScope = facet.getModule().getModuleScope();
initializeGenSourceRoot(module,
AndroidRootUtil.getRenderscriptGenSourceRootPath(facet),
initializeGenSourceRoot(module, AndroidRootUtil.getRenderscriptGenSourceRootPath(facet),
FileTypeIndex.getFiles(AndroidRenderscriptFileType.INSTANCE, moduleScope).size() > 0);
if (AndroidAptCompiler.isToCompileModule(module, facet.getConfiguration())) {
initializeGenSourceRoot(module, AndroidRootUtil.getAptGenSourceRootPath(facet), true);
}
else {
// we need to include generated-sources/r to compilation, because it contains R.java generated by Maven,
// which should be used in Maven-based resource processing mode
includeAaptGenSourceRootToCompilation(facet);
}
initializeGenSourceRoot(module, AndroidRootUtil.getAptGenSourceRootPath(facet), true);
initializeGenSourceRoot(module,
AndroidRootUtil.getAidlGenSourceRootPath(facet),
initializeGenSourceRoot(module, AndroidRootUtil.getAidlGenSourceRootPath(facet),
FileTypeIndex.getFiles(AndroidIdlFileType.ourFileType, moduleScope).size() > 0);
}
private static void includeAaptGenSourceRootToCompilation(AndroidFacet facet) {
final Project project = facet.getModule().getProject();
final ExcludedEntriesConfiguration configuration =
((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getExcludedEntriesConfiguration();
final ExcludeEntryDescription[] descriptions = configuration.getExcludeEntryDescriptions();
configuration.removeAllExcludeEntryDescriptions();
for (ExcludeEntryDescription description : descriptions) {
final VirtualFile vFile = description.getVirtualFile();
if (!Comparing.equal(vFile, AndroidRootUtil.getAaptGenDir(facet))) {
configuration.addExcludeEntryDescription(description);
}
}
}
private static void initializeGenSourceRoot(@NotNull Module module, @Nullable String sourceRootPath, boolean createIfNotExist) {
if (sourceRootPath == null) {
return;
@@ -88,7 +88,7 @@ class InitialKeyStep extends ExportSignedPackageWizardStep {
myNewKeyButton.setSelected(true);
}
myAliasCombo.setModel(new CollectionComboBoxModel(myAliasList, myAliasList.size() > 0 ? myAliasList.get(0) : null));
String defaultAlias = PropertiesComponent.getInstance().getValue(DEFAULT_KEY_ALIAS);
String defaultAlias = PropertiesComponent.getInstance(myWizard.getProject()).getValue(DEFAULT_KEY_ALIAS);
if (defaultAlias != null) {
myAliasCombo.setSelectedItem(defaultAlias);
}
@@ -113,7 +113,7 @@ class InitialKeyStep extends ExportSignedPackageWizardStep {
if (privateKey == null || certificate == null) {
throw new CommitStepException(AndroidBundle.message("android.extract.package.cannot.find.key.error", alias));
}
PropertiesComponent.getInstance().setValue(DEFAULT_KEY_ALIAS, alias);
PropertiesComponent.getInstance(myWizard.getProject()).setValue(DEFAULT_KEY_ALIAS, alias);
myWizard.setPrivateKey(privateKey);
myWizard.setCertificate((X509Certificate)certificate);
}
@@ -57,7 +57,7 @@ class KeystoreStep extends ExportSignedPackageWizardStep {
public KeystoreStep(ExportSignedPackageWizard wizard) {
myWizard = wizard;
myKeystoreLocationLabel.setLabelFor(myKeystoreLocationField);
final String defaultLocation = PropertiesComponent.getInstance().getValue(DEFAULT_KEYSTORE_LOCATION);
final String defaultLocation = PropertiesComponent.getInstance(wizard.getProject()).getValue(DEFAULT_KEYSTORE_LOCATION);
final SaveFileListener newKeystoreLocationListener = new SaveFileListener(myContentPanel, myKeystoreLocationField,
AndroidBundle.message(
"android.extract.package.choose.keystore.title")) {
@@ -129,6 +129,12 @@ class KeystoreStep extends ExportSignedPackageWizardStep {
private void checkNewKeystoreOptions(File keystoreFile) throws CommitStepException {
checkNewPassword(myKeystorePasswordField, myConfirmKeystorePasswordField);
if (keystoreFile.exists()) {
throw new CommitStepException(AndroidBundle.message(
"file.already.exists.error", keystoreFile.getPath()));
}
File parentFile = keystoreFile.getParentFile();
if (parentFile == null || !parentFile.isDirectory()) {
String parentDir = keystoreFile.getParent();
@@ -184,7 +190,7 @@ class KeystoreStep extends ExportSignedPackageWizardStep {
else {
throw new CommitStepException(AndroidBundle.message("android.export.package.keystore.error.title"));
}
PropertiesComponent.getInstance().setValue(DEFAULT_KEYSTORE_LOCATION, keyStoreLocation);
PropertiesComponent.getInstance(myWizard.getProject()).setValue(DEFAULT_KEYSTORE_LOCATION, keyStoreLocation);
}
myWizard.setKeystoreLocation(keyStoreLocation);
myWizard.setKeystorePassword(myKeystorePasswordField.getPassword());
@@ -194,7 +200,7 @@ class KeystoreStep extends ExportSignedPackageWizardStep {
public void actionPerformed(ActionEvent e) {
String path = myKeystoreLocationField.getText().trim();
if (path == null || path.length() == 0) {
String defaultLocation = PropertiesComponent.getInstance().getValue(DEFAULT_KEYSTORE_LOCATION);
String defaultLocation = PropertiesComponent.getInstance(myWizard.getProject()).getValue(DEFAULT_KEYSTORE_LOCATION);
path = defaultLocation != null ? defaultLocation : "";
}
VirtualFile f = LocalFileSystem.getInstance().findFileByPath(path);
@@ -201,7 +201,7 @@ public class NewKeyStep extends ExportSignedPackageWizardStep {
}
throw new CommitStepException(AndroidBundle.message("android.cannot.create.new.key.error"));
}
PropertiesComponent.getInstance().setValue(KeystoreStep.DEFAULT_KEYSTORE_LOCATION, keystoreLocation);
PropertiesComponent.getInstance(myWizard.getProject()).setValue(KeystoreStep.DEFAULT_KEYSTORE_LOCATION, keystoreLocation);
loadKeystoreAndKey(keystoreLocation, keystorePassword, keyAlias, keyPassword);
}
finally {
@@ -227,7 +227,7 @@ public class NewKeyStep extends ExportSignedPackageWizardStep {
if (privateKey == null || certificate == null) {
throw new CommitStepException(AndroidBundle.message("android.extract.package.cannot.find.key.error", keyAlias));
}
PropertiesComponent.getInstance().setValue(InitialKeyStep.DEFAULT_KEY_ALIAS, keyAlias);
PropertiesComponent.getInstance(myWizard.getProject()).setValue(InitialKeyStep.DEFAULT_KEY_ALIAS, keyAlias);
myWizard.setPrivateKey(privateKey);
myWizard.setCertificate((X509Certificate)certificate);
@@ -212,26 +212,26 @@
</clientProperties>
<border type="etched" title-resource-bundle="messages/AndroidBundle" title-key="android.aidl.settings.title"/>
<children>
<component id="1d0b4" class="javax.swing.JLabel" binding="myAidlGenPathLabel">
<component id="28c2e" class="javax.swing.JCheckBox" binding="myGenerateIdlWhenChanged">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Destination directory:"/>
<text resource-bundle="messages/AndroidBundle" key="android.regenerate.idl.when.changed.checkbox"/>
</properties>
</component>
<component id="d9360" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myAidlGenPathField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="28c2e" class="javax.swing.JCheckBox" binding="myGenerateIdlWhenChanged">
<component id="1d0b4" class="javax.swing.JLabel" binding="myAidlGenPathLabel">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/AndroidBundle" key="android.regenerate.idl.when.changed.checkbox"/>
<text value="&amp;Destination directory:"/>
</properties>
</component>
</children>
@@ -250,14 +250,14 @@
<grid id="1f282" binding="myAaptCompilerPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="2" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="2b9e0" class="javax.swing.JLabel" binding="myRGenPathLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/AndroidBundle" key="android.dest.directory.title"/>
@@ -265,13 +265,13 @@
</component>
<component id="f229f" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myRGenPathField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
</component>
<component id="c99af" class="javax.swing.JCheckBox" binding="myGenerateRJavaWhenChanged">
<constraints>
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/AndroidBundle" key="android.generate.r.java.checkbox"/>
@@ -233,6 +233,24 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
return file.isDirectory() || "apk".equals(file.getExtension());
}
});
myGenerateIdlWhenChanged.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final boolean enabled = myGenerateIdlWhenChanged.isSelected();
myAidlGenPathLabel.setEnabled(enabled);
myAidlGenPathField.setEnabled(enabled);
}
});
myGenerateRJavaWhenChanged.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final boolean enabled = myGenerateRJavaWhenChanged.isSelected();
myRGenPathLabel.setEnabled(enabled);
myRGenPathField.setEnabled(enabled);
}
});
}
private void updateAptPanel() {
@@ -579,7 +597,12 @@ public class AndroidFacetEditorTab extends FacetEditorTab {
myIncludeSystemProguardFileCheckBox.setVisible(AndroidCommonUtils.isIncludingInProguardSupported(sdkToolsRevision));
myGenerateRJavaWhenChanged.setSelected(configuration.REGENERATE_R_JAVA);
myRGenPathLabel.setEnabled(configuration.REGENERATE_R_JAVA);
myRGenPathField.setEnabled(configuration.REGENERATE_R_JAVA);
myGenerateIdlWhenChanged.setSelected(configuration.REGENERATE_JAVA_BY_AIDL);
myAidlGenPathLabel.setEnabled(configuration.REGENERATE_JAVA_BY_AIDL);
myAidlGenPathField.setEnabled(configuration.REGENERATE_JAVA_BY_AIDL);
myUseCustomSourceDirectoryRadio.setSelected(configuration.USE_CUSTOM_APK_RESOURCE_FOLDER);
myUseAptResDirectoryFromPathRadio.setSelected(!configuration.USE_CUSTOM_APK_RESOURCE_FOLDER);
@@ -68,7 +68,7 @@ public class AndroidFrameworkDetector extends FacetBasedFrameworkDetector<Androi
Manifest manifest = facet.getManifest();
if (manifest != null) {
if (AndroidUtils.getDefaultActivityName(manifest) != null) {
AndroidUtils.addRunConfiguration(facet, null, true, null, null);
AndroidUtils.addRunConfiguration(facet, null, false, null, null);
}
}
}
@@ -159,6 +159,14 @@ public class AndroidRootUtil {
: null;
}
@Nullable
public static VirtualFile getAaptGenDir(@NotNull AndroidFacet facet) {
final String genPath = getAptGenSourceRootPath(facet);
return genPath != null
? LocalFileSystem.getInstance().findFileByPath(genPath)
: null;
}
@Nullable
public static VirtualFile getRenderscriptGenDir(@NotNull AndroidFacet facet) {
final String path = getRenderscriptGenSourceRootPath(facet);
@@ -37,7 +37,6 @@ import com.intellij.openapi.util.Pair;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.components.JBList;
import com.intellij.util.IconUtil;
import org.jetbrains.android.actions.AndroidEnableAdbServiceAction;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.sdk.AndroidPlatform;
import org.jetbrains.android.util.AndroidBundle;
@@ -216,7 +215,6 @@ public abstract class AndroidLogcatToolWindowView implements Disposable {
final DefaultActionGroup group1 = new DefaultActionGroup();
group1.addAll(myLogConsole.getToolbarActions());
group1.add(new AndroidEnableAdbServiceAction(AndroidUtils.DDMS_ICON));
group1.add(new MyRestartAction());
final JComponent tbComp1 =
ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group1, false).getComponent();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,9 +28,10 @@ import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler;
import com.intellij.cvsSupport2.cvshandlers.CvsHandler;
import com.intellij.cvsSupport2.cvsoperations.cvsAdd.AddedFileInfo;
import com.intellij.cvsSupport2.cvsoperations.cvsAdd.ui.AbstractAddOptionsDialog;
import com.intellij.cvsSupport2.ui.Options;
import com.intellij.cvsSupport2.ui.CvsTabbedWindow;
import com.intellij.cvsSupport2.ui.Options;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.actions.VcsContext;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
@@ -47,31 +48,27 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
private final String myTitle;
private final Options myOptions;
private final boolean myIsAutomaticallyAction;
public static AddFileOrDirectoryAction createActionToAddNewFileAutomatically() {
return new AddFileOrDirectoryAction(CvsBundle.getAddingFilesOperationName(), Options.ON_FILE_ADDING, true);
return new AddFileOrDirectoryAction(CvsBundle.getAddingFilesOperationName(), Options.ON_FILE_ADDING);
}
public AddFileOrDirectoryAction() {
this(CvsBundle.getAddingFilesOperationName(), Options.ADD_ACTION, false);
this(CvsBundle.getAddingFilesOperationName(), Options.ADD_ACTION);
getVisibility().canBePerformedOnSeveralFiles();
}
public AddFileOrDirectoryAction(String title, Options options, boolean isAutomatically) {
public AddFileOrDirectoryAction(String title, Options options) {
super(false);
myTitle = title;
myOptions = options;
myIsAutomaticallyAction = isAutomatically;
CvsActionVisibility visibility = getVisibility();
final CvsActionVisibility visibility = getVisibility();
visibility.addCondition(FILES_ARENT_UNDER_CVS);
}
public void update(AnActionEvent e) {
super.update(e);
if (!e.getPresentation().isVisible())
return;
Project project = CvsContextWrapper.createInstance(e).getProject();
if (!e.getPresentation().isVisible()) return;
final Project project = CvsContextWrapper.createInstance(e).getProject();
if (project == null) return;
adjustName(CvsVcs2.getInstance(project).getAddOptions().getValue(), e);
}
@@ -81,41 +78,34 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
}
protected CvsHandler getCvsHandler(CvsContext context) {
Project project = context.getProject();
boolean showDialog = myOptions.isToBeShown(project) || OptionsDialog.shiftIsPressed(context.getModifiers());
return getCvsHandler(project, context.getSelectedFiles(), !myIsAutomaticallyAction, showDialog, myOptions);
final Project project = context.getProject();
final boolean showDialog = myOptions.isToBeShown(project) || OptionsDialog.shiftIsPressed(context.getModifiers());
return getCvsHandler(project, context.getSelectedFiles(), showDialog, myOptions);
}
public static CvsHandler getDefaultHandler(Project project, VirtualFile[] files) {
return getCvsHandler(project, files, true, true, Options.NULL);
return getCvsHandler(project, files, true, Options.NULL);
}
private static CvsHandler getCvsHandler(final Project project,
final VirtualFile[] files,
final boolean includeAllRoots,
final boolean showDialog,
final Options dialogOptions) {
ArrayList<VirtualFile> filesToAdd = collectFilesToAdd(files);
final ArrayList<VirtualFile> filesToAdd = collectFilesToAdd(files);
if (filesToAdd.isEmpty()) return CvsHandler.NULL;
LOG.assertTrue(!filesToAdd.isEmpty());
Collection<AddedFileInfo> roots = new CreateTreeOnFileList(filesToAdd, project, includeAllRoots).getRoots();
if (roots.size() == 0) {
final Collection<AddedFileInfo> roots = new CreateTreeOnFileList(filesToAdd, project).getRoots();
if (roots.isEmpty()) {
LOG.error(filesToAdd);
}
if (showDialog){
AbstractAddOptionsDialog dialog = AbstractAddOptionsDialog.createDialog(project,
roots,
dialogOptions);
final AbstractAddOptionsDialog dialog = AbstractAddOptionsDialog.createDialog(project, roots, dialogOptions);
dialog.show();
if (!dialog.isOK()) return CvsHandler.NULL;
}
return CommandCvsHandler.createAddFilesHandler(project, roots);
}
@@ -123,7 +113,7 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
protected void onActionPerformed(final CvsContext context,
final CvsTabbedWindow tabbedWindow, final boolean successfully, final CvsHandler handler) {
super.onActionPerformed(context, tabbedWindow, successfully, handler);
VirtualFile[] filesToAdd = context.getSelectedFiles();
final VirtualFile[] filesToAdd = context.getSelectedFiles();
final VcsDirtyScopeManager dirtyScopeManager = VcsDirtyScopeManager.getInstance(context.getProject());
for(VirtualFile file: filesToAdd) {
if (file.isDirectory()) {
@@ -136,9 +126,9 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
}
private static ArrayList<VirtualFile> collectFilesToAdd(final VirtualFile[] files) {
ArrayList<VirtualFile> result = new ArrayList<VirtualFile>();
final ArrayList<VirtualFile> result = new ArrayList<VirtualFile>();
for (VirtualFile file : files) {
List<VirtualFile> parentsToAdd = new ArrayList<VirtualFile>();
final List<VirtualFile> parentsToAdd = new ArrayList<VirtualFile>();
VirtualFile parent = file.getParent();
do {
if (parent == null || CvsUtil.fileExistsInCvs(parent) || result.contains(parent)) break;
@@ -150,23 +140,20 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
if (parent != null) {
result.addAll(parentsToAdd);
}
addFilesToCollection(result, file);
}
Collections.sort(result, new Comparator<VirtualFile>() {
public int compare(final VirtualFile o1, final VirtualFile o2) {
return o1.getPath().compareTo(o2.getPath());
}
});
return result;
}
private static void addFilesToCollection(Collection<VirtualFile> collection, VirtualFile file) {
if (DeletedCVSDirectoryStorage.isAdminDir(file)) return;
collection.add(file);
VirtualFile[] children = file.getChildren();
final VirtualFile[] children = file.getChildren();
if (children == null) return;
for (VirtualFile child : children) {
addFilesToCollection(collection, child);
@@ -175,21 +162,18 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
static class CreateTreeOnFileList {
private final Collection<VirtualFile> myFiles;
private final Map<VirtualFile, AddedFileInfo> myResult
= new HashMap<VirtualFile, AddedFileInfo>();
private final Map<VirtualFile, AddedFileInfo> myResult = new HashMap<VirtualFile, AddedFileInfo>();
private final Project myProject;
public CreateTreeOnFileList(Collection<VirtualFile> files, Project project, boolean shouldIncludeAllRoots) {
public CreateTreeOnFileList(Collection<VirtualFile> files, Project project) {
myFiles = files;
myProject = project;
fillFileToInfoMap();
setAllParents();
if (!shouldIncludeAllRoots) {
final CvsEntriesManager entriesManager = CvsEntriesManager.getInstance();
for (final VirtualFile file : files) {
if (entriesManager.fileIsIgnored(file)) {
myResult.get(file).setIncluded(false);
}
final CvsEntriesManager entriesManager = CvsEntriesManager.getInstance();
for (final VirtualFile file : files) {
if (entriesManager.fileIsIgnored(file) || FileTypeManager.getInstance().isFileIgnored(file)) {
myResult.get(file).setIncluded(false);
}
}
removeFromMapInfoWithParentAndResortAll();
@@ -202,7 +186,7 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
private void removeFromMapInfoWithParentAndResortAll() {
for (final VirtualFile file : myFiles) {
if (myResult.containsKey(file)) {
AddedFileInfo info = myResult.get(file);
final AddedFileInfo info = myResult.get(file);
if (info.getParent() != null) {
myResult.remove(file);
}
@@ -216,7 +200,7 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
private void setAllParents() {
for (final VirtualFile file : myFiles) {
if (myResult.containsKey(file.getParent()) && myResult.containsKey(file)) {
AddedFileInfo info = myResult.get(file);
final AddedFileInfo info = myResult.get(file);
info.setParent(myResult.get(file.getParent()));
}
}
@@ -227,8 +211,5 @@ public class AddFileOrDirectoryAction extends ActionOnSelectedElement {
myResult.put(file, new AddedFileInfo(file, myProject, CvsConfiguration.getInstance(myProject)));
}
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vcs.ui.Refreshable;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashMap;
import java.io.File;
import java.io.IOException;
@@ -43,13 +44,12 @@ import java.util.*;
/**
* author: lesya
*/
public class IgnoreFileAction extends AnAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.actions.IgnoreFileAction");
private final CvsActionVisibility myVisibility = new CvsActionVisibility();
private final Map<VirtualFile,Set<VirtualFile>> myParentToSelectedChildren = new com.intellij.util.containers.HashMap<VirtualFile, Set<VirtualFile>>();
private final Map<VirtualFile,Set<VirtualFile>> myParentToSelectedChildren = new HashMap<VirtualFile, Set<VirtualFile>>();
public IgnoreFileAction() {
myVisibility.canBePerformedOnSeveralFiles();
@@ -57,17 +57,15 @@ public class IgnoreFileAction extends AnAction {
myVisibility.addCondition(ActionOnSelectedElement.FILES_ARE_NOT_IGNORED);
}
public void update(AnActionEvent e) {
myVisibility.applyToEvent(e);
}
public void actionPerformed(AnActionEvent e) {
CvsContext context = CvsContextWrapper.createCachedInstance(e);
VirtualFile[] selectedFiles = context.getSelectedFiles();
final CvsContext context = CvsContextWrapper.createCachedInstance(e);
final VirtualFile[] selectedFiles = context.getSelectedFiles();
for (VirtualFile selectedFile : selectedFiles) {
VirtualFile parent = selectedFile.getParent();
final VirtualFile parent = selectedFile.getParent();
if (!myParentToSelectedChildren.containsKey(parent)) myParentToSelectedChildren.put(parent, new HashSet<VirtualFile>());
myParentToSelectedChildren.get(parent).add(selectedFile);
try {
@@ -79,13 +77,11 @@ public class IgnoreFileAction extends AnAction {
CvsBundle.message("message.error.ignore.files.title"));
}
}
refreshFilesAndStatuses(context);
}
private static void refreshPanel(CvsContext context) {
Refreshable refreshablePanel = context.getRefreshableDialog();
final Refreshable refreshablePanel = context.getRefreshableDialog();
if (refreshablePanel != null) {
refreshablePanel.restoreState();
refreshablePanel.refresh();
@@ -93,7 +89,7 @@ public class IgnoreFileAction extends AnAction {
}
private void refreshFilesAndStatuses(final CvsContext context) {
Refreshable refreshablePanel = context.getRefreshableDialog();
final Refreshable refreshablePanel = context.getRefreshableDialog();
if (refreshablePanel != null) refreshablePanel.saveState();
final int[] refreshedParents = new int[]{0};
final Collection<VirtualFile> createdCvsIgnoreFiles = new ArrayList<VirtualFile>();
@@ -109,10 +105,11 @@ public class IgnoreFileAction extends AnAction {
return new Runnable() {
public void run() {
try {
VirtualFile cvsIgnoreFile = CvsVfsUtil.refreshAndfFindChild(parent, CvsUtil.CVS_IGNORE_FILE);
final VirtualFile cvsIgnoreFile = CvsVfsUtil.refreshAndfFindChild(parent, CvsUtil.CVS_IGNORE_FILE);
if (cvsIgnoreFile == null) {
String path = parent.getPath() + "/" + CvsUtil.CVS_IGNORE_FILE;
LOG.error(String.valueOf(CvsVfsUtil.findFileByPath(path)) + " " + parent.getPath() + " " + new File(VfsUtil.virtualToIoFile(parent), CvsUtil.CVS_IGNORE_FILE).isFile());
final String path = parent.getPath() + "/" + CvsUtil.CVS_IGNORE_FILE;
LOG.error(String.valueOf(CvsVfsUtil.findFileByPath(path)) + " " + parent.getPath() + " " +
new File(VfsUtil.virtualToIoFile(parent), CvsUtil.CVS_IGNORE_FILE).isFile());
return;
}
@@ -120,7 +117,7 @@ public class IgnoreFileAction extends AnAction {
createdCvsIgnoreFiles.add(cvsIgnoreFile);
}
Set<VirtualFile> filesToUpdateStatus = myParentToSelectedChildren.get(parent);
final Set<VirtualFile> filesToUpdateStatus = myParentToSelectedChildren.get(parent);
for (final VirtualFile file : filesToUpdateStatus) {
FileStatusManager.getInstance(context.getProject()).fileStatusChanged(file);
VcsDirtyScopeManager.getInstance(context.getProject()).fileDirty(file);
@@ -144,7 +141,7 @@ public class IgnoreFileAction extends AnAction {
}
private AddFileOrDirectoryAction createAddFilesAction() {
return new AddFileOrDirectoryAction(CvsBundle.message("adding.cvsignore.files.to.cvs.action.name"), Options.ON_FILE_ADDING, true) {
return new AddFileOrDirectoryAction(CvsBundle.message("adding.cvsignore.files.to.cvs.action.name"), Options.ON_FILE_ADDING) {
protected void onActionPerformed(CvsContext context,
CvsTabbedWindow tabbedWindow,
boolean successfully,
@@ -156,8 +153,7 @@ public class IgnoreFileAction extends AnAction {
};
}
private static CvsContextAdapter createContext(final Collection<VirtualFile> createdCvsIgnoreFiles,
final CvsContext context) {
private static CvsContextAdapter createContext(final Collection<VirtualFile> createdCvsIgnoreFiles, final CvsContext context) {
return new CvsContextAdapter() {
public VirtualFile[] getSelectedFiles() {
return VfsUtil.toVirtualFileArray(createdCvsIgnoreFiles);
@@ -15,6 +15,7 @@
*/
package git4idea.repo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -489,7 +490,7 @@ class GitRepositoryReader {
@Nullable
private static Charset calcEncoding(File file) {
VirtualFile vf = VcsUtil.getVirtualFile(file);
return EncodingManager.getInstance().getEncoding(vf, false);
return ApplicationManager.getApplication().isDisposed() ? null : EncodingManager.getInstance().getEncoding(vf, false);
}
/**
@@ -91,26 +91,60 @@ public class GitFetcher {
fetchResult = fetchAll(root, repository, fetchResult);
}
else {
return fetchCurrentBranch(root, repository);
return fetchCurrentRemote(repository);
}
repository.update(GitRepository.TrackedTopic.BRANCHES);
return fetchResult;
}
private GitFetchResult fetchCurrentRemote(@NotNull GitRepository repository) {
FetchParams fetchParams = getFetchParams(repository);
if (fetchParams.isError()) {
return fetchParams.getError();
}
GitRemote remote = fetchParams.getRemote();
String url = fetchParams.getUrl();
if (GitHttpAdapter.shouldUseJGit(url)) {
return GitHttpAdapter.fetch(repository, remote, url, null);
}
return fetchNatively(repository.getRoot(), remote, null);
}
// leaving this unused method, because the wanted behavior can change again
@SuppressWarnings("UnusedDeclaration")
@NotNull
private GitFetchResult fetchCurrentBranch(@NotNull VirtualFile root, @NotNull GitRepository repository) {
private GitFetchResult fetchCurrentBranch(@NotNull GitRepository repository) {
FetchParams fetchParams = getFetchParams(repository);
if (fetchParams.isError()) {
return fetchParams.getError();
}
GitRemote remote = fetchParams.getRemote();
String remoteBranch = fetchParams.getRemoteBranch();
String url = fetchParams.getUrl();
if (GitHttpAdapter.shouldUseJGit(url)) {
return GitHttpAdapter.fetch(repository, remote, url, remoteBranch);
}
return fetchNatively(repository.getRoot(), remote, remoteBranch);
}
@NotNull
private static FetchParams getFetchParams(@NotNull GitRepository repository) {
GitBranch currentBranch = repository.getCurrentBranch();
if (currentBranch == null) {
// fetching current branch is called from Update Project and Push, where branch tracking is pre-checked
String message = "Current branch can't be null here. \nRepository: " + repository;
LOG.error(message);
return GitFetchResult.error(new Exception(message));
return new FetchParams(GitFetchResult.error(new Exception(message)));
}
GitBranchTrackInfo trackInfo = GitBranchUtil.getTrackInfoForBranch(repository, currentBranch);
if (trackInfo == null) {
String message = "Tracked info is null for branch " + currentBranch + "\n Repository: " + repository;
LOG.error(message);
return GitFetchResult.error(new Exception(message));
return new FetchParams(GitFetchResult.error(new Exception(message)));
}
GitRemote remote = trackInfo.getRemote();
@@ -118,14 +152,10 @@ public class GitFetcher {
if (url == null) {
String message = "URL is null for remote " + remote.getName();
LOG.error(message);
return GitFetchResult.error(new Exception(message));
return new FetchParams(GitFetchResult.error(new Exception(message)));
}
String remoteBranch = trackInfo.getRemoteBranch();
if (GitHttpAdapter.shouldUseJGit(url)) {
return GitHttpAdapter.fetch(repository, remote, url, remoteBranch);
}
return fetchNatively(root, remote, remoteBranch);
return new FetchParams(remote, trackInfo.getRemoteBranch(), url);
}
@NotNull
@@ -317,4 +347,41 @@ public class GitFetcher {
return myPrunedRefs;
}
}
private static class FetchParams {
private GitRemote myRemote;
private String myRemoteBranch;
private GitFetchResult myError;
private String myUrl;
FetchParams(GitFetchResult error) {
myError = error;
}
FetchParams(GitRemote remote, String remoteBranch, String url) {
myRemote = remote;
myRemoteBranch = remoteBranch;
myUrl = url;
}
boolean isError() {
return myError != null;
}
public GitFetchResult getError() {
return myError;
}
public GitRemote getRemote() {
return myRemote;
}
public String getRemoteBranch() {
return myRemoteBranch;
}
public String getUrl() {
return myUrl;
}
}
}
@@ -267,11 +267,8 @@ public class ConvertParameterToMapEntryIntention extends Intention {
}
}
}
final GrArgumentList argumentList = call.getArgumentList();
final GrClosableBlock[] closureArguments = call.getClosureArguments();
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
GrClosureSignatureUtil.mapParametersToArguments(signature, argumentList, argumentList, closureArguments);
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, call);
if (argInfos == null) continue;
final GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = argInfos[index];
@@ -15,13 +15,20 @@
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrInstanceOfExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.InstructionImpl;
/**
* @author peter
*/
public class AssertionInstruction extends InstructionImpl {
public class AssertionInstruction extends InstructionImpl implements MixinTypeInstruction {
private final boolean myNegate;
public AssertionInstruction(int num, GrExpression assertion, boolean negate) {
@@ -37,4 +44,45 @@ public class AssertionInstruction extends InstructionImpl {
return "assertion: " + (myNegate ? "! " : "") + getElement().getText();
}
@Nullable
private GrInstanceOfExpression getApplicableInstanceofOrNull() {
final PsiElement element = getElement();
if (element instanceof GrInstanceOfExpression && !isNegate()) {
GrExpression operand = ((GrInstanceOfExpression)element).getOperand();
final GrTypeElement typeElement = ((GrInstanceOfExpression)element).getTypeElement();
if (operand instanceof GrReferenceExpression && ((GrReferenceExpression)operand).getQualifier() == null && typeElement != null) {
return (GrInstanceOfExpression)element;
}
}
return null;
}
@Nullable
public PsiType inferMixinType() {
GrInstanceOfExpression instanceOf = getApplicableInstanceofOrNull();
if (instanceOf == null) return null;
return instanceOf.getTypeElement().getType();
}
@Override
public ReadWriteVariableInstruction getInstructionToMixin(Instruction[] flow) {
GrInstanceOfExpression instanceOf = getApplicableInstanceofOrNull();
if (instanceOf == null) return null;
Instruction instruction = ControlFlowUtils.findInstruction(instanceOf.getOperand(), flow);
if (instruction instanceof ReadWriteVariableInstruction) {
return (ReadWriteVariableInstruction)instruction;
}
return null;
}
@Nullable
@Override
public String getVariableName() {
GrInstanceOfExpression instanceOf = getApplicableInstanceofOrNull();
if (instanceOf == null) return null;
return instanceOf.getOperand().getText();
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.Nullable;
/**
* @author Max Medvedev
*/
public interface MixinTypeInstruction extends Instruction {
@Nullable
ReadWriteVariableInstruction getInstructionToMixin(Instruction[] flow);
@Nullable
PsiType inferMixinType();
@Nullable
String getVariableName();
}
@@ -0,0 +1,108 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.MixinTypeInstruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
import static org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil.createSignature;
/**
* @author Max Medvedev
*/
public class ArgumentInstruction extends InstructionImpl implements MixinTypeInstruction {
private static final Logger LOG = Logger.getInstance(ArgumentInstruction.class);
public ArgumentInstruction(@Nullable GrReferenceExpression ref, int num) {
super(ref, num);
}
@Nullable
public PsiType inferMixinType() {
PsiElement element = getElement();
LOG.assertTrue(element instanceof GrReferenceExpression);
PsiElement parent = element.getParent().getParent();
LOG.assertTrue(parent instanceof GrCall, "elemText: " + element.getText() +
"\n elemParent = " + (element.getParent() == null ? "null" : element.getParent().getClass()) +
"\n elemPParent" + (parent == null ? "null" : parent.getClass()));
GrCall call = (GrCall)parent;
int index = ArrayUtil.indexOf(call.getExpressionArguments(), element);
if (call.getNamedArguments().length > 0) index++;
GroovyResolveResult[] variants = call.getCallVariants((GrReferenceExpression)element);
PsiType result = null;
for (GroovyResolveResult variant : variants) {
GrClosureSignature signature = createSignature(variant);
if (signature == null) continue;
if (GrClosureSignatureUtil.mapParametersToArguments(signature, call) != null && !haveNullParameters(call)) {
return null;
}
GrClosureParameter[] parameters = signature.getParameters();
if (index >= parameters.length) continue;
result = TypesUtil.getLeastUpperBoundNullable(result, parameters[index].getType(), element.getManager());
}
return result;
}
private static boolean haveNullParameters(GrCall call) {
for (GrExpression argument : call.getExpressionArguments()) {
if (argument.getType() == null) return true;
}
return false;
}
@Override
public ReadWriteVariableInstruction getInstructionToMixin(Instruction[] flow) {
Instruction instruction = ControlFlowUtils.findInstruction(getElement(), flow);
if (instruction instanceof ReadWriteVariableInstruction) {
return (ReadWriteVariableInstruction)instruction;
}
else {
return null;
}
}
public String getVariableName() {
return ((GrReferenceExpression)getElement()).getReferenceName();
}
@Override
protected String getElementPresentation() {
return "ARGUMENT " + super.getElementPresentation();
}
}
@@ -29,6 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrCondition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
@@ -236,6 +237,11 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
myHead = instruction;
}
private void addNodeAndCheckPending(InstructionImpl i) {
addNode(i);
checkPending(i);
}
private static void addEdge(InstructionImpl begin, InstructionImpl end) {
begin.addSuccessor(end);
end.addPredecessor(begin);
@@ -256,15 +262,10 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
for (String name : names) {
ReadWriteVariableInstruction i = new ReadWriteVariableInstruction(name, closure, myInstructionNumber++, READ);
addNode(i);
checkPending(i);
addNodeAndCheckPending(new ReadWriteVariableInstruction(name, closure, myInstructionNumber++, READ));
}
InstructionImpl i = new InstructionImpl(closure, myInstructionNumber++);
addNode(i);
checkPending(i);
addNodeAndCheckPending(new InstructionImpl(closure, myInstructionNumber++));
}
public void visitBreakStatement(GrBreakStatement breakStatement) {
@@ -332,8 +333,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
exception.accept(this);
final InstructionImpl throwInstruction = new ThrowingInstruction(throwStatement, myInstructionNumber++);
addNode(throwInstruction);
checkPending(throwInstruction);
addNodeAndCheckPending(throwInstruction);
interruptFlow();
final PsiType type = exception.getNominalType();
@@ -382,9 +382,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
if (lValue instanceof GrReferenceExpression) {
String referenceName = ((GrReferenceExpression)lValue).getReferenceName();
if (referenceName != null) {
ReadWriteVariableInstruction instruction = new ReadWriteVariableInstruction(referenceName, lValue, myInstructionNumber++, READ);
addNode(instruction);
checkPending(instruction);
addNodeAndCheckPending(new ReadWriteVariableInstruction(referenceName, lValue, myInstructionNumber++, READ));
}
}
}
@@ -438,9 +436,10 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
else {
boolean isWrite = !myAssertionsOnly && PsiUtil.isLValue(refExpr);
final InstructionImpl i = new ReadWriteVariableInstruction(name, refExpr, myInstructionNumber++, isWrite ? WRITE : READ);
addNode(i);
checkPending(i);
addNodeAndCheckPending(new ReadWriteVariableInstruction(name, refExpr, myInstructionNumber++, isWrite ? WRITE : READ));
if (refExpr.getParent() instanceof GrArgumentList) {
addNodeAndCheckPending(new ArgumentInstruction(refExpr, myInstructionNumber++));
}
}
}
else if (!(refExpr.getParent() instanceof GrCall)) {
@@ -507,8 +506,7 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
return;
}
final InstructionImpl instruction = new ThrowingInstruction(call, myInstructionNumber++);
addNode(instruction);
checkPending(instruction);
addNodeAndCheckPending(instruction);
for (ExceptionInfo info : myCaughtExceptionInfos) {
info.myThrowers.add(instruction);
@@ -934,13 +932,9 @@ public class ControlFlowBuilder extends GroovyRecursiveElementVisitor {
}
for (String var : vars) {
ReadWriteVariableInstruction i = new ReadWriteVariableInstruction(var, typeDefinition, myInstructionNumber++, READ);
addNode(i);
checkPending(i);
addNodeAndCheckPending(new ReadWriteVariableInstruction(var, typeDefinition, myInstructionNumber++, READ));
}
InstructionImpl i = new InstructionImpl(typeDefinition, myInstructionNumber++);
addNode(i);
checkPending(i);
addNodeAndCheckPending(new InstructionImpl(typeDefinition, myInstructionNumber++));
}
public void visitVariable(GrVariable variable) {
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIntersectionType;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.*;
import gnu.trove.TIntHashSet;
@@ -36,7 +37,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.AssertionInstruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.MixinTypeInstruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction;
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ArgumentInstruction;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.DFAEngine;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsDfaInstance;
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.reachingDefs.ReachingDefinitionsSemilattice;
@@ -66,7 +69,7 @@ public class TypeInferenceHelper {
final Instruction[] flow = scope.getControlFlow();
ReadWriteVariableInstruction instruction = findInstruction(refExpr, flow);
if (instruction == null) return null;
if (instruction.isWrite()) {
return getInitializerType(refExpr);
}
@@ -76,7 +79,7 @@ public class TypeInferenceHelper {
});
}
@Nullable
public static PsiType getInferredType(@NotNull PsiElement place, String variableName) {
final GrControlFlowOwner scope = ControlFlowUtils.findControlFlowOwner(place);
@@ -134,17 +137,18 @@ public class TypeInferenceHelper {
private static PsiType getInferredType(String varName, Instruction instruction, Instruction[] flow, GrControlFlowOwner scope) {
final Pair<ReachingDefinitionsDfaInstance, List<TIntObjectHashMap<TIntHashSet>>> pair = getDefUseMaps(scope);
final int varIndex = pair.first.getVarIndex(varName);
List<TIntObjectHashMap<TIntHashSet>> second = pair.second;
if (second == null) return null;
List<TIntObjectHashMap<TIntHashSet>> dfaResult = pair.second;
if (dfaResult == null) return null;
final TIntObjectHashMap<TIntHashSet> allDefs = second.get(instruction.num());
final int varIndex = pair.first.getVarIndex(varName);
final TIntObjectHashMap<TIntHashSet> allDefs = dfaResult.get(instruction.num());
final TIntHashSet varDefs = allDefs.get(varIndex);
if (varDefs == null) return null;
PsiType result = null;
for (int defIndex : varDefs.toArray()) {
PsiType defType = getDefinitionType(flow[defIndex]);
PsiType defType = getDefinitionType(flow[defIndex], flow, scope);
if (defType != null) {
defType = TypesUtil.boxPrimitiveType(defType, scope.getManager(), scope.getResolveScope());
result = result == null ? defType : TypesUtil.getLeastUpperBound(result, defType, scope.getManager());
@@ -174,7 +178,12 @@ public class TypeInferenceHelper {
}
}
}
} else {
}
else if (instruction instanceof ArgumentInstruction) {
final int varIndex = getVarIndex(((ArgumentInstruction)instruction).getVariableName());
registerDef(m, instruction, varIndex);
}
else {
super.fun(m, instruction);
}
}
@@ -188,26 +197,35 @@ public class TypeInferenceHelper {
}
@Nullable
private static PsiType getDefinitionType(Instruction instruction) {
private static PsiType getDefinitionType(Instruction instruction, Instruction[] flow, GrControlFlowOwner scope) {
if (instruction instanceof ReadWriteVariableInstruction && ((ReadWriteVariableInstruction) instruction).isWrite()) {
final PsiElement element = instruction.getElement();
if (element != null) {
return getInitializerType(element);
}
}
if (instruction instanceof AssertionInstruction) {
final AssertionInstruction assertionInstruction = (AssertionInstruction)instruction;
final PsiElement element = assertionInstruction.getElement();
if (element instanceof GrInstanceOfExpression && !assertionInstruction.isNegate()) {
final GrTypeElement typeElement = ((GrInstanceOfExpression)element).getTypeElement();
if (typeElement != null) {
return typeElement.getType();
}
}
if (instruction instanceof MixinTypeInstruction) {
return mixinType((MixinTypeInstruction)instruction, flow, scope);
}
return null;
}
@Nullable
private static PsiType mixinType(final MixinTypeInstruction instruction, final Instruction[] flow, final GrControlFlowOwner scope) {
return RecursionManager.doPreventingRecursion(instruction, false, new NullableComputable<PsiType>() {
@Override
@Nullable
public PsiType compute() {
final PsiType original = getInferredType(instruction.getVariableName(), instruction.getInstructionToMixin(flow), flow, scope);
final PsiType mixin = instruction.inferMixinType();
if (mixin == null) return original;
if (original == null) return mixin;
if (TypesUtil.isAssignableByMethodCallConversion(mixin, original, scope)) return original;
return PsiIntersectionType.createIntersection(mixin, original);
}
});
}
@Nullable
private static ReadWriteVariableInstruction findInstruction(final GrReferenceExpression refExpr, final Instruction[] flow) {
@@ -218,7 +236,7 @@ public class TypeInferenceHelper {
}
return null;
}
@Nullable
public static PsiType getInitializerType(final PsiElement element) {
if (element instanceof GrReferenceExpression && ((GrReferenceExpression) element).getQualifierExpression() == null) {
@@ -30,7 +30,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
@@ -494,7 +493,7 @@ public class GrClosureSignatureUtil {
return null;
}
final ArgInfo<PsiElement>[] argInfos = mapParametersToArguments(signature, namedArgs, expressionArgs, context, closureArguments, partial, eraseArgs);
final ArgInfo<PsiElement>[] argInfos = mapParametersToArguments(signature, namedArgs, expressionArgs, closureArguments, context, partial, eraseArgs);
if (argInfos == null) {
return null;
}
@@ -520,30 +519,18 @@ public class GrClosureSignatureUtil {
@Nullable
public static ArgInfo<PsiElement>[] mapParametersToArguments(@NotNull GrClosureSignature signature,
@Nullable GrArgumentList list,
@NotNull GroovyPsiElement context,
@NotNull GrClosableBlock[] closureArguments) {
return mapParametersToArguments(signature, list, context, closureArguments, false, false);
}
@Nullable
public static ArgInfo<PsiElement>[] mapParametersToArguments(@NotNull GrClosureSignature signature,
@Nullable GrArgumentList list,
@NotNull GroovyPsiElement context,
@NotNull GrClosableBlock[] closureArguments, final boolean partial, final boolean eraseArgs) {
final GrNamedArgument[] namedArgs = list == null ? GrNamedArgument.EMPTY_ARRAY : list.getNamedArguments();
final GrExpression[] expressionArgs = list == null ? GrExpression.EMPTY_ARRAY : list.getExpressionArguments();
return mapParametersToArguments(signature, namedArgs, expressionArgs, context, closureArguments, partial, eraseArgs);
public static ArgInfo<PsiElement>[] mapParametersToArguments(@NotNull GrClosureSignature signature, @NotNull GrCall call) {
return mapParametersToArguments(signature, call.getNamedArguments(), call.getExpressionArguments(), call.getClosureArguments(), call,
false, false);
}
@Nullable
public static ArgInfo<PsiElement>[] mapParametersToArguments(@NotNull GrClosureSignature signature,
@NotNull GrNamedArgument[] namedArgs,
@NotNull GrExpression[] expressionArgs,
@NotNull GroovyPsiElement context,
@NotNull GrClosableBlock[] closureArguments,
final boolean partial, boolean eraseArgs) {
@NotNull GroovyPsiElement context,
boolean partial, boolean eraseArgs) {
List<InnerArg> innerArgs = new ArrayList<InnerArg>();
boolean hasNamedArgs = namedArgs.length > 0;
@@ -81,9 +81,8 @@ public class GrMethodCallUsageInfo extends UsageInfo implements PossiblyIncorrec
myMapToArguments = GrClosureSignatureUtil.ArgInfo.empty_array();
}
else {
myMapToArguments = GrClosureSignatureUtil
.mapParametersToArguments(signature, call.getNamedArguments(), call.getExpressionArguments(), call, call.getClosureArguments(),
false, false);
myMapToArguments = GrClosureSignatureUtil.mapParametersToArguments(signature, call.getNamedArguments(), call.getExpressionArguments(),
call.getClosureArguments(), call, false, false);
}
}
@@ -56,10 +56,10 @@ class ArgumentListGenerator {
GrClosableBlock[] clArgs,
GroovyPsiElement context) {
GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
signature == null ? null : GrClosureSignatureUtil.mapParametersToArguments(signature, namedArgs, exprs, context, clArgs, false, false);
signature == null ? null : GrClosureSignatureUtil.mapParametersToArguments(signature, namedArgs, exprs, clArgs, context, false, false);
if (argInfos == null && signature != null) {
argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, namedArgs, exprs, context, clArgs, true, true);
argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, namedArgs, exprs, clArgs, context, true, true);
}
final PsiSubstitutor substitutor = signature == null ? PsiSubstitutor.EMPTY : signature.getSubstitutor();
@@ -129,8 +129,7 @@ public class TypeProvider {
if (element instanceof GrReferenceExpression) {
final GrCall call = (GrCall)element.getParent();
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil
.mapParametersToArguments(signature, call.getArgumentList(), ((GrReferenceExpression)element), call.getClosureArguments());
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, call);
if (argInfos == null) return true;
paramInds.forEach(new TIntProcedure() {
@@ -396,8 +396,9 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess
GrClosureSignature signature = GrClosureSignatureUtil.createSignature(callExpression);
if (signature == null) signature = GrClosureSignatureUtil.createSignature(toReplaceIn);
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs =
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, callExpression, callExpression.getClosureArguments(), true, true);
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs = GrClosureSignatureUtil
.mapParametersToArguments(signature, callExpression.getNamedArguments(), callExpression.getExpressionArguments(),
callExpression.getClosureArguments(), callExpression, true, true);
if (PsiTreeUtil.isAncestor(toReplaceIn, callExpression, false)) {
argList.addAfter(factory.createExpressionFromText(settings.getName()), anchor);
@@ -568,7 +569,7 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess
argList.add(expression);
}
removeParametersFromCall(methodCall, argList, settings);
removeParametersFromCall(methodCall, settings);
}
else {
@@ -576,15 +577,12 @@ public class GrIntroduceClosureParameterProcessor extends BaseRefactoringProcess
}
}
private static void removeParametersFromCall(GrMethodCallExpression methodCall,
GrArgumentList argList,
GrIntroduceParameterSettings settings) {
private static void removeParametersFromCall(GrMethodCallExpression methodCall, GrIntroduceParameterSettings settings) {
final GroovyResolveResult resolveResult = methodCall.advancedResolve();
final PsiElement resolved = resolveResult.getElement();
LOG.assertTrue(resolved instanceof PsiMethod);
final GrClosureSignature signature = GrClosureSignatureUtil.createSignature((PsiMethod)resolved, resolveResult.getSubstitutor());
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, methodCall, methodCall.getClosureArguments());
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, methodCall);
LOG.assertTrue(argInfos != null);
settings.parametersToRemove().forEach(new TIntProcedure() {
@Override
@@ -219,18 +219,15 @@ public class GroovyIntroduceParameterUtil {
argList.add(expression);
}
removeParametersFromCall(methodCall, argList, settings);
removeParametersFromCall(methodCall, settings);
}
private static void removeParametersFromCall(GrMethodCallExpression methodCall,
GrArgumentList argList,
GrIntroduceParameterSettings settings) {
private static void removeParametersFromCall(GrMethodCallExpression methodCall, GrIntroduceParameterSettings settings) {
final GroovyResolveResult resolveResult = methodCall.advancedResolve();
final PsiElement resolved = resolveResult.getElement();
LOG.assertTrue(resolved instanceof PsiMethod);
final GrClosureSignature signature = GrClosureSignatureUtil.createSignature((PsiMethod)resolved, resolveResult.getSubstitutor());
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos =
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, methodCall, methodCall.getClosureArguments());
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] argInfos = GrClosureSignatureUtil.mapParametersToArguments(signature, methodCall);
LOG.assertTrue(argInfos != null);
settings.parametersToRemove().forEach(new TIntProcedure() {
@Override
@@ -101,8 +101,9 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP
GrClosureSignature signature = GrClosureSignatureUtil.createSignature(callExpression);
if (signature == null) signature = GrClosureSignatureUtil.createSignature(data.getMethodToSearchFor(), PsiSubstitutor.EMPTY);
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs =
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, callExpression, callExpression.getClosureArguments(), true, true);
final GrClosureSignatureUtil.ArgInfo<PsiElement>[] actualArgs = GrClosureSignatureUtil
.mapParametersToArguments(signature, callExpression.getNamedArguments(), callExpression.getExpressionArguments(),
callExpression.getClosureArguments(), callExpression, true, true);
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(data.getProject());
@@ -1142,16 +1142,13 @@ Util.foo()<caret>'''
public void testPropertyChain() { doBasicTest() }
public void testMethodPointer() {
myFixture.configureByText('_a.groovy', '''\
doBasicTest('''\
class Base {
def prefixMethod(){}
def prefixField
}
new Base().&prefix<caret>''')
myFixture.completeBasic()
assertNull(myFixture.lookupElements)
myFixture.checkResult('''\
new Base().&prefix<caret>''', '''\
class Base {
def prefixMethod(){}
def prefixField
@@ -1160,23 +1157,27 @@ class Base {
new Base().&prefixMethod<caret>''')
}
public void testFieldPointer() {
myFixture.configureByText('_a.groovy', '''\
class Base {
def prefixMethod(){}
def prefixField
}
new Base().@prefix<caret>''')
private void doBasicTest(String before, String after) {
myFixture.configureByText('_a.groovy', before)
myFixture.completeBasic()
assertNull(myFixture.lookupElements)
myFixture.checkResult('''\
myFixture.checkResult(after)
}
public void testFieldPointer() {
doBasicTest '''\
class Base {
def prefixMethod(){}
def prefixField
}
new Base().@prefixField<caret>''')
new Base().@prefix<caret>''', '''\
class Base {
def prefixMethod(){}
def prefixField
}
new Base().@prefixField<caret>'''
}
public void testPrivateFieldOnSecondInvocation() {
@@ -1196,24 +1197,111 @@ new Base().fie<caret>x''')
}
public void testReturnInVoidMethod() {
myFixture.configureByText('''\
doBasicTest('''\
void foo() {
retur<caret>
}
''', '''\
void foo() {
return<caret>
}''')
}
''')
}
public void testReturnInNotVoidMethod() {
myFixture.configureByText('''\
void foo() {
doBasicTest('''\
String foo() {
retur<caret>
}
''', '''\
void foo() {
String foo() {
return <caret>
}''')
}
''')
}
void testInferArgumentTypeFromMethod1() {
doBasicTest('''\
def bar(String s) {}
def foo(Integer a) {
bar(a)
a.subSequen<caret>()
}
''', '''\
def bar(String s) {}
def foo(Integer a) {
bar(a)
a.subSequence(<caret>)
}
''')
}
void testInferArgumentTypeFromMethod2() {
doBasicTest('''\
def bar(String s) {}
def foo(Integer a) {
while(true) {
bar(a)
a.subSequen<caret>()
}
}
''', '''\
def bar(String s) {}
def foo(Integer a) {
while(true) {
bar(a)
a.subSequence(<caret>)
}
}
''')
}
void testInferArgumentTypeFromMethod3() {
doBasicTest('''\
def bar(String s) {}
def foo(Integer a) {
bar(a)
print a
a.subSequen<caret>()
}
''', '''\
def bar(String s) {}
def foo(Integer a) {
bar(a)
print a
a.subSequence(<caret>)
}
''')
}
void testInferArgumentTypeFromMethod4() {
doBasicTest('''\
def bar(String s) {}
def foo(Integer a) {
while(true) {
bar(a)
print a
a.subSequen<caret>()
}
}
''', '''\
def bar(String s) {}
def foo(Integer a) {
while(true) {
bar(a)
print a
a.subSequence(<caret>)
}
}
''')
}
}
@@ -939,5 +939,57 @@ class A {
assertEquals 'A', resolved.containingClass.name
}
public void testInferArgumentTypeFromMethod1() {
def ref = configureByText('''\
def bar(String s) {}
def foo(Integer a) {
bar(a)
a.subst<caret>ring(2)
}
''')
assertNotNull(ref.resolve())
}
public void testInferArgumentTypeFromMethod2() {
def ref = configureByText('''\
def bar(String s) {}
def foo(Integer a) {
while(true) {
bar(a)
a.subst<caret>ring(2)
}
}
''')
assertNotNull(ref.resolve())
}
public void testInferArgumentTypeFromMethod3() {
def ref = configureByText('''\
def bar(String s) {}
def foo(Integer a) {
bar(a)
a.int<caret>Value()
}
''')
assertNotNull(ref.resolve())
}
public void testInferArgumentTypeFromMethod4() {
def ref = configureByText('''\
def bar(String s) {}
def foo(Integer a) {
while(true) {
bar(a)
a.intVal<caret>ue()
}
}
''')
assertNotNull(ref.resolve())
}
}
@@ -344,9 +344,77 @@ def found = arr.findAll({it==1})
print fou<caret>nd''', 'java.util.Set<java.lang.String>')
}
void testInferArgumentTypeFromMethod1() {
doTest('''\
def bar(String s) {}
def foo(Integer a) {
while(true) {
bar(a)
<caret>a.substring(2)
}
}
''', '[java.lang.String,java.lang.Integer]')
}
void testInferArgumentTypeFromMethod2() {
doTest('''\
def bar(String s) {}
def foo(Integer a) {
bar(a)
<caret>a.substring(2)
}
''', '[java.lang.String,java.lang.Integer]')
}
void testInferArgumentTypeFromMethod3() {
doTest('''\
def bar(String s) {}
def foo(Integer a) {
bar(a)
print a
<caret>a.substring(2)
}
''', '[java.lang.String,java.lang.Integer]')
}
void testInferArgumentTypeFromMethod4() {
doTest('''\
def bar(String s) {}
def foo(Integer a) {
while(true) {
bar(a)
print a
<caret>a.substring(2)
}
}
''', '[java.lang.String,java.lang.Integer]')
}
private void doTest(String text, String type) {
def file = myFixture.configureByText('_.groovy', text)
def ref = file.findReferenceAt(myFixture.editor.caretModel.offset) as GrReferenceExpression
assertEquals(type, ref.type.canonicalText)
def actual = ref.type
if (actual instanceof PsiIntersectionType) {
assertEquals(type, genIntersectionTypeText(actual))
}
else {
assertEquals(type, actual.canonicalText)
}
}
private static String genIntersectionTypeText(PsiIntersectionType t) {
StringBuilder b = new StringBuilder('[')
for (PsiType c : t.conjuncts) {
b.append(c.canonicalText).append(',')
}
if (t.conjuncts) {
b.replace(b.length() - 1, b.length(), ']')
}
return b.toString()
}
}
+3 -2
View File
@@ -13,5 +13,6 @@ print x
3(4) element: Anonymous class
4(5) READ print
5(6) READ x
6(7) element: Call expression MAYBE_RETURN
7() element: null
6(7) ARGUMENT element: Reference expression
7(8) element: Call expression MAYBE_RETURN
8() element: null
+5 -4
View File
@@ -6,7 +6,8 @@ def t = k
1(2) WRITE k
2(3) READ sss
3(4) READ k
4(5) WRITE k
5(6) READ k
6(7) WRITE t
7() element: null
4(5) ARGUMENT element: Reference expression
5(6) WRITE k
6(7) READ k
7(8) WRITE t
8() element: null
+3 -2
View File
@@ -11,5 +11,6 @@ print x
3(4) element: Closable block
4(5) READ print
5(6) READ x
6(7) element: Call expression MAYBE_RETURN
7() element: null
6(7) ARGUMENT element: Reference expression
7(8) element: Call expression MAYBE_RETURN
8() element: null
+4 -3
View File
@@ -4,8 +4,9 @@ for (e in [1,2,3,4]) {
-----
0(1) element: null
1(2) WRITE e
2(3,6) element: For statement
2(3,7) element: For statement
3(4) element: Block statement
4(5) READ print
5(2) READ e
6() element: null
5(6) READ e
6(2) ARGUMENT element: Reference expression
7() element: null
+3 -2
View File
@@ -13,5 +13,6 @@ println blah
7(8) WRITE blah
8(9) READ println
9(10) READ blah
10(11) element: Call expression MAYBE_RETURN
11() element: null
10(11) ARGUMENT element: Reference expression
11(12) element: Call expression MAYBE_RETURN
12() element: null
+4 -3
View File
@@ -8,9 +8,10 @@ switch(i) {
-----
0(1) element: null
1(2) READ i
2(3,5,7) element: Switch statement
2(3,5,8) element: Switch statement
3(4) READ i
4(7) WRITE j
4(8) WRITE j
5(6) READ print
6(7) READ i
7() element: null
7(8) ARGUMENT element: Reference expression
8() element: null
+3 -2
View File
@@ -12,5 +12,6 @@ try {
5(6) WRITE e
6(7) READ print
7(8) READ e
8(9) element: Call expression MAYBE_RETURN
9() element: null
8(9) ARGUMENT element: Reference expression
9(10) element: Call expression MAYBE_RETURN
10() element: null
+4 -3
View File
@@ -13,12 +13,13 @@ print e
5(9) element: IF statement
6(11) element: Finally clause
7(6,8) CALL 6
8(16) AFTER CALL 7
8(17) AFTER CALL 7
9(6,10) CALL 6
10(13) AFTER CALL 9
11(12) READ e
12(8,10) RETURN
13(14) READ print
14(15) READ e
15(16) element: Call expression MAYBE_RETURN
16() element: null
15(16) ARGUMENT element: Reference expression
16(17) element: Call expression MAYBE_RETURN
17() element: null
+4 -3
View File
@@ -14,7 +14,7 @@ fScript.previewTask(taskName)
1(2,5) element: IF statement
2(3) READ ddd
3(4) READ fXRec
4(15) element: RETURN statement
4(16) element: RETURN statement
5(6) element: IF statement
6(7) WRITE fScript
7(9) element: Open block
@@ -24,5 +24,6 @@ fScript.previewTask(taskName)
11(10) RETURN
12(13) READ fScript
13(14) READ taskName
14(15) element: Method call MAYBE_RETURN
15() element: null
14(15) ARGUMENT element: Reference expression
15(16) element: Method call MAYBE_RETURN
16() element: null
+8 -7
View File
@@ -9,15 +9,16 @@ if (url == null) {
return url
-----
0(1) element: null
1(2,9) element: IF statement
1(2,10) element: IF statement
2(3) READ url
3(4) element: Open block
4(10) WRITE url
4(11) WRITE url
5(6) element: Catch clause
6(7) WRITE e
7(8) READ e
8(12) THROW. element: THROW statement
9(10) element: IF statement
10(11) READ url
11(12) element: RETURN statement
12() element: null
8(9) ARGUMENT element: Reference expression
9(13) THROW. element: THROW statement
10(11) element: IF statement
11(12) READ url
12(13) element: RETURN statement
13() element: null
@@ -9,4 +9,5 @@ foo<warning descr="'foo' in 'UnknownVarInArgList' cannot be applied to '(java.la
def abc(Date d){}
def abc(int i) {}
abc<warning descr="'abc' in 'UnknownVarInArgList' cannot be applied to '(null)'">(a)</warning>
def x = unknown2
abc<warning descr="'abc' in 'UnknownVarInArgList' cannot be applied to '(null)'">(x)</warning>
@@ -492,7 +492,7 @@ public class MavenIndex {
}
@TestOnly
public void printInfo() {
public synchronized void printInfo() {
doIndexTask(new IndexTask<Set<String>>() {
public Set<String> doTask() throws Exception {
System.out.println("BaseFile: " + myData.groupToArtifactMap.getBaseFile());
@@ -0,0 +1,5 @@
<html>
<body>
Allows to call Color Chooser for attributes
</body>
</html>
@@ -0,0 +1,87 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.intentions;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.XmlElementFactory;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.ui.ColorChooser;
import com.intellij.ui.ColorUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
/**
* @author Konstantin Bulenkov
*/
public class XmlChooseColorIntentionAction extends PsiElementBaseIntentionAction {
public XmlChooseColorIntentionAction() {
setText(CodeInsightBundle.message("intention.color.chooser.dialog"));
}
public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) {
final PsiElement parent = element.getParent();
return parent instanceof XmlAttributeValue && ColorUtil.fromHex(((XmlAttributeValue)parent).getValue(), null) != null;
}
@NotNull
public String getFamilyName() {
return getText();
}
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
if (!CodeInsightUtilBase.prepareFileForWrite(file)) return;
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
invokeForLiteral(editor.getComponent(), element);
}
private void invokeForLiteral(JComponent editorComponent, PsiElement element) {
final XmlAttributeValue literal = PsiTreeUtil.getParentOfType(element, XmlAttributeValue.class);
if (literal == null) return;
final String text = StringUtil.unquoteString(literal.getValue());
final String hexPrefix = text.startsWith("#") ? "#" : "";
Color oldColor;
try {
oldColor = Color.decode(text);
}
catch (NumberFormatException e) {
oldColor = Color.GRAY;
}
Color color = ColorChooser.chooseColor(editorComponent, getText(), oldColor, true);
if (color == null) return;
if (!Comparing.equal(color, oldColor)) {
final String newText = hexPrefix + ColorUtil.toHex(color);
final PsiManager manager = literal.getManager();
final XmlAttribute newAttribute = XmlElementFactory.getInstance(manager.getProject()).createXmlAttribute("name", newText);
literal.replace(newAttribute.getValueElement());
}
}
}