Merge remote-tracking branch 'origin/master'
authorEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Fri, 17 Jan 2014 12:04:41 +0000 (16:04 +0400)
committerEkaterina Tuzova <Ekaterina.Tuzova@jetbrains.com>
Fri, 17 Jan 2014 12:04:41 +0000 (16:04 +0400)
69 files changed:
platform/analysis-api/src/com/intellij/codeHighlighting/HighlightDisplayLevel.java
platform/analysis-api/src/com/intellij/lang/annotation/HighlightSeverity.java
platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/SeverityRegistrar.java
platform/analysis-impl/src/com/intellij/codeInspection/ex/InspectionProfileImpl.java
platform/analysis-impl/src/com/intellij/codeInspection/ex/ToolsImpl.java
platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
platform/core-impl/src/com/intellij/psi/impl/source/CharTableImpl.java
platform/icons/src/modules/types/javaModule.png
platform/icons/src/modules/types/javaModule@2x.png
platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/SeverityUtil.java
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/TrafficProgressPanel.java
platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateManagerImpl.java
platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java
platform/lang-impl/src/com/intellij/codeInspection/ex/SeverityEditorDialog.java
platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java
platform/lang-impl/src/com/intellij/profile/codeInspection/ui/SingleInspectionProfilePanel.java
platform/platform-api/src/com/intellij/util/net/CertificatesManager.java
platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java
platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java
platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyFileSystem.java
platform/platform-impl/src/com/intellij/openapi/vfs/impl/http/VirtualFileImpl.java
platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java
platform/platform-resources-en/src/tips/ShowHideSideBars.html
platform/smRunner/src/com/intellij/execution/testframework/sm/runner/states/TestIgnoredState.java
platform/smRunner/testSrc/com/intellij/execution/testframework/sm/runner/SMTRunnerConsoleTest.java
platform/testFramework/src/com/intellij/testFramework/ExpectedHighlightingData.java
platform/util/src/com/intellij/openapi/diagnostic/LogUtil.java
platform/util/src/com/intellij/util/text/CharSequenceHashingStrategy.java
plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java
plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java
plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
plugins/tasks/tasks-core/src/com/intellij/tasks/gitlab/GitlabRepository.java
plugins/tasks/tasks-core/src/com/intellij/tasks/httpclient/NewBaseRepositoryImpl.java
plugins/tasks/tasks-core/src/com/intellij/tasks/impl/TaskUtil.java
plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRepository.java
plugins/tasks/tasks-core/src/com/intellij/tasks/jira/JiraRestApi.java
plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/api2/JiraRestApi2.java
plugins/tasks/tasks-core/src/com/intellij/tasks/jira/model/api20alpha1/JiraRestApi20Alpha1.java
plugins/tasks/tasks-core/src/com/intellij/tasks/youtrack/YouTrackRepository.java
python/resources/inspectionDescriptions/PyAssignmentToForLoopParameterInspection.html [new file with mode: 0644]
python/src/META-INF/python-core.xml
python/src/com/jetbrains/python/PyBundle.properties
python/src/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspection.java [new file with mode: 0644]
python/testData/inspections/PyAssignmentToForLoopParameterInspection/good.py [new file with mode: 0644]
python/testData/inspections/PyAssignmentToForLoopParameterInspection/simpleReassignment.py [new file with mode: 0644]
python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleAssignment.py [new file with mode: 0644]
python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleDeclaration.py [new file with mode: 0644]
python/testData/inspections/PyAssignmentToForLoopParameterInspection/twoLoops.py [new file with mode: 0644]
python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java [new file with mode: 0644]
python/testSrc/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspectionTest.java [new file with mode: 0644]
spellchecker/src/com/intellij/spellchecker/SpellCheckerSeveritiesProvider.java
updater/src/com/intellij/updater/BaseUpdateAction.java
updater/src/com/intellij/updater/CreateAction.java
updater/src/com/intellij/updater/Digester.java
updater/src/com/intellij/updater/PatchAction.java
updater/src/com/intellij/updater/PatchFileCreator.java
updater/src/com/intellij/updater/Runner.java
updater/src/com/intellij/updater/UpdateAction.java
updater/src/com/intellij/updater/UpdateZipAction.java
updater/src/com/intellij/updater/Utils.java
updater/src/com/intellij/updater/ZipOutputWrapper.java
xml/impl/src/com/intellij/html/impl/Html5CustomAttributeDescriptorsProvider.java

index f8cd9d74097e18e0526822e24050cfadf55c69f7..492aa7872064656a7349fa71b5cec7c9cd3a464e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -56,7 +56,7 @@ public class HighlightDisplayLevel {
     for (Map.Entry<HighlightSeverity, HighlightDisplayLevel> entry : ourMap.entrySet()) {
       HighlightSeverity severity = entry.getKey();
       HighlightDisplayLevel displayLevel = entry.getValue();
-      if (Comparing.strEqual(severity.toString(), name)) {
+      if (Comparing.strEqual(severity.getName(), name)) {
         return displayLevel;
       }
     }
@@ -82,6 +82,11 @@ public class HighlightDisplayLevel {
     return mySeverity.toString();
   }
 
+  @NotNull
+  public String getName() {
+    return mySeverity.getName();
+  }
+
   public Icon getIcon() {
     return myIcon;
   }
index ef19e0f17d43d6c3484664de982a9fe866ef7085..eb375d23dea451a93601718a540079a0020e5c6f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -76,7 +76,7 @@ public class HighlightSeverity implements Comparable<HighlightSeverity> {
    *             if two annotations with different severity levels cover the same text range, only
    *             the annotation with a higher severity level is displayed.
    */
-  public HighlightSeverity(@NonNls String name, int val) {
+  public HighlightSeverity(@NonNls @NotNull String name, int val) {
     myName = name;
     myVal = val;
   }
@@ -84,8 +84,7 @@ public class HighlightSeverity implements Comparable<HighlightSeverity> {
 
   //read external only
   public HighlightSeverity(@NotNull Element element) {
-    myName = JDOMExternalizerUtil.readField(element, "myName");
-    myVal = Integer.valueOf(JDOMExternalizerUtil.readField(element, "myVal"));
+    this(JDOMExternalizerUtil.readField(element, "myName"), Integer.valueOf(JDOMExternalizerUtil.readField(element, "myVal")));
   }
 
   public String toString() {
@@ -113,4 +112,9 @@ public class HighlightSeverity implements Comparable<HighlightSeverity> {
   public int hashCode() {
     return myName.hashCode();
   }
+
+  @NotNull
+  public String getName() {
+    return myName;
+  }
 }
index e5c719b70860fb0c9fda774bbbdb1c5abe276dfa..3e0213cdf631f8a5ea3a8d8f5c8a4aa699160f8f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -27,8 +27,9 @@ import com.intellij.openapi.util.JDOMExternalizableStringList;
 import com.intellij.openapi.util.WriteExternalException;
 import com.intellij.profile.codeInspection.InspectionProfileManager;
 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
+import com.intellij.util.concurrency.AtomicFieldUpdater;
+import com.intellij.util.containers.ConcurrentHashMap;
 import com.intellij.util.containers.ContainerUtil;
-import gnu.trove.THashMap;
 import gnu.trove.TObjectIntHashMap;
 import gnu.trove.TObjectIntProcedure;
 import org.jdom.Element;
@@ -48,13 +49,13 @@ import java.util.List;
 public class SeverityRegistrar implements JDOMExternalizable, Comparator<HighlightSeverity> {
   @NonNls private static final String INFO_TAG = "info";
   @NonNls private static final String COLOR_ATTRIBUTE = "color";
-  private final Map<String, SeverityBasedTextAttributes> myMap = new THashMap<String, SeverityBasedTextAttributes>();
-  private final Map<String, Color> myRendererColors = new THashMap<String, Color>();
+  private final Map<String, SeverityBasedTextAttributes> myMap = new ConcurrentHashMap<String, SeverityBasedTextAttributes>();
+  private final Map<String, Color> myRendererColors = new ConcurrentHashMap<String, Color>();
 
-  private final OrderMap myOrder = new OrderMap();
+  private volatile OrderMap myOrderMap;
   private JDOMExternalizableStringList myReadOrder;
 
-  private static final Map<String, HighlightInfoType> STANDARD_SEVERITIES = new THashMap<String, HighlightInfoType>();
+  private static final Map<String, HighlightInfoType> STANDARD_SEVERITIES = new ConcurrentHashMap<String, HighlightInfoType>();
 
   public SeverityRegistrar() {
   }
@@ -68,7 +69,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
   }
 
   public static void registerStandard(@NotNull HighlightInfoType highlightInfoType, @NotNull HighlightSeverity highlightSeverity) {
-    STANDARD_SEVERITIES.put(highlightSeverity.toString(), highlightInfoType);
+    STANDARD_SEVERITIES.put(highlightSeverity.getName(), highlightInfoType);
   }
 
   @NotNull
@@ -78,22 +79,21 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
            : InspectionProjectProfileManager.getInstance(project).getSeverityRegistrar();
   }
 
-  public void registerSeverity(@NotNull SeverityBasedTextAttributes info, Color renderColor){
+  public void registerSeverity(@NotNull SeverityBasedTextAttributes info, Color renderColor) {
     final HighlightSeverity severity = info.getType().getSeverity(null);
-    myMap.put(severity.toString(), info);
-    myRendererColors.put(severity.toString(), renderColor);
-    myOrder.clear();
+    myMap.put(severity.getName(), info);
+    myRendererColors.put(severity.getName(), renderColor);
+    myOrderMap = null;
     HighlightDisplayLevel.registerSeverity(severity, renderColor);
   }
 
-
   public SeverityBasedTextAttributes unregisterSeverity(@NotNull HighlightSeverity severity){
-    return myMap.remove(severity.toString());
+    return myMap.remove(severity.getName());
   }
 
   @NotNull
   public HighlightInfoType.HighlightInfoTypeImpl getHighlightInfoTypeBySeverity(@NotNull HighlightSeverity severity) {
-    HighlightInfoType infoType = STANDARD_SEVERITIES.get(severity.toString());
+    HighlightInfoType infoType = STANDARD_SEVERITIES.get(severity.getName());
     if (infoType != null) {
       return (HighlightInfoType.HighlightInfoTypeImpl)infoType;
     }
@@ -102,13 +102,17 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
       return (HighlightInfoType.HighlightInfoTypeImpl)HighlightInfoType.INFORMATION;
     }
 
-    final SeverityBasedTextAttributes type = myMap.get(severity.toString());
-    return (HighlightInfoType.HighlightInfoTypeImpl)(type != null ? type.getType() : HighlightInfoType.WARNING);
+    final SeverityBasedTextAttributes type = getAttributesBySeverity(severity);
+    return (HighlightInfoType.HighlightInfoTypeImpl)(type == null ? HighlightInfoType.WARNING : type.getType());
+  }
+
+  private SeverityBasedTextAttributes getAttributesBySeverity(@NotNull HighlightSeverity severity) {
+    return myMap.get(severity.getName());
   }
 
   @Nullable
   public TextAttributes getTextAttributesBySeverity(@NotNull HighlightSeverity severity) {
-    final SeverityBasedTextAttributes infoType = myMap.get(severity.toString());
+    final SeverityBasedTextAttributes infoType = getAttributesBySeverity(severity);
     if (infoType != null) {
       return infoType.getAttributes();
     }
@@ -133,56 +137,59 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
       }
       registerSeverity(highlightInfo, color);
     }
-    myOrder.clear();
-
     myReadOrder = new JDOMExternalizableStringList();
     myReadOrder.readExternal(element);
+
+    OrderMap orderMap = new OrderMap(myReadOrder.size());
     for (int i = 0; i < myReadOrder.size(); i++) {
       String name = myReadOrder.get(i);
       HighlightSeverity severity = getSeverity(name);
       if (severity == null) continue;
-      myOrder.put(severity, i);
+      orderMap.put(severity, i);
     }
     final List<HighlightSeverity> knownSeverities = getDefaultOrder();
-    myOrder.retainEntries(new TObjectIntProcedure<HighlightSeverity>() {
+    orderMap.retainEntries(new TObjectIntProcedure<HighlightSeverity>() {
       @Override
       public boolean execute(HighlightSeverity severity, int order) {
         return knownSeverities.contains(severity);
       }
     });
 
-    if (myOrder.isEmpty()) {
-      setFromList(knownSeverities);
+    if (orderMap.isEmpty()) {
+      orderMap = fromList(knownSeverities);
     }
-    //enforce include all known
-    List<HighlightSeverity> list = getOrderAsList();
-    for (int i = 0; i < knownSeverities.size(); i++) {
-      HighlightSeverity stdSeverity = knownSeverities.get(i);
-      if (!list.contains(stdSeverity)) {
-        for (int oIdx = 0; oIdx < list.size(); oIdx++) {
-          HighlightSeverity orderSeverity = list.get(oIdx);
-          HighlightInfoType type = STANDARD_SEVERITIES.get(orderSeverity.toString());
-          if (type != null && knownSeverities.indexOf(type.getSeverity(null)) > i) {
-            list.add(oIdx, stdSeverity);
-            myReadOrder = null;
-            break;
+    else {
+      //enforce include all known
+      List<HighlightSeverity> list = getOrderAsList(orderMap);
+      for (int i = 0; i < knownSeverities.size(); i++) {
+        HighlightSeverity stdSeverity = knownSeverities.get(i);
+        if (!list.contains(stdSeverity)) {
+          for (int oIdx = 0; oIdx < list.size(); oIdx++) {
+            HighlightSeverity orderSeverity = list.get(oIdx);
+            HighlightInfoType type = STANDARD_SEVERITIES.get(orderSeverity.getName());
+            if (type != null && knownSeverities.indexOf(type.getSeverity(null)) > i) {
+              list.add(oIdx, stdSeverity);
+              myReadOrder = null;
+              break;
+            }
           }
         }
       }
+      orderMap = fromList(list);
     }
-    setFromList(list);
+    myOrderMap = orderMap;
   }
 
   @Override
   public void writeExternal(Element element) throws WriteExternalException {
-    List<HighlightSeverity> list = getOrderAsList();
-    for (HighlightSeverity s : list) {
+    List<HighlightSeverity> list = getOrderAsList(getOrderMap());
+    for (HighlightSeverity severity : list) {
       Element info = new Element(INFO_TAG);
-      String severity = s.toString();
-      final SeverityBasedTextAttributes infoType = myMap.get(severity);
+      String severityName = severity.getName();
+      final SeverityBasedTextAttributes infoType = getAttributesBySeverity(severity);
       if (infoType != null) {
         infoType.writeExternal(info);
-        final Color color = myRendererColors.get(severity);
+        final Color color = myRendererColors.get(severityName);
         if (color != null) {
           info.setAttribute(COLOR_ATTRIBUTE, Integer.toString(color.getRGB() & 0xFFFFFF, 16));
         }
@@ -194,11 +201,11 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
       myReadOrder.writeExternal(element);
     }
     else if (!getDefaultOrder().equals(list)) {
-      final JDOMExternalizableStringList ext = new JDOMExternalizableStringList(Collections.nCopies(myOrder.size(), ""));
-      myOrder.forEachEntry(new TObjectIntProcedure<HighlightSeverity>() {
+      final JDOMExternalizableStringList ext = new JDOMExternalizableStringList(Collections.nCopies(getOrderMap().size(), ""));
+      getOrderMap().forEachEntry(new TObjectIntProcedure<HighlightSeverity>() {
         @Override
         public boolean execute(HighlightSeverity orderSeverity, int oIdx) {
-          ext.set(oIdx, orderSeverity.toString());
+          ext.set(oIdx, orderSeverity.getName());
           return true;
         }
       });
@@ -207,9 +214,9 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
   }
 
   @NotNull
-  private List<HighlightSeverity> getOrderAsList() {
+  private List<HighlightSeverity> getOrderAsList(@NotNull OrderMap orderMap) {
     List<HighlightSeverity> list = new ArrayList<HighlightSeverity>();
-    for (Object o : getOrder().keys()) {
+    for (Object o : orderMap.keys()) {
       list.add((HighlightSeverity)o);
     }
     Collections.sort(list, this);
@@ -217,12 +224,12 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
   }
 
   public int getSeveritiesCount() {
-    return createCurrentSeverities().size();
+    return createCurrentSeverityNames().size();
   }
 
   public HighlightSeverity getSeverityByIndex(final int i) {
     final HighlightSeverity[] found = new HighlightSeverity[1];
-    getOrder().forEachEntry(new TObjectIntProcedure<HighlightSeverity>() {
+    getOrderMap().forEachEntry(new TObjectIntProcedure<HighlightSeverity>() {
       @Override
       public boolean execute(HighlightSeverity severity, int order) {
         if (order == i) {
@@ -236,7 +243,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
   }
 
   public int getSeverityMaxIndex() {
-    int[] values = getOrder().getValues();
+    int[] values = getOrderMap().getValues();
     int max = values[0];
     for(int i = 1; i < values.length; ++i) if (values[i] > max) max = values[i];
 
@@ -253,7 +260,7 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
   }
 
   @NotNull
-  private List<String> createCurrentSeverities() {
+  private List<String> createCurrentSeverityNames() {
     List<String> list = new ArrayList<String>();
     list.addAll(STANDARD_SEVERITIES.keySet());
     list.addAll(myMap.keySet());
@@ -268,37 +275,50 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
       return level.getIcon();
     }
 
-    return HighlightDisplayLevel.createIconByMask(myRendererColors.get(severity.toString()));
+    return HighlightDisplayLevel.createIconByMask(myRendererColors.get(severity.getName()));
   }
 
-  public boolean isSeverityValid(@NotNull String severity) {
-    return createCurrentSeverities().contains(severity);
+  public boolean isSeverityValid(@NotNull String severityName) {
+    return createCurrentSeverityNames().contains(severityName);
   }
 
   @Override
   public int compare(final HighlightSeverity s1, final HighlightSeverity s2) {
-    OrderMap order = getOrder();
-    int o1 = order.getOrder(s1, -1);
-    int o2 = order.getOrder(s2, -1);
+    OrderMap orderMap = getOrderMap();
+    int o1 = orderMap.getOrder(s1, -1);
+    int o2 = orderMap.getOrder(s2, -1);
     return o1 - o2;
   }
 
 
   @NotNull
-  private OrderMap getOrder() {
-    if (myOrder.isEmpty()) {
-      List<HighlightSeverity> order = getDefaultOrder();
-      setFromList(order);
+  private OrderMap getOrderMap() {
+    OrderMap orderMap;
+    OrderMap defaultOrder = null;
+    while ((orderMap = myOrderMap) == null) {
+      if (defaultOrder == null) {
+        defaultOrder = fromList(getDefaultOrder());
+      }
+      boolean replaced = ORDER_MAP_UPDATER.compareAndSet(this, null, defaultOrder);
+      if (replaced) {
+        orderMap = defaultOrder;
+        break;
+      }
     }
-    return myOrder;
+    return orderMap;
   }
 
-  private void setFromList(@NotNull List<HighlightSeverity> order) {
-    myOrder.clear();
-    for (int i = 0; i < order.size(); i++) {
-      HighlightSeverity severity = order.get(i);
-      myOrder.put(severity, i);
+  private static final AtomicFieldUpdater<SeverityRegistrar, OrderMap> ORDER_MAP_UPDATER = AtomicFieldUpdater.forFieldOfType(SeverityRegistrar.class, OrderMap.class);
+
+  @NotNull
+  private static OrderMap fromList(@NotNull List<HighlightSeverity> orderList) {
+    OrderMap orderMap = new OrderMap(orderList.size());
+    for (int i = 0; i < orderList.size(); i++) {
+      HighlightSeverity severity = orderList.get(i);
+      orderMap.put(severity, i);
     }
+    orderMap.trimToSize();
+    return orderMap;
   }
 
   @NotNull
@@ -315,13 +335,13 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
     return order;
   }
 
-  public void setOrder(@NotNull List<HighlightSeverity> order) {
-    setFromList(order);
+  public void setOrder(@NotNull List<HighlightSeverity> orderList) {
+    myOrderMap = fromList(orderList);
     myReadOrder = null;
   }
 
   public int getSeverityIdx(@NotNull HighlightSeverity severity) {
-    return getOrder().getOrder(severity, -1);
+    return getOrderMap().getOrder(severity, -1);
   }
 
   public boolean isDefaultSeverity(@NotNull HighlightSeverity severity) {
@@ -336,6 +356,10 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
   }
 
   private static class OrderMap extends TObjectIntHashMap<HighlightSeverity> {
+    private OrderMap(int initialCapacity) {
+      super(initialCapacity);
+    }
+
     private int getOrder(@NotNull HighlightSeverity severity, int defaultOrder) {
       int index = index(severity);
       return index < 0 ? defaultOrder : _values[index];
@@ -348,24 +372,25 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
 
     //read external
     public SeverityBasedTextAttributes(@NotNull Element element) throws InvalidDataException {
-      myAttributes = new TextAttributes(element);
-      myType = new HighlightInfoType.HighlightInfoTypeImpl(element);
+      this(new TextAttributes(element), new HighlightInfoType.HighlightInfoTypeImpl(element));
     }
 
-    public SeverityBasedTextAttributes(final TextAttributes attributes, final HighlightInfoType.HighlightInfoTypeImpl type) {
+    public SeverityBasedTextAttributes(@NotNull TextAttributes attributes, @NotNull HighlightInfoType.HighlightInfoTypeImpl type) {
       myAttributes = attributes;
       myType = type;
     }
 
+    @NotNull
     public TextAttributes getAttributes() {
       return myAttributes;
     }
 
+    @NotNull
     public HighlightInfoType.HighlightInfoTypeImpl getType() {
       return myType;
     }
 
-    private void writeExternal(Element element) throws WriteExternalException {
+    private void writeExternal(@NotNull Element element) throws WriteExternalException {
       myAttributes.writeExternal(element);
       myType.writeExternal(element);
     }
@@ -381,15 +406,15 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
 
       final SeverityBasedTextAttributes that = (SeverityBasedTextAttributes)o;
 
-      if (myAttributes != null ? !myAttributes.equals(that.myAttributes) : that.myAttributes != null) return false;
-      if (myType != null ? !myType.equals(that.myType) : that.myType != null) return false;
+      if (!myAttributes.equals(that.myAttributes)) return false;
+      if (!myType.equals(that.myType)) return false;
 
       return true;
     }
 
     public int hashCode() {
-      int result = myAttributes != null ? myAttributes.hashCode() : 0;
-      result = 31 * result + (myType != null ? myType.hashCode() : 0);
+      int result = myAttributes.hashCode();
+      result = 31 * result + myType.hashCode();
       return result;
     }
   }
@@ -402,5 +427,4 @@ public class SeverityRegistrar implements JDOMExternalizable, Comparator<Highlig
   Collection<HighlightInfoType> standardSeverities() {
     return STANDARD_SEVERITIES.values();
   }
-
 }
index b8c786952fde1a2ce70a515276340b565d8070ef..e37a348a4d547d99ae23069f6025f1d8e681f8c4 100644 (file)
@@ -213,7 +213,7 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
     Project project = element == null ? null : element.getProject();
     final ToolsImpl tools = getTools(inspectionToolKey.toString(), project);
     HighlightDisplayLevel level = tools != null ? tools.getLevel(element) : HighlightDisplayLevel.WARNING;
-    if (!((SeverityProvider)getProfileManager()).getOwnSeverityRegistrar().isSeverityValid(level.getSeverity().toString())) {
+    if (!((SeverityProvider)getProfileManager()).getOwnSeverityRegistrar().isSeverityValid(level.getSeverity().getName())) {
       level = HighlightDisplayLevel.WARNING;
       setErrorLevel(inspectionToolKey, level, project);
     }
index f8d215ceee24f52a2a45f87ac1756c242a8a9155..b86ff683daa298515d0e525abac72300916d9bbd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -142,7 +142,7 @@ public class ToolsImpl implements Tools {
       for (ScopeToolState state : myTools) {
         final Element scopeElement = new Element("scope");
         scopeElement.setAttribute("name", state.getScopeName());
-        scopeElement.setAttribute(LEVEL_ATTRIBUTE, state.getLevel().toString());
+        scopeElement.setAttribute(LEVEL_ATTRIBUTE, state.getLevel().getName());
         scopeElement.setAttribute(ENABLED_ATTRIBUTE, Boolean.toString(state.isEnabled()));
         InspectionToolWrapper toolWrapper = state.getTool();
         if (toolWrapper.isInitialized()) {
@@ -152,7 +152,7 @@ public class ToolsImpl implements Tools {
       }
     }
     inspectionElement.setAttribute(ENABLED_ATTRIBUTE, Boolean.toString(isEnabled()));
-    inspectionElement.setAttribute(LEVEL_ATTRIBUTE, getLevel().toString());
+    inspectionElement.setAttribute(LEVEL_ATTRIBUTE, getLevel().getName());
     inspectionElement.setAttribute(ENABLED_BY_DEFAULT_ATTRIBUTE, Boolean.toString(myDefaultState.isEnabled()));
     InspectionToolWrapper toolWrapper = myDefaultState.getTool();
     if (toolWrapper.isInitialized()) {
index 2616941566dd5d680e98bf8b6e665d820547eddf..51fdaea6f1ac8da57deed8843cd15e81dc25e8aa 100644 (file)
@@ -65,7 +65,7 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
   private volatile SoftReference<String> myTextString;
 
   private boolean myIsReadOnly = false;
-  private boolean isStripTrailingSpacesEnabled = true;
+  private volatile boolean isStripTrailingSpacesEnabled = true;
   private volatile long myModificationStamp;
   private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this);
 
index 4ee8df9d024ae6ce8050ad1d70d154372db85ede..179d344711ae514ddea76069b76f466cc9d1ecdf 100644 (file)
@@ -34,7 +34,7 @@ import java.lang.reflect.Modifier;
  */
 public class CharTableImpl implements CharTable {
   private static final int INTERN_THRESHOLD = 40; // 40 or more characters long tokens won't be interned.
-  private static final CharSequenceHashingStrategy HASHER = new CharSequenceHashingStrategy();
+  private static final CharSequenceHashingStrategy HASHER = CharSequenceHashingStrategy.CASE_SENSITIVE;
   private static final OpenTHashSet<CharSequence> STATIC_ENTRIES = newStaticSet();
 
   private final OpenTHashSet<CharSequence> entries = new OpenTHashSet<CharSequence>(10, 0.9f, HASHER);
index ffd12819cdfef63caa9f046392bbbc20b7b7012d..5a040c86a354577005f9d48f03e11a5a6b59a434 100644 (file)
Binary files a/platform/icons/src/modules/types/javaModule.png and b/platform/icons/src/modules/types/javaModule.png differ
index 25962f60e0be24f3e7ef5841b02605bb7b69a18e..3cdbe09fb7ad80540da8d9ecb9defb3dd5893b02 100644 (file)
Binary files a/platform/icons/src/modules/types/javaModule@2x.png and b/platform/icons/src/modules/types/javaModule@2x.png differ
index 79434f98cdf00d4e3f03e97aa27d2f11338909ea..b91ac03f53c1b4453393532129605b68b98bce89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -463,7 +463,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
         }
       };
       boolean success = processFilesWithText(scope, searchContext, caseSensitively, text, processor);
-      LOG.assertTrue(success);
+      // success == false means exception in index
     }
     finally {
       myManager.finishBatchFilesProcessingMode();
index 04c4b63b50843e984828302c998350d7dec756e2..1cb4441d20b235c04e7af76e6bb9eec3d548c5bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -142,7 +142,10 @@ public class PsiUtilBase extends PsiUtilCore {
   }
 
   @Nullable
-  public static Language reallyEvaluateLanguageInRange(final int start, final int end, final PsiFile file) {
+  public static Language reallyEvaluateLanguageInRange(final int start, final int end, @NotNull PsiFile file) {
+    if (file instanceof PsiBinaryFile) {
+      return file.getLanguage();
+    }
     Language lang = null;
     int curOffset = start;
     do {
@@ -170,7 +173,7 @@ public class PsiUtilBase extends PsiUtilCore {
   }
 
   @Nullable
-  public static Language evaluateLanguageInRange(final int start, final int end, final PsiFile file) {
+  public static Language evaluateLanguageInRange(final int start, final int end, @NotNull PsiFile file) {
     PsiElement elt = getElementAtOffset(file, start);
 
     TextRange selectionRange = new TextRange(start, end);
index de2e3532159032fe8eb7c961472805439a67fbd9..e4181e1be28cd6cf224724d01ff027bbf19b8130 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -38,6 +38,7 @@ public class SeverityUtil {
     if (textAttributes != null) {
       return new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes, (HighlightInfoType.HighlightInfoTypeImpl)type);
     }
-    return new SeverityRegistrar.SeverityBasedTextAttributes(registrar.getTextAttributesBySeverity(type.getSeverity(null)), (HighlightInfoType.HighlightInfoTypeImpl)type);
+    TextAttributes severity = registrar.getTextAttributesBySeverity(type.getSeverity(null));
+    return new SeverityRegistrar.SeverityBasedTextAttributes(severity, (HighlightInfoType.HighlightInfoTypeImpl)type);
   }
 }
index 0b221e059da9462bca047531d321013a42e110bb..19a958a8bd712c1ed727eb7ac22492ed91763f1e 100644 (file)
@@ -229,7 +229,7 @@ public class TrafficProgressPanel extends JPanel {
         if (status.errorCount[i] > 0) {
           final HighlightSeverity severity = SeverityRegistrar.getSeverityRegistrar(myTrafficLightRenderer.getProject()).getSeverityByIndex(i);
           String name =
-            status.errorCount[i] > 1 ? StringUtil.pluralize(severity.toString().toLowerCase()) : severity.toString().toLowerCase();
+            status.errorCount[i] > 1 ? StringUtil.pluralize(severity.getName().toLowerCase()) : severity.getName().toLowerCase();
           text += status.errorAnalyzingFinished
                   ? DaemonBundle.message("errors.found", status.errorCount[i], name)
                   : DaemonBundle.message("errors.found.so.far", status.errorCount[i], name);
index b5bbc1720689e5d5be9fce9d4485584becb82b13..00346e1e6cd7cab470a4d1f17623a1a45963bda7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -123,7 +123,7 @@ public class BraceHighlightingHandler {
           public void run() {
             final PsiFile injected;
             try {
-              injected = psiFile == null || psiFile instanceof PsiCompiledElement || isReallyDisposed(editor, project)
+              injected = psiFile == null || psiFile instanceof PsiCompiledElement || psiFile instanceof PsiBinaryFile || isReallyDisposed(editor, project)
                      ? null : getInjectedFileIfAny(editor, project, offset, psiFile, alarm);
             }
             catch (RuntimeException e) {
index 41cfbad7323ecf889562a2b34a870744a2742243..05ecfadee46d2c0b227186fe59c9c399f99f0f74 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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,11 +80,11 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
         Editor editor = event.getEditor();
         if (editor.getProject() != null && editor.getProject() != myProject) return;
         if (myProject.isDisposed() || !myProject.isOpen()) return;
-        TemplateState tState = getTemplateState(editor);
-        if (tState != null) {
-          tState.gotoEnd();
+        TemplateState state = getTemplateState(editor);
+        if (state != null) {
+          state.gotoEnd();
         }
-        editor.putUserData(TEMPLATE_STATE_KEY, null);
+        clearTemplateState(editor);
       }
     };
     EditorFactory.getInstance().addEditorFactoryListener(myEditorFactoryListener, myProject);
@@ -108,8 +108,8 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
     });
   }
 
-  private static void disposeState(final TemplateState tState) {
-    Disposer.dispose(tState);
+  private static void disposeState(@NotNull TemplateState state) {
+    Disposer.dispose(state);
   }
 
   @Override
@@ -123,11 +123,11 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
   }
 
   @Nullable
-  public static TemplateState getTemplateState(Editor editor) {
+  public static TemplateState getTemplateState(@NotNull Editor editor) {
     return editor.getUserData(TEMPLATE_STATE_KEY);
   }
 
-  void clearTemplateState(final Editor editor) {
+  static void clearTemplateState(@NotNull Editor editor) {
     TemplateState prevState = getTemplateState(editor);
     if (prevState != null) {
       disposeState(prevState);
@@ -135,7 +135,7 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
     editor.putUserData(TEMPLATE_STATE_KEY, null);
   }
 
-  private TemplateState initTemplateState(final Editor editor) {
+  private TemplateState initTemplateState(@NotNull Editor editor) {
     clearTemplateState(editor);
     TemplateState state = new TemplateState(myProject, editor);
     Disposer.register(this, state);
@@ -379,7 +379,7 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
     final Document document = editor.getDocument();
     final CharSequence text = document.getCharsSequence();
 
-    if (template2argument == null || template2argument.size() == 0) {
+    if (template2argument == null || template2argument.isEmpty()) {
       return null;
     }
     if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), myProject)) {
@@ -407,14 +407,13 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
                                                          @Nullable Character shortcutChar,
                                                          TemplateSettings settings,
                                                          boolean hasArgument) {
-    String key;
     List<TemplateImpl> candidates = Collections.emptyList();
     for (int i = settings.getMaxKeyLength(); i >= 1; i--) {
       int wordStart = caretOffset - i;
       if (wordStart < 0) {
         continue;
       }
-      key = text.subSequence(wordStart, caretOffset).toString();
+      String key = text.subSequence(wordStart, caretOffset).toString();
       if (Character.isJavaIdentifierStart(key.charAt(0))) {
         if (wordStart > 0 && Character.isJavaIdentifierPart(text.charAt(wordStart - 1))) {
           continue;
@@ -519,7 +518,7 @@ public class TemplateManagerImpl extends TemplateManager implements ProjectCompo
     final TemplateContextType[] typeCollection = getAllContextTypes();
     LinkedList<TemplateContextType> userDefinedExtensionsFirst = new LinkedList<TemplateContextType>();
     for (TemplateContextType contextType : typeCollection) {
-      if (contextType.getClass().getName().startsWith("com.intellij.codeInsight.template")) {
+      if (contextType.getClass().getName().startsWith(Template.class.getPackage().getName())) {
         userDefinedExtensionsFirst.addLast(contextType);
       }
       else {
index 2bcf02b50abc275d124bab7ce5056906584650ba..1ce2e351b3edf7472c25f4d8829b5377585a1358 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -93,6 +93,7 @@ public class TemplateState implements Disposable {
   private boolean myFinished;
   @Nullable private PairProcessor<String, String> myProcessor;
   private boolean mySelectionCalculated = false;
+  private boolean myStarted;
 
   public TemplateState(@NotNull Project project, final Editor editor) {
     myProject = project;
@@ -134,32 +135,27 @@ public class TemplateState implements Disposable {
           final LookupImpl lookup = myEditor != null ? (LookupImpl)LookupManager.getActiveLookup(myEditor) : null;
           if (lookup != null) {
             lookup.performGuardedChange(runnable);
-          } else {
+          }
+          else {
             runnable.run();
           }
         }
       }
     };
 
-    myDocument.addDocumentListener(myEditorDocumentListener);
-    CommandProcessor.getInstance().addCommandListener(myCommandListener);
+    myDocument.addDocumentListener(myEditorDocumentListener, this);
+    CommandProcessor.getInstance().addCommandListener(myCommandListener, this);
   }
 
   @Override
   public synchronized void dispose() {
-    if (myEditorDocumentListener != null) {
-      myDocument.removeDocumentListener(myEditorDocumentListener);
-      myEditorDocumentListener = null;
-    }
-    if (myCommandListener != null) {
-      CommandProcessor.getInstance().removeCommandListener(myCommandListener);
-      myCommandListener = null;
-    }
+    myEditorDocumentListener = null;
+    myCommandListener = null;
 
     myProcessor = null;
 
     //Avoid the leak of the editor
-    releaseEditor();
+    releaseAll();
     myDocument = null;
   }
 
@@ -176,7 +172,7 @@ public class TemplateState implements Disposable {
 
   private void setCurrentVariableNumber(int variableNumber) {
     myCurrentVariableNumber = variableNumber;
-    final boolean isFinished = variableNumber < 0;
+    final boolean isFinished = isFinished();
     ((DocumentEx)myDocument).setStripTrailingSpacesEnabled(isFinished);
     myCurrentSegmentNumber = isFinished ? -1 : getCurrentSegmentNumber();
   }
@@ -262,9 +258,11 @@ public class TemplateState implements Disposable {
     }
   }
 
-  public void start(TemplateImpl template,
+  public void start(@NotNull TemplateImpl template,
                     @Nullable final PairProcessor<String, String> processor,
                     @Nullable Map<String, String> predefinedVarValues) {
+    LOG.assertTrue(!myStarted, "Already started");
+    myStarted = true;
     myTemplate = template;
     PsiDocumentManager.getInstance(myProject).commitAllDocuments();
 
@@ -328,7 +326,7 @@ public class TemplateState implements Disposable {
     }
   }
 
-  private void processAllExpressions(final TemplateImpl template) {
+  private void processAllExpressions(@NotNull final TemplateImpl template) {
     ApplicationManager.getApplication().runWriteAction(new Runnable() {
       @Override
       public void run() {
@@ -365,7 +363,7 @@ public class TemplateState implements Disposable {
     });
   }
 
-  public void doReformat(final TextRange range) {
+  private void doReformat(final TextRange range) {
     RangeMarker rangeMarker = null;
     if (range != null) {
       rangeMarker = myDocument.createRangeMarker(range);
@@ -876,14 +874,20 @@ public class TemplateState implements Disposable {
     }
   }
 
+  boolean isDisposed() {
+    return myDocument == null;
+  }
+
   private void cleanupTemplateState(boolean brokenOff) {
     final Editor editor = myEditor;
     fireBeforeTemplateFinished();
     int oldVar = myCurrentVariableNumber;
-    setCurrentVariableNumber(-1);
     currentVariableChanged(oldVar);
-    ((TemplateManagerImpl)TemplateManager.getInstance(myProject)).clearTemplateState(editor);
-    fireTemplateFinished(brokenOff);
+    if (!isDisposed()) {
+      setCurrentVariableNumber(-1);
+      TemplateManagerImpl.clearTemplateState(editor);
+      fireTemplateFinished(brokenOff);
+    }
     myListeners.clear();
     myProject = null;
   }
index ec2974082ac7ec367bbabc20fc528fbab34ab915..b5333e8bd63ea341c4833b2bc983c992676b2ca8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +29,6 @@ import com.intellij.lang.annotation.HighlightSeverity;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
 import com.intellij.openapi.actionSystem.DataContext;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.colors.CodeInsightColors;
 import com.intellij.openapi.editor.colors.EditorColorsScheme;
@@ -86,7 +85,7 @@ public class SeverityEditorDialog extends DialogWrapper {
       public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
         final Component rendererComponent = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
         if (value instanceof SeverityBasedTextAttributes) {
-          setText(((SeverityBasedTextAttributes)value).getSeverity().toString());
+          setText(((SeverityBasedTextAttributes)value).getSeverity().getName());
         }
         return rendererComponent;
       }
index ed196a32d77e440194430481d8a090c7ca975af6..5dffdf756cac67fe26f77b36cc738af36ef23218 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -97,7 +97,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
     public int compare(HighlightDisplayLevel o1, HighlightDisplayLevel o2) {
       final int severityDiff = o1.getSeverity().compareTo(o2.getSeverity());
       if (severityDiff == 0) {
-        return o1.toString().compareTo(o2.toString());
+        return o1.getName().compareTo(o2.getName());
       }
       return severityDiff;
     }
index b512f43b247acebc3de01b412d885c856dd2d15c..8b980cfd49765348aacdd4f8f6cc09b4f9c87edc 100644 (file)
@@ -610,7 +610,7 @@ public class SingleInspectionProfilePanel extends JPanel {
   }
 
   static String renderSeverity(HighlightSeverity severity) {
-    return StringUtil.capitalizeWords(severity.toString().toLowerCase(), true);
+    return StringUtil.capitalizeWords(severity.getName().toLowerCase(), true);
   }
 
   private void toggleToolNode(final InspectionConfigTreeNode toolNode) {
@@ -1007,7 +1007,7 @@ public class SingleInspectionProfilePanel extends JPanel {
     final Set<HighlightSeverity> severities = ((InspectionProfileImpl)selectedProfile).getUsedSeverities();
     for (Iterator<HighlightSeverity> iterator = severities.iterator(); iterator.hasNext();) {
       HighlightSeverity severity = iterator.next();
-      if (registrar.isSeverityValid(severity.toString())) {
+      if (registrar.isSeverityValid(severity.getName())) {
         iterator.remove();
       }
     }
@@ -1015,9 +1015,9 @@ public class SingleInspectionProfilePanel extends JPanel {
     if (!severities.isEmpty()) {
       final SeverityRegistrar oppositeRegister = ((SeverityProvider)selectedProfile.getProfileManager()).getSeverityRegistrar();
       for (HighlightSeverity severity : severities) {
-        final TextAttributesKey attributesKey = TextAttributesKey.find(severity.toString());
+        final TextAttributesKey attributesKey = TextAttributesKey.find(severity.getName());
         final TextAttributes textAttributes = oppositeRegister.getTextAttributesBySeverity(severity);
-        LOG.assertTrue(textAttributes != null, severity.toString());
+        LOG.assertTrue(textAttributes != null, severity);
         HighlightInfoType.HighlightInfoTypeImpl info = new HighlightInfoType.HighlightInfoTypeImpl(severity, attributesKey);
         registrar.registerSeverity(new SeverityRegistrar.SeverityBasedTextAttributes(textAttributes.clone(), info),
                                    textAttributes.getErrorStripeColor());
index 16cd2c2a5fe14d55ffffb6c5751235eee3640aba..06efd50b7d7743145d3b37e1b4323245c6fb31a8 100644 (file)
@@ -139,6 +139,10 @@ public class CertificatesManager implements ApplicationComponent {
     factory.init((KeyStore)null);
     // assume that only X509 TrustManagers exist
     X509TrustManager systemManager = findX509TrustManager(factory.getTrustManagers());
+    assert systemManager != null;
+
+    // can also check, that default trust store exists, on this step
+    //assert systemManager.getAcceptedIssuers().length != 0
 
     MutableX509TrustManager customManager = new MutableX509TrustManager(myCacertsPath, myPassword);
     MyX509TrustManager trustManager = new MyX509TrustManager(systemManager, customManager);
@@ -192,7 +196,15 @@ public class CertificatesManager implements ApplicationComponent {
       try {
         mySystemManager.checkServerTrusted(certificates, s);
       }
-      catch (CertificateException e1) {
+      catch (RuntimeException e) {
+        Throwable cause = e.getCause();
+        // this can happen on some version of Apple's JRE, e.g. see IDEA-115565
+        if (cause != null && cause.getMessage().equals("the trustAnchors parameter must be non-empty")) {
+          LOG.error("It seems, that your JRE installation doesn't have system trust store.\n" +
+                    "If you're using Mac JRE, try upgrading to the latest version.", e);
+        }
+      }
+      catch (CertificateException e) {
         X509Certificate certificate = certificates[0];
         // looks like self-signed certificate
         if (certificates.length == 1) {
@@ -203,7 +215,7 @@ public class CertificatesManager implements ApplicationComponent {
             }
             catch (CertificateException e2) {
               if (myCustomManager.isBroken() || !updateTrustStore(certificate)) {
-                throw e1;
+                throw e;
               }
             }
           }
index a060fa84bfb4d39b27081ab80826561b9c83bdf0..fb2808ea887b759757f8e8299a01a8d6111d11da 100644 (file)
@@ -613,6 +613,12 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
                 ? new MyDialogWrapper(myParentWindow, myShouldShowCancel)
                 : new MyDialogWrapper(myProject, myShouldShowCancel);
       myPopup.setUndecorated(true);
+      if (SystemInfo.isAppleJvm) {
+        // With Apple JDK we look for MacMessage parent by the window title.
+        // As far as progress windows are undecorated we set the window
+        // component name as a title to keep it unique.
+        myPopup.setTitle(myPopup.getWindow().getName());
+      }
       if (myPopup.getPeer() instanceof DialogWrapperPeerImpl) {
         ((DialogWrapperPeerImpl)myPopup.getPeer()).setAutoRequestFocus(false);
       }
index 516480781c80b5f964c834e6e23fbb3f114d9ab8..a071640c960912b2bcbed2609b790c8e56b0dc26 100644 (file)
@@ -168,7 +168,7 @@ public abstract class DummyCachingFileSystem<T extends VirtualFile> extends Dumm
     }
   }
 
-  protected void beforeFileRename(VirtualFile file, Object requestor, String oldName, String newName) {
+  protected void beforeFileRename(@NotNull VirtualFile file, Object requestor, @NotNull String oldName, @NotNull String newName) {
     fireBeforePropertyChange(requestor, file, VirtualFile.PROP_NAME, oldName, newName);
     myCachedFiles.remove(file.getPath());
   }
index 1c182d30aaad7acd285b2b5fbbf2d7292e59f4d1..ee751e6f18c8ac5a05ea04e6b60d3676af9648b9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -118,7 +118,7 @@ public class DummyFileSystem extends DeprecatedVirtualFileSystem implements NonP
 
   @Override
   public VirtualFile createChildFile(Object requestor, @NotNull VirtualFile vDir, @NotNull String fileName) throws IOException {
-    final VirtualFileDirectoryImpl dir = ((VirtualFileDirectoryImpl)vDir);
+    final VirtualFileDirectoryImpl dir = (VirtualFileDirectoryImpl)vDir;
     VirtualFileImpl child = new VirtualFileDataImpl(this, dir, fileName);
     dir.addChild(child);
     fireFileCreated(requestor, child);
@@ -138,7 +138,7 @@ public class DummyFileSystem extends DeprecatedVirtualFileSystem implements NonP
   @Override
   @NotNull
   public VirtualFile createChildDirectory(Object requestor, @NotNull VirtualFile vDir, @NotNull String dirName) throws IOException {
-    final VirtualFileDirectoryImpl dir = ((VirtualFileDirectoryImpl)vDir);
+    final VirtualFileDirectoryImpl dir = (VirtualFileDirectoryImpl)vDir;
     VirtualFileImpl child = new VirtualFileDirectoryImpl(this, dir, dirName);
     dir.addChild(child);
     fireFileCreated(requestor, child);
index 8262224e3485ff2b9e7591f47a19228009378276..82fd22cd03f7483d9bacda6265f740cb18a11ec7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,13 +35,13 @@ import java.util.Collections;
 
 class VirtualFileImpl extends HttpVirtualFile {
   private final HttpFileSystemBase myFileSystem;
-  private final @Nullable RemoteFileInfoImpl myFileInfo;
+  @Nullable private final RemoteFileInfoImpl myFileInfo;
   private FileType myInitialFileType;
   private final String myPath;
   private final String myParentPath;
   private final String myName;
 
-  VirtualFileImpl(HttpFileSystemBase fileSystem, String path, final @Nullable RemoteFileInfoImpl fileInfo) {
+  VirtualFileImpl(HttpFileSystemBase fileSystem, String path, @Nullable final RemoteFileInfoImpl fileInfo) {
     myFileSystem = fileSystem;
     myPath = path;
     myFileInfo = fileInfo;
index 40cf3d19d080e5713c477ace9d60eb8e10d1f23e..c9c0579146ce90ba96660f7043885a7d5e07c78e 100644 (file)
@@ -456,7 +456,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone
   }
 
   @Override
-  public void renameFile(final Object requestor, @NotNull final VirtualFile file, @NotNull final String newName) throws IOException {
+  public void renameFile(final Object requestor, @NotNull VirtualFile file, @NotNull String newName) throws IOException {
     getDelegate(file).renameFile(requestor, file, newName);
     processEvent(new VFilePropertyChangeEvent(requestor, file, VirtualFile.PROP_NAME, file.getName(), newName, false));
   }
index 8da87796a798e5ae1d0adeece0bdb972f92c93cb..ed0d28659827d8ed9a9c320049000811703e99fe 100644 (file)
Binary files a/platform/platform-resources-en/src/tips/ShowHideSideBars.html and b/platform/platform-resources-en/src/tips/ShowHideSideBars.html differ
index 38a4d94e1789746465737fb2754050adea706b7a..f2363a236b46844dfcb6f4e2935a973c3e3217fb 100644 (file)
@@ -69,10 +69,7 @@ public class TestIgnoredState extends AbstractState {
     if (myText != null) {
       printer.print(myText, ConsoleViewContentType.SYSTEM_OUTPUT);
     }
-    if (StringUtil.isEmptyOrSpaces(myStacktrace)) {
-      printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.SYSTEM_OUTPUT);
-    }
-    else {
+    if (!StringUtil.isEmptyOrSpaces(myStacktrace)) {
       printer.print(CompositePrintable.NEW_LINE, ConsoleViewContentType.ERROR_OUTPUT);
       printer.mark();
       printer.print(myStacktrace, ConsoleViewContentType.ERROR_OUTPUT);
index 4593c6f467773a29ae4f8e56edbb073561b853c6..4e85c6cc384d14fe2b70b0fb8151691e1d24aafc 100644 (file)
@@ -394,7 +394,7 @@ public class SMTRunnerConsoleTest extends BaseSMTRunnerTestCase {
     myEventsProcessor.onTestOutput(new TestOutputEvent("my_test", "stdout1 ", true));
     myEventsProcessor.onTestOutput(new TestOutputEvent("my_test", "stderr1 ", false));
 
-    assertAllOutputs(myMockResettablePrinter, "stdout1 ", "stderr1 ", "\nignored msg\n");
+    assertAllOutputs(myMockResettablePrinter, "stdout1 ", "stderr1 ", "\nignored msg");
 
     final MockPrinter mockPrinter1 = new MockPrinter(true);
     mockPrinter1.onNewAvailable(myTest1);
index ffa6de7fba90323c68be38f1412d66c8155a6e30..93de7cc42f88b17057cda941204187befdad35cd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -138,7 +138,7 @@ public class ExpectedHighlightingData {
         for (SeveritiesProvider provider : Extensions.getExtensions(SeveritiesProvider.EP_NAME)) {
           for (HighlightInfoType type : provider.getSeveritiesHighlightInfoTypes()) {
             final HighlightSeverity severity = type.getSeverity(null);
-            highlightingTypes.put(severity.toString(), new ExpectedHighlightingSet(severity, false, true));
+            highlightingTypes.put(severity.getName(), new ExpectedHighlightingSet(severity, false, true));
           }
         }
         highlightingTypes.put(END_LINE_HIGHLIGHT_MARKER, new ExpectedHighlightingSet(HighlightSeverity.ERROR, true, true));
index 69f7585613d96cc769170b69d8be397f50e20463..55441aeb4a7fdf4c90bdca843b486d1894e3f345 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.diagnostic;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.util.ExceptionUtil;
+import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -33,7 +34,7 @@ public class LogUtil {
   /**
    * Format string syntax as in {@linkplain String#format(String, Object...)}.
    */
-  public static void debug(@NotNull Logger logger, @NotNull String format, @Nullable Object... args) {
+  public static void debug(@NotNull Logger logger, @NonNls @NotNull String format, @Nullable Object... args) {
     if (logger.isDebugEnabled()) {
       logger.debug(String.format(format, args));
     }
index 9933b2abe0ef6eb249841dc14b75a18881f284fb..b19f6cd0aa265542106d35a06713f2dcc1ef8cc6 100644 (file)
@@ -15,6 +15,7 @@
  */
 package com.intellij.util.text;
 
+import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.text.StringUtil;
 import gnu.trove.TObjectHashingStrategy;
 
@@ -22,27 +23,26 @@ import gnu.trove.TObjectHashingStrategy;
  * @author max
  */
 public final class CharSequenceHashingStrategy implements TObjectHashingStrategy<CharSequence> {
-  private static final int COMPARISON_THRESHOLD = 5;
+  public static final CharSequenceHashingStrategy CASE_SENSITIVE = new CharSequenceHashingStrategy(true);
+  public static final CharSequenceHashingStrategy CASE_INSENSITIVE = new CharSequenceHashingStrategy(false);
+  private final boolean myCaseSensitive;
+
+  @Deprecated
+  public CharSequenceHashingStrategy() {
+    this(true);
+  }
+
+  private CharSequenceHashingStrategy(boolean caseSensitive) {
+    myCaseSensitive = caseSensitive;
+  }
 
   @Override
   public int computeHashCode(final CharSequence chars) {
-    return StringUtil.stringHashCode(chars);
+    return myCaseSensitive ? StringUtil.stringHashCode(chars) : StringUtil.stringHashCodeInsensitive(chars);
   }
 
   @Override
   public boolean equals(final CharSequence s1, final CharSequence s2) {
-    if(s1 == null || s2 == null) return false;
-    if(s1 == s2) return true;
-    int len = s1.length();
-    if (len != s2.length()) return false;
-
-    if (len > COMPARISON_THRESHOLD && s1 instanceof String && s2 instanceof String) {
-      return s1.equals(s2);
-    }
-
-    for (int i = 0; i < len; i++) {
-      if (s1.charAt(i) != s2.charAt(i)) return false;
-    }
-    return true;
+    return Comparing.equal(s1, s2, myCaseSensitive);
   }
 }
index d427796e7a52ec9c3986ae7ef0d2e9348b0bef8f..cc8cce768f9a04a5e1fd9f448553a6acfc90d72d 100644 (file)
@@ -658,14 +658,16 @@ public class GitCheckinEnvironment implements CheckinEnvironment {
     protected String getLastCommitMessage(@NotNull VirtualFile root) throws VcsException {
       GitSimpleHandler h = new GitSimpleHandler(myProject, root, GitCommand.LOG);
       h.addParameters("--max-count=1");
+      String formatPattern;
       if (GitVersionSpecialty.STARTED_USING_RAW_BODY_IN_FORMAT.existsIn(myVcs.getVersion())) {
-        h.addParameters("--pretty=%B");
+        formatPattern = "%B";
       }
       else {
         // only message: subject + body; "%-b" means that preceding line-feeds will be deleted if the body is empty
         // %s strips newlines from subject; there is no way to work around it before 1.7.2 with %B (unless parsing some fixed format)
-        h.addParameters("--pretty=%s%n%n%-b");
+        formatPattern = "%s%n%n%-b";
       }
+      h.addParameters("--pretty=format:" + formatPattern);
       return h.run();
     }
 
index 3c4c47c18e56a1698a39fef56cb9434d27d07907..86340adf0ea73cbb9afd5857ac5f0269eadb822c 100644 (file)
@@ -58,7 +58,7 @@ public class MavenModuleResourceConfiguration {
   public Set<String> filteringExclusions = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
 
   @OptionTag
-  public String escapeString = MavenProjectConfiguration.DEFAULT_ESCAPE_STRING;
+  public String escapeString = null;
 
   @OptionTag
   public boolean escapeWindowsPaths = true;
index 209583b6f7312ac9d30aa068c8c0ade46bafa2ec..d5eb4a69d7f76977c888eaea4e74415969dc6dcc 100644 (file)
@@ -167,7 +167,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
         Set<String> nonFilteredExtensions = collectNonFilteredExtensions(mavenProject);
         String escapeString = MavenJDOMUtil.findChildValueByPath(mavenProject.getPluginConfiguration("org.apache.maven.plugins",
                                                                                                      "maven-resources-plugin"),
-                                                                 "escapeString", "\\");
+                                                                 "escapeString", null);
 
         List<MyProcessingItem> moduleItemsToProcess = new ArrayList<MyProcessingItem>();
         collectProcessingItems(eachModule, mavenProject, context, properties, propertiesHashCode,
@@ -245,7 +245,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
                                              Properties properties,
                                              long propertiesHashCode,
                                              Set<String> nonFilteredExtensions,
-                                             String escapeString,
+                                             @Nullable String escapeString,
                                              boolean tests,
                                              List<MyProcessingItem> result) {
     String outputDir = CompilerPaths.getModuleOutputPath(module, tests);
@@ -305,7 +305,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
                                              final Properties properties,
                                              final long propertiesHashCode,
                                              final Set<String> nonFilteredExtensions,
-                                             final String escapeString,
+                                             @Nullable final String escapeString,
                                              final List<MyProcessingItem> result,
                                              final ProgressIndicator indicator) {
     VfsUtilCore.visitChildrenRecursively(currentDir, new VirtualFileVisitor() {
@@ -476,7 +476,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
                             boolean isFiltered,
                             Properties properties,
                             long propertiesHashCode,
-                            String escapeString) {
+                            @Nullable String escapeString) {
       myModule = module;
       mySourceFile = sourceFile;
       myOutputPath = outputPath;
@@ -507,6 +507,7 @@ public class MavenResourceCompiler implements ClassPostProcessingCompiler {
       return myProperties;
     }
 
+    @Nullable
     public String getEscapeString() {
       return myEscapeString;
     }
index 979e182bad25553b7a47a94015ae6ddf51a20ae7..66875895f2785b0f2b59f9328d28bda20e0820b2 100644 (file)
@@ -47,7 +47,7 @@ public class MavenPropertyResolver {
   public static void doFilterText(Module module,
                                   String text,
                                   Properties additionalProperties,
-                                  String propertyEscapeString,
+                                  @Nullable String propertyEscapeString,
                                   Appendable out) throws IOException {
     MavenProjectsManager manager = MavenProjectsManager.getInstance(module.getProject());
     MavenProject mavenProject = manager.findProject(module);
index 523d5cbec95890ca3de2a31b950b002e77058b62..c2b0aa9ba49bc975aea6750773f3b1fabea9ea84 100644 (file)
@@ -129,7 +129,7 @@ public class MavenResourceCompilerConfigurationGenerator {
       }
 
       Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin");
-      resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString", "\\");
+      resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString", null);
       String escapeWindowsPaths = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeWindowsPaths");
       if (escapeWindowsPaths != null) {
         resourceConfig.escapeWindowsPaths = Boolean.parseBoolean(escapeWindowsPaths);
index 4c2c7815e5ff54bf7aad7832986e113b2e08cb5d..efd72477bf8310152c982cbd2acbbcefe32b0cf6 100644 (file)
@@ -887,6 +887,15 @@ public abstract class ResourceFilteringTest extends MavenImportingTestCase {
                   "      <filtering>true</filtering>" +
                   "    </resource>" +
                   "  </resources>" +
+                  "  <plugins>" +
+                  "    <plugin>" +
+                  "      <groupId>org.apache.maven.plugins</groupId>" +
+                  "      <artifactId>maven-resources-plugin</artifactId>" +
+                  "      <configuration>" +
+                  "        <escapeString>\\</escapeString>" +
+                  "      </configuration>" +
+                  "    </plugin>" +
+                  "  </plugins>" +
                   "</build>");
 
     compileModules("project");
index 9256b3543f11ce0bda7fa250e54976754aa0f94e..b8b52b114f5ea48ad3097010a0f7903b4e8867db 100644 (file)
@@ -217,7 +217,7 @@ public abstract class TaskRepository {
     return "{id} (e.g. FOO-001), {summary}, {number} (e.g. 001), {project} (e.g. FOO)";
   }
 
-  public void updateTimeSpent(final LocalTask task, final String timeSpent, final String comment) throws Exception {
+  public void updateTimeSpent(@NotNull LocalTask task, @NotNull String timeSpent, @NotNull String comment) throws Exception {
     throw new UnsupportedOperationException();
   }
 
index 2d0978462228d063f1a92f673d34d18303128d3b..7a07878de709eb1d27ed947e81835feee1a81cbf 100644 (file)
@@ -134,7 +134,7 @@ public class GitlabRepository extends NewBaseRepositoryImpl {
 
   @NotNull
   List<GitlabProject> fetchProjects() throws Exception {
-    HttpGet request = new HttpGet(getRestApiBaseUrl() + "projects");
+    HttpGet request = new HttpGet(getRestApiUrl("projects"));
     ResponseHandler<List<GitlabProject>> handler = new GsonMultipleObjectsDeserializer<GitlabProject>(GSON, LIST_OF_PROJECTS_TYPE);
     return getHttpClient().execute(request, handler);
   }
@@ -142,7 +142,7 @@ public class GitlabRepository extends NewBaseRepositoryImpl {
   @SuppressWarnings("UnusedDeclaration")
   @NotNull
   GitlabProject fetchProject(int id) throws Exception {
-    HttpGet request = new HttpGet(getRestApiBaseUrl() + "project/" + id);
+    HttpGet request = new HttpGet(getRestApiUrl("project", id));
     return getHttpClient().execute(request, new GsonSingleObjectDeserializer<GitlabProject>(GSON, GitlabProject.class));
   }
 
@@ -154,14 +154,14 @@ public class GitlabRepository extends NewBaseRepositoryImpl {
 
   private String getIssuesUrl() {
     if (myCurrentProject != null && myCurrentProject != UNSPECIFIED_PROJECT) {
-      return getRestApiBaseUrl() + "projects/" + myCurrentProject.getId() + "/issues";
+      return getRestApiUrl("projects", myCurrentProject.getId(), "issues");
     }
-    return getRestApiBaseUrl() + "issues";
+    return getRestApiUrl("issues");
   }
 
   @NotNull
   GitlabIssue fetchIssue(int id) throws Exception {
-    HttpGet request = new HttpGet(getRestApiBaseUrl() + "issues/" + id);
+    HttpGet request = new HttpGet(getRestApiUrl("issues", id));
     ResponseHandler<GitlabIssue> handler = new GsonSingleObjectDeserializer<GitlabIssue>(GSON, GitlabIssue.class);
     return getHttpClient().execute(request, handler);
   }
@@ -171,8 +171,10 @@ public class GitlabRepository extends NewBaseRepositoryImpl {
     return super.isConfigured() && !myPassword.isEmpty();
   }
 
-  private String getRestApiBaseUrl() {
-    return getUrl() + REST_API_PATH_PREFIX;
+  @NotNull
+  @Override
+  public String getRestApiPathPrefix() {
+    return REST_API_PATH_PREFIX;
   }
 
   @Nullable
index 38739e50917de3d0b30bdb2a9e42d67a22e77078..45aff814d20001e7c4c57263eae12f5be2c0d1fe 100644 (file)
@@ -4,6 +4,7 @@ import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.tasks.TaskRepositoryType;
 import com.intellij.tasks.config.TaskSettings;
 import com.intellij.tasks.impl.BaseRepository;
+import com.intellij.tasks.impl.TaskUtil;
 import com.intellij.util.net.CertificatesManager;
 import com.intellij.util.net.HttpConfigurable;
 import org.apache.http.HttpHost;
@@ -49,7 +50,7 @@ public abstract class NewBaseRepositoryImpl extends BaseRepository {
     HttpClientBuilder builder = HttpClients.custom()
       .setDefaultRequestConfig(createRequestConfig())
       .setSslcontext(CertificatesManager.getInstance().getSslContext())
-      // TODO: use custom one for additional certificate check
+        // TODO: use custom one for additional certificate check
       .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
       .setDefaultCredentialsProvider(createCredentialsProvider());
     HttpRequestInterceptor interceptor = createRequestInterceptor();
@@ -98,4 +99,40 @@ public abstract class NewBaseRepositoryImpl extends BaseRepository {
     }
     return builder.build();
   }
+
+  /**
+   * Return server's REST API path prefix, e.g. {@code /rest/api/latest} for JIRA or {@code /api/v3/} for Gitlab.
+   * This value will be used in {@link #getRestApiUrl(Object...)}
+   *
+   * @return server's REST API path prefix
+   */
+  @NotNull
+  public String getRestApiPathPrefix() {
+    return "";
+  }
+
+  /**
+   * Build URL using {@link #getUrl()}, {@link #getRestApiPathPrefix()}} and specified path components.
+   * <p/>
+   * Individual path components will should not contain leading or trailing slashes. Empty or null components
+   * will be omitted. Each components is converted to string using its {@link Object#toString()} method and url encoded, so
+   * numeric IDs can be used as well. Returned URL doesn't contain trailing '/', because it's not compatible with some services.
+   *
+   * @return described URL
+   */
+  @NotNull
+  public String getRestApiUrl(@NotNull Object... parts) {
+    StringBuilder builder = new StringBuilder(getUrl());
+    builder.append(getRestApiPathPrefix());
+    if (builder.charAt(builder.length() - 1) == '/') {
+      builder.deleteCharAt(builder.length() - 1);
+    }
+    for (Object part : parts) {
+      if (part == null || part.equals("")) {
+        continue;
+      }
+      builder.append('/').append(TaskUtil.encodeUrl(String.valueOf(part)));
+    }
+    return builder.toString();
+  }
 }
index 7e6ac533e464a28893cd18fe0a53d56a50a1c20a..87dbd625095345e488603e76b63691a4dd419783 100644 (file)
@@ -21,6 +21,7 @@ import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.JDOMUtil;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
 import com.intellij.tasks.Task;
 import com.intellij.tasks.TaskRepository;
 import org.jdom.Element;
@@ -28,7 +29,9 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.lang.reflect.Type;
+import java.net.URLEncoder;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Arrays;
@@ -220,4 +223,19 @@ public class TaskUtil {
   public static GsonBuilder installDateDeserializer(GsonBuilder builder) {
     return builder.registerTypeAdapter(Date.class, DATE_DESERIALIZER);
   }
+
+  /**
+   * Perform standard {@code application/x-www-urlencoded} translation for string {@code s}.
+   *
+   * @return urlencoded string
+   */
+  @NotNull
+  public static String encodeUrl(@NotNull String s) {
+    try {
+      return URLEncoder.encode(s, CharsetToolkit.UTF8);
+    }
+    catch (UnsupportedEncodingException e) {
+      throw new AssertionError("UTF-8 is not supported");
+    }
+  }
 }
index d5eda2e9faccb6aac1309fa0b237b4e9fc067f21..129a798a5ba94c18769e4f3fce4bca07a64ebbca 100644 (file)
@@ -5,8 +5,11 @@ import com.google.gson.GsonBuilder;
 import com.google.gson.JsonObject;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.io.StreamUtil;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.tasks.LocalTask;
 import com.intellij.tasks.Task;
 import com.intellij.tasks.TaskState;
 import com.intellij.tasks.impl.BaseRepositoryImpl;
@@ -34,7 +37,7 @@ public class JiraRepository extends BaseRepositoryImpl {
   public static final Gson GSON = TaskUtil.installDateDeserializer(new GsonBuilder()).create();
   private final static Logger LOG = Logger.getInstance("#com.intellij.tasks.jira.JiraRepository");
   public static final String LOGIN_FAILED_CHECK_YOUR_PERMISSIONS = "Login failed. Check your permissions.";
-  public static final String REST_API_PATH_SUFFIX = "/rest/api/latest";
+  public static final String REST_API_PATH = "/rest/api/latest";
 
   /**
    * Default JQL query
@@ -109,7 +112,7 @@ public class JiraRepository extends BaseRepositoryImpl {
   @Nullable
   @Override
   public CancellableConnection createCancellableConnection() {
-    String uri = getUrl() + REST_API_PATH_SUFFIX + "/search?maxResults=1&jql=" + encodeUrl(mySearchQuery);
+    String uri = getUrl() + REST_API_PATH + "/search?maxResults=1&jql=" + encodeUrl(mySearchQuery);
     return new HttpTestConnection<GetMethod>(new GetMethod(uri)) {
       @Override
       public void doTest(GetMethod method) throws Exception {
@@ -139,7 +142,7 @@ public class JiraRepository extends BaseRepositoryImpl {
   public JiraRestApi discoverRestApiVersion() throws Exception {
     String responseBody;
     try {
-      responseBody = executeMethod(new GetMethod(getUrl() + REST_API_PATH_SUFFIX + "/serverInfo"));
+      responseBody = executeMethod(new GetMethod(getRestUrl("serverInfo")));
     }
     catch (Exception e) {
       LOG.warn("Can't find out JIRA REST API version");
@@ -148,7 +151,11 @@ public class JiraRepository extends BaseRepositoryImpl {
     JsonObject object = GSON.fromJson(responseBody, JsonObject.class);
     // when JIRA 4.x support will be dropped 'versionNumber' array in response
     // may be used instead version string parsing
-    return JiraRestApi.fromJiraVersion(object.get("version").getAsString(), this);
+    JiraRestApi version = JiraRestApi.fromJiraVersion(object.get("version").getAsString(), this);
+    if (version == null) {
+      throw new Exception("JIRA below 4.0.0 doesn't have REST API and is no longer supported.");
+    }
+    return version;
   }
 
   @Override
@@ -156,17 +163,22 @@ public class JiraRepository extends BaseRepositoryImpl {
     myRestApiVersion.setTaskState(task, state);
   }
 
+  @Override
+  public void updateTimeSpent(@NotNull LocalTask task, @NotNull String timeSpent, @NotNull String comment) throws Exception {
+    myRestApiVersion.updateTimeSpend(task, timeSpent, comment);
+  }
+
   @NotNull
-  public String executeMethod(HttpMethod method) throws Exception {
-    LOG.debug("URI is " + method.getURI());
+  public String executeMethod(@NotNull HttpMethod method) throws Exception {
+    LOG.debug("URI: " + method.getURI());
     int statusCode;
     String entityContent;
     try {
       statusCode = getHttpClient().executeMethod(method);
-      LOG.debug("Status code is " + statusCode);
+      LOG.debug("Status code: " + statusCode);
       // may be null if 204 No Content received
       final InputStream stream = method.getResponseBodyAsStream();
-      entityContent = stream == null ? "" : StreamUtil.readText(stream, "utf-8");
+      entityContent = stream == null ? "" : StreamUtil.readText(stream, CharsetToolkit.UTF8);
       LOG.debug(entityContent);
     }
     finally {
@@ -174,8 +186,8 @@ public class JiraRepository extends BaseRepositoryImpl {
     }
     // besides SC_OK, can also be SC_NO_CONTENT in issue transition requests
     // see: JiraRestApi#setTaskStatus
-    if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_NO_CONTENT) {
-      //if (statusCode >= 200 && statusCode < 300) {
+    //if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_NO_CONTENT) {
+    if (statusCode >= 200 && statusCode < 300) {
       return entityContent;
     }
     else if (method.getResponseHeader("Content-Type") != null) {
@@ -200,7 +212,8 @@ public class JiraRepository extends BaseRepositoryImpl {
     if (statusCode == HttpStatus.SC_UNAUTHORIZED) {
       throw new Exception(LOGIN_FAILED_CHECK_YOUR_PERMISSIONS);
     }
-    throw new Exception("Request failed with HTTP error: " + HttpStatus.getStatusText(method.getStatusCode()));
+    String statusText = HttpStatus.getStatusText(method.getStatusCode());
+    throw new Exception(String.format("Request failed with HTTP error: %d %s", statusCode, statusText));
   }
 
   @Override
@@ -208,4 +221,8 @@ public class JiraRepository extends BaseRepositoryImpl {
     myRestApiVersion = null;
     super.setUrl(url);
   }
+
+  public String getRestUrl(String... parts) {
+    return getUrl() + REST_API_PATH + "/" + FileUtil.join(parts);
+  }
 }
index 04006cbecf5b1c3606cef81778880e4ae32c1dc2..cc6fd11cdaf2889750933c2d7cdf9153b79adc18 100644 (file)
@@ -1,6 +1,8 @@
 package com.intellij.tasks.jira;
 
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.tasks.LocalTask;
 import com.intellij.tasks.Task;
 import com.intellij.tasks.TaskState;
 import com.intellij.tasks.jira.model.JiraIssue;
@@ -9,14 +11,14 @@ import com.intellij.tasks.jira.model.api20alpha1.JiraRestApi20Alpha1;
 import org.apache.commons.httpclient.NameValuePair;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.RequestEntity;
 import org.apache.commons.httpclient.methods.StringRequestEntity;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.io.UnsupportedEncodingException;
 import java.util.List;
 
-import static com.intellij.tasks.jira.JiraRepository.REST_API_PATH_SUFFIX;
-
 /**
  * @author Mikhail Golubev
  */
@@ -63,12 +65,12 @@ public abstract class JiraRestApi {
 
   @NotNull
   protected GetMethod getSingleIssueSearchMethod(String key) {
-    return new GetMethod(myRepository.getUrl() + REST_API_PATH_SUFFIX + "/issue/" + key);
+    return new GetMethod(myRepository.getRestUrl("issue", key));
   }
 
   @NotNull
   protected GetMethod getMultipleIssuesSearchMethod(String jql, int max) {
-    GetMethod method = new GetMethod(myRepository.getUrl() + REST_API_PATH_SUFFIX + "/search");
+    GetMethod method = new GetMethod(myRepository.getRestUrl("search"));
     method.setQueryString(new NameValuePair[]{
       new NameValuePair("jql", jql),
       new NameValuePair("maxResults", String.valueOf(max))
@@ -92,16 +94,26 @@ public abstract class JiraRestApi {
 
   public void setTaskState(Task task, TaskState state) throws Exception {
     String requestBody = getRequestForStateTransition(state);
+    LOG.debug(String.format("Transition: %s -> %s, request: %s", task.getState(), state, requestBody));
     if (requestBody == null) {
       return;
     }
-    final String transitionsUrl = myRepository.getUrl() + REST_API_PATH_SUFFIX + "/issue/" + task.getId() + "/transitions";
-    LOG.debug(String.format("Transition: %s -> %s, request: %s", task.getState(), state, requestBody));
-    final PostMethod method = new PostMethod(transitionsUrl);
-    method.setRequestEntity(new StringRequestEntity(requestBody, "application/json", "utf-8"));
+    PostMethod method = new PostMethod(myRepository.getRestUrl("issue", task.getId(), "transitions"));
+    method.setRequestEntity(createJsonEntity(requestBody));
     myRepository.executeMethod(method);
   }
 
   @Nullable
   protected abstract String getRequestForStateTransition(@NotNull TaskState state);
+
+  public abstract void updateTimeSpend(LocalTask task, String timeSpent, String comment) throws Exception;
+
+  protected static RequestEntity createJsonEntity(String requestBody) {
+    try {
+      return new StringRequestEntity(requestBody, "application/json", CharsetToolkit.UTF8);
+    }
+    catch (UnsupportedEncodingException e) {
+      throw new AssertionError("UTF-8 encoding is not supported");
+    }
+  }
 }
index e362dc263291d0600812ca5fdbca32472d946564..2e658829b42ce205622c7df9198a935667af5e66 100644 (file)
@@ -2,12 +2,15 @@ package com.intellij.tasks.jira.model.api2;
 
 import com.google.gson.reflect.TypeToken;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.tasks.LocalTask;
 import com.intellij.tasks.TaskState;
 import com.intellij.tasks.jira.JiraRepository;
 import com.intellij.tasks.jira.JiraRestApi;
 import com.intellij.tasks.jira.model.JiraIssue;
 import com.intellij.tasks.jira.model.JiraResponseWrapper;
 import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -76,6 +79,20 @@ public class JiraRestApi2 extends JiraRestApi {
     }
   }
 
+  @Override
+  public void updateTimeSpend(LocalTask task, String timeSpent, String comment) throws Exception {
+    LOG.debug(String.format("Time spend: %s, comment: %s", timeSpent, comment));
+    PostMethod method = new PostMethod(myRepository.getRestUrl("issue", task.getId(), "worklog"));
+    String request;
+    if (StringUtil.isEmpty(comment)) {
+      request = String.format("{\"timeSpent\" : \"" + timeSpent + "\"}", timeSpent);
+    } else {
+      request = String.format("{\"timeSpent\": \"%s\", \"comment\": \"%s\"}", timeSpent, StringUtil.escapeQuotes(comment));
+    }
+    method.setRequestEntity(createJsonEntity(request));
+    myRepository.executeMethod(method);
+  }
+
   @NotNull
   @Override
   public String getVersionName() {
index eda4430ffd212667df3fee67f9ff26a6d1adcc7c..453147a33cfd9c33ec8ef1a2a3f1f5b9ef038add 100644 (file)
@@ -2,6 +2,7 @@ package com.intellij.tasks.jira.model.api20alpha1;
 
 import com.google.gson.reflect.TypeToken;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.tasks.LocalTask;
 import com.intellij.tasks.TaskState;
 import com.intellij.tasks.jira.JiraRepository;
 import com.intellij.tasks.jira.JiraRestApi;
@@ -64,6 +65,11 @@ public class JiraRestApi20Alpha1 extends JiraRestApi {
     }
   }
 
+  @Override
+  public void updateTimeSpend(LocalTask task, String timeSpent, String comment) throws Exception {
+    throw new Exception(String.format("This version of JIRA REST API (%s) doesn't support updating worklog items.", getVersionName()));
+  }
+
   @NotNull
   @Override
   public String getVersionName() {
index 413c9b8933edce9d432ac50d0a37221860bf2380..bc004516ad5ebe8f02ec89ef2a93d0c2cc267434 100644 (file)
@@ -307,7 +307,7 @@ public class YouTrackRepository extends BaseRepositoryImpl {
   private static final Logger LOG = Logger.getInstance("#com.intellij.tasks.youtrack.YouTrackRepository");
 
   @Override
-  public void updateTimeSpent(final LocalTask task, final String timeSpent, final String comment) throws Exception {
+  public void updateTimeSpent(@NotNull LocalTask task, @NotNull String timeSpent, @NotNull String comment) throws Exception {
     checkVersion();
     final HttpMethod method = doREST("/rest/issue/execute/" + task.getId() + "?command=work+Today+" + timeSpent.replaceAll(" ", "+") + "+" + comment, true);
     if (method.getStatusCode() != 200) {
diff --git a/python/resources/inspectionDescriptions/PyAssignmentToForLoopParameterInspection.html b/python/resources/inspectionDescriptions/PyAssignmentToForLoopParameterInspection.html
new file mode 100644 (file)
index 0000000..5944aee
--- /dev/null
@@ -0,0 +1,13 @@
+<html>
+<body>
+<span style="font-family: verdana,serif;">
+  This inspection checks for cases when loop variable is redeclared inside of loop.
+</span>
+<pre style="font-family: monospace">
+    for i in xrange(5):
+      for i in xrange(20, 25):
+          print("Inner", i)
+      print("Outer", i)
+  </pre>
+</body>
+</html>
index f11f009b3a5c5975c886f6bf9c36c81eb9de4996..424f0f79a19b5ec3c8ef6c6773c634a5de6ec15b 100644 (file)
     <localInspection language="Python" shortName="PyShadowingNamesInspection" displayName="Shadowing names from outer scopes" groupKey="INSP.GROUP.python" enabledByDefault="true"  level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyShadowingNamesInspection"/>
     <localInspection language="Python" shortName="PyAbstractClassInspection" displayName="Class must implement all abstract methods" groupKey="INSP.GROUP.python" enabledByDefault="true"  level="WARNING" implementationClass="com.jetbrains.python.inspections.PyAbstractClassInspection"/>
     <localInspection language="Python" shortName="PyPep8NamingInspection" displayName="PEP 8 naming convention violation" groupKey="INSP.GROUP.python" enabledByDefault="true"  level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyPep8NamingInspection"/>
+    <localInspection language="Python" shortName="PyAssignmentToForLoopParameterInspection" displayName="Assignment to 'for' loop parameter" groupKey="INSP.GROUP.python" enabledByDefault="true"  level="WARNING" implementationClass="com.jetbrains.python.inspections.PyAssignmentToForLoopParameterInspection"/>
 
     <liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType"/>
     <liveTemplateMacro implementation="com.jetbrains.python.codeInsight.liveTemplates.CollectionElementNameMacro"/>
index 84d4c6d7423bcc95127572651f9418a4b3b8f298..f780607189a9f269e36471f006dfeff4b3e813e9 100644 (file)
@@ -511,6 +511,9 @@ INSP.none.function.assignment=Function ''{0}'' doesn''t return anything
 INSP.NAME.global.undefined=Global variable is undefined at the module level
 INSP.NAME.global.$0.undefined=Global variable ''{0}'' is undefined at the module level
 
+#PyAssignmentToForLoopParameterInspection
+INSP.NAME.assignment.to.for.loop.parameter.display.name=Assignment to 'for' loop parameter
+
 # Refactoring
 # introduce
 refactoring.introduce.name.error=Incorrect name
diff --git a/python/src/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspection.java b/python/src/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspection.java
new file mode 100644 (file)
index 0000000..fcfb364
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2000-2014 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.jetbrains.python.inspections;
+
+import com.intellij.codeInspection.LocalInspectionToolSession;
+import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.PsiFile;
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.psi.PyForPart;
+import com.jetbrains.python.psi.PyTargetExpression;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+//TODO: Try to share logic with AssignmentToForLoopParameterInspection
+
+/**
+ * Checks for cases like
+ * <pre>
+ *   for i in range(1, 10):
+ *    i = "new value"
+ * </pre>
+ *
+ * @author link
+ */
+public class PyAssignmentToForLoopParameterInspection extends PyInspection {
+
+  private static final String MESSAGE = PyBundle.message("INSP.NAME.assignment.to.for.loop.parameter.display.name");
+
+  @NotNull
+  @Override
+  public String getDisplayName() {
+    return MESSAGE;
+  }
+
+
+  @NotNull
+  @Override
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder,
+                                        boolean isOnTheFly,
+                                        @NotNull final LocalInspectionToolSession session) {
+    return new Visitor(holder, session);
+  }
+
+  private static class Visitor extends PyInspectionVisitor {
+    private Visitor(@Nullable ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
+      super(holder, session);
+    }
+
+    @Override
+    public void visitPyTargetExpression(PyTargetExpression node) {
+      PsiElement variableDeclaration = node.getReference().resolve();
+      if (variableDeclaration == null) {
+        return;
+      }
+      PsiElement variableFirstTimeDeclaration = variableDeclaration.getParent();
+
+      if (variableFirstTimeDeclaration.equals(node.getParent())) {
+        return; //We are checking first time declaration
+      }
+
+      //Find "for" between predecessors until we tree root
+      PsiElement element = variableFirstTimeDeclaration;
+      while (!(element instanceof PsiFile) && element != null) {
+        if (element instanceof PyForPart) {
+          registerProblem(node, MESSAGE);
+          return;
+        }
+        element = element.getParent();
+      }
+    }
+  }
+}
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/good.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/good.py
new file mode 100644 (file)
index 0000000..3ea1ee1
--- /dev/null
@@ -0,0 +1,9 @@
+for a in (1, 12):
+    for b in (2, 24):
+        for (c, d) in {"C": "D"}.items():
+            (e, f) = (a, d)
+
+i = 12
+print(i)
+(z, x) = (i, 12)
+print(z)
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/simpleReassignment.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/simpleReassignment.py
new file mode 100644 (file)
index 0000000..1301764
--- /dev/null
@@ -0,0 +1,3 @@
+for i in range(1, 2):
+    print(i)
+    <warning descr="Assignment to 'for' loop parameter">i</warning> = 12
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleAssignment.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleAssignment.py
new file mode 100644 (file)
index 0000000..07281c7
--- /dev/null
@@ -0,0 +1,3 @@
+for i in [1, 2, 3]:
+    print(i)
+    (<warning descr="Assignment to 'for' loop parameter">i</warning>, f) = (1, 2)
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleDeclaration.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/tupleDeclaration.py
new file mode 100644 (file)
index 0000000..52905d4
--- /dev/null
@@ -0,0 +1,3 @@
+for (k, v) in {"K": "V"}.items():
+    print(k)
+    <warning descr="Assignment to 'for' loop parameter">k</warning> = "12"
\ No newline at end of file
diff --git a/python/testData/inspections/PyAssignmentToForLoopParameterInspection/twoLoops.py b/python/testData/inspections/PyAssignmentToForLoopParameterInspection/twoLoops.py
new file mode 100644 (file)
index 0000000..c39f582
--- /dev/null
@@ -0,0 +1,4 @@
+for i in range(5):
+    for <warning descr="Assignment to 'for' loop parameter">i</warning> in range(20, 25):
+        print("Inner", i)
+    print("Outer", i) 
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/PyInspectionTestCase.java
new file mode 100644 (file)
index 0000000..96fca13
--- /dev/null
@@ -0,0 +1,44 @@
+package com.jetbrains.python.fixtures;
+
+import com.jetbrains.python.inspections.PyInspection;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Helps you to create inspection tests.
+ * <br/>
+ * For each case
+ * <ol>
+ * <li>Create file <code>testData/inspections/_YOUR_INSPECTION_CLASS_SIMPLE_NAME_/CASE_NAME_CAMEL_CASE.py</code></li>
+ * <li>Create method <code>test_YOUR_CASE_NAME_PASCAL_CASE</code> that runs {@link #doTest()}</li>
+ * <li>Overwrite {@link #isInfo()}, {@link #isWarning()} or {@link #isWeakWarning()} to configure what to check</li>
+ * </ol>
+ *
+ * @author link
+ */
+public abstract class PyInspectionTestCase extends PyTestCase {
+
+  @NotNull
+  protected abstract Class<? extends PyInspection> getInspectionClass();
+
+  /**
+   * Launches test. To be called by test author
+   */
+  protected void doTest() {
+    myFixture.configureByFile("inspections/" + getInspectionClass().getSimpleName() + "/" + getTestName(true) + ".py");
+    myFixture.enableInspections(getInspectionClass());
+    myFixture.checkHighlighting(isWarning(), isInfo(), isWeakWarning());
+  }
+
+
+  protected boolean isWeakWarning() {
+    return true;
+  }
+
+  protected boolean isInfo() {
+    return false;
+  }
+
+  protected boolean isWarning() {
+    return true;
+  }
+}
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyAssignmentToForLoopParameterInspectionTest.java
new file mode 100644 (file)
index 0000000..9231a3d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2014 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.jetbrains.python.inspections;
+
+import com.jetbrains.python.fixtures.PyInspectionTestCase;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author link
+ */
+public class PyAssignmentToForLoopParameterInspectionTest extends PyInspectionTestCase {
+
+  public void testGood() {
+    doTest();
+  }
+
+  public void testSimpleReassignment() {
+    doTest();
+  }
+
+  public void testTupleAssignment() {
+    doTest();
+  }
+
+  public void testTupleDeclaration() {
+    doTest();
+  }
+
+  public void testTwoLoops() {
+    doTest();
+  }
+
+
+  @NotNull
+  @Override
+  protected Class<? extends PyInspection> getInspectionClass() {
+    return PyAssignmentToForLoopParameterInspection.class;
+  }
+
+  @Override
+  protected boolean isWeakWarning() {
+    return false;
+  }
+}
index 6ac8570db2782d4e7063249eab1fcf40c384b59f..bfa7b5527d41f1ed2c7eb360a799367c165b84bf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 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,7 +29,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
 import org.jetbrains.annotations.NotNull;
 
 import java.awt.*;
-import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 public class SpellCheckerSeveritiesProvider extends SeveritiesProvider {
@@ -38,16 +38,13 @@ public class SpellCheckerSeveritiesProvider extends SeveritiesProvider {
   @Override
   @NotNull
   public List<HighlightInfoType> getSeveritiesHighlightInfoTypes() {
-    final List<HighlightInfoType> result = new ArrayList<HighlightInfoType>();
-
     final TextAttributes attributes = new TextAttributes();
 
     attributes.setEffectType(EffectType.WAVE_UNDERSCORE);
     attributes.setEffectColor(new Color(0, 128, 0));
 
-    result.add(new HighlightInfoType.HighlightInfoTypeImpl(TYPO,
-               TextAttributesKey.createTextAttributesKey("TYPO", attributes)));
-    return result;
+    HighlightInfoType typo = new HighlightInfoType.HighlightInfoTypeImpl(TYPO, TextAttributesKey.createTextAttributesKey("TYPO", attributes));
+    return Collections.singletonList(typo);
   }
 
   @Override
index 3eead4a936289fef60f37d0c80eba930841fe6c0..1d5e5a1cc78f61653f7c1923d7b723e2d8e4b25f 100644 (file)
@@ -52,9 +52,6 @@ public abstract class BaseUpdateAction extends PatchAction {
     try {
       writeDiff(olderFileIn, newerFileIn, patchOutput);
     }
-    catch (Exception ex) {
-      Runner.printStackTrace(ex);
-    }
     finally {
       olderFileIn.close();
       newerFileIn.close();
index e5bd5f72600e94f97097943d966e0ac50f8c01e8..1d6ca0cc2b9c3fe3aca395fa38d5128b9090b201 100644 (file)
@@ -53,9 +53,6 @@ public class CreateAction extends PatchAction {
       Utils.copyStreamToFile(in, toFile);
       Utils.setExecutable(toFile, executable);
     }
-    catch (Exception ex) {
-      Runner.printStackTrace(ex);
-    }
     finally {
       in.close();
     }
index 54bef0c1f14ab4f478283c1d07cf92ce3f8f8f02..00792ce00321df7e6e1a3076b0ab31146eb8566c 100644 (file)
@@ -35,9 +35,6 @@ public class Digester {
       try {
         return doDigestZipFile(zipFile);
       }
-      catch (Exception e) {
-        Runner.printStackTrace(e);
-      }
       finally {
         zipFile.close();
       }
@@ -76,9 +73,6 @@ public class Digester {
       try {
         doDigestStream(in, crc);
       }
-      catch (Exception e) {
-        Runner.printStackTrace(e);
-      }
       finally {
         in.close();
       }
index cbeda1584dff5793af634f31e386d2c012cd8dc5..42afb50b989d50936d13a05aeae8f32e8424a878 100644 (file)
@@ -95,9 +95,6 @@ public abstract class PatchAction {
         if (lock == null) return false;
         lock.release();
       }
-      catch (Exception e) {
-        Runner.printStackTrace(e);
-      }
       finally {
         ch.close();
         s.close();
index a2923e67ddcc8649b001191913a2947ce9b9e7e4..e8892375e204b6a4e194e2d4e83bb2c6387cabbd 100644 (file)
@@ -43,9 +43,6 @@ public class PatchFileCreator {
         each.buildPatchFile(olderDir, newerDir, out);
       }
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       out.close();
     }
@@ -101,9 +98,6 @@ public class PatchFileCreator {
     try {
       preparationResult.patch.revert(actionsToRevert, backupDir, preparationResult.toDir, ui);
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       zipFile.close();
     }
index efaaf9a22bbe70801661daf20b15c87144100676..30191eaea86d6ef01ec5dcbb5ea5b65629c56763 100644 (file)
@@ -160,9 +160,6 @@ public class Runner {
             out.zipEntry(e, in);
           }
         }
-        catch (Exception ex) {
-          printStackTrace(ex);
-        }
         finally {
           in.close();
         }
@@ -174,9 +171,6 @@ public class Runner {
           props.setProperty(NEW_BUILD_DESCRIPTION, newBuildDesc);
           props.store(byteOut, "");
         }
-        catch (Exception ex) {
-          printStackTrace(ex);
-        }
         finally {
           byteOut.close();
         }
@@ -185,16 +179,10 @@ public class Runner {
         out.zipFile(PATCH_FILE_NAME, tempPatchFile);
         out.finish();
       }
-      catch (Exception ex) {
-        printStackTrace(ex);
-      }
       finally {
         fileOut.close();
       }
     }
-    catch (Exception ex) {
-      printStackTrace(ex);
-    }
     finally {
       cleanup(ui);
     }
@@ -213,9 +201,6 @@ public class Runner {
     try {
       props.load(in);
     }
-    catch (Exception ex) {
-      printStackTrace(ex);
-    }
     finally {
       in.close();
     }
@@ -257,17 +242,11 @@ public class Runner {
           try {
             Utils.copyStream(in, out);
           }
-          catch (Exception ex) {
-            printStackTrace(ex);
-          }
           finally {
             in.close();
             out.close();
           }
         }
-        catch (Exception ex) {
-          printStackTrace(ex);
-        }
         finally {
           jarFile.close();
         }
@@ -284,9 +263,6 @@ public class Runner {
         printStackTrace(e);
       }
     }
-    catch (Exception ex) {
-      printStackTrace(ex);
-    }
     finally {
       try {
         cleanup(ui);
index e639eff1df8df88fd7bfff7a2b1c6adf8433ffec..6c79c44cbc4b54faddc70c3ce153f76d20a0d843 100644 (file)
@@ -34,16 +34,10 @@ public class UpdateAction extends BaseUpdateAction {
       try {
         applyDiff(in, oldFileIn, out);
       }
-      catch (Exception e) {
-        Runner.printStackTrace(e);
-      }
       finally {
         oldFileIn.close();
       }
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       out.close();
     }
index 64fc9a26eb7d88cfaa0e70c2e167946927da50dc..7741b813318a5696bd8ca5914a70901cc68bfb2a 100644 (file)
@@ -148,9 +148,6 @@ public class UpdateZipAction extends BaseUpdateAction {
         }
       });
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       olderZip.close();
     }
@@ -173,9 +170,6 @@ public class UpdateZipAction extends BaseUpdateAction {
             try {
               applyDiff(Utils.findEntryInputStream(patchFile, myPath + "/" + path), in, entryOut);
             }
-            catch (Exception e) {
-              Runner.printStackTrace(e);
-            }
             finally {
               entryOut.close();
             }
@@ -191,9 +185,6 @@ public class UpdateZipAction extends BaseUpdateAction {
         try {
           out.zipEntry(each, in);
         }
-        catch (Exception e) {
-          Runner.printStackTrace(e);
-        }
         finally {
           in.close();
         }
@@ -201,9 +192,6 @@ public class UpdateZipAction extends BaseUpdateAction {
 
       out.finish();
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       fileOut.close();
     }
@@ -226,9 +214,6 @@ public class UpdateZipAction extends BaseUpdateAction {
         processed.add(inEntry.getName());
       }
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       in.close();
     }
index 234d87e552f67dffb873dc73ea7dbca93694038b..a71121e4a74de03cf34713fafa7f906a0273ac51 100644 (file)
@@ -85,9 +85,6 @@ public class Utils {
       try {
         copyStreamToFile(in, to);
       }
-      catch (Exception e) {
-        Runner.printStackTrace(e);
-      }
       finally {
         in.close();
       }
@@ -100,9 +97,6 @@ public class Utils {
     try {
       copyStream(in, out);
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       in.close();
     }
@@ -114,9 +108,6 @@ public class Utils {
     try {
       copyStream(from, out);
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       out.close();
     }
@@ -127,9 +118,6 @@ public class Utils {
     try {
       from.writeTo(out);
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       out.flush();
     }
@@ -144,9 +132,6 @@ public class Utils {
     try {
       copyStream(in, byteOut);
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       byteOut.close();
     }
index f1e1b10321cb5641082a71b2060f233029da8082..ec4754600bfe40079de24d3a085205a79f09494e 100644 (file)
@@ -56,9 +56,6 @@ public class ZipOutputWrapper {
     try {
       Utils.copyStream(from, tempOut);
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       tempOut.close();
     }
@@ -91,9 +88,6 @@ public class ZipOutputWrapper {
     try {
       zipEntry(new ZipEntry(entryPath), from);
     }
-    catch (Exception e) {
-      Runner.printStackTrace(e);
-    }
     finally {
       from.close();
     }
index a75e395fdec25310bbf182551ba6c47257ab8c9a..92a34a934559d1e7656728587eb0dd66c5f3bd80 100644 (file)
@@ -16,6 +16,8 @@
 package com.intellij.html.impl;
 
 import com.intellij.html.index.Html5CustomAttributesIndex;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.xml.XmlAttribute;
 import com.intellij.psi.xml.XmlTag;
 import com.intellij.util.Processor;
@@ -42,9 +44,19 @@ public class Html5CustomAttributeDescriptorsProvider implements XmlAttributeDesc
       currentAttrs.add(attribute.getName());
     }
     final List<XmlAttributeDescriptor> result = new ArrayList<XmlAttributeDescriptor>();
+    final GlobalSearchScope scope = GlobalSearchScope.allScope(tag.getProject());
     FileBasedIndex.getInstance().processAllKeys(Html5CustomAttributesIndex.INDEX_ID, new Processor<String>() {
       @Override
       public boolean process(String s) {
+        final boolean canProcessKey = !FileBasedIndex.getInstance().processValues(Html5CustomAttributesIndex.INDEX_ID, s,
+                                                                                  null, new FileBasedIndex.ValueProcessor<Void>() {
+            @Override
+            public boolean process(VirtualFile file, Void value) {
+              return false;
+            }
+          }, scope);
+        if (!canProcessKey) return true;
+
         boolean add = true;
         for (String attr : currentAttrs) {
           if (attr.startsWith(s)) {
@@ -56,7 +68,7 @@ public class Html5CustomAttributeDescriptorsProvider implements XmlAttributeDesc
         }
         return true;
       }
-    }, tag.getProject());
+    }, scope, null);
 
     return result.toArray(new XmlAttributeDescriptor[result.size()]);
   }