mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 13:11:39 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -36,7 +36,9 @@ import com.intellij.ui.CollectionListModel;
|
||||
import com.intellij.ui.ColoredListCellRenderer;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ConcurrentMultiMap;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -88,45 +90,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
|
||||
myModulesProvider = modulesProvider;
|
||||
|
||||
myTemplatesMap = new ConcurrentMultiMap<TemplatesGroup, ProjectTemplate>();
|
||||
myTemplatesMap.putAllValues(CreateFromTemplateMode.getTemplatesMap(context, false));
|
||||
|
||||
for (ProjectCategory category : ProjectCategory.EXTENSION_POINT_NAME.getExtensions()) {
|
||||
myTemplatesMap.put(new TemplatesGroup(category), new ArrayList<ProjectTemplate>());
|
||||
}
|
||||
if (context.isCreatingNewProject()) {
|
||||
MultiMap<String, ProjectTemplate> localTemplates = loadLocalTemplates();
|
||||
for (TemplatesGroup group : myTemplatesMap.keySet()) {
|
||||
myTemplatesMap.putValues(group, localTemplates.get(group.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
// remove empty groups
|
||||
for (Iterator<Map.Entry<TemplatesGroup, Collection<ProjectTemplate>>> iterator = myTemplatesMap.entrySet().iterator();
|
||||
iterator.hasNext(); ) {
|
||||
Map.Entry<TemplatesGroup, Collection<ProjectTemplate>> entry = iterator.next();
|
||||
if (entry.getValue().isEmpty()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
List<TemplatesGroup> groups = new ArrayList<TemplatesGroup>(myTemplatesMap.keySet());
|
||||
Collections.sort(groups);
|
||||
|
||||
// move subgroups
|
||||
MultiMap<String, TemplatesGroup> subGroups = new MultiMap<String, TemplatesGroup>();
|
||||
for (ListIterator<TemplatesGroup> iterator = groups.listIterator(); iterator.hasNext(); ) {
|
||||
TemplatesGroup group = iterator.next();
|
||||
if (group.getParentGroup() != null) {
|
||||
subGroups.putValue(group.getParentGroup(), group);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
for (ListIterator<TemplatesGroup> iterator = groups.listIterator(); iterator.hasNext(); ) {
|
||||
TemplatesGroup group = iterator.next();
|
||||
for (TemplatesGroup subGroup : subGroups.get(group.getName())) {
|
||||
iterator.add(subGroup);
|
||||
}
|
||||
}
|
||||
List<TemplatesGroup> groups = fillTemplatesMap(context);
|
||||
|
||||
myProjectTypeList.setModel(new CollectionListModel<TemplatesGroup>(groups));
|
||||
myProjectTypeList.setCellRenderer(new ColoredListCellRenderer<TemplatesGroup>() {
|
||||
@@ -137,9 +101,9 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
|
||||
}
|
||||
else {
|
||||
setBorder(IdeBorderFactory.createEmptyBorder(3, 10, 3, 5));
|
||||
setIcon(value.getIcon());
|
||||
}
|
||||
append(value.getName());
|
||||
setIcon(value.getIcon());
|
||||
}
|
||||
});
|
||||
|
||||
@@ -165,6 +129,56 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable, Act
|
||||
myProjectTypeList.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
private List<TemplatesGroup> fillTemplatesMap(WizardContext context) {
|
||||
myTemplatesMap.putAllValues(CreateFromTemplateMode.getTemplatesMap(context));
|
||||
|
||||
for (ProjectCategory category : ProjectCategory.EXTENSION_POINT_NAME.getExtensions()) {
|
||||
myTemplatesMap.put(new TemplatesGroup(category), new ArrayList<ProjectTemplate>());
|
||||
}
|
||||
if (context.isCreatingNewProject()) {
|
||||
MultiMap<String, ProjectTemplate> localTemplates = loadLocalTemplates();
|
||||
for (TemplatesGroup group : myTemplatesMap.keySet()) {
|
||||
myTemplatesMap.putValues(group, localTemplates.get(group.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
// remove empty groups
|
||||
for (Iterator<Map.Entry<TemplatesGroup, Collection<ProjectTemplate>>> iterator = myTemplatesMap.entrySet().iterator();
|
||||
iterator.hasNext(); ) {
|
||||
Map.Entry<TemplatesGroup, Collection<ProjectTemplate>> entry = iterator.next();
|
||||
if (entry.getValue().isEmpty()) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
List<TemplatesGroup> groups = new ArrayList<TemplatesGroup>(myTemplatesMap.keySet());
|
||||
Collections.sort(groups);
|
||||
Set<String> groupNames = ContainerUtil.map2Set(groups, new Function<TemplatesGroup, String>() {
|
||||
@Override
|
||||
public String fun(TemplatesGroup group) {
|
||||
return group.getName();
|
||||
}
|
||||
});
|
||||
|
||||
// move subgroups
|
||||
MultiMap<String, TemplatesGroup> subGroups = new MultiMap<String, TemplatesGroup>();
|
||||
for (ListIterator<TemplatesGroup> iterator = groups.listIterator(); iterator.hasNext(); ) {
|
||||
TemplatesGroup group = iterator.next();
|
||||
String parentGroup = group.getParentGroup();
|
||||
if (parentGroup != null && groupNames.contains(parentGroup) && !group.getName().equals(parentGroup)) {
|
||||
subGroups.putValue(parentGroup, group);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
for (ListIterator<TemplatesGroup> iterator = groups.listIterator(); iterator.hasNext(); ) {
|
||||
TemplatesGroup group = iterator.next();
|
||||
for (TemplatesGroup subGroup : subGroups.get(group.getName())) {
|
||||
iterator.add(subGroup);
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
// new category or template is selected
|
||||
public void projectTypeChanged() {
|
||||
|
||||
|
||||
+2
-4
@@ -24,7 +24,6 @@ import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
|
||||
import com.intellij.platform.ProjectTemplate;
|
||||
import com.intellij.platform.ProjectTemplatesFactory;
|
||||
import com.intellij.platform.templates.ArchivedTemplatesFactory;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -41,11 +40,10 @@ public class CreateFromTemplateMode extends WizardMode {
|
||||
|
||||
private SelectTemplateStep mySelectTemplateStep;
|
||||
|
||||
public static MultiMap<TemplatesGroup, ProjectTemplate> getTemplatesMap(WizardContext context, boolean includeArchived) {
|
||||
public static MultiMap<TemplatesGroup, ProjectTemplate> getTemplatesMap(WizardContext context) {
|
||||
ProjectTemplatesFactory[] factories = ProjectTemplatesFactory.EP_NAME.getExtensions();
|
||||
final MultiMap<TemplatesGroup, ProjectTemplate> groups = new MultiMap<TemplatesGroup, ProjectTemplate>();
|
||||
for (ProjectTemplatesFactory factory : factories) {
|
||||
if (!includeArchived && (factory instanceof ArchivedTemplatesFactory)) continue;
|
||||
for (String group : factory.getGroups()) {
|
||||
ProjectTemplate[] templates = factory.createTemplates(group, context);
|
||||
List<ProjectTemplate> values = Arrays.asList(templates);
|
||||
@@ -79,7 +77,7 @@ public class CreateFromTemplateMode extends WizardMode {
|
||||
@Nullable
|
||||
@Override
|
||||
protected StepSequence createSteps(@NotNull WizardContext context, @NotNull ModulesProvider modulesProvider) {
|
||||
MultiMap<TemplatesGroup, ProjectTemplate> map = getTemplatesMap(context, true);
|
||||
MultiMap<TemplatesGroup, ProjectTemplate> map = getTemplatesMap(context);
|
||||
StepSequence sequence = new StepSequence();
|
||||
for (ProjectTemplate template : map.values()) {
|
||||
sequence.addStepsForBuilder(template.createModuleBuilder(), context, modulesProvider);
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
package com.intellij.platform.templates;
|
||||
|
||||
import com.intellij.ide.fileTemplates.impl.UrlUtil;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.PluginManagerCore;
|
||||
import com.intellij.ide.util.projectWizard.WizardContext;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -48,22 +46,21 @@ public class ArchivedTemplatesFactory extends ProjectTemplatesFactory {
|
||||
@Override
|
||||
protected MultiMap<String, Pair<URL, ClassLoader>> compute() {
|
||||
MultiMap<String, Pair<URL, ClassLoader>> map = new MultiMap<String, Pair<URL, ClassLoader>>();
|
||||
IdeaPluginDescriptor[] plugins = PluginManagerCore.getPlugins();
|
||||
Map<URL, ClassLoader> urls = new HashMap<URL, ClassLoader>();
|
||||
for (IdeaPluginDescriptor plugin : plugins) {
|
||||
if (!plugin.isEnabled()) continue;
|
||||
try {
|
||||
ClassLoader loader = plugin.getPluginClassLoader();
|
||||
Enumeration<URL> resources = loader.getResources("resources/projectTemplates");
|
||||
ArrayList<URL> list = Collections.list(resources);
|
||||
for (URL url : list) {
|
||||
urls.put(url, loader);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
//for (IdeaPluginDescriptor plugin : plugins) {
|
||||
// if (!plugin.isEnabled()) continue;
|
||||
// try {
|
||||
// ClassLoader loader = plugin.getPluginClassLoader();
|
||||
// Enumeration<URL> resources = loader.getResources("resources/projectTemplates");
|
||||
// ArrayList<URL> list = Collections.list(resources);
|
||||
// for (URL url : list) {
|
||||
// urls.put(url, loader);
|
||||
// }
|
||||
// }
|
||||
// catch (IOException e) {
|
||||
// LOG.error(e);
|
||||
// }
|
||||
//}
|
||||
|
||||
URL configURL = getCustomTemplatesURL();
|
||||
if (configURL != null) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -544,27 +544,35 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM
|
||||
final XmlTag rootTag = document.getRootTag();
|
||||
final String externalName = getExternalName(listOwner, false);
|
||||
if (rootTag != null) {
|
||||
XmlTag anchor = null;
|
||||
for (XmlTag item : rootTag.getSubTags()) {
|
||||
if (Comparing.strEqual(StringUtil.unescapeXml(item.getAttributeValue("name")), externalName)) {
|
||||
int compare = Comparing.compare(externalName, StringUtil.unescapeXml(item.getAttributeValue("name")));
|
||||
if (compare == 0) {
|
||||
anchor = null;
|
||||
for (XmlTag annotation : item.getSubTags()) {
|
||||
if (Comparing.strEqual(annotation.getAttributeValue("name"), annotationFQName)) {
|
||||
compare = Comparing.compare(annotationFQName, annotation.getAttributeValue("name"));
|
||||
if (compare == 0) {
|
||||
annotation.delete();
|
||||
break;
|
||||
}
|
||||
if (compare < 0) break;
|
||||
anchor = annotation;
|
||||
}
|
||||
XmlTag newTag = XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(
|
||||
createAnnotationTag(annotationFQName, values));
|
||||
item.add(newTag);
|
||||
item.addAfter(newTag, anchor);
|
||||
commitChanges(xmlFile);
|
||||
notifyAfterAnnotationChanging(listOwner, annotationFQName, true);
|
||||
return;
|
||||
}
|
||||
if (compare < 0) break;
|
||||
anchor = item;
|
||||
}
|
||||
@NonNls String text =
|
||||
"<item name=\'" + StringUtil.escapeXml(externalName) + "\'>\n";
|
||||
text += createAnnotationTag(annotationFQName, values);
|
||||
text += "</item>";
|
||||
rootTag.add(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(text));
|
||||
rootTag.addAfter(XmlElementFactory.getInstance(myPsiManager.getProject()).createTagFromText(text), anchor);
|
||||
}
|
||||
}
|
||||
commitChanges(xmlFile);
|
||||
@@ -604,7 +612,8 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(itemTags, new Comparator<XmlTag>() {
|
||||
List<XmlTag> sorted = new ArrayList<XmlTag>(itemTags);
|
||||
Collections.sort(sorted, new Comparator<XmlTag>() {
|
||||
@Override
|
||||
public int compare(XmlTag item1, XmlTag item2) {
|
||||
String externalName1 = item1.getAttributeValue("name");
|
||||
@@ -613,9 +622,11 @@ public class ExternalAnnotationsManagerImpl extends ReadableExternalAnnotationsM
|
||||
return externalName1.compareTo(externalName2);
|
||||
}
|
||||
});
|
||||
for (XmlTag item : itemTags) {
|
||||
rootTag.addAfter(item, null);
|
||||
item.delete();
|
||||
if (!sorted.equals(itemTags)) {
|
||||
for (XmlTag item : sorted) {
|
||||
rootTag.addAfter(item, null);
|
||||
item.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,8 @@ public class MethodGroupingRule implements UsageGroupingRule {
|
||||
|
||||
@Override
|
||||
public FileStatus getFileStatus() {
|
||||
return isValid() ? NavigationItemFileStatus.get(getMethod()) : null;
|
||||
PsiFile file = myMethodPointer.getContainingFile();
|
||||
return file == null ? null : NavigationItemFileStatus.get(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-6
@@ -1,8 +1,8 @@
|
||||
<root>
|
||||
<item name='p.TestDeannotation java.lang.String get()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='p.TestDeannotation1 java.lang.String get(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='p.TestDeannotation java.lang.String get()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='p.TestDeannotation1 java.lang.String get(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
</root>
|
||||
+8
-8
@@ -1,10 +1,10 @@
|
||||
<root>
|
||||
<item name='suppressed.ExistingExternalName java.lang.String foo()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='suppressed.SecondSuppression void second()'>
|
||||
<annotation name='java.lang.SuppressWarnings'>
|
||||
<val val="{DoesntMatterWhat}"/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='suppressed.ExistingExternalName java.lang.String foo()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='suppressed.SecondSuppression void second()'>
|
||||
<annotation name='java.lang.SuppressWarnings'>
|
||||
<val val="{DoesntMatterWhat}"/>
|
||||
</annotation>
|
||||
</item>
|
||||
</root>
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
<root>
|
||||
<item name='multiRoot.Test java.lang.String get(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'>
|
||||
<val name="value" val=""foo""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='multiRoot.Test java.lang.String get(java.lang.String) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'>
|
||||
<val name="value" val=""foo""/>
|
||||
</annotation>
|
||||
</item>
|
||||
</root>
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
<root>
|
||||
<item name='multiRoot.Test java.lang.String get(java.lang.String)'>
|
||||
<annotation name='org.jetbrains.annotations.Nullable'>
|
||||
<val name="value" val=""foo""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='multiRoot.Test java.lang.String get(java.lang.String)'>
|
||||
<annotation name='org.jetbrains.annotations.Nullable'>
|
||||
<val name="value" val=""foo""/>
|
||||
</annotation>
|
||||
</item>
|
||||
</root>
|
||||
+9
-9
@@ -22,13 +22,13 @@ public class NewPostfixTemplateTest extends PostfixTemplateTestCase {
|
||||
@Override
|
||||
protected String getSuffix() { return "new"; }
|
||||
|
||||
public void testNew01() { doTest(); }
|
||||
public void testNew02() { doTest(); }
|
||||
public void testNew03() { doTest(); }
|
||||
public void testNew04() { doTest(); }
|
||||
public void testNew05() { doTest(); }
|
||||
public void testNew06() { doTest(); }
|
||||
public void testNew07() { doTest(); }
|
||||
public void testNew08() { doTest(); }
|
||||
public void testNewOnAssignExpression() { doTest(); }
|
||||
public void _testNew01() { doTest(); }
|
||||
public void _testNew02() { doTest(); }
|
||||
public void _testNew03() { doTest(); }
|
||||
public void _testNew04() { doTest(); }
|
||||
public void _testNew05() { doTest(); }
|
||||
public void _testNew06() { doTest(); }
|
||||
public void _testNew07() { doTest(); }
|
||||
public void _testNew08() { doTest(); }
|
||||
public void _testNewOnAssignExpression() { doTest(); }
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
<item name="javax.swing.tree.TreePath TreePath(javax.swing.tree.TreePath, java.lang.Object) 1">
|
||||
<annotation name="org.jetbrains.annotations.NotNull" />
|
||||
</item>
|
||||
<item name='javax.swing.tree.TreePath java.lang.Object[] getPath()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name="javax.swing.tree.TreePath javax.swing.tree.TreePath pathByAddingChild(java.lang.Object) 0">
|
||||
<annotation name="org.jetbrains.annotations.NotNull" />
|
||||
</item>
|
||||
|
||||
@@ -109,7 +109,7 @@ public abstract class ProjectWizardTestCase<T extends AbstractProjectWizard> ext
|
||||
}
|
||||
|
||||
protected Project createProject(Consumer<Step> adjuster) throws IOException {
|
||||
createWizard(getProject());
|
||||
createWizard(null);
|
||||
runWizard(adjuster);
|
||||
myCreatedProject = NewProjectUtil.createFromWizard(myWizard, null);
|
||||
return myCreatedProject;
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
#include "com_intellij_ui_LibNotifyWrapper.h"
|
||||
|
||||
// to build 32bit version use
|
||||
// gcc -I/usr/include/gdk-pixbuf-2.0 -I/usr/lib/i386-linux-gnu/glib-2.0/include/ -I/usr/include/glib-2.0/ -I/jdk/jdk1.6.0_45/include -I/jdk/jdk1.6.0_45/include/linux -fPIC -shared -o libnotifywrapper.so LibNotifyWrapper.c -L/usr/lib/i386-linux-gnu/ -m32
|
||||
// do not forget something like "sudo apt-get install libnotify-dev:i386"
|
||||
|
||||
// to build 64 bit version use
|
||||
// gcc `pkg-config --cflags --libs libnotify` -I/jdk/jdk1.6.0_45/include -I/jdk/jdk1.6.0_45/include/linux -fPIC -shared -o libnotifywrapper64.so LibNotifyWrapper.c -lnotify
|
||||
#include <dlfcn.h>
|
||||
|
||||
/*
|
||||
* Class: com_intellij_ui_LibNotifyWrapper
|
||||
@@ -13,14 +7,46 @@
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_intellij_ui_LibNotifyWrapper_showNotification
|
||||
(JNIEnv * jEnv, jclass c, jstring jTitle, jstring jDescription) {
|
||||
(JNIEnv * jEnv, jclass c, jstring jTitle, jstring jDescription, jstring jLogoPath) {
|
||||
|
||||
void *handle;
|
||||
gboolean (*notify_init_func)(const char *app_name);
|
||||
void (*notify_uninit_func)();
|
||||
NotifyNotification* (*notify_notification_new_func) (const char *summary,
|
||||
const char *body,
|
||||
const char *icon);
|
||||
gboolean (*notify_notification_show_func) (NotifyNotification *notification,
|
||||
GError **error);
|
||||
char *error;
|
||||
|
||||
dlerror();
|
||||
|
||||
handle = dlopen("libnotify.so", RTLD_LAZY);
|
||||
|
||||
if ((error = dlerror()) != NULL)
|
||||
{
|
||||
(*jEnv)->ThrowNew(jEnv, (*jEnv)->FindClass(jEnv, "java/lang/UnsatisfiedLinkError"), error);
|
||||
return;
|
||||
}
|
||||
|
||||
dlerror();
|
||||
|
||||
*(void **) (¬ify_init_func) = dlsym(handle, "notify_init");
|
||||
*(void **) (¬ify_uninit_func) = dlsym(handle, "notify_init");
|
||||
*(void **) (¬ify_notification_new_func) = dlsym(handle, "notify_notification_new");
|
||||
*(void **) (¬ify_notification_show_func) = dlsym(handle, "notify_notification_show");
|
||||
|
||||
(*notify_init_func) ("JetBrains");
|
||||
|
||||
const char *title = (*jEnv)->GetStringUTFChars(jEnv, jTitle, 0);
|
||||
const char *description = (*jEnv)->GetStringUTFChars(jEnv, jDescription, 0);
|
||||
NotifyNotification * notification = notify_notification_new (title, description, "idea.png");
|
||||
notify_init ("JetBrains");
|
||||
notify_notification_show (notification, NULL);
|
||||
notify_uninit();
|
||||
const char *logoPath = (*jEnv)->GetStringUTFChars(jEnv, jLogoPath, 0);
|
||||
NotifyNotification * notification = (*notify_notification_new_func) (title, description, logoPath);
|
||||
(*notify_notification_show_func) (notification, NULL);
|
||||
(*notify_uninit_func)();
|
||||
(*jEnv)->ReleaseStringUTFChars(jEnv, jTitle, title);
|
||||
(*jEnv)->ReleaseStringUTFChars(jEnv, jDescription, description);
|
||||
}
|
||||
(*jEnv)->ReleaseStringUTFChars(jEnv, jLogoPath, logoPath);
|
||||
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ extern "C" {
|
||||
/*
|
||||
* Class: com_intellij_ui_LibNotifyWrapper
|
||||
* Method: showNotification
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/String;)V
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_intellij_ui_LibNotifyWrapper_showNotification
|
||||
(JNIEnv *, jclass, jstring, jstring);
|
||||
(JNIEnv *, jclass, jstring, jstring, jstring);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -1,8 +1,24 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.ide.presentation;
|
||||
|
||||
import com.intellij.ide.TypePresentationService;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -10,7 +26,7 @@ import javax.swing.*;
|
||||
* @author yole
|
||||
*/
|
||||
public class VirtualFilePresentation {
|
||||
public static Icon getIcon(VirtualFile vFile) {
|
||||
public static Icon getIcon(@NotNull VirtualFile vFile) {
|
||||
Icon icon = TypePresentationService.getService().getIcon(vFile);
|
||||
if (icon != null) {
|
||||
return icon;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -80,4 +80,9 @@ public class CompositeFoldingBuilder extends FoldingBuilderEx implements DumbAwa
|
||||
final FoldingBuilder builder = node.getUserData(FOLDING_BUILDER);
|
||||
return builder != null && builder.isCollapsedByDefault(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + myBuilders;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
* @see com.intellij.psi.LanguageSubstitutors
|
||||
*/
|
||||
public abstract class LanguageSubstitutor {
|
||||
|
||||
|
||||
@@ -121,44 +121,46 @@ public class IconUtil {
|
||||
return new ImageIcon(second);
|
||||
}
|
||||
|
||||
private static final NullableFunction<FileIconKey, Icon> ICON_NULLABLE_FUNCTION = new NullableFunction<FileIconKey, Icon>() {
|
||||
@Override
|
||||
public Icon fun(final FileIconKey key) {
|
||||
final VirtualFile file = key.getFile();
|
||||
final int flags = key.getFlags();
|
||||
final Project project = key.getProject();
|
||||
|
||||
if (!file.isValid() || project != null && (project.isDisposed() || !wasEverInitialized(project))) return null;
|
||||
|
||||
final Icon providersIcon = getProvidersIcon(file, flags, project);
|
||||
Icon icon = providersIcon == null ? VirtualFilePresentation.getIcon(file) : providersIcon;
|
||||
|
||||
final boolean dumb = project != null && DumbService.getInstance(project).isDumb();
|
||||
for (FileIconPatcher patcher : getPatchers()) {
|
||||
if (dumb && !DumbService.isDumbAware(patcher)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
icon = patcher.patchIcon(icon, file, flags, project);
|
||||
}
|
||||
|
||||
if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 &&
|
||||
(!file.isWritable() || !WritingAccessProvider.isPotentiallyWritable(file, project))) {
|
||||
icon = new LayeredIcon(icon, PlatformIcons.LOCKED_ICON);
|
||||
}
|
||||
if (file.is(VFileProperty.SYMLINK)) {
|
||||
icon = new LayeredIcon(icon, PlatformIcons.SYMLINK_ICON);
|
||||
}
|
||||
|
||||
Iconable.LastComputedIcon.put(file, icon, flags);
|
||||
|
||||
return icon;
|
||||
}
|
||||
};
|
||||
|
||||
public static Icon getIcon(@NotNull final VirtualFile file, @Iconable.IconFlags final int flags, @Nullable final Project project) {
|
||||
Icon lastIcon = Iconable.LastComputedIcon.get(file, flags);
|
||||
|
||||
final Icon base = lastIcon != null ? lastIcon : VirtualFilePresentation.getIcon(file);
|
||||
return IconDeferrer.getInstance().defer(base, new FileIconKey(file, project, flags), new NullableFunction<FileIconKey, Icon>() {
|
||||
@Override
|
||||
public Icon fun(final FileIconKey key) {
|
||||
final VirtualFile file = key.getFile();
|
||||
final int flags = key.getFlags();
|
||||
final Project project = key.getProject();
|
||||
|
||||
if (!file.isValid() || project != null && (project.isDisposed() || !wasEverInitialized(project))) return null;
|
||||
|
||||
final Icon providersIcon = getProvidersIcon(file, flags, project);
|
||||
Icon icon = providersIcon == null ? VirtualFilePresentation.getIcon(file) : providersIcon;
|
||||
|
||||
final boolean dumb = project != null && DumbService.getInstance(project).isDumb();
|
||||
for (FileIconPatcher patcher : getPatchers()) {
|
||||
if (dumb && !DumbService.isDumbAware(patcher)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
icon = patcher.patchIcon(icon, file, flags, project);
|
||||
}
|
||||
|
||||
if ((flags & Iconable.ICON_FLAG_READ_STATUS) != 0 &&
|
||||
(!file.isWritable() || !WritingAccessProvider.isPotentiallyWritable(file, project))) {
|
||||
icon = new LayeredIcon(icon, PlatformIcons.LOCKED_ICON);
|
||||
}
|
||||
if (file.is(VFileProperty.SYMLINK)) {
|
||||
icon = new LayeredIcon(icon, PlatformIcons.SYMLINK_ICON);
|
||||
}
|
||||
|
||||
Iconable.LastComputedIcon.put(file, icon, flags);
|
||||
|
||||
return icon;
|
||||
}
|
||||
});
|
||||
return IconDeferrer.getInstance().defer(base, new FileIconKey(file, project, flags), ICON_NULLABLE_FUNCTION);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -218,11 +218,19 @@ public abstract class AbstractIndentParser implements PsiParser {
|
||||
errorMarker.error(message);
|
||||
}
|
||||
|
||||
protected void errorUntilEol(String message) {
|
||||
protected void errorUntilEol(@NotNull String message) {
|
||||
PsiBuilder.Marker errorMarker = mark();
|
||||
advanceUntilEol();
|
||||
errorMarker.error(message);
|
||||
}
|
||||
|
||||
protected void errorUntilEof(@NotNull String message) {
|
||||
PsiBuilder.Marker errorMarker = mark();
|
||||
while (!eof()) {
|
||||
advance();
|
||||
}
|
||||
errorMarker.error(message);
|
||||
}
|
||||
|
||||
protected void expectEolOrEof() {
|
||||
if (!isNewLine() && !eof()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.vcs.FileStatusManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -43,11 +44,11 @@ public class NavigationItemFileStatus {
|
||||
return FileStatus.NOT_CHANGED;
|
||||
}
|
||||
|
||||
private static FileStatus getPsiElementFileStatus(PsiElement psiElement) {
|
||||
private static FileStatus getPsiElementFileStatus(@NotNull PsiElement psiElement) {
|
||||
if (!psiElement.isPhysical()) return FileStatus.NOT_CHANGED;
|
||||
PsiFile contFile = psiElement.getContainingFile();
|
||||
if (contFile == null) return FileStatus.NOT_CHANGED;
|
||||
VirtualFile vFile = contFile.getVirtualFile();
|
||||
return vFile != null ? FileStatusManager.getInstance(psiElement.getProject()).getStatus(vFile) : FileStatus.NOT_CHANGED;
|
||||
return vFile == null ? FileStatus.NOT_CHANGED : FileStatusManager.getInstance(psiElement.getProject()).getStatus(vFile);
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -217,6 +217,7 @@ public class ManageCodeStyleSchemesDialog extends DialogWrapper {
|
||||
VirtualFile[] selection = fileChooser.choose(CodeStyleSchemesUIConfiguration.Util.getRecentImportFile(), null);
|
||||
if (selection.length == 1) {
|
||||
VirtualFile selectedFile = selection[0];
|
||||
selectedFile.refresh(false, false);
|
||||
CodeStyleSchemesUIConfiguration.Util.setRecentImportFile(selectedFile);
|
||||
try {
|
||||
InputStream nameInputStream = selectedFile.getInputStream();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.intellij.codeInsight.folding.impl;
|
||||
|
||||
import com.intellij.diagnostic.AttachmentFactory;
|
||||
import com.intellij.injected.editor.DocumentWindow;
|
||||
import com.intellij.injected.editor.EditorWindow;
|
||||
import com.intellij.lang.Language;
|
||||
@@ -23,6 +24,7 @@ import com.intellij.lang.folding.FoldingBuilder;
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.lang.folding.LanguageFolding;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Attachment;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -34,6 +36,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
@@ -206,7 +209,9 @@ public class FoldingUpdate {
|
||||
" made by " + foldingBuilder +
|
||||
" for " +language +
|
||||
" and called on file " + psi +
|
||||
" is outside document range: " + docRange);
|
||||
" is outside document range: " + docRange,
|
||||
AttachmentFactory.createAttachment(document),
|
||||
new Attachment("psiTree.txt", DebugUtil.psiToString(psi, false, true)));
|
||||
}
|
||||
elementsToFoldMap.putValue(descriptor.getElement().getPsi(), descriptor);
|
||||
}
|
||||
|
||||
@@ -547,9 +547,17 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
|
||||
int startOffset = cur.getStartOffset();
|
||||
int endOffset = cur.getEndOffset();
|
||||
|
||||
Point startPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(startOffset));
|
||||
Point endPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(endOffset));
|
||||
Point point = new Point((startPoint.x + endPoint.x)/2, startPoint.y);
|
||||
if (startOffset >= myEditor.getDocument().getTextLength()) {
|
||||
if (!object.isDisposed()) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
object.hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (!SearchResults.insideVisibleArea(myEditor, cur)) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
@@ -575,6 +583,11 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
|
||||
myVisibleAreaListenersToRemove.add(visibleAreaListener);
|
||||
|
||||
}
|
||||
|
||||
Point startPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(startOffset));
|
||||
Point endPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(endOffset));
|
||||
Point point = new Point((startPoint.x + endPoint.x)/2, startPoint.y);
|
||||
|
||||
return new RelativePoint(myEditor.getContentComponent(), point);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.ide;
|
||||
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.EditorNotificationPanel;
|
||||
import com.intellij.ui.EditorNotifications;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class GeneratedFileEditingNotificationProvider extends EditorNotifications.Provider<EditorNotificationPanel> {
|
||||
private static final Key<EditorNotificationPanel> KEY = Key.create("generated.source.file.editing.notification.panel");
|
||||
private final GeneratedSourceFileChangeTracker myChangeTracker;
|
||||
|
||||
public GeneratedFileEditingNotificationProvider(GeneratedSourceFileChangeTracker changeTracker) {
|
||||
myChangeTracker = changeTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Key<EditorNotificationPanel> getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
|
||||
if (!myChangeTracker.isEditedGeneratedFile(file)) return null;
|
||||
|
||||
EditorNotificationPanel panel = new EditorNotificationPanel();
|
||||
panel.setText("Generated source files should not be edited. The changes will be lost when sources are regenerated.");
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.ide;
|
||||
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class GeneratedSourceFileChangeTracker extends AbstractProjectComponent {
|
||||
@NotNull
|
||||
public static GeneratedSourceFileChangeTracker getInstance(@NotNull Project project) {
|
||||
return project.getComponent(GeneratedSourceFileChangeTracker.class);
|
||||
}
|
||||
|
||||
protected GeneratedSourceFileChangeTracker(Project project) {
|
||||
super(project);
|
||||
}
|
||||
|
||||
public abstract boolean isEditedGeneratedFile(@NotNull VirtualFile file);
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.ide;
|
||||
|
||||
import com.intellij.AppTopics;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.fileEditor.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.GeneratedSourcesFilter;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.EditorNotifications;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.messages.MessageBusConnection;
|
||||
import com.intellij.util.ui.update.MergingUpdateQueue;
|
||||
import com.intellij.util.ui.update.Update;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class GeneratedSourceFileChangeTrackerImpl extends GeneratedSourceFileChangeTracker {
|
||||
private final FileDocumentManager myDocumentManager;
|
||||
private final EditorNotifications myEditorNotifications;
|
||||
private final MergingUpdateQueue myCheckingQueue;
|
||||
private final Set<VirtualFile> myFilesToCheck = Collections.synchronizedSet(new HashSet<VirtualFile>());
|
||||
private final Set<VirtualFile> myEditedGeneratedFiles = Collections.synchronizedSet(new HashSet<VirtualFile>());
|
||||
|
||||
public GeneratedSourceFileChangeTrackerImpl(Project project, FileDocumentManager documentManager, EditorNotifications editorNotifications) {
|
||||
super(project);
|
||||
myDocumentManager = documentManager;
|
||||
myEditorNotifications = editorNotifications;
|
||||
myCheckingQueue = new MergingUpdateQueue("Checking for changes in generated sources", 500, false, null, project, null, Alarm.ThreadToUse.SHARED_THREAD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditedGeneratedFile(@NotNull VirtualFile file) {
|
||||
return myEditedGeneratedFiles.contains(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectOpened() {
|
||||
final Update check = new Update("check for changes in generated files") {
|
||||
@Override
|
||||
public void run() {
|
||||
checkFiles();
|
||||
}
|
||||
};
|
||||
EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
VirtualFile file = myDocumentManager.getFile(e.getDocument());
|
||||
if (file != null) {
|
||||
myFilesToCheck.add(file);
|
||||
myCheckingQueue.queue(check);
|
||||
}
|
||||
}
|
||||
}, myProject);
|
||||
MessageBusConnection connection = myProject.getMessageBus().connect();
|
||||
connection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() {
|
||||
@Override
|
||||
public void fileContentReloaded(VirtualFile file, @NotNull Document document) {
|
||||
myFilesToCheck.remove(file);
|
||||
if (myEditedGeneratedFiles.remove(file)) {
|
||||
myEditorNotifications.updateNotifications(file);
|
||||
}
|
||||
}
|
||||
});
|
||||
connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerAdapter() {
|
||||
@Override
|
||||
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
|
||||
myEditedGeneratedFiles.remove(file);
|
||||
}
|
||||
});
|
||||
myCheckingQueue.activate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectClosed() {
|
||||
myCheckingQueue.deactivate();
|
||||
}
|
||||
|
||||
private void checkFiles() {
|
||||
final VirtualFile[] files;
|
||||
synchronized (myFilesToCheck) {
|
||||
files = myFilesToCheck.toArray(new VirtualFile[myFilesToCheck.size()]);
|
||||
myFilesToCheck.clear();
|
||||
}
|
||||
final List<VirtualFile> newEditedGeneratedFiles = new ArrayList<VirtualFile>();
|
||||
new ReadAction() {
|
||||
protected void run(final @NotNull Result result) {
|
||||
if (myProject.isDisposed()) return;
|
||||
for (VirtualFile file : files) {
|
||||
if (isGenerated(file)) {
|
||||
newEditedGeneratedFiles.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
|
||||
if (!newEditedGeneratedFiles.isEmpty()) {
|
||||
List<VirtualFile> toNotify = new ArrayList<VirtualFile>();
|
||||
synchronized (myEditedGeneratedFiles) {
|
||||
for (VirtualFile file : newEditedGeneratedFiles) {
|
||||
if (myEditedGeneratedFiles.add(file)) {
|
||||
toNotify.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (VirtualFile file : toNotify) {
|
||||
myEditorNotifications.updateNotifications(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGenerated(VirtualFile file) {
|
||||
for (GeneratedSourcesFilter filter : GeneratedSourcesFilter.EP_NAME.getExtensions()) {
|
||||
if (filter.isGeneratedSource(file, myProject)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -511,7 +511,7 @@ public class EditorWindow extends UserDataHolderBase implements EditorEx {
|
||||
|
||||
@Override
|
||||
public boolean isDisposed() {
|
||||
return !myDisposed && myDelegate.isDisposed();
|
||||
return myDisposed || myDelegate.isDisposed();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -22,6 +22,7 @@ import com.intellij.concurrency.Job;
|
||||
import com.intellij.concurrency.JobLauncher;
|
||||
import com.intellij.injected.editor.DocumentWindow;
|
||||
import com.intellij.injected.editor.DocumentWindowImpl;
|
||||
import com.intellij.injected.editor.EditorWindow;
|
||||
import com.intellij.injected.editor.VirtualFileWindow;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
@@ -41,7 +42,6 @@ import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ProperTextRange;
|
||||
import com.intellij.openapi.util.Segment;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -67,7 +67,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class InjectedLanguageManagerImpl extends InjectedLanguageManager implements Disposable{
|
||||
public class InjectedLanguageManagerImpl extends InjectedLanguageManager implements Disposable {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.injected.InjectedLanguageManagerImpl");
|
||||
private final Project myProject;
|
||||
private final DumbService myDumbService;
|
||||
@@ -118,6 +118,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
EditorWindow.disposeInvalidEditors();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -236,7 +237,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
|
||||
@Override
|
||||
@NotNull
|
||||
public TextRange injectedToHost(@NotNull PsiElement injectedContext, @NotNull TextRange injectedTextRange) {
|
||||
ProperTextRange.assertProperRange(injectedTextRange);
|
||||
TextRange.assertProperRange(injectedTextRange);
|
||||
PsiFile file = injectedContext.getContainingFile();
|
||||
if (file == null) return injectedTextRange;
|
||||
Document document = PsiDocumentManager.getInstance(file.getProject()).getCachedDocument(file);
|
||||
@@ -488,7 +489,7 @@ public class InjectedLanguageManagerImpl extends InjectedLanguageManager impleme
|
||||
InjectedLanguagePlaces placesRegistrar = new InjectedLanguagePlaces() {
|
||||
@Override
|
||||
public void addPlace(@NotNull Language language, @NotNull TextRange rangeInsideHost, @NonNls @Nullable String prefix, @NonNls @Nullable String suffix) {
|
||||
ProperTextRange.assertProperRange(rangeInsideHost);
|
||||
TextRange.assertProperRange(rangeInsideHost);
|
||||
injectionPlacesRegistrar
|
||||
.startInjecting(language)
|
||||
.addPlace(prefix, suffix, host, rangeInsideHost)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -22,6 +22,7 @@ package com.intellij.ui;
|
||||
import com.intellij.concurrency.Job;
|
||||
import com.intellij.concurrency.JobLauncher;
|
||||
import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.project.IndexNotReadyException;
|
||||
@@ -45,6 +46,7 @@ import java.util.Set;
|
||||
|
||||
public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
private static final RepaintScheduler ourRepaintScheduler = new RepaintScheduler();
|
||||
@NotNull
|
||||
private volatile Icon myDelegateIcon;
|
||||
private Function<T, Icon> myEvaluator;
|
||||
private volatile boolean myIsScheduled = false;
|
||||
@@ -53,7 +55,7 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
private final boolean myNeedReadAction;
|
||||
private boolean myDone;
|
||||
|
||||
private IconListener<T> myEvalListener;
|
||||
private final IconListener<T> myEvalListener;
|
||||
private static final TransferToEDTQueue<Runnable> ourLaterInvocator = new TransferToEDTQueue<Runnable>("Deferred icon later invocator", new Processor<Runnable>() {
|
||||
@Override
|
||||
public boolean process(Runnable runnable) {
|
||||
@@ -62,17 +64,22 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
}
|
||||
}, Condition.FALSE, 200);
|
||||
|
||||
public DeferredIconImpl(Icon baseIcon, T param, @NotNull Function<T, Icon> evaluator) {
|
||||
this(baseIcon, param, true, evaluator);
|
||||
DeferredIconImpl(Icon baseIcon, T param, @NotNull Function<T, Icon> evaluator, @NotNull IconListener<T> listener) {
|
||||
this(baseIcon, param, true, evaluator, listener);
|
||||
}
|
||||
|
||||
public DeferredIconImpl(Icon baseIcon, T param, final boolean needReadAction, @NotNull Function<T, Icon> evaluator) {
|
||||
this(baseIcon, param, needReadAction, evaluator, null);
|
||||
}
|
||||
private DeferredIconImpl(Icon baseIcon, T param, final boolean needReadAction, @NotNull Function<T, Icon> evaluator, IconListener<T> listener) {
|
||||
myParam = param;
|
||||
myDelegateIcon = nonNull(baseIcon);
|
||||
myEvaluator = evaluator;
|
||||
myNeedReadAction = needReadAction;
|
||||
myEvalListener = listener;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Icon nonNull(final Icon icon) {
|
||||
return icon == null ? EMPTY_ICON : icon;
|
||||
}
|
||||
@@ -271,18 +278,20 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
private final Alarm myAlarm = new Alarm();
|
||||
private final Set<RepaintRequest> myQueue = new LinkedHashSet<RepaintRequest>();
|
||||
|
||||
public void pushDirtyComponent(final Component c, final Rectangle rec) {
|
||||
public void pushDirtyComponent(@NotNull Component c, final Rectangle rec) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread(); // assert myQueue accessed from EDT only
|
||||
myAlarm.cancelAllRequests();
|
||||
myAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (RepaintRequest each : myQueue) {
|
||||
Rectangle r = each.getRectangle();
|
||||
if (r != null) {
|
||||
each.getComponent().repaint(r.x, r.y, r.width, r.height);
|
||||
} else {
|
||||
if (r == null) {
|
||||
each.getComponent().repaint();
|
||||
}
|
||||
else {
|
||||
each.getComponent().repaint(r.x, r.y, r.width, r.height);
|
||||
}
|
||||
}
|
||||
myQueue.clear();
|
||||
}
|
||||
@@ -296,11 +305,12 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
private final Component myComponent;
|
||||
private final Rectangle myRectangle;
|
||||
|
||||
private RepaintRequest(Component component, Rectangle rectangle) {
|
||||
private RepaintRequest(@NotNull Component component, Rectangle rectangle) {
|
||||
myComponent = component;
|
||||
myRectangle = rectangle;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Component getComponent() {
|
||||
return myComponent;
|
||||
}
|
||||
@@ -310,11 +320,6 @@ public class DeferredIconImpl<T> implements DeferredIcon {
|
||||
}
|
||||
}
|
||||
|
||||
public DeferredIconImpl setDoneListener(@NotNull IconListener<T> disposer) {
|
||||
myEvalListener = disposer;
|
||||
return this;
|
||||
}
|
||||
|
||||
public interface IconListener<T> {
|
||||
void evalDone(T key, @NotNull Icon result);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -41,7 +41,8 @@ public class IconDeferrerImpl extends IconDeferrer {
|
||||
}
|
||||
};
|
||||
private long myLastClearTimestamp = 0;
|
||||
@SuppressWarnings("UnusedDeclaration") private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clear();
|
||||
@@ -81,7 +82,7 @@ public class IconDeferrerImpl extends IconDeferrer {
|
||||
Icon result = myIconsCache.get(param);
|
||||
if (result == null) {
|
||||
final long started = myLastClearTimestamp;
|
||||
result = new DeferredIconImpl<T>(base, param, f).setDoneListener(new DeferredIconImpl.IconListener<T>() {
|
||||
result = new DeferredIconImpl<T>(base, param, f, new DeferredIconImpl.IconListener<T>() {
|
||||
@Override
|
||||
public void evalDone(T key, @NotNull Icon r) {
|
||||
synchronized (LOCK) {
|
||||
@@ -106,7 +107,7 @@ public class IconDeferrerImpl extends IconDeferrer {
|
||||
}
|
||||
};
|
||||
|
||||
public static void evaluateDeferred(@NotNull Runnable runnable) {
|
||||
static void evaluateDeferred(@NotNull Runnable runnable) {
|
||||
try {
|
||||
myEvaluationIsInProgress.set(Boolean.TRUE);
|
||||
runnable.run();
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.ide;
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.GeneratedSourcesFilter;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class GeneratedSourceFileChangeTrackerTest extends CodeInsightFixtureTestCase {
|
||||
private final GeneratedSourcesFilter myGeneratedSourcesFilter = new GeneratedSourcesFilter() {
|
||||
@Override
|
||||
public boolean isGeneratedSource(@NotNull VirtualFile file, @NotNull Project project) {
|
||||
return file.getName().startsWith("Gen");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Extensions.getRootArea().getExtensionPoint(GeneratedSourcesFilter.EP_NAME).registerExtension(myGeneratedSourcesFilter);
|
||||
getTracker().projectOpened();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
Extensions.getRootArea().getExtensionPoint(GeneratedSourcesFilter.EP_NAME).unregisterExtension(myGeneratedSourcesFilter);
|
||||
getTracker().projectClosed();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public void testChangeOrdinary() {
|
||||
PsiFile file = myFixture.configureByText("Ordinary.txt", "");
|
||||
myFixture.type('a');
|
||||
assertFalse(isEditedGeneratedFile(file));
|
||||
}
|
||||
|
||||
public void testChangeGenerated() {
|
||||
PsiFile file = myFixture.configureByText("Gen.txt", "");
|
||||
myFixture.type('a');
|
||||
assertTrue(isEditedGeneratedFile(file));
|
||||
}
|
||||
|
||||
public void testChangeGeneratedExternally() throws IOException {
|
||||
PsiFile file = myFixture.configureByText("Gen.txt", "");
|
||||
VfsUtil.saveText(file.getVirtualFile(), "abc");
|
||||
assertFalse(isEditedGeneratedFile(file));
|
||||
}
|
||||
|
||||
private boolean isEditedGeneratedFile(PsiFile file) {
|
||||
return getTracker().isEditedGeneratedFile(file.getVirtualFile());
|
||||
}
|
||||
|
||||
private GeneratedSourceFileChangeTracker getTracker() {
|
||||
return GeneratedSourceFileChangeTracker.getInstance(getProject());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -18,6 +18,7 @@ package com.intellij.openapi.vcs;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@@ -29,7 +30,7 @@ public abstract class FileStatusManager {
|
||||
return project.getComponent(FileStatusManager.class);
|
||||
}
|
||||
|
||||
public abstract FileStatus getStatus(VirtualFile virtualFile);
|
||||
public abstract FileStatus getStatus(@NotNull VirtualFile virtualFile);
|
||||
|
||||
public abstract void fileStatusesChanged();
|
||||
public abstract void fileStatusChanged(VirtualFile file);
|
||||
|
||||
@@ -45,15 +45,13 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
|
||||
|
||||
private boolean myOpaque = true;
|
||||
@Override
|
||||
public final Component getTreeCellRendererComponent(
|
||||
JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus
|
||||
){
|
||||
public final Component getTreeCellRendererComponent(JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus){
|
||||
myTree = tree;
|
||||
|
||||
clear();
|
||||
@@ -72,20 +70,18 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
|
||||
setBackground(hasFocus ? UIUtil.getTreeSelectionBackground() : UIUtil.getTreeUnfocusedSelectionBackground());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (selected) {
|
||||
setPaintFocusBorder(true);
|
||||
if (isFocused()) {
|
||||
setBackground(UIUtil.getTreeSelectionBackground());
|
||||
}
|
||||
else {
|
||||
setBackground(null);
|
||||
}
|
||||
else if (selected) {
|
||||
setPaintFocusBorder(true);
|
||||
if (isFocused()) {
|
||||
setBackground(UIUtil.getTreeSelectionBackground());
|
||||
}
|
||||
else {
|
||||
setBackground(null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setBackground(null);
|
||||
}
|
||||
|
||||
if (value instanceof LoadingNode) {
|
||||
setForeground(JBColor.GRAY);
|
||||
@@ -176,13 +172,11 @@ public abstract class ColoredTreeCellRenderer extends SimpleColoredComponent imp
|
||||
* This method is invoked only for customization of component.
|
||||
* All component attributes are cleared when this method is being invoked.
|
||||
*/
|
||||
public abstract void customizeCellRenderer(
|
||||
JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus
|
||||
);
|
||||
public abstract void customizeCellRenderer(@NotNull JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
|
||||
@@ -24,11 +25,12 @@ public class LoadingNode extends DefaultMutableTreeNode {
|
||||
this(getText());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getText() {
|
||||
return IdeBundle.message("treenode.loading");
|
||||
}
|
||||
|
||||
public LoadingNode(String text) {
|
||||
public LoadingNode(@NotNull String text) {
|
||||
super(text);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -41,16 +42,16 @@ public interface PaintingParent {
|
||||
* @return a rectangle, if null -- the whole component will be repainted
|
||||
*/
|
||||
@Nullable
|
||||
Rectangle getChildRec(Component c);
|
||||
Rectangle getChildRec(@NotNull Component c);
|
||||
|
||||
class Wrapper extends JPanel implements PaintingParent {
|
||||
public Wrapper(Component component) {
|
||||
public Wrapper(@NotNull Component component) {
|
||||
super(new BorderLayout(0,0));
|
||||
add(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rectangle getChildRec(Component c) {
|
||||
public Rectangle getChildRec(@NotNull Component c) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.diagnostic;
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.LogManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Allows to apply & persist custom log debug categories which can be turned on by user via the {@link com.intellij.ide.actions.DebugLogConfigureAction}. <br/>
|
||||
* Applies these custom categories on startup.
|
||||
*/
|
||||
public class DebugLogManager extends ApplicationComponent.Adapter {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(DebugLogManager.class);
|
||||
private static final String LOG_DEBUG_CATEGORIES = "log.debug.categories";
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
List<String> categories = getSavedCategories();
|
||||
if (categories.isEmpty()) {
|
||||
saveCategories(getCurrentCategories());
|
||||
}
|
||||
else {
|
||||
applyCategories(categories);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getSavedCategories() {
|
||||
String value = PropertiesComponent.getInstance().getValue(LOG_DEBUG_CATEGORIES);
|
||||
return value == null ? Collections.<String>emptyList() : fromString(value);
|
||||
}
|
||||
|
||||
public void applyCategories(@NotNull List<String> categories) {
|
||||
for (String category : categories) {
|
||||
org.apache.log4j.Logger logger = LogManager.getLogger(category);
|
||||
if (logger != null) {
|
||||
logger.setLevel(Level.DEBUG);
|
||||
}
|
||||
}
|
||||
LOG.info("Set DEBUG for the following categories: " + categories);
|
||||
}
|
||||
|
||||
public void saveCategories(@NotNull List<String> categories) {
|
||||
PropertiesComponent.getInstance().setValue(LOG_DEBUG_CATEGORIES, toString(categories));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> fromString(@NotNull String text) {
|
||||
return Arrays.asList(StringUtil.splitByLines(text, true));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String toString(@NotNull List<String> categories) {
|
||||
return StringUtil.join(categories, "\n");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> getCurrentCategories() {
|
||||
Enumeration currentLoggers = LogManager.getCurrentLoggers();
|
||||
return ContainerUtil.mapNotNull(ContainerUtil.toList(currentLoggers), new Function<Object, String>() {
|
||||
@Override
|
||||
public String fun(Object o) {
|
||||
if (o instanceof org.apache.log4j.Logger) {
|
||||
String category = ((org.apache.log4j.Logger)o).getName();
|
||||
if (Logger.getInstance(category).isDebugEnabled()) {
|
||||
return category;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.util.ExecUtil;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
@@ -50,8 +51,6 @@ import static java.util.Arrays.asList;
|
||||
public class CreateDesktopEntryAction extends DumbAwareAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.CreateDesktopEntryAction");
|
||||
|
||||
private static final int MIN_ICON_SIZE = 32;
|
||||
|
||||
public static boolean isAvailable() {
|
||||
return SystemInfo.isUnix && SystemInfo.hasXdgOpen();
|
||||
}
|
||||
@@ -138,7 +137,7 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
|
||||
String name = ApplicationNamesInfo.getInstance().getFullProductName();
|
||||
if (PlatformUtils.isCommunity()) name += " Community Edition";
|
||||
|
||||
final String iconPath = findIcon(binPath);
|
||||
final String iconPath = AllIcons.findIcon(binPath);
|
||||
if (iconPath == null) {
|
||||
throw new RuntimeException(ApplicationBundle.message("desktop.entry.icon.missing", binPath));
|
||||
}
|
||||
@@ -161,34 +160,6 @@ public class CreateDesktopEntryAction extends DumbAwareAction {
|
||||
return entryFile;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String findIcon(final String iconsPath) {
|
||||
final File iconsDir = new File(iconsPath);
|
||||
|
||||
// 1. look for .svg icon
|
||||
for (String child : iconsDir.list()) {
|
||||
if (child.endsWith(".svg")) {
|
||||
return iconsPath + '/' + child;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. look for .png icon of max size
|
||||
int max = 0;
|
||||
String iconPath = null;
|
||||
for (String child : iconsDir.list()) {
|
||||
if (!child.endsWith(".png")) continue;
|
||||
final String path = iconsPath + '/' + child;
|
||||
final Icon icon = new ImageIcon(path);
|
||||
final int size = icon.getIconHeight();
|
||||
if (size >= MIN_ICON_SIZE && size > max && size == icon.getIconWidth()) {
|
||||
max = size;
|
||||
iconPath = path;
|
||||
}
|
||||
}
|
||||
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String findScript(final String binPath) {
|
||||
final String productName = ApplicationNamesInfo.getInstance().getProductName();
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.ide.actions;
|
||||
|
||||
import com.intellij.diagnostic.DebugLogManager;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
public class DebugLogConfigureAction extends DumbAwareAction {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
Project project = e.getProject() == null ? ProjectManager.getInstance().getDefaultProject() : e.getProject();
|
||||
DebugLogManager logCustomizer = ServiceManager.getService(DebugLogManager.class);
|
||||
DebugLogConfigureDialog dialog = new DebugLogConfigureDialog(project, logCustomizer.getSavedCategories());
|
||||
if (dialog.showAndGet()) {
|
||||
List<String> categories = dialog.getLogCategories();
|
||||
logCustomizer.applyCategories(categories);
|
||||
logCustomizer.saveCategories(categories);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DebugLogConfigureDialog extends DialogWrapper {
|
||||
|
||||
private static final String ALL_POSSIBLE_SEPARATORS = "(\n|,|;)+";
|
||||
@NotNull private final JTextArea myTextArea;
|
||||
|
||||
protected DebugLogConfigureDialog(@Nullable Project project, List<String> categories) {
|
||||
super(project, false);
|
||||
myTextArea = new JTextArea(10, 30);
|
||||
myTextArea.setText(StringUtil.join(categories, "\n"));
|
||||
setTitle("Custom Debug Log Configuration");
|
||||
init();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent createNorthPanel() {
|
||||
return new JBLabel("Add log categories separated by new lines");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return ScrollPaneFactory.createScrollPane(myTextArea);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getLogCategories() {
|
||||
return parseCategories(myTextArea.getText());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> parseCategories(@NotNull String text) {
|
||||
return ContainerUtil.mapNotNull(text.split(ALL_POSSIBLE_SEPARATORS), new Function<String, String>() {
|
||||
@Override
|
||||
public String fun(String s) {
|
||||
return StringUtil.isEmptyOrSpaces(s) ? null : s.trim();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -440,6 +440,7 @@ public class ActionsTree {
|
||||
}
|
||||
|
||||
private class KeymapsRenderer extends ColoredTreeCellRenderer {
|
||||
// Make sure that the text rendered by this method is 'searchable' via com.intellij.openapi.keymap.impl.ui.ActionsTree.filter method.
|
||||
public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
|
||||
final boolean showIcons = UISettings.getInstance().SHOW_ICONS_IN_MENUS;
|
||||
Keymap originalKeymap = myKeymap != null ? myKeymap.getParent() : null;
|
||||
|
||||
+13
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -485,26 +485,18 @@ public class ActionsTreeUtil {
|
||||
if (filter == null) return true;
|
||||
if (action == null) return false;
|
||||
final String insensitiveFilter = filter.toLowerCase();
|
||||
final String text = action.getTemplatePresentation().getText();
|
||||
if (text != null) {
|
||||
final String lowerText = text.toLowerCase();
|
||||
if (SearchUtil
|
||||
.isComponentHighlighted(lowerText, insensitiveFilter, force, null)) {
|
||||
return true;
|
||||
}
|
||||
else if (lowerText.contains(insensitiveFilter)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final String description = action.getTemplatePresentation().getDescription();
|
||||
if (description != null) {
|
||||
final String insensitiveDescription = description.toLowerCase();
|
||||
if (SearchUtil
|
||||
.isComponentHighlighted(insensitiveDescription, insensitiveFilter, force, null)) {
|
||||
return true;
|
||||
}
|
||||
else if (insensitiveDescription.contains(insensitiveFilter)) {
|
||||
return true;
|
||||
for (String text : new String[]{action.getTemplatePresentation().getText(),
|
||||
action.getTemplatePresentation().getDescription(),
|
||||
action instanceof ActionStub ? ((ActionStub)action).getId() : ActionManager.getInstance().getId(action)}) {
|
||||
if (text != null) {
|
||||
final String lowerText = text.toLowerCase();
|
||||
|
||||
if (SearchUtil.isComponentHighlighted(lowerText, insensitiveFilter, force, null)) {
|
||||
return true;
|
||||
}
|
||||
else if (lowerText.contains(insensitiveFilter)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
+26
-9
@@ -99,6 +99,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC
|
||||
@Override
|
||||
public void run() {
|
||||
DocumentAdapter documentListener = new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent event) {
|
||||
VirtualFile file = FileDocumentManager.getInstance().getFile(event.getDocument());
|
||||
if (file != null) {
|
||||
@@ -114,6 +115,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC
|
||||
}
|
||||
});
|
||||
startupManager.registerPostStartupActivity(new DumbAwareRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fileStatusesChanged();
|
||||
}
|
||||
@@ -139,47 +141,58 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC
|
||||
return getDefaultStatus(virtualFile);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FileStatus getDefaultStatus(@NotNull final VirtualFile file) {
|
||||
return file.isValid() && file.is(VFileProperty.SPECIAL) ? FileStatus.IGNORED : FileStatus.NOT_CHANGED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectClosed() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void projectOpened() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeComponent() {
|
||||
myCachedStatuses.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "FileStatusManager";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFileStatusListener(@NotNull FileStatusListener listener) {
|
||||
myListeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFileStatusListener(final FileStatusListener listener, Disposable parentDisposable) {
|
||||
addFileStatusListener(listener);
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
removeFileStatusListener(listener);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileStatusesChanged() {
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
if (!ApplicationManager.getApplication().isDispatchThread()) {
|
||||
ApplicationManager.getApplication().invokeLater(new DumbAwareRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fileStatusesChanged();
|
||||
}
|
||||
@@ -195,26 +208,28 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC
|
||||
}
|
||||
}
|
||||
|
||||
private void cacheChangedFileStatus(final VirtualFile vf, final FileStatus fs) {
|
||||
myCachedStatuses.put(vf, fs);
|
||||
private void cacheChangedFileStatus(final VirtualFile virtualFile, final FileStatus fs) {
|
||||
myCachedStatuses.put(virtualFile, fs);
|
||||
if (FileStatus.NOT_CHANGED.equals(fs)) {
|
||||
final ThreeState parentingStatus = myFileStatusProvider.getNotChangedDirectoryParentingStatus(vf);
|
||||
final ThreeState parentingStatus = myFileStatusProvider.getNotChangedDirectoryParentingStatus(virtualFile);
|
||||
if (ThreeState.YES.equals(parentingStatus)) {
|
||||
myWhetherExactlyParentToChanged.put(vf, true);
|
||||
myWhetherExactlyParentToChanged.put(virtualFile, true);
|
||||
}
|
||||
else if (ThreeState.UNSURE.equals(parentingStatus)) {
|
||||
myWhetherExactlyParentToChanged.put(vf, false);
|
||||
myWhetherExactlyParentToChanged.put(virtualFile, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myWhetherExactlyParentToChanged.remove(vf);
|
||||
myWhetherExactlyParentToChanged.remove(virtualFile);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileStatusChanged(final VirtualFile file) {
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
if (!application.isDispatchThread() && !application.isUnitTestMode()) {
|
||||
ApplicationManager.getApplication().invokeLater(new DumbAwareRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
fileStatusChanged(file);
|
||||
}
|
||||
@@ -222,7 +237,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC
|
||||
return;
|
||||
}
|
||||
|
||||
if ((file == null) || (!file.isValid())) return;
|
||||
if (file == null || !file.isValid()) return;
|
||||
FileStatus cachedStatus = getCachedStatus(file);
|
||||
if (cachedStatus == FileStatusNull.INSTANCE) {
|
||||
return;
|
||||
@@ -240,7 +255,8 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC
|
||||
}
|
||||
}
|
||||
|
||||
public FileStatus getStatus(final VirtualFile file) {
|
||||
@Override
|
||||
public FileStatus getStatus(@NotNull final VirtualFile file) {
|
||||
if (file instanceof LightVirtualFile) {
|
||||
return FileStatus.NOT_CHANGED; // do not leak light files via cache
|
||||
}
|
||||
@@ -258,6 +274,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC
|
||||
return myCachedStatuses.get(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFileStatusListener(FileStatusListener listener) {
|
||||
myListeners.remove(listener);
|
||||
}
|
||||
@@ -271,7 +288,7 @@ public class FileStatusManagerImpl extends FileStatusManager implements ProjectC
|
||||
final Boolean exactMatch = myWhetherExactlyParentToChanged.get(vf);
|
||||
return exactMatch == null
|
||||
? notChangedColor
|
||||
: (exactMatch ? FileStatus.NOT_CHANGED_IMMEDIATE.getColor() : FileStatus.NOT_CHANGED_RECURSIVE.getColor());
|
||||
: exactMatch ? FileStatus.NOT_CHANGED_IMMEDIATE.getColor() : FileStatus.NOT_CHANGED_RECURSIVE.getColor();
|
||||
}
|
||||
|
||||
public void refreshFileStatusFromDocument(final VirtualFile file, final Document doc) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.vcs.FileStatus;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ThreeState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -28,8 +29,9 @@ public interface FileStatusProvider {
|
||||
|
||||
ExtensionPointName<FileStatusProvider> EP_NAME = ExtensionPointName.create("com.intellij.vcs.fileStatusProvider");
|
||||
|
||||
FileStatus getFileStatus(final VirtualFile virtualFile);
|
||||
void refreshFileStatusFromDocument(final VirtualFile file, final Document doc);
|
||||
FileStatus getFileStatus(@NotNull VirtualFile virtualFile);
|
||||
void refreshFileStatusFromDocument(@NotNull VirtualFile virtualFile, @NotNull Document doc);
|
||||
|
||||
ThreeState getNotChangedDirectoryParentingStatus(VirtualFile vf);
|
||||
@NotNull
|
||||
ThreeState getNotChangedDirectoryParentingStatus(@NotNull VirtualFile virtualFile);
|
||||
}
|
||||
@@ -15,6 +15,11 @@
|
||||
*/
|
||||
package com.intellij.ui;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationGroup;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.notification.Notifications;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.util.lang.UrlClassLoader;
|
||||
|
||||
@@ -23,9 +28,41 @@ import com.intellij.util.lang.UrlClassLoader;
|
||||
*/
|
||||
public class LibNotifyWrapper {
|
||||
|
||||
private final static String message = "Looks like you have run 32-bit Java on a 64-bit version of OS " +
|
||||
"or just have not installed appropriate libnotify.so library";
|
||||
|
||||
private static boolean available = true;
|
||||
|
||||
static{
|
||||
UrlClassLoader.loadPlatformLibrary("notifywrapper");
|
||||
}
|
||||
|
||||
native public static void showNotification(String title, String description);
|
||||
native private static void showNotification(final String title, final String description, final String iconPath);
|
||||
|
||||
public static void show(final String title, final String description, final String iconPath) {
|
||||
if (! available) return;
|
||||
try {
|
||||
showNotification(title, description, iconPath);
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
available = false;
|
||||
NotificationGroup.balloonGroup("Linux configuration messages");
|
||||
Notifications.Bus.notify(
|
||||
new Notification("Linux configuration messages",
|
||||
"Notification library has not been installed",
|
||||
message, NotificationType.INFORMATION)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a libnotify notification with an icon from the ide bin directory.
|
||||
* If there is no such icon a default information icon is shown.
|
||||
* @param title notification title
|
||||
* @param description notification description
|
||||
*/
|
||||
public static void showWithAppIcon(final String title, final String description) {
|
||||
String iconPath = AllIcons.findIcon(PathManager.getBinPath());
|
||||
show(title, description, (iconPath == null) ? "dialog-information" : iconPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class SystemNotificationsImpl extends SystemNotifications implements Pers
|
||||
if (!areNotificationsEnabled() || ApplicationManager.getApplication().isActive()) return;
|
||||
|
||||
if (SystemInfo.isLinux && Registry.is("ide.linux.gtk.notifications.enabled") ) {
|
||||
LibNotifyWrapper.showNotification(title, text);
|
||||
LibNotifyWrapper.showWithAppIcon(title, text);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1062,6 +1062,8 @@ action.Graph.print.preview=Print Preview
|
||||
|
||||
action.SendFeedback.text=Submit _Feedback
|
||||
action.SendFeedback.description=Submit feedback to the JetBrains Web site
|
||||
action.LogDebugConfigure.text=Configure Debug Log Settings
|
||||
action.LogDebugConfigure.description=Enable or disable additional log categories. Allows to provide more information to the support team by request.
|
||||
action.ShowLog.text=Open Log file
|
||||
action.ShowLog.description=Opens folder with log file
|
||||
action.TechnicalSupport.text=Contact _Support Team
|
||||
|
||||
@@ -818,6 +818,7 @@
|
||||
<checkinHandlerFactory implementation="com.intellij.openapi.vcs.checkin.TodoCheckinHandlerFactory"/>
|
||||
|
||||
<defaultHighlightingSettingProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.GeneratedSourcesHighlightingSettingProvider"/>
|
||||
<editorNotificationProvider implementation="com.intellij.ide.GeneratedFileEditingNotificationProvider"/>
|
||||
|
||||
<projectService serviceInterface="com.intellij.openapi.vcs.CodeSmellDetector"
|
||||
serviceImplementation="com.intellij.openapi.vcs.impl.CodeSmellDetectorImpl"/>
|
||||
|
||||
@@ -230,6 +230,10 @@
|
||||
<skipForDefaultProject/>
|
||||
</component>
|
||||
|
||||
<component>
|
||||
<interface-class>com.intellij.ide.GeneratedSourceFileChangeTracker</interface-class>
|
||||
<implementation-class>com.intellij.ide.GeneratedSourceFileChangeTrackerImpl</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<module-components>
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
<implementation-class>com.intellij.ide.SystemHealthMonitor</implementation-class>
|
||||
<headless-implementation-class/>
|
||||
</component>
|
||||
|
||||
<component>
|
||||
<implementation-class>com.intellij.diagnostic.DebugLogManager</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<project-components>
|
||||
|
||||
@@ -409,6 +409,7 @@
|
||||
<separator/>
|
||||
<action id="TechnicalSupport" class="com.intellij.ide.actions.TechnicalSupportAction"/>
|
||||
<action id="SendFeedback" class="com.intellij.ide.actions.SendFeedbackAction"/>
|
||||
<action id="LogDebugConfigure" class="com.intellij.ide.actions.DebugLogConfigureAction"/>
|
||||
<action id="ShowLog" class="com.intellij.ide.actions.ShowLogAction"/>
|
||||
<separator/>
|
||||
<action id="OnlineDocAction" class="com.intellij.ide.actions.OnlineDocAction"/>
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.openapi.keymap.impl.ui;
|
||||
|
||||
import com.intellij.openapi.actionSystem.ex.QuickList;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
|
||||
|
||||
public class ActionsTreeTest extends LightPlatformCodeInsightTestCase {
|
||||
private static final String ACTION_WITHOUT_TEXT_AND_DESCRIPTION = "EditorDeleteToLineEnd";
|
||||
private static final String ACTION_WITH_TEXT_ONLY = "EditorCutLineEnd";
|
||||
private static final String ACTION_WITH_TEXT_AND_DESCRIPTION = "EditorHungryBackSpace";
|
||||
|
||||
private ActionsTree myActionsTree;
|
||||
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myActionsTree = new ActionsTree();
|
||||
myActionsTree.reset(KeymapManager.getInstance().getActiveKeymap(), new QuickList[0]);
|
||||
}
|
||||
|
||||
public void testVariousActionsArePresent() {
|
||||
doTest(null,
|
||||
ACTION_WITHOUT_TEXT_AND_DESCRIPTION,
|
||||
ACTION_WITH_TEXT_ONLY,
|
||||
ACTION_WITH_TEXT_AND_DESCRIPTION);
|
||||
}
|
||||
|
||||
public void testFiltering() {
|
||||
doTest("Editor",
|
||||
// all below actions should still be present, as they contain 'Editor' in their actionId
|
||||
ACTION_WITHOUT_TEXT_AND_DESCRIPTION,
|
||||
ACTION_WITH_TEXT_ONLY,
|
||||
ACTION_WITH_TEXT_AND_DESCRIPTION);
|
||||
}
|
||||
|
||||
private void doTest(String filter, String... idsThatMustBePresent) {
|
||||
if (filter != null) {
|
||||
myActionsTree.filter(filter, new QuickList[0]);
|
||||
}
|
||||
|
||||
for (String actionId : idsThatMustBePresent) {
|
||||
assertTrue(actionId + " is absent", myActionsTree.getMainGroup().containsId(actionId));
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-1
@@ -1,3 +1,18 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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.testFramework.vcs;
|
||||
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
@@ -204,8 +219,9 @@ public class MockChangeListManager extends ChangeListManagerEx {
|
||||
return changes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ThreeState haveChangesUnder(VirtualFile vf) {
|
||||
public ThreeState haveChangesUnder(@NotNull VirtualFile vf) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -71,6 +71,7 @@ public interface UsageView extends Disposable {
|
||||
*/
|
||||
void addPerformOperationAction(@NotNull Runnable processRunnable, String commandName, String cannotMakeString, @NotNull String shortDescription, boolean checkReadOnlyStatus);
|
||||
|
||||
@NotNull
|
||||
UsageViewPresentation getPresentation();
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
package com.intellij.icons;
|
||||
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* NOTE THIS FILE IS AUTO-GENERATED
|
||||
@@ -1137,4 +1139,34 @@ public class AllIcons {
|
||||
public static final Icon Html_id = IconLoader.getIcon("/xml/html_id.png"); // 16x16
|
||||
|
||||
}
|
||||
|
||||
private static final int MIN_ICON_SIZE = 32;
|
||||
|
||||
@Nullable
|
||||
public static String findIcon(final String iconsPath) {
|
||||
final File iconsDir = new File(iconsPath);
|
||||
|
||||
// 1. look for .svg icon
|
||||
for (String child : iconsDir.list()) {
|
||||
if (child.endsWith(".svg")) {
|
||||
return iconsPath + '/' + child;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. look for .png icon of max size
|
||||
int max = 0;
|
||||
String iconPath = null;
|
||||
for (String child : iconsDir.list()) {
|
||||
if (!child.endsWith(".png")) continue;
|
||||
final String path = iconsPath + '/' + child;
|
||||
final Icon icon = new ImageIcon(path);
|
||||
final int size = icon.getIconHeight();
|
||||
if (size >= MIN_ICON_SIZE && size > max && size == icon.getIconWidth()) {
|
||||
max = size;
|
||||
iconPath = path;
|
||||
}
|
||||
}
|
||||
|
||||
return iconPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@ public class FileUtil extends FileUtilRt {
|
||||
return !ThreeState.NO.equals(isAncestorThreeState(ancestor, file, strict));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ThreeState isAncestorThreeState(@NotNull String ancestor, @NotNull String file, boolean strict) {
|
||||
String ancestorPath = toCanonicalPath(ancestor);
|
||||
String filePath = toCanonicalPath(file);
|
||||
@@ -127,6 +128,7 @@ public class FileUtil extends FileUtilRt {
|
||||
/**
|
||||
* @return ThreeState.YES if same path or immediate parent
|
||||
*/
|
||||
@NotNull
|
||||
private static ThreeState startsWith(@NotNull String path, @NotNull String start, boolean strict, boolean caseSensitive,
|
||||
boolean checkImmediateParent) {
|
||||
final int length1 = path.length();
|
||||
@@ -138,12 +140,11 @@ public class FileUtil extends FileUtilRt {
|
||||
return strict ? ThreeState.NO : ThreeState.YES;
|
||||
}
|
||||
char last2 = start.charAt(length2 - 1);
|
||||
char next1;
|
||||
int slashOrSeparatorIdx = length2;
|
||||
if (last2 == '/' || last2 == File.separatorChar) {
|
||||
slashOrSeparatorIdx = length2 - 1;
|
||||
}
|
||||
next1 = path.charAt(slashOrSeparatorIdx);
|
||||
char next1 = path.charAt(slashOrSeparatorIdx);
|
||||
if (next1 == '/' || next1 == File.separatorChar) {
|
||||
if (!checkImmediateParent) return ThreeState.YES;
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
*/
|
||||
package com.intellij.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AdapterProcessor<T, S> implements Processor<T> {
|
||||
private final Processor<S> myAdaptee;
|
||||
private final Function<T, S> myConversion;
|
||||
|
||||
public AdapterProcessor(Processor<S> adaptee, Function<T, S> conversion) {
|
||||
public AdapterProcessor(@NotNull Processor<S> adaptee, @NotNull Function<T, S> conversion) {
|
||||
myAdaptee = adaptee;
|
||||
myConversion = conversion;
|
||||
}
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package com.intellij.util.enumeration;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public final class EmptyEnumeration implements Enumeration {
|
||||
public final class EmptyEnumeration<E> implements Enumeration<E> {
|
||||
public static Enumeration INSTANCE = new EmptyEnumeration();
|
||||
|
||||
private EmptyEnumeration(){
|
||||
@@ -30,9 +32,15 @@ public final class EmptyEnumeration implements Enumeration {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object nextElement(){
|
||||
public E nextElement(){
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <E> Enumeration<E> getInstance() {
|
||||
//noinspection unchecked
|
||||
return INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -157,5 +157,6 @@ public abstract class ChangeListManager implements ChangeListModification {
|
||||
|
||||
public abstract List<VirtualFile> getModifiedWithoutEditing();
|
||||
|
||||
public abstract ThreeState haveChangesUnder(VirtualFile vf);
|
||||
@NotNull
|
||||
public abstract ThreeState haveChangesUnder(@NotNull VirtualFile vf);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -1088,9 +1088,10 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
|
||||
return getChangesIn(new FilePathImpl(dir));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ThreeState haveChangesUnder(final VirtualFile vf) {
|
||||
if (vf == null || ! vf.isValid() || ! vf.isDirectory()) return ThreeState.NO;
|
||||
public ThreeState haveChangesUnder(@NotNull final VirtualFile vf) {
|
||||
if (!vf.isValid() || !vf.isDirectory()) return ThreeState.NO;
|
||||
synchronized (myDataLock) {
|
||||
return myWorker.haveChangesUnder(vf);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -693,8 +693,9 @@ public class ChangeListWorker implements ChangeListsWriteOperations {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ThreeState haveChangesUnder(final VirtualFile vf) {
|
||||
final String absolutePath = new File(vf.getPath()).getAbsolutePath();
|
||||
@NotNull
|
||||
public ThreeState haveChangesUnder(@NotNull VirtualFile virtualFile) {
|
||||
final String absolutePath = new File(virtualFile.getPath()).getAbsolutePath();
|
||||
final SortedSet<String> tailSet = myIdx.getAffectedPaths().tailSet(absolutePath);
|
||||
for (String path : tailSet) {
|
||||
return FileUtil.isAncestorThreeState(absolutePath, path, false);
|
||||
|
||||
+8
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
|
||||
import com.intellij.openapi.vcs.impl.FileStatusProvider;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ThreeState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -48,8 +49,9 @@ public class ChangelistConflictFileStatusProvider implements FileStatusProvider
|
||||
myConflictTracker = changeListManager.getConflictTracker();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public FileStatus getFileStatus(VirtualFile virtualFile) {
|
||||
public FileStatus getFileStatus(@NotNull VirtualFile virtualFile) {
|
||||
ChangelistConflictTracker.Options options = myConflictTracker.getOptions();
|
||||
if (!options.TRACKING_ENABLED) {
|
||||
return null;
|
||||
@@ -69,12 +71,14 @@ public class ChangelistConflictFileStatusProvider implements FileStatusProvider
|
||||
return null;
|
||||
}
|
||||
|
||||
public void refreshFileStatusFromDocument(VirtualFile file, Document doc) {
|
||||
@Override
|
||||
public void refreshFileStatusFromDocument(@NotNull VirtualFile virtualFile, @NotNull Document doc) {
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ThreeState getNotChangedDirectoryParentingStatus(VirtualFile vf) {
|
||||
public ThreeState getNotChangedDirectoryParentingStatus(@NotNull VirtualFile virtualFile) {
|
||||
throw new UnsupportedOperationException("Shouldn't be called");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.vcs.readOnlyHandler.ReadonlyStatusHandlerImpl;
|
||||
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ThreeState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -60,18 +61,22 @@ public class VcsFileStatusProvider implements FileStatusProvider, VcsBaseContent
|
||||
myFileStatusManager.setFileStatusProvider(this);
|
||||
|
||||
changeListManager.addChangeListListener(new ChangeListAdapter() {
|
||||
@Override
|
||||
public void changeListAdded(ChangeList list) {
|
||||
fileStatusesChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeListRemoved(ChangeList list) {
|
||||
fileStatusesChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeListChanged(ChangeList list) {
|
||||
fileStatusesChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeListUpdateDone() {
|
||||
if (myHaveEmptyContentRevisions) {
|
||||
myHaveEmptyContentRevisions = false;
|
||||
@@ -89,7 +94,9 @@ public class VcsFileStatusProvider implements FileStatusProvider, VcsBaseContent
|
||||
myFileStatusManager.fileStatusesChanged();
|
||||
}
|
||||
|
||||
public FileStatus getFileStatus(final VirtualFile virtualFile) {
|
||||
@Override
|
||||
@NotNull
|
||||
public FileStatus getFileStatus(@NotNull final VirtualFile virtualFile) {
|
||||
final AbstractVcs vcs = myVcsManager.getVcsFor(virtualFile);
|
||||
if (vcs == null) {
|
||||
return FileStatusManagerImpl.getDefaultStatus(virtualFile);
|
||||
@@ -110,33 +117,35 @@ public class VcsFileStatusProvider implements FileStatusProvider, VcsBaseContent
|
||||
return FileDocumentManager.getInstance().isFileModified(virtualFile);
|
||||
}
|
||||
|
||||
public void refreshFileStatusFromDocument(final VirtualFile file, final Document doc) {
|
||||
@Override
|
||||
public void refreshFileStatusFromDocument(@NotNull final VirtualFile virtualFile, @NotNull final Document doc) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("refreshFileStatusFromDocument: file.getModificationStamp()=" + file.getModificationStamp() + ", document.getModificationStamp()=" + doc.getModificationStamp());
|
||||
LOG.debug("refreshFileStatusFromDocument: file.getModificationStamp()=" + virtualFile.getModificationStamp() + ", document.getModificationStamp()=" + doc.getModificationStamp());
|
||||
}
|
||||
FileStatus cachedStatus = myFileStatusManager.getCachedStatus(file);
|
||||
if (cachedStatus == null || cachedStatus == FileStatus.NOT_CHANGED || !isDocumentModified(file)) {
|
||||
final AbstractVcs vcs = myVcsManager.getVcsFor(file);
|
||||
FileStatus cachedStatus = myFileStatusManager.getCachedStatus(virtualFile);
|
||||
if (cachedStatus == null || cachedStatus == FileStatus.NOT_CHANGED || !isDocumentModified(virtualFile)) {
|
||||
final AbstractVcs vcs = myVcsManager.getVcsFor(virtualFile);
|
||||
if (vcs == null) return;
|
||||
if (cachedStatus == FileStatus.MODIFIED && !isDocumentModified(file)) {
|
||||
if (cachedStatus == FileStatus.MODIFIED && !isDocumentModified(virtualFile)) {
|
||||
if (!((ReadonlyStatusHandlerImpl) ReadonlyStatusHandlerImpl.getInstance(myProject)).getState().SHOW_DIALOG) {
|
||||
RollbackEnvironment rollbackEnvironment = vcs.getRollbackEnvironment();
|
||||
if (rollbackEnvironment != null) {
|
||||
rollbackEnvironment.rollbackIfUnchanged(file);
|
||||
rollbackEnvironment.rollbackIfUnchanged(virtualFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
myFileStatusManager.fileStatusChanged(file);
|
||||
myFileStatusManager.fileStatusChanged(virtualFile);
|
||||
ChangeProvider cp = vcs.getChangeProvider();
|
||||
if (cp != null && cp.isModifiedDocumentTrackingRequired()) {
|
||||
myDirtyScopeManager.fileDirty(file);
|
||||
myDirtyScopeManager.fileDirty(virtualFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ThreeState getNotChangedDirectoryParentingStatus(VirtualFile vf) {
|
||||
return myConfiguration.SHOW_DIRTY_RECURSIVELY ? myChangeListManager.haveChangesUnder(vf) : ThreeState.NO;
|
||||
public ThreeState getNotChangedDirectoryParentingStatus(@NotNull VirtualFile virtualFile) {
|
||||
return myConfiguration.SHOW_DIRTY_RECURSIVELY ? myChangeListManager.haveChangesUnder(virtualFile) : ThreeState.NO;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,6 +173,7 @@ public class VcsFileStatusProvider implements FileStatusProvider, VcsBaseContent
|
||||
|
||||
if (isDocumentModified(file)) {
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
return LoadTextUtil.loadText(file).toString();
|
||||
}
|
||||
|
||||
+2
-1
@@ -106,4 +106,5 @@ add.type.customizer.to.resources=Add type customizer script to resources
|
||||
target.0.does.not.exist=Target ''{0}'' does not exist
|
||||
target.annotation.is.unused=@Target is unused
|
||||
change.lvalue.type=Change variable ''{0}'' type to ''{1}''
|
||||
replace.qualified.name.with.import=Replace qualified name with import
|
||||
replace.qualified.name.with.import=Replace qualified name with import
|
||||
highlight.assignments.from.void=Highlight assignments from void type
|
||||
+39
-1
@@ -18,12 +18,14 @@ package org.jetbrains.plugins.groovy.codeInspection.assignment;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
|
||||
import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiSubstitutorImpl;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -80,6 +82,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.*;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -90,6 +93,10 @@ import java.util.Map;
|
||||
public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
private static final Logger LOG = Logger.getInstance(GroovyAssignabilityCheckInspection.class);
|
||||
|
||||
private static final String SHORT_NAME = "GroovyAssignabilityCheck";
|
||||
|
||||
public boolean myHighlightAssignmentsFromVoid = true;
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -102,6 +109,14 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createOptionsPanel() {
|
||||
final MultipleCheckboxOptionsPanel optionsPanel = new MultipleCheckboxOptionsPanel(this);
|
||||
optionsPanel.addCheckbox(GroovyInspectionBundle.message("highlight.assignments.from.void"), "myHighlightAssignmentsFromVoid");
|
||||
return optionsPanel;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -127,6 +142,14 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
final PsiType rType = expression.getType();
|
||||
if (rType == null) return;
|
||||
|
||||
if (PsiUtil.isVoidMethodCall(expression)) {
|
||||
if (isHighlightAssignmentsFromVoid(expression)) {
|
||||
registerError(toHighlight, GroovyBundle.message("cannot.assign", PsiType.VOID.getPresentableText(),
|
||||
expectedType.getPresentableText()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!TypesUtil.isAssignable(expectedType, rType, expression)) {
|
||||
final List<LocalQuickFix> fixes = ContainerUtil.newArrayList();
|
||||
fixes.add(new GrCastFix(expectedType));
|
||||
@@ -141,6 +164,21 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isHighlightAssignmentsFromVoid(PsiElement place) {
|
||||
final GroovyAssignabilityCheckInspection instance = getInspectionInstance(place.getContainingFile(), place.getProject());
|
||||
if (instance != null) {
|
||||
return instance.myHighlightAssignmentsFromVoid;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static GroovyAssignabilityCheckInspection getInspectionInstance(PsiFile file, Project project) {
|
||||
final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
|
||||
return (GroovyAssignabilityCheckInspection)profile.getUnwrappedTool(SHORT_NAME, file);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static String getLValueVarName(PsiElement highlight) {
|
||||
final PsiElement parent = highlight.getParent();
|
||||
@@ -221,7 +259,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
|
||||
if (flowOwner != null && returnType != null && returnType != PsiType.VOID) {
|
||||
if (ControlFlowUtils.isReturnValue(expression, flowOwner) &&
|
||||
!isNewInstanceInitialingByTuple(expression) &&
|
||||
expression.getType() != PsiType.VOID) {
|
||||
!PsiUtil.isVoidMethodCall(expression)) {
|
||||
checkAssignability(returnType, expression, getExpressionPartToHighlight(expression));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,12 +54,6 @@ public final class GenerateGroovyDocDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
super.dispose();
|
||||
//Disposer.dispose(myPanel);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected String getHelpId() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -36,7 +36,7 @@ import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public final class GroovyDocGenerationPanel extends JPanel/* implements Disposable*/ {
|
||||
public final class GroovyDocGenerationPanel extends JPanel {
|
||||
JPanel myPanel;
|
||||
TextFieldWithBrowseButton myOutputDir;
|
||||
NonFocusableCheckBox myIsUse;
|
||||
@@ -54,9 +54,6 @@ public final class GroovyDocGenerationPanel extends JPanel/* implements Disposab
|
||||
private final DefaultListModel myDataModel;
|
||||
|
||||
GroovyDocGenerationPanel() {
|
||||
//Disposer.register(this, myInputDir);
|
||||
//Disposer.register(this, myOutputDir);
|
||||
|
||||
myInputDir.addBrowseFolderListener(GroovyDocBundle.message("groovydoc.generate.directory.browse"), null, null,
|
||||
FileChooserDescriptorFactory.createSingleFolderDescriptor());
|
||||
|
||||
@@ -161,8 +158,4 @@ private static String[] toStringArray(final DefaultListModel model) {
|
||||
public JPanel getPanel() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
//@Override
|
||||
public void dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -18,6 +18,8 @@ package org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl;
|
||||
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -35,7 +37,7 @@ public class MaybeReturnInstruction extends InstructionImpl {
|
||||
GrExpression expression = (GrExpression) getElement();
|
||||
assert expression != null;
|
||||
final PsiType type = expression.getType();
|
||||
return type != PsiType.VOID;
|
||||
return type != PsiType.VOID && !PsiUtil.isVoidMethodCall(expression);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -557,7 +557,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
public GrMethod createMethodFromSignature(String name, GrClosureSignature signature) {
|
||||
StringBuilder builder = new StringBuilder("public");
|
||||
final PsiType returnType = signature.getReturnType();
|
||||
if (returnType != null) {
|
||||
if (returnType != null && returnType != PsiType.NULL) {
|
||||
builder.append(' ');
|
||||
builder.append(returnType.getCanonicalText());
|
||||
}
|
||||
|
||||
+22
-16
@@ -54,18 +54,21 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal
|
||||
PsiType result = null;
|
||||
for (GroovyResolveResult resolveResult : resolveResults) {
|
||||
PsiType returnType = calculateReturnTypeInner(callExpression, refExpr, resolveResult);
|
||||
|
||||
if (returnType == null) return null;
|
||||
if (!(returnType instanceof GrLiteralClassType)) {
|
||||
returnType = TypesUtil.substituteBoxAndNormalizeType(returnType, resolveResult.getSubstitutor(), resolveResult.getSpreadState(), callExpression);
|
||||
LOG.assertTrue(returnType != null);
|
||||
}
|
||||
|
||||
if (result == null || returnType.isAssignableFrom(result)) {
|
||||
result = returnType;
|
||||
PsiType nonVoid = PsiType.VOID.equals(returnType) ? PsiType.NULL : returnType;
|
||||
|
||||
PsiType normalized = nonVoid instanceof GrLiteralClassType
|
||||
? nonVoid
|
||||
: TypesUtil.substituteBoxAndNormalizeType(nonVoid, resolveResult.getSubstitutor(), resolveResult.getSpreadState(), callExpression);
|
||||
|
||||
LOG.assertTrue(normalized != null);
|
||||
|
||||
if (result == null || normalized.isAssignableFrom(result)) {
|
||||
result = normalized;
|
||||
}
|
||||
else if (!result.isAssignableFrom(returnType)) {
|
||||
result = TypesUtil.getLeastUpperBound(result, returnType, manager);
|
||||
else if (!result.isAssignableFrom(normalized)) {
|
||||
result = TypesUtil.getLeastUpperBound(result, normalized, manager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,26 +84,29 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal
|
||||
GrReferenceExpression refExpr,
|
||||
GroovyResolveResult resolveResult) {
|
||||
PsiElement resolved = resolveResult.getElement();
|
||||
PsiType returnType = null;
|
||||
if (resolved instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)resolved;
|
||||
if (resolveResult.isInvokedOnProperty()) {
|
||||
final PsiType propertyType = PsiUtil.getSmartReturnType(method);
|
||||
returnType = extractReturnTypeFromType(propertyType, true, callExpression);
|
||||
return extractReturnTypeFromType(propertyType, true, callExpression);
|
||||
}
|
||||
else {
|
||||
returnType = getClosureMethodsReturnType(callExpression, refExpr, method);
|
||||
if (returnType == null) {
|
||||
returnType = PsiUtil.getSmartReturnType(method);
|
||||
PsiType closureReturnType = getClosureMethodsReturnType(callExpression, refExpr, method);
|
||||
if (closureReturnType != null) {
|
||||
return closureReturnType;
|
||||
}
|
||||
else {
|
||||
final PsiType smartReturnType = PsiUtil.getSmartReturnType(method);
|
||||
return smartReturnType;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (resolved instanceof GrVariable) {
|
||||
PsiType refType = refExpr.getType();
|
||||
final PsiType type = refType == null ? ((GrVariable)resolved).getTypeGroovy() : refType;
|
||||
returnType = extractReturnTypeFromType(type, false, callExpression);
|
||||
return extractReturnTypeFromType(type, false, callExpression);
|
||||
}
|
||||
return returnType;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+9
-7
@@ -38,6 +38,7 @@ import icons.JetgroovyIcons;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster;
|
||||
import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor;
|
||||
import org.jetbrains.plugins.groovy.gpp.GppTypeConverter;
|
||||
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocComment;
|
||||
@@ -260,25 +261,26 @@ public abstract class GrMethodBaseImpl extends GrStubElementBase<GrMethodStub> i
|
||||
@Nullable
|
||||
public GrTypeElement setReturnType(@Nullable PsiType newReturnType) {
|
||||
GrTypeElement typeElement = getReturnTypeElementGroovy();
|
||||
if (newReturnType == null) {
|
||||
if (newReturnType == null || newReturnType == PsiType.NULL) {
|
||||
if (typeElement != null) typeElement.delete();
|
||||
return null;
|
||||
}
|
||||
GrTypeElement newTypeElement = GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(newReturnType);
|
||||
final GrTypeElement stub = GroovyPsiElementFactory.getInstance(getProject()).createTypeElement(newReturnType);
|
||||
GrTypeElement newTypeElement;
|
||||
if (typeElement == null) {
|
||||
PsiElement anchor = getTypeParameterList();
|
||||
if (anchor == null) anchor = getModifierList();
|
||||
newTypeElement = (GrTypeElement)addAfter(newTypeElement, anchor);
|
||||
final GrTypeParameterList typeParemeterList = getTypeParameterList();
|
||||
PsiElement anchor = typeParemeterList != null ? typeParemeterList : getModifierList();
|
||||
newTypeElement = (GrTypeElement)addAfter(stub, anchor);
|
||||
}
|
||||
else {
|
||||
newTypeElement = (GrTypeElement)typeElement.replace(newTypeElement);
|
||||
newTypeElement = (GrTypeElement)typeElement.replace(stub);
|
||||
}
|
||||
|
||||
newTypeElement.accept(new GroovyRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitCodeReferenceElement(GrCodeReferenceElement refElement) {
|
||||
super.visitCodeReferenceElement(refElement);
|
||||
org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster.shortenReference(refElement);
|
||||
GrReferenceAdjuster.shortenReference(refElement);
|
||||
}
|
||||
});
|
||||
return newTypeElement;
|
||||
|
||||
@@ -28,9 +28,7 @@ import com.intellij.psi.impl.light.LightElement;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.VisibilityUtil;
|
||||
@@ -56,6 +54,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrSpreadArgument;
|
||||
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;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrAssertStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement;
|
||||
@@ -63,6 +62,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrThrowStatem
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrPropertySelection;
|
||||
@@ -73,6 +73,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrNamedArgumentsOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
@@ -1347,4 +1348,38 @@ public class PsiUtil {
|
||||
final String qname = aClass.getQualifiedName();
|
||||
return GroovyCommonClassNames.GROOVY_EXTENSION_CLASSES.contains(qname);
|
||||
}
|
||||
|
||||
public static boolean isVoidMethodCall(@Nullable GrExpression expression) {
|
||||
if (expression instanceof GrMethodCall && PsiType.NULL.equals(expression.getType())) {
|
||||
final GroovyResolveResult resolveResult = ((GrMethodCall)expression).advancedResolve();
|
||||
final PsiType[] args = getArgumentTypes(((GrMethodCall)expression).getInvokedExpression(), true);
|
||||
return PsiType.VOID.equals(ResolveUtil.extractReturnTypeFromCandidate(resolveResult, expression, args));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isVoidMethod(@NotNull PsiMethod method) {
|
||||
return PsiType.VOID.equals(method.getReturnType()) ||
|
||||
|
||||
method instanceof GrMethod &&
|
||||
((GrMethod)method).getReturnTypeElementGroovy() == null &&
|
||||
((GrMethod)method).getBlock() != null &&
|
||||
isBlockReturnVoid(((GrMethod)method).getBlock());
|
||||
}
|
||||
|
||||
public static boolean isBlockReturnVoid(@NotNull final GrCodeBlock block) {
|
||||
return CachedValuesManager.getCachedValue(block, new CachedValueProvider<Boolean>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Result<Boolean> compute() {
|
||||
return Result.create(ControlFlowUtils.visitAllExitPoints(block, new ControlFlowUtils.ExitPointVisitor() {
|
||||
@Override
|
||||
public boolean visitExitPoint(Instruction instruction, @Nullable GrExpression returnValue) {
|
||||
return returnValue == null || !(returnValue instanceof GrLiteral);
|
||||
}
|
||||
}), PsiModificationTracker.MODIFICATION_COUNT);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -68,9 +68,10 @@ public class AnonymousFromMapGenerator {
|
||||
final GrExpression expression = arg.getExpression();
|
||||
if (name == null || expression == null || !(expression instanceof GrClosableBlock)) continue;
|
||||
|
||||
final GrParameter[] allParameters = ((GrClosableBlock)expression).getAllParameters();
|
||||
final GrClosableBlock closure = (GrClosableBlock)expression;
|
||||
final GrParameter[] allParameters = closure.getAllParameters();
|
||||
List<GrParameter> actual = new ArrayList<GrParameter>(Arrays.asList(allParameters));
|
||||
final PsiType clReturnType = ((GrClosableBlock)expression).getReturnType();
|
||||
final PsiType clReturnType = context.typeProvider.getReturnType(closure);
|
||||
|
||||
GrExpression[] args = new GrExpression[allParameters.length];
|
||||
for (int i = 0; i < allParameters.length; i++) {
|
||||
|
||||
+7
-6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2013 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.
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrRe
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyFileImpl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.refactoring.convertToJava.TypeWriter.writeType;
|
||||
import static org.jetbrains.plugins.groovy.refactoring.convertToJava.TypeWriter.writeTypeForNew;
|
||||
@@ -85,15 +86,15 @@ public class ClosureGenerator {
|
||||
|
||||
private void generateClosureMainMethod(@NotNull GrClosableBlock block) {
|
||||
builder.append("public ");
|
||||
final PsiType returnType = block.getReturnType();
|
||||
final PsiType returnType = context.typeProvider.getReturnType(block);
|
||||
writeType(builder, returnType, block);
|
||||
builder.append(" doCall");
|
||||
final GrParameter[] parameters = block.getAllParameters();
|
||||
GenerationUtil.writeParameterList(builder, parameters, new GeneratorClassNameProvider(), context);
|
||||
|
||||
Collection<GrStatement> myExitPoints = ControlFlowUtils.collectReturns(block);
|
||||
boolean shouldInsertReturnNull =
|
||||
!(returnType instanceof PsiPrimitiveType) && MissingReturnInspection.methodMissesSomeReturns(block, MissingReturnInspection.ReturnStatus.shouldNotReturnValue);
|
||||
Collection<GrStatement> myExitPoints = returnType != PsiType.VOID ? ControlFlowUtils.collectReturns(block) : Collections.<GrStatement>emptySet();
|
||||
boolean shouldInsertReturnNull = !(returnType instanceof PsiPrimitiveType) &&
|
||||
MissingReturnInspection.methodMissesSomeReturns(block, MissingReturnInspection.ReturnStatus.shouldNotReturnValue);
|
||||
|
||||
new CodeBlockGenerator(builder, context.extend(), myExitPoints).generateCodeBlock(block, shouldInsertReturnNull);
|
||||
builder.append('\n');
|
||||
@@ -104,7 +105,7 @@ public class ClosureGenerator {
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.project);
|
||||
final GrMethod method = factory.createMethodFromText("def doCall(){}", block);
|
||||
|
||||
method.setReturnType(block.getReturnType());
|
||||
method.setReturnType(context.typeProvider.getReturnType(block));
|
||||
if (block.hasParametersSection()) {
|
||||
method.getParameterList().replace(block.getParameterList());
|
||||
}
|
||||
|
||||
+19
-5
@@ -101,14 +101,18 @@ public class CodeBlockGenerator extends Generator {
|
||||
public void generateMethodBody(GrMethod method) {
|
||||
final GrOpenBlock block = method.getBlock();
|
||||
|
||||
boolean shouldInsertReturnNull = false;
|
||||
boolean shouldInsertReturnNull;
|
||||
myExitPoints.clear();
|
||||
PsiType returnType = context.typeProvider.getReturnType(method);
|
||||
if (!method.isConstructor() && returnType != PsiType.VOID) {
|
||||
myExitPoints.addAll(ControlFlowUtils.collectReturns(block));
|
||||
shouldInsertReturnNull = block != null && !(returnType instanceof PsiPrimitiveType) &&
|
||||
MissingReturnInspection.methodMissesSomeReturns(block,
|
||||
MissingReturnInspection.ReturnStatus.getReturnStatus(method));
|
||||
shouldInsertReturnNull = block != null &&
|
||||
!(returnType instanceof PsiPrimitiveType) &&
|
||||
MissingReturnInspection.methodMissesSomeReturns(block, MissingReturnInspection.ReturnStatus.getReturnStatus(
|
||||
method));
|
||||
}
|
||||
else {
|
||||
shouldInsertReturnNull = false;
|
||||
}
|
||||
|
||||
if (block != null) {
|
||||
@@ -321,7 +325,7 @@ public class CodeBlockGenerator extends Generator {
|
||||
GenerationUtil.writeStatement(builder, context, expression, new StatementWriter() {
|
||||
@Override
|
||||
public void writeStatement(StringBuilder builder, ExpressionContext context) {
|
||||
if (myExitPoints.contains(expression) && expression.getType() != PsiType.VOID) {
|
||||
if (myExitPoints.contains(expression) && isRealExpression(expression)) {
|
||||
writeReturn(builder, context, expression);
|
||||
}
|
||||
else {
|
||||
@@ -329,6 +333,16 @@ public class CodeBlockGenerator extends Generator {
|
||||
builder.append(';');
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRealExpression(GrExpression expression) {
|
||||
final PsiType type = expression.getType();
|
||||
|
||||
if (type == PsiType.VOID) return false; //statement
|
||||
|
||||
if (type == PsiType.NULL) return !org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.isVoidMethodCall(expression);
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+18
-1
@@ -25,6 +25,7 @@ import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
@@ -55,7 +56,9 @@ public class TypeProvider {
|
||||
if (typeElement != null) return typeElement.getType();
|
||||
}
|
||||
final PsiType smartReturnType = PsiUtil.getSmartReturnType(method);
|
||||
if (smartReturnType != null) return smartReturnType;
|
||||
if (smartReturnType != null && !PsiType.NULL.equals(smartReturnType)) return smartReturnType;
|
||||
|
||||
if (PsiType.NULL.equals(smartReturnType) && PsiUtil.isVoidMethod(method)) return PsiType.VOID;
|
||||
|
||||
//todo make smarter. search for usages and infer type from them
|
||||
return TypesUtil.getJavaLangObject(method);
|
||||
@@ -161,4 +164,18 @@ public class TypeProvider {
|
||||
inferredTypes.put(method, types);
|
||||
return types;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiType getReturnType(GrClosableBlock closure) {
|
||||
final PsiType returnType = closure.getReturnType();
|
||||
if (PsiType.NULL.equals(returnType) && PsiUtil.isBlockReturnVoid(closure)) {
|
||||
return PsiType.VOID;
|
||||
}
|
||||
|
||||
if (returnType == null) {
|
||||
return TypesUtil.getJavaLangObject(closure);
|
||||
}
|
||||
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -53,13 +53,13 @@ public class TypeWriter extends PsiTypeVisitor<Object> {
|
||||
@Nullable PsiType type,
|
||||
@NotNull final PsiElement context,
|
||||
@NotNull final ClassNameProvider classNameProvider) {
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
builder.append(type.getCanonicalText());
|
||||
if (type == null || PsiType.NULL.equals(type)) {
|
||||
builder.append(CommonClassNames.JAVA_LANG_OBJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == null) {
|
||||
builder.append(CommonClassNames.JAVA_LANG_OBJECT);
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
builder.append(type.getCanonicalText());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -39,6 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaratio
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
|
||||
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.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
@@ -407,11 +408,11 @@ public class ExtractUtil {
|
||||
GrExpression expr = stringPartInfo != null
|
||||
? GrIntroduceHandlerBase.generateExpressionFromStringPart(stringPartInfo, helper.getProject())
|
||||
: (GrExpression)PsiUtil.skipParentheses(helper.getStatements()[0], false);
|
||||
boolean addReturn = !isVoid && forceReturn;
|
||||
boolean addReturn = !isVoid && forceReturn && !PsiUtil.isVoidMethodCall(expr);
|
||||
if (addReturn) {
|
||||
buffer.append("return ");
|
||||
expr = ApplicationStatementUtil.convertToMethodCallExpression(expr);
|
||||
buffer.append(expr.getText());
|
||||
final GrExpression methodCall = ApplicationStatementUtil.convertToMethodCallExpression(expr);
|
||||
buffer.append(methodCall.getText());
|
||||
}
|
||||
else {
|
||||
buffer.append(expr != null ? expr.getText() : "");
|
||||
|
||||
+1
-1
@@ -368,7 +368,7 @@ def foo(Function<String, String> function) {
|
||||
foo<warning descr="'foo' in '_' cannot be applied to '(Function<java.lang.Double,java.lang.Double>)'">({println it.byteValue()} as Function<Double, Double>)</warning>
|
||||
foo({println it.substring(1)} as Function)
|
||||
foo({println it.substring(1)} as Function<String, String>)
|
||||
foo<warning descr="'foo' in '_' cannot be applied to '(groovy.lang.Closure<java.lang.Void>)'">({println it})</warning>
|
||||
foo<warning descr="'foo' in '_' cannot be applied to '(groovy.lang.Closure)'">({println it})</warning>
|
||||
|
||||
''')
|
||||
}
|
||||
|
||||
+1
-1
@@ -231,7 +231,7 @@ public class TypeInferenceTest extends GroovyResolveTestCase {
|
||||
final PsiReference ref = configureByFile(getTestName(true) + "/A.groovy");
|
||||
assertInstanceOf(ref, GrReferenceExpression.class);
|
||||
final PsiType type = ((GrReferenceExpression)ref).type;
|
||||
assertNull(type);
|
||||
assertTrue(true); //test just should not fail with SOF exception
|
||||
}
|
||||
|
||||
public void testTraditionalForVar() {
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@ class StringCategory {
|
||||
testMethod()
|
||||
}
|
||||
|
||||
private void testMethod() {
|
||||
use(StringCategory) {
|
||||
private testMethod() {
|
||||
return use(StringCategory) {
|
||||
println "TeSt".lower()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
java.util.ArrayList<java.lang.Integer> list = new java.util.ArrayList<java.lang.Integer>(java.util.Arrays.asList(1, 2, 3));
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(list, new groovy.lang.Closure<java.lang.Void>(this, this) {
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.each(list, new groovy.lang.Closure<java.lang.Object>(this, this) {
|
||||
public void doCall(java.lang.Integer it) {
|
||||
print(it);
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ new closureInUse(new groovy.lang.Binding(args)).run();
|
||||
public java.lang.Object run() {
|
||||
|
||||
|
||||
return org.codehaus.groovy.runtime.DefaultGroovyMethods.use(this, IntCat.class, new groovy.lang.Closure<java.lang.Void>(this, this) {
|
||||
return org.codehaus.groovy.runtime.DefaultGroovyMethods.use(this, IntCat.class, new groovy.lang.Closure<java.lang.Object>(this, this) {
|
||||
public void doCall(java.lang.Object it) {
|
||||
IntCat.call(2);
|
||||
IntCat.call(2, "a");
|
||||
|
||||
@@ -42,7 +42,7 @@ final MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
|
||||
|
||||
long start = java.lang.System.currentTimeMillis();
|
||||
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.eachByte(f, MB, new groovy.lang.Closure<java.lang.Void>(this, this) {
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.eachByte(f, MB, new groovy.lang.Closure<java.lang.Object>(this, this) {
|
||||
public void doCall(java.lang.Byte[] buf, int bytesRead) {
|
||||
messageDigest.update(buf, 0, bytesRead);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ new refInClosureInScript(new groovy.lang.Binding(args)).run();
|
||||
public java.lang.Object run() {
|
||||
final groovy.lang.Reference<java.lang.Integer> foo = new groovy.lang.Reference<java.lang.Integer>(2);
|
||||
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.times(3, new groovy.lang.Closure<java.lang.Void>(this, this) {
|
||||
org.codehaus.groovy.runtime.DefaultGroovyMethods.times(3, new groovy.lang.Closure<java.lang.Object>(this, this) {
|
||||
public void doCall(java.lang.Integer it) {
|
||||
foo.set(foo.get()++);
|
||||
foo.set(foo.get() + 2);
|
||||
|
||||
@@ -437,9 +437,6 @@
|
||||
icon="AllIcons.Nodes.ExceptionClass">
|
||||
</action>
|
||||
|
||||
<action id="Maven.Help"
|
||||
class="com.intellij.ide.actions.ContextHelpAction" text="Help"/>
|
||||
|
||||
<action id="Maven.ExpandAll" class="org.jetbrains.idea.maven.navigator.actions.MavenTreeAction$ExpandAll" text="Expand All"
|
||||
icon="AllIcons.Actions.Expandall"
|
||||
use-shortcut-of="ExpandAll"/>
|
||||
@@ -527,7 +524,6 @@
|
||||
<reference id="Maven.CollapseAll"/>
|
||||
<separator/>
|
||||
<reference id="Maven.ShowSettings"/>
|
||||
<reference id="Maven.Help"/>
|
||||
</group>
|
||||
|
||||
<group id="Maven.DependencyMenu">
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<postfixTemplate implementation="com.intellij.codeInsight.template.postfix.templates.ForeachPostfixTemplate"/>
|
||||
<postfixTemplate implementation="com.intellij.codeInsight.template.postfix.templates.WhileStatementPostfixTemplate"/>
|
||||
<postfixTemplate implementation="com.intellij.codeInsight.template.postfix.templates.CastExpressionPostfixTemplate"/>
|
||||
<postfixTemplate implementation="com.intellij.codeInsight.template.postfix.templates.NewExpressionPostfixTemplate"/>
|
||||
<!--<postfixTemplate implementation="com.intellij.codeInsight.template.postfix.templates.NewExpressionPostfixTemplate"/>-->
|
||||
<postfixTemplate implementation="com.intellij.codeInsight.template.postfix.templates.IfStatementPostfixTemplate"/>
|
||||
<postfixTemplate implementation="com.intellij.codeInsight.template.postfix.templates.ForAscendingPostfixTemplate"/>
|
||||
<postfixTemplate implementation="com.intellij.codeInsight.template.postfix.templates.ForDescendingPostfixTemplate"/>
|
||||
|
||||
@@ -177,7 +177,7 @@ public class OpenFileInDefaultBrowserAction extends DumbAwareAction {
|
||||
public PsiFile getFile() {
|
||||
if (file == null) {
|
||||
file = PsiManager.getInstance(getProject()).findFile(virtualFile);
|
||||
LOG.assertTrue(file != null);
|
||||
LOG.assertTrue(file != null, virtualFile.getPath());
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ public abstract class OpenInBrowserRequest {
|
||||
|
||||
@Nullable
|
||||
public static OpenInBrowserRequest create(@NotNull final PsiElement element) {
|
||||
PsiFile psiFile = element.getContainingFile();
|
||||
if (psiFile == null) {
|
||||
PsiFile psiFile = element.isValid() ? element.getContainingFile() : null;
|
||||
if (psiFile == null || psiFile.getVirtualFile() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user