mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
-1
@@ -6,7 +6,6 @@ import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.keymap.KeymapUtil
|
||||
import com.intellij.testGuiFramework.fixtures.IdeFrameFixture
|
||||
import com.intellij.testGuiFramework.impl.GuiTestCase
|
||||
import com.intellij.testGuiFramework.impl.LogActionsDuringTest
|
||||
import com.intellij.testGuiFramework.impl.ScreenshotsDuringTest
|
||||
import com.intellij.testGuiFramework.tests.community.CommunityProjectCreator
|
||||
import com.intellij.testGuiFramework.util.Key.ESCAPE
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.uast;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.UastLanguagePlugin;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class UastMetaLanguage extends MetaLanguage {
|
||||
private final Set<Language> myLanguages = new HashSet<>();
|
||||
private final Set<Language> myLanguages;
|
||||
|
||||
protected UastMetaLanguage() {
|
||||
super("UAST");
|
||||
for (UastLanguagePlugin plugin: UastLanguagePlugin.Companion.getInstances()) {
|
||||
|
||||
Collection<UastLanguagePlugin> languagePlugins = UastLanguagePlugin.Companion.getInstances();
|
||||
myLanguages = new THashSet<>(languagePlugins.size());
|
||||
for (UastLanguagePlugin plugin: languagePlugins) {
|
||||
myLanguages.add(plugin.getLanguage());
|
||||
}
|
||||
}
|
||||
@@ -31,6 +35,6 @@ public class UastMetaLanguage extends MetaLanguage {
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<Language> getMatchingLanguages() {
|
||||
return myLanguages;
|
||||
return Collections.unmodifiableSet(myLanguages);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-23
@@ -5,7 +5,6 @@ import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -13,12 +12,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
* @author max
|
||||
*/
|
||||
public class VFileCreateEvent extends VFileEvent {
|
||||
@NotNull private final VirtualFile myParent;
|
||||
private final @NotNull VirtualFile myParent;
|
||||
private final @NotNull String myChildName;
|
||||
private final boolean myDirectory;
|
||||
private final boolean myEmptyDirectory;
|
||||
@NotNull private final String myChildName;
|
||||
private final FileAttributes myAttributes;
|
||||
private final String mySymlinkTarget;
|
||||
private final boolean myEmptyDirectory;
|
||||
private VirtualFile myCreatedFile;
|
||||
|
||||
public VFileCreateEvent(Object requestor,
|
||||
@@ -30,8 +29,8 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
boolean isFromRefresh,
|
||||
boolean isEmptyDirectory) {
|
||||
super(requestor, isFromRefresh);
|
||||
myChildName = childName;
|
||||
myParent = parent;
|
||||
myChildName = childName;
|
||||
myDirectory = isDirectory;
|
||||
myAttributes = attributes;
|
||||
mySymlinkTarget = symlinkTarget;
|
||||
@@ -47,13 +46,6 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
return myDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the newly created file is a directory which has no children.
|
||||
*/
|
||||
public boolean isEmptyDirectory() {
|
||||
return isDirectory() && myEmptyDirectory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getParent() {
|
||||
return myParent;
|
||||
@@ -69,11 +61,9 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
return mySymlinkTarget;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VfsEvent[create " + (myDirectory ? (isEmptyDirectory() ? "(empty) " :"") + "dir "
|
||||
: "file ") + myChildName + " in " + myParent.getUrl() + "]";
|
||||
/** @return true if the newly created file is a directory which has no children. */
|
||||
public boolean isEmptyDirectory() {
|
||||
return isDirectory() && myEmptyDirectory;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -105,12 +95,7 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
if (myParent.isValid()) {
|
||||
boolean childExists = myParent.findChild(myChildName) != null;
|
||||
return !childExists;
|
||||
}
|
||||
|
||||
return false;
|
||||
return myParent.isValid() && myParent.findChild(myChildName) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,4 +118,10 @@ public class VFileCreateEvent extends VFileEvent {
|
||||
result = 31 * result + myChildName.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String kind = myDirectory ? (isEmptyDirectory() ? "(empty) " : "") + "dir " : "file ";
|
||||
return "VfsEvent[create " + kind + myChildName + " in " + myParent.getUrl() + "]";
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -197,7 +197,7 @@ public class ShowIntentionActionsHandler implements CodeInsightActionHandler {
|
||||
}
|
||||
|
||||
private static void invokeIntention(@NotNull IntentionAction action, @Nullable Editor editor, @NotNull PsiFile file) {
|
||||
IntentionsCollector.getInstance().record(action, file.getLanguage());
|
||||
IntentionsCollector.getInstance().record(file.getProject(), action, file.getLanguage());
|
||||
PsiElement elementToMakeWritable = action.getElementToMakeWritable(file);
|
||||
if (elementToMakeWritable != null && !FileModificationService.getInstance().preparePsiElementsForWrite(elementToMakeWritable)) {
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.intellij.ide.actions;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.xmlb.annotations.MapAnnotation;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -18,18 +19,10 @@ import java.util.Map;
|
||||
*/
|
||||
public abstract class ActionsCollector {
|
||||
/**
|
||||
* Only actions from platform and JB plugins are recorded.
|
||||
* If no context class is provided then nothing will be recorded.
|
||||
* @deprecated use {@link #record(String, Class)} instead
|
||||
* @deprecated use {@link #record(Project, AnAction, AnActionEvent)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void record(String actionId) {}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #record(AnAction, AnActionEvent)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public void record(@Nullable String actionId, @NotNull Class context, @Nullable AnActionEvent event) {}
|
||||
public void record(@Nullable AnAction action, @Nullable AnActionEvent event) {}
|
||||
|
||||
/**
|
||||
* Records explicitly whitelisted actions
|
||||
@@ -47,7 +40,7 @@ public abstract class ActionsCollector {
|
||||
* Records action id for global actions or action class name for actions generated on runtime.
|
||||
* Only actions from platform and JB plugins are recorded.
|
||||
*/
|
||||
public abstract void record(@Nullable AnAction action, @Nullable AnActionEvent event);
|
||||
public abstract void record(@Nullable Project project, @Nullable AnAction action, @Nullable AnActionEvent event);
|
||||
|
||||
public abstract State getState();
|
||||
|
||||
|
||||
+3
-2
@@ -16,6 +16,7 @@ import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.RoamingType;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -53,11 +54,11 @@ public class ActionsCollectorImpl extends ActionsCollector implements Persistent
|
||||
}
|
||||
|
||||
@Override
|
||||
public void record(@Nullable AnAction action, @Nullable AnActionEvent event) {
|
||||
public void record(@Nullable Project project, @Nullable AnAction action, @Nullable AnActionEvent event) {
|
||||
if (action == null) return;
|
||||
|
||||
final PluginInfo info = PluginInfoDetectorKt.getPluginInfo(action.getClass());
|
||||
final FeatureUsageData data = new FeatureUsageData().addOS().addPluginInfo(info);
|
||||
final FeatureUsageData data = new FeatureUsageData().addOS().addProject(project).addPluginInfo(info);
|
||||
|
||||
if (event != null) {
|
||||
data.addInputEvent(event).
|
||||
|
||||
+6
@@ -12,6 +12,7 @@ import com.intellij.internal.statistic.utils.PluginInfo;
|
||||
import com.intellij.internal.statistic.utils.PluginInfoDetectorKt;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.components.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.xmlb.annotations.MapAnnotation;
|
||||
import com.intellij.util.xmlb.annotations.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -41,10 +42,15 @@ public class IntentionsCollector implements PersistentStateComponent<IntentionsC
|
||||
}
|
||||
|
||||
public void record(@NotNull IntentionAction action, @NotNull Language language) {
|
||||
record(null, action, language);
|
||||
}
|
||||
|
||||
public void record(@Nullable Project project, @NotNull IntentionAction action, @NotNull Language language) {
|
||||
final Class<?> clazz = getOriginalHandlerClass(action);
|
||||
final PluginInfo info = PluginInfoDetectorKt.getPluginInfo(clazz);
|
||||
|
||||
final FeatureUsageData data = new FeatureUsageData().addOS().
|
||||
addProject(project).
|
||||
addPluginInfo(info).
|
||||
addLanguage(language);
|
||||
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ import java.util.prefs.Preferences
|
||||
object EventLogConfiguration {
|
||||
private val LOG = Logger.getInstance(EventLogConfiguration::class.java)
|
||||
private const val SALT_PREFERENCE_KEY = "feature_usage_event_log_salt"
|
||||
const val version: Int = 7
|
||||
const val version: Int = 8
|
||||
|
||||
val sessionId: String = UUID.randomUUID().toString().shortedUUID()
|
||||
|
||||
|
||||
+1
-1
@@ -1191,7 +1191,7 @@ public final class ActionManagerImpl extends ActionManagerEx implements Disposab
|
||||
}
|
||||
//noinspection AssignmentToStaticFieldFromInstanceMethod
|
||||
IdeaLogger.ourLastActionId = myLastPreformedActionId;
|
||||
ActionsCollector.getInstance().record(action, event);
|
||||
ActionsCollector.getInstance().record(CommonDataKeys.PROJECT.getData(dataContext), action, event);
|
||||
for (AnActionListener listener : myActionListeners) {
|
||||
listener.beforeActionPerformed(action, dataContext, event);
|
||||
}
|
||||
|
||||
+3
-6
@@ -3,7 +3,6 @@ package com.intellij.openapi.vfs.newvfs.persistent;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
@@ -35,9 +34,9 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
class LocalFileSystemRefreshWorker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.newvfs.persistent.RefreshWorker");
|
||||
import static com.intellij.openapi.vfs.newvfs.persistent.VfsEventGenerationHelper.LOG;
|
||||
|
||||
class LocalFileSystemRefreshWorker {
|
||||
private final boolean myIsRecursive;
|
||||
private final Queue<NewVirtualFile> myRefreshQueue = new Queue<>(100);
|
||||
private final VfsEventGenerationHelper myHelper = new VfsEventGenerationHelper();
|
||||
@@ -89,9 +88,7 @@ class LocalFileSystemRefreshWorker {
|
||||
|
||||
while (!myRefreshQueue.isEmpty()) {
|
||||
NewVirtualFile file = myRefreshQueue.pullFirst();
|
||||
boolean fileDirty = file.isDirty();
|
||||
if (LOG.isTraceEnabled()) LOG.trace("file=" + file + " dirty=" + fileDirty);
|
||||
if (!fileDirty) continue;
|
||||
if (!myHelper.checkDirty(file)) continue;
|
||||
|
||||
checkCancelled(file);
|
||||
|
||||
|
||||
+20
-33
@@ -3,12 +3,10 @@ package com.intellij.openapi.vfs.newvfs.persistent;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VFileProperty;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -36,14 +34,13 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.openapi.util.Pair.pair;
|
||||
import static com.intellij.openapi.vfs.newvfs.persistent.VfsEventGenerationHelper.LOG;
|
||||
import static com.intellij.util.containers.ContainerUtil.newTroveSet;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class RefreshWorker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.newvfs.persistent.RefreshWorker");
|
||||
|
||||
private final boolean myIsRecursive;
|
||||
private final Queue<Pair<NewVirtualFile, FileAttributes>> myRefreshQueue = new Queue<>(100);
|
||||
private final VfsEventGenerationHelper myHelper = new VfsEventGenerationHelper();
|
||||
@@ -74,6 +71,7 @@ public class RefreshWorker {
|
||||
myLocalFileSystemRefreshWorker.scan();
|
||||
return;
|
||||
}
|
||||
|
||||
NewVirtualFile root = myRefreshQueue.peekFirst().first;
|
||||
NewVirtualFileSystem fs = root.getFileSystem();
|
||||
if (root.isDirectory()) {
|
||||
@@ -93,9 +91,7 @@ public class RefreshWorker {
|
||||
while (!myRefreshQueue.isEmpty()) {
|
||||
Pair<NewVirtualFile, FileAttributes> pair = myRefreshQueue.pullFirst();
|
||||
NewVirtualFile file = pair.first;
|
||||
boolean fileDirty = file.isDirty();
|
||||
if (LOG.isTraceEnabled()) LOG.trace("file=" + file + " dirty=" + fileDirty);
|
||||
if (!fileDirty) continue;
|
||||
if (!myHelper.checkDirty(file)) continue;
|
||||
|
||||
checkCancelled(file);
|
||||
|
||||
@@ -216,18 +212,11 @@ public class RefreshWorker {
|
||||
|
||||
return true;
|
||||
});
|
||||
if (hasEvents) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasEvents) break;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Path appendPath(@NotNull String parent, @NotNull String name) {
|
||||
return StringUtil.endsWith(parent, "/") ? Paths.get(parent + name) : Paths.get(parent + "/" + name);
|
||||
}
|
||||
|
||||
|
||||
private void partialDirRefresh(@NotNull NewVirtualFileSystem fs,
|
||||
@NotNull TObjectHashingStrategy<String> strategy,
|
||||
@NotNull VirtualDirectoryImpl dir) {
|
||||
@@ -289,9 +278,8 @@ public class RefreshWorker {
|
||||
|
||||
return true;
|
||||
});
|
||||
if (hasEvents) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasEvents) break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,21 +302,10 @@ public class RefreshWorker {
|
||||
FileAttributes attributes = fs.getAttributes(file);
|
||||
if (attributes == null) return null;
|
||||
String symlinkTarget = attributes.isSymLink() ? fs.resolveSymLink(file) : null;
|
||||
return new NewChildRecord(name, appendPath(dir.getPath(), name), attributes, symlinkTarget);
|
||||
return new NewChildRecord(name, Paths.get(dir.getPath() + '/' + name), attributes, symlinkTarget);
|
||||
}
|
||||
|
||||
private void checkAndScheduleFileNameChange(@Nullable OpenTHashSet<String> actualNames, @NotNull VirtualFile child) {
|
||||
if (actualNames != null) {
|
||||
String currentName = child.getName();
|
||||
String actualName = actualNames.get(currentName);
|
||||
if (actualName != null && !currentName.equals(actualName)) {
|
||||
myHelper.scheduleAttributeChange(child, VirtualFile.PROP_NAME, currentName, actualName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class RefreshCancelledException extends RuntimeException {
|
||||
}
|
||||
private static class RefreshCancelledException extends RuntimeException { }
|
||||
|
||||
private void checkCancelled(@NotNull NewVirtualFile stopAt) {
|
||||
if (myCancelled || ourCancellingCondition != null && ourCancellingCondition.fun(stopAt)) {
|
||||
@@ -373,13 +350,23 @@ public class RefreshWorker {
|
||||
if (currentIsDirectory != upToDateIsDirectory || currentIsSymlink != upToDateIsSymlink || currentIsSpecial != upToDateIsSpecial) {
|
||||
myHelper.scheduleDeletion(child);
|
||||
String symlinkTarget = upToDateIsSymlink ? fs.resolveSymLink(child) : null;
|
||||
myHelper.scheduleCreation(parent, child.getName(), appendPath(parent.getPath(), child.getName()), childAttributes, symlinkTarget);
|
||||
myHelper.scheduleCreation(parent, child.getName(), Paths.get(parent.getPath() + '/' + child.getName()), childAttributes, symlinkTarget);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkAndScheduleFileNameChange(@Nullable OpenTHashSet<String> actualNames, @NotNull VirtualFile child) {
|
||||
if (actualNames != null) {
|
||||
String currentName = child.getName();
|
||||
String actualName = actualNames.get(currentName);
|
||||
if (actualName != null && !currentName.equals(actualName)) {
|
||||
myHelper.scheduleAttributeChange(child, VirtualFile.PROP_NAME, currentName, actualName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Function<? super VirtualFile, Boolean> ourCancellingCondition;
|
||||
|
||||
@TestOnly
|
||||
|
||||
+17
-21
@@ -7,6 +7,7 @@ import com.intellij.openapi.util.io.FileAttributes;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.impl.local.LocalFileSystemBase;
|
||||
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.events.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -15,8 +16,8 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class VfsEventGenerationHelper {
|
||||
protected static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.newvfs.persistent.RefreshWorker");
|
||||
private static final Logger LOG_ATTRIBUTES = Logger.getInstance("#com.intellij.openapi.vfs.newvfs.persistent.RefreshWorker_Attributes");
|
||||
static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.newvfs.persistent.RefreshWorker");
|
||||
|
||||
private final List<VFileEvent> myEvents = new ArrayList<>();
|
||||
|
||||
@NotNull
|
||||
@@ -24,26 +25,20 @@ class VfsEventGenerationHelper {
|
||||
return myEvents;
|
||||
}
|
||||
|
||||
void scheduleAttributeChange(@NotNull VirtualFile file, @VirtualFile.PropName @NotNull String property, Object current, Object upToDate) {
|
||||
if (LOG.isTraceEnabled()) LOG.trace("update '" + property + "' file=" + file);
|
||||
myEvents.add(new VFilePropertyChangeEvent(null, file, property, current, upToDate, true));
|
||||
boolean checkDirty(@NotNull NewVirtualFile file) {
|
||||
boolean fileDirty = file.isDirty();
|
||||
if (LOG.isTraceEnabled()) LOG.trace("file=" + file + " dirty=" + fileDirty);
|
||||
return fileDirty;
|
||||
}
|
||||
|
||||
void checkContentChanged(@NotNull VirtualFile file, long oldTimestamp, long newTimestamp, long oldLength, long newLength) {
|
||||
if (oldTimestamp != newTimestamp || oldLength != newLength) {
|
||||
scheduleUpdateContent(file, oldTimestamp, newTimestamp, oldLength, newLength);
|
||||
}
|
||||
}
|
||||
|
||||
void scheduleUpdateContent(@NotNull VirtualFile file, long oldTimestamp, long newTimestamp, long oldLength, long newLength) {
|
||||
if (LOG.isTraceEnabled()) {
|
||||
LOG.trace(
|
||||
if (LOG.isTraceEnabled()) LOG.trace(
|
||||
"update file=" + file +
|
||||
(oldTimestamp != newTimestamp ? ", oldtimestamp=" + oldTimestamp + ", newtimestamp=" + newTimestamp : "") +
|
||||
(oldLength != newLength ? ", oldlength=" + oldLength + ", length=" + newLength : "")
|
||||
);
|
||||
(oldTimestamp != newTimestamp ? " TS=" + oldTimestamp + "->" + newTimestamp : "") +
|
||||
(oldLength != newLength ? " len=" + oldLength + "->" + newLength : ""));
|
||||
myEvents.add(new VFileContentChangeEvent(null, file, file.getModificationStamp(), -1, oldTimestamp, newTimestamp, oldLength, newLength, true));
|
||||
}
|
||||
myEvents.add(new VFileContentChangeEvent(null, file, file.getModificationStamp(), -1, oldTimestamp, newTimestamp, oldLength, newLength, true));
|
||||
}
|
||||
|
||||
void scheduleCreation(@NotNull VirtualFile parent,
|
||||
@@ -51,9 +46,8 @@ class VfsEventGenerationHelper {
|
||||
@NotNull Path path,
|
||||
@NotNull FileAttributes attributes,
|
||||
String symlinkTarget) {
|
||||
boolean isEmptyDir = attributes.isDirectory() && !LocalFileSystemBase.hasChildren(path);
|
||||
|
||||
if (LOG.isTraceEnabled()) LOG.trace("create parent=" + parent + " name=" + childName + " attr=" + attributes);
|
||||
boolean isEmptyDir = attributes.isDirectory() && !LocalFileSystemBase.hasChildren(path);
|
||||
myEvents.add(new VFileCreateEvent(null, parent, childName, attributes.isDirectory(), attributes, symlinkTarget, true, isEmptyDir));
|
||||
}
|
||||
|
||||
@@ -76,14 +70,16 @@ class VfsEventGenerationHelper {
|
||||
}
|
||||
|
||||
void checkWritableAttributeChange(@NotNull VirtualFile file, boolean oldWritable, boolean newWritable) {
|
||||
if (LOG_ATTRIBUTES.isTraceEnabled()) {
|
||||
LOG_ATTRIBUTES.trace("file=" + file + " writable vfs=" + file.isWritable() + " persistence=" + oldWritable + " real=" + newWritable);
|
||||
}
|
||||
if (oldWritable != newWritable) {
|
||||
scheduleAttributeChange(file, VirtualFile.PROP_WRITABLE, oldWritable, newWritable);
|
||||
}
|
||||
}
|
||||
|
||||
void scheduleAttributeChange(@NotNull VirtualFile file, @VirtualFile.PropName @NotNull String property, Object current, Object upToDate) {
|
||||
if (LOG.isTraceEnabled()) LOG.trace("update file=" + file + ' ' + property + '=' + current + "->" + upToDate);
|
||||
myEvents.add(new VFilePropertyChangeEvent(null, file, property, current, upToDate, true));
|
||||
}
|
||||
|
||||
void addAllEventsFrom(@NotNull VfsEventGenerationHelper otherHelper) {
|
||||
myEvents.addAll(otherHelper.myEvents);
|
||||
}
|
||||
|
||||
@@ -88,10 +88,6 @@ open class GuiTestCase {
|
||||
@JvmField
|
||||
val testMethod = TestName()
|
||||
|
||||
@Rule
|
||||
@JvmField
|
||||
val logActionsDuringTest = LogActionsDuringTest()
|
||||
|
||||
val projectFolder: String by lazy {
|
||||
val dir = File(projectsFolder, testMethod.methodName)
|
||||
if (!dir.mkdirs()) {
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.testGuiFramework.impl
|
||||
|
||||
import com.intellij.application.subscribe
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.actionSystem.ActionManager
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.actionSystem.ex.AnActionListener
|
||||
import com.intellij.openapi.diagnostic.logger
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import org.junit.rules.TestWatcher
|
||||
import org.junit.runner.Description
|
||||
|
||||
private val LOG = logger<LogActionsDuringTest>()
|
||||
|
||||
/**
|
||||
* Rule that logs all actions during the test.
|
||||
*/
|
||||
class LogActionsDuringTest : TestWatcher() {
|
||||
private var disposable: Disposable? = null
|
||||
|
||||
private val actionListener = object : AnActionListener {
|
||||
override fun beforeActionPerformed(action: AnAction, dataContext: DataContext, event: AnActionEvent) {
|
||||
LOG.info("Action: $action (actionId: ${ActionManager.getInstance().getId(action)}); DataContext: $dataContext; Event: $event")
|
||||
}
|
||||
}
|
||||
|
||||
override fun starting(description: Description) {
|
||||
disposable = Disposer.newDisposable()
|
||||
AnActionListener.TOPIC.subscribe(disposable!!, actionListener)
|
||||
}
|
||||
|
||||
override fun finished(description: Description) {
|
||||
disposable?.let {
|
||||
this.disposable = null
|
||||
Disposer.dispose(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-4
@@ -1,6 +1,4 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o.
|
||||
// Use of this source code is governed by the Apache 2.0 license that can be
|
||||
// found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection;
|
||||
|
||||
import com.intellij.codeInspection.booleanIsAlwaysInverted.BooleanMethodIsAlwaysInvertedInspection;
|
||||
@@ -9,7 +7,6 @@ import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.siyeh.ig.IGInspectionTestCase;
|
||||
|
||||
public class BooleanMethodIsAlwaysInvertedInspectionTest extends IGInspectionTestCase {
|
||||
|
||||
public void testUnusedMethod() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
+141
-82
@@ -1,26 +1,24 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.plugins.github.pullrequest.data.service
|
||||
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
import com.intellij.openapi.ui.popup.JBPopupListener
|
||||
import com.intellij.openapi.ui.popup.LightweightWindowEvent
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.ui.CollectionListModel
|
||||
import com.intellij.ui.ColorUtil
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
import com.intellij.ui.*
|
||||
import com.intellij.ui.components.JBList
|
||||
import com.intellij.util.ui.ColorIcon
|
||||
import com.intellij.util.ui.JBUI
|
||||
import com.intellij.util.ui.StatusText
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import com.intellij.ui.speedSearch.NameFilteringListModel
|
||||
import com.intellij.ui.speedSearch.SpeedSearch
|
||||
import com.intellij.util.ui.*
|
||||
import com.intellij.util.ui.JBUI.Panels.simplePanel
|
||||
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||
import org.jetbrains.plugins.github.api.GithubApiRequestExecutor
|
||||
import org.jetbrains.plugins.github.api.GithubApiRequests
|
||||
@@ -36,10 +34,16 @@ import org.jetbrains.plugins.github.pullrequest.data.GithubPullRequestsBusyState
|
||||
import org.jetbrains.plugins.github.pullrequest.data.GithubPullRequestsDataLoader
|
||||
import org.jetbrains.plugins.github.util.*
|
||||
import java.awt.Component
|
||||
import java.awt.Cursor
|
||||
import java.awt.event.ActionListener
|
||||
import java.awt.event.KeyEvent
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Function
|
||||
import javax.swing.*
|
||||
import javax.swing.event.DocumentEvent
|
||||
|
||||
class GithubPullRequestsMetadataServiceImpl internal constructor(private val project: Project,
|
||||
private val progressManager: ProgressManager,
|
||||
@@ -101,8 +105,7 @@ class GithubPullRequestsMetadataServiceImpl internal constructor(private val pro
|
||||
|
||||
override fun adjustLabels(pullRequest: Long, parentComponent: JComponent) {
|
||||
showChooser(pullRequest, "Labels", parentComponent,
|
||||
{ SelectionListCellRenderer.Labels() }, { it.name },
|
||||
{ _, _ -> repoIssuesLabels }, { it.labels.orEmpty() })
|
||||
{ SelectionListCellRenderer.Labels() }, { _, _ -> repoIssuesLabels }, { it.labels.orEmpty() })
|
||||
.handleOnEdt(getAdjustmentHandler(pullRequest, "label") { delta, indicator ->
|
||||
requestExecutor.execute(indicator,
|
||||
GithubApiRequests.Repos.Issues.Labels
|
||||
@@ -120,89 +123,152 @@ class GithubPullRequestsMetadataServiceImpl internal constructor(private val pro
|
||||
return showChooser(pullRequest, popupTitle, parentComponent, { list ->
|
||||
val avatarIconsProvider = avatarIconsProviderFactory.create(JBUI.uiIntValue("GitHub.Avatars.Size", 20), list)
|
||||
SelectionListCellRenderer.Users(avatarIconsProvider)
|
||||
}, { it.login }, availableListProvider, currentListExtractor)
|
||||
}, availableListProvider, currentListExtractor)
|
||||
}
|
||||
|
||||
private fun <T> showChooser(pullRequest: Long,
|
||||
popupTitle: String,
|
||||
parentComponent: JComponent,
|
||||
cellRendererFactory: (JList<SelectableWrapper<T>>) -> ListCellRenderer<SelectableWrapper<T>>,
|
||||
speedSearchNamer: (T) -> String,
|
||||
cellRendererFactory: (JList<SelectableWrapper<T>>) -> SelectionListCellRenderer<T>,
|
||||
availableListProvider: (ProgressIndicator, GithubPullRequestDetailed) -> List<T>,
|
||||
currentListExtractor: (GithubPullRequestDetailed) -> List<T>)
|
||||
: CompletableFuture<CollectionDelta<T>> {
|
||||
|
||||
val listModel = CollectionListModel<SelectableWrapper<T>>()
|
||||
val list = JBList<SelectableWrapper<T>>(listModel)
|
||||
val list = JBList<SelectableWrapper<T>>(listModel).apply {
|
||||
visibleRowCount = 7
|
||||
isFocusable = false
|
||||
selectionMode = ListSelectionModel.SINGLE_SELECTION
|
||||
}
|
||||
val listCellRenderer = cellRendererFactory(list)
|
||||
list.cellRenderer = listCellRenderer
|
||||
|
||||
val builder = PopupChooserBuilder<SelectableWrapper<T>>(list)
|
||||
.setTitle(popupTitle)
|
||||
.setResizable(true)
|
||||
.setMovable(true)
|
||||
.setNamerForFiltering { speedSearchNamer(it.value) }
|
||||
.setAutoSelectIfEmpty(false)
|
||||
.setCloseOnEnter(false)
|
||||
.setRenderer(cellRendererFactory(list))
|
||||
.setItemsChosenCallback {
|
||||
for (item in it) {
|
||||
item.selected = !item.selected
|
||||
val speedSearch = SpeedSearch()
|
||||
val filteringListModel = NameFilteringListModel<SelectableWrapper<T>>(list,
|
||||
{ listCellRenderer.getText(it.value) },
|
||||
speedSearch::shouldBeShowing,
|
||||
speedSearch)
|
||||
|
||||
speedSearch.addChangeListener {
|
||||
val prevSelection = list.selectedValue // save to restore the selection on filter drop
|
||||
filteringListModel.refilter()
|
||||
if (filteringListModel.size > 0) {
|
||||
val fullMatchIndex = if (speedSearch.isHoldingFilter) filteringListModel.closestMatchIndex
|
||||
else filteringListModel.getElementIndex(prevSelection)
|
||||
if (fullMatchIndex != -1) {
|
||||
list.selectedIndex = fullMatchIndex
|
||||
}
|
||||
|
||||
if (filteringListModel.size <= list.selectedIndex || !filteringListModel.contains(list.selectedValue)) {
|
||||
list.selectedIndex = 0
|
||||
}
|
||||
list.repaint()
|
||||
}
|
||||
val popup = builder.createPopup()
|
||||
}
|
||||
|
||||
val updater = builder.backgroundUpdater
|
||||
updater.paintBusy(true)
|
||||
list.emptyText.text = "Loading..."
|
||||
val scrollPane = ScrollPaneFactory.createScrollPane(list, true).apply {
|
||||
viewport.cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)
|
||||
isFocusable = false
|
||||
}
|
||||
|
||||
var originalSelection: Set<T> = setOf()
|
||||
|
||||
val progressIndicator = EmptyProgressIndicator()
|
||||
Disposer.register(popup, Disposable { progressIndicator.cancel() })
|
||||
|
||||
val loadingFuture = GithubAsyncUtil
|
||||
.futureOfMutable { dataLoader.getDataProvider(pullRequest).detailsRequest }
|
||||
.thenComposeAsync(Function { details: GithubPullRequestDetailedWithHtml ->
|
||||
originalSelection = currentListExtractor(details).toHashSet()
|
||||
progressManager.submitBackgroundTask(project, "Load List Of Possibilities", true, progressIndicator) {
|
||||
availableListProvider(it, details)
|
||||
val searchField = SearchTextField(false).apply {
|
||||
border = IdeBorderFactory.createBorder(SideBorder.BOTTOM)
|
||||
UIUtil.setBackgroundRecursively(this, UIUtil.getListBackground())
|
||||
textEditor.border = JBUI.Borders.empty()
|
||||
//focus dark magic, otherwise focus shifts to searchfield panel
|
||||
isFocusable = false
|
||||
addDocumentListener(object : DocumentAdapter() {
|
||||
override fun textChanged(e: DocumentEvent) {
|
||||
speedSearch.updatePattern(text)
|
||||
}
|
||||
})
|
||||
.thenAcceptAsync(Consumer { possibilities ->
|
||||
listModel.replaceAll(possibilities
|
||||
.map { SelectableWrapper(it, originalSelection.contains(it)) }
|
||||
.sortedBy { !it.selected })
|
||||
}
|
||||
|
||||
updater.paintBusy(false)
|
||||
list.emptyText.text = StatusText.DEFAULT_EMPTY_TEXT
|
||||
val panel = simplePanel(scrollPane).addToTop(searchField)
|
||||
ScrollingUtil.installActions(list, panel)
|
||||
ListUtil.installAutoSelectOnMouseMove(list)
|
||||
|
||||
popup.pack(true, true)
|
||||
}, EDT_EXECUTOR)
|
||||
.exceptionally {
|
||||
updater.paintBusy(false)
|
||||
list.emptyText.clear()
|
||||
list.emptyText.appendText("Can't load the list", SimpleTextAttributes.ERROR_ATTRIBUTES)
|
||||
list.emptyText.appendSecondaryText(it.message.orEmpty(), SimpleTextAttributes.ERROR_ATTRIBUTES, null)
|
||||
throw it
|
||||
fun toggleSelection() {
|
||||
for (item in list.selectedValuesList) {
|
||||
item.selected = !item.selected
|
||||
}
|
||||
list.repaint()
|
||||
}
|
||||
|
||||
Disposer.register(popup, Disposable {
|
||||
loadingFuture.cancel(true)
|
||||
list.addMouseListener(object : MouseAdapter() {
|
||||
override fun mouseReleased(e: MouseEvent) {
|
||||
if (UIUtil.isActionClick(e, MouseEvent.MOUSE_RELEASED) && !UIUtil.isSelectionButtonDown(e) && !e.isConsumed) toggleSelection()
|
||||
}
|
||||
})
|
||||
|
||||
val result = CompletableFuture<CollectionDelta<T>>()
|
||||
popup.addListener(object : JBPopupListener {
|
||||
override fun onClosed(event: LightweightWindowEvent) {
|
||||
if (!loadingFuture.isDone || loadingFuture.isCancelled || loadingFuture.isCompletedExceptionally) {
|
||||
result.cancel(true)
|
||||
return
|
||||
JBPopupFactory.getInstance().createComponentPopupBuilder(panel, searchField)
|
||||
.setRequestFocus(true)
|
||||
.setCancelOnClickOutside(true)
|
||||
.setTitle(popupTitle)
|
||||
.setResizable(true)
|
||||
.setMovable(true)
|
||||
.setKeyboardActions(listOf(Pair.create(ActionListener { toggleSelection() }, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0))))
|
||||
.addListener(object : JBPopupListener {
|
||||
private lateinit var loadingFuture: CompletableFuture<Void>
|
||||
private lateinit var originalSelection: Set<T>
|
||||
|
||||
override fun beforeShown(event: LightweightWindowEvent) {
|
||||
val popup = event.asPopup()
|
||||
|
||||
list.setPaintBusy(true)
|
||||
list.emptyText.text = "Loading..."
|
||||
|
||||
|
||||
val progressIndicator = EmptyProgressIndicator()
|
||||
|
||||
loadingFuture = GithubAsyncUtil
|
||||
.futureOfMutable { dataLoader.getDataProvider(pullRequest).detailsRequest }
|
||||
.thenComposeAsync(Function { details: GithubPullRequestDetailedWithHtml ->
|
||||
originalSelection = currentListExtractor(details).toHashSet()
|
||||
progressManager.submitBackgroundTask(project, "Load List Of Possibilities", true, progressIndicator) {
|
||||
availableListProvider(it, details)
|
||||
}
|
||||
})
|
||||
.thenAcceptAsync(Consumer { possibilities ->
|
||||
listModel.replaceAll(possibilities
|
||||
.map { SelectableWrapper(it, originalSelection.contains(it)) }
|
||||
.sortedBy { !it.selected })
|
||||
|
||||
list.setPaintBusy(false)
|
||||
list.emptyText.text = UIBundle.message("message.noMatchesFound")
|
||||
|
||||
popup.pack(true, true)
|
||||
|
||||
if (list.selectedIndex == -1) {
|
||||
list.selectedIndex = 0
|
||||
}
|
||||
}, EDT_EXECUTOR)
|
||||
.exceptionally {
|
||||
list.setPaintBusy(false)
|
||||
list.emptyText.clear()
|
||||
list.emptyText.appendText("Can't load the list", SimpleTextAttributes.ERROR_ATTRIBUTES)
|
||||
list.emptyText.appendSecondaryText(it.message.orEmpty(), SimpleTextAttributes.ERROR_ATTRIBUTES, null)
|
||||
throw it
|
||||
}
|
||||
|
||||
Disposer.register(popup, Disposable {
|
||||
progressIndicator.cancel()
|
||||
loadingFuture.cancel(true)
|
||||
})
|
||||
}
|
||||
|
||||
val selected = listModel.items.filter { it.selected }.map { it.value }
|
||||
result.complete(CollectionDelta(originalSelection, selected))
|
||||
}
|
||||
})
|
||||
popup.showUnderneathOf(parentComponent)
|
||||
override fun onClosed(event: LightweightWindowEvent) {
|
||||
if (!loadingFuture.isDone || loadingFuture.isCancelled || loadingFuture.isCompletedExceptionally) {
|
||||
result.cancel(true)
|
||||
return
|
||||
}
|
||||
|
||||
val selected = listModel.items.filter { it.selected }.map { it.value }
|
||||
result.complete(CollectionDelta(originalSelection, selected))
|
||||
}
|
||||
})
|
||||
.createPopup()
|
||||
.showUnderneathOf(parentComponent)
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -240,19 +306,19 @@ class GithubPullRequestsMetadataServiceImpl internal constructor(private val pro
|
||||
|
||||
private data class SelectableWrapper<T>(val value: T, var selected: Boolean = false)
|
||||
|
||||
private sealed class SelectionListCellRenderer<T>
|
||||
: ListCellRenderer<SelectableWrapper<T>>, BorderLayoutPanel() {
|
||||
private sealed class SelectionListCellRenderer<T> : ListCellRenderer<SelectableWrapper<T>>, BorderLayoutPanel() {
|
||||
|
||||
private val mainLabel = JLabel()
|
||||
private val checkIconLabel = JLabel()
|
||||
|
||||
init {
|
||||
checkIconLabel.iconTextGap = JBUI.scale(UIUtil.DEFAULT_VGAP)
|
||||
checkIconLabel.border = JBUI.Borders.empty(0, 4)
|
||||
|
||||
addToLeft(checkIconLabel)
|
||||
addToCenter(mainLabel)
|
||||
|
||||
border = JBUI.Borders.empty(2)
|
||||
border = JBUI.Borders.empty(4, 0)
|
||||
}
|
||||
|
||||
override fun getListCellRendererComponent(list: JList<out SelectableWrapper<T>>,
|
||||
@@ -260,9 +326,8 @@ class GithubPullRequestsMetadataServiceImpl internal constructor(private val pro
|
||||
index: Int,
|
||||
isSelected: Boolean,
|
||||
cellHasFocus: Boolean): Component {
|
||||
font = list.font
|
||||
foreground = UIUtil.getListForeground(isSelected, list.hasFocus())
|
||||
background = UIUtil.getListBackground(isSelected, list.hasFocus())
|
||||
foreground = UIUtil.getListForeground(isSelected, true)
|
||||
background = UIUtil.getListBackground(isSelected, true)
|
||||
|
||||
mainLabel.foreground = foreground
|
||||
mainLabel.font = font
|
||||
@@ -270,14 +335,8 @@ class GithubPullRequestsMetadataServiceImpl internal constructor(private val pro
|
||||
mainLabel.text = getText(value.value)
|
||||
mainLabel.icon = getIcon(value.value)
|
||||
|
||||
if (value.selected) {
|
||||
checkIconLabel.icon = AllIcons.Actions.Checked
|
||||
checkIconLabel.border = JBUI.Borders.empty(0, 4)
|
||||
}
|
||||
else {
|
||||
checkIconLabel.icon = null
|
||||
checkIconLabel.border = JBUI.Borders.empty(0, 10)
|
||||
}
|
||||
val icon = LafIconLookup.getIcon("checkmark", isSelected, false)
|
||||
checkIconLabel.icon = if (value.selected) icon else EmptyIcon.create(icon)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@ public abstract class AbstractModelBuilderTest {
|
||||
{"2.6"}, /*{"2.7"}, {"2.8"}, {"2.9"}, {"2.10"}, {"2.11"}, {"2.12"}, {"2.13"}, */{"2.14.1"},
|
||||
{"3.0"}, /*{"3.1"}, {"3.2"}, {"3.3"}, {"3.4"},*/ {"3.5"},
|
||||
{"4.0"}, /*{"4.1"}, {"4.2"}, {"4.3"}, {"4.4"}, {"4.5.1"}, {"4.6"}, {"4.7"}, {"4.8"}, {"4.9"},*/ {"4.10.3"},
|
||||
{"5.0"}
|
||||
{"5.0"}, {"5.2"}
|
||||
};
|
||||
public static final String BASE_GRADLE_VERSION = String.valueOf(SUPPORTED_GRADLE_VERSIONS[SUPPORTED_GRADLE_VERSIONS.length - 1][0]);
|
||||
|
||||
|
||||
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.
|
||||
*/
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.uast
|
||||
|
||||
import com.intellij.lang.Language
|
||||
@@ -21,13 +7,12 @@ import com.intellij.psi.*
|
||||
|
||||
interface UastLanguagePlugin {
|
||||
companion object {
|
||||
val extensionPointName: ExtensionPointName<UastLanguagePlugin> =
|
||||
ExtensionPointName.create<UastLanguagePlugin>("org.jetbrains.uast.uastLanguagePlugin")
|
||||
private val extensionArray: Array<UastLanguagePlugin> by lazy(LazyThreadSafetyMode.PUBLICATION) { extensionPointName.extensions }
|
||||
val extensionPointName = ExtensionPointName<UastLanguagePlugin>("org.jetbrains.uast.uastLanguagePlugin")
|
||||
private val extensions by lazy(LazyThreadSafetyMode.PUBLICATION) { extensionPointName.extensionList }
|
||||
|
||||
fun getInstances(): Collection<UastLanguagePlugin> = extensionArray.toList()
|
||||
fun getInstances(): Collection<UastLanguagePlugin> = extensions
|
||||
|
||||
fun byLanguage(language: Language): UastLanguagePlugin? = extensionArray.firstOrNull { it.language === language }
|
||||
fun byLanguage(language: Language): UastLanguagePlugin? = extensions.firstOrNull { it.language === language }
|
||||
}
|
||||
|
||||
data class ResolvedMethod(val call: UCallExpression, val method: PsiMethod)
|
||||
|
||||
Reference in New Issue
Block a user