@Override
 @NotNull
 public Project[] getOpenProjects() {
   synchronized (myOpenProjects) {
     if (myOpenProjectsArrayCache.length != myOpenProjects.size()) {
       LOG.error(
           "Open projects: "
               + myOpenProjects
               + "; cache: "
               + Arrays.asList(myOpenProjectsArrayCache));
     }
     if (myOpenProjectsArrayCache.length > 0
         && myOpenProjectsArrayCache[0] != myOpenProjects.get(0)) {
       LOG.error(
           "Open projects cache corrupted. Open projects: "
               + myOpenProjects
               + "; cache: "
               + Arrays.asList(myOpenProjectsArrayCache));
     }
     if (ApplicationManager.getApplication().isUnitTestMode()) {
       Project[] testProjects = myTestProjects.toArray(new Project[myTestProjects.size()]);
       for (Project testProject : testProjects) {
         assert !testProject.isDisposed() : testProject;
       }
       return ArrayUtil.mergeArrays(myOpenProjectsArrayCache, testProjects);
     }
     return myOpenProjectsArrayCache;
   }
 }
  @NotNull
  public static String buildStringToFindForIndicesFromRegExp(
      @NotNull String stringToFind, @NotNull Project project) {
    if (!Registry.is("idea.regexp.search.uses.indices")) return "";

    final AccessToken accessToken = ReadAction.start();
    try {
      final List<PsiElement> topLevelRegExpChars = getTopLevelRegExpChars("a", project);
      if (topLevelRegExpChars.size() != 1) return "";

      // leave only top level regExpChars
      return StringUtil.join(
          getTopLevelRegExpChars(stringToFind, project),
          new Function<PsiElement, String>() {
            final Class regExpCharPsiClass = topLevelRegExpChars.get(0).getClass();

            @Override
            public String fun(PsiElement element) {
              return regExpCharPsiClass.isInstance(element) ? element.getText() : " ";
            }
          },
          "");
    } finally {
      accessToken.finish();
    }
  }
 @NotNull
 private static String toVfString(@NotNull Collection<VirtualFile> list) {
   List<VirtualFile> sub = new ArrayList<VirtualFile>(list).subList(0, Math.min(list.size(), 100));
   return list.size()
       + " files: "
       + StringUtil.join(sub, file -> file.getName(), ", ")
       + (list.size() == sub.size() ? "" : "...");
 }
Пример #4
0
  @NotNull
  private static List<VFileEvent> validateEvents(@NotNull List<VFileEvent> events) {
    final List<EventWrapper> deletionEvents = ContainerUtil.newArrayList();
    for (int i = 0, size = events.size(); i < size; i++) {
      final VFileEvent event = events.get(i);
      if (event instanceof VFileDeleteEvent && event.isValid()) {
        deletionEvents.add(new EventWrapper((VFileDeleteEvent) event, i));
      }
    }

    final TIntHashSet invalidIDs;
    if (deletionEvents.isEmpty()) {
      invalidIDs = EmptyIntHashSet.INSTANCE;
    } else {
      ContainerUtil.quickSort(deletionEvents, DEPTH_COMPARATOR);

      invalidIDs = new TIntHashSet(deletionEvents.size());
      final Set<VirtualFile> dirsToBeDeleted = new THashSet<VirtualFile>(deletionEvents.size());
      nextEvent:
      for (EventWrapper wrapper : deletionEvents) {
        final VirtualFile candidate = wrapper.event.getFile();
        VirtualFile parent = candidate;
        while (parent != null) {
          if (dirsToBeDeleted.contains(parent)) {
            invalidIDs.add(wrapper.id);
            continue nextEvent;
          }
          parent = parent.getParent();
        }

        if (candidate.isDirectory()) {
          dirsToBeDeleted.add(candidate);
        }
      }
    }

    final List<VFileEvent> filtered = new ArrayList<VFileEvent>(events.size() - invalidIDs.size());
    for (int i = 0, size = events.size(); i < size; i++) {
      final VFileEvent event = events.get(i);
      if (event.isValid() && !(event instanceof VFileDeleteEvent && invalidIDs.contains(i))) {
        filtered.add(event);
      }
    }
    return filtered;
  }
  private boolean processFilesConcurrently(
      @NotNull Set<VirtualFile> files,
      @NotNull final ProgressIndicator indicator,
      @NotNull final Processor<VirtualFile> processor) {
    final List<VirtualFile> fileList = new ArrayList<VirtualFile>(files);
    // fine but grabs all CPUs
    // return JobLauncher.getInstance().invokeConcurrentlyUnderProgress(fileList, indicator, false,
    // false, processor);

    int parallelism = CacheUpdateRunner.indexingThreadCount();
    final Callable<Boolean> processFileFromSet =
        () -> {
          final boolean[] result = {true};
          ProgressManager.getInstance()
              .executeProcessUnderProgress(
                  () -> {
                    while (true) {
                      ProgressManager.checkCanceled();
                      VirtualFile file;
                      synchronized (fileList) {
                        file = fileList.isEmpty() ? null : fileList.remove(fileList.size() - 1);
                      }
                      if (file == null) {
                        break;
                      }
                      if (!processor.process(file)) {
                        result[0] = false;
                        break;
                      }
                    }
                  },
                  indicator);
          return result[0];
        };
    List<Future<Boolean>> futures =
        ContainerUtil.map(
            Collections.nCopies(parallelism, ""),
            s -> myApplication.executeOnPooledThread(processFileFromSet));

    List<Boolean> results =
        ContainerUtil.map(
            futures,
            future -> {
              try {
                return future.get();
              } catch (Exception e) {
                LOG.error(e);
              }
              return false;
            });

    return !ContainerUtil.exists(
        results,
        result -> {
          return result != null && !result; // null means PCE
        });
  }
  public void doPrepare(final List<Module> pluginModules, final Project project) {
    final List<String> errorMessages = new ArrayList<String>();
    final List<String> successMessages = new ArrayList<String>();

    final CompilerManager compilerManager = CompilerManager.getInstance(project);
    compilerManager.make(
        compilerManager.createModulesCompileScope(
            pluginModules.toArray(new Module[pluginModules.size()]), true),
        new CompileStatusNotification() {
          public void finished(
              final boolean aborted,
              final int errors,
              final int warnings,
              final CompileContext compileContext) {
            if (aborted || errors != 0) return;
            ApplicationManager.getApplication()
                .invokeLater(
                    new Runnable() {
                      public void run() {
                        for (Module aModule : pluginModules) {
                          if (!doPrepare(aModule, errorMessages, successMessages)) {
                            return;
                          }
                        }

                        if (!errorMessages.isEmpty()) {
                          Messages.showErrorDialog(
                              errorMessages.iterator().next(),
                              DevKitBundle.message("error.occurred"));
                        } else if (!successMessages.isEmpty()) {
                          StringBuilder messageBuf = new StringBuilder();
                          for (String message : successMessages) {
                            if (messageBuf.length() != 0) {
                              messageBuf.append('\n');
                            }
                            messageBuf.append(message);
                          }
                          Messages.showInfoMessage(
                              messageBuf.toString(),
                              pluginModules.size() == 1
                                  ? DevKitBundle.message(
                                      "success.deployment.message", pluginModules.get(0).getName())
                                  : DevKitBundle.message("success.deployment.message.all"));
                        }
                      }
                    },
                    project.getDisposed());
          }
        });
  }
 /** @deprecated to be removed in IDEA 16 */
 @Nullable
 public static Pattern createFileMaskRegExp(@Nullable String filter) {
   if (filter == null) {
     return null;
   }
   String pattern;
   final List<String> strings = StringUtil.split(filter, ",");
   if (strings.size() == 1) {
     pattern = PatternUtil.convertToRegex(filter.trim());
   } else {
     pattern =
         StringUtil.join(strings, s -> "(" + PatternUtil.convertToRegex(s.trim()) + ")", "|");
   }
   return Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
 }
  @NotNull
  private static VirtualFilePointer[] toPointers(@NotNull List<FilePointerPartNode> pointers) {
    if (pointers.isEmpty()) return VirtualFilePointer.EMPTY_ARRAY;
    List<VirtualFilePointer> list =
        ContainerUtil.mapNotNull(
            pointers,
            new Function<FilePointerPartNode, VirtualFilePointer>() {
              @Override
              public VirtualFilePointer fun(FilePointerPartNode pair) {
                return pair.leaf;
              }
            });

    return list.toArray(new VirtualFilePointer[list.size()]);
  }
  private void assertEvent(Class<? extends VFileEvent> type, String... paths) {
    List<VFileEvent> events = getEvents(type.getSimpleName(), null);
    assertEquals(events.toString(), paths.length, events.size());

    Set<String> pathSet =
        ContainerUtil.map2Set(
            paths,
            new Function<String, String>() {
              @Override
              public String fun(final String path) {
                return FileUtil.toSystemIndependentName(path);
              }
            });

    for (VFileEvent event : events) {
      assertTrue(event.toString(), type.isInstance(event));
      VirtualFile eventFile = event.getFile();
      assertNotNull(event.toString(), eventFile);
      assertTrue(
          eventFile + " not in " + Arrays.toString(paths), pathSet.remove(eventFile.getPath()));
    }
  }
  @NotNull
  private FSRecords.NameId[] persistAllChildren(
      @NotNull final VirtualFile file, final int id, @NotNull FSRecords.NameId[] current) {
    assert file != mySuperRoot;
    final NewVirtualFileSystem fs = replaceWithNativeFS(getDelegate(file));

    String[] delegateNames = VfsUtil.filterNames(fs.list(file));
    if (delegateNames.length == 0 && current.length > 0) {
      return current;
    }

    Set<String> toAdd = ContainerUtil.newHashSet(delegateNames);
    for (FSRecords.NameId nameId : current) {
      toAdd.remove(nameId.name);
    }

    final TIntArrayList childrenIds = new TIntArrayList(current.length + toAdd.size());
    final List<FSRecords.NameId> nameIds =
        ContainerUtil.newArrayListWithExpectedSize(current.length + toAdd.size());
    for (FSRecords.NameId nameId : current) {
      childrenIds.add(nameId.id);
      nameIds.add(nameId);
    }
    for (String newName : toAdd) {
      FakeVirtualFile child = new FakeVirtualFile(file, newName);
      FileAttributes attributes = fs.getAttributes(child);
      if (attributes != null) {
        int childId = createAndFillRecord(fs, child, id, attributes);
        childrenIds.add(childId);
        nameIds.add(new FSRecords.NameId(childId, FileNameCache.storeName(newName), newName));
      }
    }

    FSRecords.updateList(id, childrenIds.toNativeArray());
    setChildrenCached(id);

    return nameIds.toArray(new FSRecords.NameId[nameIds.size()]);
  }
    @Override
    public void after(@NotNull final List<? extends VFileEvent> events) {
      cleanContainerCaches();

      if (myUrlsToUpdate == null) {
        return;
      }
      for (String url : myUrlsToUpdate) {
        synchronized (VirtualFilePointerManagerImpl.this) {
          for (TreeMap<String, VirtualFilePointerImpl> urlToPointer : myUrlToPointerMaps.values()) {
            VirtualFilePointerImpl pointer = urlToPointer.remove(url);
            if (pointer != null) {
              String path = VfsUtil.urlToPath(pointer.getUrl());
              urlToPointer.put(path, pointer);
            }
          }
        }
      }

      for (VirtualFilePointer pointer : myPointersToUpdate) {
        ((VirtualFilePointerImpl) pointer).update();
      }

      for (EventDescriptor event : myEvents) {
        event.fireAfter();
      }

      if (!myPointersToUpdate.isEmpty()) {
        VirtualFilePointer[] arr =
            myPointersToUpdate.toArray(new VirtualFilePointer[myPointersToUpdate.size()]);
        myBus.syncPublisher(VirtualFilePointerListener.TOPIC).validityChanged(arr);
      }

      myUrlsToUpdate = null;
      myEvents = null;
      myPointersToUpdate = null;
    }
    @Override
    public void before(@NotNull final List<? extends VFileEvent> events) {
      cleanContainerCaches();
      List<VirtualFilePointer> toFireEvents = new ArrayList<VirtualFilePointer>();
      List<String> toUpdateUrl = new ArrayList<String>();

      synchronized (VirtualFilePointerManagerImpl.this) {
        for (VFileEvent event : events) {
          if (event instanceof VFileDeleteEvent) {
            final VFileDeleteEvent deleteEvent = (VFileDeleteEvent) event;
            String url = deleteEvent.getFile().getPath();
            addPointersUnder(url, true, toFireEvents);
          } else if (event instanceof VFileCreateEvent) {
            final VFileCreateEvent createEvent = (VFileCreateEvent) event;
            String url = createEvent.getPath();
            addPointersUnder(url, false, toFireEvents);
          } else if (event instanceof VFileCopyEvent) {
            final VFileCopyEvent copyEvent = (VFileCopyEvent) event;
            String url = copyEvent.getNewParent().getPath() + "/" + copyEvent.getFile().getName();
            addPointersUnder(url, false, toFireEvents);
          } else if (event instanceof VFileMoveEvent) {
            final VFileMoveEvent moveEvent = (VFileMoveEvent) event;
            List<VirtualFilePointer> pointers = new ArrayList<VirtualFilePointer>();
            addPointersUnder(moveEvent.getFile().getPath(), false, pointers);
            for (VirtualFilePointer pointer : pointers) {
              VirtualFile file = pointer.getFile();
              if (file != null) {
                toUpdateUrl.add(file.getPath());
              }
            }
          } else if (event instanceof VFilePropertyChangeEvent) {
            final VFilePropertyChangeEvent change = (VFilePropertyChangeEvent) event;
            if (VirtualFile.PROP_NAME.equals(change.getPropertyName())) {
              List<VirtualFilePointer> pointers = new ArrayList<VirtualFilePointer>();
              addPointersUnder(change.getFile().getPath(), false, pointers);
              for (VirtualFilePointer pointer : pointers) {
                VirtualFile file = pointer.getFile();
                if (file != null) {
                  toUpdateUrl.add(file.getPath());
                }
              }
            }
          }
        }

        myEvents = new ArrayList<EventDescriptor>();
        for (VirtualFilePointerListener listener : myUrlToPointerMaps.keySet()) {
          if (listener == null) continue;
          EventDescriptor event = new EventDescriptor(listener, toFireEvents);
          myEvents.add(event);
        }
      }

      for (EventDescriptor event : myEvents) {
        event.fireBefore();
      }

      if (!toFireEvents.isEmpty()) {
        VirtualFilePointer[] arr =
            toFireEvents.toArray(new VirtualFilePointer[toFireEvents.size()]);
        myBus.syncPublisher(VirtualFilePointerListener.TOPIC).beforeValidityChanged(arr);
      }

      myPointersToUpdate = toFireEvents;
      myUrlsToUpdate = toUpdateUrl;
    }
  @Override
  public void before(@NotNull final List<? extends VFileEvent> events) {
    List<FilePointerPartNode> toFireEvents = new ArrayList<FilePointerPartNode>();
    List<FilePointerPartNode> toUpdateUrl = new ArrayList<FilePointerPartNode>();
    VirtualFilePointer[] toFirePointers;

    synchronized (this) {
      incModificationCount();
      for (VFileEvent event : events) {
        if (event instanceof VFileDeleteEvent) {
          final VFileDeleteEvent deleteEvent = (VFileDeleteEvent) event;
          addPointersUnder(deleteEvent.getFile(), false, "", toFireEvents);

        } else if (event instanceof VFileCreateEvent) {
          final VFileCreateEvent createEvent = (VFileCreateEvent) event;
          addPointersUnder(createEvent.getParent(), true, createEvent.getChildName(), toFireEvents);
        } else if (event instanceof VFileCopyEvent) {
          final VFileCopyEvent copyEvent = (VFileCopyEvent) event;
          addPointersUnder(
              copyEvent.getNewParent(), true, copyEvent.getFile().getName(), toFireEvents);
        } else if (event instanceof VFileMoveEvent) {
          final VFileMoveEvent moveEvent = (VFileMoveEvent) event;
          VirtualFile eventFile = moveEvent.getFile();
          addPointersUnder(moveEvent.getNewParent(), true, eventFile.getName(), toFireEvents);

          List<FilePointerPartNode> nodes = new ArrayList<FilePointerPartNode>();
          addPointersUnder(eventFile, false, "", nodes);
          for (FilePointerPartNode pair : nodes) {
            VirtualFile file = pair.leaf.getFile();
            if (file != null) {
              toUpdateUrl.add(pair);
            }
          }
        } else if (event instanceof VFilePropertyChangeEvent) {
          final VFilePropertyChangeEvent change = (VFilePropertyChangeEvent) event;
          if (VirtualFile.PROP_NAME.equals(change.getPropertyName())) {
            VirtualFile eventFile = change.getFile();
            VirtualFile parent = eventFile.getParent(); // e.g. for LightVirtualFiles
            addPointersUnder(parent, true, change.getNewValue().toString(), toFireEvents);

            List<FilePointerPartNode> nodes = new ArrayList<FilePointerPartNode>();
            addPointersUnder(eventFile, false, "", nodes);
            for (FilePointerPartNode pair : nodes) {
              VirtualFile file = pair.leaf.getFile();
              if (file != null) {
                toUpdateUrl.add(pair);
              }
            }
          }
        }
      }

      myEvents = new ArrayList<EventDescriptor>();
      toFirePointers = toPointers(toFireEvents);
      for (final VirtualFilePointerListener listener : myPointers.keySet()) {
        if (listener == null) continue;
        List<VirtualFilePointer> filtered =
            ContainerUtil.filter(
                toFirePointers,
                new Condition<VirtualFilePointer>() {
                  @Override
                  public boolean value(VirtualFilePointer pointer) {
                    return ((VirtualFilePointerImpl) pointer).getListener() == listener;
                  }
                });
        if (!filtered.isEmpty()) {
          EventDescriptor event =
              new EventDescriptor(
                  listener, filtered.toArray(new VirtualFilePointer[filtered.size()]));
          myEvents.add(event);
        }
      }
    }

    for (EventDescriptor descriptor : myEvents) {
      descriptor.fireBefore();
    }

    if (!toFireEvents.isEmpty()) {
      myBus.syncPublisher(VirtualFilePointerListener.TOPIC).beforeValidityChanged(toFirePointers);
    }

    myPointersToFire = toFireEvents;
    myPointersToUpdateUrl = toUpdateUrl;
  }
 private void cacheOpenProjects() {
   myOpenProjectsArrayCache = myOpenProjects.toArray(new Project[myOpenProjects.size()]);
 }
  public static void generate(GeneratingCompiler compiler, final CompileContext context) {
    if (context == null) {
      return;
    }

    final Set<Module> affectedModules = new HashSet<Module>();
    Collections.addAll(affectedModules, context.getCompileScope().getAffectedModules());

    ApplicationManager.getApplication()
        .invokeAndWait(
            new Runnable() {
              @Override
              public void run() {
                for (Module module : affectedModules) {
                  if (module.isDisposed() || module.getProject().isDisposed()) {
                    continue;
                  }

                  final AndroidFacet facet = AndroidFacet.getInstance(module);
                  if (facet != null) {
                    AndroidCompileUtil.createGenModulesAndSourceRoots(facet);
                  }
                }
              }
            },
            ModalityState.defaultModalityState());

    List<GeneratingCompiler.GenerationItem> itemsToGenerate =
        new ArrayList<GeneratingCompiler.GenerationItem>();
    for (GeneratingCompiler.GenerationItem item : compiler.getGenerationItems(context)) {
      if (affectedModules.contains(item.getModule())) {
        itemsToGenerate.add(item);
      }
    }

    GeneratingCompiler.GenerationItem[] items =
        itemsToGenerate.toArray(new GeneratingCompiler.GenerationItem[itemsToGenerate.size()]);

    final boolean[] run = {true};
    final VirtualFile[] files = getFilesToCheckReadonlyStatus(items);
    if (files.length > 0) {
      ApplicationManager.getApplication()
          .invokeAndWait(
              new Runnable() {
                @Override
                public void run() {
                  ApplicationManager.getApplication()
                      .runReadAction(
                          new Runnable() {
                            @Override
                            public void run() {
                              final Project project = context.getProject();
                              run[0] =
                                  !project.isDisposed()
                                      && ReadonlyStatusHandler.ensureFilesWritable(project, files);
                            }
                          });
                }
              },
              ModalityState.defaultModalityState());
    }

    if (run[0]) {
      compiler.generate(context, items, null);
    }
  }