mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new framework detection: show only valid detected framework in the dialog, tests added
This commit is contained in:
+2
-2
@@ -109,8 +109,8 @@ public class DetectedFrameworksData {
|
||||
return myDetectedFrameworks;
|
||||
}
|
||||
|
||||
public List<? extends DetectedFrameworkDescription> updateFrameworksList(Integer detectorId,
|
||||
List<? extends DetectedFrameworkDescription> frameworks) {
|
||||
public Collection<? extends DetectedFrameworkDescription> updateFrameworksList(Integer detectorId,
|
||||
Collection<? extends DetectedFrameworkDescription> frameworks) {
|
||||
final Collection<DetectedFrameworkDescription> oldFrameworks = myDetectedFrameworks.remove(detectorId);
|
||||
myDetectedFrameworks.putValues(detectorId, frameworks);
|
||||
if (oldFrameworks != null) {
|
||||
|
||||
+9
-3
@@ -24,7 +24,6 @@ import com.intellij.openapi.roots.ModifiableModelsProvider;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -45,8 +44,11 @@ public abstract class FacetBasedDetectedFrameworkDescription<F extends Facet, C
|
||||
myConfiguration = configuration;
|
||||
myRelatedFiles = files;
|
||||
myFacetType = detector.getFacetType();
|
||||
final Icon icon = myFacetType.getIcon();
|
||||
myFrameworkType = new FrameworkType(myFacetType.getStringId(), myFacetType.getPresentableName(), icon);
|
||||
myFrameworkType = createFrameworkType(myFacetType);
|
||||
}
|
||||
|
||||
public static FrameworkType createFrameworkType(final FacetType<?, ?> facetType) {
|
||||
return new FrameworkType(facetType.getStringId(), facetType.getPresentableName(), facetType.getIcon());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -61,6 +63,10 @@ public abstract class FacetBasedDetectedFrameworkDescription<F extends Facet, C
|
||||
return myRelatedFiles;
|
||||
}
|
||||
|
||||
public C getConfiguration() {
|
||||
return myConfiguration;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getSetupDescription() {
|
||||
|
||||
+106
-41
@@ -27,6 +27,7 @@ import com.intellij.notification.NotificationGroup;
|
||||
import com.intellij.notification.NotificationListener;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -37,6 +38,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectBundle;
|
||||
import com.intellij.openapi.roots.PlatformModifiableModelsProvider;
|
||||
import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -46,6 +48,7 @@ import com.intellij.util.indexing.FileBasedIndex;
|
||||
import com.intellij.util.ui.update.MergingUpdateQueue;
|
||||
import com.intellij.util.ui.update.Update;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import java.util.*;
|
||||
@@ -60,7 +63,7 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen
|
||||
private final Update myDetectionUpdate = new Update("detection") {
|
||||
@Override
|
||||
public void run() {
|
||||
runDetection();
|
||||
doRunDetection();
|
||||
}
|
||||
};
|
||||
private final Set<Integer> myDetectorsToProcess = new HashSet<Integer>();
|
||||
@@ -81,6 +84,10 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen
|
||||
public void initComponent() {
|
||||
if (myProject.isDefault()) return;
|
||||
myDetectionQueue = new MergingUpdateQueue("FrameworkDetectionQueue", 500, true, null, myProject);
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
myDetectionQueue.setPassThrough(false);
|
||||
myDetectionQueue.hideNotify();
|
||||
}
|
||||
myDetectedFrameworksData = new DetectedFrameworksData(myProject);
|
||||
FrameworkDetectionIndex.getInstance().addListener(this, myProject);
|
||||
myProject.getMessageBus().connect().subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() {
|
||||
@@ -98,12 +105,10 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen
|
||||
|
||||
@Override
|
||||
public void projectOpened() {
|
||||
final int[] ids = FrameworkDetectorRegistry.getInstance().getAllDetectorIds();
|
||||
final Collection<Integer> ids = FrameworkDetectorRegistry.getInstance().getAllDetectorIds();
|
||||
synchronized (myLock) {
|
||||
myDetectorsToProcess.clear();
|
||||
for (int id : ids) {
|
||||
myDetectorsToProcess.add(id);
|
||||
}
|
||||
myDetectorsToProcess.addAll(ids);
|
||||
}
|
||||
queueDetection();
|
||||
}
|
||||
@@ -136,7 +141,7 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen
|
||||
return null;
|
||||
}
|
||||
|
||||
private void runDetection() {
|
||||
private void doRunDetection() {
|
||||
Set<Integer> detectorsToProcess;
|
||||
synchronized (myLock) {
|
||||
detectorsToProcess = new HashSet<Integer>(myDetectorsToProcess);
|
||||
@@ -149,34 +154,16 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen
|
||||
LOG.debug("Starting framework detectors: " + detectorsToProcess);
|
||||
}
|
||||
final FileBasedIndex index = FileBasedIndex.getInstance();
|
||||
Map<Integer, List<? extends DetectedFrameworkDescription>> newDescriptions = new HashMap<Integer, List<? extends DetectedFrameworkDescription>>();
|
||||
Map<Integer, Collection<? extends DetectedFrameworkDescription>> newDescriptions = new HashMap<Integer, Collection<? extends DetectedFrameworkDescription>>();
|
||||
final DetectionExcludesConfiguration excludesConfiguration = DetectionExcludesConfiguration.getInstance(myProject);
|
||||
for (Integer id : detectorsToProcess) {
|
||||
Collection<VirtualFile> files = index.getContainingFiles(FrameworkDetectionIndex.NAME, id, GlobalSearchScope.projectScope(myProject));
|
||||
final Collection<VirtualFile> newFiles = myDetectedFrameworksData.retainNewFiles(id, files);
|
||||
FrameworkDetector detector = FrameworkDetectorRegistry.getInstance().getDetectorById(id);
|
||||
if (detector != null) {
|
||||
excludesConfiguration.removeExcluded(newFiles, detector);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Detector '" + detector.getDetectorId() + "': " + files.size() + " accepted files, " + newFiles.size() + " files to process");
|
||||
}
|
||||
final List<? extends DetectedFrameworkDescription> frameworks;
|
||||
if (!newFiles.isEmpty()) {
|
||||
frameworks = detector.detect(newFiles, new FrameworkDetectionContextImpl(myProject));
|
||||
}
|
||||
else {
|
||||
frameworks = Collections.emptyList();
|
||||
}
|
||||
final List<? extends DetectedFrameworkDescription> updated = myDetectedFrameworksData.updateFrameworksList(id, frameworks);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(frameworks.size() + " frameworks detected, " + updated.size() + " changed");
|
||||
}
|
||||
if (!updated.isEmpty()) {
|
||||
newDescriptions.put(id, updated);
|
||||
}
|
||||
final List<? extends DetectedFrameworkDescription> frameworks = runDetector(id, index, excludesConfiguration, true);
|
||||
final Collection<? extends DetectedFrameworkDescription> updated = myDetectedFrameworksData.updateFrameworksList(id, frameworks);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(frameworks.size() + " frameworks detected, " + updated.size() + " changed");
|
||||
}
|
||||
else {
|
||||
LOG.info("Framework detector not found by id " + id);
|
||||
if (!updated.isEmpty()) {
|
||||
newDescriptions.put(id, updated);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,15 +188,44 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen
|
||||
}
|
||||
}
|
||||
|
||||
private List<? extends DetectedFrameworkDescription> runDetector(Integer detectorId,
|
||||
FileBasedIndex index,
|
||||
DetectionExcludesConfiguration excludesConfiguration,
|
||||
final boolean processNewFilesOnly) {
|
||||
Collection<VirtualFile> acceptedFiles = index.getContainingFiles(FrameworkDetectionIndex.NAME, detectorId, GlobalSearchScope.projectScope(myProject));
|
||||
final Collection<VirtualFile> filesToProcess;
|
||||
if (processNewFilesOnly) {
|
||||
filesToProcess = myDetectedFrameworksData.retainNewFiles(detectorId, acceptedFiles);
|
||||
}
|
||||
else {
|
||||
filesToProcess = new ArrayList<VirtualFile>(acceptedFiles);
|
||||
}
|
||||
FrameworkDetector detector = FrameworkDetectorRegistry.getInstance().getDetectorById(detectorId);
|
||||
if (detector == null) {
|
||||
LOG.info("Framework detector not found by id " + detectorId);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
excludesConfiguration.removeExcluded(filesToProcess, detector);
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Detector '" + detector.getDetectorId() + "': " + acceptedFiles.size() + " accepted files, " + filesToProcess.size() + " files to process");
|
||||
}
|
||||
final List<? extends DetectedFrameworkDescription> frameworks;
|
||||
if (!filesToProcess.isEmpty()) {
|
||||
frameworks = detector.detect(filesToProcess, new FrameworkDetectionContextImpl(myProject));
|
||||
}
|
||||
else {
|
||||
frameworks = Collections.emptyList();
|
||||
}
|
||||
return frameworks;
|
||||
}
|
||||
|
||||
private void showSetupFrameworksDialog(Notification notification) {
|
||||
final MultiMap<Integer,DetectedFrameworkDescription> frameworks = myDetectedFrameworksData.getDetectedFrameworks();
|
||||
IdentityHashMap<DetectedFrameworkDescription, Integer> frameworksToId = new IdentityHashMap<DetectedFrameworkDescription, Integer>();
|
||||
List<DetectedFrameworkDescription> descriptions = new ArrayList<DetectedFrameworkDescription>();
|
||||
for (Integer id : frameworks.keySet()) {
|
||||
for (DetectedFrameworkDescription description : frameworks.get(id)) {
|
||||
descriptions.add(description);
|
||||
frameworksToId.put(description, id);
|
||||
}
|
||||
List<DetectedFrameworkDescription> descriptions = getValidDetectedFrameworks(frameworksToId);
|
||||
if (descriptions.isEmpty()) {
|
||||
Messages.showInfoMessage(myProject, "No frameworks are detected", "Framework Detection");
|
||||
return;
|
||||
}
|
||||
final ConfigureDetectedFrameworksDialog dialog = new ConfigureDetectedFrameworksDialog(myProject, descriptions);
|
||||
dialog.show();
|
||||
@@ -230,6 +246,57 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen
|
||||
}
|
||||
}
|
||||
|
||||
private List<DetectedFrameworkDescription> getValidDetectedFrameworks(IdentityHashMap<DetectedFrameworkDescription, Integer> frameworksToId) {
|
||||
final MultiMap<Integer,DetectedFrameworkDescription> frameworksMap = myDetectedFrameworksData.getDetectedFrameworks();
|
||||
List<DetectedFrameworkDescription> descriptions = new ArrayList<DetectedFrameworkDescription>();
|
||||
final FileBasedIndex index = FileBasedIndex.getInstance();
|
||||
final DetectionExcludesConfiguration excludesConfiguration = DetectionExcludesConfiguration.getInstance(myProject);
|
||||
for (Integer id : frameworksMap.keySet()) {
|
||||
final Collection<VirtualFile> acceptedFiles = index.getContainingFiles(FrameworkDetectionIndex.NAME, id,
|
||||
GlobalSearchScope.projectScope(myProject));
|
||||
boolean obsolete = false;
|
||||
for (DetectedFrameworkDescription description : frameworksMap.get(id)) {
|
||||
if (!acceptedFiles.containsAll(description.getRelatedFiles())) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("Some files from " + description.getRelatedFiles() + " aren't accepted by detector any more (accepted = " + acceptedFiles + ")");
|
||||
}
|
||||
obsolete = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
final Collection<? extends DetectedFrameworkDescription> frameworks;
|
||||
if (obsolete) {
|
||||
frameworks = runDetector(id, index, excludesConfiguration, false);
|
||||
}
|
||||
else {
|
||||
frameworks = frameworksMap.get(id);
|
||||
}
|
||||
|
||||
for (DetectedFrameworkDescription framework : frameworks) {
|
||||
descriptions.add(framework);
|
||||
frameworksToId.put(framework, id);
|
||||
}
|
||||
}
|
||||
return descriptions;
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public void runDetection() {
|
||||
ensureIndexIsUpToDate(FrameworkDetectorRegistry.getInstance().getAllDetectorIds());
|
||||
doRunDetection();
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public List<DetectedFrameworkDescription> getDetectedFrameworks() {
|
||||
return getValidDetectedFrameworks(new IdentityHashMap<DetectedFrameworkDescription, Integer>());
|
||||
}
|
||||
|
||||
private void ensureIndexIsUpToDate(final Collection<Integer> detectors) {
|
||||
for (Integer detectorId : detectors) {
|
||||
FileBasedIndex.getInstance().getValues(FrameworkDetectionIndex.NAME, detectorId, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
}
|
||||
|
||||
private class FrameworkDetectionHighlightingPass extends TextEditorHighlightingPass {
|
||||
private final Collection<Integer> myDetectors;
|
||||
|
||||
@@ -240,9 +307,7 @@ public class FrameworkDetectionManager extends AbstractProjectComponent implemen
|
||||
|
||||
@Override
|
||||
public void doCollectInformation(ProgressIndicator progress) {
|
||||
for (Integer detectorId : myDetectors) {
|
||||
FileBasedIndex.getInstance().getValues(FrameworkDetectionIndex.NAME, detectorId, GlobalSearchScope.projectScope(myProject));
|
||||
}
|
||||
ensureIndexIsUpToDate(myDetectors);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -50,5 +50,5 @@ public abstract class FrameworkDetectorRegistry {
|
||||
@NotNull
|
||||
public abstract Collection<Integer> getDetectorIds(@NotNull FileType fileType);
|
||||
|
||||
public abstract int[] getAllDetectorIds();
|
||||
public abstract Collection<Integer> getAllDetectorIds();
|
||||
}
|
||||
|
||||
+7
-2
@@ -189,7 +189,12 @@ public class FrameworkDetectorRegistryImpl extends FrameworkDetectorRegistry {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getAllDetectorIds() {
|
||||
return myDetectorIds.getValues();
|
||||
public Collection<Integer> getAllDetectorIds() {
|
||||
final int[] ids = myDetectorIds.getValues();
|
||||
final List<Integer> result = new ArrayList<Integer>();
|
||||
for (int id : ids) {
|
||||
result.add(id);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package com.intellij.testFramework;
|
||||
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -43,6 +45,7 @@ import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
@NonNls public class PsiTestUtil {
|
||||
@@ -187,6 +190,28 @@ import java.util.Collection;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void addExcludedRoot(Module module, VirtualFile dir) {
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
|
||||
boolean added = false;
|
||||
for (ContentEntry entry : model.getContentEntries()) {
|
||||
if (VfsUtil.isAncestor(entry.getFile(), dir, false)) {
|
||||
entry.addExcludeFolder(dir);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
throw new RuntimeException(dir + " is not under content roots: " + Arrays.toString(model.getContentRoots()));
|
||||
}
|
||||
model.commit();
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeContentEntry(final Module module, final ContentEntry e) {
|
||||
new WriteCommandAction.Simple(module.getProject()) {
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.testFramework;
|
||||
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.text.StringTokenizer;
|
||||
import junit.framework.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class VfsTestUtil {
|
||||
private VfsTestUtil() {
|
||||
}
|
||||
|
||||
public static VirtualFile createFile(final VirtualFile root, final String relativePath) {
|
||||
return createFile(root, relativePath, "");
|
||||
}
|
||||
|
||||
public static VirtualFile createFile(final VirtualFile root, final String relativePath, final String text) {
|
||||
return createFileOrDir(root, relativePath, text, false);
|
||||
}
|
||||
|
||||
public static VirtualFile createDir(final VirtualFile root, final String relativePath) {
|
||||
return createFileOrDir(root, relativePath, "", true);
|
||||
}
|
||||
|
||||
private static VirtualFile createFileOrDir(final VirtualFile root,
|
||||
final String relativePath,
|
||||
final String text,
|
||||
final boolean dir) {
|
||||
try {
|
||||
AccessToken token = WriteAction.start();
|
||||
try {
|
||||
VirtualFile parent = root;
|
||||
Assert.assertNotNull(parent);
|
||||
StringTokenizer parents = new StringTokenizer(PathUtil.getParentPath(relativePath), "/");
|
||||
while (parents.hasMoreTokens()) {
|
||||
final String name = parents.nextToken();
|
||||
VirtualFile child = parent.findChild(name);
|
||||
if (child == null || !child.isValid()) {
|
||||
child = parent.createChildDirectory(VfsTestUtil.class, name);
|
||||
}
|
||||
parent = child;
|
||||
}
|
||||
final VirtualFile file;
|
||||
if (dir) {
|
||||
file = parent.createChildDirectory(VfsTestUtil.class, PathUtil.getFileName(relativePath));
|
||||
}
|
||||
else {
|
||||
file = parent.createChildData(VfsTestUtil.class, PathUtil.getFileName(relativePath));
|
||||
VfsUtil.saveText(file, text);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearContent(VirtualFile file) {
|
||||
Assert.assertNotNull(file);
|
||||
try {
|
||||
VfsUtil.saveText(file, "");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user