Merge remote-tracking branch 'origin/master'
@@ -51,7 +51,11 @@ if [ -x "$READLINK" ]; then
|
||||
fi
|
||||
|
||||
IDE_BIN_HOME=`dirname "$SCRIPT_LOCATION"`
|
||||
IDE_HOME=`dirname "$IDE_BIN_HOME"`
|
||||
if [ "$IDE_BIN_HOME" = "." ]; then
|
||||
IDE_HOME=".."
|
||||
else
|
||||
IDE_HOME=`dirname "$IDE_BIN_HOME"`
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Locate a JDK installation directory which will be used to run the IDE.
|
||||
|
||||
@@ -46,7 +46,6 @@ public class CucumberMain {
|
||||
exitStatus = 1;
|
||||
}
|
||||
System.exit(exitStatus);
|
||||
|
||||
}
|
||||
|
||||
public static int run(final String[] argv, final ClassLoader classLoader) throws IOException {
|
||||
|
||||
@@ -95,7 +95,7 @@ class ReportMissingOrExcessiveInlineHint : AnAction() {
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
val text = file.readText()
|
||||
LOG.debug("File text $text")
|
||||
if (StatsSender.send(text)) {
|
||||
if (StatsSender.send(text, compress = false)) {
|
||||
file.delete()
|
||||
LOG.debug("File deleted")
|
||||
}
|
||||
|
||||
@@ -861,4 +861,15 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
schemeName.substring(DefaultColorsScheme.EDITABLE_COPY_PREFIX.length()) :
|
||||
schemeName;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public AbstractColorsScheme getOriginal() {
|
||||
String originalSchemeName = getMetaProperties().getProperty(META_INFO_ORIGINAL);
|
||||
if (originalSchemeName != null) {
|
||||
EditorColorsScheme originalScheme = EditorColorsManager.getInstance().getScheme(originalSchemeName);
|
||||
if (originalScheme instanceof AbstractColorsScheme) return (AbstractColorsScheme)originalScheme;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.application.ApplicationNamesInfo;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.*;
|
||||
import com.intellij.openapi.editor.colors.impl.*;
|
||||
import com.intellij.openapi.editor.markup.EffectType;
|
||||
@@ -72,6 +73,8 @@ import java.util.List;
|
||||
|
||||
public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract implements EditorOptionsProvider {
|
||||
public static final String ID = "reference.settingsdialog.IDE.editor.colors";
|
||||
|
||||
private static Logger LOG = Logger.getInstance("#" + ColorAndFontOptions.class.getName());
|
||||
|
||||
private Map<String, MyColorScheme> mySchemes;
|
||||
private MyColorScheme mySelectedScheme;
|
||||
@@ -245,6 +248,16 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
resetSchemesCombo(null);
|
||||
mySomeSchemesDeleted = mySomeSchemesDeleted || !deletedNewlyCreated;
|
||||
}
|
||||
|
||||
|
||||
void resetSchemeToOriginal(@NotNull String name) {
|
||||
MyColorScheme schemeToReset = mySchemes.get(name);
|
||||
schemeToReset.resetToOriginal();
|
||||
resetImpl();
|
||||
selectScheme(name);
|
||||
resetSchemesCombo(null);
|
||||
((EditorColorsManagerImpl)EditorColorsManager.getInstance()).schemeChangedOrSwitched(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
@@ -1167,6 +1180,16 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void resetToOriginal() {
|
||||
if (myParentScheme instanceof AbstractColorsScheme) {
|
||||
AbstractColorsScheme originalScheme = ((AbstractColorsScheme)myParentScheme).getOriginal();
|
||||
if (originalScheme != null) {
|
||||
originalScheme.copyTo((AbstractColorsScheme)myParentScheme);
|
||||
((AbstractColorsScheme)myParentScheme).setSaveNeeded(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,9 +21,7 @@ import com.intellij.application.options.SaveSchemeDialog;
|
||||
import com.intellij.application.options.SkipSelfSearchComponent;
|
||||
import com.intellij.openapi.application.ApplicationBundle;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.impl.AbstractColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.impl.EditorColorsSchemeImpl;
|
||||
import com.intellij.openapi.editor.colors.impl.EmptyColorScheme;
|
||||
import com.intellij.openapi.editor.colors.impl.*;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.options.SchemeImportException;
|
||||
import com.intellij.openapi.options.SchemeImportUtil;
|
||||
@@ -32,6 +30,7 @@ import com.intellij.openapi.options.SchemeImporterEP;
|
||||
import com.intellij.openapi.project.DefaultProjectFactory;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.EventDispatcher;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -51,6 +50,7 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
|
||||
private ComboBox<MySchemeItem> mySchemeComboBox;
|
||||
|
||||
private JButton myDeleteButton;
|
||||
private JButton myResetButton;
|
||||
private JButton myImportButton;
|
||||
private JLabel myHintLabel;
|
||||
|
||||
@@ -79,6 +79,12 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
|
||||
if (areSchemesLoaded()) {
|
||||
myDispatcher.getMulticaster().schemeChanged(SchemesPanel.this);
|
||||
}
|
||||
AbstractColorsScheme originalScheme =
|
||||
selected instanceof AbstractColorsScheme ? ((AbstractColorsScheme)selected).getOriginal() : null;
|
||||
myResetButton.setEnabled(
|
||||
!readOnly &&
|
||||
selectedName.startsWith(DefaultColorsScheme.EDITABLE_COPY_PREFIX) &&
|
||||
originalScheme instanceof ReadOnlyColorsScheme);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -128,6 +134,23 @@ public class SchemesPanel extends JPanel implements SkipSelfSearchComponent {
|
||||
panel.add(myDeleteButton,
|
||||
new GridBagConstraints(gridx++, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new JBInsets(0, 0, 5, 5), 0,
|
||||
0));
|
||||
myResetButton = new JButton(ApplicationBundle.message("color.scheme.reset"));
|
||||
myResetButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull ActionEvent e) {
|
||||
String selectedName = getSelectedSchemeName();
|
||||
if (selectedName != null) {
|
||||
if (Messages
|
||||
.showOkCancelDialog(ApplicationBundle.message("color.scheme.reset.message"),
|
||||
ApplicationBundle.message("color.scheme.reset.title"), Messages.getQuestionIcon()) == Messages.OK) {
|
||||
myOptions.resetSchemeToOriginal(selectedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
panel.add(myResetButton,
|
||||
new GridBagConstraints(gridx++, 0, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new JBInsets(0, 0, 5, 5), 0,
|
||||
0));
|
||||
myImportButton = new JButton("Import...");
|
||||
myImportButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.intellij.find;
|
||||
|
||||
import com.intellij.execution.impl.ConsoleViewUtil;
|
||||
import com.intellij.find.editorHeaderActions.*;
|
||||
import com.intellij.find.impl.livePreview.LivePreviewController;
|
||||
import com.intellij.find.impl.livePreview.SearchResults;
|
||||
@@ -154,7 +155,7 @@ public class EditorSearchSession implements SearchSession,
|
||||
updateUIWithFindModel();
|
||||
mySearchResults.clear();
|
||||
updateResults(true);
|
||||
FindUtil.updateFindInFileModel(getProject(), myFindModel);
|
||||
FindUtil.updateFindInFileModel(getProject(), myFindModel, !ConsoleViewUtil.isConsoleViewEditor(editor));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -143,14 +143,20 @@ public class FindUtil {
|
||||
model.setPromptOnReplace(false);
|
||||
}
|
||||
|
||||
public static void updateFindInFileModel(@Nullable Project project, @NotNull FindModel with) {
|
||||
public static void updateFindInFileModel(@Nullable Project project, @NotNull FindModel with, boolean saveFindString) {
|
||||
FindModel model = FindManager.getInstance(project).getFindInFileModel();
|
||||
model.setCaseSensitive(with.isCaseSensitive());
|
||||
model.setWholeWordsOnly(with.isWholeWordsOnly());
|
||||
model.setRegularExpressions(with.isRegularExpressions());
|
||||
model.setSearchContext(with.getSearchContext());
|
||||
|
||||
if (saveFindString && !with.getStringToFind().isEmpty()) {
|
||||
model.setStringToFind(with.getStringToFind());
|
||||
}
|
||||
|
||||
if (with.isReplaceState()) {
|
||||
model.setPreserveCase(with.isPreserveCase());
|
||||
if (saveFindString) model.setStringToReplace(with.getStringToReplace());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction;
|
||||
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
|
||||
public class IncrementalFindAction extends EditorAction {
|
||||
public static class Handler extends EditorActionHandler {
|
||||
@@ -57,9 +56,14 @@ public class IncrementalFindAction extends EditorAction {
|
||||
model = new FindModel();
|
||||
model.copyFrom(findManager.getFindInFileModel());
|
||||
}
|
||||
FindUtil.configureFindModel(myReplace, editor, model, true);
|
||||
boolean consoleViewEditor = ConsoleViewUtil.isConsoleViewEditor(editor);
|
||||
FindUtil.configureFindModel(myReplace, editor, model, consoleViewEditor);
|
||||
EditorSearchSession.start(editor, model, project).getComponent()
|
||||
.requestFocusInTheSearchFieldAndSelectContent(project);
|
||||
if (!consoleViewEditor && editor.getSelectionModel().hasSelection()) {
|
||||
// selection is used as string to find without search model modification so save the pattern explicitly
|
||||
FindUtil.updateFindInFileModel(project, model, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.openapi.command.UndoConfirmationPolicy;
|
||||
import com.intellij.openapi.editor.*;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.reporting.FreezeLogger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -132,7 +133,7 @@ public class TypedAction {
|
||||
public final void actionPerformed(@Nullable final Editor editor, final char charTyped, final DataContext dataContext) {
|
||||
if (editor == null) return;
|
||||
Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
FreezeLogger.runUnderPerformanceMonitor(project, () -> myRawHandler.execute(editor, charTyped, dataContext));
|
||||
FreezeLogger.getInstance().runUnderPerformanceMonitor(project, () -> myRawHandler.execute(editor, charTyped, dataContext));
|
||||
}
|
||||
|
||||
private class DefaultRawHandler implements TypedActionHandler {
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.reporting;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class FreezeLogger {
|
||||
|
||||
public static FreezeLogger getInstance() {
|
||||
return ServiceManager.getService(FreezeLogger.class);
|
||||
}
|
||||
|
||||
public abstract void runUnderPerformanceMonitor(@Nullable Project project, @NotNull Runnable action);
|
||||
|
||||
}
|
||||
@@ -13,25 +13,28 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.openapi.editor.actionSystem;
|
||||
package com.intellij.reporting;
|
||||
|
||||
import com.intellij.diagnostic.ThreadDumper;
|
||||
import com.intellij.openapi.application.ApplicationInfo;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.Alarm;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class FreezeLogger {
|
||||
public class FreezeLoggerImpl extends FreezeLogger {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(FreezeLogger.class);
|
||||
private static final Logger LOG = Logger.getInstance(FreezeLoggerImpl.class);
|
||||
private static final Alarm ALARM = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, ApplicationManager.getApplication());
|
||||
private static final int MAX_ALLOWED_TIME = 500;
|
||||
|
||||
public static void runUnderPerformanceMonitor(@Nullable Project project, @NotNull Runnable action) {
|
||||
@Override
|
||||
public void runUnderPerformanceMonitor(@Nullable Project project, @NotNull Runnable action) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
action.run();
|
||||
return;
|
||||
@@ -64,8 +67,35 @@ public class FreezeLogger {
|
||||
final String msg = "Typing freeze report, (DumbMode=" + isInDumbMode + ") thread dumps attached. EDT stacktrace:\n"
|
||||
+ edtTrace
|
||||
+ "\n\n\n";
|
||||
|
||||
LOG.error(msg, dumps);
|
||||
|
||||
if (Registry.is("typing.freeze.report.dumps")) {
|
||||
ThreadDumpInfo info = new ThreadDumpInfo(dumps, isInDumbMode);
|
||||
String report = ReporterKt.createReportLine("typing-freeze-dumps", info);
|
||||
if (!StatsSender.INSTANCE.send(report, true)) {
|
||||
LOG.debug("Error while reporting thread dump");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG.error(msg, dumps);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ThreadDumpInfo {
|
||||
public final String dump;
|
||||
public final String version;
|
||||
public final String product;
|
||||
public final String buildNumber;
|
||||
public final boolean isEAP;
|
||||
public final boolean isInDumbMode;
|
||||
|
||||
public ThreadDumpInfo(String dump, boolean isInDumbMode) {
|
||||
this.dump = dump;
|
||||
this.product = ApplicationInfo.getInstance().getVersionName();
|
||||
this.version = ApplicationInfo.getInstance().getFullVersion();
|
||||
this.buildNumber = ApplicationInfo.getInstance().getBuild().toString();
|
||||
this.isEAP = ApplicationManager.getApplication().isEAP();
|
||||
this.isInDumbMode = isInDumbMode;
|
||||
}
|
||||
}
|
||||
@@ -15,14 +15,21 @@
|
||||
*/
|
||||
package com.intellij.reporting
|
||||
|
||||
import com.google.common.net.HttpHeaders
|
||||
import com.google.gson.Gson
|
||||
import com.intellij.openapi.application.PermanentInstallationID
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import org.apache.commons.codec.binary.Base64OutputStream
|
||||
import org.apache.http.client.fluent.Request
|
||||
import org.apache.http.entity.ContentType
|
||||
import org.apache.http.message.BasicHeader
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
|
||||
private class StatsServerInfo(@JvmField var status: String, @JvmField var url: String) {
|
||||
private class StatsServerInfo(@JvmField var status: String,
|
||||
@JvmField var url: String,
|
||||
@JvmField var urlForZipBase64Content: String) {
|
||||
fun isServiceAlive() = "ok" == status
|
||||
}
|
||||
|
||||
@@ -30,16 +37,15 @@ private object Utils {
|
||||
val gson = Gson()
|
||||
}
|
||||
|
||||
|
||||
object StatsSender {
|
||||
private val infoUrl = "https://www.jetbrains.com/config/features-service-status.json"
|
||||
private val LOG = Logger.getInstance(StatsSender::class.java)
|
||||
|
||||
private fun requestServerUrl(): String? {
|
||||
|
||||
private fun requestServerUrl(): StatsServerInfo? {
|
||||
try {
|
||||
val response = Request.Get(infoUrl).execute().returnContent().asString()
|
||||
val info = Utils.gson.fromJson(response, StatsServerInfo::class.java)
|
||||
if (info.isServiceAlive()) return info.url
|
||||
if (info.isServiceAlive()) return info
|
||||
}
|
||||
catch (e: Exception) {
|
||||
LOG.debug(e)
|
||||
@@ -47,11 +53,11 @@ object StatsSender {
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun send(text: String): Boolean {
|
||||
val url = requestServerUrl() ?: return false
|
||||
|
||||
fun send(text: String, compress: Boolean = true): Boolean {
|
||||
val info = requestServerUrl() ?: return false
|
||||
try {
|
||||
val response = Request.Post(url).bodyString(text, ContentType.TEXT_HTML).execute()
|
||||
val response = createRequest(info, text, compress).execute()
|
||||
val code = response.handleResponse { it.statusLine.statusCode }
|
||||
if (code >= 200 && code < 300) {
|
||||
return true
|
||||
@@ -62,7 +68,28 @@ object StatsSender {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
private fun createRequest(info: StatsServerInfo, text: String, compress: Boolean): Request {
|
||||
if (compress) {
|
||||
val data = Base64GzipCompressor.compress(text)
|
||||
val request = Request.Post(info.urlForZipBase64Content).bodyByteArray(data)
|
||||
request.addHeader(BasicHeader(HttpHeaders.CONTENT_ENCODING, "gzip"))
|
||||
return request
|
||||
}
|
||||
|
||||
return Request.Post(info.url).bodyString(text, ContentType.TEXT_HTML)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private object Base64GzipCompressor {
|
||||
fun compress(text: String): ByteArray {
|
||||
val outputStream = ByteArrayOutputStream()
|
||||
val base64Stream = GZIPOutputStream(Base64OutputStream(outputStream))
|
||||
base64Stream.write(text.toByteArray())
|
||||
base64Stream.close()
|
||||
return outputStream.toByteArray()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> createReportLine(recorderId: String, data: T): String {
|
||||
|
||||
@@ -762,4 +762,8 @@ checkbox.stop.4=Stop #4
|
||||
checkbox.stop.5=Stop #5
|
||||
checkbox.rainbow=<html>Unique color for each parameter<br>and local variable<br><font color=gray><sub>Chosen from generated gradient</sub></font></html>
|
||||
label.rainbow.inheritance=<html><div style="text-align:right" vertical-align="top">''{0}->Unique color''<br>of <a href="{1}">{2}</html>
|
||||
label.rainbow.inheritance.tooltip=<html>''{0}->Unique color'' from<br>''{1}'' section</html>
|
||||
label.rainbow.inheritance.tooltip=<html>''{0}->Unique color'' from<br>''{1}'' section</html>
|
||||
|
||||
color.scheme.reset=Reset
|
||||
color.scheme.reset.message=Reset the scheme to its default values?\nNote: all the changes you have made to the scheme will be lost.
|
||||
color.scheme.reset.title=Scheme Reset
|
||||
@@ -141,6 +141,8 @@
|
||||
|
||||
<applicationService serviceInterface="com.intellij.featureStatistics.FeatureUsageTracker"
|
||||
serviceImplementation="com.intellij.featureStatistics.FeatureUsageTrackerImpl"/>
|
||||
<applicationService serviceInterface="com.intellij.reporting.FreezeLogger"
|
||||
serviceImplementation="com.intellij.reporting.FreezeLoggerImpl"/>
|
||||
<applicationService serviceInterface="com.intellij.featureStatistics.ProductivityFeaturesRegistry"
|
||||
serviceImplementation="com.intellij.featureStatistics.ProductivityFeaturesRegistryImpl"/>
|
||||
<applicationService serviceInterface="com.intellij.util.InstanceofCheckerGenerator"
|
||||
|
||||
@@ -809,3 +809,6 @@ javafx.fxml.controller.from.loader.description=Resolve FXML controllers specifie
|
||||
|
||||
low.memory.watcher.sync=true
|
||||
low.memory.watcher.sync.description=Whether LowMemoryWatcher runnables should be executed on the same thread that the low memory events come
|
||||
|
||||
typing.freeze.report.dumps=false
|
||||
typing.freeze.report.dumps.description=Automatically reports thread dumps to our statistics server
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2012 Bas Leijdekkers
|
||||
* Copyright 2006-2016 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,6 @@ package com.siyeh.ig.controlflow;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
@@ -26,6 +25,7 @@ import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.PsiReplacementUtil;
|
||||
import com.siyeh.ig.psiutils.BoolUtils;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import com.siyeh.ig.psiutils.TypeUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -68,7 +68,7 @@ public class DoubleNegationInspection extends BaseInspection {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
|
||||
protected void doFix(Project project, ProblemDescriptor descriptor) {
|
||||
final PsiElement expression = descriptor.getPsiElement();
|
||||
if (expression instanceof PsiPrefixExpression) {
|
||||
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)expression;
|
||||
@@ -163,6 +163,9 @@ public class DoubleNegationInspection extends BaseInspection {
|
||||
}
|
||||
|
||||
static boolean isNegation(PsiPolyadicExpression expression) {
|
||||
for (PsiExpression operand : expression.getOperands()) {
|
||||
if (TypeUtils.hasFloatingPointType(operand)) return false; // don't change semantics for NaNs
|
||||
}
|
||||
return JavaTokenType.NE.equals(expression.getOperationTokenType());
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2015 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,6 @@ package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -85,8 +84,7 @@ public class BoolUtils {
|
||||
}
|
||||
return ParenthesesUtils.getText(negated, precedence);
|
||||
}
|
||||
else if (ComparisonUtils.isComparison(expression) &&
|
||||
!TypeConversionUtil.isFloatOrDoubleType(ComparisonUtils.getComparisonType(expression))) {
|
||||
else if (ComparisonUtils.isComparison(expression)) {
|
||||
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
|
||||
final String negatedComparison = ComparisonUtils.getNegatedComparison(polyadicExpression.getOperationTokenType());
|
||||
final StringBuilder result = new StringBuilder();
|
||||
@@ -94,6 +92,10 @@ public class BoolUtils {
|
||||
final boolean isEven = (operands.length & 1) != 1;
|
||||
for (int i = 0, length = operands.length; i < length; i++) {
|
||||
final PsiExpression operand = operands[i];
|
||||
if (TypeUtils.hasFloatingPointType(operand)) {
|
||||
// preserve semantics for NaNs
|
||||
return "!(" + polyadicExpression.getText() + ')';
|
||||
}
|
||||
if (i > 0) {
|
||||
if (isEven && (i & 1) != 1) {
|
||||
final PsiJavaToken token = polyadicExpression.getTokenBeforeOperand(operand);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
|
||||
* Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiPolyadicExpression;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -60,37 +60,6 @@ public class ComparisonUtils {
|
||||
s_invertedComparisons.put(JavaTokenType.LE, ">");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual type of compared values in comparison expression after unboxing and promotion if applicable.
|
||||
*
|
||||
* @param expression the expression to get the type of compared values
|
||||
* @return the resulting type or null if expression is not a comparison or type is not known.
|
||||
*/
|
||||
@Contract("null -> null")
|
||||
@Nullable
|
||||
public static PsiType getComparisonType(PsiExpression expression) {
|
||||
if(!(expression instanceof PsiPolyadicExpression)) return null;
|
||||
PsiPolyadicExpression operation = (PsiPolyadicExpression)expression;
|
||||
IElementType tokenType = operation.getOperationTokenType();
|
||||
if (!isComparisonOperation(tokenType)) return null;
|
||||
PsiType lType;
|
||||
PsiType rType;
|
||||
if(operation instanceof PsiBinaryExpression) {
|
||||
PsiExpression left = ((PsiBinaryExpression)operation).getLOperand();
|
||||
PsiExpression right = ((PsiBinaryExpression)operation).getROperand();
|
||||
lType = left.getType();
|
||||
rType = right == null ? null : right.getType();
|
||||
} else {
|
||||
PsiExpression[] operands = operation.getOperands();
|
||||
if(operands.length <= 2) return null;
|
||||
lType = PsiType.BOOLEAN;
|
||||
rType = operands[operands.length-1].getType();
|
||||
}
|
||||
if (lType == null || rType == null) return null;
|
||||
if (lType.equals(rType)) return lType;
|
||||
return TypeConversionUtil.unboxAndBalanceTypes(lType, rType);
|
||||
}
|
||||
|
||||
public static boolean isComparison(@Nullable PsiExpression expression) {
|
||||
if (!(expression instanceof PsiPolyadicExpression)) {
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class X {
|
||||
void vm(Double a, Double b) {
|
||||
boolean r = a == null || b != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class X {
|
||||
void vm(Double a, Double b) {
|
||||
boolean r = !(<caret>a != null) || b != null;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ public class ConfusingElse {
|
||||
public static void main(String[] args) {
|
||||
if (foo()) {
|
||||
return;
|
||||
} else {
|
||||
} <warning descr="'else' branch may be unwrapped, as the 'if' branch never completes">else</warning> {
|
||||
System.out.println("ConfusingElseInspection.main");
|
||||
}
|
||||
bar();
|
||||
@@ -55,7 +55,7 @@ public class ConfusingElse {
|
||||
void elseIf(int i) {
|
||||
if (i == 1) {
|
||||
return;
|
||||
} else if (i == 3) {
|
||||
} <warning descr="'else' branch may be unwrapped, as the 'if' branch never completes">else</warning> if (i == 3) {
|
||||
System.out.println("i = " + i);
|
||||
}
|
||||
System.out.println();
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>ConfusingElse.java</file>
|
||||
<line>8</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Confusing 'else' branch</problem_class>
|
||||
<description><code>else</code> branch may be unwrapped, as the if branch never completes #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>ConfusingElse.java</file>
|
||||
<line>58</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Confusing 'else' branch</problem_class>
|
||||
<description><code>else</code> branch may be unwrapped, as the if branch never completes #loc</description>
|
||||
</problem>
|
||||
|
||||
</problems>
|
||||
@@ -3,10 +3,14 @@ package com.siyeh.igtest.controlflow.double_negation;
|
||||
public class DoubleNegation {
|
||||
|
||||
void negative(boolean b1, boolean b2, boolean b3) {
|
||||
boolean r1 = !(b1 != b2);
|
||||
boolean r2 = !!b1;
|
||||
boolean r3 = !b1 != b2;
|
||||
boolean r4 = (b1 != (b2 != b3));
|
||||
boolean r5 = (b1 != b2 != b3);
|
||||
boolean r1 = <warning descr="Double negation in '!(b1 != b2)'">!(b1 != b2)</warning>;
|
||||
boolean r2 = <warning descr="Double negation in '!!b1'">!!b1</warning>;
|
||||
boolean r3 = <warning descr="Double negation in '!b1 != b2'">!b1 != b2</warning>;
|
||||
boolean r4 = (<warning descr="Double negation in 'b1 != (b2 != b3)'">b1 != (b2 != b3)</warning>);
|
||||
boolean r5 = (<warning descr="Double negation in 'b1 != b2 != b3'">b1 != b2 != b3</warning>);
|
||||
}
|
||||
|
||||
void vm(Double a, double b) {
|
||||
boolean r = <warning descr="Double negation in '!(a != null)'">!(a != null)</warning> || !(b != Double.NaN != false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<problems>
|
||||
<problem>
|
||||
<file>DoubleNegation.java</file>
|
||||
<line>6</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Double negation</problem_class>
|
||||
<description>Double negation in <code>!(b1 != b2)</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>DoubleNegation.java</file>
|
||||
<line>7</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Double negation</problem_class>
|
||||
<description>Double negation in <code>!!b1</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>DoubleNegation.java</file>
|
||||
<line>8</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Double negation</problem_class>
|
||||
<description>Double negation in <code>!b1 != b2</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>DoubleNegation.java</file>
|
||||
<line>9</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Double negation</problem_class>
|
||||
<description>Double negation in <code>b1 != (b2 != b3)</code> #loc</description>
|
||||
</problem>
|
||||
|
||||
<problem>
|
||||
<file>DoubleNegation.java</file>
|
||||
<line>10</line>
|
||||
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Double negation</problem_class>
|
||||
<description>Double negation in <code>b1 != b2 != b3</code> #loc</description>
|
||||
</problem>
|
||||
</problems>
|
||||
@@ -1,12 +1,36 @@
|
||||
/*
|
||||
* 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.siyeh.ig.controlflow;
|
||||
|
||||
import com.siyeh.ig.IGInspectionTestCase;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ConfusingElseInspectionTest
|
||||
extends IGInspectionTestCase {
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class ConfusingElseInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest("com/siyeh/igtest/controlflow/confusing_else",
|
||||
new ConfusingElseInspection());
|
||||
public void testConfusingElse() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new ConfusingElseInspection();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,36 @@
|
||||
/*
|
||||
* 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.siyeh.ig.controlflow;
|
||||
|
||||
import com.siyeh.ig.IGInspectionTestCase;
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class DoubleNegationInspectionTest
|
||||
extends IGInspectionTestCase {
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class DoubleNegationInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest("com/siyeh/igtest/controlflow/double_negation", new DoubleNegationInspection());
|
||||
public void testDoubleNegation() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
return new DoubleNegationInspection();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.siyeh.ig.fixes.controlflow;
|
||||
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.IGQuickFixesTestCase;
|
||||
import com.siyeh.ig.controlflow.DoubleNegationInspection;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class DoubleNegationFixTest extends IGQuickFixesTestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myFixture.enableInspections(new DoubleNegationInspection());
|
||||
myRelativePath = "controlflow/double_negation";
|
||||
myDefaultHint = InspectionGadgetsBundle.message("double.negation.quickfix");
|
||||
}
|
||||
|
||||
public void testDoubleDoubleNegation() { doTest(); }
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<component>
|
||||
<version major="2016" minor="2" eap="true"/>
|
||||
<version major="2016" minor="3" eap="true"/>
|
||||
<company name="JetBrains s.r.o." url="https://www.jetbrains.com/?fromIDE"/>
|
||||
<build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
|
||||
<logo url="/pycharm_core_logo.png" textcolor="dddddd" progressColor="08f5d6" progressX="0" progressY="280" progressHeight="3"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 300 KiB After Width: | Height: | Size: 308 KiB |
|
Before Width: | Height: | Size: 234 KiB After Width: | Height: | Size: 233 KiB |
|
Before Width: | Height: | Size: 660 KiB After Width: | Height: | Size: 666 KiB |
@@ -57,7 +57,7 @@ public class PydevConsoleExecuteActionHandler extends ProcessBackedConsoleExecut
|
||||
private final ConsoleCommunication myConsoleCommunication;
|
||||
private boolean myEnabled = false;
|
||||
|
||||
private int myIpythonInputPromptCount = 0;
|
||||
private int myIpythonInputPromptCount = 1;
|
||||
|
||||
public PydevConsoleExecuteActionHandler(LanguageConsoleView consoleView,
|
||||
ProcessHandler processHandler,
|
||||
|
||||