Merge remote-tracking branch 'origin/master' appcode/163.3052
authorDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Mon, 22 Aug 2016 11:58:50 +0000 (13:58 +0200)
committerDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Mon, 22 Aug 2016 11:58:50 +0000 (13:58 +0200)
12 files changed:
java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/PostHighlightingVisitor.java
java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java
java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java
java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java
java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java
platform/util/src/com/intellij/util/text/CharArrayCharSequence.java
updater/src/com/intellij/updater/CreateAction.java
updater/src/com/intellij/updater/DeleteAction.java
updater/src/com/intellij/updater/Patch.java
updater/src/com/intellij/updater/PatchAction.java
updater/src/com/intellij/updater/UpdateAction.java
updater/src/com/intellij/updater/Utils.java

index d75a00b93390c57b88f3444a169815cc653541e7..634bfcf27e3a813b383be0ec5c9e31175454919d 100644 (file)
@@ -218,9 +218,13 @@ class PostHighlightingVisitor {
     if (parent instanceof PsiField && compareVisibilities((PsiModifierListOwner)parent, myUnusedSymbolInspection.getFieldVisibility())) {
       return processField(myProject, (PsiField)parent, identifier, progress, helper);
     }
-    if (parent instanceof PsiParameter && compareVisibilities((PsiModifierListOwner)parent, myUnusedSymbolInspection.getParameterVisibility())) {
-      if (SuppressionUtil.isSuppressed(identifier, UnusedSymbolLocalInspectionBase.UNUSED_PARAMETERS_SHORT_NAME)) return null;
-      return processParameter(myProject, (PsiParameter)parent, identifier, progress);
+    if (parent instanceof PsiParameter) {
+      final PsiElement declarationScope = ((PsiParameter)parent).getDeclarationScope();
+      if (declarationScope instanceof PsiMethod ? compareVisibilities((PsiModifierListOwner)declarationScope, myUnusedSymbolInspection.getParameterVisibility())
+                                                : myUnusedSymbolInspection.LOCAL_VARIABLE) {
+        if (SuppressionUtil.isSuppressed(identifier, UnusedSymbolLocalInspectionBase.UNUSED_PARAMETERS_SHORT_NAME)) return null;
+        return processParameter(myProject, (PsiParameter)parent, identifier, progress);
+      }
     }
     if (parent instanceof PsiMethod) {
       if (myUnusedSymbolInspection.isIgnoreAccessors() && PropertyUtil.isSimplePropertyAccessor((PsiMethod)parent)) {
index 782edbdaf78ac948ebde07f752209d9787a09a14..858b40ea04c9f1674c0a1517d0ea3634c78e6655 100644 (file)
@@ -441,7 +441,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta
 
   @PsiModifier.ModifierConstant
   private static String getAcceptedVisibility(UnusedSymbolLocalInspectionBase tool, RefJavaElement element) {
-    if (element instanceof RefClass) {
+    if (element instanceof RefClass || element instanceof RefImplicitConstructor) {
       return tool.getClassVisibility();
     }
     if (element instanceof RefField) {
index 68cb7d142c1b9f68faea330408fb9c2283e379c7..b7c81c74c3b8206fd9c21e9827731c180b3e7122 100644 (file)
@@ -185,6 +185,12 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
           }
 
           JSlider slider = new JSlider(SwingConstants.VERTICAL, 1, modifiers.length, 1);
+          slider.addChangeListener(val -> {
+            final String modifier = modifiers[slider.getValue() - 1];
+            setter.consume(modifier);
+            setText(getPresentableText(modifier));
+            fireStateChanged();
+          });
           slider.setLabelTable(sliderLabels);
           slider.putClientProperty(UIUtil.JSLIDER_ISFILLED, Boolean.TRUE);
           slider.setPreferredSize(JBUI.size(150, modifiers.length * 25));
@@ -193,17 +199,9 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase
           slider.setValue(ArrayUtil.find(modifiers, visibilityProducer.produce()) + 1);
           final JBPopup popup = JBPopupFactory.getInstance()
             .createComponentPopupBuilder(slider, null)
+            .setTitle("Effective Visibility")
             .setCancelOnClickOutside(true)
             .createPopup();
-          popup.addListener(new JBPopupAdapter() {
-            @Override
-            public void onClosed(LightweightWindowEvent event) {
-              final String modifier = modifiers[slider.getValue() - 1];
-              setter.consume(modifier);
-              setText(getPresentableText(modifier));
-              fireStateChanged();
-            }
-          });
           popup.show(new RelativePoint(MyLabel.this, new Point(getWidth(), 0)));
           return true;
         }
index 93036467b451f5eeee1af41d9edb9cdf62c9222b..a72c5993e476231c7b9c99af803eb3f1bea1981f 100644 (file)
@@ -17,6 +17,7 @@ package com.intellij.ide.actions;
 
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.IdeBundle;
+import com.intellij.ide.IdeView;
 import com.intellij.ide.fileTemplates.FileTemplate;
 import com.intellij.ide.fileTemplates.FileTemplateManager;
 import com.intellij.ide.fileTemplates.actions.AttributesDefaults;
@@ -33,6 +34,7 @@ import com.intellij.psi.PsiDirectory;
 import com.intellij.psi.search.FilenameIndex;
 import com.intellij.psi.util.PsiUtil;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import java.util.Optional;
 import java.util.Properties;
@@ -58,6 +60,13 @@ public class CreateModuleInfoAction extends CreateFromTemplateActionBase {
     e.getPresentation().setEnabledAndVisible(available);
   }
 
+  @Nullable
+  @Override
+  protected PsiDirectory getTargetDirectory(DataContext dataContext, IdeView view) {
+    PsiDirectory[] directories = view.getDirectories();
+    return directories.length == 1 ? directories[0] : null;
+  }
+
   @Override
   protected FileTemplate getTemplate(@NotNull Project project, @NotNull PsiDirectory dir) {
     FileTemplate template = FileTemplateManager.getInstance(project).getInternalTemplate(INTERNAL_MODULE_INFO_TEMPLATE_NAME);
index 78f3118f39787aaa24b6ac277775116683c756d9..dc79feafc79615874b319ad927a64fd47d9969e9 100644 (file)
@@ -237,7 +237,7 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase {
 
       VirtualFile file = PsiUtilCore.getVirtualFile(cls);
       assertNotNull(file);
-      assertTrue(file.getPath(), FileUtil.startsWith(file.getPath(), jdkHome.getPath(), true));
+      assertTrue(file.getPath(), FileUtil.startsWith(file.getPath(), FileUtil.toSystemIndependentName(jdkHome.getPath()), true));
     }
   }
 
index 0557c9da5505ba2b3c95cab9292e0b16f56b0a44..1a9499bc67b26182231b6cd72827eae51754dc17 100644 (file)
@@ -78,19 +78,20 @@ public class CharArrayCharSequence implements CharSequenceBackedByArray, CharSeq
     if (this == anObject) {
       return true;
     }
-    if (anObject instanceof CharSequence) {
-      CharSequence anotherString = (CharSequence)anObject;
-      int n = myEnd - myStart;
-      if (n == anotherString.length()) {
-        for (int i = 0; i < n; i++) {
-          if (myChars[myStart + i] != anotherString.charAt(i)) {
-            return false;
-          }
-        }
-        return true;
+    if (anObject == null || getClass() != anObject.getClass()) {
+      return false;
+    }
+    final CharArrayCharSequence anotherString = (CharArrayCharSequence)anObject;
+    if (length() != anotherString.length()) {
+      return false;
+    }
+
+    for (int i = 0; i < length(); i++) {
+      if (charAt(i) != anotherString.charAt(i)) {
+        return false;
       }
     }
-    return false;
+    return true;
   }
 
   /**
index 67794c0b5409a625c27a6c079e6661c652df706a..e5bc063ed8ff2e42a632c3dec620d117006ece6a 100644 (file)
@@ -22,8 +22,12 @@ public class CreateAction extends PatchAction {
     Runner.logger.info("building PatchFile");
     patchOutput.putNextEntry(new ZipEntry(myPath));
     if (!newerFile.isDirectory()) {
-      writeExecutableFlag(patchOutput, newerFile);
-      Utils.copyFileToStream(newerFile, patchOutput);
+      if (Utils.isLink(newerFile)) {
+        writeLinkInfo(newerFile, patchOutput);
+      } else {
+        writeExecutableFlag(patchOutput, newerFile);
+        Utils.copyFileToStream(newerFile, patchOutput);
+      }
     }
 
     patchOutput.closeEntry();
@@ -64,9 +68,14 @@ public class CreateAction extends PatchAction {
     } else {
       InputStream in = Utils.findEntryInputStreamForEntry(patchFile, entry);
       try {
-        boolean executable = readExecutableFlag(in);
-        Utils.copyStreamToFile(in, toFile);
-        Utils.setExecutable(toFile, executable);
+        int filePermissions = in.read();
+        if (filePermissions > 1 ) {
+          Utils.createLink(readLinkInfo(in, filePermissions), toFile);
+        }
+        else {
+          Utils.copyStreamToFile(in, toFile);
+          Utils.setExecutable(toFile, filePermissions == 1 );
+        }
       }
       finally {
         in.close();
index 6809cf134ae86bdf5f806d01ee1db8ce7df53cc3..76a3017a9b49b3db5152eddb90939d147b50f208 100644 (file)
@@ -44,7 +44,10 @@ public class DeleteAction extends PatchAction {
 
   @Override
   protected void doApply(ZipFile patchFile, File backupDir, File toFile) throws IOException {
-    Utils.delete(toFile);
+    //NOTE: a folder can be deleted only in case if it does not contain any user's files/folders.
+    if (!toFile.isDirectory() || (toFile.listFiles() != null && toFile.listFiles().length == 0)) {
+      Utils.delete(toFile);
+    }
   }
 
   @Override
index daf401ddbfe0ffb777f42759aea7ce2a9d9b021b..ec6f952dc35d51af3a541d4478e75ce3f87a3f0f 100644 (file)
@@ -238,7 +238,8 @@ public class Patch {
     final File toDir = toBaseDir(rootDir);
     boolean checkWarnings = true;
     while (checkWarnings) {
-      files = Utils.collectRelativePaths(toDir, myIsStrict);
+      //always collect files and folders to avoid cases such as IDEA-152249
+      files = Utils.collectRelativePaths(toDir, true);
       checkWarnings = false;
       for (String file : files) {
         String warning = myWarnings.get(file);
@@ -376,7 +377,8 @@ public class Patch {
     throws IOException, OperationCancelledException {
     Map<String, Long> result = new LinkedHashMap<>();
 
-    LinkedHashSet<String> paths = Utils.collectRelativePaths(dir, myIsStrict);
+    //always collect files and folders to avoid cases such as IDEA-152249
+    LinkedHashSet<String> paths = Utils.collectRelativePaths(dir, true);
     for (String each : paths) {
       if (ignoredFiles.contains(each)) continue;
       ui.setStatus(each);
index bf7bf27c91e1d8cfbfc15939ac8986a6ebdee0d0..ac08422ac4af2002f6ccb5bd27fdfd22fc670498 100644 (file)
@@ -1,6 +1,9 @@
 package com.intellij.updater;
 
 import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.Path;
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 import java.nio.channels.OverlappingFileLockException;
@@ -46,8 +49,21 @@ public abstract class PatchAction {
     out.write(file.canExecute() ? 1 : 0);
   }
 
-  protected static boolean readExecutableFlag(InputStream in) throws IOException {
-    return in.read() == 1;
+  protected static void writeLinkInfo(File file, OutputStream out) throws IOException {
+    Path path = Paths.get(file.getAbsolutePath());
+    String link = Files.readSymbolicLink(path).toString();
+    out.write(link.length());
+    byte[] byteArray = link.getBytes();
+    out.write(byteArray);
+  }
+
+  protected static String readLinkInfo(InputStream in, int length) throws IOException {
+    byte[] byteArray = new byte[length];
+    String link = "";
+    if (in.read(byteArray) > -1){
+      link = new String(byteArray, "UTF-8");
+    }
+    return link;
   }
 
   public boolean calculate(File olderDir, File newerDir) throws IOException {
index b9c34d8413b750508ec129c7998101de95398410..2af2f64c4cf168a4370c1b8bd6a5a8ec9055a55e 100644 (file)
@@ -22,8 +22,12 @@ public class UpdateAction extends BaseUpdateAction {
   protected void doBuildPatchFile(File olderFile, File newerFile, ZipOutputStream patchOutput) throws IOException {
     if (!myIsMove) {
       patchOutput.putNextEntry(new ZipEntry(myPath));
-      writeExecutableFlag(patchOutput, newerFile);
-      writeDiff(olderFile, newerFile, patchOutput);
+      if (Utils.isLink(newerFile)) {
+        writeLinkInfo(newerFile, patchOutput);
+      } else {
+        writeExecutableFlag(patchOutput, newerFile);
+        writeDiff(olderFile, newerFile, patchOutput);
+      }
       patchOutput.closeEntry();
     }
   }
@@ -35,22 +39,27 @@ public class UpdateAction extends BaseUpdateAction {
     if (!myIsMove) {
       updated = Utils.createTempFile();
       InputStream in = Utils.findEntryInputStream(patchFile, myPath);
-      boolean executable = readExecutableFlag(in);
-
-      OutputStream out = new BufferedOutputStream(new FileOutputStream(updated));
-      try {
-        InputStream oldFileIn = Utils.newFileInputStream(source, myPatch.isNormalized());
+      int filePermissions = in.read();
+      if (filePermissions > 1 ) {
+        Utils.createLink(readLinkInfo(in, filePermissions), toFile);
+        in.close();
+        return;
+      } else {
+        OutputStream out = new BufferedOutputStream(new FileOutputStream(updated));
         try {
-          applyDiff(in, oldFileIn, out);
+          InputStream oldFileIn = Utils.newFileInputStream(source, myPatch.isNormalized());
+          try {
+            applyDiff(in, oldFileIn, out);
+          }
+          finally {
+            oldFileIn.close();
+          }
         }
         finally {
-          oldFileIn.close();
+          out.close();
         }
       }
-      finally {
-        out.close();
-      }
-      Utils.setExecutable(updated, executable);
+      Utils.setExecutable(updated, filePermissions == 1);
     } else {
       updated = source;
     }
index 220e554b1d2caab2a9131ae11b573b973fec4ef9..38f9a95cc18f229e49305a3d92212806b5ae74b0 100644 (file)
@@ -1,6 +1,9 @@
 package com.intellij.updater;
 
 import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.*;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -81,6 +84,21 @@ public class Utils {
     }
   }
 
+  public static boolean isLink(File file) throws IOException {
+    return Files.isSymbolicLink(Paths.get(file.getAbsolutePath()));
+  }
+
+  public static void createLink(String target, File link) throws IOException {
+    if (target == "") {
+      Runner.logger.error("Can't create link for " +  link.getName());
+    } else {
+      if (link.exists()) {
+        delete(link);
+      }
+      Files.createSymbolicLink(Paths.get(link.getAbsolutePath()), Paths.get(target));
+    }
+  }
+
   public static void copy(File from, File to) throws IOException {
     Runner.logger.info("from " + from.getPath() + " to " + to.getPath());
     if (from.isDirectory()) {
@@ -92,14 +110,16 @@ public class Utils {
       }
     }
     else {
-      InputStream in = new BufferedInputStream(new FileInputStream(from));
-      try {
-        copyStreamToFile(in, to);
-      }
-      finally {
-        in.close();
+      if (! isLink(from)) {
+        InputStream in = new BufferedInputStream(new FileInputStream(from));
+        try {
+          copyStreamToFile(in, to);
+        }
+        finally {
+          in.close();
+        }
+        setExecutable(to, from.canExecute());
       }
-      setExecutable(to, from.canExecute());
     }
   }