Merge remote-tracking branch 'origin/master' appcode/138.91 cppide/138.93 idea/136.1793 phpstorm/138.90 rubymine/138.89 webstorm/138.88
authorDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Tue, 6 May 2014 00:19:12 +0000 (02:19 +0200)
committerDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Tue, 6 May 2014 00:19:12 +0000 (02:19 +0200)
84 files changed:
java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/RedundantSuppressInspectionBase.java
java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java
java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
java/java-analysis-impl/src/com/intellij/codeInspection/miscGenerics/SuspiciousMethodCallUtil.java
java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java
java/java-impl/src/com/intellij/openapi/roots/impl/LanguageLevelProjectExtensionImpl.java
java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java
java/java-psi-api/src/com/intellij/openapi/roots/LanguageLevelProjectExtension.java
java/java-psi-impl/src/com/intellij/core/CoreLanguageLevelProjectExtension.java
java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/diamond/Varargs.java
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/TargetTypeParameter.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA124547.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromMethodRef/afterStaticMethodInInterface.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromMethodRef/beforeStaticMethodInInterface.java [new file with mode: 0644]
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAnonymous1.java [new file with mode: 0644]
java/java-tests/testData/inspection/dataFlow/fixture/ConstantDoubleComparisons.java
java/java-tests/testData/inspection/deprecation/DeprecatedDefaultConstructorFromTypeParameter/expected.xml [new file with mode: 0644]
java/java-tests/testData/inspection/deprecation/DeprecatedDefaultConstructorFromTypeParameter/src/Test.java [new file with mode: 0644]
java/java-tests/testData/inspection/redundantSuppress/alternativeIds/expected.xml [new file with mode: 0644]
java/java-tests/testData/inspection/redundantSuppress/alternativeIds/src/x/X.java [new file with mode: 0644]
java/java-tests/testData/inspection/suspiciousCalls/ConcurrentHashMap.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferredTypeTest.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MostSpecificResolutionTest.java
java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java
java/java-tests/testSrc/com/intellij/codeInspection/DeprecationInspectionTest.java
java/java-tests/testSrc/com/intellij/codeInspection/RedundantSuppressTest.java
java/java-tests/testSrc/com/intellij/codeInspection/SuspiciousCollectionMethodCallsTest.java
java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java
platform/analysis-api/src/com/intellij/util/ui/CheckBox.java
platform/core-api/src/com/intellij/openapi/vfs/JarFile.java
platform/core-api/src/com/intellij/psi/CommonClassNames.java
platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java
platform/core-impl/src/com/intellij/core/CoreProjectEnvironment.java
platform/core-impl/src/com/intellij/openapi/vfs/impl/jar/JarHandlerBase.java
platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnActionEvent.java
platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionBase.java
platform/lang-api/src/com/intellij/execution/configuration/RunConfigurationExtensionsManager.java
platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java
platform/lang-impl/src/com/intellij/ide/actions/QuickChangeCodeStyleSchemeAction.java
platform/lang-impl/src/com/intellij/ide/todo/configurable/FilterDialog.java
platform/platform-api/src/com/intellij/openapi/vfs/JarFileSystem.java
platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java
platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java
platform/platform-impl/src/com/intellij/openapi/vfs/impl/jar/JarFileSystemImpl.java
platform/platform-tests/testSrc/com/intellij/util/messages/MessageBusTest.java [moved from platform/util/testSrc/com/intellij/util/messages/MessageBusTest.java with 99% similarity]
platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/PsiVisitors.java
platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/VariableView.java
platform/testFramework/src/com/intellij/testFramework/TestLoggerFactory.java
platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java
platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestFixture.java
platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java
platform/util/src/com/intellij/openapi/util/io/ZipFileCache.java [new file with mode: 0644]
platform/util/src/com/intellij/util/lang/JarLoader.java
platform/util/src/com/intellij/util/lang/JarMemoryLoader.java
platform/util/src/com/intellij/util/lang/MemoryResource.java [new file with mode: 0644]
platform/util/src/com/intellij/util/messages/MessageBusFactory.java
platform/util/src/com/intellij/util/messages/impl/MessageBusImpl.java
platform/util/util.iml
platform/vcs-impl/src/com/intellij/openapi/vcs/changes/actions/RevertCommittedStuffAbstractAction.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javadoc/UnnecessaryInheritDocInspection.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/ForCanBeForeachInspectionBase.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/IfCanBeSwitchInspection.java
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/AutoCloseableResourceInspectionBase.java [moved from plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java with 68% similarity]
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/resources/IOResourceInspectionBase.java
plugins/InspectionGadgets/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java [new file with mode: 0644]
plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/ForCanBeForEach.java
plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/expected.xml [deleted file]
plugins/InspectionGadgets/test/com/siyeh/igtest/verbose/OuterClass.java [deleted file]
plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/UnnecessaryInheritDocInspectionTest.java [new file with mode: 0644]
plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/ForCanBeForeachInspectionTest.java
plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java
plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties
plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java
plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java
plugins/git4idea/tests/git4idea/test/GitPlatformTest.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/actions/MavenExecuteGoalAction.java
python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralExtensionPoint.java
python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralRenameHandler.java
python/src/com/jetbrains/python/magicLiteral/PyMagicLiteralTools.java
xml/dom-openapi/src/com/intellij/util/xml/JavaMethod.java
xml/dom-openapi/src/com/intellij/util/xml/JavaMethodSignature.java

index 1944f8367f2e984c8d3489df44412dce979b2d1f..6fb217eaa4e9a70c55ce6411dcbab34d388d8f92 100644 (file)
@@ -91,6 +91,8 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
                                                                  PsiType functionalInterfaceType) {
     PsiCallExpression methodCall = extractMethodCallFromBlock(body);
 
+    if (methodCall instanceof PsiNewExpression && ((PsiNewExpression)methodCall).getAnonymousClass() != null) return null;
+
     if (methodCall != null) {
       final PsiExpressionList argumentList = methodCall.getArgumentList();
       if (argumentList != null) {
@@ -102,7 +104,6 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
         if (psiMethod == null) {
           isConstructor = true;
           if (!(methodCall instanceof PsiNewExpression)) return null;
-          if (((PsiNewExpression)methodCall).getAnonymousClass() != null) return null;
           final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression)methodCall).getClassOrAnonymousClassReference();
           if (classReference == null) return null;
           containingClass = (PsiClass)classReference.resolve();
index f35609aabd5d42b6e7917f4f11c5465c8acbc4f9..507c60b6d251031a1217e2b5f08f815290752376 100644 (file)
@@ -31,7 +31,6 @@ import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.containers.BidirectionalMap;
 import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashMap;
-import gnu.trove.THashSet;
 import org.jdom.Element;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -160,25 +159,27 @@ public class RedundantSuppressInspectionBase extends GlobalInspectionTool {
 
     if (suppressedScopes.values().isEmpty()) return null;
     // have to visit all file from scratch since inspections can be written in any perversive way including checkFile() overriding
-    Collection<InspectionToolWrapper> suppressedTools = new THashSet<InspectionToolWrapper>();
+    Map<InspectionToolWrapper, String> suppressedTools = new THashMap<InspectionToolWrapper, String>();
     InspectionToolWrapper[] toolWrappers = getInspectionTools(psiElement, manager);
     for (Collection<String> ids : suppressedScopes.values()) {
       for (Iterator<String> iterator = ids.iterator(); iterator.hasNext(); ) {
         final String shortName = iterator.next().trim();
         for (InspectionToolWrapper toolWrapper : toolWrappers) {
-          if (toolWrapper instanceof LocalInspectionToolWrapper && ((LocalInspectionToolWrapper)toolWrapper).getTool().getID().equals(shortName)) {
+          if (toolWrapper instanceof LocalInspectionToolWrapper && 
+              (((LocalInspectionToolWrapper)toolWrapper).getTool().getID().equals(shortName) ||
+               shortName.equals(((LocalInspectionToolWrapper)toolWrapper).getTool().getAlternativeID()))) {
             if (((LocalInspectionToolWrapper)toolWrapper).isUnfair()) {
               iterator.remove();
               break;
             }
             else {
-              suppressedTools.add(toolWrapper);
+              suppressedTools.put(toolWrapper, shortName);
             }
           }
           else if (toolWrapper.getShortName().equals(shortName)) {
             //ignore global unused as it won't be checked anyway
             if (toolWrapper instanceof LocalInspectionToolWrapper || toolWrapper instanceof GlobalInspectionToolWrapper) {
-              suppressedTools.add(toolWrapper);
+              suppressedTools.put(toolWrapper, shortName);
             }
             else {
               iterator.remove();
@@ -199,8 +200,8 @@ public class RedundantSuppressInspectionBase extends GlobalInspectionTool {
     final List<ProblemDescriptor> result;
     try {
       result = new ArrayList<ProblemDescriptor>();
-      for (InspectionToolWrapper toolWrapper : suppressedTools) {
-        String toolId = toolWrapper instanceof LocalInspectionToolWrapper ? ((LocalInspectionToolWrapper)toolWrapper).getTool().getID() : toolWrapper.getShortName();
+      for (InspectionToolWrapper toolWrapper : suppressedTools.keySet()) {
+        String toolId = suppressedTools.get(toolWrapper);
         toolWrapper.initialize(globalContext);
         final Collection<CommonProblemDescriptor> descriptors;
         if (toolWrapper instanceof LocalInspectionToolWrapper) {
index ca2e13620c921576e165caf9965eeeab7d0f5f62..f00f3ce0c67714cbf3dd6e475d4f3a5057cd7341 100644 (file)
@@ -89,6 +89,11 @@ public class DfaConstValue extends DfaValue {
       if (TypeConversionUtil.isNumericType(type) && !TypeConversionUtil.isFloatOrDoubleType(type)) {
         value = TypeConversionUtil.computeCastTo(value, PsiType.LONG);
       }
+      if (value instanceof Double || value instanceof Float) {
+        double doubleValue = ((Number)value).doubleValue();
+        if (doubleValue == -0.0) doubleValue = +0.0;
+        value = new Double(doubleValue);
+      }
       DfaConstValue instance = myValues.get(value);
       if (instance == null) {
         instance = new DfaConstValue(value, myFactory, constant);
index 85b3674d520de164f5d96020d717ea4f1423cfa7..a490f81b1d65b01c38d353513e4d123bc90689ec 100644 (file)
@@ -189,6 +189,7 @@ public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool {
 
     @Override
     public void visitClass(PsiClass aClass) {
+      if (aClass instanceof PsiTypeParameter) return;
       final PsiMethod[] currentConstructors = aClass.getConstructors();
       if (currentConstructors.length == 0) {
         final PsiClass superClass = aClass.getSuperClass();
index 0732c292ff9f047c1df964439d5e52498bfa7ba5..3f8b5feed2bef00b6d850bb0c35de72d4ed37162 100644 (file)
@@ -30,8 +30,9 @@ public class SuspiciousMethodCallUtil {
                                   GlobalSearchScope searchScope,
                                   List<PsiMethod> patternMethods,
                                   IntArrayList indices) {
+    final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(manager.getProject());
     final PsiClass
-      collectionClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_UTIL_COLLECTION, searchScope);
+      collectionClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_COLLECTION, searchScope);
     PsiType[] javaLangObject = {PsiType.getJavaLangObject(manager, searchScope)};
     MethodSignature removeSignature = MethodSignatureUtil
       .createMethodSignature("remove", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
@@ -43,7 +44,7 @@ public class SuspiciousMethodCallUtil {
       addMethod(contains, 0, patternMethods, indices);
     }
 
-    final PsiClass listClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_UTIL_LIST, searchScope);
+    final PsiClass listClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_LIST, searchScope);
     if (listClass != null) {
       MethodSignature indexofSignature = MethodSignatureUtil.createMethodSignature("indexOf", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
       PsiMethod indexof = MethodSignatureUtil.findMethodBySignature(listClass, indexofSignature, false);
@@ -53,7 +54,7 @@ public class SuspiciousMethodCallUtil {
       addMethod(lastindexof, 0, patternMethods, indices);
     }
 
-    final PsiClass mapClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(CommonClassNames.JAVA_UTIL_MAP, searchScope);
+    final PsiClass mapClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_MAP, searchScope);
     if (mapClass != null) {
       PsiMethod remove = MethodSignatureUtil.findMethodBySignature(mapClass, removeSignature, false);
       addMethod(remove, 0, patternMethods, indices);
@@ -67,6 +68,13 @@ public class SuspiciousMethodCallUtil {
       PsiMethod containsValue = MethodSignatureUtil.findMethodBySignature(mapClass, containsValueSignature, false);
       addMethod(containsValue, 1, patternMethods, indices);
     }
+
+    final PsiClass concurrentMapClass = javaPsiFacade.findClass(CommonClassNames.JAVA_UTIL_CONCURRENT_HASH_MAP, searchScope);
+    if (concurrentMapClass != null) {
+      MethodSignature containsSignature = MethodSignatureUtil.createMethodSignature("contains", javaLangObject, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
+      PsiMethod contains = MethodSignatureUtil.findMethodBySignature(concurrentMapClass, containsSignature, false);
+      addMethod(contains, 1, patternMethods, indices);
+    }
   }
 
   private static void addMethod(final PsiMethod patternMethod, int typeParamIndex, List<PsiMethod> patternMethods, IntArrayList indices) {
index 70fa10703c265e4131d1a59aff90e70218449a3a..2669e518c74d10e06b0d966ae961ee22288b72cc 100644 (file)
@@ -135,7 +135,7 @@ public class CreateFromUsageUtils {
 
     JVMElementFactory factory = JVMElementFactories.getFactory(aClass.getLanguage(), aClass.getProject());
 
-    LOG.assertTrue(!aClass.isInterface() || method.hasModifierProperty(PsiModifier.DEFAULT), "Interface bodies should be already set up");
+    LOG.assertTrue(!aClass.isInterface() || method.hasModifierProperty(PsiModifier.DEFAULT) || method.hasModifierProperty(PsiModifier.STATIC), "Interface bodies should be already set up");
 
     FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension());
     Properties properties = new Properties();
index 654b4d89845d20ddb36a3107f3e984d2017b6042..496795b85444a317281f11f7591ae8cb7d7ee7de 100644 (file)
@@ -20,6 +20,7 @@
  */
 package com.intellij.openapi.roots.impl;
 
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.LanguageLevelProjectExtension;
 import com.intellij.openapi.roots.ProjectExtension;
@@ -31,6 +32,7 @@ import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
 public class LanguageLevelProjectExtensionImpl extends LanguageLevelProjectExtension {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.LanguageLevelProjectExtensionImpl");
   @Deprecated
   @NonNls private static final String ASSERT_KEYWORD_ATTR = "assert-keyword";
   @Deprecated
@@ -98,6 +100,11 @@ public class LanguageLevelProjectExtensionImpl extends LanguageLevelProjectExten
     JavaLanguageLevelPusher.pushLanguageLevel(myProject);
   }
 
+  @Override
+  public void reloadProjectOnLanguageLevelChange(@NotNull LanguageLevel languageLevel, boolean forceReload) {
+    LOG.warn("Calling deprecated LanguageLevelProjectExtensionImpl.reloadProjectOnLanguageLevelChange, while project reloading is not needed on language level changes");
+  }
+
   public static class MyProjectExtension extends ProjectExtension {
     private final Project myProject;
 
index 34abe924cc62a8f478fa90136df6bc913e299d61..d151bf324b71bcac69044761288ff91d019f67de 100644 (file)
@@ -253,20 +253,9 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
       else if (psiType instanceof PsiClassType) {
         final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)psiType).resolveGenerics();
         final PsiClass psiClass = resolveResult.getElement();
-        final Project project = statement.getProject();
-        final PsiClass iterableClass =
-            JavaPsiFacade.getInstance(project).findClass("java.lang.Iterable", GlobalSearchScope.allScope(project));
-        if (iterableClass == null) return;
-        if (!InheritanceUtil.isInheritorOrSelf(psiClass, iterableClass, true)) {
-          findConversionOrFail(value, value, typeView.getTypePair());
-          return;
-        }
-        final PsiSubstitutor iterableParamSubstitutor =
-            TypeConversionUtil.getClassSubstitutor(iterableClass, psiClass, PsiSubstitutor.EMPTY);
-        LOG.assertTrue(iterableParamSubstitutor != null);
-        final PsiTypeParameter[] typeParameters = iterableClass.getTypeParameters();
-        LOG.assertTrue(typeParameters.length == 1);
-        psiType = resolveResult.getSubstitutor().substitute(iterableParamSubstitutor.substitute(typeParameters[0]));
+        final PsiType targetTypeParameter = getTargetTypeParameter(psiClass, value, typeView);
+        if (targetTypeParameter == null) return;
+        psiType = resolveResult.getSubstitutor().substitute(targetTypeParameter);
         if (psiType instanceof PsiWildcardType) {
           psiType = ((PsiWildcardType)psiType).getExtendsBound();
         }
@@ -283,9 +272,13 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
         } else {
           final PsiClass iterableClass = PsiUtil.resolveClassInType(typeViewType);
           LOG.assertTrue(iterableClass != null);
-          final PsiTypeParameter[] typeParameters = iterableClass.getTypeParameters();
-          LOG.assertTrue(typeParameters.length == 1);
-          final Map<PsiTypeParameter, PsiType> substMap = Collections.singletonMap(typeParameters[0], left.getType());
+
+          final PsiType targetType = getTargetTypeParameter(iterableClass, value, typeView);
+          final PsiClass typeParam = PsiUtil.resolveClassInClassTypeOnly(targetType);
+          if (!(typeParam instanceof PsiTypeParameter)) return;
+
+          final Map<PsiTypeParameter, PsiType> substMap = Collections.singletonMap(((PsiTypeParameter)typeParam), left.getType());
+
           final PsiElementFactory factory = JavaPsiFacade.getElementFactory(iterableClass.getProject());
           iterableType = factory.createType(iterableClass, factory.createSubstitutor(substMap));
         }
@@ -296,6 +289,22 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
     }
   }
 
+  private PsiType getTargetTypeParameter(PsiClass iterableClass, PsiExpression value, TypeView typeView) {
+    final Project project = iterableClass.getProject();
+    final PsiClass itClass =
+      JavaPsiFacade.getInstance(project).findClass("java.lang.Iterable", GlobalSearchScope.allScope(project));
+    if (itClass == null) return null;
+
+    if (!InheritanceUtil.isInheritorOrSelf(iterableClass, itClass, true)) {
+      findConversionOrFail(value, value, typeView.getTypePair());
+      return null;
+    }
+
+    final PsiSubstitutor aSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(itClass, iterableClass, PsiSubstitutor.EMPTY);
+
+    return aSubstitutor.substitute(itClass.getTypeParameters()[0]);
+  }
+  
   @Override
   public void visitNewExpression(final PsiNewExpression expression) {
     super.visitNewExpression(expression);
index 45ad4e664adb2b1b57446bb7f0bf9a41e3a8b798..e09f149927acaa59d45093e3b45c15727e697433 100644 (file)
@@ -35,4 +35,10 @@ public abstract class LanguageLevelProjectExtension {
   public abstract void setLanguageLevel(@NotNull LanguageLevel languageLevel);
 
   public abstract void languageLevelsChanged();
+
+  /**
+   * Project reloading is not needed on language level changes
+   * @deprecated to remove in IDEA 15
+   */
+  public abstract void reloadProjectOnLanguageLevelChange(@NotNull LanguageLevel languageLevel, boolean forceReload);
 }
index 6a231f0aeb65c7d761710159b4e3fc6080caafc7..58956f32a406531f88fc306dccf751aafbeaa72d 100644 (file)
@@ -39,4 +39,8 @@ public class CoreLanguageLevelProjectExtension extends LanguageLevelProjectExten
   @Override
   public void languageLevelsChanged() {
   }
+
+  @Override
+  public void reloadProjectOnLanguageLevelChange(@NotNull LanguageLevel languageLevel, boolean forceReload) {
+  }
 }
index 9dfb4fc391340521da6eee94e445e08e29cb6510..df053c53291e33577a63cfe88d3cf8ae5bb81610 100644 (file)
@@ -153,6 +153,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
         if (methodParameters.length == 0) continue;
         final PsiParameter param = i < methodParameters.length ? methodParameters[i] : methodParameters[methodParameters.length - 1];
         final PsiType paramType = param.getType();
+        // http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.1
+        // A lambda expression or a method reference expression is potentially compatible with a type variable if the type variable is a type parameter of the candidate method.
+        final PsiClass paramClass = PsiUtil.resolveClassInType(paramType);
+        if (paramClass instanceof PsiTypeParameter && ((PsiTypeParameter)paramClass).getOwner() == method) continue;
         if (!lambdaExpression.isAcceptable(((MethodCandidateInfo)conflict).getSubstitutor(false).substitute(paramType), lambdaExpression.hasFormalParameterTypes())) {
           iterator.remove();
         }
index 2826e5802e91d7ef59d211925f5d3754a8d0716e..9afe7e792e3e3ce9bf5626db3a938bd3a7b798ff 100644 (file)
@@ -7,7 +7,7 @@ class A<T> {
     foo(new A<>("", ""));
     bar(new A<>("", ""));
     bar(new A<>(get()));
-    //bar(new A<>(get( ), ""));
+    bar(new A<>(get( ), ""));
   }
 
   void foo(A<String> s) {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/TargetTypeParameter.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/mostSpecific/TargetTypeParameter.java
new file mode 100644 (file)
index 0000000..550ecf8
--- /dev/null
@@ -0,0 +1,11 @@
+import java.util.function.Supplier;
+
+class Test {
+
+  public static void main(String... args) {
+    c<error descr="Cannot resolve method 'c(<lambda expression>, <lambda expression>)'">(() -> 3, () -> 10)</error>;
+  }
+
+  public static <T> void c(Supplier<T> s1, Supplier<T> s2) {}
+  public static <T> void c(Supplier<T> s1, T value) {}
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA124547.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA124547.java
new file mode 100644 (file)
index 0000000..f13899b
--- /dev/null
@@ -0,0 +1,18 @@
+import java.util.List;
+import java.util.stream.Collectors;
+
+class Scratch {
+  private List<Id> entries;
+
+  public String encode() {
+    return  entries.stream()
+      .map(e -> String.valueOf(e.getId()))
+      .collect(Collectors.joining("+"));
+  }
+
+  private static class Id {
+    public long getId() {
+      return 0;
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromMethodRef/afterStaticMethodInInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromMethodRef/afterStaticMethodInInterface.java
new file mode 100644 (file)
index 0000000..f96a5a2
--- /dev/null
@@ -0,0 +1,12 @@
+// "Create Method 'fooBar'" "true"
+interface I {
+    static void fooBar() {
+        
+    }
+}
+
+class Test {
+  void test() {
+    Runnable runnable = I::fooBar;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromMethodRef/beforeStaticMethodInInterface.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMethodFromMethodRef/beforeStaticMethodInInterface.java
new file mode 100644 (file)
index 0000000..ae119dd
--- /dev/null
@@ -0,0 +1,9 @@
+// "Create Method 'fooBar'" "true"
+interface I {
+}
+
+class Test {
+  void test() {
+    Runnable runnable = I::foo<caret>Bar;
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAnonymous1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lambda2methodReference/beforeAnonymous1.java
new file mode 100644 (file)
index 0000000..00b9355
--- /dev/null
@@ -0,0 +1,15 @@
+// "Replace lambda with method reference" "false"
+class NonStaticInner3 {
+    class Foo {
+      public Foo() {
+      }
+    }
+
+    interface I1<X> {
+        X m();
+    }
+
+    {
+        I1<Foo> b2 = () -> <caret>new Foo(){};
+    }
+}
\ No newline at end of file
index f126ac1e10e2ca93ba5e60c279c4468ecdfa9b1b..6efbfce60be70c0884fc60c85f28d36ec2b5afa2 100644 (file)
@@ -8,4 +8,12 @@ class Foo {
       }
     }
   }
+
+  void equalZeroes() {
+    double posz = +0.0, negz = -0.0;
+    System.out.println(<warning descr="Condition 'posz == negz' is always 'true'">posz == negz</warning>);
+    if (<warning descr="Condition '+0.0 == -0.0' is always 'true'">+0.0 == -0.0</warning>) {
+      System.out.println("true!");
+    }
+  }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/deprecation/DeprecatedDefaultConstructorFromTypeParameter/expected.xml b/java/java-tests/testData/inspection/deprecation/DeprecatedDefaultConstructorFromTypeParameter/expected.xml
new file mode 100644 (file)
index 0000000..4704d91
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems/>
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/deprecation/DeprecatedDefaultConstructorFromTypeParameter/src/Test.java b/java/java-tests/testData/inspection/deprecation/DeprecatedDefaultConstructorFromTypeParameter/src/Test.java
new file mode 100644 (file)
index 0000000..f3f5575
--- /dev/null
@@ -0,0 +1,6 @@
+class Test {
+  @Deprecated
+  protected Test() { }
+
+  static <T extends Test> void foo() {}
+}
diff --git a/java/java-tests/testData/inspection/redundantSuppress/alternativeIds/expected.xml b/java/java-tests/testData/inspection/redundantSuppress/alternativeIds/expected.xml
new file mode 100644 (file)
index 0000000..4704d91
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems/>
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/redundantSuppress/alternativeIds/src/x/X.java b/java/java-tests/testData/inspection/redundantSuppress/alternativeIds/src/x/X.java
new file mode 100644 (file)
index 0000000..d424cb5
--- /dev/null
@@ -0,0 +1,9 @@
+package x;
+
+class S {
+  @SuppressWarnings("rawtypes")
+  public String get(final Class cls)
+  {
+    return "";
+  }
+}
diff --git a/java/java-tests/testData/inspection/suspiciousCalls/ConcurrentHashMap.java b/java/java-tests/testData/inspection/suspiciousCalls/ConcurrentHashMap.java
new file mode 100644 (file)
index 0000000..e0b7b5c
--- /dev/null
@@ -0,0 +1,9 @@
+import java.util.concurrent.ConcurrentHashMap;
+
+class Main<K, V> {
+  void f(ConcurrentHashMap<K, V> map, K key){
+    if (map.contains(<warning descr="Suspicious call to 'ConcurrentHashMap.contains'">key</warning>)) {
+      System.out.println();
+    }
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferredTypeTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/InferredTypeTest.java
new file mode 100644 (file)
index 0000000..541a519
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.intellij.codeInsight.daemon.lambda;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiIdentifier;
+import com.intellij.psi.PsiType;
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Assert;
+
+public class InferredTypeTest extends LightCodeInsightFixtureTestCase {
+  public void testNestedCallReturnType() throws Exception {
+    myFixture.configureByText("a.java", "import java.util.List;\n" +
+                                        "abstract class Test {\n" +
+                                        "    abstract <R, K> R foo(K k1, K k2);\n" +
+                                        "    {\n" +
+                                        "        String str = \"\";\n" +
+                                        "        List<String> l = f<caret>oo(foo(str, str), str);\n" +
+                                        "    }\n" +
+                                        "}\n");
+    final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getCaretOffset());
+    Assert.assertTrue(elementAtCaret instanceof PsiIdentifier);
+
+    final PsiElement refExpr = elementAtCaret.getParent();
+    Assert.assertTrue(refExpr.toString(), refExpr instanceof PsiExpression);
+    final PsiType type = ((PsiExpression)refExpr).getType();
+    Assert.assertNotNull(refExpr.toString(), type);
+    Assert.assertTrue(type.getCanonicalText(), type.equalsToText("java.util.List<java.lang.String>"));
+  }
+
+  @NotNull
+  @Override
+  protected LightProjectDescriptor getProjectDescriptor() {
+    return JAVA_8;
+  }
+}
index 10832088f537be9cd0bfa9ff3b6e24989db7fea6..31bbe648ea1e155db2c9c841ec43b1aa9baaa715 100644 (file)
@@ -99,6 +99,10 @@ public class MostSpecificResolutionTest extends LightDaemonAnalyzerTestCase {
     doTest();
   }
 
+  public void testTargetTypeParameter() throws Exception {
+    doTest(false);
+  }
+
   private void doTest() {
     doTest(true);
   }
index 692706fa350ae78bde84cef59264bd818e095fc4..6f7b5aa51a3cefbbaac95309a24b81a65e9b5051 100644 (file)
@@ -214,6 +214,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
     doTest();
   }
 
+  public void testIDEA124547() throws Exception {
+    doTest();
+  }
+
   private void doTest() {
     doTest(false);
   }
index e3a4f92db57393a5d799f01a5cc3fb1c89278ed9..2cd737e5ed785fc3d24ce92394742bfba9ae10d3 100644 (file)
@@ -49,4 +49,8 @@ public class DeprecationInspectionTest extends InspectionTestCase {
     doTest();
   }
 
+  public void testDeprecatedDefaultConstructorFromTypeParameter() throws Exception {
+    doTest();
+  }
+
 }
index 1d00526eacf7a502446e5bd0bdb31e6cfc66ca18..39f83d4f7796484cbee8cf0ef0fba1d4d4656167 100644 (file)
@@ -5,6 +5,7 @@ import com.intellij.codeInspection.ex.*;
 import com.intellij.codeInspection.i18n.I18nInspection;
 import com.intellij.psi.PsiElement;
 import com.intellij.testFramework.InspectionTestCase;
+import com.siyeh.ig.migration.RawUseOfParameterizedTypeInspection;
 import org.jetbrains.annotations.NotNull;
 
 public class RedundantSuppressTest extends InspectionTestCase {
@@ -15,7 +16,9 @@ public class RedundantSuppressTest extends InspectionTestCase {
   protected void setUp() throws Exception {
     super.setUp();
     InspectionToolRegistrar.getInstance().ensureInitialized();
-    myInspectionToolWrappers = new InspectionToolWrapper[]{new LocalInspectionToolWrapper(new I18nInspection()),
+    myInspectionToolWrappers = new InspectionToolWrapper[]{
+      new LocalInspectionToolWrapper(new I18nInspection()),
+      new LocalInspectionToolWrapper(new RawUseOfParameterizedTypeInspection()),
       new GlobalInspectionToolWrapper(new EmptyMethodInspection())};
 
     myWrapper = new GlobalInspectionToolWrapper(new RedundantSuppressInspection() {
@@ -30,6 +33,10 @@ public class RedundantSuppressTest extends InspectionTestCase {
     doTest();
   }
 
+  public void testAlternativeIds() throws Exception {
+    doTest();
+  }
+
   public void testSuppressAll() throws Exception {
     try {
       ((RedundantSuppressInspection)myWrapper.getTool()).IGNORE_ALL = true;
index 22e972f55d1bcacdd2f5585d562682adad0f70ee..cd966088d6e3828506bbd35d75194c27f31d56c2 100644 (file)
@@ -2,7 +2,9 @@ package com.intellij.codeInspection;
 
 import com.intellij.JavaTestUtil;
 import com.intellij.codeInspection.miscGenerics.SuspiciousCollectionsMethodCallsInspection;
+import com.intellij.testFramework.LightProjectDescriptor;
 import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
 
 public class SuspiciousCollectionMethodCallsTest extends LightCodeInsightFixtureTestCase {
   private final SuspiciousCollectionsMethodCallsInspection myTool = new SuspiciousCollectionsMethodCallsInspection();
@@ -17,10 +19,17 @@ public class SuspiciousCollectionMethodCallsTest extends LightCodeInsightFixture
     myFixture.testHighlighting(getTestName(false) + ".java");
   }
 
+  public void testConcurrentHashMap() throws Exception { doTest(); }
   public void testUseDfa() throws Exception { doTest(); }
   public void testWildcard() throws Exception { doTest(); }
   public void testIgnoreConvertible() throws Exception {
     myTool.REPORT_CONVERTIBLE_METHOD_CALLS = false;
     doTest();
   }
+
+  @NotNull
+  @Override
+  protected LightProjectDescriptor getProjectDescriptor() {
+    return JAVA_8;
+  }
 }
index 903ad9168dd55214e554bd2e5e03a8d788e46fcf..04c21395d4dfc283cf4028857e432fba5f99da05 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.
@@ -59,7 +59,7 @@ public class JarVersionDetectionUtil {
   }
 
   /** @deprecated use {@link JarUtil#getJarAttribute(File, Attributes.Name)} (to remove in IDEA 15) */
-  @SuppressWarnings("UnusedDeclaration")
+  @SuppressWarnings({"UnusedDeclaration", "deprecation"})
   public static String detectJarVersion(@Nullable com.intellij.openapi.vfs.JarFile zipFile) {
     if (zipFile == null) {
       return null;
index 5e407b39da541e1ee9a2fc70de1691b4978849f6..d6e4101c608687cad9c0428572992cc5de7edf5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,9 +40,9 @@ public class CheckBox extends JCheckBox {
     private static boolean getPropertyValue(InspectionProfileEntry owner,
                                             String property) {
         try {
-            final Class<? extends InspectionProfileEntry> aClass =
-                    owner.getClass();
-            final Field field = aClass.getField(property);
+            final Class<? extends InspectionProfileEntry> aClass = owner.getClass();
+            final Field field = getField(aClass, property);
+            field.setAccessible(true);
             return field.getBoolean(owner);
         } catch (IllegalAccessException ignore) {
             return false;
@@ -51,6 +51,19 @@ public class CheckBox extends JCheckBox {
         }
     }
 
+  static Field getField(Class clazz, String fieldName) throws NoSuchFieldException {
+    try {
+      return clazz.getDeclaredField(fieldName);
+    } catch (NoSuchFieldException e) {
+      final Class superClass = clazz.getSuperclass();
+      if (superClass == null) {
+        throw e;
+      } else {
+        return getField(superClass, fieldName);
+      }
+    }
+  }
+
     private static class SingleCheckboxChangeListener
             implements ChangeListener {
 
@@ -73,9 +86,9 @@ public class CheckBox extends JCheckBox {
                                              String property,
                                              boolean selected) {
             try {
-                final Class<? extends InspectionProfileEntry> aClass =
-                        owner.getClass();
-                final Field field = aClass.getField(property);
+                final Class<? extends InspectionProfileEntry> aClass = owner.getClass();
+                final Field field = getField(aClass, property);
+                field.setAccessible(true);
                 field.setBoolean(owner, selected);
             } catch (IllegalAccessException ignore) {
                 // do nothing
index be4ec5be6e2355e9f063fcae912abc923063a6f4..c363a815577ada174a45319942dbb33042aae173 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.
@@ -22,9 +22,7 @@ import java.io.InputStream;
 import java.util.Enumeration;
 import java.util.zip.ZipFile;
 
-/**
- * Encapsulates operations with .jar file
- */
+/** @deprecated causes ZipFile leaks, do not use (to be removed in IDEA 15) */
 public interface JarFile {
   interface JarEntry {
     String getName();
index 8cfc405ed8ebc8516f7d5cfa699463d892f2a155..3e5959c3661c5294bff678a776cc9e92b63df29b 100644 (file)
@@ -58,6 +58,7 @@ public interface CommonClassNames {
   @NonNls String JAVA_UTIL_MAP = "java.util.Map";
   @NonNls String JAVA_UTIL_MAP_ENTRY = "java.util.Map.Entry";
   @NonNls String JAVA_UTIL_HASH_MAP = "java.util.HashMap";
+  @NonNls String JAVA_UTIL_CONCURRENT_HASH_MAP = "java.util.concurrent.ConcurrentHashMap";
   @NonNls String JAVA_UTIL_LIST = "java.util.List";
   @NonNls String JAVA_UTIL_ARRAY_LIST = "java.util.ArrayList";
   @NonNls String JAVA_UTIL_SET = "java.util.Set";
index 8a46c4ed707610a4ba242f9f037ce2757be30dd9..4fb5cc3fcb2a328ff11689a1c0f9e0c4658ac385 100644 (file)
@@ -57,7 +57,7 @@ import com.intellij.psi.stubs.StubTreeLoader;
 import com.intellij.util.Consumer;
 import com.intellij.util.Function;
 import com.intellij.util.Processor;
-import com.intellij.util.messages.impl.MessageBusImpl;
+import com.intellij.util.messages.MessageBusFactory;
 import org.jetbrains.annotations.NotNull;
 import org.picocontainer.MutablePicoContainer;
 
@@ -105,7 +105,7 @@ public class CoreApplicationEnvironment {
     }, null));
 
     VirtualFileSystem[] fs = {myLocalFileSystem, myJarFileSystem};
-    VirtualFileManagerImpl virtualFileManager = new VirtualFileManagerImpl(fs, new MessageBusImpl(myApplication, null));
+    VirtualFileManagerImpl virtualFileManager = new VirtualFileManagerImpl(fs, MessageBusFactory.newMessageBus(myApplication));
     registerComponentInstance(appContainer, VirtualFileManager.class, virtualFileManager);
 
     registerApplicationService(VirtualFilePointerManager.class, createVirtualFilePointerManager());
index d7fcde008e770cba1fe28907c826902b16de0535..5889dbf48c6369425b7965f26f3e8e6f48d0a0a0 100644 (file)
@@ -40,7 +40,8 @@ import com.intellij.psi.search.ProjectScopeBuilder;
 import com.intellij.psi.util.CachedValuesManager;
 import com.intellij.psi.util.PsiModificationTracker;
 import com.intellij.util.CachedValuesManagerImpl;
-import com.intellij.util.messages.impl.MessageBusImpl;
+import com.intellij.util.messages.MessageBus;
+import com.intellij.util.messages.MessageBusFactory;
 import org.jetbrains.annotations.NotNull;
 import org.picocontainer.PicoContainer;
 
@@ -51,7 +52,7 @@ public class CoreProjectEnvironment {
   protected final FileIndexFacade myFileIndexFacade;
   protected final PsiManagerImpl myPsiManager;
   protected final MockProject myProject;
-  protected final MessageBusImpl myMessageBus;
+  protected final MessageBus myMessageBus;
 
   public CoreProjectEnvironment(Disposable parentDisposable, CoreApplicationEnvironment applicationEnvironment) {
     myParentDisposable = parentDisposable;
@@ -61,7 +62,7 @@ public class CoreProjectEnvironment {
     preregisterServices();
 
     myFileIndexFacade = createFileIndexFacade();
-    myMessageBus = new MessageBusImpl("CoreProjectEnvironment", null);
+    myMessageBus = MessageBusFactory.newMessageBus("CoreProjectEnvironment");
 
     PsiModificationTrackerImpl modificationTracker = new PsiModificationTrackerImpl(myProject);
     myProject.registerService(PsiModificationTracker.class, modificationTracker);
index 06f8391e10b49a48f6c1f905001231ec06708ac7..d5f8610f3567a45b99aba7a45c09d577dedfd8ed 100644 (file)
@@ -17,16 +17,12 @@ package com.intellij.openapi.vfs.impl.jar;
 
 import com.intellij.openapi.diagnostic.LogUtil;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream;
-import com.intellij.openapi.util.io.FileAttributes;
-import com.intellij.openapi.util.io.FileSystemUtil;
-import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.*;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.JarFile;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.reference.SoftReference;
 import com.intellij.util.ArrayUtil;
-import com.intellij.util.TimedReference;
 import gnu.trove.THashMap;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -45,10 +41,9 @@ public class JarHandlerBase {
   protected static final long DEFAULT_LENGTH = 0L;
   protected static final long DEFAULT_TIMESTAMP = -1L;
 
-  private final TimedReference<JarFile> myJarFile = new TimedReference<JarFile>(null);
+  private final Object myLock = new Object();
   private volatile Reference<Map<String, EntryInfo>> myRelPathsToEntries = new SoftReference<Map<String, EntryInfo>>(null);
   private boolean myCorruptedJar = false;
-  private final Object myLock = new Object();
 
   protected final String myBasePath;
 
@@ -76,34 +71,17 @@ public class JarHandlerBase {
     return originalFile;
   }
 
-  @Nullable
+  /** @deprecated to be removed in IDEA 15 */
+  @SuppressWarnings("deprecation")
   public JarFile getJar() {
-    JarFile jar = myJarFile.get();
-    if (jar == null) {
-      synchronized (myLock) {
-        if (myCorruptedJar) {
-          return null;
-        }
-        jar = myJarFile.get();
-        if (jar == null) {
-          try {
-            jar = createJarFile();
-            myJarFile.set(jar);
-          }
-          catch (IOException e) {
-            myCorruptedJar = true;
-            LOG.warn(e.getMessage() + ": " + myBasePath, e);
-            return null;
-          }
-        }
-      }
+    try {
+      File mirror = getMirrorFile(getOriginalFile());
+      return new MyJarFile(new ZipFile(mirror));
+    }
+    catch (IOException e) {
+      LOG.warn(e.getMessage() + ": " + myBasePath, e);
+      return null;
     }
-    return jar;
-  }
-
-  private JarFile createJarFile() throws IOException {
-    File mirrorFile = getMirrorFile(getOriginalFile());
-    return new MyJarFile(new ZipFile(mirrorFile));
   }
 
   @NotNull
@@ -146,25 +124,34 @@ public class JarHandlerBase {
         map = SoftReference.dereference(myRelPathsToEntries);
 
         if (map == null) {
-          JarFile zip = getJar();
-          if (zip != null) {
+          if (myCorruptedJar) {
+            map = Collections.emptyMap();
+          }
+          else {
             LogUtil.debug(LOG, "mapping %s", myBasePath);
-
             map = new THashMap<String, EntryInfo>();
             map.put("", new EntryInfo(null, "", true, DEFAULT_LENGTH, DEFAULT_TIMESTAMP));
 
-            Enumeration<? extends JarFile.JarEntry> entries = zip.entries();
-            while (entries.hasMoreElements()) {
-              JarFile.JarEntry entry = entries.nextElement();
-              if (entry == null) break;  // corrupted .jar
-              getOrCreate(entry, map, zip);
+            try {
+              ZipFile zip = getZipFile();
+              try {
+                Enumeration<? extends ZipEntry> entries = zip.entries();
+                while (entries.hasMoreElements()) {
+                  getOrCreate(entries.nextElement(), map, zip);
+                }
+              }
+              finally {
+                ZipFileCache.release(zip);
+              }
+            }
+            catch (IOException e) {
+              myCorruptedJar = true;
+              LOG.warn(e.getMessage() + ": " + myBasePath, e);
+              map = Collections.emptyMap();
             }
-
-            myRelPathsToEntries = new SoftReference<Map<String, EntryInfo>>(Collections.unmodifiableMap(map));
-          }
-          else {
-            map = Collections.emptyMap();
           }
+
+          myRelPathsToEntries = new SoftReference<Map<String, EntryInfo>>(Collections.unmodifiableMap(map));
         }
       }
     }
@@ -172,7 +159,13 @@ public class JarHandlerBase {
   }
 
   @NotNull
-  private static EntryInfo getOrCreate(JarFile.JarEntry entry, Map<String, EntryInfo> map, JarFile zip) {
+  private ZipFile getZipFile() throws IOException {
+    File mirror = getMirrorFile(getOriginalFile());
+    return ZipFileCache.acquire(mirror.getPath());
+  }
+
+  @NotNull
+  private static EntryInfo getOrCreate(ZipEntry entry, Map<String, EntryInfo> map, ZipFile zip) {
     boolean isDirectory = entry.isDirectory();
     String entryName = entry.getName();
     if (StringUtil.endsWithChar(entryName, '/')) {
@@ -199,11 +192,11 @@ public class JarHandlerBase {
   }
 
   @NotNull
-  private static EntryInfo getOrCreate(String entryName, Map<String, EntryInfo> map, JarFile zip) {
+  private static EntryInfo getOrCreate(String entryName, Map<String, EntryInfo> map, ZipFile zip) {
     EntryInfo info = map.get(entryName);
 
     if (info == null) {
-      JarFile.JarEntry entry = zip.getEntry(entryName + "/");
+      ZipEntry entry = zip.getEntry(entryName + "/");
       if (entry != null) {
         return getOrCreate(entry, map, zip);
       }
@@ -218,8 +211,7 @@ public class JarHandlerBase {
     }
 
     if (!info.isDirectory) {
-      //noinspection ConstantConditions
-      LOG.info(zip.getZipFile().getName() + ": " + entryName + " should be a directory");
+      LOG.info(zip.getName() + ": " + entryName + " should be a directory");
       info = new EntryInfo(info.parent, info.shortName, true, info.length, info.timestamp);
       map.put(entryName, info);
     }
@@ -246,11 +238,9 @@ public class JarHandlerBase {
   }
 
   public boolean exists(@NotNull VirtualFile file) {
-    if (file.getParent() == null) {
-      return myJarFile.get() != null || getOriginalFile().exists();
-    }
-
-    return getEntryInfo(file) != null;
+    if (file.getParent() == null) return getOriginalFile().exists();
+    EntryInfo info = getEntryInfo(file);
+    return info != null;
   }
 
   @Nullable
@@ -271,11 +261,11 @@ public class JarHandlerBase {
 
   @NotNull
   public byte[] contentsToByteArray(@NotNull VirtualFile file) throws IOException {
-    JarFile jar = getJar();
-    if (jar != null) {
-      JarFile.JarEntry entry = jar.getEntry(getRelativePath(file));
+    ZipFile zip = getZipFile();
+    try {
+      ZipEntry entry = zip.getEntry(getRelativePath(file));
       if (entry != null) {
-        InputStream stream = jar.getInputStream(entry);
+        InputStream stream = zip.getInputStream(entry);
         if (stream != null) {
           try {
             return FileUtil.loadBytes(stream, (int)entry.getSize());
@@ -286,9 +276,13 @@ public class JarHandlerBase {
         }
       }
     }
+    finally {
+      ZipFileCache.release(zip);
+    }
     return ArrayUtil.EMPTY_BYTE_ARRAY;
   }
 
+  @SuppressWarnings("deprecation")
   private static class MyJarFile implements JarFile {
     private static class MyJarEntry implements JarFile.JarEntry {
       private final ZipEntry myEntry;
index dfbb2ae08b2d77ecfc74c410c0dc045ed4c6aeb5..5202aa291224763952d234e5263c0548f4131d15 100644 (file)
@@ -140,20 +140,34 @@ public class AnActionEvent implements PlaceProvider<String> {
     return key.getData(getDataContext());
   }
 
-  @NotNull
-  public <T> T getDataChecked(@NotNull DataKey<T> key) {
-    T data = getData(key);
-    assert data != null;
-    return data;
-  }
-
   /**
-   * @deprecated
-   * @use getDataChecked
+   * Returns not null data by a data key. This method assumes that data has been checked for null in AnAction#update method.
+   *<br/><br/>
+   * Example of proper usage:
+   *
+   * <pre>
+   *
+   * public class MyAction extends AnAction {
+   *   public void update(AnActionEvent e) {
+   *     //perform action if and only if EDITOR != null
+   *     boolean enabled = e.getData(CommonDataKeys.EDITOR) != null;
+   *     e.getPresentation.setEnabled(enabled);
+   *   }
+   *
+   *   public void actionPerformed(AnActionEvent e) {
+   *     //if we're here then EDITOR != null
+   *     Document doc = e.getRequiredData(CommonDataKeys.EDITOR).getDocument();
+   *     doSomething(doc);
+   *   }
+   * }
+   *
+   * </pre>
    */
   @NotNull
   public <T> T getRequiredData(@NotNull DataKey<T> key) {
-    return getDataChecked(key);
+    T data = getData(key);
+    assert data != null;
+    return data;
   }
 
   /**
index fd89fea5b04a950a444d04ab984e848c63041508..b5f88830119cd96635ed564590d4d685e23b5d0e 100644 (file)
@@ -107,7 +107,8 @@ public abstract class RunConfigurationExtensionBase<T extends RunConfigurationBa
    * @throws ExecutionException if there was an error configuring the command line and the execution should be canceled.
    */
   protected abstract void patchCommandLine(@NotNull final T configuration,
-                                           RunnerSettings runnerSettings, @NotNull final GeneralCommandLine cmdLine,
+                                           @Nullable RunnerSettings runnerSettings, 
+                                           @NotNull final GeneralCommandLine cmdLine,
                                            @NotNull final String runnerId) throws ExecutionException;
 
   /**
@@ -119,7 +120,7 @@ public abstract class RunConfigurationExtensionBase<T extends RunConfigurationBa
    */
   protected void attachToProcess(@NotNull final T configuration,
                                  @NotNull final ProcessHandler handler,
-                                 RunnerSettings runnerSettings) {
+                                 @Nullable RunnerSettings runnerSettings) {
 
   }
 
index 579f0f9e4bb716db8e2dab48581940f98ae045da..c52f6c9da729d7f7962bc01bfe9af065119857d3 100644 (file)
@@ -160,7 +160,7 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
     }
   }
 
-  private List<T> getApplicableExtensions(@NotNull final U configuration) {
+  protected List<T> getApplicableExtensions(@NotNull final U configuration) {
     final List<T> extensions = new ArrayList<T>();
     for (T extension : Extensions.getExtensions(myExtensionPointName)) {
       if (extension.isApplicableFor(configuration)) {
@@ -170,7 +170,7 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
     return extensions;
   }
 
-  private List<T> getEnabledExtensions(@NotNull final U configuration, @Nullable RunnerSettings runnerSettings) {
+  protected List<T> getEnabledExtensions(@NotNull final U configuration, @Nullable RunnerSettings runnerSettings) {
     final List<T> extensions = new ArrayList<T>();
     for (T extension : Extensions.getExtensions(myExtensionPointName)) {
       if (extension.isApplicableFor(configuration) && extension.isEnabledFor(configuration, runnerSettings)) {
index 6ba7340598b78bd11896b62d791ee7d0a2e93d3a..bc7499f726747726a9e8e5fd4700f1c8b8f896bb 100644 (file)
@@ -751,7 +751,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
   }
 
   private boolean isTheAmountOfTextTooBig(final int textLength) {
-    return textLength > myBuffer.getCyclicBufferSize() / 50; //magic number, it has no deep meaning
+    return textLength > myBuffer.getCyclicBufferSize() / 10; //magic number, it has no deep meaning
   }
 
   private void clearHyperlinkAndFoldings() {
index 9a351928c96b1edc5432f0eed0773f4a11e71a3c..37994de8a17682b2842ba1ed1b0212d970cdd9d2 100644 (file)
@@ -81,6 +81,7 @@ public class QuickChangeCodeStyleSchemeAction extends QuickSwitchSchemeAction {
         }
         CodeStyleSchemes.getInstance().setCurrentScheme(scheme);
         manager.USE_PER_PROJECT_SETTINGS = false;
+        manager.PREFERRED_PROJECT_CODE_STYLE = scheme.getName();
         EditorFactory.getInstance().refreshAllEditors();
       }
     });
index 2002246d4a051db943c6c73a2536122d59657377..3b342800269b1d97b8bf7e056a1bedef867fc75e 100644 (file)
@@ -197,7 +197,9 @@ class FilterDialog extends DialogWrapper {
         case 0:
           TodoPattern pattern = myPatterns.get(row);
           if (((Boolean)value).booleanValue()) {
-            myFilter.addTodoPattern(pattern);
+            if (!myFilter.contains(pattern)) {
+              myFilter.addTodoPattern(pattern);
+            }
           }
           else {
             myFilter.removeTodoPattern(pattern);
index a94b4420f2528e04f5d7e69b78cf901e35769ed9..b4c0e77ec10ff9771d1057f3c29a52b7cf21c52d 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.
@@ -39,7 +39,8 @@ public abstract class JarFileSystem extends NewVirtualFileSystem implements JarC
   @Nullable
   public abstract VirtualFile getVirtualFileForJar(@Nullable VirtualFile entryVFile);
 
-  /** @deprecated do not use (leaks file handles), to remove in IDEA 15 */
+  /** @deprecated to be removed in IDEA 15 */
+  @SuppressWarnings({"UnusedDeclaration", "deprecation"})
   public abstract JarFile getJarFile(@NotNull VirtualFile entryVFile) throws IOException;
 
   /**
index e6b73e6095cd49135e18583f74d817e42aca0a5b..37ab37828658a622adcb1a6c8544a76efae8af23 100644 (file)
@@ -765,8 +765,13 @@ public final class EditorUtil {
   }
 
   public static void scrollToTheEnd(@NotNull Editor editor) {
-    editor.getCaretModel().moveToOffset(editor.getDocument().getTextLength());
     editor.getSelectionModel().removeSelection();
+    int lastLine = Math.max(0, editor.getDocument().getLineCount() - 1);
+    if (editor.getCaretModel().getLogicalPosition().line == lastLine) {
+      editor.getCaretModel().moveToOffset(editor.getDocument().getTextLength());
+    } else {
+      editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(lastLine, 0));
+    }
     editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
   }
 
index 313630083c1f36c6ed5a6b0c5656f71ed68a0dcd..bf0027c675ad77280b80b6984abb7583fbe10eec 100644 (file)
@@ -215,20 +215,19 @@ public class FileContentQueue {
             if (isValidFile(virtualFileToLoad)) {
               try {
                 content.getBytes();
+                return content;
+              }
+              catch (IOException e) {
+                LOG.info(virtualFileToLoad + ": " + e);
+              }
+              catch (InvalidVirtualFileAccessException e) {
+                LOG.info(virtualFileToLoad + ": " + e);
               }
               catch (Throwable t) {
-                if (t instanceof IOException || t instanceof InvalidVirtualFileAccessException) {
-                  LOG.info(t);
-                }
-                else {
-                  LOG.error(t);
-                }
-                content.setEmptyContent();
+                LOG.error(virtualFileToLoad + ": " + t);
               }
             }
-            else {
-              content.setEmptyContent();
-            }
+            content.setEmptyContent();
             return content;
           }
 
index 9ad72c75dc9a387c1841fa5eb2b491f5516b5084..e86ea895cd9b78d1391ad33326f49e02ddc26d3b 100644 (file)
@@ -22,6 +22,7 @@ import com.intellij.openapi.components.ApplicationComponent;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.io.FileAttributes;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.ZipFileCache;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.*;
 import com.intellij.openapi.vfs.newvfs.*;
@@ -39,7 +40,6 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -64,7 +64,7 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo
     bus.connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
       @Override
       public void after(@NotNull List<? extends VFileEvent> events) {
-        List<VirtualFile> rootsToRefresh = new ArrayList<VirtualFile>();
+        List<VirtualFile> rootsToRefresh = ContainerUtil.newSmartList();
 
         for (VFileEvent event : events) {
           if (event.getFileSystem() instanceof LocalFileSystem) {
@@ -91,6 +91,14 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo
         }
 
         if (!rootsToRefresh.isEmpty()) {
+          List<String> pathsToReset = ContainerUtil.newArrayListWithCapacity(rootsToRefresh.size());
+          for (VirtualFile root : rootsToRefresh) {
+            String rootPath = root.getPath();
+            String jarPath = rootPath.substring(0, rootPath.length() - 2);
+            pathsToReset.add(FileUtil.toSystemDependentName(jarPath));
+          }
+          ZipFileCache.reset(pathsToReset);
+
           boolean async = !ApplicationManager.getApplication().isUnitTestMode();
           RefreshQueue.getInstance().refresh(async, true, null, rootsToRefresh);
         }
@@ -144,7 +152,9 @@ public class JarFileSystemImpl extends JarFileSystem implements ApplicationCompo
     return StandardFileSystems.getVirtualFileForJar(entryVFile);
   }
 
+  @SuppressWarnings("deprecation")
   @Override
+  /** @deprecated to be removed in IDEA 15 */
   public JarFile getJarFile(@NotNull VirtualFile entryVFile) throws IOException {
     return getHandler(entryVFile).getJar();
   }
similarity index 99%
rename from platform/util/testSrc/com/intellij/util/messages/MessageBusTest.java
rename to platform/platform-tests/testSrc/com/intellij/util/messages/MessageBusTest.java
index e27dbc606d5d9e092eec04f94bf8ef9fabfec259..d0b5829dccca3c8482b876e25b25bd889941e4a5 100644 (file)
@@ -215,7 +215,7 @@ public class MessageBusTest extends TestCase {
       new MessageBusImpl(this, childBus);
     }
 
-    PlatformTestUtil.assertTiming("Too long", 2000, new Runnable() {
+    PlatformTestUtil.assertTiming("Too long", 2500, new Runnable() {
       @Override
       public void run() {
         T1Listener publisher = myBus.syncPublisher(TOPIC1);
index 735f0bd8537bc96e22652279dc31db70e19f8383..b7c2f266faaa81997f51aa1a86d3942df7939128 100644 (file)
@@ -9,14 +9,12 @@ import com.intellij.psi.*;
 import com.intellij.psi.impl.source.tree.ForeignLeafPsiElement;
 import com.intellij.util.DocumentUtil;
 import com.intellij.xdebugger.XSourcePosition;
-import org.jetbrains.annotations.Contract;
 import org.jetbrains.annotations.NotNull;
 
 public final class PsiVisitors {
   /**
-   * Read action will be taken automatically.
+   * Read action will be taken automatically
    */
-  @Contract("_, _, _, null -> null")
   public static <RESULT> RESULT visit(@NotNull XSourcePosition position, @NotNull Project project, @NotNull Visitor<RESULT> visitor, RESULT defaultResult) {
     Document document = FileDocumentManager.getInstance().getDocument(position.getFile());
     AccessToken token = ReadAction.start();
@@ -27,7 +25,7 @@ public final class PsiVisitors {
       }
 
       int positionOffset;
-      int column = position instanceof SourceInfo ? Math.min(((SourceInfo)position).getColumn(), 0) : 0;
+      int column = position instanceof SourceInfo ? Math.max(((SourceInfo)position).getColumn(), 0) : 0;
       try {
         positionOffset = column == 0 ? DocumentUtil.getFirstNonSpaceCharOffset(document, position.getLine()) : document.getLineStartOffset(position.getLine()) + column;
       }
index 6a5e7452dc932fc138fa4d5c3fbae9f2745563e6..0b7c43a3684c757a3cb08990f5b8f510380624a2 100644 (file)
@@ -1,13 +1,19 @@
 package org.jetbrains.debugger;
 
 import com.intellij.icons.AllIcons;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.ActionCallback;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.pom.Navigatable;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
 import com.intellij.util.Consumer;
 import com.intellij.util.PairConsumer;
 import com.intellij.util.SmartList;
 import com.intellij.util.ThreeState;
 import com.intellij.xdebugger.ObsolescentAsyncResults;
+import com.intellij.xdebugger.XSourcePositionWrapper;
 import com.intellij.xdebugger.frame.*;
 import com.intellij.xdebugger.frame.presentation.XKeywordValuePresentation;
 import com.intellij.xdebugger.frame.presentation.XNumericValuePresentation;
@@ -476,7 +482,44 @@ public final class VariableView extends XNamedValue implements VariableContext {
           getViewSupport().getVm().getScriptManager().getScript(function).doWhenDone(new Consumer<Script>() {
             @Override
             public void consume(Script script) {
-              navigatable.setSourcePosition(script == null ? null : getViewSupport().getSourceInfo(null, script, function.getOpenParenLine(), function.getOpenParenColumn()));
+              SourceInfo position = script == null ? null : getViewSupport().getSourceInfo(null, script, function.getOpenParenLine(), function.getOpenParenColumn());
+              navigatable.setSourcePosition(position == null ? null : new XSourcePositionWrapper(position) {
+                @NotNull
+                @Override
+                public Navigatable createNavigatable(@NotNull Project project) {
+                  Navigatable result = PsiVisitors.visit(myPosition, project, new PsiVisitors.Visitor<Navigatable>() {
+                    @Override
+                    public Navigatable visit(@NotNull PsiElement element, int positionOffset, @NotNull Document document) {
+                      // element will be "open paren", but we should navigate to function name,
+                      // we cannot use specific PSI type here (like JSFunction), so, we try to find reference expression (i.e. name expression)
+                      PsiElement referenceCandidate = element;
+                      PsiElement psiReference = null;
+                      while ((referenceCandidate = referenceCandidate.getPrevSibling()) != null) {
+                        if (referenceCandidate instanceof PsiReference) {
+                          psiReference = referenceCandidate;
+                          break;
+                        }
+                      }
+
+                      if (psiReference == null) {
+                        referenceCandidate = element.getParent();
+                        if (referenceCandidate != null) {
+                          while ((referenceCandidate = referenceCandidate.getPrevSibling()) != null) {
+                            if (referenceCandidate instanceof PsiReference) {
+                              psiReference = referenceCandidate;
+                              break;
+                            }
+                          }
+                        }
+                      }
+
+                      PsiElement navigationElement = psiReference == null ? element.getNavigationElement() : psiReference.getNavigationElement();
+                      return navigationElement instanceof Navigatable ? (Navigatable)navigationElement : null;
+                    }
+                  }, null);
+                  return result == null ? super.createNavigatable(project) : result;
+                }
+              });
             }
           });
         }
index 576be2355972584146b873bfe0ec78335919153a..03771742ba3dc431933f1a2b07b56cf71c1c8934 100644 (file)
  */
 package com.intellij.testFramework;
 
+import com.intellij.openapi.Disposable;
 import com.intellij.openapi.application.PathManager;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
+import org.apache.log4j.Level;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.xml.DOMConfigurator;
 import org.jetbrains.annotations.NotNull;
@@ -106,4 +109,16 @@ public class TestLoggerFactory implements Logger.Factory {
     }
   }
 
+  public static void enableDebugLogging(@NotNull Disposable parentDisposable, String... categories) {
+    for (String category : categories) {
+      final Logger logger = Logger.getInstance(category);
+      logger.setLevel(Level.DEBUG);
+      Disposer.register(parentDisposable, new Disposable() {
+        @Override
+        public void dispose() {
+          logger.setLevel(Level.INFO);
+        }
+      });
+    }
+  }
 }
\ No newline at end of file
index 99bfa4addb85fcc15617c9692b8374d075cc0974..898d9d04bd28fd174417e9812642ceed99d821be 100644 (file)
@@ -938,20 +938,4 @@ public abstract class UsefulTestCase extends TestCase {
     }.process(test);
     return testSuite;
   }
-
-  protected void findHandlerAndDoRename(final String newName, Editor editor, Project project, PsiFile file) {
-    final DataContext editorContext = ((EditorEx)editor).getDataContext();
-    final DataContext context = new DataContext() {
-      @Override
-      public Object getData(@NonNls String dataId) {
-        return PsiElementRenameHandler.DEFAULT_NAME.getName().equals(dataId)
-               ? newName
-               : editorContext.getData(dataId);
-      }
-    };
-    final RenameHandler renameHandler = RenameHandlerRegistry.getInstance().getRenameHandler(context);
-    assertNotNull(renameHandler);
-
-    renameHandler.invoke(project, editor, file, context);
-  }
 }
index 658b73fa2bcfec3e1b522e6455f4cdbdae985e7a..6a546467f327bc1bacd915fa008f8464bf99b4cd 100644 (file)
@@ -492,6 +492,13 @@ public interface CodeInsightTestFixture extends IdeaProjectTestFixture {
 
   void renameElementAtCaret(@NotNull String newName);
 
+  /**
+   * Renames element at caret using injected {@link com.intellij.refactoring.rename.RenameHandler}s.
+   * Very close to {@link #renameElementAtCaret(String)} but uses handlers.
+   * @param newName new name for the element.
+   */
+  void renameElementAtCaretUsingHandler(@NotNull String newName);
+
   void renameElement(@NotNull PsiElement element, @NotNull String newName);
 
   void allowTreeAccessForFile(@NotNull VirtualFile file);
index fc48a3f2d5b7fec9f7b37bba99a009d97bd4c7fd..7bc0f5753a85fa80e4b31ff467db4a0ac7e04b58 100644 (file)
@@ -98,8 +98,7 @@ import com.intellij.psi.search.UsageSearchContext;
 import com.intellij.psi.stubs.StubUpdatingIndex;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
-import com.intellij.refactoring.rename.RenameProcessor;
-import com.intellij.refactoring.rename.RenamePsiElementProcessor;
+import com.intellij.refactoring.rename.*;
 import com.intellij.rt.execution.junit.FileComparisonFailure;
 import com.intellij.testFramework.*;
 import com.intellij.testFramework.fixtures.*;
@@ -689,6 +688,23 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig
     renameElement(getElementAtCaret(), newName);
   }
 
+  @Override
+  public void renameElementAtCaretUsingHandler(@NotNull final String newName) {
+      final DataContext editorContext = ((EditorEx)myEditor).getDataContext();
+      final DataContext context = new DataContext() {
+        @Override
+        public Object getData(@NonNls final String dataId) {
+          return PsiElementRenameHandler.DEFAULT_NAME.getName().equals(dataId)
+                 ? newName
+                 : editorContext.getData(dataId);
+        }
+      };
+      final RenameHandler renameHandler = RenameHandlerRegistry.getInstance().getRenameHandler(context);
+      assert renameHandler != null: "No handler for this context";
+
+      renameHandler.invoke(getProject(), myEditor, getFile(), context);
+  }
+
   @Override
   public void renameElement(@NotNull final PsiElement element, @NotNull final String newName) {
     final boolean searchInComments = false;
diff --git a/platform/util/src/com/intellij/openapi/util/io/ZipFileCache.java b/platform/util/src/com/intellij/openapi/util/io/ZipFileCache.java
new file mode 100644 (file)
index 0000000..392a82a
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * 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.intellij.openapi.util.io;
+
+import com.intellij.openapi.diagnostic.LogUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.ConcurrencyUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.zip.ZipFile;
+
+/**
+ * <p>Utility class which tries to keep frequently requested .zip files open
+ * to avoid time loss on closing/reopening ZipFile instances.</p>
+ *
+ * <p>Clients obtain a file by calling {@link #acquire(String)}
+ * and indicate the loss of interest to it via {@link #release(ZipFile)}.
+ * Released files are closed after some period of time (about 30 seconds),
+ * unless requested again within the period.</p>
+ *
+ * <p>Since ZipFiles are read-only objects allowing concurrent access,
+ * a same instance may be returned to a different threads requesting a same path.
+ * A file may be closed only after being released by all applicants.</p>
+ *
+ * <p>The class does not expect .zip files on a disk to be changed,
+ * so it may return an outdated instance of ZipFile (reading from it
+ * may return inaccurate data or even cause an exceptions to happen).
+ * It's a clients' responsibility to keep a track of .zip files
+ * and call the {@link #reset(Collection)} method for a paths
+ * which are possibly changed. Reset paths are removed from the cache
+ * and are closed immediately after being released.</p>
+ */
+public class ZipFileCache {
+  private static final int PERIOD = 10000;   // disposer schedule, ms
+  private static final int TIMEOUT = 30000;  // released file close delay, ms
+
+  private static class CacheRecord {
+    private final String path;
+    private final ZipFile file;
+    private int count = 1;
+    private long released = 0;
+
+    private CacheRecord(@NotNull String path, @NotNull ZipFile file) throws IOException {
+      this.path = path;
+      this.file = file;
+    }
+  }
+
+  private static final Object ourLock = new Object();
+  private static final Map<String, CacheRecord> ourPathCache = ContainerUtil.newTroveMap(FileUtil.PATH_HASHING_STRATEGY);
+  private static final Map<ZipFile, CacheRecord> ourFileCache = ContainerUtil.newHashMap();
+  private static final Map<ZipFile, Integer> ourQueue = ContainerUtil.newHashMap();
+
+  static {
+    ConcurrencyUtil.newSingleScheduledThreadExecutor("ZipFileCache Dispose", Thread.MIN_PRIORITY).scheduleWithFixedDelay(new Runnable() {
+      @Override
+      public void run() {
+        List<ZipFile> toClose = getFilesToClose(0, System.currentTimeMillis() - TIMEOUT);
+        if (toClose != null) {
+          close(toClose);
+        }
+      }
+    }, PERIOD, PERIOD, TimeUnit.MILLISECONDS);
+  }
+
+  @NotNull
+  public static ZipFile acquire(@NotNull String path) throws IOException {
+    path = FileUtil.toCanonicalPath(path);
+
+    synchronized (ourLock) {
+      CacheRecord record = ourPathCache.get(path);
+      if (record != null) {
+        record.count++;
+        return record.file;
+      }
+    }
+
+    CacheRecord record;
+    ZipFile file = tryOpen(path);
+
+    synchronized (ourLock) {
+      record = ourPathCache.get(path);
+      if (record == null) {
+        record = new CacheRecord(path, file);
+        ourPathCache.put(path, record);
+        ourFileCache.put(file, record);
+        return file;
+      }
+      else {
+        record.count++;
+      }
+    }
+
+    close(file);
+    return record.file;
+  }
+
+  private static ZipFile tryOpen(String path) throws IOException {
+    path = FileUtil.toSystemDependentName(path);
+    debug("opening %s", path);
+    try {
+      return new ZipFile(path);
+    }
+    catch (IOException e) {
+      String reason = e.getMessage();
+      if ("too many open files".equalsIgnoreCase(reason) && tryCloseFiles() > 0) {
+        return new ZipFile(path);
+      }
+      else {
+        throw e;
+      }
+    }
+  }
+
+  private static int tryCloseFiles() {
+    List<ZipFile> toClose = getFilesToClose(5, 0);
+    if (toClose == null) return 0;
+    close(toClose);
+    logger().warn("too many open files, closed: " + toClose.size());
+    return toClose.size();
+  }
+
+  @Nullable
+  private static List<ZipFile> getFilesToClose(int limit, long timeout) {
+    List<ZipFile> toClose = null;
+
+    synchronized (ourLock) {
+      Iterator<CacheRecord> i = ourPathCache.values().iterator();
+      while (i.hasNext() && (limit == 0 || toClose == null || toClose.size() < limit)) {
+        CacheRecord record = i.next();
+        if (record.count <= 0 && (timeout == 0 || record.released <= timeout)) {
+          i.remove();
+          ourFileCache.remove(record.file);
+          if (toClose == null) toClose = ContainerUtil.newArrayList();
+          toClose.add(record.file);
+        }
+      }
+    }
+
+    return toClose;
+  }
+
+  public static void release(@NotNull ZipFile file) {
+    synchronized (ourLock) {
+      CacheRecord record = ourFileCache.get(file);
+      if (record != null) {
+        record.count--;
+        record.released = System.currentTimeMillis();
+        logger().assertTrue(record.count >= 0, record.path);
+        return;
+      }
+
+      Integer count = ourQueue.get(file);
+      if (count != null) {
+        count--;
+        if (count == 0) {
+          ourQueue.remove(file);
+          close(file);
+        }
+        else {
+          ourQueue.put(file, count);
+        }
+        return;
+      }
+    }
+
+    logger().warn(new IllegalArgumentException("stray file: " + file.getName()));
+    close(file);
+  }
+
+  public static void reset(@NotNull Collection<String> paths) {
+    debug("resetting %s", paths);
+
+    List<ZipFile> toClose = ContainerUtil.newSmartList();
+
+    synchronized (ourLock) {
+      for (String path : paths) {
+        CacheRecord record = ourPathCache.remove(path);
+        if (record != null) {
+          ourFileCache.remove(record.file);
+          if (record.count > 0) {
+            ourQueue.put(record.file, record.count);
+          }
+          else {
+            toClose.add(record.file);
+          }
+        }
+      }
+    }
+
+    close(toClose);
+  }
+
+  private static void close(@NotNull List<ZipFile> files) {
+    for (ZipFile file : files) {
+      close(file);
+    }
+  }
+
+  private static void close(@NotNull ZipFile file) {
+    debug("closing %s", file.getName());
+    try {
+      file.close();
+    }
+    catch (IOException e) {
+      logger().info(file.getName(), e);
+    }
+  }
+
+  private static Logger logger() {
+    return Logger.getInstance(ZipFileCache.class);
+  }
+
+  private static void debug(@NotNull String format, Object... args) {
+    LogUtil.debug(logger(), format, args);
+  }
+}
index 6dcbef212b4c630c2b8e6a48092712e5e4817588..a088275a79131264dee89d892f9599d70672716b 100644 (file)
@@ -17,14 +17,12 @@ package com.intellij.util.lang;
 
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.TimedComputable;
+import com.intellij.openapi.util.io.ZipFileCache;
 import com.intellij.util.io.URLUtil;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import sun.misc.Resource;
 
-import java.io.*;
+import java.io.IOException;
 import java.lang.ref.SoftReference;
 import java.net.URL;
 import java.util.Enumeration;
@@ -35,21 +33,8 @@ class JarLoader extends Loader {
   private static final Logger LOG = Logger.getInstance(JarLoader.class);
 
   private final URL myURL;
-  private SoftReference<JarMemoryLoader> myMemoryLoader;
   private final boolean myCanLockJar;
-
-  private final TimedComputable<ZipFile> myZipFileRef = new TimedComputable<ZipFile>(null) {
-    @Override
-    @NotNull
-    protected ZipFile calc() {
-      try {
-        return doGetZipFile();
-      }
-      catch (IOException e) {
-        throw new RuntimeException(e);
-      }
-    }
-  };
+  private SoftReference<JarMemoryLoader> myMemoryLoader;
 
   JarLoader(URL url, boolean canLockJar, int index) throws IOException {
     super(new URL(URLUtil.JAR_PROTOCOL, "", -1, url + "!/"), index);
@@ -57,61 +42,44 @@ class JarLoader extends Loader {
     myCanLockJar = canLockJar;
   }
 
-  void preloadClasses() {
-    ZipFile zipFile = null;
-    try {
-      zipFile = acquireZipFile();
-      if (zipFile == null) return;
-      try {
-        File file = new File(zipFile.getName());
-        myMemoryLoader = new SoftReference<JarMemoryLoader>(JarMemoryLoader.load(file, getBaseURL()));
-      }
-      catch (Exception e) {
-        LOG.error(e);
-      }
-    }
-    catch (Exception e) {
-      // it happens :) eg tools.jar under MacOS
-    }
-    finally {
-      try {
-        releaseZipFile(zipFile);
-      }
-      catch (IOException ignore) {
-
-      }
-    }
-  }
-
-  @Nullable
   private ZipFile acquireZipFile() throws IOException {
-    if (myCanLockJar) {
-      return myZipFileRef.acquire();
-    }
-    return doGetZipFile();
+    String path = FileUtil.unquote(myURL.getFile());
+    //noinspection IOResourceOpenedButNotSafelyClosed
+    return myCanLockJar ? ZipFileCache.acquire(path) : new ZipFile(path);
   }
 
-  private void releaseZipFile(final ZipFile zipFile) throws IOException {
+  private void releaseZipFile(ZipFile zipFile) throws IOException {
     if (myCanLockJar) {
-      myZipFileRef.release();
+      ZipFileCache.release(zipFile);
     }
     else if (zipFile != null) {
       zipFile.close();
     }
   }
 
-  private ZipFile doGetZipFile() throws IOException {
-    return new ZipFile(FileUtil.unquote(myURL.getFile()));
+  void preloadClasses() {
+    try {
+      ZipFile zipFile = acquireZipFile();
+      try {
+        JarMemoryLoader loader = JarMemoryLoader.load(zipFile, getBaseURL());
+        if (loader != null) {
+          myMemoryLoader = new SoftReference<JarMemoryLoader>(loader);
+        }
+      }
+      finally {
+        releaseZipFile(zipFile);
+      }
+    }
+    catch (Exception e) {
+      LOG.error(e);
+    }
   }
 
   @Override
-  void buildCache(final ClasspathCache cache) throws IOException {
-    ZipFile zipFile = null;
+  void buildCache(ClasspathCache cache) throws IOException {
+    ZipFile zipFile = acquireZipFile();
     try {
-      zipFile = acquireZipFile();
-      if (zipFile == null) return;
-
-      final Enumeration<? extends ZipEntry> entries = zipFile.entries();
+      Enumeration<? extends ZipEntry> entries = zipFile.entries();
       while (entries.hasMoreElements()) {
         ZipEntry zipEntry = entries.nextElement();
         String name = zipEntry.getName();
@@ -133,101 +101,26 @@ class JarLoader extends Loader {
       if (resource != null) return resource;
     }
 
-    ZipFile file = null;
     try {
-      file = acquireZipFile();
-      if (file == null) return null;
-      ZipEntry entry = file.getEntry(name);
-      if (entry != null) {
-        return new MyResource(entry, new URL(getBaseURL(), name));
-      }
-    }
-    catch (Exception e) {
-      return null;
-    }
-    finally {
+      ZipFile file = acquireZipFile();
       try {
-        releaseZipFile(file);
-      }
-      catch (IOException ignored) { }
-    }
-
-    return null;
-  }
-
-  private class MyResource extends Resource {
-    private final ZipEntry myEntry;
-    private final URL myUrl;
-
-    public MyResource(ZipEntry name, URL url) {
-      myEntry = name;
-      myUrl = url;
-    }
-
-    @Override
-    public String getName() {
-      return myEntry.getName();
-    }
-
-    @Override
-    public URL getURL() {
-      return myUrl;
-    }
-
-    @Override
-    public URL getCodeSourceURL() {
-      return myURL;
-    }
-
-    @Override
-    @Nullable
-    public InputStream getInputStream() throws IOException {
-      final boolean[] wasReleased = {false};
-      ZipFile file = null;
-
-      try {
-        file = acquireZipFile();
-        if (file == null) {
-          releaseZipFile(file);
-          return null;
+        ZipEntry entry = file.getEntry(name);
+        if (entry != null) {
+          return MemoryResource.load(getBaseURL(), file, entry);
         }
-
-        final InputStream inputStream = file.getInputStream(myEntry);
-        if (inputStream == null) {
-          releaseZipFile(file);
-          return null; // if entry was not found
-        }
-
-        final ZipFile finalFile = file;
-        return new FilterInputStream(inputStream) {
-          private boolean myClosed = false;
-
-          @Override
-          public void close() throws IOException {
-            super.close();
-            if (!myClosed) {
-              releaseZipFile(finalFile);
-            }
-            myClosed = true;
-            wasReleased[0] = true;
-          }
-        };
       }
-      catch (IOException e) {
-        e.printStackTrace();
+      finally {
         releaseZipFile(file);
-        assert !wasReleased[0];
-        return null;
       }
     }
-
-    @Override
-    public int getContentLength() {
-      return (int)myEntry.getSize();
+    catch (Exception e) {
+      LOG.error(e);
     }
+
+    return null;
   }
 
-  @NonNls
+  @Override
   public String toString() {
     return "JarLoader [" + myURL + "]";
   }
index f5761e69ad500cd3fa8a2429339e733ed3449423..e29a37127159c246d21533921621f80c12a5c5d6 100644 (file)
 package com.intellij.util.lang;
 
 import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.util.io.UnsyncByteArrayInputStream;
 import com.intellij.util.io.zip.ZipShort;
 import gnu.trove.THashMap;
 import org.jetbrains.annotations.Nullable;
 import sun.misc.Resource;
 
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
 import java.net.URL;
+import java.util.Enumeration;
 import java.util.Map;
 import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
+import java.util.zip.ZipFile;
 
 /**
  * @author Dmitry Avdeev
- *         Date: 7/12/11
+ * @since 12/07/2011
  */
 public class JarMemoryLoader {
   public static final String SIZE_ENTRY = "META-INF/jb/$$size$$";
@@ -45,73 +46,32 @@ public class JarMemoryLoader {
 
   @Nullable
   public static JarMemoryLoader load(File file, URL baseUrl) throws IOException {
-    FileInputStream inputStream = new FileInputStream(file);
+    ZipFile zipFile = new ZipFile(file);
     try {
-      return load(inputStream, baseUrl);
+      return load(zipFile, baseUrl);
     }
     finally {
-      inputStream.close();
+      zipFile.close();
     }
   }
 
   @Nullable
-  public static JarMemoryLoader load(InputStream inputStream, URL baseUrl) throws IOException {
-    ZipInputStream zipStream = new ZipInputStream(inputStream);
-    try {
-      ZipEntry sizeEntry = zipStream.getNextEntry();
-      if (sizeEntry == null || !sizeEntry.getName().equals(SIZE_ENTRY)) return null;
-      byte[] bytes = FileUtil.loadBytes(zipStream, 2);
-      int size = ZipShort.getValue(bytes);
-
-      JarMemoryLoader loader = new JarMemoryLoader();
-      for (int i = 0; i < size; i++) {
-        ZipEntry entry = zipStream.getNextEntry();
-        if (entry == null) return loader;
-        byte[] content = FileUtil.loadBytes(zipStream, (int)entry.getSize());
-        MyResource resource = new MyResource(entry.getName(), new URL(baseUrl, entry.getName()), content);
-        loader.myResources.put(entry.getName(), resource);
-      }
-      return loader;
-    }
-    finally {
-      zipStream.close();
-    }
-  }
+  public static JarMemoryLoader load(ZipFile zipFile, URL baseUrl) throws IOException {
+    Enumeration<? extends ZipEntry> entries = zipFile.entries();
+    if (!entries.hasMoreElements()) return null;
 
-  private static class MyResource extends Resource {
-    private String myName;
-    private URL myUrl;
-    private final byte[] myContent;
-
-    public MyResource(String name, URL url, byte[] content) {
-      myName = name;
-      myUrl = url;
-      myContent = content;
-    }
+    ZipEntry sizeEntry = entries.nextElement();
+    if (sizeEntry == null || !sizeEntry.getName().equals(SIZE_ENTRY)) return null;
 
-    @Override
-    public String getName() {
-      return myName;
-    }
-
-    @Override
-    public URL getURL() {
-      return myUrl;
-    }
-
-    @Override
-    public URL getCodeSourceURL() {
-      return myUrl;
-    }
-
-    @Override
-    public InputStream getInputStream() throws IOException {
-      return new UnsyncByteArrayInputStream(myContent);
-    }
+    byte[] bytes = FileUtil.loadBytes(zipFile.getInputStream(sizeEntry), 2);
+    int size = ZipShort.getValue(bytes);
 
-    @Override
-    public int getContentLength() throws IOException {
-      return myContent.length;
+    JarMemoryLoader loader = new JarMemoryLoader();
+    for (int i = 0; i < size; i++) {
+      ZipEntry entry = entries.nextElement();
+      MemoryResource resource = MemoryResource.load(baseUrl, zipFile, entry);
+      loader.myResources.put(entry.getName(), resource);
     }
+    return loader;
   }
 }
diff --git a/platform/util/src/com/intellij/util/lang/MemoryResource.java b/platform/util/src/com/intellij/util/lang/MemoryResource.java
new file mode 100644 (file)
index 0000000..6d658a7
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.intellij.util.lang;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.io.UnsyncByteArrayInputStream;
+import org.jetbrains.annotations.NotNull;
+import sun.misc.Resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+class MemoryResource extends Resource {
+  private String myName;
+  private URL myUrl;
+  private final byte[] myContent;
+
+  public MemoryResource(String name, URL url, byte[] content) {
+    myName = name;
+    myUrl = url;
+    myContent = content;
+  }
+
+  @Override
+  public String getName() {
+    return myName;
+  }
+
+  @Override
+  public URL getURL() {
+    return myUrl;
+  }
+
+  @Override
+  public URL getCodeSourceURL() {
+    return myUrl;
+  }
+
+  @Override
+  public InputStream getInputStream() throws IOException {
+    return new UnsyncByteArrayInputStream(myContent);
+  }
+
+  @Override
+  public int getContentLength() throws IOException {
+    return myContent.length;
+  }
+
+  @NotNull
+  public static MemoryResource load(URL baseUrl, @NotNull ZipFile zipFile, @NotNull ZipEntry entry) throws IOException {
+    String name = entry.getName();
+    URL url = new URL(baseUrl, name);
+
+    byte[] content = ArrayUtil.EMPTY_BYTE_ARRAY;
+    InputStream stream = zipFile.getInputStream(entry);
+    if (stream != null) {
+      try {
+        content = FileUtil.loadBytes(stream, (int)entry.getSize());
+      }
+      finally {
+        stream.close();
+      }
+    }
+
+    return new MemoryResource(name, url, content);
+  }
+}
index 46fabf4ea9d382ec125dd818919d8b1079844d78..c1875a8c429cb71e0efaf0a22d44a046187492dd 100644 (file)
@@ -21,15 +21,16 @@ package com.intellij.util.messages;
 
 import com.intellij.util.messages.impl.MessageBusImpl;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 public class MessageBusFactory {
   private MessageBusFactory() {}
 
   public static MessageBus newMessageBus(@NotNull Object owner) {
-    return new MessageBusImpl(owner, null);
+    return new MessageBusImpl.RootBus(owner);
   }
 
-  public static MessageBus newMessageBus(@NotNull Object owner, MessageBus parentBus) {
-    return new MessageBusImpl(owner, parentBus);
+  public static MessageBus newMessageBus(@NotNull Object owner, @Nullable MessageBus parentBus) {
+    return parentBus == null ? newMessageBus(owner) : new MessageBusImpl(owner, parentBus);
   }
 }
\ No newline at end of file
index 5040467dc1b2f842670861771eae755564573860..ba7b35024eb95676516e43e7ad1fb150afee3869 100644 (file)
@@ -49,15 +49,6 @@ public class MessageBusImpl implements MessageBus {
   };
   private final ThreadLocal<Queue<DeliveryJob>> myMessageQueue = createThreadLocalQueue();
 
-  /**
-   * Holds the counts of pending messages for all message buses in the hierarchy
-   * This field is null for non-root buses
-   * The map's keys are sorted by {@link #myOrder}
-   *
-   * Used to avoid traversing the whole hierarchy when there are no messages to be sent in most of it
-   */
-  private final ThreadLocal<SortedMap<MessageBusImpl, Integer>> myWaitingBuses;
-
   /**
    * Root's order is empty
    * Child bus's order is its parent order plus one more element, an int that's bigger than that of all sibling buses that come before
@@ -89,22 +80,16 @@ public class MessageBusImpl implements MessageBus {
   private final Object myOwner;
   private boolean myDisposed;
 
-  @SuppressWarnings("UnusedDeclaration")
-  public MessageBusImpl() {
-    this("?", null);
+  public MessageBusImpl(@NotNull Object owner, @NotNull MessageBus parentBus) {
+    myOwner = owner.toString();
+    myParentBus = (MessageBusImpl)parentBus;
+    myOrder = myParentBus.notifyChildBusCreated(this);
+    LOG.assertTrue(myParentBus.myChildBuses.contains(this));
   }
 
-  public MessageBusImpl(@NotNull Object owner, MessageBus parentBus) {
+  private MessageBusImpl(Object owner) {
     myOwner = owner.toString();
-    myParentBus = (MessageBusImpl)parentBus;
-    if (myParentBus != null) {
-      myOrder = myParentBus.notifyChildBusCreated(this);
-      LOG.assertTrue(myParentBus.myChildBuses.contains(this));
-      myWaitingBuses = null;
-    } else {
-      myOrder = Collections.emptyList();
-      myWaitingBuses = new ThreadLocal<SortedMap<MessageBusImpl, Integer>>();
-    }
+    myOrder = Collections.emptyList();
   }
 
   @Override
@@ -113,8 +98,12 @@ public class MessageBusImpl implements MessageBus {
   }
 
   @NotNull
-  private MessageBusImpl getRootBus() {
-    return myParentBus != null ? myParentBus.getRootBus() : this;
+  private RootBus getRootBus() {
+    return myParentBus != null ? myParentBus.getRootBus() : asRoot();
+  }
+
+  private RootBus asRoot() {
+    return (RootBus)this;
   }
 
   private List<Integer> notifyChildBusCreated(final MessageBusImpl childBus) {
@@ -227,7 +216,7 @@ public class MessageBusImpl implements MessageBus {
       myParentBus.notifyChildBusDisposed(this);
       myParentBus = null;
     } else {
-      myWaitingBuses.remove();
+      asRoot().myWaitingBuses.remove();
     }
     myDisposed = true;
   }
@@ -304,7 +293,7 @@ public class MessageBusImpl implements MessageBus {
       myParentBus.pumpMessages();
     }
     else {
-      Map<MessageBusImpl, Integer> map = myWaitingBuses.get();
+      Map<MessageBusImpl, Integer> map = asRoot().myWaitingBuses.get();
       if (map != null) {
         Set<MessageBusImpl> buses = map.keySet();
         if (!buses.isEmpty()) {
@@ -339,7 +328,7 @@ public class MessageBusImpl implements MessageBus {
     getRootBus().clearSubscriberCache();
   }
 
-  private void clearSubscriberCache() {
+  void clearSubscriberCache() {
     mySubscriberCache.clear();
     for (MessageBusImpl bus : myChildBuses) {
       bus.clearSubscriberCache();
@@ -350,8 +339,8 @@ public class MessageBusImpl implements MessageBus {
     for (List<MessageBusConnectionImpl> topicSubscribers : mySubscribers.values()) {
       topicSubscribers.remove(connection);
     }
-    getRootBus().clearSubscriberCache();
     if (myDisposed) return;
+    getRootBus().clearSubscriberCache();
 
     final Iterator<DeliveryJob> i = myMessageQueue.get().iterator();
     while (i.hasNext()) {
@@ -380,4 +369,19 @@ public class MessageBusImpl implements MessageBus {
       }
     };
   }
+
+  public static class RootBus extends MessageBusImpl {
+    /**
+     * Holds the counts of pending messages for all message buses in the hierarchy
+     * This field is null for non-root buses
+     * The map's keys are sorted by {@link #myOrder}
+     *
+     * Used to avoid traversing the whole hierarchy when there are no messages to be sent in most of it
+     */
+    private final ThreadLocal<SortedMap<MessageBusImpl, Integer>> myWaitingBuses = new ThreadLocal<SortedMap<MessageBusImpl, Integer>>();
+
+    public RootBus(@NotNull Object owner) {
+      super(owner);
+    }
+  }
 }
index 4bb188ce67a6a59c05bc6aa6aea81e1d587f0795..d0155fd9b0b0de2f7974041a98a3290e830de745 100644 (file)
@@ -23,7 +23,6 @@
     <orderEntry type="library" name="CGLIB" level="project" />
     <orderEntry type="library" name="asm" level="project" />
     <orderEntry type="library" exported="" name="ForkJoin" level="project" />
-    <orderEntry type="module" module-name="testFramework" scope="TEST" />
   </component>
   <component name="copyright">
     <Base>
index a8f9ce08766f100f9e4e99cbd223b22d19e28fcc..3d05470a8d9c996f24ba46b58bdb0337f16cc716 100644 (file)
@@ -56,7 +56,7 @@ abstract class RevertCommittedStuffAbstractAction extends AnAction implements Du
   }
 
   public void actionPerformed(final AnActionEvent e) {
-    final Project project = e.getDataChecked(CommonDataKeys.PROJECT);
+    final Project project = e.getRequiredData(CommonDataKeys.PROJECT);
     final VirtualFile baseDir = project.getBaseDir();
     assert baseDir != null;
     final Change[] changes = myForPerformConvertor.convert(e);
index c65d39cd2ea7ead13eaaf85b33c6282c5283ea0d..3bd9eafc5123adc83a514977593dea970bfd4c9b 100644 (file)
@@ -2080,4 +2080,6 @@ all.levels.option=all log levels
 warn.level.and.lower.option=warn level and lower
 info.level.and.lower.option=info level and lower
 debug.level.and.lower.option=debug level and lower
-trace.level.option=trace level
\ No newline at end of file
+trace.level.option=trace level
+ignored.autocloseable.types.column.label=Ignored AutoCloseable resource types
+choose.autocloseable.type.to.ignore.title=Choose AutoCloseable resource type to ignore
\ No newline at end of file
index 780a44ba6ddaf56a08a50d522969f9ba7b35a25f..3d4aa12fd4729a10064f7acffcfca8e38d8a7159 100644 (file)
@@ -105,8 +105,11 @@ public class UnnecessaryInheritDocInspection extends BaseInspection {
       if (docComment == null) {
         return;
       }
-      final PsiDocToken[] docTokens = PsiTreeUtil.getChildrenOfType(
-        docComment, PsiDocToken.class);
+      final PsiDocTag[] docTags = docComment.getTags();
+      if (docTags.length > 0) {
+        return;
+      }
+      final PsiDocToken[] docTokens = PsiTreeUtil.getChildrenOfType(docComment, PsiDocToken.class);
       if (docTokens == null) {
         return;
       }
index f2597139bed26047851874d1f7ec51c73b05d961..2ba4d45db06f806f9fde2eda975827a86b355ca5 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.
@@ -740,6 +740,7 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
     extends JavaRecursiveElementVisitor {
 
     private boolean indexVariableUsedOnlyAsIndex = true;
+    private boolean listGetCalled = false;
     private final PsiVariable indexVariable;
     private final Holder collection;
 
@@ -769,6 +770,9 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
         if (!isListIndexExpression(reference)) {
           indexVariableUsedOnlyAsIndex = false;
         }
+        else {
+          listGetCalled = true;
+        }
       }
       else if (collection == Holder.DUMMY) {
         if (isListNonGetMethodCall(reference)) {
@@ -782,7 +786,7 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
     }
 
     public boolean isIndexVariableUsedOnlyAsIndex() {
-      return indexVariableUsedOnlyAsIndex;
+      return indexVariableUsedOnlyAsIndex && listGetCalled;
     }
 
     private boolean isListNonGetMethodCall(
@@ -897,22 +901,16 @@ public class ForCanBeForeachInspectionBase extends BaseInspection {
     }
   }
 
-  private class ForCanBeForeachVisitor
-    extends BaseInspectionVisitor {
+  private class ForCanBeForeachVisitor extends BaseInspectionVisitor {
 
     @Override
-    public void visitForStatement(
-      @NotNull PsiForStatement forStatement) {
+    public void visitForStatement(@NotNull PsiForStatement forStatement) {
       super.visitForStatement(forStatement);
       if (!PsiUtil.isLanguageLevel5OrHigher(forStatement)) {
         return;
       }
-      if (isArrayLoopStatement(forStatement)
-          || isCollectionLoopStatement(forStatement,
-                                       ignoreUntypedCollections)
-          || (REPORT_INDEXED_LOOP &&
-              isIndexedListLoopStatement(forStatement,
-                                         ignoreUntypedCollections))) {
+      if (isArrayLoopStatement(forStatement) || isCollectionLoopStatement(forStatement, ignoreUntypedCollections) ||
+          REPORT_INDEXED_LOOP && isIndexedListLoopStatement(forStatement, ignoreUntypedCollections)) {
         registerStatementError(forStatement);
       }
     }
index 0501301b69e5083fe3d0acd74a1cb969628af38d..5b4c0c9c830512ccf06590962d3011aba1785580 100644 (file)
@@ -513,12 +513,9 @@ public class IfCanBeSwitchInspection extends BaseInspection {
   @Override
   public void readSettings(@NotNull Element node) throws InvalidDataException {
     super.readSettings(node);
-    for (Element o : node.getChildren()) {
-      if (Comparing.strEqual(node.getAttributeValue("name"), ONLY_SAFE)) {
-        final String onlySafe = node.getAttributeValue("value");
-        if (onlySafe != null) {
-          onlySuggestNullSafe = Boolean.parseBoolean(onlySafe);
-        }
+    for (Element child : node.getChildren("option")) {
+      if (Comparing.strEqual(child.getAttributeValue("name"), ONLY_SAFE)) {
+        onlySuggestNullSafe = Boolean.parseBoolean(child.getAttributeValue("value"));
         break;
       }
     }
  */
 package com.siyeh.ig.resources;
 
-import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiUtil;
 import com.siyeh.InspectionGadgetsBundle;
 import com.siyeh.ig.BaseInspection;
 import com.siyeh.ig.BaseInspectionVisitor;
 import com.siyeh.ig.psiutils.TypeUtils;
+import org.jdom.Element;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
-import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * @author Bas Leijdekkers
  */
-public class AutoCloseableResourceInspection extends BaseInspection {
+public class AutoCloseableResourceInspectionBase extends BaseInspection {
 
   @SuppressWarnings("PublicField")
   public boolean ignoreFromMethodCall = false;
 
+  final List<String> ignoredTypes = new ArrayList(Arrays.asList("java.util.stream.Stream"));
+
   @Nls
   @NotNull
   @Override
@@ -59,11 +64,28 @@ public class AutoCloseableResourceInspection extends BaseInspection {
     return InspectionGadgetsBundle.message("auto.closeable.resource.problem.descriptor", text);
   }
 
-  @Nullable
   @Override
-  public JComponent createOptionsPanel() {
-    return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("auto.closeable.resource.returned.option"),
-                                          this, "ignoreFromMethodCall");
+  public void readSettings(@NotNull Element node) throws InvalidDataException {
+    super.readSettings(node);
+    for (Element option : node.getChildren("option")) {
+      final String name = option.getAttributeValue("name");
+      if ("ignoredTypes".equals(name)) {
+        final String ignoredTypesString = option.getAttributeValue("value");
+        if (ignoredTypesString != null) {
+          ignoredTypes.clear();
+          parseString(ignoredTypesString, ignoredTypes);
+        }
+      }
+    }
+  }
+
+  @Override
+  public void writeSettings(@NotNull Element node) throws WriteExternalException {
+    super.writeSettings(node);
+    final String ignoredTypesString = formatString(ignoredTypes);
+    if (!"java.util.stream.Stream".equals(ignoredTypesString)) {
+      node.addContent(new Element("option").setAttribute("name", "ignoredTypes").setAttribute("value", ignoredTypesString));
+    }
   }
 
   @Override
@@ -98,6 +120,9 @@ public class AutoCloseableResourceInspection extends BaseInspection {
       if (!PsiUtil.isLanguageLevel7OrHigher(expression) || !TypeUtils.expressionHasTypeOrSubtype(expression, "java.lang.AutoCloseable")) {
         return false;
       }
+      if (TypeUtils.expressionHasTypeOrSubtype(expression, ignoredTypes)) {
+        return false;
+      }
       final PsiVariable variable = ResourceInspection.getVariable(expression);
       return !(variable instanceof PsiResourceVariable) && !ResourceInspection.isResourceEscapingFromMethod(variable, expression);
     }
index 31ac244ac7c5980e752b82f99b233cce233b12df..d7c1c9c00a5c590214aeaf30409dda79a4af507a 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.
@@ -48,7 +48,6 @@ public class IOResourceInspectionBase extends ResourceInspection {
                                      ',' + "java.io.CharArrayReader" +
                                      ',' + "java.io.StringWriter" +
                                      ',' + "java.io.StringReader";
-  @SuppressWarnings({"PublicField"})
 
   @Override
   @NotNull
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/resources/AutoCloseableResourceInspection.java
new file mode 100644 (file)
index 0000000..03a0165
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.siyeh.ig.resources;
+
+import com.intellij.codeInspection.ui.ListTable;
+import com.intellij.codeInspection.ui.ListWrappingTableModel;
+import com.intellij.util.ui.CheckBox;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.ui.UiUtils;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class AutoCloseableResourceInspection extends AutoCloseableResourceInspectionBase {
+
+  @Override
+  public JComponent createOptionsPanel() {
+    final JComponent panel = new JPanel(new BorderLayout());
+    final ListTable table =
+      new ListTable(new ListWrappingTableModel(ignoredTypes, InspectionGadgetsBundle.message("ignored.autocloseable.types.column.label")));
+    final JPanel tablePanel =
+      UiUtils.createAddRemoveTreeClassChooserPanel(table, InspectionGadgetsBundle.message("choose.autocloseable.type.to.ignore.title"),
+                                                   "java.lang.AutoCloseable");
+    final CheckBox checkBox =
+      new CheckBox(InspectionGadgetsBundle.message("auto.closeable.resource.returned.option"), this, "ignoreFromMethodCall");
+    panel.add(tablePanel, BorderLayout.CENTER);
+    panel.add(checkBox, BorderLayout.SOUTH);
+    return panel;
+  }
+}
index 4a760eb8b6f8919254aadbbe2357c68dc591f68e..f742c291ad8a6827b8729d034af530dbe6cd05f4 100644 (file)
@@ -1,18 +1,16 @@
 package com.siyeh.igtest.migration.foreach;
 
-import com.siyeh.igtest.verbose.OuterClass;
-
 import java.util.*;
 
 public class ForCanBeForEach {
 
     public void foo(int[] is) {
-        for (int i = 0; i < is.length; i++) {
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = 0; i < is.length; i++) {
         }
     }
 
     public void test(Collection bars){
-        for(Iterator<List> it = bars.iterator(); it .hasNext();){
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning>(Iterator<List> it = bars.iterator(); it .hasNext();){
             final List bar = it.next();
             bar.size();
         }
@@ -21,7 +19,7 @@ public class ForCanBeForEach {
     public int foo(){
         final int[] ints = new int[3];
         int total = 0;
-        for(int i = 0; i < ints.length; i++){
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning>(int i = 0; i < ints.length; i++){
             final int j = ints[i];
             total += j;
         }
@@ -31,7 +29,7 @@ public class ForCanBeForEach {
     public int bar(){
         final int[] ints = new int[3];
         int total = 0;
-        for(int i = 0; i < ints.length; i++){
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning>(int i = 0; i < ints.length; i++){
             total += ints[i];
         }
         return total;
@@ -40,7 +38,7 @@ public class ForCanBeForEach {
     public int baz(){
         int total = 0;
         final List ints = new ArrayList();
-        for(Iterator iterator = ints.iterator(); iterator.hasNext();){
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning>(Iterator iterator = ints.iterator(); iterator.hasNext();){
             final Integer value = (Integer) iterator.next();
             total += value.intValue();
         }
@@ -50,7 +48,7 @@ public class ForCanBeForEach {
     public int bazoom(){
         int total = 0;
         final List<Integer> ints = new ArrayList<Integer>();
-        for(Iterator<Integer> iterator = ints.iterator(); iterator.hasNext();){
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning>(Iterator<Integer> iterator = ints.iterator(); iterator.hasNext();){
             final Integer value = iterator.next();
             total += value.intValue();
         }
@@ -60,7 +58,7 @@ public class ForCanBeForEach {
     public int wildBazoom(){
         int total = 0;
         final List<? extends Integer> ints = new ArrayList<Integer>();
-        for(Iterator<? extends Integer> iterator = ints.iterator();
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning>(Iterator<? extends Integer> iterator = ints.iterator();
             iterator.hasNext();){
             final Integer value = iterator.next();
             total += value.intValue();
@@ -80,7 +78,7 @@ public class ForCanBeForEach {
         Map<String, Integer> m = new HashMap<String, Integer>();
         m.put("123", 123);
         m.put("456", 456);
-        for(Iterator<Map.Entry<String, Integer>> iterator = m.entrySet()
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning>(Iterator<Map.Entry<String, Integer>> iterator = m.entrySet()
                 .iterator(); iterator.hasNext();){
             Map.Entry<String, Integer> entry = iterator.next();
             System.out.println(entry.getKey() + "=" + entry.getValue());
@@ -103,7 +101,7 @@ public class ForCanBeForEach {
 
     public void boom2(){
         OuterClass.UnnecessaryEnumModifier2Inspection[] inners = new OuterClass.UnnecessaryEnumModifier2Inspection[3];
-        for(int i = 0; i < inners.length; i++){
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning>(int i = 0; i < inners.length; i++){
             OuterClass.UnnecessaryEnumModifier2Inspection inner = inners[i];
             System.out.println(inner);
         }
@@ -125,7 +123,7 @@ public class ForCanBeForEach {
     }
 
     public void quickFixBoom(List numbers) {
-        for (int i = 0; i < (numbers.size()); i++) {
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = 0; i < (numbers.size()); i++) {
             System.out.println("numbers[i]: " + numbers.get(i));
         }
     }
@@ -181,7 +179,7 @@ public class ForCanBeForEach {
 
     void sizeInVariable(List ls) {
         int size = ls.size();
-        for (int i = (0); (i < (size)); (i)++) {
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = (0); (i < (size)); (i)++) {
             Object o = ls.get(i);
             System.out.println("o = " + o);
         }
@@ -190,7 +188,7 @@ public class ForCanBeForEach {
     class X extends ArrayList {
 
         void foo() {
-            for (int i = 0; i < size(); i++) {
+            <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = 0; i < size(); i++) {
                 this.get(i);
             }
         }
@@ -207,7 +205,7 @@ public class ForCanBeForEach {
     int strange() {
         int total = 0;
         final List ints = new ArrayList();
-        for (ListIterator l = ints.listIterator(); l.hasNext(); ) {
+        <warning descr="'for' loop replaceable with 'foreach'">for</warning> (ListIterator l = ints.listIterator(); l.hasNext(); ) {
             System.out.println(l.next());
         }
         return total;
@@ -228,20 +226,20 @@ public class ForCanBeForEach {
     }
 
     void listIteration(List<String> l) {
-        for (Iterator<String> i = l.listIterator(); l.hasNext(); ) {
-            if ("sit".equals(l.next())) {
+        for (ListIterator<String> i = l.listIterator(); i.hasNext(); ) {
+            if ("sit".equals(i.next())) {
                 i.set("stay");
             }
         }
     }
 
   void indexedList(List<String> l) {
-    for (int i = 0, max = l.size(); i < max; i++) {
-
-    }
-    for (int i = (0), max = (l.size()); ((max) > (i)); ((i)++) {
-
+    <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = 0, max = l.size(); i < max; i++) {
+      System.out.println(l.get(i));
     }
+    <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = (0), max = (l.size()); ((max) > (i)); (i)++) {
+      System.out.println(l.get(i)); }
+    for (int i = 0; i < l.size(); i++) {}
   }
 
   static class Constants {
@@ -249,14 +247,14 @@ public class ForCanBeForEach {
   }
   static class User {{
     String[] strings = Constants.STRINGS;
-    for (int i = 0, length = strings.length; i < length; i++) { // should warn here
+    <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = 0, length = strings.length; i < length; i++) { // should warn here
       String s = strings[i];
       System.out.println(s);
     }
   }}
 
   public void food(int[] is) {
-    for (int i = 0; is.length > i; i++) {
+    <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = 0; is.length > i; i++) {
     }
     for (int i = 0, j = 10; i < is.length; i++) {
     }
@@ -268,11 +266,20 @@ public class ForCanBeForEach {
     }
   }
 
-  class X<T> {
-    void m(T ts) {
-      for (int i = 0; i < ts.length; i++) {
+  class XX<T> {
+    void m(T[] ts) {
+      <warning descr="'for' loop replaceable with 'foreach'">for</warning> (int i = 0; i < ts.length; i++) {
         System.out.println();
       }
     }
   }
 }
+class OuterClass
+{
+  public static enum UnnecessaryEnumModifier2Inspection {
+    Red, Green, Blue;
+
+    private UnnecessaryEnumModifier2Inspection() {
+    }
+  }
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach/expected.xml
deleted file mode 100644 (file)
index c544dc2..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<problems>
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>10</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>15</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>24</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>34</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>43</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>53</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>63</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>83</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>106</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>128</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable by 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable by 'for each'</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>184</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable with 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable with 'for each' #loc</description>
-  </problem>
-
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>193</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable with 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable with 'for each' #loc</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>210</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable with 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable with 'for each' #loc</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>239</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable with 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable with 'for each' #loc</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>242</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable with 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable with 'for each' #loc</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>252</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable with 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable with 'for each' #loc</description>
-  </problem>
-
-  <problem>
-    <file>ForCanBeForEach.java</file>
-    <line>259</line>
-    <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">'for' loop replaceable with 'for each'</problem_class>
-    <description>&lt;code&gt;for&lt;/code&gt; loop replaceable with 'for each' #loc</description>
-  </problem>
-</problems>
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/verbose/OuterClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/verbose/OuterClass.java
deleted file mode 100644 (file)
index 0e36008..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.siyeh.igtest.verbose;
-
-public class OuterClass
-{
-    public static enum UnnecessaryEnumModifier2Inspection {
-        Red, Green, Blue;
-
-        private UnnecessaryEnumModifier2Inspection() {
-        }
-    }
-}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/UnnecessaryInheritDocInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/javadoc/UnnecessaryInheritDocInspectionTest.java
new file mode 100644 (file)
index 0000000..430ccdb
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.siyeh.ig.javadoc;
+
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
+
+public class UnnecessaryInheritDocInspectionTest extends LightInspectionTestCase {
+
+  public void testAdditionalTags() {
+    addEnvironmentClass("interface I { /***/ void f();}");
+    myFixture.configureByText("X.java", "class X implements I {" +
+                                        "    /**\n" +
+                                        "     * {@inheritDoc}\n" +
+                                        "     * @throws FooException comment\n" +
+                                        "     */" +
+                                        "    public void f() {}" +
+                                        "}");
+    myFixture.testHighlighting(true, false, false);
+  }
+
+  @Override
+  protected InspectionProfileEntry getInspection() {
+    return new UnnecessaryInheritDocInspection();
+  }
+}
index 66866ddc06ef9aaef97b12708300d6573c881717..fe513136456d25561430fb8b745ed01ae50c7f78 100644 (file)
@@ -1,12 +1,21 @@
 package com.siyeh.ig.migration;
 
-import com.siyeh.ig.IGInspectionTestCase;
-import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.siyeh.ig.LightInspectionTestCase;
 
-public class ForCanBeForeachInspectionTest extends IGInspectionTestCase {
+public class ForCanBeForeachInspectionTest extends LightInspectionTestCase {
 
-  public void test() throws Exception {
-    doTest("com/siyeh/igtest/migration/foreach",
-           new LocalInspectionToolWrapper(new ForCanBeForeachInspection()), "java 1.5");
+  public void testForCanBeForEach() {
+    doTest();
+  }
+
+  @Override
+  protected InspectionProfileEntry getInspection() {
+    return new ForCanBeForeachInspection();
+  }
+
+  @Override
+  protected String getBasePath() {
+    return "/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/foreach";
   }
 }
\ No newline at end of file
index b3cc7ec25c3207e80b3c39f3c24d4bb75cf2b6e8..37d5e89343c7fce505d0d67727c520b416bdef04 100644 (file)
@@ -257,6 +257,23 @@ public class EclipseCodeStyleSchemeImporter implements SchemeImporter<CodeStyleS
         commonSettings.KEEP_BLANK_LINES_IN_DECLARATIONS = intValue;
         commonSettings.KEEP_BLANK_LINES_BEFORE_RBRACE = intValue;
       }
+      else if (OPTION_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK.equals(key)) {
+        boolean insertSpace = valueToBoolean(key, value);
+        commonSettings.SPACE_BEFORE_ELSE_KEYWORD = insertSpace;
+        commonSettings.SPACE_BEFORE_CATCH_KEYWORD = insertSpace;
+        commonSettings.SPACE_BEFORE_FINALLY_KEYWORD = insertSpace;
+      }
+      else if (OPTION_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK.equals(key)) {
+        boolean insertSpace = valueToBoolean(key, value);
+        commonSettings.SPACE_BEFORE_IF_LBRACE = insertSpace;
+        commonSettings.SPACE_BEFORE_FOR_LBRACE = insertSpace;
+        commonSettings.SPACE_BEFORE_WHILE_LBRACE = insertSpace;
+        commonSettings.SPACE_BEFORE_DO_LBRACE = insertSpace;
+        commonSettings.SPACE_BEFORE_TRY_LBRACE = insertSpace;
+        commonSettings.SPACE_BEFORE_CATCH_LBRACE = insertSpace;
+        commonSettings.SPACE_BEFORE_FINALLY_LBRACE = insertSpace;
+        commonSettings.SPACE_BEFORE_SYNCHRONIZED_LBRACE = insertSpace;
+      }
     }
     else if (object instanceof CommonCodeStyleSettings.IndentOptions) {
       CommonCodeStyleSettings.IndentOptions indentOptions = (CommonCodeStyleSettings.IndentOptions)object;
index 9bc5f9b2e66a8cd1e668072832e0a17f4ca10ff4..6ec7b84527fb4755a2e408c3a08a5e162873cf21 100644 (file)
@@ -10,7 +10,7 @@
 
 #org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=
 #org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=
-#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=Java:SPACE_BEFORE_CLASS_LBRACE
 org.eclipse.jdt.core.formatter.disabling_tag=FORMATTER_OFF_TAG
 org.eclipse.jdt.core.formatter.enabling_tag=FORMATTER_ON_TAG
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=Java:SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS
@@ -61,14 +61,14 @@ org.eclipse.jdt.core.formatter.blank_lines_before_package=Java:BLANK_LINES_BEFOR
 #org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=
 #org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=
 #org.eclipse.jdt.core.formatter.join_wrapped_lines=
-#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=Java:<Programmatic>
 #org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=Java:SPACE_BEFORE_COMMA
 #org.eclipse.jdt.core.formatter.blank_lines_before_member_type=
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=Java:ALIGN_GROUP_FIELD_DECLARATIONS
 #org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=Java:SPACE_WITHIN_FOR_PARENTHESES
-org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=Java:SPACE_BEFORE_METHOD_PARENTHESES
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=Java:SPACE_BEFORE_METHOD_LBRACE
 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=Java:<Programmatic>
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=Java:SPACE_WITHIN_SWITCH_PARENTHESES
 org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=Java:SPACE_AROUND_UNARY_OPERATOR
@@ -119,7 +119,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=Java:SPAC
 #org.eclipse.jdt.core.formatter.brace_position_for_switch=
 #org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=
 #org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=
-#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=Java:SPACE_BEFORE_ANOTATION_PARAMETER_LIST
 org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=Java:SPACE_AFTER_QUEST
 #org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=Java:SPACE_WITHIN_TRY_PARENTHESES
@@ -151,7 +151,7 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_p
 org.eclipse.jdt.core.formatter.tabulation.size=Java:IndentOptions:<Programmatic>
 #org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=
 #org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=Java:ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE
-#org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=Java:<Programmatic>
 #org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=
 #org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=
 #org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=
index b1b805c41dbd6944136f443f529c4a1b59f7bed0..111ed3b739798bd5887005e657c28cb104ab5c5f 100644 (file)
@@ -65,6 +65,9 @@ public interface EclipseXmlProfileElements {
 
   String OPTION_BLANK_LINES_BEFORE_FIRST_DECLARATION_IN_CLASS = "org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration";
   String OPTION_EMPTY_LINES_TO_PRESERVE = "org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve";
+  
+  String OPTION_SPACE_AFTER_CLOSING_BRACE_IN_BLOCK = "org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block";
+  String OPTION_SPACE_BEFORE_OPENING_BRACE_IN_BLOCK = "org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block";
 
   int WRAP_MASK = 0x70;
 
index acca9e192f1a4bfe73c68a766fffc3f18735b061..278d7cace7fb2a50bec4000accf6d5e9c912891a 100644 (file)
@@ -129,6 +129,20 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
     indentOptions.SMART_TABS = false;
     indentOptions.TAB_SIZE = 3;
     settings.FORMATTER_TAGS_ENABLED = false;
+    javaSettings.SPACE_BEFORE_ELSE_KEYWORD = false;
+    javaSettings.SPACE_BEFORE_FINALLY_KEYWORD = false;
+    javaSettings.SPACE_BEFORE_CATCH_KEYWORD = false;
+    javaSettings.SPACE_BEFORE_IF_LBRACE = false;
+    javaSettings.SPACE_BEFORE_FOR_LBRACE = false;
+    javaSettings.SPACE_BEFORE_WHILE_LBRACE = false;
+    javaSettings.SPACE_BEFORE_DO_LBRACE = false;
+    javaSettings.SPACE_BEFORE_TRY_LBRACE = false;
+    javaSettings.SPACE_BEFORE_CATCH_LBRACE = false;
+    javaSettings.SPACE_BEFORE_FINALLY_LBRACE = false;
+    javaSettings.SPACE_BEFORE_SYNCHRONIZED_LBRACE = false;
+    javaSettings.SPACE_BEFORE_METHOD_LBRACE = false;
+    javaSettings.SPACE_BEFORE_CLASS_LBRACE = false;
+    javaSettings.SPACE_BEFORE_ANOTATION_PARAMETER_LIST = true;
 
     InputStream inputStream = new FileInputStream(input);
     try {
@@ -229,6 +243,20 @@ public class EclipseSettingsImportTest extends PlatformTestCase {
       assertEquals(5, javaSettings.KEEP_BLANK_LINES_IN_CODE);
       assertEquals(5, javaSettings.KEEP_BLANK_LINES_IN_DECLARATIONS);
       assertEquals(5, javaSettings.KEEP_BLANK_LINES_BEFORE_RBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_ELSE_KEYWORD);
+      assertTrue(javaSettings.SPACE_BEFORE_FINALLY_KEYWORD);
+      assertTrue(javaSettings.SPACE_BEFORE_CATCH_KEYWORD);
+      assertTrue(javaSettings.SPACE_BEFORE_IF_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_FOR_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_WHILE_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_DO_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_TRY_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_CATCH_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_FINALLY_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_SYNCHRONIZED_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_METHOD_LBRACE);
+      assertTrue(javaSettings.SPACE_BEFORE_CLASS_LBRACE);
+      assertFalse(javaSettings.SPACE_BEFORE_ANOTATION_PARAMETER_LIST);
     }
     finally {
       inputStream.close();
index d74117ffda303ff5a3f62f8c88ea8be5ea4c0423..fe920a906debcc4027c7e5e0c9e4511fc7c77668 100644 (file)
@@ -17,12 +17,14 @@ package git4idea.test;
 
 import com.intellij.openapi.components.ProjectComponent;
 import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vcs.*;
 import com.intellij.openapi.vcs.changes.ChangeListManager;
 import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.testFramework.TestLoggerFactory;
 import com.intellij.testFramework.UsefulTestCase;
 import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
 import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
@@ -37,8 +39,16 @@ import git4idea.repo.GitRepository;
 import git4idea.repo.GitRepositoryManager;
 import org.jetbrains.annotations.NotNull;
 
+import java.io.IOException;
+
 public abstract class GitPlatformTest extends UsefulTestCase {
 
+  static {
+    Logger.setFactory(TestLoggerFactory.class);
+  }
+
+  private static final Logger LOG = Logger.getInstance(GitPlatformTest.class);
+
   @NotNull protected Project myProject;
   @NotNull protected VirtualFile myProjectRoot;
   @NotNull protected String myProjectPath;
@@ -51,6 +61,7 @@ public abstract class GitPlatformTest extends UsefulTestCase {
   @NotNull protected TestVcsNotifier myVcsNotifier;
 
   @NotNull private IdeaProjectTestFixture myProjectFixture;
+  private String myTestStartedIndicator;
 
   @SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors", "UnusedDeclaration"})
   protected GitPlatformTest() {
@@ -61,6 +72,7 @@ public abstract class GitPlatformTest extends UsefulTestCase {
   @Override
   protected void setUp() throws Exception {
     super.setUp();
+    enableDebugLogging();
 
     try {
       myProjectFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getTestName(true)).getFixture();
@@ -118,6 +130,35 @@ public abstract class GitPlatformTest extends UsefulTestCase {
     }
   }
 
+  private void enableDebugLogging() {
+    TestLoggerFactory.enableDebugLogging(myTestRootDisposable, "#" + Executor.class.getName());
+    myTestStartedIndicator = createTestStartedIndicator();
+    LOG.info(myTestStartedIndicator);
+  }
+
+  @Override
+  protected void defaultRunBare() throws Throwable {
+    try {
+      super.defaultRunBare();
+    }
+    catch (Throwable throwable) {
+      try {
+        if (myTestStartedIndicator != null) {
+          TestLoggerFactory.dumpLogToStdout(myTestStartedIndicator);
+        }
+        throw throwable;
+      }
+      catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  }
+
+  @NotNull
+  private String createTestStartedIndicator() {
+    return "Starting " + getClass().getName() + "." + getTestName(false) + Math.random();
+  }
+
   @NotNull
   protected GitRepository createRepository(@NotNull String rootDir) {
     return GitTestUtil.createRepository(myProject, rootDir);
index b8944ea321c0f9982ca6bd01c2a3d2fe0dc542cf..e591bb61d11b96684cf8f7df16cdcfd1e520cf19 100644 (file)
@@ -46,7 +46,7 @@ import java.util.List;
 public class MavenExecuteGoalAction extends DumbAwareAction {
   @Override
   public void actionPerformed(final AnActionEvent e) {
-    final Project project = e.getDataChecked(CommonDataKeys.PROJECT);
+    final Project project = e.getRequiredData(CommonDataKeys.PROJECT);
 
     ExecuteMavenGoalHistoryService historyService = ExecuteMavenGoalHistoryService.getInstance(project);
 
index 3adf05fc0f45f8e3a29eb55ff06b2f026aa269e7..3ac61566c7662afdea2de18537aeb300d5f046e6 100644 (file)
@@ -1,9 +1,8 @@
 package com.jetbrains.python.magicLiteral;
 
 import com.intellij.openapi.extensions.ExtensionPointName;
-import com.jetbrains.python.psi.PyStringLiteralExpression;
+import com.jetbrains.python.psi.StringLiteralExpression;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 /**
  * Any magic literal extension point should imlement this interface and be installed as extesnion point
@@ -21,7 +20,7 @@ public interface PyMagicLiteralExtensionPoint {
    * @param element element to check
    * @return true if magic.
    */
-  boolean isMagicLiteral(@NotNull PyStringLiteralExpression element);
+  boolean isMagicLiteral(@NotNull StringLiteralExpression element);
 
 
   /**
index 702adedade2e7f8e59abdee61eebc56b9d934fe2..c60ce98133c57abfc8e48712c9b088aa0b1ae32a 100644 (file)
@@ -25,6 +25,7 @@ import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.refactoring.rename.RenameDialog;
 import com.intellij.refactoring.rename.RenameHandler;
 import com.jetbrains.python.psi.PyStringLiteralExpression;
+import com.jetbrains.python.psi.StringLiteralExpression;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -59,7 +60,7 @@ public class PyMagicLiteralRenameHandler implements RenameHandler {
     if (element instanceof PyStringLiteralExpression) {
       return element;
     }
-    return PsiTreeUtil.getParentOfType(element, PyStringLiteralExpression.class);
+    return PsiTreeUtil.getParentOfType(element, StringLiteralExpression.class);
   }
 
   @Override
index 58118a999ff50e5cdd314414f8e3382e5796981a..d119ec0646dc590afb9bec80a634a5a59f728f0a 100644 (file)
@@ -2,7 +2,7 @@ package com.jetbrains.python.magicLiteral;
 
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.psi.PsiElement;
-import com.jetbrains.python.psi.PyStringLiteralExpression;
+import com.jetbrains.python.psi.StringLiteralExpression;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -23,7 +23,7 @@ public final class PyMagicLiteralTools {
    * @return true if magic
    */
   public static boolean isMagicLiteral(@NotNull final PsiElement element) {
-    return (element instanceof PyStringLiteralExpression) && (getPoint((PyStringLiteralExpression)element) != null);
+    return (element instanceof StringLiteralExpression) && (getPoint((StringLiteralExpression)element) != null);
   }
 
   /**
@@ -33,7 +33,7 @@ public final class PyMagicLiteralTools {
    * @return extension point (if any) or null if literal is unknown to all installed magic literal extesnion points
    */
   @Nullable
-  public static PyMagicLiteralExtensionPoint getPoint(@NotNull final PyStringLiteralExpression element) {
+  public static PyMagicLiteralExtensionPoint getPoint(@NotNull final StringLiteralExpression element) {
     final PyMagicLiteralExtensionPoint[] magicLiteralExtPoints =
       ApplicationManager.getApplication().getExtensions(PyMagicLiteralExtensionPoint.EP_NAME);
 
index 41113774d0d0c5ac23fd86ca46624e32f329dbd9..c4fe1c96596f212d7b052fa5a89654587f9b80ce 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.
@@ -27,7 +27,7 @@ import java.util.List;
 /**
  * @author peter
  */
-public final class JavaMethod implements AnnotatedElement{
+public final class JavaMethod implements AnnotatedElement {
   public static final JavaMethod[] EMPTY_ARRAY = new JavaMethod[0];
   private static final Object NONE = new Object();
 
@@ -101,14 +101,10 @@ public final class JavaMethod implements AnnotatedElement{
     return annotation == NONE ? null : (T)annotation;
   }
 
-  @NotNull private Object findAnnotation(Class<? extends Annotation> annotationClass) {
-    for (Method method : mySignature.getAllMethods(myDeclaringClass)) {
-      final Annotation annotation = method.getAnnotation(annotationClass);
-      if (annotation != null) {
-        return annotation;
-      }
-    }
-    return NONE;
+  @NotNull
+  private Object findAnnotation(Class<? extends Annotation> annotationClass) {
+    final Annotation annotation = mySignature.findAnnotation(annotationClass, myDeclaringClass);
+    return annotation == null ? NONE : annotation;
   }
 
   @Override
index 54a2fe95a98c19e584ac8411e4257bf53622c4d5..3e82904ad3d7002e6f2ae0e5142bcd92cd427e53 100644 (file)
@@ -16,6 +16,8 @@
 package com.intellij.util.xml;
 
 import com.intellij.util.ArrayUtil;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.Processor;
 import com.intellij.util.ReflectionUtil;
 import org.jetbrains.annotations.Nullable;
 
@@ -54,8 +56,8 @@ public class JavaMethodSignature {
     return method;
   }
 
-  private void collectMethods(final Class aClass, List<Method> methods) {
-    addMethodWithSupers(aClass, findMethod(aClass), methods);
+  private boolean processMethods(final Class aClass, Processor<Method> processor) {
+    return processMethodWithSupers(aClass, findMethod(aClass), processor);
   }
 
   @Nullable
@@ -64,38 +66,56 @@ public class JavaMethodSignature {
     return method == null ? ReflectionUtil.getDeclaredMethod(aClass, myMethodName, myMethodParameters) : method;
   }
 
-  private void addMethodWithSupers(final Class aClass, final Method method, List<Method> methods) {
+  private boolean processMethodWithSupers(final Class aClass, final Method method, final Processor<Method> processor) {
     if (method != null) {
-      methods.add(method);
+      if (!processor.process(method)) return false;
     }
     final Class superClass = aClass.getSuperclass();
     if (superClass != null) {
-      collectMethods(superClass, methods);
-    } else {
+      if (!processMethods(superClass, processor)) return false;
+    }
+    else {
       if (aClass.isInterface()) {
-        collectMethods(Object.class, methods);
+        if (!processMethods(Object.class, processor)) return false;
       }
     }
     for (final Class anInterface : aClass.getInterfaces()) {
-      collectMethods(anInterface, methods);
+      if (!processMethods(anInterface, processor)) return false;
     }
+    return true;
   }
 
   public final List<Method> getAllMethods(final Class startFrom) {
-    final ArrayList<Method> methods = new ArrayList<Method>();
-    collectMethods(startFrom, methods);
-    return methods;
+    final List<Method> result = new ArrayList<Method>();
+    processMethods(startFrom, new CommonProcessors.CollectProcessor<Method>(result));
+    return result;
   }
 
   @Nullable
   public final <T extends Annotation> Method findAnnotatedMethod(final Class<T> annotationClass, final Class startFrom) {
-    for (Method method : getAllMethods(startFrom)) {
-      final T annotation = method.getAnnotation(annotationClass);
-      if (annotation != null && ReflectionUtil.isAssignable(method.getDeclaringClass(), startFrom)) {
-        return method;
+    CommonProcessors.FindFirstProcessor<Method> processor = new CommonProcessors.FindFirstProcessor<Method>() {
+      @Override
+      protected boolean accept(Method method) {
+        final T annotation = method.getAnnotation(annotationClass);
+        return annotation != null && ReflectionUtil.isAssignable(method.getDeclaringClass(), startFrom);
       }
-    }
-    return null;
+    };
+    processMethods(startFrom, processor);
+    return processor.getFoundValue();
+  }
+
+  @Nullable
+  public final <T extends Annotation> T findAnnotation(final Class<T> annotationClass, final Class startFrom) {
+    CommonProcessors.FindFirstProcessor<Method> processor = new CommonProcessors.FindFirstProcessor<Method>() {
+      @Override
+      protected boolean accept(Method method) {
+        final T annotation = method.getAnnotation(annotationClass);
+        return annotation != null;
+      }
+    };
+    processMethods(startFrom, processor);
+    final Method foundMethod = processor.getFoundValue();
+    return foundMethod == null ? null : foundMethod.getAnnotation(annotationClass);
   }
 
   public String toString() {
@@ -121,5 +141,4 @@ public class JavaMethodSignature {
     result = 31 * result + Arrays.hashCode(myMethodParameters);
     return result;
   }
-
 }