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:
@@ -17,6 +17,8 @@ package com.intellij.compiler.actions;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.TransactionKind;
|
||||
import com.intellij.openapi.application.WrapInTransaction;
|
||||
import com.intellij.openapi.compiler.CompilerManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -24,6 +26,7 @@ import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.psi.PsiFile;
|
||||
|
||||
@WrapInTransaction(TransactionKind.Common.ANY_CHANGE)
|
||||
public abstract class CompileActionBase extends AnAction implements DumbAware {
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final DataContext dataContext = e.getDataContext();
|
||||
|
||||
@@ -36,10 +36,7 @@ import com.intellij.ide.PowerSaveMode;
|
||||
import com.intellij.ide.file.BatchFileChangeListener;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.compiler.CompilationStatusListener;
|
||||
import com.intellij.openapi.compiler.CompileContext;
|
||||
import com.intellij.openapi.compiler.CompilerPaths;
|
||||
@@ -77,7 +74,6 @@ import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.FileNameCache;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import com.intellij.util.concurrency.SequentialTaskExecutor;
|
||||
import com.intellij.util.containers.IntArrayList;
|
||||
import com.intellij.util.io.storage.HeavyProcessLatch;
|
||||
@@ -105,7 +101,6 @@ import org.jetbrains.jps.cmdline.ClasspathBootstrap;
|
||||
import org.jetbrains.jps.incremental.Utils;
|
||||
import org.jetbrains.jps.model.serialization.JpsGlobalLoader;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.tools.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
@@ -186,25 +181,11 @@ public class BuildManager implements Disposable {
|
||||
return Registry.intValue("compiler.document.save.trigger.delay");
|
||||
}
|
||||
|
||||
private final Semaphore mySemaphore = new Semaphore();
|
||||
private final Runnable mySaveDocsRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
((FileDocumentManagerImpl)FileDocumentManager.getInstance()).saveAllDocuments(false);
|
||||
}
|
||||
finally {
|
||||
mySemaphore.up();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void runTask() {
|
||||
if (shouldSaveDocuments()) {
|
||||
mySemaphore.down();
|
||||
ApplicationManager.getApplication().invokeLater(mySaveDocsRunnable, ModalityState.NON_MODAL);
|
||||
mySemaphore.waitFor();
|
||||
TransactionGuard.getInstance().submitTransactionAndWait(TransactionKind.ANY_CHANGE, () ->
|
||||
((FileDocumentManagerImpl)FileDocumentManager.getInstance()).saveAllDocuments(false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,12 +753,7 @@ public class BuildManager implements Disposable {
|
||||
// ensure project model is saved on disk, so that automake sees the latest model state.
|
||||
// For ordinary make all project, app settings and unsaved docs are always saved before build starts.
|
||||
try {
|
||||
SwingUtilities.invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
project.save();
|
||||
}
|
||||
});
|
||||
TransactionGuard.getInstance().submitTransactionAndWait(TransactionKind.ANY_CHANGE, project::save);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
LOG.info(e);
|
||||
|
||||
+3
-3
@@ -24,7 +24,7 @@ class JavaPredefinedConfigurations {
|
||||
// Expression patterns
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.method.calls"), "'_Instance?.'MethodCall('_Parameter*)", EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.new.expressions"), "new 'Constructor('_Argument*)", EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.lambdas"), "('_Parameter*) -> ", EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.lambdas"), "('_Parameter*) -> {}", EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.field.selections"),"'_Instance?.'Field",EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.array.access"),"'_Field['_Index]",EXPRESSION_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.assignments"),"'_Inst = '_Expr",EXPRESSION_TYPE),
|
||||
@@ -279,8 +279,8 @@ class JavaPredefinedConfigurations {
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.fields.variables.read"),"'Symbol:[read]",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.fields_variables.with.given.name.pattern.updated"),"'Symbol:[regex( name ) && write]",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.usage.of.derived.type.in.cast"),"('CastType:*[regex( Base )]) '_Expr",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.declarations"),"'_Type:Object|Integer|Boolean|Long|Character|Short|Byte 'Var = '_Value:[exprtype( int|boolean|long|char|short|byte )]",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.declarations"),"'_Type:int|boolean|long|char|short|byte 'Var = '_Value:[exprtype( Integer|Boolean|Long|Character|Short|Byte )]",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.declarations"),"'_Type:Object|Integer|Boolean|Long|Character|Short|Byte 'Var = '_Value:[exprtype( int|boolean|long|char|short|byte )];",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.declarations"),"'_Type:int|boolean|long|char|short|byte 'Var = '_Value:[exprtype( Integer|Boolean|Long|Character|Short|Byte )];",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.boxing.in.method.calls"),"'_Instance?.'Call('_BeforeParam*,'_Param:[ exprtype( int|boolean|long|char|short|byte ) && formal( Object|Integer|Boolean|Long|Character|Short|Byte )],'_AfterParam*)",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.unboxing.in.method.calls"), "'_Instance?.'Call('_BeforeParam*,'_Param:[ formal( int|boolean|long|char|short|byte ) && exprtype( Integer|Boolean|Long|Character|Short|Byte )],'_AfterParam*)",INTERESTING_TYPE),
|
||||
createSearchTemplateInfo(SSRBundle.message("predefined.configuration.any.boxing"), "'_expression:[ exprtype( int|boolean|long|char|short|byte ) && formal( Object|Integer|Boolean|Long|Character|Short|Byte )]", INTERESTING_TYPE),
|
||||
|
||||
+29
-6
@@ -407,13 +407,35 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
@Override
|
||||
public void visitErrorElement(PsiErrorElement element) {
|
||||
super.visitErrorElement(element);
|
||||
//final PsiElement parent = element.getParent();
|
||||
//if (parent != myCurrent || !"';' expected".equals(element.getErrorDescription())) {
|
||||
// throw new MalformedPatternException(element.getErrorDescription());
|
||||
//}
|
||||
final PsiElement parent = element.getParent();
|
||||
final String errorDescription = element.getErrorDescription();
|
||||
if (parent instanceof PsiClass && "Identifier expected".equals(errorDescription)) {
|
||||
// other class content variable.
|
||||
return;
|
||||
}
|
||||
if (parent instanceof PsiTryStatement && "'catch' or 'finally' expected".equals(errorDescription)) {
|
||||
// searching for naked try allowed
|
||||
return;
|
||||
}
|
||||
if (parent == myCurrent) {
|
||||
// search for expression, type, annotation or symbol
|
||||
if ("';' expected".equals(errorDescription)) {
|
||||
// expression
|
||||
return;
|
||||
}
|
||||
if ("Identifier or type expected".equals(errorDescription)) {
|
||||
// annotation
|
||||
return;
|
||||
}
|
||||
if ("Identifier expected".equals(errorDescription)) {
|
||||
// type
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new MalformedPatternException(errorDescription);
|
||||
}
|
||||
|
||||
public void setCurrent(PsiElement current) {
|
||||
void setCurrent(PsiElement current) {
|
||||
myCurrent = current;
|
||||
}
|
||||
}
|
||||
@@ -423,7 +445,8 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile {
|
||||
final NodeIterator nodes = compiledPattern.getNodes();
|
||||
while (nodes.hasNext()) {
|
||||
final PsiElement current = nodes.current();
|
||||
visitor.setCurrent(nodeCount == 1 && current instanceof PsiExpressionStatement ? current : null);
|
||||
visitor.setCurrent((nodeCount == 1 && (current instanceof PsiExpressionStatement|| current instanceof PsiDeclarationStatement))
|
||||
? current : null);
|
||||
current.accept(visitor);
|
||||
nodes.advance();
|
||||
}
|
||||
|
||||
@@ -374,6 +374,7 @@ public class JsonSchemaMappingsConfigurable extends MasterDetailsComponent imple
|
||||
myText = FileUtil.loadFile(ioFile);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
JsonSchemaReader.LOG.info(e1);
|
||||
myError = "Problem during reading JSON schema from '" + myFile.getName() + "': " + e1.getMessage();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import com.intellij.notification.NotificationGroup;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ThrowablePairConsumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -18,10 +19,12 @@ import java.util.*;
|
||||
* @author Irina.Chernushina on 8/27/2015.
|
||||
*/
|
||||
public class JsonSchemaReader {
|
||||
public static final Logger LOG = Logger.getInstance("#com.jetbrains.jsonSchema.impl.JsonSchemaReader");
|
||||
public static final NotificationGroup ERRORS_NOTIFICATION = NotificationGroup.logOnlyGroup("JSON Schema");
|
||||
|
||||
public JsonSchemaObject read(@NotNull final Reader reader) throws IOException {
|
||||
final JsonReader in = new JsonReader(reader);
|
||||
in.setLenient(true);
|
||||
|
||||
in.beginObject();
|
||||
final JsonSchemaObject object = new JsonSchemaObject();
|
||||
@@ -43,9 +46,11 @@ public class JsonSchemaReader {
|
||||
new JsonSchemaReader().read(new java.io.StringReader(string));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
LOG.info(e);
|
||||
errorConsumer.consume(e.getMessage());
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
LOG.info(e);
|
||||
errorConsumer.consume(e.getMessage());
|
||||
return false;
|
||||
}
|
||||
@@ -293,7 +298,12 @@ public class JsonSchemaReader {
|
||||
}
|
||||
|
||||
private JsonSchemaType parseType(JsonReader in) throws IOException {
|
||||
return JsonSchemaType.valueOf("_" + in.nextString());
|
||||
final String typeString = in.nextString();
|
||||
try {
|
||||
return JsonSchemaType.valueOf("_" + typeString);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IOException("Wrong type value: " + typeString + "\"");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -45,7 +45,8 @@ public class TransactionGuardImpl extends TransactionGuard {
|
||||
return AccessToken.EMPTY_ACCESS_TOKEN;
|
||||
}
|
||||
if (myTransactionStartTrace != null) {
|
||||
LOG.error("Nested transactions are not allowed, see FAQ in TransactionGuard class javadoc. Transaction start trace is in attachment.",
|
||||
// please assign exceptions that occur here to Peter
|
||||
LOG.error("Nested transactions are not allowed, see FAQ in TransactionGuard class javadoc. Transaction start trace is in attachment. Kind is " + kind,
|
||||
new Attachment("trace.txt", myTransactionStartTrace));
|
||||
//throw new IllegalStateException("Nested transactions are not allowed");
|
||||
}
|
||||
|
||||
@@ -26,7 +26,10 @@ import com.intellij.util.text.ByteArrayCharSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import java.util.zip.ZipEntry;
|
||||
@@ -53,14 +56,9 @@ public class ZipHandler extends ArchiveHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disposeAccessor(final ZipFile fileAccessor) {
|
||||
protected void disposeAccessor(final ZipFile fileAccessor) throws IOException {
|
||||
// todo: ZipFile isn't disposable for Java6, replace the code below with 'disposeCloseable(fileAccessor);'
|
||||
disposeCloseable(new Closeable() {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
fileAccessor.close();
|
||||
}
|
||||
});
|
||||
fileAccessor.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
|
||||
@@ -45,18 +46,20 @@ public class OffsetMap implements Disposable {
|
||||
* -1 if offset wasn't registered or became invalidated due to document changes
|
||||
*/
|
||||
public int getOffset(OffsetKey key) {
|
||||
final RangeMarker marker = myMap.get(key);
|
||||
if (marker == null) return -1;
|
||||
if (!marker.isValid()) {
|
||||
removeOffset(key);
|
||||
return -1;
|
||||
}
|
||||
synchronized (myMap) {
|
||||
final RangeMarker marker = myMap.get(key);
|
||||
if (marker == null) return -1;
|
||||
if (!marker.isValid()) {
|
||||
removeOffset(key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
final int endOffset = marker.getEndOffset();
|
||||
if (marker.getStartOffset() != endOffset) {
|
||||
saveOffset(key, endOffset, false);
|
||||
final int endOffset = marker.getEndOffset();
|
||||
if (marker.getStartOffset() != endOffset) {
|
||||
saveOffset(key, endOffset, false);
|
||||
}
|
||||
return endOffset;
|
||||
}
|
||||
return endOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,12 +69,14 @@ public class OffsetMap implements Disposable {
|
||||
* @param offset offset in the document
|
||||
*/
|
||||
public void addOffset(OffsetKey key, int offset) {
|
||||
if (offset < 0) {
|
||||
removeOffset(key);
|
||||
return;
|
||||
}
|
||||
synchronized (myMap) {
|
||||
if (offset < 0) {
|
||||
removeOffset(key);
|
||||
return;
|
||||
}
|
||||
|
||||
saveOffset(key, offset, true);
|
||||
saveOffset(key, offset, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveOffset(OffsetKey key, int offset, boolean externally) {
|
||||
@@ -88,37 +93,49 @@ public class OffsetMap implements Disposable {
|
||||
}
|
||||
|
||||
public void removeOffset(OffsetKey key) {
|
||||
assert !myDisposed;
|
||||
myModified.add(key);
|
||||
RangeMarker old = myMap.get(key);
|
||||
if (old != null) old.dispose();
|
||||
synchronized (myMap) {
|
||||
ProgressManager.checkCanceled();
|
||||
assert !myDisposed;
|
||||
myModified.add(key);
|
||||
RangeMarker old = myMap.get(key);
|
||||
if (old != null) old.dispose();
|
||||
|
||||
myMap.remove(key);
|
||||
myMap.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public List<OffsetKey> getAllOffsets() {
|
||||
assert !myDisposed;
|
||||
return new ArrayList<OffsetKey>(myMap.keySet());
|
||||
synchronized (myMap) {
|
||||
ProgressManager.checkCanceled();
|
||||
assert !myDisposed;
|
||||
return new ArrayList<OffsetKey>(myMap.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder("OffsetMap:");
|
||||
for (final OffsetKey key : myMap.keySet()) {
|
||||
builder.append(key).append("->").append(myMap.get(key)).append(";");
|
||||
synchronized (myMap) {
|
||||
final StringBuilder builder = new StringBuilder("OffsetMap:");
|
||||
for (final OffsetKey key : myMap.keySet()) {
|
||||
builder.append(key).append("->").append(myMap.get(key)).append(";");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public boolean wasModified(OffsetKey key) {
|
||||
return myModified.contains(key);
|
||||
synchronized (myMap) {
|
||||
return myModified.contains(key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
myDisposed = true;
|
||||
for (RangeMarker rangeMarker : myMap.values()) {
|
||||
rangeMarker.dispose();
|
||||
synchronized (myMap) {
|
||||
myDisposed = true;
|
||||
for (RangeMarker rangeMarker : myMap.values()) {
|
||||
rangeMarker.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-9
@@ -30,7 +30,10 @@ import com.intellij.injected.editor.DocumentWindow;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.application.TransactionKind;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.*;
|
||||
@@ -176,7 +179,9 @@ public class CodeCompletionHandlerBase {
|
||||
}
|
||||
};
|
||||
if (autopopup) {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction(initCmd);
|
||||
try (AccessToken ignored = TransactionGuard.getInstance().startSynchronousTransaction(TransactionKind.TEXT_EDITING)) {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction(initCmd);
|
||||
}
|
||||
CompletionAssertions.checkEditorValid(editor);
|
||||
if (!restarted && shouldSkipAutoPopup(editor, initializationContext[0].getFile())) {
|
||||
CompletionServiceImpl.setCompletionPhase(CompletionPhase.NoCompletion);
|
||||
@@ -626,20 +631,18 @@ public class CodeCompletionHandlerBase {
|
||||
|
||||
private static void afterItemInsertion(final CompletionProgressIndicator indicator, final Runnable laterRunnable) {
|
||||
if (laterRunnable != null) {
|
||||
final Runnable runnable1 = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!indicator.getProject().isDisposed()) {
|
||||
laterRunnable.run();
|
||||
}
|
||||
indicator.disposeIndicator();
|
||||
final Runnable runnable1 = () -> {
|
||||
if (!indicator.getProject().isDisposed()) {
|
||||
laterRunnable.run();
|
||||
}
|
||||
indicator.disposeIndicator();
|
||||
};
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
runnable1.run();
|
||||
}
|
||||
else {
|
||||
ApplicationManager.getApplication().invokeLater(runnable1);
|
||||
ApplicationManager.getApplication().invokeLater(
|
||||
() -> TransactionGuard.getInstance().submitMergeableTransaction(TransactionKind.TEXT_EDITING, runnable1));
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
+1
-5
@@ -34,8 +34,6 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.application.TransactionKind;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -476,9 +474,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
}
|
||||
|
||||
void disposeIndicator() {
|
||||
// our offset map should be disposed under write action, so that duringCompletion (read action) won't access it after disposing
|
||||
TransactionGuard.getInstance().submitMergeableTransaction(TransactionKind.TEXT_EDITING, () ->
|
||||
ApplicationManager.getApplication().runWriteAction(() -> Disposer.dispose(this)));
|
||||
Disposer.dispose(this);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
|
||||
+5
-3
@@ -18,13 +18,14 @@ package com.intellij.codeInsight.completion.actions;
|
||||
import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
|
||||
import com.intellij.codeInsight.completion.CompletionType;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.TransactionKind;
|
||||
import com.intellij.openapi.application.WrapInTransaction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
@@ -34,7 +35,8 @@ import java.awt.event.InputEvent;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class BaseCodeCompletionAction extends AnAction implements HintManagerImpl.ActionToIgnore, DumbAware {
|
||||
@WrapInTransaction(TransactionKind.Common.TEXT_EDITING)
|
||||
public abstract class BaseCodeCompletionAction extends DumbAwareAction implements HintManagerImpl.ActionToIgnore {
|
||||
|
||||
protected BaseCodeCompletionAction() {
|
||||
setEnabledInModalContext(true);
|
||||
|
||||
+1
-1
@@ -55,6 +55,6 @@ public class InspectionViewNavigationPanel extends JPanel {
|
||||
|
||||
@NotNull
|
||||
public static String getTitleText(boolean addGroupWord, boolean addColon) {
|
||||
return "Select inspection " + (addGroupWord ? "group" : "") + " to see problems" + (addColon ? ":" : ".");
|
||||
return "Select inspection" + (addGroupWord ? " group " : " ") + "to see problems" + (addColon ? ":" : ".");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorSettings;
|
||||
@@ -479,7 +480,7 @@ public class FindDialog extends DialogWrapper {
|
||||
if (component instanceof EditorTextField) {
|
||||
final Document document = ((EditorTextField)component).getDocument();
|
||||
if (document != null) {
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(document);
|
||||
TransactionGuard.submitTransaction(() -> PsiDocumentManager.getInstance(myProject).commitDocument(document));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1526,7 +1526,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
else {
|
||||
// we do invoke later since we can have read lock acquired
|
||||
//noinspection SSBasedInspection
|
||||
ApplicationManager.getApplication().invokeLater(rebuildRunnable, ModalityState.NON_MODAL);
|
||||
ApplicationManager.getApplication().invokeLater(() -> TransactionGuard.submitTransaction(rebuildRunnable), ModalityState.NON_MODAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +74,9 @@ public class SaveAndSyncHandlerImpl extends SaveAndSyncHandler implements Dispos
|
||||
mySettings = generalSettings;
|
||||
myProgressManager = progressManager;
|
||||
|
||||
myIdleListener = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mySettings.isAutoSaveIfInactive() && canSyncOrSave()) {
|
||||
((FileDocumentManagerImpl)fileDocumentManager).saveAllDocuments(false);
|
||||
}
|
||||
myIdleListener = () -> {
|
||||
if (mySettings.isAutoSaveIfInactive() && canSyncOrSave()) {
|
||||
TransactionGuard.submitTransaction(() -> ((FileDocumentManagerImpl)fileDocumentManager).saveAllDocuments(false));
|
||||
}
|
||||
};
|
||||
IdeEventQueue.getInstance().addIdleListener(myIdleListener, mySettings.getInactiveTimeout() * 1000);
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.intellij.ide.actions;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.WrapInTransaction;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@WrapInTransaction
|
||||
public class SaveAllAction extends AnAction implements DumbAware {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.ShutDownTracker;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.SystemInfoRt;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.openapi.util.io.win32.IdeaWin32;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -52,6 +51,7 @@ import com.sun.jna.Native;
|
||||
import org.apache.log4j.ConsoleAppender;
|
||||
import org.apache.log4j.Level;
|
||||
import org.apache.log4j.PatternLayout;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.io.BuiltInServer;
|
||||
|
||||
@@ -421,24 +421,15 @@ public class StartupUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param alternativeHTML Updated version of Privacy Policy text if any.
|
||||
* @param htmlText Updated version of Privacy Policy text if any.
|
||||
* If it's <code>null</code> the standard text from bundled resources would be used.
|
||||
*/
|
||||
public static void showPrivacyPolicyAgreement(@Nullable String alternativeHTML) {
|
||||
public static void showPrivacyPolicyAgreement(@NotNull String htmlText) {
|
||||
DialogWrapper dialog = new DialogWrapper(true) {
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
JPanel centerPanel = new JPanel(new BorderLayout(5, 5));
|
||||
String html = alternativeHTML;
|
||||
if (html == null) {
|
||||
try {
|
||||
html = FileUtil.loadTextAndClose(StartupUtil.class.getResource("/PrivacyPolicy.html").openStream());
|
||||
}
|
||||
catch (IOException e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
JPanel centerPanel = new JPanel(new BorderLayout(JBUI.scale(5), JBUI.scale(5)));
|
||||
JEditorPane viewer = SwingHelper.createHtmlViewer(true, null, JBColor.WHITE, JBColor.BLACK);
|
||||
viewer.setFocusable(true);
|
||||
viewer.addHyperlinkListener(new HyperlinkAdapter() {
|
||||
@@ -447,12 +438,13 @@ public class StartupUtil {
|
||||
URL url = e.getURL();
|
||||
if (url != null) {
|
||||
BrowserUtil.browse(url);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
SwingHelper.scrollToReference(viewer, e.getDescription());
|
||||
}
|
||||
}
|
||||
});
|
||||
viewer.setText(html);
|
||||
viewer.setText(htmlText);
|
||||
viewer.setCaretPosition(0);
|
||||
viewer.setBorder(JBUI.Borders.empty(5));
|
||||
centerPanel.add(new JLabel("Please read and accept these terms and conditions:"), BorderLayout.NORTH);
|
||||
@@ -485,8 +477,7 @@ public class StartupUtil {
|
||||
};
|
||||
dialog.setModal(true);
|
||||
dialog.setTitle(ApplicationNamesInfo.getInstance().getFullProductName() + " Privacy Policy Agreement");
|
||||
dialog.setResizable(false);
|
||||
dialog.setSize(509, 395);
|
||||
dialog.setSize(JBUI.scale(509), JBUI.scale(395));
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ import com.intellij.CommonBundle;
|
||||
import com.intellij.ide.actions.ShowSettingsUtilImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.options.BaseConfigurable;
|
||||
@@ -288,7 +289,7 @@ public class SingleConfigurableEditor extends DialogWrapper {
|
||||
myConfigurable = null;
|
||||
|
||||
if (mySaveAllOnClose) {
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
TransactionGuard.submitTransaction(ApplicationManager.getApplication()::saveAll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ package com.intellij.openapi.options.newEditor;
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.openapi.actionSystem.DataProvider;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurableGroup;
|
||||
@@ -156,7 +157,7 @@ public class SettingsDialog extends DialogWrapper implements DataProvider {
|
||||
@Override
|
||||
public void doOKAction() {
|
||||
if (myEditor.apply()) {
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
TransactionGuard.submitTransaction(ApplicationManager.getApplication()::saveAll);
|
||||
SettingsDialog.super.doOKAction();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,12 @@ public class VagrantBasedCredentialsHolder {
|
||||
private static final String VAGRANT_FOLDER = "VAGRANT_FOLDER";
|
||||
private static final String MACHINE_NAME = "MACHINE_NAME";
|
||||
|
||||
@NotNull
|
||||
private String myVagrantFolder;
|
||||
private String myMachineName;
|
||||
|
||||
public VagrantBasedCredentialsHolder() {
|
||||
myVagrantFolder = "";
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
|
||||
+5
-5
@@ -584,8 +584,8 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
|
||||
|
||||
public void testReplaceParameter() {
|
||||
String s1 = "class A { void b(int c, int d, int e) {} }";
|
||||
String s2 = "int d";
|
||||
String s3 = "int d2";
|
||||
String s2 = "int d;";
|
||||
String s3 = "int d2;";
|
||||
String expectedResult = "class A { void b(int c, int d2, int e) {} }";
|
||||
|
||||
actualResult = replacer.testReplace(s1,s2,s3,options);
|
||||
@@ -2194,12 +2194,12 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase {
|
||||
" final int x = 5;\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
String s2 = "final '_type 'var = '_init?";
|
||||
String s3 = "$type$ $var$ = $init$";
|
||||
String s2 = "final '_type 'var = '_init?;";
|
||||
String s3 = "$type$ $var$ = $init$;";
|
||||
|
||||
String expected = "class Foo {\n" +
|
||||
" void foo(int i, int i2, int i3) {\n" +
|
||||
" int x = 5\n" +
|
||||
" int x = 5;\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
|
||||
+21
-15
@@ -680,9 +680,9 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
" void main(String argv[]);" +
|
||||
" void main(String argv);" +
|
||||
"}";
|
||||
String s12 = "'_t:[regex( *Object\\[\\] ) ] '_t2";
|
||||
String s12_2 = "'_t:[regex( *Object ) ] '_t2 []";
|
||||
String s12_3 = "'_t:[regex( *Object ) ] '_t2";
|
||||
String s12 = "'_t:[regex( *Object\\[\\] ) ] '_t2;";
|
||||
String s12_2 = "'_t:[regex( *Object ) ] '_t2 [];";
|
||||
String s12_3 = "'_t:[regex( *Object ) ] '_t2;";
|
||||
|
||||
assertEquals(
|
||||
"Find array covariant types",
|
||||
@@ -725,10 +725,10 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
" void y(String... ss) {}" +
|
||||
" void y(boolean b) {}" +
|
||||
"}";
|
||||
assertEquals("find ellipsis type 1", 1, findMatchesCount(source2, "String[] '_a"));
|
||||
assertEquals("find ellipsis type 2", 1, findMatchesCount(source2, "int[] '_a"));
|
||||
assertEquals("find ellipsis type 1", 1, findMatchesCount(source2, "String[] '_a;"));
|
||||
assertEquals("find ellipsis type 2", 1, findMatchesCount(source2, "int[] '_a;"));
|
||||
assertEquals("find ellipsis type 3", 1, findMatchesCount(source2, "class '_X { void '_m(int... '_a); }"));
|
||||
assertEquals("find ellipsis type 4", 2, findMatchesCount(source2, "'_T[] '_a"));
|
||||
assertEquals("find ellipsis type 4", 2, findMatchesCount(source2, "'_T[] '_a;"));
|
||||
|
||||
String source3 = "class A {" +
|
||||
" private int[] is;" +
|
||||
@@ -1200,7 +1200,7 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
"class '_a {" +
|
||||
" '_b '_c = '_d;" +
|
||||
" '_e '_f() {" +
|
||||
" '_g '_h = '_i" +
|
||||
" '_g '_h = '_i;" +
|
||||
" return '_j;" +
|
||||
" }" +
|
||||
"}"));
|
||||
@@ -1621,7 +1621,13 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
// typed var with instanceof
|
||||
assertEquals("typed instanceof",findMatchesCount(s65,s66),1);
|
||||
|
||||
assertEquals("don't throw exception on incomplete instanceof expression", findMatchesCount(s65, "'_T instanceof"), 2);
|
||||
try {
|
||||
// warn on incomplete instanceof
|
||||
findMatchesCount(s65, "'_T instanceof");
|
||||
fail();
|
||||
} catch (MalformedPatternException e) {
|
||||
assertEquals("Type expected", e.getMessage());
|
||||
}
|
||||
|
||||
// typed vars with arrays
|
||||
assertEquals("typed pattern with array",findMatchesCount(s23,s24_1),2);
|
||||
@@ -3054,22 +3060,22 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
"}";
|
||||
|
||||
String pattern1 = "class '_A {" +
|
||||
" '_type+ 'method+ () throws '_E{0,0}" +
|
||||
" '_type+ 'method+ () throws '_E{0,0};" +
|
||||
"}";
|
||||
assertEquals(1, findMatchesCount(source, pattern1));
|
||||
|
||||
String pattern2 = "class '_A {" +
|
||||
" '_type+ 'method+ () throws '_E{1,2}" +
|
||||
" '_type+ 'method+ () throws '_E{1,2};" +
|
||||
"}";
|
||||
assertEquals(2, findMatchesCount(source, pattern2));
|
||||
|
||||
String pattern3 = "class '_A {" +
|
||||
" '_type+ 'method+ () throws '_E{2,2}" +
|
||||
" '_type+ 'method+ () throws '_E{2,2};" +
|
||||
"}";
|
||||
assertEquals(1, findMatchesCount(source, pattern3));
|
||||
|
||||
String pattern4 = "class '_A {" +
|
||||
" '_type+ 'method+ () throws '_E{0,0}:[ regex( E2 )]" +
|
||||
" '_type+ 'method+ () throws '_E{0,0}:[ regex( E2 )];" +
|
||||
"}";
|
||||
assertEquals(2, findMatchesCount(source, pattern4));
|
||||
}
|
||||
@@ -3146,8 +3152,8 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
" }" +
|
||||
"}";
|
||||
|
||||
String pattern1 = "() ->";
|
||||
assertEquals("should find lamdas", 4, findMatchesCount(source, pattern1));
|
||||
String pattern1 = "() -> {}";
|
||||
assertEquals("should find lambdas", 4, findMatchesCount(source, pattern1));
|
||||
|
||||
String pattern2 = "(int '_a) -> {}";
|
||||
assertEquals("should find lambdas with specific parameter type", 1, findMatchesCount(source, pattern2));
|
||||
@@ -3330,7 +3336,7 @@ public class StructuralSearchTest extends StructuralSearchTestCase {
|
||||
" } finally {}\n" +
|
||||
"}}";
|
||||
|
||||
String pattern1 = "try ('_ResourceType '_Var) { '_Statement*; }";
|
||||
String pattern1 = "try ('_ResourceType '_Var = '_exp) { '_Statement*; }";
|
||||
assertEquals("Find try-with-resources", 1, findMatchesCount(source, pattern1));
|
||||
|
||||
String pattern2 = "try { '_St1*; } catch ('_ExceptionType1 '_e1) { '_St2*; } catch ('_ExceptionType2 '_e2) { '_St3*; }";
|
||||
|
||||
@@ -4,9 +4,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Version {
|
||||
public final int major;
|
||||
public final int minor;
|
||||
@@ -22,23 +19,27 @@ public class Version {
|
||||
public static Version parseVersion(@NotNull String versionString) {
|
||||
String[] versions = versionString.split("\\.");
|
||||
String version = versions[0];
|
||||
int major = StringUtil.parseInt(version, -1);
|
||||
int major = parseNumber(version, -1);
|
||||
if (major < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int minor = (versions.length > 1) ? StringUtil.parseInt(versions[1], -1) : 0;
|
||||
int minor = (versions.length > 1) ? parseNumber(versions[1], -1) : 0;
|
||||
if (minor < 0) {
|
||||
return null;
|
||||
return new Version(major, 0, 0);
|
||||
}
|
||||
|
||||
int patch = (versions.length > 2) ? StringUtil.parseInt(versions[2], -1) : 0;
|
||||
int patch = (versions.length > 2) ? parseNumber(versions[2], -1) : 0;
|
||||
if (patch < 0) {
|
||||
return null;
|
||||
return new Version(major, minor, 0);
|
||||
}
|
||||
|
||||
return new Version(major, minor, patch);
|
||||
}
|
||||
|
||||
private static int parseNumber(String num, int def) {
|
||||
return StringUtil.parseInt(num.replaceFirst("(\\d+).*", "$1"), def);
|
||||
}
|
||||
|
||||
public boolean is(@Nullable Integer major) {
|
||||
return is(major, null);
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.intellij.util.io;
|
||||
import com.intellij.util.containers.SLRUCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@@ -46,15 +45,7 @@ public abstract class FileAccessorCache<K, T> implements com.intellij.util.conta
|
||||
}
|
||||
|
||||
protected abstract T createAccessor(K key) throws IOException;
|
||||
protected abstract void disposeAccessor(T fileAccessor);
|
||||
|
||||
protected void disposeCloseable(Closeable fileAccessor) {
|
||||
try {
|
||||
fileAccessor.close();
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
protected abstract void disposeAccessor(T fileAccessor) throws IOException;
|
||||
|
||||
@NotNull
|
||||
public final Handle<T> get(K key) {
|
||||
@@ -113,7 +104,11 @@ public abstract class FileAccessorCache<K, T> implements com.intellij.util.conta
|
||||
|
||||
public final void release() {
|
||||
if (myRefCount.decrementAndGet() == 0) {
|
||||
myOwner.disposeAccessor(myFileAccessor);
|
||||
try {
|
||||
myOwner.disposeAccessor(myFileAccessor);
|
||||
} catch (IOException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ public class PersistentHashMapValueStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disposeAccessor(RandomAccessFileWithLengthAndSizeTracking fileAccessor) {
|
||||
disposeCloseable(fileAccessor);
|
||||
protected void disposeAccessor(RandomAccessFileWithLengthAndSizeTracking fileAccessor) throws IOException {
|
||||
fileAccessor.close();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -75,8 +75,8 @@ public class PersistentHashMapValueStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disposeAccessor(DataOutputStream fileAccessor) {
|
||||
disposeCloseable(fileAccessor);
|
||||
protected void disposeAccessor(DataOutputStream fileAccessor) throws IOException {
|
||||
fileAccessor.close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.util;
|
||||
|
||||
import com.intellij.openapi.util.Version;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class VersionTest extends TestCase {
|
||||
public void testParseVersion() throws Exception {
|
||||
assertEquals(new Version(1, 0, 0), Version.parseVersion("1"));
|
||||
assertEquals(new Version(1, 2, 0), Version.parseVersion("1.2"));
|
||||
assertEquals(new Version(1, 2, 3), Version.parseVersion("1.2.3"));
|
||||
assertEquals(new Version(1, 2, 3), Version.parseVersion("1.2.3.4"));
|
||||
|
||||
assertEquals(new Version(1, 0, 0), Version.parseVersion("1beta"));
|
||||
assertEquals(new Version(1, 2, 0), Version.parseVersion("1.2beta"));
|
||||
assertEquals(new Version(1, 2, 3), Version.parseVersion("1.2.3beta"));
|
||||
assertEquals(new Version(1, 2, 3), Version.parseVersion("1.2.3.4beta"));
|
||||
|
||||
assertEquals(new Version(1, 0, 0), Version.parseVersion("1-beta"));
|
||||
assertEquals(new Version(1, 2, 0), Version.parseVersion("1.2-beta"));
|
||||
assertEquals(new Version(1, 2, 3), Version.parseVersion("1.2.3-beta"));
|
||||
assertEquals(new Version(1, 2, 3), Version.parseVersion("1.2.3.4-beta"));
|
||||
|
||||
assertEquals(new Version(1, 0, 0), Version.parseVersion("1.beta"));
|
||||
assertEquals(new Version(1, 2, 0), Version.parseVersion("1.2.beta"));
|
||||
assertEquals(new Version(1, 2, 3), Version.parseVersion("1.2.3.beta"));
|
||||
|
||||
assertEquals(null, Version.parseVersion(""));
|
||||
assertEquals(null, Version.parseVersion("beta1"));
|
||||
assertEquals(null, Version.parseVersion("beta.beta.beta"));
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -17,8 +17,7 @@ package com.intellij.openapi.vcs.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
@@ -80,7 +79,7 @@ public abstract class AbstractCommonCheckinAction extends AbstractVcsAction {
|
||||
@NotNull
|
||||
protected FilePath[] prepareRootsForCommit(@NotNull FilePath[] roots, @NotNull Project project) {
|
||||
if (ApplicationManager.getApplication().isDispatchThread()) {
|
||||
ApplicationManager.getApplication().saveAll();
|
||||
TransactionGuard.submitTransaction(ApplicationManager.getApplication()::saveAll);
|
||||
}
|
||||
|
||||
return filterDescindingFiles(roots, project);
|
||||
|
||||
@@ -293,7 +293,9 @@ public class MainFrame extends JPanel implements DataProvider, Disposable {
|
||||
}), VcsRevisionNumber.class);
|
||||
}
|
||||
else if (VcsDataKeys.VCS.is(dataId)) {
|
||||
Set<VirtualFile> roots = ContainerUtil.map2Set(Ints.asList(myGraphTable.getSelectedRows()), new Function<Integer, VirtualFile>() {
|
||||
int[] selectedRows = myGraphTable.getSelectedRows();
|
||||
if (selectedRows.length == 0 || selectedRows.length > VcsLogUtil.MAX_SELECTED_COMMITS) return null;
|
||||
Set<VirtualFile> roots = ContainerUtil.map2Set(Ints.asList(selectedRows), new Function<Integer, VirtualFile>() {
|
||||
@Override
|
||||
public VirtualFile fun(@NotNull Integer row) {
|
||||
return myGraphTable.getModel().getRoot(row);
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
groupKey="inspections.group.name"
|
||||
enabledByDefault="false" isInternal="true"
|
||||
level="ERROR" implementationClass="org.jetbrains.idea.devkit.inspections.internal.HighlightVisitorInternalInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="QuickFixGetFamilyNameViolation"
|
||||
<localInspection language="JAVA" shortName="QuickFixGetFamilyNameViolation"
|
||||
displayName="QuickFix's getFamilyName() implementation must not depend on a specific context"
|
||||
groupKey="inspections.group.name"
|
||||
enabledByDefault="true"
|
||||
|
||||
@@ -34,14 +34,16 @@ public class QuickFixGetFamilyNameViolationInspection extends DevKitInspectionBa
|
||||
@Nullable
|
||||
@Override
|
||||
public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
if ("getFamilyName".equals(method.getName()) && method.getParameterList().getParametersCount() == 0 && !method.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
if ("getFamilyName".equals(method.getName()) &&
|
||||
method.getParameterList().getParametersCount() == 0 &&
|
||||
!method.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
final PsiClass aClass = method.getContainingClass();
|
||||
if (InheritanceUtil.isInheritor(aClass, QuickFix.class.getName()) && doesMethodViolate(method)) {
|
||||
final PsiIdentifier identifier = method.getNameIdentifier();
|
||||
LOG.assertTrue(identifier != null);
|
||||
//noinspection DialogTitleCapitalization
|
||||
return new ProblemDescriptor[]{
|
||||
manager.createProblemDescriptor(identifier, "QuickFix's getFamilyName() implementation must not depend on a specific context", (LocalQuickFix) null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, true)};
|
||||
manager.createProblemDescriptor(identifier, "QuickFix's getFamilyName() implementation must not depend on a specific context",
|
||||
(LocalQuickFix)null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, true)};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -86,11 +86,7 @@ class GitRepositoryReader {
|
||||
|
||||
GitLocalBranch currentBranch;
|
||||
String currentRevision;
|
||||
if (!headInfo.isBranch) {
|
||||
currentBranch = null;
|
||||
currentRevision = headInfo.content;
|
||||
}
|
||||
else if (!localBranches.isEmpty()) {
|
||||
if (!headInfo.isBranch || !localBranches.isEmpty()) {
|
||||
currentBranch = findCurrentBranch(headInfo, state, localBranches.keySet());
|
||||
currentRevision = getCurrentRevision(headInfo, currentBranch == null ? null : localBranches.get(currentBranch));
|
||||
}
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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 git4idea.repo;
|
||||
|
||||
import com.intellij.dvcs.repo.Repository;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import git4idea.GitLocalBranch;
|
||||
import git4idea.GitRemoteBranch;
|
||||
import git4idea.branch.GitBranchUtil;
|
||||
import git4idea.test.GitSingleRepoTest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
||||
import static git4idea.test.GitExecutor.git;
|
||||
import static git4idea.test.GitExecutor.last;
|
||||
import static git4idea.test.GitScenarios.commit;
|
||||
import static git4idea.test.GitScenarios.conflict;
|
||||
import static git4idea.test.GitTestUtil.makeCommit;
|
||||
|
||||
/**
|
||||
* {@link GitRepositoryReaderTest} reads information from the pre-created .git directory from a real project.
|
||||
* This one, on the other hand, operates on a live Git repository, putting it to various situations and checking the results.
|
||||
*/
|
||||
public class GitRepositoryReaderNewTest extends GitSingleRepoTest {
|
||||
|
||||
// inspired by IDEA-93806
|
||||
public void test_rebase_with_conflicts_while_being_on_detached_HEAD() throws IOException {
|
||||
makeCommit("file.txt");
|
||||
conflict(myRepo, "feature");
|
||||
commit(myRepo);
|
||||
commit(myRepo);
|
||||
git("checkout HEAD^");
|
||||
git("rebase feature", true);
|
||||
|
||||
GitBranchState state = readState();
|
||||
assertNull("Current branch can't be identified for this case", state.getCurrentBranch());
|
||||
assertEquals("State value is incorrect", Repository.State.REBASING, state.getState());
|
||||
}
|
||||
|
||||
// inspired by IDEA-124052
|
||||
public void test_remote_reference_without_remote() throws IOException {
|
||||
makeCommit("file.txt");
|
||||
final String INVALID_REMOTE = "invalid-remote";
|
||||
final String INVALID_REMOTE_BRANCH = "master";
|
||||
git("update-ref refs/remotes/" + INVALID_REMOTE + "/" + INVALID_REMOTE_BRANCH + " HEAD");
|
||||
|
||||
Collection<GitRemoteBranch> remoteBranches = readState().getRemoteBranches().keySet();
|
||||
assertTrue("Remote branch not found", ContainerUtil.exists(remoteBranches, new Condition<GitRemoteBranch>() {
|
||||
@Override
|
||||
public boolean value(GitRemoteBranch branch) {
|
||||
return branch.getNameForLocalOperations().equals(INVALID_REMOTE + "/" + INVALID_REMOTE_BRANCH);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// inspired by IDEA-134286
|
||||
public void test_detached_HEAD() throws IOException {
|
||||
String head = getToDetachedHead();
|
||||
GitBranchState state = readState();
|
||||
assertEquals("Detached HEAD is not detected", GitRepository.State.DETACHED, state.getState());
|
||||
assertEquals("Detached HEAD hash is incorrect", head, state.getCurrentRevision());
|
||||
}
|
||||
|
||||
// inspired by IDEA-135966
|
||||
public void test_no_local_branches() throws IOException {
|
||||
String head = getToDetachedHead();
|
||||
git("branch -D master");
|
||||
GitBranchState state = readState();
|
||||
assertEquals("Detached HEAD is not detected", GitRepository.State.DETACHED, state.getState());
|
||||
assertEquals("Detached HEAD hash is incorrect", head, state.getCurrentRevision());
|
||||
assertTrue("There should be no local branches", state.getLocalBranches().isEmpty());
|
||||
}
|
||||
|
||||
public void test_tracking_remote_with_complex_name() throws IOException {
|
||||
makeCommit("file.txt");
|
||||
git("remote add my/remote http://my.remote.git");
|
||||
git("update-ref refs/remotes/my/remote/master HEAD");
|
||||
git("config branch.master.remote my/remote");
|
||||
git("config branch.master.merge refs/heads/master");
|
||||
myRepo.update();
|
||||
|
||||
|
||||
GitBranchTrackInfo trackInfo = GitBranchUtil.getTrackInfoForBranch(myRepo, ObjectUtils.assertNotNull(myRepo.getCurrentBranch()));
|
||||
assertNotNull(trackInfo);
|
||||
GitRemote remote = trackInfo.getRemote();
|
||||
assertEquals("my/remote", remote.getName());
|
||||
assertEquals("http://my.remote.git", remote.getFirstUrl());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getToDetachedHead() throws IOException {
|
||||
makeCommit("file.txt");
|
||||
makeCommit("file.txt");
|
||||
git("checkout HEAD^");
|
||||
return last();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private GitBranchState readState() {
|
||||
GitRepositoryFiles gitFiles = myRepo.getRepositoryFiles();
|
||||
GitConfig config = GitConfig.read(myPlatformFacade, gitFiles.getConfigFile());
|
||||
GitRepositoryReader reader = new GitRepositoryReader(gitFiles);
|
||||
Collection<GitRemote> remotes = config.parseRemotes();
|
||||
return reader.readState(remotes);
|
||||
}
|
||||
|
||||
// inspired by IDEA-134412
|
||||
public void test_fresh_repository_is_on_branch() {
|
||||
GitLocalBranch currentBranch = readState().getCurrentBranch();
|
||||
assertNotNull("Current branch shouldn't be null in a fresh repository", currentBranch);
|
||||
assertEquals("Fresh repository should be on master", "master", currentBranch.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean makeInitialCommit() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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 git4idea.repo
|
||||
|
||||
import com.intellij.dvcs.repo.Repository.State
|
||||
import git4idea.branch.GitBranchUtil
|
||||
import git4idea.test.GitExecutor.git
|
||||
import git4idea.test.GitExecutor.last
|
||||
import git4idea.test.GitScenarios.commit
|
||||
import git4idea.test.GitScenarios.conflict
|
||||
import git4idea.test.GitSingleRepoTest
|
||||
import git4idea.test.GitTestUtil.makeCommit
|
||||
|
||||
/**
|
||||
* [GitRepositoryReaderTest] reads information from the pre-created .git directory from a real project.
|
||||
* This one, on the other hand, operates on a live Git repository, putting it to various situations and checking the results.
|
||||
*/
|
||||
class GitRepositoryReaderNewTest : GitSingleRepoTest() {
|
||||
|
||||
override fun makeInitialCommit(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
// IDEA-152632
|
||||
fun `test current branch is known during rebase`() {
|
||||
makeCommit("file.txt")
|
||||
conflict(myRepo, "feature")
|
||||
git("checkout feature")
|
||||
git("rebase master", true)
|
||||
|
||||
val state = readState()
|
||||
assertEquals("State value is incorrect", State.REBASING, state.state)
|
||||
val currentBranch = state.currentBranch
|
||||
assertNotNull("Current branch should be known during rebase", currentBranch)
|
||||
assertEquals("Current branch is incorrect", "feature", currentBranch!!.name)
|
||||
}
|
||||
|
||||
fun `test rebase with conflicts while being on detached HEAD`() {
|
||||
makeCommit("file.txt")
|
||||
conflict(myRepo, "feature")
|
||||
commit(myRepo)
|
||||
commit(myRepo)
|
||||
git("checkout HEAD^")
|
||||
git("rebase feature", true)
|
||||
|
||||
val state = readState()
|
||||
assertNull("Current branch can't be identified for this case", state.currentBranch)
|
||||
assertEquals("State value is incorrect", State.REBASING, state.state)
|
||||
}
|
||||
|
||||
// IDEA-124052
|
||||
fun `test remote reference without remote`() {
|
||||
makeCommit("file.txt")
|
||||
val INVALID_REMOTE = "invalid-remote"
|
||||
val INVALID_REMOTE_BRANCH = "master"
|
||||
git("update-ref refs/remotes/$INVALID_REMOTE/$INVALID_REMOTE_BRANCH HEAD")
|
||||
|
||||
val remoteBranches = readState().remoteBranches.keys
|
||||
assertTrue("Remote branch not found", remoteBranches.any { it.nameForLocalOperations == "$INVALID_REMOTE/$INVALID_REMOTE_BRANCH" })
|
||||
}
|
||||
|
||||
// IDEA-134286
|
||||
fun `test detached HEAD`() {
|
||||
val head = moveToDetachedHead()
|
||||
val state = readState()
|
||||
assertEquals("Detached HEAD is not detected", State.DETACHED, state.state)
|
||||
assertEquals("Detached HEAD hash is incorrect", head, state.currentRevision)
|
||||
}
|
||||
|
||||
// IDEA-135966
|
||||
fun `test no local branches`() {
|
||||
val head = moveToDetachedHead()
|
||||
git("branch -D master")
|
||||
val state = readState()
|
||||
assertEquals("Detached HEAD is not detected", State.DETACHED, state.state)
|
||||
assertEquals("Detached HEAD hash is incorrect", head, state.currentRevision)
|
||||
assertTrue("There should be no local branches", state.localBranches.isEmpty())
|
||||
}
|
||||
|
||||
fun `test tracking remote with complex name`() {
|
||||
makeCommit("file.txt")
|
||||
git("remote add my/remote http://my.remote.git")
|
||||
git("update-ref refs/remotes/my/remote/master HEAD")
|
||||
git("config branch.master.remote my/remote")
|
||||
git("config branch.master.merge refs/heads/master")
|
||||
myRepo.update()
|
||||
|
||||
val trackInfo = GitBranchUtil.getTrackInfoForBranch(myRepo, myRepo.currentBranch!!)!!
|
||||
val remote = trackInfo.remote
|
||||
assertEquals("my/remote", remote.name)
|
||||
assertEquals("http://my.remote.git", remote.firstUrl)
|
||||
}
|
||||
|
||||
// IDEA-134412
|
||||
fun `test fresh repository is on branch`() {
|
||||
val currentBranch = readState().currentBranch
|
||||
assertNotNull("Current branch shouldn't be null in a fresh repository", currentBranch)
|
||||
assertEquals("Fresh repository should be on master", "master", currentBranch!!.name)
|
||||
}
|
||||
|
||||
private fun moveToDetachedHead(): String {
|
||||
makeCommit("file.txt")
|
||||
makeCommit("file.txt")
|
||||
git("checkout HEAD^")
|
||||
return last()
|
||||
}
|
||||
|
||||
private fun readState(): GitBranchState {
|
||||
val gitFiles = myRepo.repositoryFiles
|
||||
val config = GitConfig.read(myPlatformFacade, gitFiles.configFile)
|
||||
val reader = GitRepositoryReader(gitFiles)
|
||||
val remotes = config.parseRemotes()
|
||||
return reader.readState(remotes)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user