Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2013-11-25 18:51:06 +04:00
14 changed files with 443 additions and 172 deletions
@@ -62,7 +62,7 @@ public class VariableInplaceRenamer extends InplaceRefactoring {
);
private ResolveSnapshotProvider.ResolveSnapshot mySnapshot;
private TextRange mySelectedRange;
private Language myLanguage;
protected Language myLanguage;
public VariableInplaceRenamer(@NotNull PsiNamedElement elementToRename, Editor editor) {
this(elementToRename, editor, elementToRename.getProject());
@@ -0,0 +1,71 @@
/*
* Copyright 2000-2013 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.ui.mac;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.sun.jna.Callback;
import com.sun.jna.Pointer;
import java.util.concurrent.atomic.AtomicInteger;
import static com.intellij.ui.mac.foundation.Foundation.invoke;
/**
* @author Denis Fokin
*/
public class JDK7WindowReorderingWorkaround {
private static AtomicInteger requestorCount = new AtomicInteger();
private static final Callback windowDidBecomeMainCallback = new Callback() {
@SuppressWarnings("UnusedDeclaration") // this is a native up-call
public void callback(ID self,
ID nsNotification)
{
if (requestorCount.intValue() == 0) {
invoke(self, "oldWindowDidBecomeMain:", nsNotification);
}
}
};
static {
if (SystemInfo.isJavaVersionAtLeast("1.7")) {
ID awtWindow = Foundation.getObjcClass("AWTWindow");
Pointer windowWillEnterFullScreenMethod = Foundation.createSelector("windowDidBecomeMain:");
ID originalWindowWillEnterFullScreen = Foundation.class_replaceMethod(awtWindow, windowWillEnterFullScreenMethod,
windowDidBecomeMainCallback, "v@::@");
Foundation.addMethodByID(awtWindow, Foundation.createSelector("oldWindowDidBecomeMain:"),
originalWindowWillEnterFullScreen, "v@::@");
}
}
static void disableReordering() {
if (SystemInfo.isJavaVersionAtLeast("1.7")) {
requestorCount.incrementAndGet();
}
}
static void enableReordering () {
if (SystemInfo.isJavaVersionAtLeast("1.7")) {
requestorCount.decrementAndGet();
}
}
}
@@ -137,6 +137,7 @@ public class MacFileChooserDialogImpl implements PathChooserDialog {
finally {
Foundation.cfRelease(self);
Foundation.cfRelease(contextInfo);
JDK7WindowReorderingWorkaround.enableReordering();
}
}
};
@@ -323,6 +324,7 @@ public class MacFileChooserDialogImpl implements PathChooserDialog {
ourImplMap.put(delegate, impl);
final ID select = toSelect == null ? null : Foundation.nsString(toSelect);
JDK7WindowReorderingWorkaround.disableReordering();
invoke(delegate, "performSelectorOnMainThread:withObject:waitUntilDone:", Foundation.createSelector("showOpenPanel:"), select, false);
}
@@ -36,7 +36,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
@@ -72,6 +71,7 @@ public class MacMessagesImpl extends MacMessages {
resultsFromDocumentRoot.put(documentRoot, new MessageResult(returnCode.intValue(), suppressState.intValue() == 1));
queuesFromDocumentRoot.get(windowFromId.get(contextInfo.longValue())).runFromQueue();
}
JDK7WindowReorderingWorkaround.enableReordering();
cfRelease(self);
}
};
@@ -203,6 +203,7 @@ public class MacMessagesImpl extends MacMessages {
private MacMessagesImpl() {}
private static final Callback windowDidBecomeMainCallback = new Callback() {
@SuppressWarnings("UnusedDeclaration") // this is a native up-call
public void callback(ID self,
ID nsNotification)
{
@@ -357,6 +358,7 @@ public class MacMessagesImpl extends MacMessages {
private static void startModal(final Window w, ID windowId) {
long windowPtr = windowId.longValue();
synchronized (lock) {
JDK7WindowReorderingWorkaround.disableReordering();
windowFromId.put(windowPtr, w);
if (blockedDocumentRoots.keySet().contains(w)) {
blockedDocumentRoots.put(w, blockedDocumentRoots.get(w) + 1);
@@ -566,7 +568,7 @@ public class MacMessagesImpl extends MacMessages {
final Window documentRoot = getDocumentRootFromWindow(foremostWindow);
final ID nativeFocusedWindow = windowIdFromWindow(foremostWindow);
final ID nativeFocusedWindow = MacUtil.findWindowFromJavaWindow(foremostWindow);
paramsWrapper.setNativeWindow(nativeFocusedWindow);
@@ -591,54 +593,10 @@ public class MacMessagesImpl extends MacMessages {
return documentRoot;
}
private static ID windowIdFromWindow (Window w) {
ID windowId = null;
if (SystemInfo.isJavaVersionAtLeast("1.7") && Registry.is("skip.untitled.windows.for.mac.messages")) {
try {
Class <?> cWindowPeerClass = w.getPeer().getClass();
Method getPlatformWindowMethod = cWindowPeerClass.getDeclaredMethod("getPlatformWindow");
Object cPlatformWindow = getPlatformWindowMethod.invoke(w.getPeer());
Class <?> cPlatformWindowClass = cPlatformWindow.getClass();
Method getNSWindowPtrMethod = cPlatformWindowClass.getDeclaredMethod("getNSWindowPtr");
windowId = new ID((Long)getNSWindowPtrMethod.invoke(cPlatformWindow));
}
catch (NoSuchMethodException e) {
LOG.debug(e);
}
catch (InvocationTargetException e) {
LOG.debug(e);
}
catch (IllegalAccessException e) {
LOG.debug(e);
}
} else {
String foremostWindowTitle = getWindowTitle(w);
windowId = MacUtil.findWindowForTitle(foremostWindowTitle);
}
return windowId;
}
private static int convertReturnCodeFromNativeMessageDialog(int result) {
return result - 1000;
}
private static String getWindowTitle(Window documentRoot) {
String windowTitle;
if (documentRoot instanceof Frame) {
windowTitle = ((Frame)documentRoot).getTitle();
} else if (documentRoot instanceof Dialog) {
windowTitle = ((Dialog)documentRoot).getTitle();
} else {
throw new RuntimeException("The window is not a frame and not a dialog!");
}
return windowTitle;
}
@Messages.YesNoCancelResult
private static int convertReturnCodeFromNativeAlertDialog(int returnCode, String alternateText) {
// DEFAULT = 1
@@ -744,8 +702,8 @@ public class MacMessagesImpl extends MacMessages {
}
//Actually can, but not in this implementation. If you know a reasonable scenario, please ask Denis Fokin for the improvement.
LOG.assertTrue(getWindowTitle(_window) != null, "A window without a title should not be used for showing MacMessages");
while (_window != null && getWindowTitle(_window) == null) {
LOG.assertTrue(MacUtil.getWindowTitle(_window) != null, "A window without a title should not be used for showing MacMessages");
while (_window != null && MacUtil.getWindowTitle(_window) == null) {
_window = _window.getOwner();
//At least our frame should have a title
}
@@ -20,6 +20,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.Consumer;
import com.intellij.util.io.BaseDataReader;
import com.intellij.util.io.BaseOutputReader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -28,7 +29,7 @@ import java.io.*;
import java.nio.charset.Charset;
import java.util.concurrent.*;
import static com.intellij.util.io.BaseOutputReader.AdaptiveSleepingPolicy;
import static com.intellij.util.io.BaseDataReader.AdaptiveSleepingPolicy;
public class BaseOSProcessHandler extends ProcessHandler implements TaskExecutor {
private static final Logger LOG = Logger.getInstance("#com.intellij.execution.process.OSProcessHandlerBase");
@@ -82,13 +83,10 @@ public class BaseOSProcessHandler extends ProcessHandler implements TaskExecutor
@Override
public void startNotified(final ProcessEvent event) {
try {
BaseOutputReader.SleepingPolicy sleepingPolicy =
useAdaptiveSleepingPolicyWhenReadingOutput() ? new AdaptiveSleepingPolicy() : BaseOutputReader.SleepingPolicy.SIMPLE;
final BaseOutputReader stdoutReader = new SimpleOutputReader(createProcessOutReader(), ProcessOutputTypes.STDOUT, sleepingPolicy);
final BaseOutputReader stderrReader = processHasSeparateErrorStream()
? new SimpleOutputReader(createProcessErrReader(), ProcessOutputTypes.STDERR,
sleepingPolicy)
: null;
BaseDataReader.SleepingPolicy sleepingPolicy =
useAdaptiveSleepingPolicyWhenReadingOutput() ? new AdaptiveSleepingPolicy() : BaseDataReader.SleepingPolicy.SIMPLE;
final BaseDataReader stdoutReader = createOutputDataReader(sleepingPolicy);
final BaseDataReader stderrReader = processHasSeparateErrorStream() ? createErrorDataReader(sleepingPolicy) : null;
myWaitFor.setTerminationCallback(new Consumer<Integer>() {
@Override
@@ -120,6 +118,17 @@ public class BaseOSProcessHandler extends ProcessHandler implements TaskExecutor
super.startNotify();
}
@NotNull
protected BaseDataReader createErrorDataReader(BaseDataReader.SleepingPolicy sleepingPolicy) {
return new SimpleOutputReader(createProcessErrReader(), ProcessOutputTypes.STDERR,
sleepingPolicy);
}
@NotNull
protected BaseDataReader createOutputDataReader(BaseDataReader.SleepingPolicy sleepingPolicy) {
return new SimpleOutputReader(createProcessOutReader(), ProcessOutputTypes.STDOUT, sleepingPolicy);
}
protected void onOSProcessTerminated(final int exitCode) {
notifyProcessTerminated(exitCode);
}
@@ -16,9 +16,11 @@
package com.intellij.ui.mac.foundation;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -27,6 +29,8 @@ import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.AWTEventListener;
import java.awt.event.KeyEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static com.intellij.ui.mac.foundation.Foundation.invoke;
import static com.intellij.ui.mac.foundation.Foundation.toStringViaUTF8;
@@ -35,6 +39,7 @@ import static com.intellij.ui.mac.foundation.Foundation.toStringViaUTF8;
* @author pegov
*/
public class MacUtil {
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.mac.foundation.MacUtil");
public static final String MAC_NATIVE_WINDOW_SHOWING = "MAC_NATIVE_WINDOW_SHOWING";
private MacUtil() {
@@ -72,7 +77,7 @@ public class MacUtil {
return focusedWindow;
}
public static synchronized void startModal(JComponent component, String key) {
try {
if (SwingUtilities.isEventDispatchThread()) {
@@ -91,7 +96,7 @@ public class MacUtil {
((MenuComponent)source).dispatchEvent(event);
}
else {
System.err.println("Unable to dispatch: " + event);
LOG.debug("Unable to dispatch: " + event);
}
}
}
@@ -137,4 +142,47 @@ public class MacUtil {
});
Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.KEY_EVENT_MASK);
}
@SuppressWarnings("deprecation")
public static ID findWindowFromJavaWindow(final Window w) {
ID windowId = null;
if (SystemInfo.isJavaVersionAtLeast("1.7") && Registry.is("skip.untitled.windows.for.mac.messages")) {
try {
//noinspection deprecation
Class <?> cWindowPeerClass = w.getPeer().getClass();
Method getPlatformWindowMethod = cWindowPeerClass.getDeclaredMethod("getPlatformWindow");
Object cPlatformWindow = getPlatformWindowMethod.invoke(w.getPeer());
Class <?> cPlatformWindowClass = cPlatformWindow.getClass();
Method getNSWindowPtrMethod = cPlatformWindowClass.getDeclaredMethod("getNSWindowPtr");
windowId = new ID((Long)getNSWindowPtrMethod.invoke(cPlatformWindow));
}
catch (NoSuchMethodException e) {
LOG.debug(e);
}
catch (InvocationTargetException e) {
LOG.debug(e);
}
catch (IllegalAccessException e) {
LOG.debug(e);
}
} else {
String foremostWindowTitle = getWindowTitle(w);
windowId = findWindowForTitle(foremostWindowTitle);
}
return windowId;
}
public static String getWindowTitle(Window documentRoot) {
String windowTitle;
if (documentRoot instanceof Frame) {
windowTitle = ((Frame)documentRoot).getTitle();
} else if (documentRoot instanceof Dialog) {
windowTitle = ((Dialog)documentRoot).getTitle();
} else {
throw new RuntimeException("The window is not a frame and not a dialog!");
}
return windowTitle;
}
}
@@ -0,0 +1,139 @@
/*
* Copyright 2000-2013 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.io;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.TimeoutUtil;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* @author Konstantin Kolosovsky.
*/
public abstract class BaseDataReader {
private static final Logger LOG = Logger.getInstance(BaseDataReader.class);
protected volatile boolean isStopped = false;
private Future<?> myFinishedFuture = null;
@NotNull protected final SleepingPolicy mySleepingPolicy;
public BaseDataReader(SleepingPolicy sleepingPolicy) {
mySleepingPolicy = sleepingPolicy != null ? sleepingPolicy: SleepingPolicy.SIMPLE;
}
protected void start() {
if (myFinishedFuture == null) {
myFinishedFuture = executeOnPooledThread(new Runnable() {
@Override
public void run() {
doRun();
}
});
}
}
protected abstract Future<?> executeOnPooledThread(Runnable runnable);
public interface SleepingPolicy {
int sleepTimeWhenWasActive = 1;
int sleepTimeWhenIdle = 5;
SleepingPolicy SIMPLE = new SleepingPolicy() {
@Override
public int getTimeToSleep(boolean wasActive) {
return wasActive ? sleepTimeWhenWasActive : sleepTimeWhenIdle;
}
};
int getTimeToSleep(boolean wasActive);
}
public static class AdaptiveSleepingPolicy implements SleepingPolicy {
private static final int maxSleepTimeWhenIdle = 200;
private static final int maxIterationsWithCurrentSleepTime = 50;
private volatile int myIterationsWithCurrentTime;
private volatile int myCurrentSleepTime = sleepTimeWhenIdle;
@Override
public int getTimeToSleep(boolean wasActive) {
int currentSleepTime = myCurrentSleepTime; // volatile read
if (wasActive) currentSleepTime = sleepTimeWhenWasActive;
else if (currentSleepTime == sleepTimeWhenWasActive) {
currentSleepTime = sleepTimeWhenIdle;
myIterationsWithCurrentTime = 0;
}
else {
int iterationsWithCurrentTime = ++myIterationsWithCurrentTime;
if (iterationsWithCurrentTime >= maxIterationsWithCurrentSleepTime) {
myIterationsWithCurrentTime = 0;
currentSleepTime = Math.min(2* currentSleepTime, maxSleepTimeWhenIdle);
}
}
myCurrentSleepTime = currentSleepTime; // volatile write
return currentSleepTime;
}
}
protected void doRun() {
try {
while (true) {
boolean read = readAvailable();
if (isStopped) {
break;
}
TimeoutUtil.sleep(mySleepingPolicy.getTimeToSleep(read));
}
}
catch (IOException e) {
LOG.info(e);
}
catch (Exception e) {
LOG.error(e);
}
finally {
try {
close();
}
catch (IOException e) {
LOG.error("Can't close stream", e);
}
}
}
protected abstract boolean readAvailable() throws IOException;
protected abstract void close() throws IOException;
public void stop() {
isStopped = true;
}
public void waitFor() throws InterruptedException {
try {
myFinishedFuture.get();
}
catch (ExecutionException e) {
LOG.error(e);
}
}
}
@@ -15,121 +15,29 @@
*/
package com.intellij.util.io;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.TimeoutUtil;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.Reader;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* @author traff
*/
public abstract class BaseOutputReader {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.io.BaseOutputReader");
public abstract class BaseOutputReader extends BaseDataReader {
protected final Reader myReader;
protected volatile boolean isStopped = false;
private final char[] myBuffer = new char[8192];
private final StringBuilder myTextBuffer = new StringBuilder();
private boolean skipLF = false;
private Future<?> myFinishedFuture = null;
@NotNull protected final SleepingPolicy mySleepingPolicy;
public BaseOutputReader(@NotNull Reader reader) {
this(reader, null);
}
public BaseOutputReader(@NotNull Reader reader, SleepingPolicy sleepingPolicy) {
super(sleepingPolicy);
myReader = reader;
mySleepingPolicy = sleepingPolicy != null ? sleepingPolicy: SleepingPolicy.SIMPLE;
}
protected void start() {
if (myFinishedFuture == null) {
myFinishedFuture = executeOnPooledThread(new Runnable() {
@Override
public void run() {
doRun();
}
});
}
}
protected abstract Future<?> executeOnPooledThread(Runnable runnable);
public interface SleepingPolicy {
int sleepTimeWhenWasActive = 1;
int sleepTimeWhenIdle = 5;
SleepingPolicy SIMPLE = new SleepingPolicy() {
@Override
public int getTimeToSleep(boolean wasActive) {
return wasActive ? sleepTimeWhenWasActive : sleepTimeWhenIdle;
}
};
int getTimeToSleep(boolean wasActive);
}
public static class AdaptiveSleepingPolicy implements SleepingPolicy {
private static final int maxSleepTimeWhenIdle = 200;
private static final int maxIterationsWithCurrentSleepTime = 50;
private volatile int myIterationsWithCurrentTime;
private volatile int myCurrentSleepTime = sleepTimeWhenIdle;
@Override
public int getTimeToSleep(boolean wasActive) {
int currentSleepTime = myCurrentSleepTime; // volatile read
if (wasActive) currentSleepTime = sleepTimeWhenWasActive;
else if (currentSleepTime == sleepTimeWhenWasActive) {
currentSleepTime = sleepTimeWhenIdle;
myIterationsWithCurrentTime = 0;
}
else {
int iterationsWithCurrentTime = ++myIterationsWithCurrentTime;
if (iterationsWithCurrentTime >= maxIterationsWithCurrentSleepTime) {
myIterationsWithCurrentTime = 0;
currentSleepTime = Math.min(2* currentSleepTime, maxSleepTimeWhenIdle);
}
}
myCurrentSleepTime = currentSleepTime; // volatile write
return currentSleepTime;
}
}
protected void doRun() {
try {
while (true) {
boolean read = readAvailable();
if (isStopped) {
break;
}
TimeoutUtil.sleep(mySleepingPolicy.getTimeToSleep(read));
}
}
catch (IOException e) {
LOG.info(e);
}
catch (Exception e) {
LOG.error(e);
}
finally {
try {
myReader.close();
}
catch (IOException e) {
LOG.error("Can't close stream", e);
}
}
}
/**
@@ -176,18 +84,10 @@ public abstract class BaseOutputReader {
return read;
}
@Override
protected void close() throws IOException {
myReader.close();
}
protected abstract void onTextAvailable(@NotNull String text);
public void stop() {
isStopped = true;
}
public void waitFor() throws InterruptedException {
try {
myFinishedFuture.get();
}
catch (ExecutionException e) {
LOG.error(e);
}
}
}
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2013 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.io;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.InputStream;
/**
* @author Konstantin Kolosovsky.
*/
public abstract class BinaryOutputReader extends BaseDataReader {
@NotNull private final InputStream myStream;
@NotNull private final byte[] myBuffer = new byte[8192];
public BinaryOutputReader(@NotNull InputStream stream, SleepingPolicy sleepingPolicy) {
super(sleepingPolicy);
myStream = stream;
}
@Override
protected boolean readAvailable() throws IOException {
byte[] buffer = myBuffer;
boolean read = false;
while (myStream.available() > 0) {
int n = myStream.read(buffer);
if (n <= 0) break;
read = true;
onBinaryAvailable(buffer, n);
}
return read;
}
protected abstract void onBinaryAvailable(@NotNull byte[] data, int size);
@Override
protected void close() throws IOException {
myStream.close();
}
}
@@ -22,13 +22,18 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.io.BaseDataReader;
import com.intellij.util.io.BinaryOutputReader;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.tmatesoft.svn.core.SVNCancelException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@@ -117,7 +122,13 @@ public class CommandExecutor {
@NotNull
protected OSProcessHandler createProcessHandler() {
return new OSProcessHandler(myProcess, myCommandLine.getCommandLineString());
return needsBinaryOutput()
? new BinaryOSProcessHandler(myProcess, myCommandLine.getCommandLineString())
: new OSProcessHandler(myProcess, myCommandLine.getCommandLineString());
}
private boolean needsBinaryOutput() {
return SvnCommandName.cat.equals(myCommand.getName());
}
@NotNull
@@ -142,6 +153,11 @@ public class CommandExecutor {
return outputAdapter.getOutput().getStderr();
}
@Nullable
public ByteArrayOutputStream getBinaryOutput() {
return myHandler instanceof BinaryOSProcessHandler ? ((BinaryOSProcessHandler)myHandler).myBinaryOutput : null;
}
// TODO: Carefully here - do not modify command from threads other than the one started command execution
@NotNull
public Command getCommand() {
@@ -344,4 +360,38 @@ public class CommandExecutor {
}
}
}
private static class BinaryOSProcessHandler extends OSProcessHandler {
@NotNull private final ByteArrayOutputStream myBinaryOutput;
public BinaryOSProcessHandler(@NotNull final Process process, @Nullable final String commandLine) {
super(process, commandLine);
myBinaryOutput = new ByteArrayOutputStream();
}
@NotNull
@Override
protected BaseDataReader createOutputDataReader(BaseDataReader.SleepingPolicy sleepingPolicy) {
return new SimpleBinaryOutputReader(myProcess.getInputStream(), sleepingPolicy);
}
private class SimpleBinaryOutputReader extends BinaryOutputReader {
public SimpleBinaryOutputReader(@NotNull InputStream stream, SleepingPolicy sleepingPolicy) {
super(stream, sleepingPolicy);
start();
}
@Override
protected void onBinaryAvailable(@NotNull byte[] data, int size) {
myBinaryOutput.write(data, 0, size);
}
@Override
protected Future<?> executeOnPooledThread(Runnable runnable) {
return BinaryOSProcessHandler.this.executeOnPooledThread(runnable);
}
}
}
}
@@ -10,6 +10,7 @@ import org.jetbrains.idea.svn.commandLine.*;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
@@ -22,17 +23,17 @@ public class CmdContentClient extends BaseSvnClient implements ContentClient {
public byte[] getContent(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable SVNRevision pegRevision)
throws VcsException, FileTooBigRuntimeException {
// TODO: rewrite this to provide output as Stream
// TODO: rewrite without conversion from String to byte[]
// TODO: Also implement max size constraint like in SvnKitContentClient
// TODO: Could not use export to get content of scheduled for deletion file - use cat command, but write special binary handler
// NOTE: Export could not be used to get content of scheduled for deletion file
List<String> parameters = new ArrayList<String>();
CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision);
CommandUtil.put(parameters, revision);
CommandExecutor command = CommandUtil.execute(myVcs, target, SvnCommandName.cat, parameters, null);
byte[] bytes = CharsetToolkit.getUtf8Bytes(command.getOutput());
// TODO: currently binary output will be null for terminal mode - use text output in this case
ByteArrayOutputStream output = command.getBinaryOutput();
byte[] bytes = output != null ? output.toByteArray() : CharsetToolkit.getUtf8Bytes(command.getOutput());
ContentRevisionCache.checkContentsSize(target.getPathOrUrlString(), bytes.length);
@@ -7,7 +7,8 @@
</extensions>
<extensions defaultExtensionNs="com.intellij">
<patterns.patternClass className="com.jetbrains.python.patterns.PythonPatterns" alias="py"/>
<multiHostInjector implementation="com.jetbrains.python.intelliLang.PyTemporaryInjector"/>
<multiHostInjector implementation="com.jetbrains.python.intelliLang.PyCommentInjector"/>
<multiHostInjector implementation="com.jetbrains.python.intelliLang.PyConfigurationInjector"/>
<multiHostInjector implementation="com.jetbrains.python.intelliLang.PyTemporaryInjector"/>
</extensions>
</idea-plugin>
@@ -0,0 +1,25 @@
package com.jetbrains.python.intelliLang;
import com.intellij.lang.Language;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.codeInsight.PyInjectorBase;
import org.intellij.plugins.intelliLang.inject.InjectedLanguage;
import org.intellij.plugins.intelliLang.inject.InjectorUtils;
import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author vlan
*/
public class PyCommentInjector extends PyInjectorBase {
@Nullable
@Override
public Language getInjectedLanguage(@NotNull PsiElement context) {
final BaseInjection injection = InjectorUtils.findCommentInjection(context, "comment", null);
if (injection != null) {
return InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
}
return null;
}
}
@@ -15,10 +15,13 @@
*/
package com.jetbrains.python.intelliLang;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.jetbrains.python.patterns.PythonPatterns;
import com.jetbrains.python.psi.PyElement;
import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport;
import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,4 +54,10 @@ public class PyLanguageInjectionSupport extends AbstractLanguageInjectionSupport
public String getHelpId() {
return "reference.settings.language.injection.generic.python";
}
@Nullable
@Override
public BaseInjection findCommentInjection(@NotNull PsiElement host, @Nullable Ref<PsiElement> commentRef) {
return null;
}
}