void () { if (LightEdit.owns(myProject)) { return; } Set<String> detectorsToProcess; synchronized (myLock) { detectorsToProcess = new HashSet<>(myDetectorsToProcess); myDetectorsToProcess.clear(); } if (detectorsToProcess.isEmpty()) { return; } if (LOG.isDebugEnabled()) { LOG.debug("Starting framework detectors: " + detectorsToProcess); } List<DetectedFrameworkDescription> newDescriptions = new ArrayList<>(); List<DetectedFrameworkDescription> oldDescriptions = new ArrayList<>(); for (String id : detectorsToProcess) { final List<? extends DetectedFrameworkDescription> frameworks = ReadAction .nonBlocking(() -> runDetector(id, true)) .inSmartMode(myProject) .executeSynchronously(); oldDescriptions.addAll(frameworks); final Collection<? extends DetectedFrameworkDescription> updated = myDetectedFrameworksData.updateFrameworksList(id, frameworks); newDescriptions.addAll(updated); oldDescriptions.removeAll(updated); if (LOG.isDebugEnabled()) { LOG.debug(frameworks.size() + " frameworks detected, " + updated.size() + " changed"); } } if (!newDescriptions.isEmpty()) { Set<String> frameworkNames = ReadAction.nonBlocking(() -> { Set<String> names = new HashSet<>(); for (final DetectedFrameworkDescription description : FrameworkDetectionUtil.removeDisabled(newDescriptions, oldDescriptions)) { names.add(description.getDetector().getFrameworkType().getPresentableName()); } return names; }) .expireWith(this) .executeSynchronously(); if (!frameworkNames.isEmpty()) { String names = StringUtil.join(frameworkNames, ", "); final String text = ProjectBundle.message("framework.detected.info.text", names, frameworkNames.size()); NotificationGroupManager.getInstance().getNotificationGroup("Framework Detection") .createNotification(ProjectBundle.message("notification.title.frameworks.detected"), text, NotificationType.INFORMATION) .addAction(new NotificationAction(IdeBundle.messagePointer("action.Anonymous.text.configure")) { @Override public void actionPerformed(@NotNull AnActionEvent e, @NotNull Notification notification) { showSetupFrameworksDialog(notification); } }) .notify(myProject); } } }