Merge remote-tracking branch 'origin/master'

This commit is contained in:
Oleg Sukhodolsky
2015-02-23 09:09:00 +03:00
47 changed files with 488 additions and 54 deletions
@@ -93,6 +93,7 @@ import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.util.internal.ThreadLocalRandom;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.ide.PooledThreadExecutor;
@@ -999,6 +1000,9 @@ public class BuildManager implements ApplicationComponent{
cmdLine.addParameter("-Didea.case.sensitive.fs=" + isFSCaseSensitive);
}
// this will make netty initialization faster on some systems
cmdLine.addParameter("-Dio.netty.initialSeedUniquifier=" + ThreadLocalRandom.getInitialSeedUniquifier());
boolean isProfilingMode = false;
final String additionalOptions = config.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS;
if (!StringUtil.isEmpty(additionalOptions)) {
@@ -106,7 +106,7 @@ public class CodeInsightUtil {
if (parent == null) return PsiElement.EMPTY_ARRAY;
while (true) {
if (parent instanceof PsiStatement) {
if (!(element1 instanceof PsiComment || element2 instanceof PsiComment)) {
if (!(element1 instanceof PsiComment)) {
parent = parent.getParent();
}
break;
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

@@ -107,7 +107,7 @@
<text value="Scope:"/>
</properties>
</component>
<component id="1fda7" class="javax.swing.JLabel">
<component id="1fda7" class="javax.swing.JLabel" binding="myOptionalLabel">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
@@ -51,6 +51,7 @@ public class LayoutCodeDialog extends DialogWrapper {
private JPanel myActionsPanel;
private JPanel myScopePanel;
private JLabel myOptionalLabel;
private LayoutCodeOptions myRunOptions;
@@ -127,6 +128,8 @@ public class LayoutCodeDialog extends DialogWrapper {
if (canRearrangeCode) {
myRearrangeCodeCb.setSelected(myLastRunOptions.isRearrangeCode(myFile.getLanguage()));
}
myOptionalLabel.setVisible(canOptimizeImports || canRearrangeCode);
}
@Nullable
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2015 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,11 +15,8 @@
*/
package com.intellij.ide.ui.laf;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.laf.darcula.DarculaLaf;
import com.intellij.openapi.util.SystemInfo;
import javax.swing.*;
import javax.swing.plaf.metal.DefaultMetalTheme;
/**
@@ -36,19 +33,6 @@ public class IntelliJLaf extends DarculaLaf {
return "intellijlaf";
}
@Override
public UIDefaults getDefaults() {
UIDefaults defaults = super.getDefaults();
if (SystemInfo.isLinux) {
try {
LafManagerImpl.initFontDefaults(defaults, "Dialog", 12);
}
catch (Exception ignore) {
}
}
return defaults;
}
@Override
protected DefaultMetalTheme createMetalTheme() {
return new IdeaBlueMetalTheme();
@@ -560,6 +560,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
List<String> myIntKeys = Arrays.asList("Tree.leftChildIndent",
"Tree.rightChildIndent");
List<String> patched = new ArrayList<String>();
for (Map.Entry<Object, Object> entry : defaults.entrySet()) {
Object value = entry.getValue();
String key = entry.getKey().toString();
@@ -569,10 +570,16 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
entry.setValue(JBUI.insets(((InsetsUIResource)value)).asUIResource());
} else if (value instanceof Integer) {
if (key.endsWith(".maxGutterIconWidth") || myIntKeys.contains(key)) {
entry.setValue(Integer.valueOf(JBUI.scale((Integer)value)));
if (!"true".equals(defaults.get(key +".hidpi.patched"))) {
entry.setValue(Integer.valueOf(JBUI.scale((Integer)value)));
patched.add(key);
}
}
}
}
for (String key : patched) {
defaults.put(key + ".hidpi.patched", "true");
}
}
public static void updateToolWindows() {
@@ -42,10 +42,8 @@ import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Arrays;
import java.util.*;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
/**
* @author Konstantin Bulenkov
@@ -82,7 +80,7 @@ public class DarculaLaf extends BasicLookAndFeel {
@SuppressWarnings("UnusedParameters")
private static void log(Exception e) {
// everything is gonna be alright
// e.printStackTrace();
e.printStackTrace();
}
@Override
@@ -91,6 +89,7 @@ public class DarculaLaf extends BasicLookAndFeel {
final Method superMethod = BasicLookAndFeel.class.getDeclaredMethod("getDefaults");
superMethod.setAccessible(true);
final UIDefaults metalDefaults = (UIDefaults)superMethod.invoke(new MetalLookAndFeel());
final UIDefaults defaults = (UIDefaults)superMethod.invoke(base);
if (SystemInfo.isLinux) {
if (!Registry.is("darcula.use.native.fonts.on.linux")) {
@@ -124,6 +123,9 @@ public class DarculaLaf extends BasicLookAndFeel {
if (SystemInfo.isWindows) {
//JFrame.setDefaultLookAndFeelDecorated(true);
}
if (SystemInfo.isLinux && JBUI.isHiDPI()) {
applySystemFonts(defaults);
}
defaults.put("EditorPane.font", defaults.getFont("TextField.font"));
return defaults;
}
@@ -133,6 +135,23 @@ public class DarculaLaf extends BasicLookAndFeel {
return super.getDefaults();
}
private static void applySystemFonts(UIDefaults defaults) {
try {
String fqn = UIManager.getSystemLookAndFeelClassName();
Object systemLookAndFeel = Class.forName(fqn).newInstance();
final Method superMethod = BasicLookAndFeel.class.getDeclaredMethod("getDefaults");
superMethod.setAccessible(true);
final UIDefaults systemDefaults = (UIDefaults)superMethod.invoke(systemLookAndFeel);
for (Map.Entry<Object, Object> entry : systemDefaults.entrySet()) {
if (entry.getValue() instanceof Font) {
defaults.put(entry.getKey(), entry.getValue());
}
}
} catch (Exception e) {
log(e);
}
}
protected DefaultMetalTheme createMetalTheme() {
return new DarculaMetalTheme();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -47,7 +47,7 @@ public class Splash extends JDialog implements StartupProgress {
@Nullable public static Rectangle BOUNDS;
private final Icon myImage;
private int myProgressHeight = 2;
private int myProgressHeight = JBUI.scale(2);
private Color myProgressColor = null;
private int myProgressY;
private float myProgress;
@@ -102,7 +102,7 @@ public class Splash extends JDialog implements StartupProgress {
this(info.getSplashImageUrl(), info.getSplashTextColor());
if (info instanceof ApplicationInfoImpl) {
final ApplicationInfoImpl appInfo = (ApplicationInfoImpl)info;
myProgressHeight = 2;
myProgressHeight = JBUI.scale(2);
myProgressColor = appInfo.getProgressColor();
myProgressY = appInfo.getProgressY();
myProgressTail = appInfo.getProgressTailIcon();
@@ -143,8 +143,8 @@ public class Splash extends JDialog implements StartupProgress {
g.setColor(color);
g.fillRect(1, getProgressY(), width, getProgressHeight());
if (myProgressTail != null) {
myProgressTail.paintIcon(this, g, width - (myProgressTail.getIconWidth()/2),
getProgressY() - (myProgressTail.getIconHeight() - getProgressHeight())/2);
myProgressTail.paintIcon(this, g, width - (myProgressTail.getIconWidth() / JBUI.scale(1) / 2 * JBUI.scale(1)),
getProgressY() - (myProgressTail.getIconHeight() - getProgressHeight()) / JBUI.scale(1) / 2 * JBUI.scale(1)); //I'll buy you a beer if you understand this line without playing with it
}
myProgressLastPosition = progressWidth;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -30,6 +30,8 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
@@ -63,7 +65,14 @@ public class ImageLoader implements Serializable {
public static Image loadFromUrl(@NotNull URL url) {
for (Pair<String, Integer> each : getFileNames(url.toString())) {
try {
return loadFromStream(URLUtil.openStream(new URL(each.first)), each.second);
Image image = loadFromStream(URLUtil.openStream(new URL(each.first)), each.second);
//we can't check all 3rd party plugins and convince the authors to add @2x icons.
// isHiDPI() != isRetina() => we should scale images manually
if (image != null && JBUI.isHiDPI() && !each.first.contains("@2x")) {
image = upscale(image);
}
return image;
}
catch (IOException ignore) {
}
@@ -71,6 +80,19 @@ public class ImageLoader implements Serializable {
return null;
}
@NotNull
private static Image upscale(Image image) {
float scale = JBUI.scale(1f);
int width = (int)(scale * image.getWidth(null));
int height = (int)(scale * image.getHeight(null));
@SuppressWarnings("UndesirableClassUsage")
BufferedImage tmp = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = tmp.createGraphics();
g.drawImage(image, AffineTransform.getScaleInstance(scale, scale), null);
image = tmp;
return image;
}
@Nullable
public static Image loadFromUrl(URL url, boolean dark, boolean retina) {
for (Pair<String, Integer> each : getFileNames(url.toString(), dark, retina || JBUI.isHiDPI())) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -135,4 +135,12 @@ public class SystemProperties {
public static String getJavaVendor() {
return System.getProperty("java.vendor");
}
public static boolean is(String key) {
return getBooleanProperty(key, false);
}
public static boolean has(String key) {
return System.getProperty(key) != null;
}
}
@@ -17,6 +17,7 @@ package com.intellij.util.ui;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.border.CustomLineBorder;
import com.intellij.util.SystemProperties;
import javax.swing.*;
import javax.swing.border.Border;
@@ -26,7 +27,27 @@ import java.awt.*;
* @author Konstantin Bulenkov
*/
public class JBUI {
private static boolean IS_HIDPI = !SystemInfo.isMac && ("true".equals(System.getProperty("hidpi")) || "true".equals(System.getProperty("is.hidpi")));
private static boolean IS_HIDPI = calculateHiDPI();
private static boolean calculateHiDPI() {
if (SystemInfo.isMac) {
return false;
}
if (SystemProperties.is("hidpi")) {
return true;
}
if (SystemProperties.has("hidpi") && !SystemProperties.is("hidpi")) {
return false;
}
if (SystemInfo.isWindows && getSystemDPI() > 144) {
return true;
}
return false;
}
private static int getSystemDPI() {
try {
@@ -15,7 +15,6 @@
*/
package com.siyeh.ig.style;
import com.intellij.codeInsight.javadoc.JavaDocUtil;
import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.diagnostic.Logger;
@@ -26,6 +25,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.impl.source.codeStyle.ImportHelper;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
@@ -206,11 +206,6 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection impl
if (element != null) {
return;
}
final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(reference.getProject());
PsiDocComment containingComment = PsiTreeUtil.getParentOfType(reference, PsiDocComment.class);
if (containingComment != null && acceptFullyQualifiedNamesInJavadoc(containingComment, styleSettings)) {
return;
}
final PsiFile containingFile = reference.getContainingFile();
if (!(containingFile instanceof PsiJavaFile)) {
return;
@@ -219,6 +214,11 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection impl
if (!(target instanceof PsiClass)) {
return;
}
final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(reference.getProject());
PsiDocComment containingComment = PsiTreeUtil.getParentOfType(reference, PsiDocComment.class);
if (containingComment != null && acceptFqnInJavadoc((PsiJavaFile)containingFile, reference.getQualifiedName(), styleSettings)) {
return;
}
final PsiJavaCodeReferenceElement qualifierReference = (PsiJavaCodeReferenceElement)qualifier;
final PsiElement qualifierTarget = qualifierReference.resolve();
if (!(qualifierTarget instanceof PsiPackage)) {
@@ -262,11 +262,14 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection impl
}
}
public static boolean acceptFullyQualifiedNamesInJavadoc(PsiDocComment comment, CodeStyleSettings styleSettings) {
if (JavaDocUtil.isInsidePackageInfo(comment)) {
private static boolean acceptFqnInJavadoc(PsiJavaFile javaFile, String fullyQualifiedName, CodeStyleSettings styleSettings) {
if ("package-info.java".equals(javaFile.getName())) {
return true;
}
JavaCodeStyleSettings javaSettings = styleSettings.getCustomSettings(JavaCodeStyleSettings.class);
if (javaSettings.CLASS_NAMES_IN_JAVADOC == JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED) {
return !ImportHelper.isAlreadyImported(javaFile, fullyQualifiedName);
}
return javaSettings.useFqNamesInJavadocAlways();
}
}
@@ -0,0 +1,7 @@
import java.util.HashMap;
/**
* {@link java.util.HashMap}
*/
public class DoubleQualify {
}
@@ -0,0 +1,5 @@
/**
* {@link java.util.HashMap}
*/
public class Single {
}
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>DoubleQualify.java</file>
<line>4</line>
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Unnecessary fully qualified name</problem_class>
<description>Fully qualified name &lt;code&gt;java.util.HashMap&lt;/code&gt; is unnecessary, and can be replaced with an import #loc</description>
</problem>
</problems>
@@ -10,7 +10,7 @@ public class UnnecessaryFullyQualifiedNameInspectionTest extends IGInspectionTes
private static final String BASE_DIR = "com/siyeh/igtest/style/";
public void testFqnInJavadoc_Unnecessary_WhenFullyQualifyIfNotImported() throws Exception {
doTestWithFqnInJavadocSetting(BASE_DIR + "unnecessary_fully_qualified_name/", JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED);
doTestWithFqnInJavadocSetting(BASE_DIR + "unnecessary_fqn_javadoc_fully_qualify_if_not_imported", JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED);
}
public void testFqnInJavadoc_Unnecessary_WhenShortNamesAlways() {
@@ -54,6 +54,12 @@
enabledByDefault="true"
level="WARNING"
implementationClass="com.intellij.codeInspection.capitalization.TitleCapitalizationInspection"/>
<localInspection language="Properties" shortName="SuspiciousLocalesLanguages"
groupBundle="messages.InspectionsBundle" groupKey="group.names.internationalization.issues"
displayName="Suspicious resource bundle locale languages"
enabledByDefault="true"
level="WARNING"
implementationClass="com.intellij.codeInspection.SuspiciousLocalesLanguagesInspection"/>
<intentionAction>
<className>com.intellij.codeInspection.capitalization.AnnotateCapitalizationIntention</className>
@@ -0,0 +1,237 @@
/*
* Copyright 2000-2015 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.codeInspection;
import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
import com.intellij.lang.properties.*;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.customizeActions.DissociateResourceBundleAction;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.InputValidator;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile;
import com.intellij.reference.SoftLazyValue;
import com.intellij.ui.AnActionButton;
import com.intellij.ui.AnActionButtonRunnable;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.components.JBList;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import org.jdom.Element;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;
/**
* @author Dmitry Batkovich
*/
public class SuspiciousLocalesLanguagesInspection extends BaseLocalInspectionTool {
private static final String ADDITIONAL_LANGUAGES_ATTR_NAME = "additionalLanguages";
private final static SoftLazyValue<Set<String>> JAVA_LOCALES = new SoftLazyValue<Set<String>>() {
@NotNull
@Override
protected Set<String> compute() {
final Set<String> result = new HashSet<String>();
for (Locale locale : Locale.getAvailableLocales()) {
result.add(locale.getLanguage());
}
return result;
}
};
private final List<String> myAdditionalLanguages = new ArrayList<String>();
@Nls
@NotNull
@Override
public String getDisplayName() {
return "Suspicious resource bundle locale languages";
}
@TestOnly
public void setAdditionalLanguages(List<String> additionalLanguages) {
myAdditionalLanguages.clear();
myAdditionalLanguages.addAll(additionalLanguages);
}
@Override
public void readSettings(@NotNull Element node) throws InvalidDataException {
final String rawLanguages = node.getAttributeValue(ADDITIONAL_LANGUAGES_ATTR_NAME);
if (rawLanguages != null) {
myAdditionalLanguages.clear();
myAdditionalLanguages.addAll(StringUtil.split(rawLanguages, ","));
}
}
@Override
public void writeSettings(@NotNull Element node) throws WriteExternalException {
if (!myAdditionalLanguages.isEmpty()) {
final ArrayList<String> uniqueLanguages = ContainerUtil.newArrayList(ContainerUtil.newHashSet(myAdditionalLanguages));
Collections.sort(uniqueLanguages);
final String locales = StringUtil.join(uniqueLanguages, ",");
node.setAttribute(ADDITIONAL_LANGUAGES_ATTR_NAME, locales);
}
}
@Nullable
@Override
public JComponent createOptionsPanel() {
return new MyOptions().getComponent();
}
@Nullable
@Override
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
final PropertiesFile propertiesFile = PropertiesImplUtil.getPropertiesFile(file);
if (propertiesFile == null) {
return null;
}
final ResourceBundle resourceBundle = propertiesFile.getResourceBundle();
final List<PropertiesFile> files = resourceBundle.getPropertiesFiles();
if (!(resourceBundle instanceof ResourceBundleImpl) || files.size() < 2) {
return null;
}
List<Locale> bundleLocales = ContainerUtil.mapNotNull(files, new Function<PropertiesFile, Locale>() {
@Override
public Locale fun(PropertiesFile propertiesFile) {
final Locale locale = propertiesFile.getLocale();
return locale == ResourceBundleManager.DEFAULT_LOCALE ? null : locale;
}
});
bundleLocales = ContainerUtil.filter(bundleLocales, new Condition<Locale>() {
@Override
public boolean value(Locale locale) {
return !JAVA_LOCALES.getValue().contains(locale.getLanguage()) && !myAdditionalLanguages.contains(locale.getLanguage());
}
});
if (bundleLocales.isEmpty()) {
return null;
}
final ProblemDescriptor descriptor = manager.createProblemDescriptor(file,
PropertiesBundle.message(
"resource.bundle.contains.locales.with.suspicious.locale.languages.desciptor"),
new DissociateResourceBundleQuickFix(resourceBundle),
ProblemHighlightType.WEAK_WARNING,
true);
return new ProblemDescriptor[] {descriptor};
}
private static class DissociateResourceBundleQuickFix implements LocalQuickFix {
private final ResourceBundle myResourceBundle;
private DissociateResourceBundleQuickFix(ResourceBundle bundle) {
myResourceBundle = bundle;
}
@Nls
@NotNull
@Override
public String getName() {
return getFamilyName();
}
@NotNull
@Override
public String getFamilyName() {
return PropertiesBundle.message("dissociate.resource.bundle.quick.fix.name");
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
DissociateResourceBundleAction.dissociate(Collections.singleton(myResourceBundle), project);
}
}
private class MyOptions {
private JBList myAdditionalLocalesList;
public MyOptions() {
myAdditionalLocalesList = new JBList(new MyListModel());
myAdditionalLocalesList.setCellRenderer(new DefaultListCellRenderer());
}
public JPanel getComponent() {
final JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel(PropertiesBundle.message("dissociate.resource.bundle.quick.fix.options.label")), BorderLayout.NORTH);
panel.add(
ToolbarDecorator.createDecorator(myAdditionalLocalesList)
.setAddAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
Messages.showInputDialog(panel, PropertiesBundle.message("dissociate.resource.bundle.quick.fix.options.input.text"),
PropertiesBundle.message("dissociate.resource.bundle.quick.fix.options.input.title"), null, "", new InputValidator() {
@Override
public boolean checkInput(String inputString) {
return 1 < inputString.length() && inputString.length() < 9 && !myAdditionalLanguages.contains(inputString);
}
@Override
public boolean canClose(String inputString) {
if (inputString != null) {
myAdditionalLanguages.add(inputString);
((MyListModel)myAdditionalLocalesList.getModel()).fireContentsChanged();
}
return true;
}
});
}
})
.setRemoveAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
final int index = myAdditionalLocalesList.getSelectedIndex();
if (index > -1 && index < myAdditionalLanguages.size()) {
myAdditionalLanguages.remove(index);
((MyListModel)myAdditionalLocalesList.getModel()).fireContentsChanged();
}
}
})
.setPreferredSize(new Dimension(-1, 100))
.disableUpDownActions()
.createPanel(),
BorderLayout.CENTER);
return panel;
}
private class MyListModel extends AbstractListModel {
@Override
public int getSize() {
return myAdditionalLanguages.size();
}
@Override
public Object getElementAt(int index) {
return myAdditionalLanguages.get(index);
}
public void fireContentsChanged() {
fireContentsChanged(myAdditionalLanguages, -1, -1);
}
}
}
}
@@ -0,0 +1 @@
<weak_warning descr="Resource bundle contains locales with suspicious locale languages"></weak_warning>
@@ -0,0 +1 @@
<weak_warning descr="Resource bundle contains locales with suspicious locale languages"></weak_warning>
@@ -0,0 +1,55 @@
/*
* Copyright 2000-2015 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.codeInspection;
import com.intellij.openapi.application.PluginPathManager;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.util.containers.ContainerUtil;
import java.io.File;
/**
* @author Dmitry Batkovich
*/
public class SuspiciousLanguagesInspectionTest extends LightCodeInsightFixtureTestCase {
@Override
protected String getBasePath() {
return PluginPathManager.getPluginHomePathRelative("java-i18n") + "/testData/inspections/suspiciousLanguages";
}
public void testSimple1() {
doTest("p.properties", "p_en.properties");
}
public void testSimple2() {
doTest("p.properties", "p_asd.properties");
}
public void testWithAdditionalLocales() {
doTest("p.properties", "p_asd.properties", "asd");
}
private void doTest(final String file1, final String file2, final String... additionalLocales) {
myFixture.configureByFile(getTestName(true) + "/" + file1);
myFixture.configureByFile(getTestName(true) + "/" + file2);
final SuspiciousLocalesLanguagesInspection inspection = new SuspiciousLocalesLanguagesInspection();
if (additionalLocales.length != 0) {
inspection.setAdditionalLanguages(ContainerUtil.newArrayList(additionalLocales));
}
myFixture.enableInspections(inspection);
myFixture.checkHighlighting();
}
}
@@ -60,3 +60,9 @@ inline.property.confirmation=Inline property ''{0}'' with value ''{1}''?
alpha.unsorted.properties.file.inspection.display.name=Properties File or Resource Bundle is Alphabetically Unsorted
trailing.spaces.in.property.inspection.ignore.visible.spaces=Ignore visible whitespaces
resource.bundle.contains.locales.with.suspicious.locale.languages.desciptor=Resource bundle contains locales with suspicious locale languages
dissociate.resource.bundle.quick.fix.name=Dissociate Resource Bundle
dissociate.resource.bundle.quick.fix.options.label=Additional language codes\:
dissociate.resource.bundle.quick.fix.options.input.text=Inter language code
dissociate.resource.bundle.quick.fix.options.input.title=Additional Locale Languages
@@ -47,7 +47,7 @@ import java.util.regex.Matcher;
})
public class ResourceBundleManager implements PersistentStateComponent<ResourceBundleManagerState> {
private final static Logger LOG = Logger.getInstance(ResourceBundleManager.class);
private final static Locale DEFAULT_LOCALE = new Locale("", "", "");
public final static Locale DEFAULT_LOCALE = new Locale("", "", "");
private ResourceBundleManagerState myState = new ResourceBundleManagerState();
@@ -172,7 +172,11 @@ public class ResourceBundleManager implements PersistentStateComponent<ResourceB
name = name.substring(customResourceBundleName.length());
}
final Matcher matcher = PropertiesUtil.LOCALE_PATTERN.matcher(name);
return extractLocale(name);
}
public static Locale extractLocale(final String suffix) {
final Matcher matcher = PropertiesUtil.LOCALE_PATTERN.matcher(suffix);
if (matcher.find()) {
final String rawLocale = matcher.group(1);
final String[] splittedRawLocale = rawLocale.split("_");
@@ -17,6 +17,7 @@ package com.intellij.lang.properties.customizeActions;
import com.intellij.icons.AllIcons;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.lang.properties.PropertiesImplUtil;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.ResourceBundleManager;
@@ -27,12 +28,15 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.*;
/**
@@ -54,15 +58,7 @@ public class DissociateResourceBundleAction extends AnAction {
}
final Collection<ResourceBundle> resourceBundles = extractResourceBundles(e);
assert resourceBundles.size() > 0;
final FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
for (ResourceBundle resourceBundle : resourceBundles) {
fileEditorManager.closeFile(new ResourceBundleAsVirtualFile(resourceBundle));
for (final PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
fileEditorManager.closeFile(propertiesFile.getVirtualFile());
}
ResourceBundleManager.getInstance(e.getProject()).dissociateResourceBundle(resourceBundle);
}
ProjectView.getInstance(project).refresh();
dissociate(resourceBundles, project);
}
@Override
@@ -79,6 +75,26 @@ public class DissociateResourceBundleAction extends AnAction {
}
}
public static void dissociate(final Collection<ResourceBundle> resourceBundles, final Project project) {
final FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
final Set<PsiFileSystemItem> toUpdateInProjectView = new HashSet<PsiFileSystemItem>();
for (ResourceBundle resourceBundle : resourceBundles) {
fileEditorManager.closeFile(new ResourceBundleAsVirtualFile(resourceBundle));
for (final PropertiesFile propertiesFile : resourceBundle.getPropertiesFiles()) {
fileEditorManager.closeFile(propertiesFile.getVirtualFile());
PsiDirectory containingDirectory = propertiesFile.getContainingFile().getContainingDirectory();
if (containingDirectory != null) {
toUpdateInProjectView.add(containingDirectory);
}
}
ResourceBundleManager.getInstance(project).dissociateResourceBundle(resourceBundle);
}
AbstractTreeBuilder treeBuilder = ProjectView.getInstance(project).getCurrentProjectViewPane().getTreeBuilder();
for (PsiFileSystemItem item : toUpdateInProjectView) {
treeBuilder.queueUpdateFrom(item, false);
}
}
@NotNull
private static Collection<ResourceBundle> extractResourceBundles(final AnActionEvent event) {
final Set<ResourceBundle> targetResourceBundles = new HashSet<ResourceBundle>();
@@ -32,6 +32,7 @@ import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
@@ -97,4 +98,12 @@ public class ResourceBundleNode extends ProjectViewNode<ResourceBundle>{
public Comparable getTypeSortKey() {
return new PsiFileNode.ExtensionSortKey(StdFileTypes.PROPERTIES.getDefaultExtension());
}
@Override
public boolean validate() {
if (!super.validate()) {
return false;
}
return Comparing.equal(getValue().getDefaultPropertiesFile().getResourceBundle(), getValue());
}
}
@@ -488,7 +488,7 @@ public class RemoteDebugger implements ProcessDebugger {
private StringBuilder myTextBuilder = new StringBuilder();
private DebuggerReader(final InputStream stream) throws IOException {
super(stream, CharsetToolkit.UTF8_CHARSET); //TODO: correct encoding?
super(stream, CharsetToolkit.UTF8_CHARSET, SleepingPolicy.BLOCKING); //TODO: correct encoding?
start();
}
@@ -0,0 +1,5 @@
<html>
<body>
Inspection detects locales which contain language codes not supported by Java.
</body>
</html>