diff --git a/RegExpSupport/src/META-INF/RegExpPlugin.xml b/RegExpSupport/src/META-INF/RegExpPlugin.xml index 9153bad786b8..392b7431ec2a 100644 --- a/RegExpSupport/src/META-INF/RegExpPlugin.xml +++ b/RegExpSupport/src/META-INF/RegExpPlugin.xml @@ -34,10 +34,13 @@ implementationClass="org.intellij.lang.regexp.inspection.SingleCharAlternationInspection"/> - + + diff --git a/RegExpSupport/src/inspectionDescriptions/EscapedMetaCharacter.html b/RegExpSupport/src/inspectionDescriptions/EscapedMetaCharacter.html new file mode 100644 index 000000000000..183bf157ef70 --- /dev/null +++ b/RegExpSupport/src/inspectionDescriptions/EscapedMetaCharacter.html @@ -0,0 +1,12 @@ + + +Reports the escaped meta characters, e.g. \.. +Some RegExp coding styles specify that meta characters should be placed inside a character class, +to make the regular expression easier to understand. +For example the regex \d+\.\d+ would be written as \d+[.]\d+. +This inspection does not warn about the meta character [, ] and ^, +because those would need additional escaping inside a character class. + +

New in 2017.1 + + \ No newline at end of file diff --git a/RegExpSupport/src/org/intellij/lang/regexp/inspection/EscapedMetaCharacterInspection.java b/RegExpSupport/src/org/intellij/lang/regexp/inspection/EscapedMetaCharacterInspection.java new file mode 100644 index 000000000000..78f0d79f6594 --- /dev/null +++ b/RegExpSupport/src/org/intellij/lang/regexp/inspection/EscapedMetaCharacterInspection.java @@ -0,0 +1,115 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.intellij.lang.regexp.inspection; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.lang.ASTNode; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementVisitor; +import org.intellij.lang.regexp.RegExpTT; +import org.intellij.lang.regexp.psi.RegExpBranch; +import org.intellij.lang.regexp.psi.RegExpChar; +import org.intellij.lang.regexp.psi.RegExpElementVisitor; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +/** + * @author Bas Leijdekkers + */ +public class EscapedMetaCharacterInspection extends LocalInspectionTool { + + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new EscapedMetaCharacterVisitor(holder); + } + + private static class EscapedMetaCharacterVisitor extends RegExpElementVisitor { + + private final ProblemsHolder myHolder; + + public EscapedMetaCharacterVisitor(ProblemsHolder holder) { + myHolder = holder; + } + + @Override + public void visitRegExpChar(RegExpChar ch) { + if (ch.getType() != RegExpChar.Type.CHAR) { + return; + } + final String text = ch.getUnescapedText(); + if (text.length() != 2 || text.charAt(0) != '\\') { + return; + } + final char c = text.charAt(1); + switch (c) { + case '{': + case '}': + case '(': + case ')': + case '.': + case '*': + case '+': + case '?': + case '|': + case '$': + final ASTNode node = ch.getNode().getFirstChildNode(); + if (node != null && node.getElementType() == RegExpTT.REDUNDANT_ESCAPE) { + return; + } + myHolder.registerProblem(ch, "Escaped meta character " + c + "", new EscapedMetaCharacterFix(c)); + break; + } + } + } + + private static class EscapedMetaCharacterFix implements LocalQuickFix { + + private final char myC; + + EscapedMetaCharacterFix(char c) { + myC = c; + } + + @Nls + @NotNull + @Override + public String getName() { + return "Replace with '[" + myC + "]'"; + } + + @Nls + @NotNull + @Override + public String getFamilyName() { + return "Replace with character inside class"; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + final PsiElement element = descriptor.getPsiElement(); + if (!(element instanceof RegExpChar)) { + return; + } + final RegExpBranch branch = RegExpFactory.createBranchFromText("[" + myC + ']', element); + element.replace(branch.getFirstChild()); + } + } +} diff --git a/RegExpSupport/test/org/intellij/lang/regexp/inspection/EscapedMetaCharacterInspectionTest.java b/RegExpSupport/test/org/intellij/lang/regexp/inspection/EscapedMetaCharacterInspectionTest.java new file mode 100644 index 000000000000..ac69291ad304 --- /dev/null +++ b/RegExpSupport/test/org/intellij/lang/regexp/inspection/EscapedMetaCharacterInspectionTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.intellij.lang.regexp.inspection; + +import com.intellij.codeInspection.LocalInspectionTool; +import org.jetbrains.annotations.NotNull; + +/** + * @author Bas Leijdekkers + */ +public class EscapedMetaCharacterInspectionTest extends RegExpInspectionTestCase { + + public void testSimple() { + quickfixTest("\\.", "[.]", "Replace with '[.]'"); + } + + public void testNoWarn() { + highlightTest("\\[\\^\\]"); + } + + public void testHighlighting() { + highlightTest("\\{" + + "\\}" + // already has redundant character escape warning + "\\(" + + "\\)" + + "\\." + + "\\*" + + "\\+" + + "\\?" + + "\\|" + + "\\$"); + } + + @NotNull + @Override + protected LocalInspectionTool getInspection() { + return new EscapedMetaCharacterInspection(); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java index 9143d38890b7..52f48bc28bf4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java @@ -34,14 +34,14 @@ import com.sun.jdi.VMDisconnectedException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; /** * @author lex */ public class DebuggerManagerThreadImpl extends InvokeAndWaitThread implements DebuggerManagerThread, Disposable { private static final Logger LOG = Logger.getInstance(DebuggerManagerThreadImpl.class); - public static final int COMMAND_TIMEOUT = 3000; + static final int COMMAND_TIMEOUT = 3000; private volatile boolean myDisposed; @@ -55,6 +55,19 @@ public class DebuggerManagerThreadImpl extends InvokeAndWaitThread future) { + try { + LOG.debug("Waiting for " + future); + future.get(1, TimeUnit.MINUTES); + } + catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + catch (TimeoutException e) { + throw new RuntimeException("Termination request is still pending", e); + } + } + @TestOnly public static DebuggerManagerThreadImpl createTestInstance(@NotNull Disposable parent, Project project) { return new DebuggerManagerThreadImpl(parent, project); @@ -106,13 +119,13 @@ public class DebuggerManagerThreadImpl extends InvokeAndWaitThread future = AppExecutorUtil.getAppScheduledExecutorService().schedule( () -> { if (currentCommand == myEvents.getCurrentEvent()) { // if current command is still in progress, cancel it @@ -131,7 +144,10 @@ public class DebuggerManagerThreadImpl extends InvokeAndWaitThread waitForTerminateFutureToComplete(future)); } } @@ -174,7 +190,7 @@ public class DebuggerManagerThreadImpl extends InvokeAndWaitThread { + implements PersistentStateComponent { private final EventDispatcher myDispatcher = - EventDispatcher.create(InstancesTrackerListener.class); + EventDispatcher.create(InstancesTrackerListener.class); private MyState myState = new MyState(); public InstancesTracker(Project project) { @@ -84,7 +84,7 @@ public class InstancesTracker extends AbstractProjectComponent public void setBackgroundTackingEnabled(boolean state) { boolean oldState = myState.isBackgroundTrackingEnabled; - if(state != oldState) { + if (state != oldState) { myState.isBackgroundTrackingEnabled = state; myDispatcher.getMulticaster().backgroundTrackingValueChanged(state); } @@ -104,7 +104,6 @@ public class InstancesTracker extends AbstractProjectComponent static class MyState { boolean isBackgroundTrackingEnabled = false; - @NotNull @AbstractCollection(surroundWithTag = false, elementTypes = {Map.Entry.class}) final Map classes = new ConcurrentHashMap<>(); diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/component/MemoryViewComponent.java b/java/debugger/impl/src/com/intellij/debugger/memory/component/MemoryViewComponent.java index cc57dffe746e..fc9c91f31257 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/component/MemoryViewComponent.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/component/MemoryViewComponent.java @@ -51,13 +51,19 @@ public class MemoryViewComponent extends AbstractProjectComponent { @Override public void processStarted(@NotNull XDebugProcess debugProcess) { final XDebugSession session = debugProcess.getSession(); + final Project project = session.getProject(); final DebugProcess javaProcess = - DebuggerManager.getInstance(session.getProject()).getDebugProcess(debugProcess.getProcessHandler()); + DebuggerManager.getInstance(project).getDebugProcess(debugProcess.getProcessHandler()); if (javaProcess instanceof DebugProcessImpl) { final DebugProcessImpl processImpl = (DebugProcessImpl)javaProcess; ApplicationManager.getApplication().invokeLater(() -> { + if (project.isDisposed()) { + return; + } + + final InstancesTracker tracker = InstancesTracker.getInstance(project); final RunnerLayoutUi ui = session.getUI(); - final ClassesFilteredView classesFilteredView = new ClassesFilteredView(session, processImpl); + final ClassesFilteredView classesFilteredView = new ClassesFilteredView(session, processImpl, tracker); classesFilteredView.setActive(true); final Content memoryViewContent = ui.createContent(MEMORY_VIEW_CONTENT_ID, classesFilteredView, "Memory View", diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/tracking/ConstructorInstancesTracker.java b/java/debugger/impl/src/com/intellij/debugger/memory/tracking/ConstructorInstancesTracker.java index 0ba28d87c153..4899b1ee74fe 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/tracking/ConstructorInstancesTracker.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/tracking/ConstructorInstancesTracker.java @@ -69,16 +69,16 @@ public class ConstructorInstancesTracker implements TrackerForNewInstances, Disp private volatile boolean myIsBackgroundTrackingEnabled; public ConstructorInstancesTracker(@NotNull ReferenceType ref, - @NotNull XDebugSession debugSession) { + @NotNull XDebugSession debugSession, + @NotNull InstancesTracker instancesTracker) { myReference = ref; myProject = debugSession.getProject(); - myIsBackgroundTrackingEnabled = InstancesTracker.getInstance(myProject) - .isBackgroundTrackingEnabled(); + myIsBackgroundTrackingEnabled = instancesTracker.isBackgroundTrackingEnabled(); final DebugProcessImpl debugProcess = (DebugProcessImpl)DebuggerManager.getInstance(myProject) .getDebugProcess(debugSession.getDebugProcess().getProcessHandler()); - InstancesTracker.getInstance(myProject).addTrackerListener(new InstancesTrackerListener() { + instancesTracker.addTrackerListener(new InstancesTrackerListener() { @Override public void backgroundTrackingValueChanged(boolean newState) { if (myIsBackgroundTrackingEnabled != newState) { diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/ui/ClassesFilteredView.java b/java/debugger/impl/src/com/intellij/debugger/memory/ui/ClassesFilteredView.java index fa090419063a..08c03e639a5e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/ui/ClassesFilteredView.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/ui/ClassesFilteredView.java @@ -62,6 +62,7 @@ import javax.swing.event.DocumentEvent; import java.awt.*; import java.awt.event.*; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -104,12 +105,14 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable */ private boolean myIsActive; - public ClassesFilteredView(@NotNull XDebugSession debugSession, @NotNull DebugProcessImpl debugProcess) { + public ClassesFilteredView(@NotNull XDebugSession debugSession, + @NotNull DebugProcessImpl debugProcess, + @NotNull InstancesTracker tracker) { super(); myProject = debugSession.getProject(); - myInstancesTracker = InstancesTracker.getInstance(myProject); + myInstancesTracker = tracker; final InstancesTrackerListener instancesTrackerListener = new InstancesTrackerListener() { @Override public void classChanged(@NotNull String name, @NotNull TrackingType type) { @@ -147,7 +150,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable @Override protected void action() throws Exception { final boolean activated = myIsTrackersActivated.get(); - myInstancesTracker.getTrackedClasses().forEach((className, type) -> { + tracker.getTrackedClasses().forEach((className, type) -> { List classes = debugProcess.getVirtualMachineProxy().classesByName(className); if (classes.isEmpty()) { new ClassPreparedListener(className, debugSession) { @@ -164,14 +167,14 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable } }); - myInstancesTracker.addTrackerListener(instancesTrackerListener, ClassesFilteredView.this); + tracker.addTrackerListener(instancesTrackerListener, ClassesFilteredView.this); } }); final MemoryViewManagerState memoryViewManagerState = MemoryViewManager.getInstance().getState(); - myTable = new ClassesTable(debugSession, memoryViewManagerState.isShowWithDiffOnly, - memoryViewManagerState.isShowWithInstancesOnly, memoryViewManagerState.isShowTrackedOnly, this); + myTable = new ClassesTable(tracker, this, memoryViewManagerState.isShowWithDiffOnly, + memoryViewManagerState.isShowWithInstancesOnly, memoryViewManagerState.isShowTrackedOnly); myTable.getEmptyText().setText(EMPTY_TABLE_CONTENT_WHEN_RUNNING); Disposer.register(this, myTable); @@ -286,7 +289,7 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable return; } - final ConstructorInstancesTracker tracker = new ConstructorInstancesTracker(ref, debugSession); + final ConstructorInstancesTracker tracker = new ConstructorInstancesTracker(ref, debugSession, myInstancesTracker); tracker.setBackgroundMode(!myIsActive); if (isTrackerEnabled) { tracker.enable(); @@ -303,7 +306,10 @@ public class ClassesFilteredView extends BorderLayoutPanel implements Disposable private void handleClassSelection(@Nullable ReferenceType ref) { final XDebugSession debugSession = XDebuggerManager.getInstance(myProject).getCurrentSession(); if (ref != null && debugSession != null && debugSession.isSuspended()) { - new InstancesWindow(debugSession, limit -> ref.instances(limit), ref.name()).show(); + new InstancesWindow(debugSession, limit -> { + final List instances = ref.instances(limit); + return instances == null ? Collections.emptyList() : instances; + }, ref.name()).show(); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/ui/ClassesTable.java b/java/debugger/impl/src/com/intellij/debugger/memory/ui/ClassesTable.java index b363f7990fec..e024d4492c61 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/ui/ClassesTable.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/ui/ClassesTable.java @@ -37,7 +37,6 @@ import com.intellij.ui.table.JBTable; import com.intellij.util.containers.FList; import com.intellij.util.ui.JBDimension; import com.intellij.util.ui.JBUI; -import com.intellij.xdebugger.XDebugSession; import com.sun.jdi.ObjectReference; import com.sun.jdi.ReferenceType; import org.jetbrains.annotations.NonNls; @@ -79,14 +78,15 @@ public class ClassesTable extends JBTable implements DataProvider, Disposable { private volatile List myItems = Collections.unmodifiableList(new ArrayList<>()); - ClassesTable(@NotNull XDebugSession session, boolean onlyWithDiff, boolean onlyWithInstances, - boolean onlyTracked, @NotNull ClassesFilteredView parent) { + public ClassesTable(@NotNull InstancesTracker tracker, @NotNull ClassesFilteredView parent, boolean onlyWithDiff, + boolean onlyWithInstances, + boolean onlyTracked) { setModel(myModel); myOnlyWithDiff = onlyWithDiff; myOnlyWithInstances = onlyWithInstances; myOnlyTracked = onlyTracked; - myInstancesTracker = InstancesTracker.getInstance(session.getProject()); + myInstancesTracker = tracker; myParent = parent; TableColumn classesColumn = getColumnModel().getColumn(DiffViewTableModel.CLASSNAME_COLUMN_INDEX); diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/ui/InstancesWithStackFrameView.java b/java/debugger/impl/src/com/intellij/debugger/memory/ui/InstancesWithStackFrameView.java index 4fc5b098e06f..a04795139ca8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/ui/InstancesWithStackFrameView.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/ui/InstancesWithStackFrameView.java @@ -24,6 +24,7 @@ import com.intellij.debugger.memory.utils.StackFrameItem; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; import com.intellij.ui.JBSplitter; import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBScrollPane; @@ -49,9 +50,10 @@ class InstancesWithStackFrameView { private boolean myIsHided = false; InstancesWithStackFrameView(@NotNull XDebugSession debugSession, @NotNull InstancesTree tree, - @NotNull StackFrameList list, String className) { + @NotNull StackFrameList list, @NotNull String className) { mySplitter.setFirstComponent(new JBScrollPane(tree)); + final Project project = debugSession.getProject(); list.setEmptyText(EMPTY_TEXT_WHEN_ITEM_NOT_SELECTED); JLabel stackTraceLabel; if (isArrayType(className)) { @@ -63,8 +65,10 @@ class InstancesWithStackFrameView { new AnAction() { @Override public void actionPerformed(AnActionEvent e) { - InstancesTracker.getInstance(debugSession.getProject()) - .add(className, TrackingType.CREATION); + final Project project = e.getProject(); + if (project != null && !project.isDisposed()) { + InstancesTracker.getInstance(project).add(className, TrackingType.CREATION); + } } }); @@ -77,30 +81,32 @@ class InstancesWithStackFrameView { JComponent stackComponent = new JBScrollPane(list); - InstancesTracker instancesTracker = InstancesTracker.getInstance(debugSession.getProject()); - instancesTracker.addTrackerListener(new InstancesTrackerListener() { - @Override - public void classChanged(@NotNull String name, @NotNull TrackingType type) { - if (Objects.equals(className, name) && type == TrackingType.CREATION) { - mySplitter.setSecondComponent(stackComponent); + if (!project.isDisposed()) { + final InstancesTracker tracker = InstancesTracker.getInstance(project); + tracker.addTrackerListener(new InstancesTrackerListener() { + @Override + public void classChanged(@NotNull String name, @NotNull TrackingType type) { + if (Objects.equals(className, name) && type == TrackingType.CREATION) { + mySplitter.setSecondComponent(stackComponent); + } } - } - @Override - public void classRemoved(@NotNull String name) { - if (Objects.equals(name, className)) { - mySplitter.setSecondComponent(stackTraceLabel); + @Override + public void classRemoved(@NotNull String name) { + if (Objects.equals(name, className)) { + mySplitter.setSecondComponent(stackTraceLabel); + } } - } - }, tree); + }, tree); - mySplitter.setSecondComponent(instancesTracker.isTracked(className) ? stackComponent : stackTraceLabel); + mySplitter.setSecondComponent(tracker.isTracked(className) ? stackComponent : stackTraceLabel); + } mySplitter.setHonorComponentsMinimumSize(false); myHidedProportion = DEFAULT_SPLITTER_PROPORTION; final MemoryViewDebugProcessData data = - DebuggerManager.getInstance(debugSession.getProject()).getDebugProcess(debugSession.getDebugProcess().getProcessHandler()) + DebuggerManager.getInstance(project).getDebugProcess(debugSession.getDebugProcess().getProcessHandler()) .getUserData(MemoryViewDebugProcessData.KEY); tree.addTreeSelectionListener(e -> { ObjectReference ref = tree.getSelectedReference(); diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CaptureConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CaptureConfigurable.java index 9513b9691f6f..60a31c993ca8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/CaptureConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/CaptureConfigurable.java @@ -17,6 +17,7 @@ package com.intellij.debugger.settings; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.fileChooser.FileChooserFactory; @@ -31,8 +32,11 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileWrapper; import com.intellij.ui.*; import com.intellij.ui.table.JBTable; +import com.intellij.util.PlatformIcons; import com.intellij.util.ui.ItemRemovable; import com.intellij.util.xmlb.XmlSerializer; +import one.util.streamex.IntStreamEx; +import one.util.streamex.StreamEx; import org.jdom.Document; import org.jdom.Element; import org.jetbrains.annotations.Nls; @@ -48,6 +52,8 @@ import java.util.List; * @author egor */ public class CaptureConfigurable implements SearchableConfigurable { + private static final Logger LOG = Logger.getInstance(CaptureConfigurable.class); + private MyTableModel myTableModel; @NotNull @@ -93,6 +99,26 @@ public class CaptureConfigurable implements SearchableConfigurable { } }); + decorator.addExtraAction(new DumbAwareActionButton("Duplicate", "Duplicate", PlatformIcons.COPY_ICON) { + @Override + public boolean isEnabled() { + return table.getSelectedRowCount() == 1; + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + selectedCapturePoints(table).forEach(c -> { + try { + myTableModel.add(c.clone()); + table.getSelectionModel().setSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1); + } + catch (CloneNotSupportedException ex) { + LOG.error(ex); + } + }); + } + }); + decorator.addExtraAction(new DumbAwareActionButton("Import", "Import", AllIcons.Actions.Install) { @Override public void actionPerformed(@NotNull final AnActionEvent e) { @@ -136,16 +162,16 @@ public class CaptureConfigurable implements SearchableConfigurable { if (wrapper == null) return; Element rootElement = new Element("capture-points"); - for (int row : table.getSelectedRows()) { - CapturePoint c = myTableModel.get(table.convertRowIndexToModel(row)); + selectedCapturePoints(table).forEach(c -> { try { CapturePoint clone = c.clone(); clone.myEnabled = false; rootElement.addContent(XmlSerializer.serialize(clone)); } - catch (CloneNotSupportedException ignore) { + catch (CloneNotSupportedException ex) { + LOG.error(ex); } - } + }); try { JDOMUtil.writeDocument(new Document(rootElement), wrapper.getFile(), "\n"); } @@ -164,6 +190,10 @@ public class CaptureConfigurable implements SearchableConfigurable { return decorator.createPanel(); } + private StreamEx selectedCapturePoints(JBTable table) { + return IntStreamEx.of(table.getSelectedRows()).map(table::convertRowIndexToModel).mapToObj(myTableModel::get); + } + private static class MyTableModel extends AbstractTableModel implements ItemRemovable { public static final int ENABLED_COLUMN = 0; public static final int CLASS_COLUMN = 1; diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java index b2fbc479fd4a..99376e50e1ec 100644 --- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java +++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfiguration.java @@ -298,7 +298,7 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration> exports = CachedValuesManager.getCachedValue(source, () -> Result.create(exportsMap(source), source.getContainingFile())); Set targets = exports.get(packageName); - return targets != null && (targets.isEmpty() || targets.contains(target.getModuleName())); + return targets != null && (targets.isEmpty() || targets.contains(target.getName())); } public static boolean reads(@NotNull PsiJavaModule source, @NotNull PsiJavaModule destination) { @@ -178,7 +178,7 @@ public class JavaModuleGraphUtil { } public static String key(PsiJavaModule module, PsiJavaModule exporter) { - return module.getModuleName() + '/' + exporter.getModuleName(); + return module.getName() + '/' + exporter.getName(); } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java index 13625596af71..7f8030f7d531 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java @@ -223,13 +223,13 @@ public class ModuleHighlightUtil { return moduleResolveError(refElement, ref); } else if (target == container) { - String message = JavaErrorMessages.message("module.cyclic.dependence", container.getModuleName()); + String message = JavaErrorMessages.message("module.cyclic.dependence", container.getName()); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).description(message).create(); } else { Collection cycle = JavaModuleGraphUtil.findCycle((PsiJavaModule)target); if (cycle != null && cycle.contains(container)) { - Stream stream = cycle.stream().map(PsiJavaModule::getModuleName); + Stream stream = cycle.stream().map(PsiJavaModule::getName); if (ApplicationManager.getApplication().isUnitTestMode()) stream = stream.sorted(); String message = JavaErrorMessages.message("module.cyclic.dependence", stream.collect(Collectors.joining(", "))); return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).description(message).create(); @@ -373,8 +373,8 @@ public class ModuleHighlightUtil { return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).description(message).create(); } - String refModuleName = refModule.getModuleName(); - String requiredName = targetModule.getModuleName(); + String refModuleName = refModule.getName(); + String requiredName = targetModule.getName(); if (!(targetModule instanceof LightJavaModule || JavaModuleGraphUtil.exports(targetModule, packageName, refModule))) { String message = JavaErrorMessages.message("module.package.not.exported", requiredName, packageName, refModuleName); return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).description(message).create(); @@ -421,7 +421,7 @@ public class ModuleHighlightUtil { private static TextRange range(PsiJavaModule module) { PsiKeyword kw = PsiTreeUtil.getChildOfType(module, PsiKeyword.class); - return new TextRange(kw != null ? kw.getTextOffset() : module.getTextOffset(), module.getNameElement().getTextRange().getEndOffset()); + return new TextRange(kw != null ? kw.getTextOffset() : module.getTextOffset(), module.getNameIdentifier().getTextRange().getEndOffset()); } private static PsiElement range(PsiJavaCodeReferenceElement refElement) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddRequiredModuleFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddRequiredModuleFix.java index 27fce6ec163b..1f41b4ac15e1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddRequiredModuleFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddRequiredModuleFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,8 +66,7 @@ public class AddRequiredModuleFix implements IntentionAction { if (module == null) return; PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(project).getParserFacade(); - PsiJavaModule tempModule = - parserFacade.createModuleFromText("module " + module.getModuleName() + " { requires " + myRequiredName + "; }"); + PsiJavaModule tempModule = parserFacade.createModuleFromText("module " + module.getName() + " { requires " + myRequiredName + "; }"); Iterable tempModuleRequires = tempModule.getRequires(); PsiRequiresStatement requiresStatement = tempModuleRequires.iterator().next(); @@ -90,7 +89,7 @@ public class AddRequiredModuleFix implements IntentionAction { @Nullable private static PsiElement getLBrace(@NotNull PsiJavaModule module) { - PsiJavaModuleReferenceElement nameElement = module.getNameElement(); + PsiJavaModuleReferenceElement nameElement = module.getNameIdentifier(); for (PsiElement element = nameElement.getNextSibling(); element != null; element = element.getNextSibling()) { if (PsiUtil.isJavaToken(element, JavaTokenType.LBRACE)) { return element; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java index 29942e804e9d..46129774dc11 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ package com.intellij.codeInspection.dataFlow; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.NullableNotNullManager; +import com.intellij.codeInsight.PsiEquivalenceUtil; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpressionFix; import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix; @@ -48,12 +49,10 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.refactoring.extractMethod.ExtractMethodUtil; -import com.intellij.util.ArrayUtil; -import com.intellij.util.ArrayUtilRt; -import com.intellij.util.IncorrectOperationException; -import com.intellij.util.SmartList; +import com.intellij.util.*; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; +import com.siyeh.ig.psiutils.TypeUtils; import one.util.streamex.StreamEx; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -73,6 +72,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { public boolean REPORT_CONSTANT_REFERENCE_VALUES = true; public boolean REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER = true; public boolean REPORT_NULLABLE_METHODS_RETURNING_NOT_NULL = true; + public boolean REPORT_UNCHECKED_OPTIONALS = true; @Override public JComponent createOptionsPanel() { @@ -98,6 +98,9 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { if (!REPORT_NULLABLE_METHODS_RETURNING_NOT_NULL) { node.addContent(new Element("option").setAttribute("name", "REPORT_NULLABLE_METHODS_RETURNING_NOT_NULL").setAttribute("value", "false")); } + if (!REPORT_UNCHECKED_OPTIONALS) { + node.addContent(new Element("option").setAttribute("name", "REPORT_UNCHECKED_OPTIONALS").setAttribute("value", "false")); + } } @Override @@ -338,6 +341,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { reportOptionalOfNullableImprovements(holder, reportedAnchors, runner.getInstructions()); + reportUncheckedOptionalGet(holder, visitor.getOptionalCalls(), visitor.getOptionalQualifiers()); if (REPORT_CONSTANT_REFERENCE_VALUES) { reportConstantReferenceValues(holder, visitor, reportedAnchors); @@ -348,6 +352,36 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { } } + private void reportUncheckedOptionalGet(ProblemsHolder holder, + Map calls, + List qualifiers) { + for (Map.Entry entry : calls.entrySet()) { + ThreeState state = entry.getValue(); + if (state == ThreeState.YES || state == ThreeState.UNSURE && !REPORT_UNCHECKED_OPTIONALS) { + continue; + } + PsiMethodCallExpression call = entry.getKey(); + PsiMethod method = call.resolveMethod(); + if (method == null) continue; + PsiClass optionalClass = method.getContainingClass(); + if (optionalClass == null) continue; + if (state == ThreeState.NO) { + holder.registerProblem(getElementToHighlight(call), + InspectionsBundle.message("dataflow.message.optional.get.definitely.absent", optionalClass.getName())); + } else if (state == ThreeState.UNSURE) { + PsiExpression qualifier = PsiUtil.skipParenthesizedExprDown(call.getMethodExpression().getQualifierExpression()); + if (qualifier instanceof PsiMethodCallExpression && + qualifiers.stream().anyMatch(q -> PsiEquivalenceUtil.areElementsEquivalent(q, qualifier))) { + // Conservatively do not report methodCall().get() cases if methodCall().isPresent() was found in the same method + // without deep correspondence analysis + continue; + } + holder.registerProblem(getElementToHighlight(call), + InspectionsBundle.message("dataflow.message.optional.get.without.is.present", optionalClass.getName())); + } + } + } + private static void reportAlwaysReturnsNotNull(ProblemsHolder holder, PsiElement scope) { if (!(scope.getParent() instanceof PsiMethod)) return; @@ -895,6 +929,8 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { private final Map, StateInfo> myStateInfos = ContainerUtil.newHashMap(); private final Set myCCEInstructions = ContainerUtil.newHashSet(); private final Map myFailingCalls = new HashMap<>(); + private final Map myOptionalCalls = new HashMap<>(); + private final List myOptionalQualifiers = new ArrayList<>(); private boolean myAlwaysReturnsNotNull = true; @Override @@ -912,6 +948,14 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { }); } + Map getOptionalCalls() { + return myOptionalCalls; + } + + List getOptionalQualifiers() { + return myOptionalQualifiers; + } + Collection getAlwaysFailingCalls() { return StreamEx.ofKeys(myFailingCalls, v -> v).map(MethodCallInstruction::getCallExpression).toList(); } @@ -924,6 +968,20 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { public DfaInstructionState[] visitMethodCall(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { + PsiMethodCallExpression call = ObjectUtils.tryCast(instruction.getCallExpression(), PsiMethodCallExpression.class); + if (call != null) { + String methodName = call.getMethodExpression().getReferenceName(); + PsiExpression qualifier = PsiUtil.skipParenthesizedExprDown(call.getMethodExpression().getQualifierExpression()); + if (qualifier != null && TypeUtils.isOptional(qualifier.getType())) { + if ("isPresent".equals(methodName) && qualifier instanceof PsiMethodCallExpression) { + myOptionalQualifiers.add(qualifier); + } + else if (isOptionalGetMethodName(methodName)) { + ThreeState state = memState.checkOptional(memState.peek()); + myOptionalCalls.merge(call, state, (s1, s2) -> s1 == s2 ? s1 : ThreeState.UNSURE); + } + } + } DfaInstructionState[] states = super.visitMethodCall(instruction, runner, memState); if (hasNonTrivialFailingContracts(instruction)) { boolean allFail = Arrays.stream(states).allMatch(s -> s.getMemoryState().peek() == runner.getFactory().getConstFactory().getContractFail()); @@ -932,6 +990,10 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool { return states; } + private static boolean isOptionalGetMethodName(String name) { + return "get".equals(name) || "getAsDouble".equals(name) || "getAsInt".equals(name) || "getAsLong".equals(name); + } + private static boolean hasNonTrivialFailingContracts(MethodCallInstruction instruction) { List contracts = instruction.getContracts(); return !contracts.isEmpty() && contracts.stream().allMatch(DataFlowInstructionVisitor::isNonTrivialFailingContract); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java index 567161a3e08b..aa08cf6ebede 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ package com.intellij.codeInspection.dataFlow; import com.intellij.codeInspection.dataFlow.instructions.*; import com.intellij.codeInspection.dataFlow.value.DfaValueFactory; -import com.intellij.codeInspection.dataFlow.value.DfaVariableValue; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProgressManager; @@ -286,14 +285,14 @@ public class DataFlowRunner { for (PsiMethod method : nestedClass.getMethods()) { PsiCodeBlock body = method.getBody(); if (body != null) { - myNestedClosures.putValue(body, createClosureState(state)); + myNestedClosures.putValue(body, state.createClosureState()); } } for (PsiClassInitializer initializer : nestedClass.getInitializers()) { - myNestedClosures.putValue(initializer.getBody(), createClosureState(state)); + myNestedClosures.putValue(initializer.getBody(), state.createClosureState()); } for (PsiField field : nestedClass.getFields()) { - myNestedClosures.putValue(field, createClosureState(state)); + myNestedClosures.putValue(field, state.createClosureState()); } } @@ -301,7 +300,7 @@ public class DataFlowRunner { DfaMemoryState state = instructionState.getMemoryState(); PsiElement body = expr.getBody(); if (body != null) { - myNestedClosures.putValue(body, createClosureState(state)); + myNestedClosures.putValue(body, state.createClosureState()); } } @@ -359,16 +358,4 @@ public class DataFlowRunner { return Pair.create(trueSet, falseSet); } - - @NotNull - private static DfaMemoryStateImpl createClosureState(@NotNull DfaMemoryState memState) { - DfaMemoryStateImpl copy = (DfaMemoryStateImpl)memState.createCopy(); - copy.flushFields(); - Set vars = new HashSet<>(copy.getVariableStates().keySet()); - for (DfaVariableValue value : vars) { - copy.flushDependencies(value); - } - copy.emptyStack(); - return copy; - } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java index f78f66a45858..33997bbfdf07 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,6 +34,9 @@ public interface DfaMemoryState { @NotNull DfaMemoryState createCopy(); + @NotNull + DfaMemoryState createClosureState(); + DfaValue pop(); DfaValue peek(); void push(@NotNull DfaValue value); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java index e37f3130f3d9..e34694d07798 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java @@ -53,6 +53,8 @@ public class DfaMemoryStateImpl implements DfaMemoryState { // dfa value id -> indices in myEqClasses list of the classes which contain the id (or wrapped) private final TIntObjectHashMap myIdToEqClassesIndices; private final Stack myStack; + // Closures which correspond to the stack top (do not track other closures for now) + private final List myStackTopClosures = new ArrayList<>(); private final TLongHashSet myDistinctClasses; private final LinkedHashMap myVariableStates; private final Map myDefaultVariableStates; @@ -106,6 +108,24 @@ public class DfaMemoryStateImpl implements DfaMemoryState { return new DfaMemoryStateImpl(this); } + @NotNull + @Override + public DfaMemoryStateImpl createClosureState() { + DfaMemoryStateImpl copy = createCopy(); + copy.flushFields(); + Set vars = new HashSet<>(copy.getVariableStates().keySet()); + for (DfaVariableValue value : vars) { + copy.flushDependencies(value); + } + copy.emptyStack(); + myStackTopClosures.add(copy); + return copy; + } + + List getStackTopClosures() { + return new ArrayList<>(myStackTopClosures); + } + public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof DfaMemoryStateImpl)) return false; @@ -221,6 +241,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { @Override public DfaValue pop() { myCachedHash = null; + myStackTopClosures.clear(); return myStack.pop(); } @@ -232,12 +253,14 @@ public class DfaMemoryStateImpl implements DfaMemoryState { @Override public void push(@NotNull DfaValue value) { myCachedHash = null; + myStackTopClosures.clear(); myStack.push(value); } @Override public void emptyStack() { myCachedHash = null; + myStackTopClosures.clear(); while (!myStack.isEmpty() && !(myStack.peek() instanceof DfaControlTransferValue)) { myStack.pop(); } @@ -1116,7 +1139,7 @@ public class DfaMemoryStateImpl implements DfaMemoryState { @Override public boolean execute(int id, int[] set) { DfaValue value = myFactory.getValue(id); - s.append(value + " -> " + Arrays.toString(set) + ", "); + s.append(value).append(" -> ").append(Arrays.toString(set)).append(", "); return true; } }); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java index 5bad45e3d83c..6d0130b73580 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,6 +42,9 @@ import static com.intellij.psi.JavaTokenType.*; * @author peter */ public class StandardInstructionVisitor extends InstructionVisitor { + private static final Set OPTIONAL_METHOD_NAMES = + ContainerUtil.set("isPresent", "of", "ofNullable", "fromNullable", "empty", "absent", + "or", "orElseGet", "ifPresent", "map", "flatMap", "filter", "transform"); private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.StandardInstructionVisitor"); private static final Object ANY_VALUE = new Object(); private final Set myReachable = new THashSet<>(); @@ -180,13 +183,13 @@ public class StandardInstructionVisitor extends InstructionVisitor { @Override public DfaInstructionState[] visitMethodCall(final MethodCallInstruction instruction, final DataFlowRunner runner, final DfaMemoryState memState) { - DfaValue[] argValues = popCallArguments(instruction, runner, memState); - final DfaValue qualifier = popQualifier(instruction, runner, memState); - Set finalStates = ContainerUtil.newLinkedHashSet(); - finalStates.addAll(handleOptionalMethods(instruction, runner, memState, qualifier, argValues)); + finalStates.addAll(handleOptionalMethods(instruction, runner, memState)); if (finalStates.isEmpty()) { + DfaValue[] argValues = popCallArguments(instruction, runner, memState); + final DfaValue qualifier = popQualifier(instruction, runner, memState); + LinkedHashSet currentStates = ContainerUtil.newLinkedHashSet(memState); if (argValues != null) { for (MethodContract contract : instruction.getContracts()) { @@ -219,54 +222,63 @@ public class StandardInstructionVisitor extends InstructionVisitor { } @NotNull - private static List handleOptionalMethods(MethodCallInstruction instruction, - DataFlowRunner runner, - DfaMemoryState memState, - DfaValue qualifierValue, @Nullable DfaValue[] argValues) { + private List handleOptionalMethods(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { PsiMethodCallExpression call = ObjectUtils.tryCast(instruction.getCallExpression(), PsiMethodCallExpression.class); if (call == null) return Collections.emptyList(); String methodName = call.getMethodExpression().getReferenceName(); - if ("isPresent".equals(methodName)) { - PsiMethod method = call.resolveMethod(); - if (method != null && TypeUtils.isOptional(method.getContainingClass())) { - ThreeState state = memState.checkOptional(qualifierValue); + if (methodName == null || !OPTIONAL_METHOD_NAMES.contains(methodName)) return Collections.emptyList(); + PsiMethod method = call.resolveMethod(); + if (method == null || !TypeUtils.isOptional(method.getContainingClass())) return Collections.emptyList(); + List closures = ((DfaMemoryStateImpl)memState).getStackTopClosures(); + DfaValue[] argValues = popCallArguments(instruction, runner, memState); + final DfaValue qualifier = popQualifier(instruction, runner, memState); + switch (methodName) { + case "isPresent": { + ThreeState state = memState.checkOptional(qualifier); DfaConstValue.Factory constFactory = runner.getFactory().getConstFactory(); if (state == ThreeState.UNSURE) { DfaMemoryState falseState = memState.createCopy(); memState.push(constFactory.getTrue()); - memState.applyIsPresentCheck(true, qualifierValue); + memState.applyIsPresentCheck(true, qualifier); falseState.push(constFactory.getFalse()); - falseState.applyIsPresentCheck(false, qualifierValue); + falseState.applyIsPresentCheck(false, qualifier); return Arrays.asList(memState, falseState); } else { - DfaValue result = state == ThreeState.YES ? constFactory.getTrue() : constFactory.getFalse(); - memState.push(result); - return Collections.singletonList(memState); + memState.push(state == ThreeState.YES ? constFactory.getTrue() : constFactory.getFalse()); } + break; } - } - if ("of".equals(methodName)) { - PsiMethod method = call.resolveMethod(); - if (method != null && TypeUtils.isOptional(method.getContainingClass())) { - memState.push(runner.getFactory().getOptionalFactory().getOptional(true)); - return Collections.singletonList(memState); - } - } - if (DfaOptionalSupport.resolveOfNullable(call) != null) { - if (argValues != null && argValues.length == 1 && memState.isNotNull(argValues[0])) { - memState.push(runner.getFactory().getOptionalFactory().getOptional(true)); - return Collections.singletonList(memState); - } - } - if ("empty".equals(methodName) || "absent".equals(methodName)) { - PsiMethod method = call.resolveMethod(); - if (method != null && TypeUtils.isOptional(method.getContainingClass())) { + case "of": + case "ofNullable": + case "fromNullable": + if ("of".equals(methodName) || (argValues != null && argValues.length == 1 && memState.isNotNull(argValues[0]))) { + memState.push(runner.getFactory().getOptionalFactory().getOptional(true)); + } else { + memState.push(getMethodResultValue(instruction, qualifier, runner.getFactory())); + } + break; + case "empty": + case "absent": memState.push(runner.getFactory().getOptionalFactory().getOptional(false)); - return Collections.singletonList(memState); - } + break; + case "filter": + case "flatMap": + case "ifPresent": + case "map": + case "or": + case "orElseGet": + case "transform": + for (DfaMemoryState closure : closures) { + closure.applyIsPresentCheck(!methodName.startsWith("or"), qualifier); + } + memState.push(getMethodResultValue(instruction, qualifier, runner.getFactory())); + break; + default: + memState.push(getMethodResultValue(instruction, qualifier, runner.getFactory())); + break; } - return Collections.emptyList(); + return Collections.singletonList(memState); } @Nullable diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java index c78bfb149d6a..61e95a85876d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ */ package com.intellij.codeInspection.dataFlow.value; -public class DfaValue { +public abstract class DfaValue { private final int myID; protected final DfaValueFactory myFactory; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9ModuleExportsPackageToItselfInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9ModuleExportsPackageToItselfInspection.java index 0f21c0896fe2..e8629149d6d4 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9ModuleExportsPackageToItselfInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9ModuleExportsPackageToItselfInspection.java @@ -55,7 +55,7 @@ public class Java9ModuleExportsPackageToItselfInspection extends BaseJavaLocalIn super.visitExportsStatement(statement); PsiJavaModule javaModule = PsiTreeUtil.getParentOfType(statement, PsiJavaModule.class); if (javaModule != null) { - String moduleName = javaModule.getModuleName(); + String moduleName = javaModule.getName(); List referenceElements = ContainerUtil.newArrayList(statement.getModuleReferences()); for (PsiJavaModuleReferenceElement referenceElement : referenceElements) { if (moduleName.equals(referenceElement.getReferenceText())) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9RedundantRequiresStatementInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9RedundantRequiresStatementInspection.java index 4b986c7651ef..c758ca7427f4 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9RedundantRequiresStatementInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/java19modules/Java9RedundantRequiresStatementInspection.java @@ -173,7 +173,7 @@ public class Java9RedundantRequiresStatementInspection extends GlobalJavaBatchIn return StreamEx.of(transitiveModules) .filter(transitiveModule -> isReexported(currentModule, transitiveModule)) - .map(transitiveModule -> transitiveModule.getModuleName()) + .map(transitiveModule -> transitiveModule.getName()) .toSet(); } @@ -204,7 +204,7 @@ public class Java9RedundantRequiresStatementInspection extends GlobalJavaBatchIn PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(currentModule.getProject()).getParserFacade(); for (String dependencyName : reexportedDependencies) { PsiJavaModule tempModule = - parserFacade.createModuleFromText("module " + currentModule.getModuleName() + " { requires " + dependencyName + "; }"); + parserFacade.createModuleFromText("module " + currentModule.getName() + " { requires " + dependencyName + "; }"); Iterable tempModuleRequires = tempModule.getRequires(); PsiRequiresStatement requiresStatement = tempModuleRequires.iterator().next(); currentModule.addAfter(requiresStatement, addingPlace); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaModuleImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaModuleImpl.java index 25c23a6daf54..7ce412404b56 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaModuleImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaModuleImpl.java @@ -37,7 +37,7 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule { private List myRequiredModules; public RefJavaModuleImpl(@NotNull PsiJavaModule javaModule, @NotNull RefManagerImpl manager) { - super(javaModule.getModuleName(), javaModule, manager); + super(javaModule.getName(), javaModule, manager); myRefModule = manager.getRefModule(ModuleUtilCore.findModuleForPsiElement(javaModule)); } @@ -91,7 +91,7 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule { PsiJavaModule requiredModule = (PsiJavaModule)element; Map> packagesExportedByModule = getPackagesExportedByModule(requiredModule); if (myRequiredModules == null) myRequiredModules = new ArrayList<>(1); - myRequiredModules.add(new RequiredModule(requiredModule.getModuleName(), packagesExportedByModule, statement.isPublic())); + myRequiredModules.add(new RequiredModule(requiredModule.getName(), packagesExportedByModule, statement.isPublic())); } } } @@ -110,7 +110,7 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule { if (packageName != null && moduleElement instanceof PsiJavaModule) { List toModuleNames = myExportedPackageNames.get(packageName); if (toModuleNames == emptyList) myExportedPackageNames.put(packageName, toModuleNames = new ArrayList<>(1)); - toModuleNames.add(((PsiJavaModule)moduleElement).getModuleName()); + toModuleNames.add(((PsiJavaModule)moduleElement).getName()); } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaModuleCompletion.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaModuleCompletion.java index 4a216a3923c0..363bd2030287 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaModuleCompletion.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaModuleCompletion.java @@ -92,7 +92,7 @@ class JavaModuleCompletion { if (!(statement instanceof PsiJavaModule)) { PsiElement host = statement.getParent(); if (host instanceof PsiJavaModule) { - String hostName = ((PsiJavaModule)host).getModuleName(); + String hostName = ((PsiJavaModule)host).getName(); Project project = context.getProject(); JavaModuleNameIndex index = JavaModuleNameIndex.getInstance(); GlobalSearchScope scope = ProjectScope.getAllScope(project); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java index fc25b0cd595b..580244b0b882 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java @@ -324,7 +324,7 @@ public class MarkerType { return null; } - Comparator comparator = PsiClassListCellRenderer.INSTANCE.getComparator(); + Comparator comparator = new PsiClassListCellRenderer().getComparator(); Arrays.sort(subclasses, comparator); String start = DaemonBundle.message(aClass.isInterface() ? "interface.is.implemented.by.header" : "class.is.subclassed.by.header"); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java index e9eb75590573..65599ebc2921 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageBaseFix.java @@ -125,7 +125,7 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction { final Project project = firstClass.getProject(); final JList list = new JBList(classes); - PsiElementListCellRenderer renderer = PsiClassListCellRenderer.INSTANCE; + PsiElementListCellRenderer renderer = new PsiClassListCellRenderer(); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setCellRenderer(renderer); final PopupChooserBuilder builder = new PopupChooserBuilder(list); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateInnerClassFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateInnerClassFromUsageFix.java index 291d07a00a48..3e64d4761f28 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateInnerClassFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateInnerClassFromUsageFix.java @@ -109,7 +109,7 @@ public class CreateInnerClassFromUsageFix extends CreateClassFromUsageBaseFix { final Project project = classes[0].getProject(); final JList list = new JBList(classes); - PsiElementListCellRenderer renderer = PsiClassListCellRenderer.INSTANCE; + PsiElementListCellRenderer renderer = new PsiClassListCellRenderer(); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setCellRenderer(renderer); final PopupChooserBuilder builder = new PopupChooserBuilder(list); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java index dbfb5d678fc6..4aa4d023d1e4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/PullAsAbstractUpFix.java @@ -99,7 +99,7 @@ public class PullAsAbstractUpFix extends LocalQuickFixAndIntentionActionOnPsiEle pullUp(method, containingClass, classesToPullUp.iterator().next()); } else if (editor != null) { - NavigationUtil.getPsiElementPopup(classesToPullUp.toArray(new PsiClass[classesToPullUp.size()]), PsiClassListCellRenderer.INSTANCE, + NavigationUtil.getPsiElementPopup(classesToPullUp.toArray(new PsiClass[classesToPullUp.size()]), new PsiClassListCellRenderer(), "Choose super class", new PsiElementProcessor() { @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/highlighting/ChooseClassAndDoHighlightRunnable.java b/java/java-impl/src/com/intellij/codeInsight/highlighting/ChooseClassAndDoHighlightRunnable.java index 5bba2cdf80bf..419414d442fa 100644 --- a/java/java-impl/src/com/intellij/codeInsight/highlighting/ChooseClassAndDoHighlightRunnable.java +++ b/java/java-impl/src/com/intellij/codeInsight/highlighting/ChooseClassAndDoHighlightRunnable.java @@ -44,6 +44,6 @@ public abstract class ChooseClassAndDoHighlightRunnable extends ChooseOneOrAllRu @Override protected PsiElementListCellRenderer createRenderer() { - return PsiClassListCellRenderer.INSTANCE; + return new PsiClassListCellRenderer(); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java b/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java index a7c8780f95f3..0385c79a4313 100644 --- a/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java @@ -28,6 +28,7 @@ import com.intellij.psi.*; import com.intellij.psi.impl.FindSuperElementsHelper; import com.intellij.psi.presentation.java.SymbolPresentationUtil; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -62,7 +63,7 @@ public class ShowSiblingsAction extends ShowImplementationsAction { final boolean isMethod = superElements[0] instanceof PsiMethod; NavigatablePsiElement[] navigatablePsiElements = ContainerUtil.findAllAsArray(superElements, NavigatablePsiElement.class); final JBPopup popup = PsiElementListNavigator.navigateOrCreatePopup(navigatablePsiElements, "Choose super " + (isMethod ? "method" : "class or interface"), "Super " + (isMethod ? "methods" : "classes/interfaces"), - isMethod ? new MethodCellRenderer(false) : PsiClassListCellRenderer.INSTANCE, null, + isMethod ? new MethodCellRenderer(false) : new PsiClassListCellRenderer(), null, objects -> showSiblings(invokedByShortcut, project, editor, file, editor != null, (PsiElement)objects[0])); if (popup != null) { if (editor != null) { diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ImplementAbstractMethodHandler.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ImplementAbstractMethodHandler.java index 46851f0fc1a5..960db5832fc4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ImplementAbstractMethodHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ImplementAbstractMethodHandler.java @@ -178,9 +178,10 @@ public class ImplementAbstractMethodHandler { } private static class MyPsiElementListCellRenderer extends PsiElementListCellRenderer { + private final PsiClassListCellRenderer myRenderer = new PsiClassListCellRenderer(); void sort(PsiElement[] result) { - final Comparator comparator = PsiClassListCellRenderer.INSTANCE.getComparator(); + final Comparator comparator = myRenderer.getComparator(); Arrays.sort(result, (o1, o2) -> { if (o1 instanceof PsiEnumConstant && o2 instanceof PsiEnumConstant) { return ((PsiEnumConstant)o1).getName().compareTo(((PsiEnumConstant)o2).getName()); @@ -193,7 +194,7 @@ public class ImplementAbstractMethodHandler { @Override public String getElementText(PsiElement element) { - return element instanceof PsiClass ? PsiClassListCellRenderer.INSTANCE.getElementText((PsiClass)element) + return element instanceof PsiClass ? myRenderer.getElementText((PsiClass)element) : ((PsiEnumConstant)element).getName(); } diff --git a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index 2f65188e2b87..1442af2ce1b5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -729,7 +729,7 @@ public class JavaDocInfoGenerator { private void generateModuleJavaDoc(StringBuilder buffer, PsiJavaModule module, boolean generatePrologueAndEpilogue) { if (generatePrologueAndEpilogue) generatePrologue(buffer); - buffer.append("

module ").append(module.getModuleName()).append("
"); + buffer.append("
module ").append(module.getName()).append("
"); PsiDocComment comment = module.getDocComment(); if (comment != null) { diff --git a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoTargetRendererProvider.java b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoTargetRendererProvider.java index 8b133fe38d85..6bf0a7fe4172 100644 --- a/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoTargetRendererProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/navigation/JavaGotoTargetRendererProvider.java @@ -35,7 +35,7 @@ public class JavaGotoTargetRendererProvider implements GotoTargetRendererProvide return new MethodCellRenderer(gotoData.hasDifferentNames()); } else if (element instanceof PsiClass) { - return PsiClassListCellRenderer.INSTANCE; + return new PsiClassListCellRenderer(); } else if (element instanceof PsiFunctionalExpression) { return new PsiClassOrFunctionalExpressionListCellRenderer(); diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java index 901d43106b8a..8a102e458e5a 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java @@ -76,6 +76,7 @@ public class DataFlowInspection extends DataFlowInspectionBase { private final JCheckBox myTreatUnknownMembersAsNullable; private final JCheckBox myReportNullArguments; private final JCheckBox myReportNullableMethodsReturningNotNull; + private final JCheckBox myReportUncheckedOptionals; private OptionsPanel() { super(new GridBagLayout()); @@ -151,6 +152,15 @@ public class DataFlowInspection extends DataFlowInspectionBase { } }); + myReportUncheckedOptionals = new JCheckBox("Report Optional.get() calls without previous isPresent check"); + myReportUncheckedOptionals.setSelected(REPORT_UNCHECKED_OPTIONALS); + myReportUncheckedOptionals.getModel().addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + REPORT_UNCHECKED_OPTIONALS = myReportUncheckedOptionals.isSelected(); + } + }); + gc.insets = JBUI.emptyInsets(); gc.gridy = 0; add(mySuggestNullables, gc); @@ -182,6 +192,9 @@ public class DataFlowInspection extends DataFlowInspectionBase { gc.gridy++; add(myReportNullableMethodsReturningNotNull, gc); + + gc.gridy++; + add(myReportUncheckedOptionals, gc); } } diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocHtmlLintAnnotator.kt b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocHtmlLintAnnotator.kt index 066db18f3ad7..8c534ddaef10 100644 --- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocHtmlLintAnnotator.kt +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocHtmlLintAnnotator.kt @@ -38,7 +38,6 @@ import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.pom.java.LanguageLevel -import com.intellij.profile.codeInspection.InspectionProjectProfileManager import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.PsiJavaFile @@ -47,15 +46,17 @@ import com.intellij.psi.util.PsiTreeUtil import com.sun.tools.doclint.DocLint import java.io.File -class JavadocHtmlLintAnnotator(private val manual: Boolean = false) : +class JavadocHtmlLintAnnotator() : ExternalAnnotator() { data class Info(val file: PsiFile) data class Anno(val row: Int, val col: Int, val error: Boolean, val message: String) data class Result(val annotations: List) + override fun getPairedBatchInspectionShortName() = JavadocHtmlLintInspection.SHORT_NAME + override fun collectInformation(file: PsiFile): Info? = - if (isJava8SourceFile(file) && "/**" in file.text && isToolEnabled(file)) Info(file) else null + if (isJava8SourceFile(file) && "/**" in file.text) Info(file) else null override fun doAnnotate(collectedInfo: Info): Result? { val file = collectedInfo.file.virtualFile!! @@ -122,9 +123,6 @@ class JavadocHtmlLintAnnotator(private val manual: Boolean = false) : file is PsiJavaFile && file.languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && file.virtualFile != null && ProjectFileIndex.SERVICE.getInstance(file.project).isInSourceContent(file.virtualFile) - private fun isToolEnabled(file: PsiFile) = - manual || InspectionProjectProfileManager.getInstance(file.project).currentProfile.isToolEnabled(key.value, file) - private fun createTempFile(bytes: ByteArray): File { val tempFile = FileUtil.createTempFile(File(PathManager.getTempPath()), "javadocHtmlLint", ".java") tempFile.writeBytes(bytes) diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocHtmlLintInspection.kt b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocHtmlLintInspection.kt index 4663c136a8f1..a174ec94b592 100644 --- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocHtmlLintInspection.kt +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocHtmlLintInspection.kt @@ -15,23 +15,15 @@ */ package com.intellij.codeInspection.javaDoc -import com.intellij.codeInspection.ExternalAnnotatorInspectionVisitor import com.intellij.codeInspection.LocalInspectionTool -import com.intellij.codeInspection.ProblemsHolder import com.intellij.codeInspection.SuppressQuickFix -import com.intellij.codeInspection.ex.PairedUnfairLocalInspectionTool +import com.intellij.codeInspection.ex.ExternalAnnotatorBatchInspection import com.intellij.psi.PsiElement -class JavadocHtmlLintInspection : LocalInspectionTool(), PairedUnfairLocalInspectionTool { +class JavadocHtmlLintInspection : LocalInspectionTool(), ExternalAnnotatorBatchInspection { companion object { val SHORT_NAME = "JavadocHtmlLint" } - private val annotator = lazy { JavadocHtmlLintAnnotator(true) } - - override fun buildVisitor(holder: ProblemsHolder, onTheFly: Boolean) = ExternalAnnotatorInspectionVisitor(holder, annotator.value, onTheFly) - override fun getBatchSuppressActions(element: PsiElement?) = SuppressQuickFix.EMPTY_ARRAY - - override fun getInspectionForBatchShortName() = SHORT_NAME } \ No newline at end of file diff --git a/java/java-impl/src/com/intellij/codeInspection/streamMigration/TerminalBlock.java b/java/java-impl/src/com/intellij/codeInspection/streamMigration/TerminalBlock.java index 546d95a8795e..326102070a43 100644 --- a/java/java-impl/src/com/intellij/codeInspection/streamMigration/TerminalBlock.java +++ b/java/java-impl/src/com/intellij/codeInspection/streamMigration/TerminalBlock.java @@ -59,7 +59,8 @@ class TerminalBlock { if(statements.length == 1 && statements[0] instanceof PsiBlockStatement) { statements = ((PsiBlockStatement)statements[0]).getCodeBlock().getStatements(); } else if(statements.length == 1 && statements[0] instanceof PsiLabeledStatement) { - statements = new PsiStatement[] {((PsiLabeledStatement)statements[0]).getStatement()}; + PsiStatement statement = ((PsiLabeledStatement)statements[0]).getStatement(); + statements = statement == null ? PsiStatement.EMPTY_ARRAY : new PsiStatement[] {statement}; } else break; } myStatements = statements; diff --git a/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java b/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java index d0e9d102cbd1..ffff324f2850 100644 --- a/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java +++ b/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -66,7 +66,7 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider { } if (element instanceof PsiJavaModule) { - return ((PsiJavaModule)element).getModuleName(); + return ((PsiJavaModule)element).getName(); } if (element instanceof PsiJavaModuleReferenceElement) { @@ -74,7 +74,7 @@ public class JavaQualifiedNameProvider implements QualifiedNameProvider { if (reference != null) { PsiElement target = reference.resolve(); if (target instanceof PsiJavaModule) { - return ((PsiJavaModule)target).getModuleName(); + return ((PsiJavaModule)target).getName(); } } } diff --git a/java/java-impl/src/com/intellij/ide/util/MethodCellRenderer.java b/java/java-impl/src/com/intellij/ide/util/MethodCellRenderer.java index 10a140bec5a4..72fcbda6979c 100644 --- a/java/java-impl/src/com/intellij/ide/util/MethodCellRenderer.java +++ b/java/java-impl/src/com/intellij/ide/util/MethodCellRenderer.java @@ -23,6 +23,7 @@ import javax.swing.*; public class MethodCellRenderer extends PsiElementListCellRenderer{ private final boolean myShowMethodNames; + private final PsiClassListCellRenderer myClassListCellRenderer = new PsiClassListCellRenderer(); @PsiFormatUtil.FormatMethodOptions private final int myOptions; @@ -36,7 +37,7 @@ public class MethodCellRenderer extends PsiElementListCellRenderer{ public String getElementText(PsiMethod element) { final PsiNamedElement container = fetchContainer(element); - String text = container instanceof PsiClass ? PsiClassListCellRenderer.INSTANCE.getElementText((PsiClass)container) : container.getName(); + String text = container instanceof PsiClass ? myClassListCellRenderer.getElementText((PsiClass)container) : container.getName(); if (myShowMethodNames) { text += "."+PsiFormatUtil.formatMethod(element, PsiSubstitutor.EMPTY, myOptions, PsiFormatUtilBase.SHOW_TYPE); } @@ -57,6 +58,6 @@ public class MethodCellRenderer extends PsiElementListCellRenderer{ } public int getIconFlags() { - return PsiClassListCellRenderer.INSTANCE.getIconFlags(); + return myClassListCellRenderer.getIconFlags(); } } diff --git a/java/java-impl/src/com/intellij/ide/util/MethodOrFunctionalExpressionCellRenderer.java b/java/java-impl/src/com/intellij/ide/util/MethodOrFunctionalExpressionCellRenderer.java index 6b298e6c04a0..4c4020a6c33f 100644 --- a/java/java-impl/src/com/intellij/ide/util/MethodOrFunctionalExpressionCellRenderer.java +++ b/java/java-impl/src/com/intellij/ide/util/MethodOrFunctionalExpressionCellRenderer.java @@ -26,6 +26,7 @@ import com.intellij.psi.util.PsiFormatUtilBase; import javax.swing.*; public class MethodOrFunctionalExpressionCellRenderer extends PsiElementListCellRenderer { + private final PsiClassListCellRenderer myClassListCellRenderer = new PsiClassListCellRenderer(); private final MethodCellRenderer myMethodCellRenderer; public MethodOrFunctionalExpressionCellRenderer(boolean showMethodNames) { @@ -50,6 +51,6 @@ public class MethodOrFunctionalExpressionCellRenderer extends PsiElementListCell } public int getIconFlags() { - return PsiClassListCellRenderer.INSTANCE.getIconFlags(); + return myClassListCellRenderer.getIconFlags(); } } diff --git a/java/java-impl/src/com/intellij/ide/util/PsiClassListCellRenderer.java b/java/java-impl/src/com/intellij/ide/util/PsiClassListCellRenderer.java index 76260aefe4f6..22fb5eda7daa 100644 --- a/java/java-impl/src/com/intellij/ide/util/PsiClassListCellRenderer.java +++ b/java/java-impl/src/com/intellij/ide/util/PsiClassListCellRenderer.java @@ -20,6 +20,10 @@ import com.intellij.psi.presentation.java.ClassPresentationUtil; import org.jetbrains.annotations.Nullable; public class PsiClassListCellRenderer extends PsiElementListCellRenderer { + /** + * Should not be used, as it can result in memory leaks + */ + @Deprecated public static final PsiClassListCellRenderer INSTANCE = new PsiClassListCellRenderer(); @Override diff --git a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java index ab4061cef53e..73baaf5f8fbd 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaDocumentationProvider.java @@ -384,7 +384,7 @@ public class JavaDocumentationProvider extends DocumentationProviderEx implement VirtualFile file = PsiImplUtil.getModuleVirtualFile(module); generateOrderEntryInfo(sb, file, module.getProject()); - sb.append(LangBundle.message("java.terms.module")).append(' ').append(module.getModuleName()); + sb.append(LangBundle.message("java.terms.module")).append(' ').append(module.getName()); return sb.toString(); } diff --git a/java/java-impl/src/com/intellij/lang/java/JavaFindUsagesProvider.java b/java/java-impl/src/com/intellij/lang/java/JavaFindUsagesProvider.java index 84951dce2bcd..933b5ad5369d 100644 --- a/java/java-impl/src/com/intellij/lang/java/JavaFindUsagesProvider.java +++ b/java/java-impl/src/com/intellij/lang/java/JavaFindUsagesProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -194,7 +194,7 @@ public class JavaFindUsagesProvider implements FindUsagesProvider { return element.getText(); } if (element instanceof PsiJavaModule) { - return ((PsiJavaModule)element).getModuleName(); + return ((PsiJavaModule)element).getName(); } return ""; diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java index f5c39ee75d24..588aff781120 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java @@ -1529,7 +1529,7 @@ public class ExtractMethodProcessor implements MatchProvider { if (classes.size() > 1) { final PsiClass[] psiClasses = classes.keySet().toArray(new PsiClass[classes.size()]); final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes.keySet(), psiClasses[0]); - NavigationUtil.getPsiElementPopup(psiClasses, PsiClassListCellRenderer.INSTANCE, "Choose Destination Class", processor, preselection) + NavigationUtil.getPsiElementPopup(psiClasses, new PsiClassListCellRenderer(), "Choose Destination Class", processor, preselection) .showInBestPositionFor(myEditor); return true; } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java index e2dcd2fddfee..a9d2f934cab9 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -134,7 +134,7 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase } else if (!classes.isEmpty()){ PsiClass selection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, myParentClass); - NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), PsiClassListCellRenderer.INSTANCE, + NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor() { @Override diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java index d40e6681a2e0..dac9b3a81954 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/LocalToFieldHandler.java @@ -94,7 +94,7 @@ public abstract class LocalToFieldHandler { final boolean isStatic = tempIsStatic; final PsiClass firstClass = classes.get(0); final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, firstClass); - NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), PsiClassListCellRenderer.INSTANCE, "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor() { + NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor() { @Override public boolean execute(@NotNull PsiClass aClass) { AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, aClass); diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index 8e35192ce418..9cbb79d2cf0d 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -586,7 +586,7 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase { final PsiType returnType = emptyMethod.getReturnType(); LOG.assertTrue(returnType != null); final String title = "Choose Applicable Functional Interface: " + methodSignature + " -> " + returnType.getPresentableText(); - NavigationUtil.getPsiElementPopup(psiClasses, PsiClassListCellRenderer.INSTANCE, title, + NavigationUtil.getPsiElementPopup(psiClasses, new PsiClassListCellRenderer(), title, new PsiElementProcessor() { @Override public boolean execute(@NotNull PsiClass psiClass) { diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/GenerateMissedTestsAction.java b/java/java-impl/src/com/intellij/testIntegration/createTest/GenerateMissedTestsAction.java index 34848382a06c..bad914cb1451 100644 --- a/java/java-impl/src/com/intellij/testIntegration/createTest/GenerateMissedTestsAction.java +++ b/java/java-impl/src/com/intellij/testIntegration/createTest/GenerateMissedTestsAction.java @@ -85,7 +85,7 @@ public class GenerateMissedTestsAction extends PsiElementBaseIntentionAction { } final JBList list = new JBList(testClasses); - list.setCellRenderer(PsiClassListCellRenderer.INSTANCE); + list.setCellRenderer(new PsiClassListCellRenderer()); JBPopupFactory.getInstance().createListPopupBuilder(list) .setItemChoosenCallback(() -> generateMissedTests((PsiClass)list.getSelectedValue(), srcClass, editor)) .setTitle("Choose Test") diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java index 67c7ec7ff2f5..56741435f18d 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java @@ -22,14 +22,14 @@ import org.jetbrains.annotations.NotNull; * * @since 2016.3 */ -public interface PsiJavaModule extends NavigatablePsiElement, PsiNamedElement, PsiJavaDocumentedElement { +public interface PsiJavaModule extends NavigatablePsiElement, PsiNameIdentifierOwner, PsiJavaDocumentedElement { String MODULE_INFO_CLASS = "module-info"; String MODULE_INFO_FILE = MODULE_INFO_CLASS + ".java"; String MODULE_INFO_CLS_FILE = MODULE_INFO_CLASS + ".class"; String JAVA_BASE = "java.base"; - @NotNull PsiJavaModuleReferenceElement getNameElement(); - @NotNull String getModuleName(); + @Override @NotNull PsiJavaModuleReferenceElement getNameIdentifier(); + @Override @NotNull String getName(); @NotNull Iterable getRequires(); @NotNull Iterable getExports(); diff --git a/java/java-psi-api/src/com/intellij/psi/PsiModifier.java b/java/java-psi-api/src/com/intellij/psi/PsiModifier.java index 4d59a6c9b23d..c0e7a86495a5 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiModifier.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiModifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,27 +16,26 @@ package com.intellij.psi; import org.intellij.lang.annotations.MagicConstant; -import org.jetbrains.annotations.NonNls; /** * Provides a list of possible modifier keywords for Java classes, methods and fields. */ public interface PsiModifier { - @NonNls String PUBLIC = "public"; - @NonNls String PROTECTED = "protected"; - @NonNls String PRIVATE = "private"; - @NonNls String PACKAGE_LOCAL = "packageLocal"; - @NonNls String STATIC = "static"; - @NonNls String ABSTRACT = "abstract"; - @NonNls String FINAL = "final"; - @NonNls String NATIVE = "native"; - @NonNls String SYNCHRONIZED = "synchronized"; - @NonNls String STRICTFP = "strictfp"; - @NonNls String TRANSIENT = "transient"; - @NonNls String VOLATILE = "volatile"; - @NonNls String DEFAULT = "default"; + String PUBLIC = "public"; + String PROTECTED = "protected"; + String PRIVATE = "private"; + String PACKAGE_LOCAL = "packageLocal"; + String STATIC = "static"; + String ABSTRACT = "abstract"; + String FINAL = "final"; + String NATIVE = "native"; + String SYNCHRONIZED = "synchronized"; + String STRICTFP = "strictfp"; + String TRANSIENT = "transient"; + String VOLATILE = "volatile"; + String DEFAULT = "default"; - @NonNls String[] MODIFIERS = { + String[] MODIFIERS = { PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT }; @@ -44,4 +43,4 @@ public interface PsiModifier { PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT, PACKAGE_LOCAL }) @interface ModifierConstant { } -} +} \ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java b/java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java index d84025793fc1..569f86691a9c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java +++ b/java/java-psi-impl/src/com/intellij/psi/NonClasspathClassFinder.java @@ -18,6 +18,7 @@ package com.intellij.psi; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.impl.PackageDirectoryCache; +import com.intellij.openapi.util.LowMemoryWatcher; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -52,7 +53,7 @@ public abstract class NonClasspathClassFinder extends PsiElementFinder { private final PsiManager myManager; private final String[] myFileExtensions; - public NonClasspathClassFinder(Project project, String... fileExtensions) { + public NonClasspathClassFinder(@NotNull Project project, @NotNull String... fileExtensions) { myProject = project; myManager = PsiManager.getInstance(myProject); myFileExtensions = ArrayUtil.append(fileExtensions, "class"); @@ -63,6 +64,12 @@ public abstract class NonClasspathClassFinder extends PsiElementFinder { clearCache(); } }); + LowMemoryWatcher.register(new Runnable() { + @Override + public void run() { + clearCache(); + } + }, project); } @NotNull diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java b/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java index 6b634abca4ef..0cf597853b75 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/ConstantExpressionVisitor.java @@ -483,9 +483,12 @@ class ConstantExpressionVisitor extends JavaElementVisitor implements PsiConstan else if (tokenType == JavaTokenType.TILDE) { if (operandValue instanceof Character) operandValue = Integer.valueOf(((Character)operandValue).charValue()); if (isIntegral(operandValue)) { - value = operandValue instanceof Long - ? Long.valueOf(~((Number)operandValue).longValue()) - : Integer.valueOf(~((Number)operandValue).intValue()); + if (operandValue instanceof Long) { + value = Long.valueOf(~((Number)operandValue).longValue()); + } + else { + value = Integer.valueOf(~((Number)operandValue).intValue()); + } } } else if (tokenType == JavaTokenType.EXCL) { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java index d938d7a2743a..d262db6e0d75 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -370,7 +370,6 @@ public class ClsFileImpl extends ClsRepositoryPsiElement } return CachedValuesManager.getCachedValue(this, new CachedValueProvider() { - @Nullable @Override public Result compute() { PsiElement target = JavaPsiImplementationHelper.getInstance(getProject()).getClsFileNavigationElement(ClsFileImpl.this); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaModuleImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaModuleImpl.java index b93b2b03384a..b0d3ade10e88 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaModuleImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaModuleImpl.java @@ -41,18 +41,6 @@ public class ClsJavaModuleImpl extends ClsRepositoryPsiElement getRequires() { @@ -85,7 +73,7 @@ public class ClsJavaModuleImpl extends ClsRepositoryPsiElement getRequires() { @@ -97,9 +85,16 @@ public class LightJavaModule extends LightElement implements PsiJavaModule { return Collections.emptyList(); } + @NotNull + @Override + public PsiJavaModuleReferenceElement getNameIdentifier() { + return myRefElement; + } + + @NotNull @Override public String getName() { - return getModuleName(); + return myRefElement.getReferenceText(); } @Override @@ -125,12 +120,12 @@ public class LightJavaModule extends LightElement implements PsiJavaModule { @Override public int hashCode() { - return getModuleName().hashCode() * 31 + getManager().hashCode(); + return getName().hashCode() * 31 + getManager().hashCode(); } @Override public String toString() { - return "PsiJavaModule:" + getModuleName(); + return "PsiJavaModule:" + getName(); } private static class LightJavaModuleReferenceElement extends LightElement implements PsiJavaModuleReferenceElement { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java index fafc6311bdfe..4f25c9f6ac80 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java @@ -54,24 +54,6 @@ public class PsiJavaModuleImpl extends JavaStubPsiElement imp super(node); } - @NotNull - @Override - public PsiJavaModuleReferenceElement getNameElement() { - return PsiTreeUtil.getRequiredChildOfType(this, PsiJavaModuleReferenceElement.class); - } - - @NotNull - @Override - public String getModuleName() { - PsiJavaModuleStub stub = getGreenStub(); - if (stub != null) { - return stub.getName(); - } - else { - return getNameElement().getReferenceText(); - } - } - @NotNull @Override public Iterable getRequires() { @@ -120,16 +102,29 @@ public class PsiJavaModuleImpl extends JavaStubPsiElement imp return psiTraverser().children(this).filter(PsiProvidesStatement.class); } + @NotNull + @Override + public PsiJavaModuleReferenceElement getNameIdentifier() { + return PsiTreeUtil.getRequiredChildOfType(this, PsiJavaModuleReferenceElement.class); + } + + @NotNull @Override public String getName() { - return getModuleName(); + PsiJavaModuleStub stub = getGreenStub(); + if (stub != null) { + return stub.getName(); + } + else { + return getNameIdentifier().getReferenceText(); + } } @Override public PsiElement setName(@NotNull String name) throws IncorrectOperationException { PsiElementFactory factory = PsiElementFactory.SERVICE.getInstance(getProject()); - PsiJavaModuleReferenceElement newName = factory.createModuleFromText("module " + name + " {}").getNameElement(); - getNameElement().replace(newName); + PsiJavaModuleReferenceElement newName = factory.createModuleFromText("module " + name + " {}").getNameIdentifier(); + getNameIdentifier().replace(newName); return this; } @@ -147,7 +142,7 @@ public class PsiJavaModuleImpl extends JavaStubPsiElement imp @NotNull @Override public PsiElement getNavigationElement() { - return getNameElement(); + return getNameIdentifier(); } @Override @@ -162,6 +157,6 @@ public class PsiJavaModuleImpl extends JavaStubPsiElement imp @Override public String toString() { - return "PsiJavaModule:" + getModuleName(); + return "PsiJavaModule:" + getName(); } } \ No newline at end of file diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleReference.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleReference.java index b8d7772baa70..95d606d4dbef 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleReference.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleReference.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -67,7 +67,7 @@ public class PsiJavaModuleReference extends PsiReferenceBase.Poly gammaBuilder) { + a(Test::c, name -> gammaBuilder); + } + + + private static > void a(final Function f1, + final Function f2) { + + } + + private static String c(final Builder builder) { + return ""; + } + + static class Alfa {} + private static class Beta extends Alfa {} + + static class Builder {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeIncompleteLabel.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeIncompleteLabel.java new file mode 100644 index 000000000000..59552d348464 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/streamApiMigration/beforeIncompleteLabel.java @@ -0,0 +1,11 @@ +// "Fix all 'Loop can be collapsed with Stream API' problems in file" "false" + +import java.util.List; + +public class Main { + void test(List list) { + for(String l : list) { + TEST: + } + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/optional_get_without_is_present/OptionalGetWithoutIsPresent.java b/java/java-tests/testData/inspection/dataFlow/fixture/OptionalGetWithoutIsPresent.java similarity index 62% rename from plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/optional_get_without_is_present/OptionalGetWithoutIsPresent.java rename to java/java-tests/testData/inspection/dataFlow/fixture/OptionalGetWithoutIsPresent.java index f4f8c2610bc7..b57953ada07b 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/optional_get_without_is_present/OptionalGetWithoutIsPresent.java +++ b/java/java-tests/testData/inspection/dataFlow/fixture/OptionalGetWithoutIsPresent.java @@ -13,10 +13,65 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import java.util.Optional; +import java.util.*; class OptionalWithoutIsPresent { + void testSimple(Optional o, OptionalDouble od, OptionalInt oi, OptionalLong ol) { + System.out.println(o.get()); + System.out.println(oi.getAsInt()); + System.out.println(ol.getAsLong()); + System.out.println(od.getAsDouble()); + } + + { + System.out.println(getIntegerOptional().get()); + } + + void testWhile() { + Optional o = Optional.empty(); + while (!o.isPresent()) { + o = Optional.of(""); + } + System.out.println(o.get()); + } + + void testWhile2() { + Optional o = getIntegerOptional(); + while (o.isPresent()) { + System.out.println(o.get()); + } + } + + public void testPolyadicExpression(Optional value) { + boolean flag = value.isPresent() && "Yes".equals(value.get()); + } + + boolean testPolyadicExpression2(Optional o) { + return !o.isPresent() || o.get().equals("j"); + } + + String testPolyadicExpression3() { + Optional o = getOptional(); + if (o == null || !o.isPresent()) { + return ""; + } + return o.get(); + } + + void testNested(Optional opt, String action) { + if (!opt.isPresent()) { + throw new IllegalArgumentException(); + } + switch (action) { + case "case": + System.out.println(opt.get()); + break; + default: + System.err.println(opt.get()); + } + } + void m(Optional maybe) { if (!!!maybe.isPresent()) { maybe = getIntegerOptional(); @@ -29,9 +84,9 @@ class OptionalWithoutIsPresent { maybe = Optional.empty(); System.out.println(maybe.get()); } - boolean b = ((maybe.isPresent())) && maybe.get() == 1; - boolean c = (!maybe.isPresent()) || maybe.get() == 1; - Integer value = !maybe.isPresent() ? 0 : maybe.get(); + boolean b = ((maybe.isPresent())) && maybe.get() == 1; + boolean c = (!maybe.isPresent()) || maybe.get() == 1; + Integer value = !maybe.isPresent() ? 0 : maybe.get(); } Optional getIntegerOptional() { @@ -42,7 +97,7 @@ class OptionalWithoutIsPresent { Optional optional = Optional.empty(); final boolean present = optional.isPresent(); // optional = Optional.empty(); - if (present) { + if (present) { final String string = optional.get(); System.out.println(string); } @@ -52,7 +107,7 @@ class OptionalWithoutIsPresent { Optional optional = Optional.empty(); final boolean present = optional.isPresent(); optional = Optional.empty(); - if (present) { + if (present) { final String string = optional.get(); System.out.println(string); } @@ -101,7 +156,7 @@ class OptionalWithoutIsPresent { private void checkAsserts2() { Optional o3 = Optional.empty(); - org.testng.Assert.assertTrue(o3.isPresent()); + org.testng.Assert.assertTrue(o3.isPresent()); System.out.println(o3.get()); } @@ -131,16 +186,16 @@ class OptionalWithoutIsPresent { private void checkOfNullable(String value) { System.out.println(Optional.ofNullable(value).get()); - System.out.println(Optional.ofNullable(value+"a").get()); - System.out.println(Optional.ofNullable("xyz").get()); + System.out.println(Optional.ofNullable(value+"a").get()); + System.out.println(Optional.ofNullable("xyz").get()); } public static String demo() { Optional holder = Optional.empty(); - if (! holder.isPresent()) { + if (! holder.isPresent()) { holder = Optional.of("hello world"); - if (!holder.isPresent()) { + if (!holder.isPresent()) { return null; } } @@ -171,9 +226,10 @@ class OptionalWithoutIsPresent { return Optional.empty(); } - //void order(Optional order) { - // order.ifPresent(o -> System.out.println(order.get())); - //} + void order(Optional order, boolean b) { + order.ifPresent(o -> System.out.println(order.get())); + System.out.println(order.orElseGet(() -> order.get().trim())); + } public static void two(Optional o1,Optional o2) { if (!o1.isPresent() && !o2.isPresent()) { @@ -210,7 +266,7 @@ class OptionalWithoutIsPresent { opt2.get(); } - static final class Range { + class Range { Optional min = Optional.of(1); Optional max = Optional.of(2); @@ -243,7 +299,7 @@ class OptionalWithoutIsPresent { } void shortIf(Optional o) { - if (true || o.isPresent()) { + if (true || o.isPresent()) { o.get(); } } @@ -257,6 +313,25 @@ class OptionalWithoutIsPresent { } String f(Optional optional, Optional opt2) { - return optional.isPresent() ? opt2.get() : null; + return optional.isPresent() ? opt2.get() : ""; + } + + void guavaTest(com.google.common.base.Optional opt, String s) { + System.out.println(opt.get()); + if(opt.isPresent()) { + System.out.println(opt.get()); + } + opt = com.google.common.base.Optional.fromNullable(s); + if(opt.isPresent()) { + System.out.println(opt.get()); + } + opt = com.google.common.base.Optional.of(s); + if(opt.isPresent()) { + System.out.println(opt.get()); + } + opt = com.google.common.base.Optional.absent(); + if(opt.isPresent()) { + System.out.println(opt.get()); + } } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java index b09f1d583e81..af4633b87e9b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java @@ -517,6 +517,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testApplicabilityErrorVisibleWhenConstraintsFromFunctionalExpressionsProvideValidSubstitutor() { + doTest(); + } + public void testMethodReferenceSecondSearchDontInfluenceTopSiteSubstitutor() throws Exception { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java index 2dac136b94a3..f5583323e6db 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspection8Test.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,18 +18,29 @@ package com.intellij.codeInspection; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.NullableNotNullManager; import com.intellij.codeInspection.dataFlow.DataFlowInspection; +import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.util.Disposer; +import com.intellij.testFramework.IdeaTestUtil; import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.testFramework.PsiTestUtil; +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; import org.jetbrains.annotations.NotNull; /** * @author peter */ public class DataFlowInspection8Test extends DataFlowInspectionTestCase { + private static final DefaultLightProjectDescriptor PROJECT_DESCRIPTOR = new DefaultLightProjectDescriptor() { + @Override + public Sdk getSdk() { + return PsiTestUtil.addJdkAnnotations(IdeaTestUtil.getMockJdk18()); + } + }; + @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { - return JAVA_8; + return PROJECT_DESCRIPTOR; } @Override @@ -46,8 +57,30 @@ public class DataFlowInspection8Test extends DataFlowInspectionTestCase { public void testNullableVoidLambda() { doTest(); } public void testNullableForeachVariable() { doTestWithCustomAnnotations(); } public void testGenericParameterNullity() { doTestWithCustomAnnotations(); } + public void testOptionalOfNullable() { doTest(); } public void testOptionalIsPresent() { doTest(); } + public void testOptionalGetWithoutIsPresent() { + myFixture.addClass("package org.junit;" + + "public class Assert {" + + " public static void assertTrue(boolean b) {}" + + "}"); + myFixture.addClass("package org.testng;" + + "public class Assert {" + + " public static void assertTrue(boolean b) {}" + + "}"); + myFixture.addClass("package com.google.common.base;\n" + + "\n" + + "public abstract class Optional {\n" + + " public static Optional absent() {}\n" + + " public static Optional of(T ref) {}\n" + + " public static Optional fromNullable(T ref) {}\n" + + " public abstract T get();\n" + + " public abstract boolean isPresent();\n" + + "}"); + doTest(); + } + public void testPrimitiveInVoidLambda() { doTest(); } public void testNotNullLambdaParameter() { doTest(); } public void testNotNullOptionalLambdaParameter() { doTest(); } diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsPsiTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsPsiTest.java index 5907f03ef1a7..f2877421ae87 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsPsiTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsPsiTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -423,7 +423,7 @@ public class ClsPsiTest extends LightIdeaTestCase { PsiJavaModule module = file.getModuleDeclaration(); assertNotNull(module); - assertEquals("M.N", module.getModuleName()); + assertEquals("M.N", module.getName()); assertNull(file.getPackageStatement()); assertEquals(0, file.getClasses().length); diff --git a/java/java-tests/testSrc/com/intellij/psi/ConstantEvaluatorTest.java b/java/java-tests/testSrc/com/intellij/psi/ConstantEvaluatorTest.java index 909646357856..80332c80c2fd 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ConstantEvaluatorTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ConstantEvaluatorTest.java @@ -37,4 +37,13 @@ public class ConstantEvaluatorTest extends LightCodeInsightFixtureTestCase { assertEquals(MyEnum.Foo, result); } + + public void testPrefixExpressionEvaluation() throws Exception { + PsiJavaFile file = (PsiJavaFile)myFixture.configureByText("A.java", "class A {public static final int VALUE = ~0 >>> 1;}"); + PsiClass aClass = file.getClasses()[0]; + PsiField vField = aClass.getFields()[0]; + Object result = JavaPsiFacade.getInstance(getProject()).getConstantEvaluationHelper().computeConstantExpression(vField.getInitializer()); + + assertEquals(2147483647, result); + } } diff --git a/platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java b/platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java index 1921f9ecdb18..c85ea15be212 100644 --- a/platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java +++ b/platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java @@ -76,4 +76,14 @@ public abstract class ExternalAnnotator { */ public void apply(@NotNull PsiFile file, AnnotationResultType annotationResult, @NotNull AnnotationHolder holder) { } + + /** + * Return inspection which should run in batch mode. + * When inspection with short name is disabled, then annotator won't run in the editor via {@link com.intellij.codeInsight.daemon.impl.ExternalToolPass}. + * Implementing {@link com.intellij.codeInspection.ex.ExternalAnnotatorBatchInspection} and extending {@link com.intellij.codeInspection.LocalInspectionTool} would + * provide implementation for a batch tool which would run without read action, according to the {@link #doAnnotate(Object)} documentation + */ + public String getPairedBatchInspectionShortName() { + return null; + } } diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java b/platform/analysis-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java index 67f19f8a3403..5450302a2739 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java @@ -21,6 +21,7 @@ import com.intellij.lang.annotation.Annotation; import com.intellij.lang.annotation.AnnotationSession; import com.intellij.lang.annotation.ExternalAnnotator; import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Iconable; @@ -58,21 +59,23 @@ public class ExternalAnnotatorInspectionVisitor extends PsiElementVisitor { public static ProblemDescriptor[] checkFileWithExternalAnnotator(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly, - @NotNull ExternalAnnotator annotator) { + @NotNull ExternalAnnotator annotator) { if (isOnTheFly) { // ExternalAnnotator does this work return ProblemDescriptor.EMPTY_ARRAY; } - Init info = annotator.collectInformation(file); + Init info = ReadAction.compute(() -> annotator.collectInformation(file)); if (info != null) { Result annotationResult = annotator.doAnnotate(info); if (annotationResult == null) { return ProblemDescriptor.EMPTY_ARRAY; } - AnnotationHolderImpl annotationHolder = new AnnotationHolderImpl(new AnnotationSession(file)); - annotator.apply(file, annotationResult, annotationHolder); - return convertToProblemDescriptors(annotationHolder, manager, file); + return ReadAction.compute(() -> { + AnnotationHolderImpl annotationHolder = new AnnotationHolderImpl(new AnnotationSession(file)); + annotator.apply(file, annotationResult, annotationHolder); + return convertToProblemDescriptors(annotationHolder, manager, file); + }); } return ProblemDescriptor.EMPTY_ARRAY; } diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/ExternalAnnotatorBatchInspection.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ExternalAnnotatorBatchInspection.java new file mode 100644 index 000000000000..d5ce17d2f66a --- /dev/null +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/ExternalAnnotatorBatchInspection.java @@ -0,0 +1,57 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInspection.ex; + +import com.intellij.codeInspection.ExternalAnnotatorInspectionVisitor; +import com.intellij.codeInspection.InspectionManager; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.lang.ExternalLanguageAnnotators; +import com.intellij.lang.Language; +import com.intellij.lang.annotation.ExternalAnnotator; +import com.intellij.psi.FileViewProvider; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Set; + +public interface ExternalAnnotatorBatchInspection extends PairedUnfairLocalInspectionTool { + @NotNull + String getShortName(); + + @NotNull + @Override + default String getInspectionForBatchShortName() { + return getShortName(); + } + + default ProblemDescriptor[] checkFile(PsiFile file, InspectionManager manager) { + final String shortName = getShortName(); + final FileViewProvider viewProvider = file.getViewProvider(); + final Set relevantLanguages = viewProvider.getLanguages(); + for (Language language : relevantLanguages) { + PsiFile psiRoot = viewProvider.getPsi(language); + final List externalAnnotators = ExternalLanguageAnnotators.allForFile(language, psiRoot); + + for (ExternalAnnotator annotator : externalAnnotators) { + if (shortName.equals(annotator.getPairedBatchInspectionShortName())) { + return ExternalAnnotatorInspectionVisitor.checkFileWithExternalAnnotator(file, manager, false, annotator); + } + } + } + return ProblemDescriptor.EMPTY_ARRAY; + } +} diff --git a/platform/configuration-store-impl/testSrc/StoredPropertyStateTest.kt b/platform/configuration-store-impl/testSrc/StoredPropertyStateTest.kt index 138d03868c51..0513b79320de 100644 --- a/platform/configuration-store-impl/testSrc/StoredPropertyStateTest.kt +++ b/platform/configuration-store-impl/testSrc/StoredPropertyStateTest.kt @@ -3,20 +3,21 @@ package com.intellij.configurationStore import com.intellij.openapi.components.BaseState import com.intellij.testFramework.assertions.Assertions.assertThat import com.intellij.util.loadElement -import com.intellij.util.xmlb.XmlSerializer import com.intellij.util.xmlb.annotations.Attribute import org.junit.Test -private class AState : BaseState() { +internal class AState : BaseState() { @get:Attribute("customName") var languageLevel by storedProperty() var property2 by storedProperty(0) + var floatProperty by storedProperty(0.3) + var nestedComplex by storedProperty() } -private class NestedState : BaseState() { +internal class NestedState : BaseState() { var childProperty by storedProperty() } @@ -36,7 +37,7 @@ class StoredPropertyStateTest { assertThat(state).isNotEqualTo(AState()) - assertThat(XmlSerializer.serialize(state)).isEqualTo("""""") + assertThat(state.serialize()).isEqualTo("""""") assertThat(loadElement("""""").deserialize(AState::class.java).languageLevel).isEqualTo("foo") } diff --git a/platform/configuration-store-impl/testSrc/xml/KotlinXmlSerializerTest.kt b/platform/configuration-store-impl/testSrc/xml/KotlinXmlSerializerTest.kt index c3adb349e467..9c808d14a779 100644 --- a/platform/configuration-store-impl/testSrc/xml/KotlinXmlSerializerTest.kt +++ b/platform/configuration-store-impl/testSrc/xml/KotlinXmlSerializerTest.kt @@ -15,6 +15,7 @@ */ package com.intellij.configurationStore.xml +import com.intellij.configurationStore.AState import com.intellij.configurationStore.deserialize import com.intellij.util.loadElement import com.intellij.util.xmlb.annotations.MapAnnotation @@ -38,6 +39,16 @@ class KotlinXmlSerializerTest { """, data) } + @Test fun floatProperty() { + val state = AState() + state.floatProperty = 3.4 + doSerializerTest(""" + + + """, state) + } + @Test fun nullInMap() { @Tag("bean") class Foo { diff --git a/platform/configuration-store-impl/testSrc/xml/XmlSerializerTest.kt b/platform/configuration-store-impl/testSrc/xml/XmlSerializerTest.kt index a4a81ebbef38..b825be8c8370 100644 --- a/platform/configuration-store-impl/testSrc/xml/XmlSerializerTest.kt +++ b/platform/configuration-store-impl/testSrc/xml/XmlSerializerTest.kt @@ -15,6 +15,7 @@ */ package com.intellij.configurationStore.xml +import com.intellij.configurationStore.StoredPropertyStateTest import com.intellij.configurationStore.deserialize import com.intellij.configurationStore.serialize import com.intellij.openapi.util.JDOMUtil @@ -39,6 +40,7 @@ import java.util.* XmlSerializerTest::class, XmlSerializerMapTest::class, XmlSerializerCollectionTest::class, + StoredPropertyStateTest::class, KotlinXmlSerializerTest::class ) class XmlSerializerTestSuite @@ -240,7 +242,7 @@ internal class XmlSerializerTest { bean.INT_V = 987 bean.STRING_V = "1234" - val element = bean.serialize(null) + val element = bean.serialize() val node = element.children.get(0) element.removeContent(node) @@ -642,7 +644,7 @@ internal class XmlSerializerTest { private val XML_PREFIX = "" internal fun assertSerializer(bean: Any, expected: String, filter: SerializationFilter?, description: String = "Serialization failure"): Element { - val element = bean.serialize(filter) + val element = bean.serialize(filter) var actual = JDOMUtil.writeElement(element, "\n").trim() if (!expected.startsWith(XML_PREFIX) && actual.startsWith(XML_PREFIX)) { actual = actual.substring(XML_PREFIX.length).trim() diff --git a/platform/configuration-store-impl/testSrc/xml/XmlSerializerWithDefaultJDOMExternalizerCompatibilityTest.java b/platform/configuration-store-impl/testSrc/xml/XmlSerializerWithDefaultJDOMExternalizerCompatibilityTest.java new file mode 100644 index 000000000000..fe6f0b7fefd0 --- /dev/null +++ b/platform/configuration-store-impl/testSrc/xml/XmlSerializerWithDefaultJDOMExternalizerCompatibilityTest.java @@ -0,0 +1,61 @@ +package com.intellij.configurationStore.xml; + +import com.intellij.configurationStore.XmlSerializer; +import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.xmlb.SerializationFilter; +import com.intellij.util.xmlb.annotations.Transient; +import junit.framework.TestCase; +import org.jdom.Element; +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings({"deprecation"}) +public class XmlSerializerWithDefaultJDOMExternalizerCompatibilityTest extends TestCase { + public void testCompatibility() throws Exception { + final MyBean bean = new MyBean(); + assertCompatibleSerialization(bean, "MyBean"); + } + + private static void assertCompatibleSerialization(final Object data, final String rootTagName) throws Exception { + assertEquals(serializeWithJDom(data, rootTagName), serializeWithXmlSerializer(data)); + } + + private static String serializeWithXmlSerializer(final Object data) throws Exception { + Element element = serialize(data, null); + + String s = JDOMUtil.writeElement(element, "\n"); + return StringUtil.trimStart(s, "").trim(); + } + + private static String serializeWithJDom(final Object data, String rootTagName) throws Exception { + final Element jDomRoot = new Element(rootTagName); + + if (data instanceof com.intellij.openapi.util.JDOMExternalizable) { + ((com.intellij.openapi.util.JDOMExternalizable)data).writeExternal(jDomRoot); + } + else { + com.intellij.openapi.util.DefaultJDOMExternalizer.writeExternal(data, jDomRoot); + } + + return JDOMUtil.writeElement(jDomRoot, "\n").trim(); + } + + private static Element serialize(Object bean, @Nullable SerializationFilter filter) { + return XmlSerializer.serialize(bean, filter); + } + + @SuppressWarnings("unused") + private static class MyBean { + public int intField = 0; + public int intField2 = 1; + public boolean booleanField = false; + public boolean booleanField2 = true; + public String stringField; + public String stringField2 = "a"; + public float floatField; + public float floatField2 = 1; + public transient int transientField; + @Transient + public int transientField2; + } +} diff --git a/platform/core-api/src/com/intellij/psi/PsiNameIdentifierOwner.java b/platform/core-api/src/com/intellij/psi/PsiNameIdentifierOwner.java index d8906212fdb2..71f639b63da1 100644 --- a/platform/core-api/src/com/intellij/psi/PsiNameIdentifierOwner.java +++ b/platform/core-api/src/com/intellij/psi/PsiNameIdentifierOwner.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.psi; import org.jetbrains.annotations.Nullable; @@ -22,6 +21,5 @@ import org.jetbrains.annotations.Nullable; * @author yole */ public interface PsiNameIdentifierOwner extends PsiNamedElement { - @Nullable - PsiElement getNameIdentifier(); -} + @Nullable PsiElement getNameIdentifier(); +} \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/psi/PsiNamedElement.java b/platform/core-api/src/com/intellij/psi/PsiNamedElement.java index 9f3deae684aa..aeb57578ede6 100644 --- a/platform/core-api/src/com/intellij/psi/PsiNamedElement.java +++ b/platform/core-api/src/com/intellij/psi/PsiNamedElement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,14 +16,13 @@ package com.intellij.psi; import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * A PSI element which has a name and can be renamed (for example, a class or a method). */ -public interface PsiNamedElement extends PsiElement{ +public interface PsiNamedElement extends PsiElement { /** * The empty array of PSI named elements which can be reused to avoid unnecessary allocations. */ @@ -34,7 +33,7 @@ public interface PsiNamedElement extends PsiElement{ * * @return the element name. */ - @Nullable @NonNls String getName(); + @Nullable String getName(); /** * Renames the element. @@ -44,5 +43,5 @@ public interface PsiNamedElement extends PsiElement{ * or a different element if the rename caused the element to be replaced). * @throws IncorrectOperationException if the modification is not supported or not possible for some reason. */ - PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException; -} + PsiElement setName(@NotNull String name) throws IncorrectOperationException; +} \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/psi/PsiWalkingState.java b/platform/core-api/src/com/intellij/psi/PsiWalkingState.java index 6418a0b60804..5068757c437e 100644 --- a/platform/core-api/src/com/intellij/psi/PsiWalkingState.java +++ b/platform/core-api/src/com/intellij/psi/PsiWalkingState.java @@ -17,6 +17,7 @@ package com.intellij.psi; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.WalkingState; import org.jetbrains.annotations.NotNull; @@ -30,12 +31,17 @@ public abstract class PsiWalkingState extends WalkingState { private static class PsiTreeGuide implements TreeGuide { @Override public PsiElement getNextSibling(@NotNull PsiElement element) { - return element.getNextSibling(); + return checkSanity(element, element.getNextSibling()); + } + + private static PsiElement checkSanity(PsiElement element, PsiElement sibling) { + if (sibling == PsiUtilCore.NULL_PSI_ELEMENT) throw new PsiInvalidElementAccessException(element, "Sibling of "+element+" is NULL_PSI_ELEMENT"); + return sibling; } @Override public PsiElement getPrevSibling(@NotNull PsiElement element) { - return element.getPrevSibling(); + return checkSanity(element, element.getPrevSibling()); } @Override diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java index a9def5d1f808..58dd4a8e0b7f 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/RangeMarkerTree.java @@ -192,7 +192,9 @@ public class RangeMarkerTree extends IntervalTreeImpl node : affected) { + // reverse direction to visit leaves first - it's cheaper to compute maxEndOf for them first + for (int i = affected.size() - 1; i >= 0; i--) { + IntervalNode node = affected.get(i); // assumption: interval.getEndOffset() will never be accessed during remove() int startOffset = node.intervalStart(); int endOffset = node.intervalEnd(); diff --git a/platform/core-impl/src/com/intellij/openapi/roots/impl/PackageDirectoryCache.java b/platform/core-impl/src/com/intellij/openapi/roots/impl/PackageDirectoryCache.java index 214ffd39745c..be5ebf7eaf61 100644 --- a/platform/core-impl/src/com/intellij/openapi/roots/impl/PackageDirectoryCache.java +++ b/platform/core-impl/src/com/intellij/openapi/roots/impl/PackageDirectoryCache.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.roots.impl; -import com.intellij.openapi.util.LowMemoryWatcher; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.openapi.util.VolatileNotNullLazyValue; import com.intellij.openapi.util.registry.Registry; @@ -35,18 +34,15 @@ public class PackageDirectoryCache { private final MultiMap myRootsByPackagePrefix; private final Map myDirectoriesByPackageNameCache = ContainerUtil.newConcurrentMap(); private final Set myNonExistentPackages = ContainerUtil.newConcurrentSet(); - @SuppressWarnings("UnusedDeclaration") - private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() { - @Override - public void run() { - myNonExistentPackages.clear(); - } - }); - public PackageDirectoryCache(MultiMap rootsByPackagePrefix) { + public PackageDirectoryCache(@NotNull MultiMap rootsByPackagePrefix) { myRootsByPackagePrefix = rootsByPackagePrefix; } + public void onLowMemory() { + myNonExistentPackages.clear(); + } + @NotNull public List getDirectoriesByPackageName(@NotNull final String packageName) { PackageInfo info = getPackageInfo(packageName); @@ -120,8 +116,8 @@ public class PackageDirectoryCache { }; PackageInfo(String qname, List packageDirectories) { - this.myQname = qname; - this.myPackageDirectories = packageDirectories; + myQname = qname; + myPackageDirectories = packageDirectories; } @NotNull diff --git a/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java b/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java index a6d07ee62769..20384b040bcd 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java +++ b/platform/core-impl/src/com/intellij/psi/impl/PsiElementBase.java @@ -1,6 +1,6 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/platform/core-impl/src/com/intellij/util/CachedValueBase.java b/platform/core-impl/src/com/intellij/util/CachedValueBase.java index 548ead1529d3..fbb952138d0a 100644 --- a/platform/core-impl/src/com/intellij/util/CachedValueBase.java +++ b/platform/core-impl/src/com/intellij/util/CachedValueBase.java @@ -53,7 +53,7 @@ public abstract class CachedValueBase { @Nullable private synchronized Data cacheOrGetData(@Nullable Data expected, @Nullable Data updatedValue) { - if (expected != getData()) return null; + if (expected != getRawData()) return null; if (updatedValue != null) { myData = new SoftReference>(updatedValue); @@ -67,7 +67,7 @@ public abstract class CachedValueBase { } private synchronized boolean compareAndClearData(Data expected) { - if (getData() == expected) { + if (getRawData() == expected) { myData = null; return true; } @@ -101,7 +101,7 @@ public abstract class CachedValueBase { @Nullable private Data getUpToDateOrNull(boolean dispose) { - final Data data = getData(); + final Data data = getRawData(); if (data != null) { if (isUpToDate(data)) { @@ -115,7 +115,7 @@ public abstract class CachedValueBase { } @Nullable - private Data getData() { + final Data getRawData() { return SoftReference.dereference(myData); } @@ -223,7 +223,7 @@ public abstract class CachedValueBase { if (stamp.mayCacheNow()) { while (true) { - Data alreadyComputed = getData(); + Data alreadyComputed = getRawData(); boolean reuse = alreadyComputed != null && isUpToDate(alreadyComputed); Data toReturn = cacheOrGetData(alreadyComputed, reuse ? null : data); if (toReturn != null) { diff --git a/platform/core-impl/src/com/intellij/util/CachedValuesManagerImpl.java b/platform/core-impl/src/com/intellij/util/CachedValuesManagerImpl.java index ddb39c588151..c837e564841e 100644 --- a/platform/core-impl/src/com/intellij/util/CachedValuesManagerImpl.java +++ b/platform/core-impl/src/com/intellij/util/CachedValuesManagerImpl.java @@ -86,7 +86,11 @@ public class CachedValuesManagerImpl extends CachedValuesManager { private boolean isOutdated(CachedValue value) { return value instanceof CachedValueBase && - (!((CachedValueBase)value).isFromMyProject(myProject) || !value.hasUpToDateValue()); + (!((CachedValueBase)value).isFromMyProject(myProject) || hasOutdatedValue((CachedValueBase)value)); + } + + private static boolean hasOutdatedValue(CachedValueBase base) { + return !base.hasUpToDateValue() && base.getRawData() != null; } public Project getProject() { diff --git a/platform/core-impl/src/com/intellij/util/SofterReference.java b/platform/core-impl/src/com/intellij/util/SofterReference.java index 3a453d96d683..44f1409dec68 100644 --- a/platform/core-impl/src/com/intellij/util/SofterReference.java +++ b/platform/core-impl/src/com/intellij/util/SofterReference.java @@ -15,6 +15,7 @@ */ package com.intellij.util; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.LowMemoryWatcher; import com.intellij.util.containers.WeakList; import org.jetbrains.annotations.NotNull; @@ -34,15 +35,20 @@ public class SofterReference { private volatile Reference myRef; private static final WeakList ourRegistry = new WeakList(); - @SuppressWarnings("UnusedDeclaration") - private static final LowMemoryWatcher ourWatcher = LowMemoryWatcher.register(new Runnable() { - @Override - public void run() { - for (SofterReference reference : ourRegistry.copyAndClear()) { - reference.weaken(); - } + private static void onLowMemory() { + for (SofterReference reference : ourRegistry.copyAndClear()) { + reference.weaken(); } - }); + } + + static { + LowMemoryWatcher.register(new Runnable() { + @Override + public void run() { + onLowMemory(); + } + }, ApplicationManager.getApplication()); + } public SofterReference(@NotNull T referent) { ourRegistry.add(this); diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/MultilanguageDuplocatorSettings.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/MultilanguageDuplocatorSettings.java index e81a58c03d44..b3b791f2455f 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/MultilanguageDuplocatorSettings.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/MultilanguageDuplocatorSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; -import com.intellij.openapi.util.JDOMUtil; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; import org.jdom.Element; @@ -65,8 +64,8 @@ public class MultilanguageDuplocatorSettings implements PersistentStateComponent SkipDefaultValuesSerializationFilters filter = new SkipDefaultValuesSerializationFilters(); for (String name : mySettingsMap.keySet()) { - Element child = XmlSerializer.serialize(mySettingsMap.get(name), filter); - if (!JDOMUtil.isEmpty(child)) { + Element child = XmlSerializer.serializeIfNotDefault(mySettingsMap.get(name), filter); + if (child != null) { child.setName("object"); child.setAttribute("language", name); state.addContent(child); diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java b/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java index d4193e697a48..839575e63556 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java @@ -388,18 +388,21 @@ public class BranchActionGroupPopup extends FlatSpeedSearchPopup { @NotNull private final Project myProject; @Nullable private final String mySettingName; + private final boolean myDefaultExpandValue; private boolean myIsExpanded; @NotNull private final String myToCollapseText; @NotNull private final String myToExpandText; - public MoreAction(@NotNull Project project, int numberOfHiddenNodes, @Nullable String settingName) { + public MoreAction(@NotNull Project project, int numberOfHiddenNodes, @Nullable String settingName, boolean defaultExpandValue) { super(); myProject = project; mySettingName = settingName; + myDefaultExpandValue = defaultExpandValue; assert numberOfHiddenNodes > 0; myToExpandText = "Show " + numberOfHiddenNodes + " More..."; myToCollapseText = "Show Only Favorites"; - setExpanded(settingName != null && PropertiesComponent.getInstance(project).getBoolean(settingName, false)); + setExpanded( + settingName != null ? PropertiesComponent.getInstance(project).getBoolean(settingName, defaultExpandValue) : defaultExpandValue); } @Override @@ -430,7 +433,7 @@ public class BranchActionGroupPopup extends FlatSpeedSearchPopup { public void saveState() { if (mySettingName != null) { - PropertiesComponent.getInstance(myProject).setValue(mySettingName, myIsExpanded); + PropertiesComponent.getInstance(myProject).setValue(mySettingName, myIsExpanded, myDefaultExpandValue); } } } @@ -456,8 +459,14 @@ public class BranchActionGroupPopup extends FlatSpeedSearchPopup { public static void wrapWithMoreActionIfNeeded(@NotNull Project project, @NotNull DefaultActionGroup parentGroup, @NotNull List actionList, int maxIndex, @Nullable String settingName) { + wrapWithMoreActionIfNeeded(project, parentGroup, actionList, maxIndex, settingName, false); + } + + public static void wrapWithMoreActionIfNeeded(@NotNull Project project, + @NotNull DefaultActionGroup parentGroup, @NotNull List actionList, + int maxIndex, @Nullable String settingName, boolean defaultExpandValue) { if (actionList.size() > maxIndex) { - MoreAction moreAction = new MoreAction(project, actionList.size() - maxIndex, settingName); + MoreAction moreAction = new MoreAction(project, actionList.size() - maxIndex, settingName, defaultExpandValue); for (int i = 0; i < actionList.size(); i++) { parentGroup.add(i < maxIndex ? actionList.get(i) : new HideableActionGroup(actionList.get(i), moreAction)); } diff --git a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.kt b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.kt index efcd9ae70b5c..f19ba904be06 100644 --- a/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.kt +++ b/platform/editor-ui-api/src/com/intellij/ide/ui/UISettings.kt @@ -98,6 +98,18 @@ class UISettings : BaseState(), PersistentStateComponent { @Transient var PRESENTATION_MODE = false + @Suppress("unused") + @Deprecated("Use overrideLafFonts", replaceWith = ReplaceWith("overrideLafFonts")) + @JvmField + @Transient + var OVERRIDE_NONIDEA_LAF_FONTS = false + + @Suppress("unused") + @Deprecated("Use presentationModeFontSize", replaceWith = ReplaceWith("presentationModeFontSize")) + @JvmField + @Transient + var PRESENTATION_MODE_FONT_SIZE = 24 + @get:OptionTag("REUSE_NOT_MODIFIED_TABS") var reuseNotModifiedTabs by storedProperty(false) @get:OptionTag("ANIMATE_WINDOWS") var animateWindows by storedProperty(true) @get:OptionTag("SHOW_TOOL_WINDOW_NUMBERS") var showToolWindowsNumbers by storedProperty(true) @@ -117,36 +129,36 @@ class UISettings : BaseState(), PersistentStateComponent { @get:OptionTag("HIDE_TABS_IF_NEED") var hideTabsIfNeed by storedProperty(true) @get:OptionTag("SHOW_CLOSE_BUTTON") var showCloseButton by storedProperty(true) @get:OptionTag("EDITOR_TAB_PLACEMENT") var editorTabPlacement by storedProperty(1) - - @JvmField var HIDE_KNOWN_EXTENSION_IN_TABS = false - @JvmField var SHOW_ICONS_IN_QUICK_NAVIGATION = true - @JvmField var CLOSE_NON_MODIFIED_FILES_FIRST = false - @JvmField var ACTIVATE_MRU_EDITOR_ON_CLOSE = false - @JvmField var ACTIVATE_RIGHT_EDITOR_ON_CLOSE = false + @get:OptionTag("HIDE_KNOWN_EXTENSION_IN_TABS") var hdeKnownExtensionInTabs by storedProperty(false) + @get:OptionTag("SHOW_ICONS_IN_QUICK_NAVIGATION") var showIconInQuickNavigation by storedProperty(true) + @get:OptionTag("CLOSE_NON_MODIFIED_FILES_FIRST") var closeNonModifiedFilesFirst by storedProperty(false) + @get:OptionTag("ACTIVATE_MRU_EDITOR_ON_CLOSE") var activeMruEditorOnClose by storedProperty(false) + @get:OptionTag("ACTIVATE_RIGHT_EDITOR_ON_CLOSE") var activeRigtEditorOnClose by storedProperty(false) @get:OptionTag("IDE_AA_TYPE") var ideAAType by storedProperty(AntialiasingType.SUBPIXEL) @get:OptionTag("EDITOR_AA_TYPE") var editorAAType by storedProperty(AntialiasingType.SUBPIXEL) @JvmField var COLOR_BLINDNESS: ColorBlindness? = null - @JvmField var MOVE_MOUSE_ON_DEFAULT_BUTTON = false - @JvmField var ENABLE_ALPHA_MODE = false - @JvmField var ALPHA_MODE_DELAY = 1500 - @JvmField var ALPHA_MODE_RATIO = 0.5f - @JvmField var MAX_CLIPBOARD_CONTENTS = 5 - @JvmField var OVERRIDE_NONIDEA_LAF_FONTS = false - @JvmField var SHOW_ICONS_IN_MENUS = true - @JvmField var DISABLE_MNEMONICS = SystemInfo.isMac // IDEADEV-33409, should be disabled by default on MacOS - @JvmField var DISABLE_MNEMONICS_IN_CONTROLS = false - @JvmField var USE_SMALL_LABELS_ON_TABS = SystemInfo.isMac - @JvmField var MAX_LOOKUP_WIDTH2 = 500 - @JvmField var MAX_LOOKUP_LIST_HEIGHT = 11 - @JvmField var HIDE_NAVIGATION_ON_FOCUS_LOSS = true - @JvmField var DND_WITH_PRESSED_ALT_ONLY = false - @JvmField var DEFAULT_AUTOSCROLL_TO_SOURCE = false + @get:OptionTag("MOVE_MOUSE_ON_DEFAULT_BUTTON") var moveMouseOnDefaultButton by storedProperty(false) + @get:OptionTag("ENABLE_ALPHA_MODE") var enableAlphaMode by storedProperty(false) + @get:OptionTag("ALPHA_MODE_DELAY") var alphaModeDelay by storedProperty(1500) + @get:OptionTag("ALPHA_MODE_RATIO") var alphaModeRatio by storedProperty(0.5f) + @get:OptionTag("MAX_CLIPBOARD_CONTENTS") var maxClipboardContents by storedProperty(5) + @get:OptionTag("OVERRIDE_NONIDEA_LAF_FONTS") var overrideLafFonts by storedProperty(false) + @get:OptionTag("SHOW_ICONS_IN_MENUS") var showIconsInMenus by storedProperty(true) + // IDEADEV-33409, should be disabled by default on MacOS + @get:OptionTag("DISABLE_MNEMONICS") var disableMnemonics by storedProperty(SystemInfo.isMac) + @get:OptionTag("DISABLE_MNEMONICS_IN_CONTROLS") var disableMnemonicsInControls by storedProperty(false) + @get:OptionTag("USE_SMALL_LABELS_ON_TABS") var useSmallLabelsOnTabs by storedProperty(SystemInfo.isMac) + @get:OptionTag("MAX_LOOKUP_WIDTH2") var maxLookupWidth by storedProperty(500) + @get:OptionTag("MAX_LOOKUP_LIST_HEIGHT") var maxLookupListHeight by storedProperty(11) + @get:OptionTag("HIDE_NAVIGATION_ON_FOCUS_LOSS") var hideNavigationOnFocusLoss by storedProperty(true) + @get:OptionTag("DND_WITH_PRESSED_ALT_ONLY") var dndWithPressedAltOnly by storedProperty(false) + @get:OptionTag("DEFAULT_AUTOSCROLL_TO_SOURCE") var defaultAutoScrollToSource by storedProperty(false) @Transient var presentationMode = false - @JvmField var PRESENTATION_MODE_FONT_SIZE = 24 - @JvmField var MARK_MODIFIED_TABS_WITH_ASTERISK = false - @JvmField var SHOW_TABS_TOOLTIPS = true - @JvmField var SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES = true - @JvmField var NAVIGATE_TO_PREVIEW = false + @get:OptionTag("PRESENTATION_MODE_FONT_SIZE") var presentationModeFontSize by storedProperty(24) + @get:OptionTag("MARK_MODIFIED_TABS_WITH_ASTERISK") var markModifiedTabsWithAsterisk by storedProperty(false) + @get:OptionTag("SHOW_TABS_TOOLTIPS") var showTabsTooltips by storedProperty(true) + @get:OptionTag("SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES") var showDirectoryForNonUniqueFilenames by storedProperty(true) + @get:OptionTag("NAVIGATE_TO_PREVIEW") var navigateToPreview by storedProperty(false) private val myTreeDispatcher = ComponentTreeEventDispatcher.create(UISettingsListener::class.java) @@ -162,9 +174,8 @@ class UISettings : BaseState(), PersistentStateComponent { init { tweakPlatformDefaults() - val scrollToSource = WelcomeWizardUtil.getAutoScrollToSource() - if (scrollToSource != null) { - DEFAULT_AUTOSCROLL_TO_SOURCE = scrollToSource + WelcomeWizardUtil.getAutoScrollToSource()?.let { + defaultAutoScrollToSource = it } } @@ -177,8 +188,8 @@ class UISettings : BaseState(), PersistentStateComponent { // TODO[anton] consider making all IDEs use the same settings if (PlatformUtils.isAppCode()) { scrollTabLayoutInEditor = true - ACTIVATE_RIGHT_EDITOR_ON_CLOSE = true - SHOW_ICONS_IN_MENUS = false + activeRigtEditorOnClose = true + showIconsInMenus = false } } @@ -215,6 +226,8 @@ class UISettings : BaseState(), PersistentStateComponent { SHOW_CLOSE_BUTTON = showCloseButton EDITOR_AA_TYPE = editorAAType PRESENTATION_MODE = presentationMode + OVERRIDE_NONIDEA_LAF_FONTS = overrideLafFonts + PRESENTATION_MODE_FONT_SIZE = presentationModeFontSize } private fun initDefFont() { @@ -253,11 +266,11 @@ class UISettings : BaseState(), PersistentStateComponent { } // Check that alpha delay and ratio are valid - if (ALPHA_MODE_DELAY < 0) { - ALPHA_MODE_DELAY = 1500 + if (alphaModeDelay < 0) { + alphaModeDelay = 1500 } - if (ALPHA_MODE_RATIO < 0.0f || ALPHA_MODE_RATIO > 1.0f) { - ALPHA_MODE_RATIO = 0.5f + if (alphaModeRatio < 0.0f || alphaModeRatio > 1.0f) { + alphaModeRatio = 0.5f } if (FONT_SCALE <= 0) { @@ -292,8 +305,8 @@ class UISettings : BaseState(), PersistentStateComponent { } } - if (MAX_CLIPBOARD_CONTENTS <= 0) { - MAX_CLIPBOARD_CONTENTS = 5 + if (maxClipboardContents <= 0) { + maxClipboardContents = 5 } fireUISettingsChanged() diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java index e42d4b8dbf49..7aa8ec44f53b 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/AnAction.java @@ -80,14 +80,14 @@ public abstract class AnAction implements PossiblyDumbAware { /** - * Creates a new action with its text, description and icon set to null. + * Creates a new action with its text, description and icon set to {@code null}. */ public AnAction(){ this(null, null, null); } /** - * Creates a new action with icon provided. Its text, description set to null. + * Creates a new action with {@code icon} provided. Its text, description set to {@code null}. * * @param icon Default icon to appear in toolbars and menus (Note some platform don't have icons in menu). */ @@ -97,7 +97,7 @@ public abstract class AnAction implements PossiblyDumbAware { /** * Creates a new action with the specified text. Description and icon are - * set to null. + * set to {@code null}. * * @param text Serves as a tooltip when the presentation is a button and the name of the * menu item when the presentation is a menu item. @@ -167,12 +167,7 @@ public abstract class AnAction implements PossiblyDumbAware { } if (parentDisposable != null) { - Disposer.register(parentDisposable, new Disposable() { - @Override - public void dispose() { - unregisterCustomShortcutSet(component); - } - }); + Disposer.register(parentDisposable, () -> unregisterCustomShortcutSet(component)); } } @@ -184,9 +179,9 @@ public abstract class AnAction implements PossiblyDumbAware { } /** - * Copies template presentation and shortcuts set from sourceAction. + * Copies template presentation and shortcuts set from {@code sourceAction}. * - * @param sourceAction cannot be null + * @param sourceAction cannot be {@code null} */ public final void copyFrom(@NotNull AnAction sourceAction){ Presentation sourcePresentation = sourceAction.getTemplatePresentation(); diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java index cd9118850203..e82dc8cf32e5 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/CustomShortcutSet.java @@ -15,7 +15,6 @@ */ package com.intellij.openapi.actionSystem; -import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -32,7 +31,7 @@ public final class CustomShortcutSet implements ShortcutSet { private final Shortcut[] myShortcuts; /** - * Creates CustomShortcutSet which contains only one + * Creates {@code CustomShortcutSet} which contains only one * single stroke keyboard shortcut. */ public CustomShortcutSet(@NotNull KeyStroke keyStroke){ @@ -40,7 +39,7 @@ public final class CustomShortcutSet implements ShortcutSet { } /** - * Creates CustomShortcutSet which contains specified keyboard and + * Creates {@code CustomShortcutSet} which contains specified keyboard and * mouse shortcuts. * * @param shortcuts keyboard shortcuts @@ -49,7 +48,7 @@ public final class CustomShortcutSet implements ShortcutSet { myShortcuts = shortcuts.length == 0 ? Shortcut.EMPTY_ARRAY : shortcuts.clone(); } - public CustomShortcutSet(Integer... keyCodes) { + public CustomShortcutSet(@NotNull Integer... keyCodes) { myShortcuts = ContainerUtil.map(keyCodes, integer -> new KeyboardShortcut(KeyStroke.getKeyStroke(integer, 0), null), Shortcut.EMPTY_ARRAY); } diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java index bcb6815a85f9..205df557d1c7 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -137,7 +137,7 @@ public final class Presentation implements Cloneable { if (i >= text.length()) break; ch = text.charAt(i); if (ch != '_' && ch != '&') { - if (UISettings.getInstance().DISABLE_MNEMONICS_IN_CONTROLS) { + if (UISettings.getInstance().getDisableMnemonicsInControls()) { myMnemonic = 0; myDisplayedMnemonicIndex = -1; } diff --git a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java index e9dbdb62fc56..3f81b82c6725 100644 --- a/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java +++ b/platform/editor-ui-ex/src/com/intellij/openapi/editor/colors/impl/AbstractColorsScheme.java @@ -219,9 +219,10 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme, Serial @Override public Font getFont(EditorFontType key) { - if (UISettings.getInstance().getPresentationMode()) { + UISettings uiSettings = UISettings.getInstance(); + if (uiSettings.getPresentationMode()) { final Font font = myFonts.get(key); - return new Font(font.getName(), font.getStyle(), UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE); + return new Font(font.getName(), font.getStyle(), uiSettings.getPresentationModeFontSize()); } return myFonts.get(key); } diff --git a/platform/lang-api/src/com/intellij/execution/dashboard/DashboardGroupingRule.java b/platform/lang-api/src/com/intellij/execution/dashboard/DashboardGroupingRule.java index 902d2e23c798..2d01a48ee6a9 100644 --- a/platform/lang-api/src/com/intellij/execution/dashboard/DashboardGroupingRule.java +++ b/platform/lang-api/src/com/intellij/execution/dashboard/DashboardGroupingRule.java @@ -23,12 +23,12 @@ import org.jetbrains.annotations.Nullable; import java.util.Comparator; /** - * Action for grouping items in a runtime dashboard tree. + * Action for grouping items in a run dashboard tree. * * @author konstantin.aleev */ public interface DashboardGroupingRule extends TreeAction { - ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.runtimeDashboardGroupingRule"); + ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.runDashboardGroupingRule"); Comparator PRIORITY_COMPARATOR = (o1, o2) -> { final int res = o2.getPriority() - o1.getPriority(); diff --git a/platform/lang-api/src/com/intellij/execution/dashboard/DashboardRunConfigurationStatus.java b/platform/lang-api/src/com/intellij/execution/dashboard/DashboardRunConfigurationStatus.java index d0783e37506c..41b577ae26af 100644 --- a/platform/lang-api/src/com/intellij/execution/dashboard/DashboardRunConfigurationStatus.java +++ b/platform/lang-api/src/com/intellij/execution/dashboard/DashboardRunConfigurationStatus.java @@ -25,11 +25,11 @@ import javax.swing.*; */ public class DashboardRunConfigurationStatus { public static final DashboardRunConfigurationStatus STARTED = new DashboardRunConfigurationStatus( - ExecutionBundle.message("runtime.dashboard.started.group.name"), AllIcons.Toolwindows.ToolWindowRun); + ExecutionBundle.message("run.dashboard.started.group.name"), AllIcons.Toolwindows.ToolWindowRun); public static final DashboardRunConfigurationStatus STOPPED = new DashboardRunConfigurationStatus( - ExecutionBundle.message("runtime.dashboard.stopped.group.name"), AllIcons.Actions.Suspend); + ExecutionBundle.message("run.dashboard.stopped.group.name"), AllIcons.Actions.Suspend); public static final DashboardRunConfigurationStatus FAILED = new DashboardRunConfigurationStatus( - ExecutionBundle.message("runtime.dashboard.failed.group.name"), AllIcons.General.Error); + ExecutionBundle.message("run.dashboard.failed.group.name"), AllIcons.General.Error); private final String myName; private final Icon myIcon; diff --git a/platform/lang-api/src/com/intellij/execution/dashboard/RuntimeDashboardContributor.java b/platform/lang-api/src/com/intellij/execution/dashboard/RunDashboardContributor.java similarity index 84% rename from platform/lang-api/src/com/intellij/execution/dashboard/RuntimeDashboardContributor.java rename to platform/lang-api/src/com/intellij/execution/dashboard/RunDashboardContributor.java index d94be223954d..f1b5a98281db 100644 --- a/platform/lang-api/src/com/intellij/execution/dashboard/RuntimeDashboardContributor.java +++ b/platform/lang-api/src/com/intellij/execution/dashboard/RunDashboardContributor.java @@ -24,18 +24,18 @@ import com.intellij.openapi.util.registry.Registry; import org.jetbrains.annotations.ApiStatus; /** - * In order to show run configurations of the specific configuration type in Runtime Dashboard tool window, + * In order to show run configurations of the specific configuration type in Run Dashboard tool window, * one should register this extension. * * @author konstantin.aleev */ @ApiStatus.Experimental -public abstract class RuntimeDashboardContributor { - public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.runtimeDashboardContributor"); +public abstract class RunDashboardContributor { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.runDashboardContributor"); private final ConfigurationType myType; - protected RuntimeDashboardContributor(ConfigurationType type) { + protected RunDashboardContributor(ConfigurationType type) { myType = type; } @@ -74,13 +74,13 @@ public abstract class RuntimeDashboardContributor { return DashboardRunConfigurationStatus.FAILED; } - public static RuntimeDashboardContributor getContributor(ConfigurationType type) { - if (!Registry.is("ide.runtime.dashboard")) { + public static RunDashboardContributor getContributor(ConfigurationType type) { + if (!Registry.is("ide.run.dashboard")) { return null; } if (type != null) { - for (RuntimeDashboardContributor contributor : EP_NAME.getExtensions()) { + for (RunDashboardContributor contributor : EP_NAME.getExtensions()) { if (type.equals(contributor.getType())) { return contributor; } diff --git a/platform/lang-api/src/com/intellij/execution/dashboard/RuntimeDashboardManager.java b/platform/lang-api/src/com/intellij/execution/dashboard/RunDashboardManager.java similarity index 78% rename from platform/lang-api/src/com/intellij/execution/dashboard/RuntimeDashboardManager.java rename to platform/lang-api/src/com/intellij/execution/dashboard/RunDashboardManager.java index 8f8dcaf311b8..9f0194c372c9 100644 --- a/platform/lang-api/src/com/intellij/execution/dashboard/RuntimeDashboardManager.java +++ b/platform/lang-api/src/com/intellij/execution/dashboard/RunDashboardManager.java @@ -25,12 +25,12 @@ import javax.swing.*; /** * @author konstantin.aleev */ -public interface RuntimeDashboardManager { +public interface RunDashboardManager { Topic DASHBOARD_TOPIC = - Topic.create("runtime dashboard", DashboardListener.class, Topic.BroadcastDirection.TO_PARENT); + Topic.create("run dashboard", DashboardListener.class, Topic.BroadcastDirection.TO_PARENT); - static RuntimeDashboardManager getInstance(Project project) { - return ServiceManager.getService(project, RuntimeDashboardManager.class); + static RunDashboardManager getInstance(Project project) { + return ServiceManager.getService(project, RunDashboardManager.class); } ContentManager getDashboardContentManager(); diff --git a/platform/lang-impl/src/com/intellij/application/options/CodeCompletion.form b/platform/lang-impl/src/com/intellij/application/options/CodeCompletion.form index 1d2a2b2a43cf..a79987b49f5c 100644 --- a/platform/lang-impl/src/com/intellij/application/options/CodeCompletion.form +++ b/platform/lang-impl/src/com/intellij/application/options/CodeCompletion.form @@ -71,7 +71,7 @@ - + @@ -156,9 +156,6 @@ - - - diff --git a/platform/lang-impl/src/com/intellij/application/options/CodeCompletionPanel.java b/platform/lang-impl/src/com/intellij/application/options/CodeCompletionPanel.java index 827654bff279..1fadf1954509 100644 --- a/platform/lang-impl/src/com/intellij/application/options/CodeCompletionPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/CodeCompletionPanel.java @@ -43,6 +43,7 @@ public class CodeCompletionPanel { private JCheckBox myCbAutopopupJavaDoc; private JTextField myAutopopupJavaDocField; + private JLabel myAutoInsertLabel; private JCheckBox myCbOnCodeCompletion; private JCheckBox myCbOnSmartTypeCompletion; @@ -101,6 +102,9 @@ public class CodeCompletionPanel { ); hideOption(myCbOnSmartTypeCompletion, OptionId.COMPLETION_SMART_TYPE); + hideOption(myCbOnCodeCompletion, OptionId.AUTOCOMPLETE_ON_BASIC_CODE_COMPLETION); + if(!myCbOnSmartTypeCompletion.isVisible() && !myCbOnCodeCompletion.isVisible()) + myAutoInsertLabel.setVisible(false); reset(); } diff --git a/platform/lang-impl/src/com/intellij/application/options/OptionId.java b/platform/lang-impl/src/com/intellij/application/options/OptionId.java index 2c2f6bcd146c..b2df40ba4094 100644 --- a/platform/lang-impl/src/com/intellij/application/options/OptionId.java +++ b/platform/lang-impl/src/com/intellij/application/options/OptionId.java @@ -26,6 +26,7 @@ public class OptionId { public static final OptionId RENAME_IN_PLACE = new OptionId(); public static final OptionId COMPLETION_SHOW_STATIC_AFTER_IMPORT = new OptionId(); public static final OptionId COMPLETION_SMART_TYPE = new OptionId(); + public static final OptionId AUTOCOMPLETE_ON_BASIC_CODE_COMPLETION = new OptionId(); @Deprecated public static final OptionId COMPLETION_CLASS_NAME = new OptionId(); public static final OptionId ICONS_IN_GUTTER = new OptionId(); } diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java index b0f099416df4..0e2ebe076e60 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.java @@ -187,7 +187,7 @@ public class EditorOptionsPanel implements SearchableConfigurable { myCbVirtualPageAtBottom.setSelected(editorSettings.isAdditionalPageAtBottom()); // Limits - myClipboardContentLimitTextField.setText(Integer.toString(uiSettings.MAX_CLIPBOARD_CONTENTS)); + myClipboardContentLimitTextField.setText(Integer.toString(uiSettings.getMaxClipboardContents())); // Strip trailing spaces on save @@ -283,8 +283,8 @@ public class EditorOptionsPanel implements SearchableConfigurable { boolean uiSettingsChanged = false; int maxClipboardContents = getMaxClipboardContents(); - if (uiSettings.MAX_CLIPBOARD_CONTENTS != maxClipboardContents) { - uiSettings.MAX_CLIPBOARD_CONTENTS = maxClipboardContents; + if (uiSettings.getMaxClipboardContents() != maxClipboardContents) { + uiSettings.setMaxClipboardContents(maxClipboardContents); uiSettingsChanged = true; } @@ -449,7 +449,7 @@ public class EditorOptionsPanel implements SearchableConfigurable { // Limits - isModified |= getMaxClipboardContents() != uiSettings.MAX_CLIPBOARD_CONTENTS; + isModified |= getMaxClipboardContents() != uiSettings.getMaxClipboardContents(); // Paste diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java index 5505f0a6fb59..7425c44b4877 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorTabsConfigurable.java @@ -117,28 +117,28 @@ public class EditorTabsConfigurable implements EditorOptionsProvider { public void reset() { UISettings uiSettings=UISettings.getInstance(); - myCbModifiedTabsMarkedWithAsterisk.setSelected(uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK); - myShowTabsTooltipsCheckBox.setSelected(uiSettings.SHOW_TABS_TOOLTIPS); + myCbModifiedTabsMarkedWithAsterisk.setSelected(uiSettings.getMarkModifiedTabsWithAsterisk()); + myShowTabsTooltipsCheckBox.setSelected(uiSettings.getShowTabsTooltips()); myScrollTabLayoutInEditorCheckBox.setSelected(uiSettings.getScrollTabLayoutInEditor()); myHideTabsCheckbox.setEnabled(myScrollTabLayoutInEditorCheckBox.isSelected()); myHideTabsCheckbox.setSelected(uiSettings.getHideTabsIfNeed()); myEditorTabPlacement.setSelectedItem(uiSettings.getEditorTabPlacement()); - myHideKnownExtensions.setSelected(uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS); - myShowDirectoryInTabCheckBox.setSelected(uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES); + myHideKnownExtensions.setSelected(uiSettings.getHdeKnownExtensionInTabs()); + myShowDirectoryInTabCheckBox.setSelected(uiSettings.getShowDirectoryForNonUniqueFilenames()); myEditorTabLimitField.setText(Integer.toString(uiSettings.EDITOR_TAB_LIMIT)); myReuseNotModifiedTabsCheckBox.setSelected(uiSettings.getReuseNotModifiedTabs()); myShowCloseButtonOnCheckBox.setSelected(uiSettings.getShowCloseButton()); - if (uiSettings.CLOSE_NON_MODIFIED_FILES_FIRST) { + if (uiSettings.getCloseNonModifiedFilesFirst()) { myCloseNonModifiedFilesFirstRadio.setSelected(true); } else { myCloseLRUFilesRadio.setSelected(true); } - if (uiSettings.ACTIVATE_MRU_EDITOR_ON_CLOSE) { + if (uiSettings.getActiveMruEditorOnClose()) { myActivateMRUEditorOnCloseRadio.setSelected(true); } - else if (uiSettings.ACTIVATE_RIGHT_EDITOR_ON_CLOSE) { + else if (uiSettings.getActiveRigtEditorOnClose()) { myActivateRightNeighbouringTabRadioButton.setSelected(true); } else { @@ -150,11 +150,11 @@ public class EditorTabsConfigurable implements EditorOptionsProvider { public void apply() throws ConfigurationException { UISettings uiSettings=UISettings.getInstance(); - boolean uiSettingsChanged = uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK != myCbModifiedTabsMarkedWithAsterisk.isSelected(); - uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK = myCbModifiedTabsMarkedWithAsterisk.isSelected(); + boolean uiSettingsChanged = uiSettings.getMarkModifiedTabsWithAsterisk() != myCbModifiedTabsMarkedWithAsterisk.isSelected(); + uiSettings.setMarkModifiedTabsWithAsterisk(myCbModifiedTabsMarkedWithAsterisk.isSelected()); - if (isModified(myShowTabsTooltipsCheckBox, uiSettings.SHOW_TABS_TOOLTIPS)) uiSettingsChanged = true; - uiSettings.SHOW_TABS_TOOLTIPS = myShowTabsTooltipsCheckBox.isSelected(); + if (isModified(myShowTabsTooltipsCheckBox, uiSettings.getShowTabsTooltips())) uiSettingsChanged = true; + uiSettings.setShowTabsTooltips(myShowTabsTooltipsCheckBox.isSelected()); if (isModified(myScrollTabLayoutInEditorCheckBox, uiSettings.getScrollTabLayoutInEditor())) uiSettingsChanged = true; uiSettings.setScrollTabLayoutInEditor(myScrollTabLayoutInEditorCheckBox.isSelected()); @@ -170,16 +170,16 @@ public class EditorTabsConfigurable implements EditorOptionsProvider { uiSettings.setEditorTabPlacement(tabPlacement); boolean hide = myHideKnownExtensions.isSelected(); - if (uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS != hide) uiSettingsChanged = true; - uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS = hide; + if (uiSettings.getHdeKnownExtensionInTabs() != hide) uiSettingsChanged = true; + uiSettings.setHdeKnownExtensionInTabs(hide); boolean dir = myShowDirectoryInTabCheckBox.isSelected(); - if (uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES != dir) uiSettingsChanged = true; - uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES = dir; + if (uiSettings.getShowDirectoryForNonUniqueFilenames() != dir) uiSettingsChanged = true; + uiSettings.setShowDirectoryForNonUniqueFilenames(dir); - uiSettings.CLOSE_NON_MODIFIED_FILES_FIRST = myCloseNonModifiedFilesFirstRadio.isSelected(); - uiSettings.ACTIVATE_MRU_EDITOR_ON_CLOSE = myActivateMRUEditorOnCloseRadio.isSelected(); - uiSettings.ACTIVATE_RIGHT_EDITOR_ON_CLOSE = myActivateRightNeighbouringTabRadioButton.isSelected(); + uiSettings.setCloseNonModifiedFilesFirst(myCloseNonModifiedFilesFirstRadio.isSelected()); + uiSettings.setActiveMruEditorOnClose(myActivateMRUEditorOnCloseRadio.isSelected()); + uiSettings.setActiveRigtEditorOnClose(myActivateRightNeighbouringTabRadioButton.isSelected()); if (isModified(myReuseNotModifiedTabsCheckBox, uiSettings.getReuseNotModifiedTabs())) uiSettingsChanged = true; uiSettings.setReuseNotModifiedTabs(myReuseNotModifiedTabsCheckBox.isSelected()); @@ -198,31 +198,26 @@ public class EditorTabsConfigurable implements EditorOptionsProvider { @Override public boolean isModified() { final UISettings uiSettings = UISettings.getInstance(); - boolean isModified = isModified(myCbModifiedTabsMarkedWithAsterisk, uiSettings.MARK_MODIFIED_TABS_WITH_ASTERISK); - isModified |= isModified(myShowTabsTooltipsCheckBox, uiSettings.SHOW_TABS_TOOLTIPS); + boolean isModified = isModified(myCbModifiedTabsMarkedWithAsterisk, uiSettings.getMarkModifiedTabsWithAsterisk()); + isModified |= isModified(myShowTabsTooltipsCheckBox, uiSettings.getShowTabsTooltips()); isModified |= isModified(myEditorTabLimitField, uiSettings.EDITOR_TAB_LIMIT); isModified |= isModified(myReuseNotModifiedTabsCheckBox, uiSettings.getReuseNotModifiedTabs()); int tabPlacement = ((Integer)myEditorTabPlacement.getSelectedItem()).intValue(); isModified |= tabPlacement != uiSettings.getEditorTabPlacement(); - isModified |= myHideKnownExtensions.isSelected() != uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS; - isModified |= myShowDirectoryInTabCheckBox.isSelected() != uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES; + isModified |= myHideKnownExtensions.isSelected() != uiSettings.getHdeKnownExtensionInTabs(); + isModified |= myShowDirectoryInTabCheckBox.isSelected() != uiSettings.getShowDirectoryForNonUniqueFilenames(); isModified |= myScrollTabLayoutInEditorCheckBox.isSelected() != uiSettings.getScrollTabLayoutInEditor(); isModified |= myHideTabsCheckbox.isSelected() != uiSettings.getHideTabsIfNeed(); isModified |= myShowCloseButtonOnCheckBox.isSelected() != uiSettings.getShowCloseButton(); - isModified |= isModified(myCloseNonModifiedFilesFirstRadio, uiSettings.CLOSE_NON_MODIFIED_FILES_FIRST); - isModified |= isModified(myActivateMRUEditorOnCloseRadio, uiSettings.ACTIVATE_MRU_EDITOR_ON_CLOSE); - isModified |= isModified(myActivateRightNeighbouringTabRadioButton, uiSettings.ACTIVATE_RIGHT_EDITOR_ON_CLOSE); + isModified |= isModified(myCloseNonModifiedFilesFirstRadio, uiSettings.getCloseNonModifiedFilesFirst()); + isModified |= isModified(myActivateMRUEditorOnCloseRadio, uiSettings.getActiveMruEditorOnClose()); + isModified |= isModified(myActivateRightNeighbouringTabRadioButton, uiSettings.getActiveRigtEditorOnClose()); return isModified; } - @Override - public void disposeUIResources() { - } - - private static boolean isModified(JTextField textField, int value) { try { int fieldValue = Integer.parseInt(textField.getText().trim()); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index 87928d9422e7..03c9536b6a55 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -279,7 +279,7 @@ public class CompletionLookupArranger extends LookupArranger { private static void ensureEverythingVisibleAdded(LookupImpl lookup, final LinkedHashSet model, Iterator byRelevance) { JList list = lookup.getList(); final boolean testMode = ApplicationManager.getApplication().isUnitTestMode(); - final int limit = Math.max(list.getLastVisibleIndex(), model.size()) + ourUISettings.MAX_LOOKUP_LIST_HEIGHT * 3; + final int limit = Math.max(list.getLastVisibleIndex(), model.size()) + ourUISettings.getMaxLookupListHeight() * 3; addSomeItems(model, byRelevance, lastAdded -> !testMode && model.size() >= limit); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java index ca7c807f6661..fb9da4c0dcd7 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ExternalToolPass.java @@ -16,7 +16,9 @@ package com.intellij.codeInsight.daemon.impl; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInsight.daemon.impl.analysis.HighlightingLevelManager; +import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.lang.ExternalLanguageAnnotators; import com.intellij.lang.Language; import com.intellij.lang.annotation.Annotation; @@ -25,11 +27,13 @@ import com.intellij.lang.annotation.ExternalAnnotator; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationManagerEx; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.TextRange; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiFile; import com.intellij.util.containers.HashMap; @@ -42,6 +46,7 @@ import java.util.*; * @author ven */ public class ExternalToolPass extends ProgressableTextEditorHighlightingPass { + private static final Logger LOG = Logger.getInstance(ExternalToolPass.class); private final AnnotationHolderImpl myAnnotationHolder; private final Map myAnnotator2DataMap = new HashMap<>(); @@ -99,6 +104,7 @@ public class ExternalToolPass extends ProgressableTextEditorHighlightingPass { } setProgressLimit(externalAnnotatorsInRoots); + InspectionProfileImpl profile = InspectionProjectProfileManager.getInstance(myProject).getCurrentProfile(); for (Language language : relevantLanguages) { PsiFile psiRoot = viewProvider.getPsi(language); if (!HighlightingLevelManager.getInstance(myProject).shouldInspect(psiRoot)) continue; @@ -109,6 +115,12 @@ public class ExternalToolPass extends ProgressableTextEditorHighlightingPass { boolean errorFound = daemonCodeAnalyzer.getFileStatusMap().wasErrorFound(myDocument); for(ExternalAnnotator externalAnnotator: externalAnnotators) { + String shortName = externalAnnotator.getPairedBatchInspectionShortName(); + if (shortName != null) { + HighlightDisplayKey key = HighlightDisplayKey.find(shortName); + LOG.assertTrue(key != null, "Paired tool '" + shortName + "' not found for external annotator: " + externalAnnotator); + if (!profile.isToolEnabled(key, myFile)) continue; + } final Object collectedInfo; Editor editor = getEditor(); if (editor != null) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java deleted file mode 100644 index acb2282b66d4..000000000000 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/EndHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2000-2015 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.codeInsight.lookup.impl; - -import com.intellij.codeInsight.lookup.LookupManager; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.editor.Caret; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.actionSystem.EditorActionHandler; -import com.intellij.ui.ScrollingUtil; - -public class EndHandler extends EditorActionHandler { - private final EditorActionHandler myOriginalHandler; - - public EndHandler(EditorActionHandler originalHandler){ - myOriginalHandler = originalHandler; - } - - @Override - public void doExecute(Editor editor, Caret caret, DataContext dataContext){ - LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor); - if (lookup == null || !lookup.isFocused()) { - myOriginalHandler.execute(editor, caret, dataContext); - return; - } - - lookup.markSelectionTouched(); - ScrollingUtil.moveEnd(lookup.getList()); - lookup.refreshUi(false, true); - } -} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java deleted file mode 100644 index 4b4439bfd5c7..000000000000 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/HomeHandler.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2000-2015 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.codeInsight.lookup.impl; - -import com.intellij.codeInsight.lookup.LookupManager; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.editor.Caret; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.editor.actionSystem.EditorActionHandler; -import com.intellij.ui.ScrollingUtil; - -public class HomeHandler extends EditorActionHandler { - private final EditorActionHandler myOriginalHandler; - - public HomeHandler(EditorActionHandler originalHandler){ - myOriginalHandler = originalHandler; - } - - @Override - public void doExecute(Editor editor, Caret caret, DataContext dataContext){ - LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(editor); - if (lookup == null || !lookup.isFocused()) { - myOriginalHandler.execute(editor, caret, dataContext); - return; - } - - lookup.markSelectionTouched(); - ScrollingUtil.moveHome(lookup.getList()); - } -} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index e9201725ac6e..1150440b47b9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -432,7 +432,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable private void updateListHeight(ListModel model) { myList.setFixedCellHeight(myCellRenderer.getListCellRendererComponent(myList, model.getElementAt(0), 0, false, false).getPreferredSize().height); - myList.setVisibleRowCount(Math.min(model.getSize(), UISettings.getInstance().MAX_LOOKUP_LIST_HEIGHT)); + myList.setVisibleRowCount(Math.min(model.getSize(), UISettings.getInstance().getMaxLookupListHeight())); } private void addEmptyItem(CollectionListModel model) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java index 174c5b4c0cec..4201da08b1af 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupUi.java @@ -317,7 +317,7 @@ class LookupUi { public Dimension preferredLayoutSize(@Nullable Container parent) { int maxCellWidth = myLookup.myLookupTextWidth + myLookup.myCellRenderer.getTextIndent(); int scrollBarWidth = myScrollPane.getPreferredSize().width - myScrollPane.getViewport().getPreferredSize().width; - int listWidth = Math.min(scrollBarWidth + maxCellWidth, UISettings.getInstance().MAX_LOOKUP_WIDTH2); + int listWidth = Math.min(scrollBarWidth + maxCellWidth, UISettings.getInstance().getMaxLookupWidth()); Dimension adSize = myAdvertiser.getAdComponent().getPreferredSize(); @@ -337,12 +337,12 @@ class LookupUi { if (!myLookup.myResizePending) { Dimension preferredSize = preferredLayoutSize(null); if (preferredSize.width != size.width) { - UISettings.getInstance().MAX_LOOKUP_WIDTH2 = Math.max(500, size.width); + UISettings.getInstance().setMaxLookupWidth(Math.max(500, size.width)); } int listHeight = myList.getLastVisibleIndex() - myList.getFirstVisibleIndex() + 1; if (listHeight != myList.getModel().getSize() && listHeight != myList.getVisibleRowCount() && preferredSize.height != size.height) { - UISettings.getInstance().MAX_LOOKUP_LIST_HEIGHT = Math.max(5, listHeight); + UISettings.getInstance().setMaxLookupListHeight(Math.max(5, listHeight)); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/BackgroundUpdaterTask.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/BackgroundUpdaterTask.java index 455bb68d6b4c..dfb29c913b14 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/BackgroundUpdaterTask.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/BackgroundUpdaterTask.java @@ -104,26 +104,31 @@ public abstract class BackgroundUpdaterTask extends Task.Backgroundable { synchronized (lock) { if (myData.contains(element)) return true; myData.add(element); + if (comparator != null) { + Collections.sort(myData, comparator); + } } myAlarm.addRequest(() -> { myAlarm.cancelAllRequests(); - if (myCanceled) return; - if (myPopup.isDisposed()) return; - ArrayList data = new ArrayList<>(); - synchronized (lock) { - if (comparator != null) { - Collections.sort(myData, comparator); - } - data.addAll(myData); - } - replaceModel(data); - myPopup.setCaption(getCaption(getCurrentSize())); - myPopup.pack(true, true); + refreshModelImmediately(); }, 200, ModalityState.stateForComponent(content)); return true; } + private void refreshModelImmediately() { + ApplicationManager.getApplication().assertIsDispatchThread(); + if (myCanceled) return; + if (myPopup.isDisposed()) return; + List data; + synchronized (lock) { + data = new ArrayList<>(myData); + } + replaceModel(data); + myPopup.setCaption(getCaption(getCurrentSize())); + myPopup.pack(true, true); + } + public int getCurrentSize() { synchronized (lock) { return myData.size(); @@ -138,12 +143,13 @@ public abstract class BackgroundUpdaterTask extends Task.Backgroundable { @Override public void onSuccess() { - myPopup.setCaption(getCaption(getCurrentSize())); + refreshModelImmediately(); paintBusy(false); } @Override public void onFinished() { + myAlarm.cancelAllRequests(); myFinished = true; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java index c81f74a09a63..143a1b8bd150 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/GotoTargetHandler.java @@ -25,6 +25,7 @@ import com.intellij.ide.util.PsiElementListCellRenderer; import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.util.EditorUtil; @@ -225,7 +226,7 @@ public abstract class GotoTargetHandler implements CodeInsightActionHandler { } private Comparable getComparingObject(PsiElement o1) { - return getRenderer(o1, targetsWithRenderers, gotoData).getComparingObject(o1); + return ReadAction.compute(() -> getRenderer(o1, targetsWithRenderers, gotoData).getComparingObject(o1)); } }; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java index 7c227b46d689..3d33484f70c5 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/GlobalInspectionContextImpl.java @@ -94,6 +94,7 @@ import java.io.OutputStreamWriter; import java.lang.reflect.Constructor; import java.util.*; import java.util.concurrent.*; +import java.util.stream.Collectors; public class GlobalInspectionContextImpl extends GlobalInspectionContextBase implements GlobalInspectionContext { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.GlobalInspectionContextImpl"); @@ -424,6 +425,14 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp throw new ProcessCanceledException(); } + getWrappersFromTools(localTools, file, includeDoNotShow(getCurrentProfile())).stream() + .filter(wrapper -> wrapper.getTool() instanceof ExternalAnnotatorBatchInspection) + .forEach(wrapper -> { + ProblemDescriptor[] descriptors = ((ExternalAnnotatorBatchInspection)wrapper.getTool()).checkFile(file, inspectionManager); + InspectionToolPresentation toolPresentation = getPresentation(wrapper); + ReadAction.run(() -> LocalDescriptorsUtil.addProblemDescriptors(Arrays.asList(descriptors), false, this, null, CONVERT, toolPresentation)); + }); + return true; }; try { @@ -496,7 +505,8 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp try { boolean includeDoNotShow = includeDoNotShow(getCurrentProfile()); final List lTools = getWrappersFromTools(localTools, file, includeDoNotShow); - pass.doInspectInBatch(this, inspectionManager, lTools); + List nonExternalAnnotators = lTools.stream().filter(wrapper -> !(wrapper.getTool() instanceof ExternalAnnotatorBatchInspection)).collect(Collectors.toList()); + pass.doInspectInBatch(this, inspectionManager, nonExternalAnnotators); final List tools = getWrappersFromTools(globalSimpleTools, file, includeDoNotShow); JobLauncher.getInstance().invokeConcurrentlyUnderProgress(tools, myProgressIndicator, false, toolWrapper -> { diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/RuntimeDashboardContent.java b/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardContent.java similarity index 89% rename from platform/lang-impl/src/com/intellij/execution/dashboard/RuntimeDashboardContent.java rename to platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardContent.java index 5636945ef8e7..a1d66f9cd1b4 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/RuntimeDashboardContent.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardContent.java @@ -17,7 +17,7 @@ package com.intellij.execution.dashboard; import com.intellij.execution.*; import com.intellij.execution.dashboard.tree.DashboardGrouper; -import com.intellij.execution.dashboard.tree.RuntimeDashboardTreeStructure; +import com.intellij.execution.dashboard.tree.RunDashboardTreeStructure; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.ide.CommonActionsManager; @@ -58,11 +58,11 @@ import java.util.Set; /** * @author konstantin.aleev */ -public class RuntimeDashboardContent extends JPanel implements TreeContent, Disposable { - public static final DataKey KEY = DataKey.create("runtimeDashboardContent"); - @NonNls private static final String PLACE_TOOLBAR = "RuntimeDashboardContent#Toolbar"; - @NonNls private static final String RUNTIME_DASHBOARD_TOOLBAR = "RuntimeDashboardToolbar"; - @NonNls private static final String RUNTIME_DASHBOARD_POPUP = "RuntimeDashboardPopup"; +public class RunDashboardContent extends JPanel implements TreeContent, Disposable { + public static final DataKey KEY = DataKey.create("runDashboardContent"); + @NonNls private static final String PLACE_TOOLBAR = "RunDashboardContent#Toolbar"; + @NonNls private static final String RUN_DASHBOARD_TOOLBAR = "RunDashboardToolbar"; + @NonNls private static final String RUN_DASHBOARD_POPUP = "RunDashboardPopup"; private static final String MESSAGE_CARD = "message"; private static final String CONTENT_CARD = "content"; @@ -83,7 +83,7 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp @NotNull private final Project myProject; - public RuntimeDashboardContent(@NotNull Project project, @NotNull ContentManager contentManager, @NotNull List groupers) { + public RunDashboardContent(@NotNull Project project, @NotNull ContentManager contentManager, @NotNull List groupers) { super(new BorderLayout()); myProject = project; myGroupers = groupers; @@ -102,7 +102,7 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp splitter.setFirstComponent(ScrollPaneFactory.createScrollPane(myTree, SideBorder.LEFT)); myDetailsPanelLayout = new CardLayout(); myDetailsPanel = new JPanel(myDetailsPanelLayout); - myMessagePanel = new JBPanelWithEmptyText().withEmptyText(ExecutionBundle.message("runtime.dashboard.empty.selection.message")); + myMessagePanel = new JBPanelWithEmptyText().withEmptyText(ExecutionBundle.message("run.dashboard.empty.selection.message")); myDetailsPanel.add(MESSAGE_CARD, myMessagePanel); splitter.setSecondComponent(myDetailsPanel); add(splitter, BorderLayout.CENTER); @@ -163,9 +163,9 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp }); DefaultActionGroup popupActionGroup = new DefaultActionGroup(); - popupActionGroup.add(ActionManager.getInstance().getAction(RUNTIME_DASHBOARD_TOOLBAR)); - popupActionGroup.add(ActionManager.getInstance().getAction(RUNTIME_DASHBOARD_POPUP)); - PopupHandler.installPopupHandler(myTree, popupActionGroup, ActionPlaces.RUNTIME_DASHBOARD_POPUP, ActionManager.getInstance()); + popupActionGroup.add(ActionManager.getInstance().getAction(RUN_DASHBOARD_TOOLBAR)); + popupActionGroup.add(ActionManager.getInstance().getAction(RUN_DASHBOARD_POPUP)); + PopupHandler.installPopupHandler(myTree, popupActionGroup, ActionPlaces.RUN_DASHBOARD_POPUP, ActionManager.getInstance()); new TreeSpeedSearch(myTree, TreeSpeedSearch.NODE_DESCRIPTOR_TOSTRING, true); } @@ -173,7 +173,7 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp private void onSelectionChanged() { Set nodes = myBuilder.getSelectedElements(AbstractTreeNode.class); if (nodes.size() != 1) { - showMessagePanel(ExecutionBundle.message("runtime.dashboard.empty.selection.message")); + showMessagePanel(ExecutionBundle.message("run.dashboard.empty.selection.message")); myLastSelection = null; return; } @@ -196,12 +196,12 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp return; } if (node instanceof DashboardRunConfigurationNode) { - showMessagePanel(ExecutionBundle.message("runtime.dashboard.not.started.configuration.message")); + showMessagePanel(ExecutionBundle.message("run.dashboard.not.started.configuration.message")); return; } } - showMessagePanel(ExecutionBundle.message("runtime.dashboard.empty.selection.message")); + showMessagePanel(ExecutionBundle.message("run.dashboard.empty.selection.message")); } private void showMessagePanel(String text) { @@ -221,7 +221,7 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp } private void setupBuilder() { - RuntimeDashboardTreeStructure structure = new RuntimeDashboardTreeStructure(myProject, myGroupers); + RunDashboardTreeStructure structure = new RunDashboardTreeStructure(myProject, myGroupers); myBuilder = new AbstractTreeBuilder(myTree, myTreeModel, structure, IndexComparator.INSTANCE) { @Override protected boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) { @@ -262,7 +262,7 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp updateTreeIfNeeded(env.getRunnerAndConfigurationSettings()); } }); - connection.subscribe(RuntimeDashboardManager.DASHBOARD_TOPIC, new DashboardListener() { + connection.subscribe(RunDashboardManager.DASHBOARD_TOPIC, new DashboardListener() { @Override public void contentChanged(boolean withStructure) { updateTree(withStructure); @@ -281,7 +281,7 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp } private void updateTreeIfNeeded(@Nullable RunnerAndConfigurationSettings settings) { - if (settings != null && RuntimeDashboardContributor.isShowInDashboard(settings.getType())) { + if (settings != null && RunDashboardContributor.isShowInDashboard(settings.getType())) { updateTree(true); } } @@ -289,7 +289,7 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp private JComponent createToolbar() { JPanel toolBarPanel = new JPanel(new GridLayout()); DefaultActionGroup leftGroup = new DefaultActionGroup(); - leftGroup.add(ActionManager.getInstance().getAction(RUNTIME_DASHBOARD_TOOLBAR)); + leftGroup.add(ActionManager.getInstance().getAction(RUN_DASHBOARD_TOOLBAR)); // TODO [konstantin.aleev] provide context help ID //leftGroup.add(new Separator()); //leftGroup.add(new ContextHelpAction(HELP_ID)); @@ -301,7 +301,7 @@ public class RuntimeDashboardContent extends JPanel implements TreeContent, Disp @Override public Object getData(@NonNls String dataId) { if (KEY.getName().equals(dataId)) { - return RuntimeDashboardContent.this; + return RunDashboardContent.this; } return null; } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/RuntimeDashboardManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardManagerImpl.java similarity index 90% rename from platform/lang-impl/src/com/intellij/execution/dashboard/RuntimeDashboardManagerImpl.java rename to platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardManagerImpl.java index a4c748786096..c4f80f60bb02 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/RuntimeDashboardManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/RunDashboardManagerImpl.java @@ -46,14 +46,14 @@ import java.util.stream.Collectors; * @author konstantin.aleev */ @State( - name = "RuntimeDashboard", + name = "RunDashboard", storages = @Storage(StoragePathMacros.WORKSPACE_FILE) ) -public class RuntimeDashboardManagerImpl implements RuntimeDashboardManager, PersistentStateComponent { +public class RunDashboardManagerImpl implements RunDashboardManager, PersistentStateComponent { @NotNull private final ContentManager myContentManager; private List myGroupers = new ArrayList<>(); - public RuntimeDashboardManagerImpl(@NotNull final Project project) { + public RunDashboardManagerImpl(@NotNull final Project project) { ContentFactory contentFactory = ContentFactory.SERVICE.getInstance(); ContentUI contentUI = new PanelContentUI(); myContentManager = contentFactory.createContentManager(contentUI, false, project); @@ -68,13 +68,13 @@ public class RuntimeDashboardManagerImpl implements RuntimeDashboardManager, Per .map(DashboardGrouper::new) .collect(Collectors.toList()); - RuntimeDashboardContent dashboardContent = new RuntimeDashboardContent(project, myContentManager, myGroupers); + RunDashboardContent dashboardContent = new RunDashboardContent(project, myContentManager, myGroupers); Content content = contentFactory.createContent(dashboardContent, null, false); Disposer.register(content, dashboardContent); toolWindow.getContentManager().addContent(content); } - if (!Registry.is("ide.runtime.dashboard")) { + if (!Registry.is("ide.run.dashboard")) { toolWindow.setAvailable(false, null); } @@ -88,7 +88,7 @@ public class RuntimeDashboardManagerImpl implements RuntimeDashboardManager, Per @Override public String getToolWindowId() { - return ToolWindowId.RUNTIME_DASHBOARD; + return ToolWindowId.RUN_DASHBOARD; } @Override diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java index 05126ed327ae..c977ec3aa7f6 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java @@ -69,7 +69,7 @@ public class CopyConfigurationAction extends RunConfigurationTreeAction { } if (RunDialog.editConfiguration(node.getProject(), copiedSettings, - ExecutionBundle.message("runtime.dashboard.edit.configuration.dialog.title"))) { + ExecutionBundle.message("run.dashboard.edit.configuration.dialog.title"))) { runManager.addConfiguration(copiedSettings, runManager.isConfigurationShared(settings), runManager.getBeforeRunTasks(settings.getConfiguration()), false); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/DebugAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/DebugAction.java index 710302ed97c9..e43781358bd9 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/DebugAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/DebugAction.java @@ -26,8 +26,8 @@ import com.intellij.openapi.wm.ToolWindowId; */ public class DebugAction extends ExecutorAction { public DebugAction() { - super(ExecutionBundle.message("runtime.dashboard.debug.action.name"), - ExecutionBundle.message("runtime.dashboard.debug.action.description"), + super(ExecutionBundle.message("run.dashboard.debug.action.name"), + ExecutionBundle.message("run.dashboard.debug.action.description"), AllIcons.Toolwindows.ToolWindowDebugger); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/EditConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/EditConfigurationAction.java index d8f79c91e7fa..1622456db19a 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/EditConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/EditConfigurationAction.java @@ -26,8 +26,8 @@ import org.jetbrains.annotations.NotNull; public class EditConfigurationAction extends RunConfigurationTreeAction { public EditConfigurationAction() { - super(ExecutionBundle.message("runtime.dashboard.edit.configuration.action.name"), - ExecutionBundle.message("runtime.dashboard.edit.configuration.action.name"), + super(ExecutionBundle.message("run.dashboard.edit.configuration.action.name"), + ExecutionBundle.message("run.dashboard.edit.configuration.action.name"), AllIcons.Actions.EditSource); } @@ -35,7 +35,7 @@ public class EditConfigurationAction extends RunConfigurationTreeAction { public void update(@NotNull AnActionEvent e) { super.update(e); if (ActionPlaces.isPopupPlace(e.getPlace())) { - e.getPresentation().setText(ExecutionBundle.message("runtime.dashboard.edit.configuration.action.name") + "..."); + e.getPresentation().setText(ExecutionBundle.message("run.dashboard.edit.configuration.action.name") + "..."); } } @@ -48,6 +48,6 @@ public class EditConfigurationAction extends RunConfigurationTreeAction { @Override protected void doActionPerformed(DashboardRunConfigurationNode node) { RunDialog.editConfiguration(node.getProject(), node.getConfigurationSettings(), - ExecutionBundle.message("runtime.dashboard.edit.configuration.dialog.title")); + ExecutionBundle.message("run.dashboard.edit.configuration.dialog.title")); } } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/ExecutorAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/ExecutorAction.java index 6c50aab07137..21bcf4e23e56 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/ExecutorAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/ExecutorAction.java @@ -28,7 +28,7 @@ import javax.swing.*; /** * @author konstantin.aleev */ -public abstract class ExecutorAction extends RuntimeDashboardTreeLeafAction { +public abstract class ExecutorAction extends RunDashboardTreeLeafAction { protected ExecutorAction(String text, String description, Icon icon) { super(text, description, icon); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RemoveConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RemoveConfigurationAction.java index 8537ac79550c..d83295f0af97 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RemoveConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RemoveConfigurationAction.java @@ -19,7 +19,7 @@ import com.intellij.execution.ExecutionBundle; import com.intellij.execution.RunManager; import com.intellij.execution.RunManagerEx; import com.intellij.execution.dashboard.DashboardRunConfigurationNode; -import com.intellij.execution.dashboard.RuntimeDashboardContent; +import com.intellij.execution.dashboard.RunDashboardContent; import com.intellij.icons.AllIcons; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.project.Project; @@ -33,8 +33,8 @@ import java.util.List; */ public class RemoveConfigurationAction extends RunConfigurationTreeAction { public RemoveConfigurationAction() { - super(ExecutionBundle.message("runtime.dashboard.remove.configuration.action.name"), - ExecutionBundle.message("runtime.dashboard.remove.configuration.action.description"), + super(ExecutionBundle.message("run.dashboard.remove.configuration.action.name"), + ExecutionBundle.message("run.dashboard.remove.configuration.action.description"), AllIcons.General.Remove); } @@ -50,10 +50,10 @@ public class RemoveConfigurationAction extends RunConfigurationTreeAction { } @Override - protected void doActionPerformed(@NotNull RuntimeDashboardContent content, AnActionEvent e, List nodes) { + protected void doActionPerformed(@NotNull RunDashboardContent content, AnActionEvent e, List nodes) { if (Messages.showYesNoDialog((Project)null, - ExecutionBundle.message("runtime.dashboard.remove.configuration.dialog.message"), - ExecutionBundle.message("runtime.dashboard.remove.configuration.dialog.title"), + ExecutionBundle.message("run.dashboard.remove.configuration.dialog.message"), + ExecutionBundle.message("run.dashboard.remove.configuration.dialog.title"), Messages.getWarningIcon()) != Messages.YES) { return; diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunAction.java index 062ee8835682..3a6d363a4e92 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunAction.java @@ -25,8 +25,8 @@ import com.intellij.icons.AllIcons; */ public class RunAction extends ExecutorAction { public RunAction() { - super(ExecutionBundle.message("runtime.dashboard.run.action.name"), - ExecutionBundle.message("runtime.dashboard.run.action.description"), + super(ExecutionBundle.message("run.dashboard.run.action.name"), + ExecutionBundle.message("run.dashboard.run.action.description"), AllIcons.Toolwindows.ToolWindowRun); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunConfigurationTreeAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunConfigurationTreeAction.java index e1aca3e53e07..e7643cc6e034 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunConfigurationTreeAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunConfigurationTreeAction.java @@ -22,7 +22,7 @@ import javax.swing.*; /** * @author konstantin.aleev */ -public abstract class RunConfigurationTreeAction extends RuntimeDashboardTreeAction { +public abstract class RunConfigurationTreeAction extends RunDashboardTreeAction { protected RunConfigurationTreeAction(String text, String description, Icon icon) { super(text, description, icon); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RuntimeDashboardTreeAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunDashboardTreeAction.java similarity index 74% rename from platform/lang-impl/src/com/intellij/execution/dashboard/actions/RuntimeDashboardTreeAction.java rename to platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunDashboardTreeAction.java index d04a2d491191..918fd071ed29 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RuntimeDashboardTreeAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunDashboardTreeAction.java @@ -24,14 +24,14 @@ import javax.swing.*; /** * @author konstantin.aleev */ -public abstract class RuntimeDashboardTreeAction extends DashboardTreeAction { - protected RuntimeDashboardTreeAction(String text, String description, Icon icon) { +public abstract class RunDashboardTreeAction extends DashboardTreeAction { + protected RunDashboardTreeAction(String text, String description, Icon icon) { super(text, description, icon); } @Override - protected final RuntimeDashboardContent getTreeContent(AnActionEvent e) { - return e.getData(RuntimeDashboardContent.KEY); + protected final RunDashboardContent getTreeContent(AnActionEvent e) { + return e.getData(RunDashboardContent.KEY); } @Override diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RuntimeDashboardTreeLeafAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunDashboardTreeLeafAction.java similarity index 91% rename from platform/lang-impl/src/com/intellij/execution/dashboard/actions/RuntimeDashboardTreeLeafAction.java rename to platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunDashboardTreeLeafAction.java index 65c5cf7112b4..f333bb315636 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RuntimeDashboardTreeLeafAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RunDashboardTreeLeafAction.java @@ -27,8 +27,8 @@ import java.util.*; /** * @author konstantin.aleev */ -public abstract class RuntimeDashboardTreeLeafAction extends RuntimeDashboardTreeAction { - protected RuntimeDashboardTreeLeafAction(String text, String description, Icon icon) { +public abstract class RunDashboardTreeLeafAction extends RunDashboardTreeAction { + protected RunDashboardTreeLeafAction(String text, String description, Icon icon) { super(text, description, icon); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/StopAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/StopAction.java index d2b44aa8d2ca..8eda61cf2bb9 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/StopAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/StopAction.java @@ -29,10 +29,10 @@ import java.util.List; /** * @author konstantin.aleev */ -public class StopAction extends RuntimeDashboardTreeLeafAction { +public class StopAction extends RunDashboardTreeLeafAction { public StopAction() { - super(ExecutionBundle.message("runtime.dashboard.stop.action.name"), - ExecutionBundle.message("runtime.dashboard.stop.action.description"), + super(ExecutionBundle.message("run.dashboard.stop.action.name"), + ExecutionBundle.message("run.dashboard.stop.action.description"), AllIcons.Actions.Suspend); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/ConfigurationTypeDashboardGroupingRule.java b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/ConfigurationTypeDashboardGroupingRule.java index 857e4fe45397..13a4a87d8453 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/ConfigurationTypeDashboardGroupingRule.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/ConfigurationTypeDashboardGroupingRule.java @@ -44,8 +44,8 @@ public class ConfigurationTypeDashboardGroupingRule implements DashboardGrouping @NotNull @Override public ActionPresentation getPresentation() { - return new ActionPresentationData(ExecutionBundle.message("runtime.dashboard.group.by.type.action.name"), - ExecutionBundle.message("runtime.dashboard.group.by.type.action.name"), + return new ActionPresentationData(ExecutionBundle.message("run.dashboard.group.by.type.action.name"), + ExecutionBundle.message("run.dashboard.group.by.type.action.name"), AllIcons.Actions.GroupByFile); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/FolderDashboardGroupingRule.java b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/FolderDashboardGroupingRule.java index 00c8b46f27df..6362f280485d 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/FolderDashboardGroupingRule.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/FolderDashboardGroupingRule.java @@ -43,8 +43,8 @@ public class FolderDashboardGroupingRule implements DashboardGroupingRule { @NotNull @Override public ActionPresentation getPresentation() { - return new ActionPresentationData(ExecutionBundle.message("runtime.dashboard.group.by.folder.action.name"), - ExecutionBundle.message("runtime.dashboard.group.by.folder.action.name"), + return new ActionPresentationData(ExecutionBundle.message("run.dashboard.group.by.folder.action.name"), + ExecutionBundle.message("run.dashboard.group.by.folder.action.name"), AllIcons.Actions.GroupByPackage); } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/RunConfigurationNode.java b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/RunConfigurationNode.java index 996d702b0751..229b978701f2 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/RunConfigurationNode.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/RunConfigurationNode.java @@ -21,7 +21,7 @@ import com.intellij.execution.RunManagerEx; import com.intellij.execution.RunnerAndConfigurationSettings; import com.intellij.execution.dashboard.DashboardRunConfigurationNode; import com.intellij.execution.dashboard.DashboardRunConfigurationStatus; -import com.intellij.execution.dashboard.RuntimeDashboardContributor; +import com.intellij.execution.dashboard.RunDashboardContributor; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunContentManagerImpl; import com.intellij.ide.projectView.PresentationData; @@ -68,7 +68,7 @@ class RunConfigurationNode extends AbstractTreeNode myGroupers; private final RunConfigurationsTreeRootNode myRootElement; - public RuntimeDashboardTreeStructure(@NotNull Project project, @NotNull List groupers) { + public RunDashboardTreeStructure(@NotNull Project project, @NotNull List groupers) { super(project); myProject = project; myGroupers = groupers; @@ -72,7 +72,7 @@ public class RuntimeDashboardTreeStructure extends AbstractTreeStructureBase { public class RunConfigurationsTreeRootNode extends AbstractTreeNode { public RunConfigurationsTreeRootNode() { - super(RuntimeDashboardTreeStructure.this.myProject, new Object()); + super(RunDashboardTreeStructure.this.myProject, new Object()); } @NotNull @@ -81,7 +81,7 @@ public class RuntimeDashboardTreeStructure extends AbstractTreeStructureBase { List nodes = new ArrayList<>(); List configurations = RunManager.getInstance(myProject).getAllSettings().stream() - .filter(runConfiguration -> RuntimeDashboardContributor.isShowInDashboard(runConfiguration.getType())) + .filter(runConfiguration -> RunDashboardContributor.isShowInDashboard(runConfiguration.getType())) .collect(Collectors.toList()); //noinspection ConstantConditions ??? @@ -102,7 +102,7 @@ public class RuntimeDashboardTreeStructure extends AbstractTreeStructureBase { .collect(Collectors.toList()); List notStoredDescriptors = executionManager.getRunningDescriptors(settings -> { RunConfiguration configuration = settings.getConfiguration(); - return RuntimeDashboardContributor.isShowInDashboard(settings.getType()) && !storedConfigurations.contains(configuration); + return RunDashboardContributor.isShowInDashboard(settings.getType()) && !storedConfigurations.contains(configuration); }); notStoredDescriptors.forEach(descriptor -> { Set settings = executionManager.getConfigurations(descriptor); diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/StatusDashboardGroupingRule.java b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/StatusDashboardGroupingRule.java index 17bc4688ad11..3d5894ccdb25 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/StatusDashboardGroupingRule.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/StatusDashboardGroupingRule.java @@ -40,8 +40,8 @@ public class StatusDashboardGroupingRule implements DashboardGroupingRule { @NotNull @Override public ActionPresentation getPresentation() { - return new ActionPresentationData(ExecutionBundle.message("runtime.dashboard.group.by.status.action.name"), - ExecutionBundle.message("runtime.dashboard.group.by.status.action.name"), + return new ActionPresentationData(ExecutionBundle.message("run.dashboard.group.by.status.action.name"), + ExecutionBundle.message("run.dashboard.group.by.status.action.name"), AllIcons.Actions.GroupByPrefix); // TODO [konstantin.aleev] provide new icon } @@ -65,7 +65,7 @@ public class StatusDashboardGroupingRule implements DashboardGroupingRule { public DashboardGroup getGroup(AbstractTreeNode node) { if (node instanceof DashboardRunConfigurationNode) { DashboardRunConfigurationNode runConfigurationNode = (DashboardRunConfigurationNode)node; - RuntimeDashboardContributor contributor = RuntimeDashboardContributor.getContributor( + RunDashboardContributor contributor = RunDashboardContributor.getContributor( runConfigurationNode.getConfigurationSettings().getType()); if (contributor != null) { DashboardRunConfigurationStatus status = contributor.getStatus(runConfigurationNode); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index 5a3a344cc2ed..2f60a1ef7959 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -597,7 +597,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo StringBuilder textToSend = new StringBuilder(); // compute text input from the console contents: // all range markers beginning from the caret offset backwards, marked as user input and not marked as already sent - for (RangeMarker marker = findTokenMarker(myEditor.getCaretModel().getOffset()); + for (RangeMarker marker = findTokenMarker(myEditor.getCaretModel().getOffset()-1); marker != null; marker = ((RangeMarkerImpl)marker).findRangeMarkerBefore()) { ConsoleViewContentType tokenType = getTokenType(marker); @@ -698,18 +698,25 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo // add token information as range markers // start from the end because portion of the text can be stripped from the document beginning because of a cycle buffer int offset = document.getTextLength(); + int tokenLength = 0; for (int i = deferredTokens.size() - 1; i >= startIndex; i--) { TokenBuffer.TokenInfo token = deferredTokens.get(i); contentTypes.add(token.contentType); - int tokenLength = token.length(); - final HyperlinkInfo info = token.getHyperlinkInfo(); + tokenLength += token.length(); + TokenBuffer.TokenInfo prevToken = i == startIndex ? null : deferredTokens.get(i - 1); + if (prevToken != null && token.contentType == prevToken.contentType && token.getHyperlinkInfo() == prevToken.getHyperlinkInfo()) { + // do not create highlighter yet because can merge previous token with the current + continue; + } int start = Math.max(0, offset - tokenLength); if (start == offset) break; + final HyperlinkInfo info = token.getHyperlinkInfo(); if (info != null) { myHyperlinks.createHyperlink(start, offset, null, info).putUserData(MANUAL_HYPERLINK, true); } createTokenRangeHighlighter(token.contentType, start, offset); offset = start; + tokenLength = 0; } } finally { @@ -741,7 +748,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo ApplicationManager.getApplication().assertIsDispatchThread(); TextAttributes attributes = contentType.getAttributes(); MarkupModel model = DocumentMarkupModel.forDocument(myEditor.getDocument(), getProject(), true); - RangeHighlighter tokenMarker = model.addRangeHighlighter(startOffset, endOffset, HighlighterLayer.CONSOLE_FILTER, + int layer = HighlighterLayer.SYNTAX + 1; // make custom filters able to draw their text attributes over the default ones + RangeHighlighter tokenMarker = model.addRangeHighlighter(startOffset, endOffset, layer, attributes, HighlighterTargetArea.EXACT_RANGE); tokenMarker.putUserData(CONTENT_TYPE, contentType); } @@ -930,7 +938,10 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo if (!canHighlightHyperlinks && myUpdateFoldingsEnabled) { return; } - int endLine = myEditor.getDocument().getLineCount() - 1; + DocumentEx document = myEditor.getDocument(); + if (document.getTextLength() == 0) return; + + int endLine = Math.max(0, document.getLineCount() - 1); if (canHighlightHyperlinks) { myHyperlinks.highlightHyperlinks(myFilters, startLine, endLine); @@ -1126,11 +1137,12 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo } } + // finds range marker the [offset..offset+1) belongs to private RangeMarker findTokenMarker(int offset) { RangeMarker[] marker = new RangeMarker[1]; MarkupModelEx model = (MarkupModelEx)DocumentMarkupModel.forDocument(myEditor.getDocument(), getProject(), true); model.processRangeHighlightersOverlappingWith(offset, offset, m->{ - if (getTokenType(m) == null) return true; + if (getTokenType(m) == null || m.getStartOffset() > offset || offset + 1 > m.getEndOffset()) return true; marker[0] = m; return false; }); @@ -1165,8 +1177,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo flushDeferredText(); SelectionModel selectionModel = editor.getSelectionModel(); - int start = selectionModel.hasSelection() ? selectionModel.getSelectionStart() : editor.getCaretModel().getOffset(); - RangeMarker marker = findTokenMarker(start); + int lastOffset = selectionModel.hasSelection() ? selectionModel.getSelectionStart() : editor.getCaretModel().getOffset() - 1; + RangeMarker marker = findTokenMarker(lastOffset); if (getTokenType(marker) != ConsoleViewContentType.USER_INPUT) { print(text, ConsoleViewContentType.USER_INPUT); moveScrollRemoveSelection(editor, editor.getDocument().getTextLength()); @@ -1178,7 +1190,8 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo replaceUserText(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), textToUse); } else { - insertUserText(start, textToUse); + int typeOffset = selectionModel.hasSelection() ? selectionModel.getSelectionStart() : editor.getCaretModel().getOffset(); + insertUserText(typeOffset, textToUse); } } diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index 34c66596beab..388b0667a45c 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -17,8 +17,8 @@ package com.intellij.execution.ui; import com.intellij.execution.*; import com.intellij.execution.configurations.ConfigurationType; -import com.intellij.execution.dashboard.RuntimeDashboardContributor; -import com.intellij.execution.dashboard.RuntimeDashboardManager; +import com.intellij.execution.dashboard.RunDashboardContributor; +import com.intellij.execution.dashboard.RunDashboardManager; import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; @@ -93,7 +93,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { registerToolWindow(executor, toolWindowManager); } - RuntimeDashboardManager dashboardManager = RuntimeDashboardManager.getInstance(myProject); + RunDashboardManager dashboardManager = RunDashboardManager.getInstance(myProject); initToolWindow(null, dashboardManager.getToolWindowId(), dashboardManager.getToolWindowIcon(), dashboardManager.getDashboardContentManager()); @@ -569,8 +569,8 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { public String getContentDescriptorToolWindowId(@Nullable RunnerAndConfigurationSettings settings) { if (settings != null) { ConfigurationType type = settings.getType(); - if (RuntimeDashboardContributor.isShowInDashboard(type)) { - return RuntimeDashboardManager.getInstance(myProject).getToolWindowId(); + if (RunDashboardContributor.isShowInDashboard(type)) { + return RunDashboardManager.getInstance(myProject).getToolWindowId(); } } return null; @@ -582,7 +582,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { // TODO [konstantin.aleev] Check remaining places where Executor.getToolWindowId() is used // Also there are some places where ToolWindowId.RUN or ToolWindowId.DEBUG are used directly. // For example, HotSwapProgressImpl.NOTIFICATION_GROUP. All notifications for this group is shown in Debug tool window, - // however such notifications should be shown in Runtime Dashboard tool window, if run content is redirected to Runtime Dashboard tool window. + // however such notifications should be shown in Run Dashboard tool window, if run content is redirected to Run Dashboard tool window. String toolWindowId = getContentDescriptorToolWindowId(executionEnvironment.getRunnerAndConfigurationSettings()); return toolWindowId != null ? toolWindowId : executionEnvironment.getExecutor().getToolWindowId(); } @@ -592,7 +592,7 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { List contents = new ArrayList<>(); ContainerUtil.addAll(contents, getContentManagerForRunner(runnerInfo, null).getContents()); ContainerUtil.addAll(contents, - myToolwindowIdToContentManagerMap.get(RuntimeDashboardManager.getInstance(myProject).getToolWindowId()).getContents()); + myToolwindowIdToContentManagerMap.get(RunDashboardManager.getInstance(myProject).getToolWindowId()).getContents()); for (Content content : contents) { RunContentDescriptor runContentDescriptor = getRunContentDescriptorByContent(content); assert runContentDescriptor != null; diff --git a/platform/lang-impl/src/com/intellij/find/EditorSearchSession.java b/platform/lang-impl/src/com/intellij/find/EditorSearchSession.java index 4bc6ebde1423..373b844e661d 100644 --- a/platform/lang-impl/src/com/intellij/find/EditorSearchSession.java +++ b/platform/lang-impl/src/com/intellij/find/EditorSearchSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -468,7 +468,7 @@ public class EditorSearchSession implements SearchSession, public JComponent createCustomComponent(Presentation presentation) { JButton button = new JButton(myTitle); button.setFocusable(false); - if (!UISettings.getInstance().DISABLE_MNEMONICS_IN_CONTROLS) { + if (!UISettings.getInstance().getDisableMnemonicsInControls()) { button.setMnemonic(myMnemonic); } button.addActionListener(this); diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index 6d2a0591bbe3..2151736b31c5 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -137,7 +137,6 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo private static final boolean ourAutoscrollFromSourceDefaults = false; private boolean myFoldersAlwaysOnTop = true; - private String myCurrentViewId; private String myCurrentViewSubId; @@ -1383,7 +1382,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo return getGlobalOptions().getAutoscrollToSource(); } - return getPaneOptionValue(myAutoscrollToSource, paneId, UISettings.getInstance().DEFAULT_AUTOSCROLL_TO_SOURCE); + return getPaneOptionValue(myAutoscrollToSource, paneId, UISettings.getInstance().getDefaultAutoScrollToSource()); } public void setAutoscrollToSource(boolean autoscrollMode, String paneId) { diff --git a/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java b/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java index 630ff677a23d..60bd3ebcbc14 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/ide/util/NavigationItemListCellRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,7 +62,7 @@ public class NavigationItemListCellRenderer extends OpaquePanel implements ListC boolean cellHasFocus) { removeAll(); - final boolean hasRightRenderer = UISettings.getInstance().SHOW_ICONS_IN_QUICK_NAVIGATION; + final boolean hasRightRenderer = UISettings.getInstance().getShowIconInQuickNavigation(); final ModuleRendererFactory factory = ModuleRendererFactory.findInstance(value); final LeftRenderer left = new LeftRenderer(!hasRightRenderer || !factory.rendersLocationString(), MatcherHolder.getAssociatedMatcher(list)); diff --git a/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java b/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java index 580be4be5f45..e744d102e643 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java +++ b/platform/lang-impl/src/com/intellij/ide/util/PsiElementListCellRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.ide.util; import com.intellij.ide.ui.UISettings; @@ -50,7 +49,6 @@ import java.awt.*; import java.util.Comparator; public abstract class PsiElementListCellRenderer extends JPanel implements ListCellRenderer { - private static final String LEFT = BorderLayout.WEST; private boolean myFocusBorderEnabled = Registry.is("psi.element.list.cell.renderer.focus.border.enabled"); @@ -234,7 +232,7 @@ public abstract class PsiElementListCellRenderer extends J @Nullable protected DefaultListCellRenderer getRightCellRenderer(final Object value) { - if (UISettings.getInstance().SHOW_ICONS_IN_QUICK_NAVIGATION) { + if (UISettings.getInstance().getShowIconInQuickNavigation()) { final DefaultListCellRenderer renderer = ModuleRendererFactory.findInstance(value).getModuleRenderer(); if (renderer instanceof PlatformModuleRendererFactory.PlatformModuleRenderer) { // it won't display any new information @@ -263,7 +261,8 @@ public abstract class PsiElementListCellRenderer extends J } public Comparator getComparator() { - return (o1, o2) -> getComparingObject(o1).compareTo(getComparingObject(o2)); + //noinspection unchecked + return Comparator.comparing(this::getComparingObject); } @NotNull diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java index 949c44334cbc..6577b11ae924 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNamePopup.java @@ -135,7 +135,7 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP @Override protected boolean isCloseByFocusLost() { - return UISettings.getInstance().HIDE_NAVIGATION_ON_FOCUS_LOSS; + return UISettings.getInstance().getHideNavigationOnFocusLoss(); } @Override @@ -193,7 +193,7 @@ public class ChooseByNamePopup extends ChooseByNameBase implements ChooseByNameP // in 'focus follows mouse' mode, to avoid focus escaping to editor, don't reduce popup size when list size is reduced final Dimension currentSize = myDropdownPopup.getSize(); - if (UISettings.getInstance().HIDE_NAVIGATION_ON_FOCUS_LOSS || + if (UISettings.getInstance().getHideNavigationOnFocusLoss() || preferredBounds.width > currentSize.width || preferredBounds.height > currentSize.height) { myDropdownPopup.setSize(preferredBounds.getSize()); } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java index 413cdd830c72..1639a41655d6 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -553,7 +553,7 @@ public class GotoActionModel implements ChooseByNameModel, Comparator, D public Component getListCellRendererComponent(@NotNull JList list, Object matchedValue, int index, boolean isSelected, boolean cellHasFocus) { - boolean showIcon = UISettings.getInstance().SHOW_ICONS_IN_MENUS; + boolean showIcon = UISettings.getInstance().getShowIconsInMenus(); JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(IdeBorderFactory.createEmptyBorder(2)); panel.setOpaque(true); diff --git a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/UniqueNameEditorTabTitleProvider.java b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/UniqueNameEditorTabTitleProvider.java index 53d20c711323..6acbe6a7e48b 100644 --- a/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/UniqueNameEditorTabTitleProvider.java +++ b/platform/lang-impl/src/com/intellij/openapi/fileEditor/impl/UniqueNameEditorTabTitleProvider.java @@ -31,13 +31,16 @@ import java.io.File; public class UniqueNameEditorTabTitleProvider implements EditorTabTitleProvider { @Override public String getEditorTabTitle(Project project, VirtualFile file) { - UISettings uiSettings = UISettings.getInstance(); - if (uiSettings == null || !uiSettings.SHOW_DIRECTORY_FOR_NON_UNIQUE_FILENAMES || DumbService.isDumb(project)) return null; + UISettings uiSettings = UISettings.getInstanceOrNull(); + if (uiSettings == null || !uiSettings.getShowDirectoryForNonUniqueFilenames() || DumbService.isDumb(project)) { + return null; + } + // Even though this is a 'tab title provider' it is used also when tabs are not shown, namely for building IDE frame title. String uniqueName = uiSettings.getEditorTabPlacement() == UISettings.TABS_NONE ? UniqueVFilePathBuilder.getInstance().getUniqueVirtualFilePath(project, file) : UniqueVFilePathBuilder.getInstance().getUniqueVirtualFilePathWithinOpenedFileEditors(project, file); - uniqueName = getEditorTabText(uniqueName, File.separator, uiSettings.HIDE_KNOWN_EXTENSION_IN_TABS); + uniqueName = getEditorTabText(uniqueName, File.separator, uiSettings.getHdeKnownExtensionInTabs()); return uniqueName.equals(file.getName()) ? null : uniqueName; } diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/ProjectLoadingErrorsNotifierImpl.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/ProjectLoadingErrorsNotifierImpl.java index 4e05f77f3193..d0805b783fe7 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/ProjectLoadingErrorsNotifierImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/ProjectLoadingErrorsNotifierImpl.java @@ -27,7 +27,6 @@ import com.intellij.openapi.module.ProjectLoadingErrorsNotifier; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; @@ -96,11 +95,10 @@ public class ProjectLoadingErrorsNotifierImpl extends ProjectLoadingErrorsNotifi @NotNull HyperlinkEvent event) { final List validDescriptions = ContainerUtil.findAll(descriptions, errorDescription -> errorDescription.isValid()); - RemoveInvalidElementsDialog - .showDialog(myProject, CommonBundle.getErrorTitle(), type, invalidElements, - validDescriptions); - - notification.expire(); + if (RemoveInvalidElementsDialog.showDialog(myProject, CommonBundle.getErrorTitle(), type, + invalidElements, validDescriptions)) { + notification.expire(); + } } }), myProject); } diff --git a/platform/lang-impl/src/com/intellij/openapi/module/impl/RemoveInvalidElementsDialog.java b/platform/lang-impl/src/com/intellij/openapi/module/impl/RemoveInvalidElementsDialog.java index 995b2cd6feae..ceaae5f67756 100644 --- a/platform/lang-impl/src/com/intellij/openapi/module/impl/RemoveInvalidElementsDialog.java +++ b/platform/lang-impl/src/com/intellij/openapi/module/impl/RemoveInvalidElementsDialog.java @@ -74,13 +74,13 @@ public class RemoveInvalidElementsDialog extends DialogWrapper { } - public static void showDialog(@NotNull Project project, - @NotNull String title, - ConfigurationErrorType type, - @NotNull String invalidElements, - @NotNull List errors) { + /** + * @return {@code true} if the problems are resolved + */ + public static boolean showDialog(@NotNull Project project, @NotNull String title, ConfigurationErrorType type, + @NotNull String invalidElements, @NotNull List errors) { if (errors.isEmpty()) { - return; + return true; } if (errors.size() == 1) { ConfigurationErrorDescription error = errors.get(0); @@ -88,8 +88,9 @@ public class RemoveInvalidElementsDialog extends DialogWrapper { final int answer = Messages.showYesNoDialog(project, message, title, Messages.getErrorIcon()); if (answer == Messages.YES) { error.ignoreInvalidElement(); + return true; } - return; + return false; } RemoveInvalidElementsDialog dialog = new RemoveInvalidElementsDialog(title, type, invalidElements, project, errors); @@ -97,7 +98,9 @@ public class RemoveInvalidElementsDialog extends DialogWrapper { for (ConfigurationErrorDescription errorDescription : dialog.getSelectedItems()) { errorDescription.ignoreInvalidElement(); } + return true; } + return false; } private List getSelectedItems() { diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java index 718d05caab78..a03ebeb268cf 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/DirectoryIndexImpl.java @@ -16,7 +16,6 @@ package com.intellij.openapi.roots.impl; import com.intellij.ProjectTopics; -import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileTypeEvent; import com.intellij.openapi.fileTypes.FileTypeListener; @@ -27,6 +26,7 @@ import com.intellij.openapi.roots.ModuleRootEvent; import com.intellij.openapi.roots.ModuleRootListener; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.LowMemoryWatcher; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; @@ -56,13 +56,16 @@ public class DirectoryIndexImpl extends DirectoryIndex { myProject = project; myConnection = project.getMessageBus().connect(project); subscribeToFileChanges(); - Disposer.register(project, new Disposable() { - @Override - public void dispose() { - myDisposed = true; - myRootIndex = null; - } + Disposer.register(project, () -> { + myDisposed = true; + myRootIndex = null; }); + LowMemoryWatcher.register(() -> { + RootIndex index = myRootIndex; + if (index != null) { + index.onLowMemory(); + } + }, project); } protected void subscribeToFileChanges() { diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/SerializationManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/SerializationManagerImpl.java index 7da747f75ec1..700aed9d95d0 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/SerializationManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/SerializationManagerImpl.java @@ -48,7 +48,7 @@ public class SerializationManagerImpl extends SerializationManagerEx implements // we need to cache last id -> String mappings due to StringRefs and stubs indexing that initially creates stubs (doing enumerate on String) // and then index them (valueOf), also similar string items are expected to be enumerated during stubs processing myNameStorage = new PersistentStringEnumerator(myFile, true); - myStubSerializationHelper = new StubSerializationHelper(myNameStorage); + myStubSerializationHelper = new StubSerializationHelper(myNameStorage, this); } catch (IOException e) { nameStorageCrashed(); @@ -58,7 +58,7 @@ public class SerializationManagerImpl extends SerializationManagerEx implements } finally { registerSerializer(PsiFileStubImpl.TYPE); - ShutDownTracker.getInstance().registerShutdownTask(() -> performShutdown()); + ShutDownTracker.getInstance().registerShutdownTask(this::performShutdown); } } @@ -78,7 +78,7 @@ public class SerializationManagerImpl extends SerializationManagerEx implements IOUtil.deleteAllFilesStartingWith(myFile); myNameStorage = new PersistentStringEnumerator(myFile, true); - myStubSerializationHelper = new StubSerializationHelper(myNameStorage); + myStubSerializationHelper = new StubSerializationHelper(myNameStorage, this); for (ObjectStubSerializer serializer : myAllSerializers) { myStubSerializationHelper.assignId(serializer); } diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubSerializationHelper.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubSerializationHelper.java index 28158e796d62..abc6b4bb578c 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubSerializationHelper.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubSerializationHelper.java @@ -15,6 +15,7 @@ */ package com.intellij.psi.stubs; +import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.LogUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; @@ -44,8 +45,9 @@ public class StubSerializationHelper { protected final TIntObjectHashMap myIdToSerializer = new TIntObjectHashMap<>(); protected final TObjectIntHashMap mySerializerToId = new TObjectIntHashMap<>(); - public StubSerializationHelper(@NotNull AbstractStringEnumerator nameStorage) { + public StubSerializationHelper(@NotNull AbstractStringEnumerator nameStorage, @NotNull Disposable parentDisposable) { myNameStorage = nameStorage; + myStringInterner = new RecentStringInterner(parentDisposable); } public void assignId(@NotNull final ObjectStubSerializer serializer) throws IOException { @@ -116,7 +118,7 @@ public class StubSerializationHelper { return idValue; } - private final RecentStringInterner myStringInterner = new RecentStringInterner(); + private final RecentStringInterner myStringInterner; @NotNull public Stub deserialize(@NotNull InputStream stream) throws IOException, SerializerNotFoundException { diff --git a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java index 528f33f7919a..e230e126ba5f 100644 --- a/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java +++ b/platform/lang-impl/src/com/intellij/ui/IconDeferrerImpl.java @@ -41,25 +41,19 @@ public class IconDeferrerImpl extends IconDeferrer { } }; private long myLastClearTimestamp; - @SuppressWarnings("UnusedDeclaration") - private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(this::clear); protected IconDeferrerImpl() {} public IconDeferrerImpl(MessageBus bus) { final MessageBusConnection connection = bus.connect(); - connection.subscribe(PsiModificationTracker.TOPIC, new PsiModificationTracker.Listener() { - @Override - public void modificationCountChanged() { - clear(); - } - }); + connection.subscribe(PsiModificationTracker.TOPIC, this::clear); connection.subscribe(ProjectLifecycleListener.TOPIC, new ProjectLifecycleListener() { @Override public void afterProjectClosed(@NotNull Project project) { clear(); } }); + LowMemoryWatcher.register(this::clear, connection); } protected final void clear() { @@ -88,14 +82,11 @@ public class IconDeferrerImpl extends IconDeferrer { Icon result = myIconsCache.get(param); if (result == null) { final long started = myLastClearTimestamp; - result = new DeferredIconImpl<>(base, param, evaluator, new DeferredIconImpl.IconListener() { - @Override - public void evalDone(DeferredIconImpl source, T key, @NotNull Icon r) { - synchronized (LOCK) { - // check if our results is not outdated yet - if (started == myLastClearTimestamp) { - myIconsCache.put(key, autoUpdatable ? source : r); - } + result = new DeferredIconImpl<>(base, param, evaluator, (DeferredIconImpl source, T key, Icon r) -> { + synchronized (LOCK) { + // check if our results is not outdated yet + if (started == myLastClearTimestamp) { + myIconsCache.put(key, autoUpdatable ? source : r); } } }, autoUpdatable); @@ -112,12 +103,7 @@ public class IconDeferrerImpl extends IconDeferrer { } } - private static final ThreadLocal myEvaluationIsInProgress = new ThreadLocal() { - @Override - protected Boolean initialValue() { - return Boolean.FALSE; - } - }; + private static final ThreadLocal myEvaluationIsInProgress = ThreadLocal.withInitial(() -> Boolean.FALSE); static void evaluateDeferred(@NotNull Runnable runnable) { try { diff --git a/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java b/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java index 5961f6c3b86e..7b4b7dbce655 100644 --- a/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java +++ b/platform/lang-impl/src/com/intellij/webcore/packaging/ManagePackagesDialog.java @@ -112,6 +112,7 @@ public class ManagePackagesDialog extends DialogWrapper { application.invokeLater(() -> { //noinspection DialogTitleCapitalization Messages.showErrorDialog(myMainPanel, "Error updating package list: " + e1.getMessage(), "Reload List of Packages"); + LOG.info("Error updating list of repository packages", e1); myPackages.setPaintBusy(false); }, ModalityState.any()); } @@ -282,7 +283,7 @@ public class ManagePackagesDialog extends DialogWrapper { }); } catch(IOException e) { - LOG.info("Error updating list of installed packages:" + e); + LOG.info("Error updating list of installed packages", e); } }); } @@ -306,6 +307,7 @@ public class ManagePackagesDialog extends DialogWrapper { if (myMainPanel.isShowing()) { Messages.showErrorDialog(myMainPanel, "Error loading package list:" + e.getMessage(), "Packages"); } + LOG.info("Error initializing model", e); setDownloadStatus(false); }, ModalityState.any()); } diff --git a/platform/platform-api/src/com/intellij/openapi/MnemonicWrapper.java b/platform/platform-api/src/com/intellij/openapi/MnemonicWrapper.java index 1d178939ef4a..d38a05ebe16d 100644 --- a/platform/platform-api/src/com/intellij/openapi/MnemonicWrapper.java +++ b/platform/platform-api/src/com/intellij/openapi/MnemonicWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -176,7 +176,7 @@ abstract class MnemonicWrapper implements Runnable, Propert } boolean isDisabled() { - return UISettings.getShadowInstance().DISABLE_MNEMONICS_IN_CONTROLS; + return UISettings.getShadowInstance().getDisableMnemonicsInControls(); } abstract String getText(); diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java index 84113d734181..d60a4beab0d6 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/ActionPlaces.java @@ -131,7 +131,7 @@ public abstract class ActionPlaces { public static final String V8_HEAP_PROFILING_POPUP = "V8_HEAP_PROFILING_POPUP"; public static final String V8_HEAP_DIFF_PROFILING_POPUP = "V8_HEAP_DIFF_PROFILING_POPUP"; - public static final String RUNTIME_DASHBOARD_POPUP = "RuntimeDashboardPopup"; + public static final String RUN_DASHBOARD_POPUP = "RunDashboardPopup"; private static final Set ourToolbarPlaces = ContainerUtil.newHashSet( EDITOR_TOOLBAR, PROJECT_VIEW_TOOLBAR, TESTTREE_VIEW_TOOLBAR, MAIN_TOOLBAR, TOOLBAR, RUNNER_TOOLBAR, @@ -159,7 +159,7 @@ public abstract class ActionPlaces { GUI_DESIGNER_PROPERTY_INSPECTOR_POPUP, CREATE_EJB_POPUP, CHANGES_VIEW_POPUP, REMOTE_HOST_VIEW_POPUP, REMOTE_HOST_DIALOG_POPUP, TFS_TREE_POPUP, ACTION_PLACE_VCS_QUICK_LIST_POPUP_ACTION, PHING_EXPLORER_POPUP, NAVIGATION_BAR_POPUP, JS_BUILD_TOOL_POPUP, - V8_CPU_PROFILING_POPUP, V8_HEAP_PROFILING_POPUP, V8_HEAP_PROFILING_POPUP, RUNTIME_DASHBOARD_POPUP + V8_CPU_PROFILING_POPUP, V8_HEAP_PROFILING_POPUP, V8_HEAP_PROFILING_POPUP, RUN_DASHBOARD_POPUP ); public static boolean isPopupPlace(@NotNull String place) { diff --git a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java index 4b18339226e0..25ef9bcfc7fe 100644 --- a/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java +++ b/platform/platform-api/src/com/intellij/openapi/wm/ToolWindowId.java @@ -39,5 +39,5 @@ public interface ToolWindowId { String TASKS = UIBundle.message("tool.window.name.tasks"); String DATABASE_VIEW = UIBundle.message("tool.window.name.database"); String PREVIEW = UIBundle.message("tool.window.name.preview"); - String RUNTIME_DASHBOARD = UIBundle.message("tool.window.name.runtime.dashboard"); + String RUN_DASHBOARD = UIBundle.message("tool.window.name.run.dashboard"); } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ui/MouseDragHelper.java b/platform/platform-api/src/com/intellij/ui/MouseDragHelper.java index e46748c3a56f..3a49e618f9e7 100644 --- a/platform/platform-api/src/com/intellij/ui/MouseDragHelper.java +++ b/platform/platform-api/src/com/intellij/ui/MouseDragHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -62,7 +62,7 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe * @return false if Settings -> Appearance -> Drag-n-Drop with ALT pressed only is selected but event doesn't have ALT modifier */ public static boolean checkModifiers(InputEvent event) { - if (event == null || !UISettings.getInstance().DND_WITH_PRESSED_ALT_ONLY) return true; + if (event == null || !UISettings.getInstance().getDndWithPressedAltOnly()) return true; return (event.getModifiers() & InputEvent.ALT_MASK) != 0; } @@ -70,16 +70,19 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe if (myGlassPane != null) return; new UiNotifyConnector(myDragComponent, new Activatable() { + @Override public void showNotify() { attach(); } + @Override public void hideNotify() { detach(true); } }); Disposer.register(myParentDisposable, new Disposable() { + @Override public void dispose() { stop(); } @@ -125,6 +128,7 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe return 2; } + @Override public void mousePressed(final MouseEvent e) { if (!canStartDragging(e)) return; @@ -141,6 +145,7 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe } } + @Override public void mouseReleased(final MouseEvent e) { if (myCancelled) { myCancelled = false; @@ -179,6 +184,7 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe myDetachingMode = false; } + @Override public void mouseDragged(final MouseEvent e) { if (myPressPointScreen == null || myCancelled) return; @@ -260,15 +266,19 @@ public abstract class MouseDragHelper implements MouseListener, MouseMotionListe Math.abs(myPressPointScreen.y - screen.y - myDelta.height) < DRAG_START_DEADZONE; } + @Override public void mouseClicked(final MouseEvent e) { } + @Override public void mouseEntered(final MouseEvent e) { } + @Override public void mouseExited(final MouseEvent e) { } + @Override public void mouseMoved(final MouseEvent e) { } diff --git a/platform/platform-api/src/com/intellij/ui/NonFocusableCheckBox.java b/platform/platform-api/src/com/intellij/ui/NonFocusableCheckBox.java index 34d40667e010..f9c89fd5ee01 100644 --- a/platform/platform-api/src/com/intellij/ui/NonFocusableCheckBox.java +++ b/platform/platform-api/src/com/intellij/ui/NonFocusableCheckBox.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ public class NonFocusableCheckBox extends JCheckBox { } private void initFocusability() { - if (!UISettings.getShadowInstance().DISABLE_MNEMONICS_IN_CONTROLS) { // Or that won't be keyboard accessible at all + if (!UISettings.getShadowInstance().getDisableMnemonicsInControls()) { // Or that won't be keyboard accessible at all setFocusable(false); } } diff --git a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java index 0aa916a2a519..4d7686adf8a1 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/impl/JBEditorTabs.java @@ -103,7 +103,7 @@ public class JBEditorTabs extends JBTabsImpl { @Override public boolean useSmallLabels() { - return UISettings.getInstance().USE_SMALL_LABELS_ON_TABS; + return UISettings.getInstance().getUseSmallLabelsOnTabs(); } @Override @@ -116,8 +116,6 @@ public class JBEditorTabs extends JBTabsImpl { return isSingleRow() && !Registry.is("ide.new.editor.tabs.selection"); } - - @Override protected void doPaintInactive(Graphics2D g2d, boolean leftGhostExists, diff --git a/platform/platform-api/src/com/intellij/util/ui/DialogUtil.java b/platform/platform-api/src/com/intellij/util/ui/DialogUtil.java index 6a04e529ffaa..942a6b1376da 100644 --- a/platform/platform-api/src/com/intellij/util/ui/DialogUtil.java +++ b/platform/platform-api/src/com/intellij/util/ui/DialogUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ public class DialogUtil{ } if (mnemonic != '\0') { button.setText(realText.toString()); - if (UISettings.getShadowInstance().DISABLE_MNEMONICS_IN_CONTROLS) { + if (UISettings.getShadowInstance().getDisableMnemonicsInControls()) { button.setMnemonic(0); button.setDisplayedMnemonicIndex(-1); button.setFocusable(true); @@ -94,7 +94,7 @@ public class DialogUtil{ } if (mnemonic != '\0') { label.setText(realText.toString()); - if (UISettings.getShadowInstance().DISABLE_MNEMONICS_IN_CONTROLS) { + if (UISettings.getShadowInstance().getDisableMnemonicsInControls()) { label.setDisplayedMnemonic(0); label.setDisplayedMnemonicIndex(-1); } diff --git a/platform/platform-impl/src/com/intellij/execution/impl/ConsoleViewUtil.java b/platform/platform-impl/src/com/intellij/execution/impl/ConsoleViewUtil.java index 36e77ff407e1..195fa2ec8517 100644 --- a/platform/platform-impl/src/com/intellij/execution/impl/ConsoleViewUtil.java +++ b/platform/platform-impl/src/com/intellij/execution/impl/ConsoleViewUtil.java @@ -89,7 +89,7 @@ public class ConsoleViewUtil { final DelegateColorScheme scheme = updateConsoleColorScheme(editor.getColorsScheme()); if (UISettings.getInstance().getPresentationMode()) { - scheme.setEditorFontSize(UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE); + scheme.setEditorFontSize(UISettings.getInstance().getPresentationModeFontSize()); } editor.setColorsScheme(scheme); }); diff --git a/platform/platform-impl/src/com/intellij/ide/CopyPasteManagerEx.java b/platform/platform-impl/src/com/intellij/ide/CopyPasteManagerEx.java index ce238339e46a..6e2b8fc0fad0 100644 --- a/platform/platform-impl/src/com/intellij/ide/CopyPasteManagerEx.java +++ b/platform/platform-impl/src/com/intellij/ide/CopyPasteManagerEx.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -224,7 +224,7 @@ public class CopyPasteManagerEx extends CopyPasteManager implements ClipboardOwn } private void deleteAfterAllowedMaximum() { - int max = UISettings.getInstance().MAX_CLIPBOARD_CONTENTS; + int max = UISettings.getInstance().getMaxClipboardContents(); for (int i = myData.size() - 1; i >= max; i--) { myData.remove(i); } diff --git a/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java b/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java index a3b98296d608..ba0858873b97 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/TogglePresentationModeAction.java @@ -113,7 +113,7 @@ public class TogglePresentationModeAction extends AnAction implements DumbAware private static void tweakEditorAndFireUpdateUI(UISettings settings, boolean inPresentation) { EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme(); - int fontSize = inPresentation ? settings.PRESENTATION_MODE_FONT_SIZE : globalScheme.getEditorFontSize(); + int fontSize = inPresentation ? settings.getPresentationModeFontSize() : globalScheme.getEditorFontSize(); if (inPresentation) { ourSavedConsoleFontSize = globalScheme.getConsoleFontSize(); globalScheme.setConsoleFontSize(fontSize); @@ -148,7 +148,7 @@ public class TogglePresentationModeAction extends AnAction implements DumbAware } } } - float scaleFactor = settings.PRESENTATION_MODE_FONT_SIZE / UIUtil.DEF_SYSTEM_FONT_SIZE; + float scaleFactor = settings.getPresentationModeFontSize() / UIUtil.DEF_SYSTEM_FONT_SIZE; ourSavedScaleFactor = JBUI.scale(1f); JBUI.setUserScaleFactor(scaleFactor); for (Object key : ourSavedValues.keySet()) { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ToggleToolbarAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ToggleToolbarAction.java index 61160891c1b8..4d3a1fbc8802 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ToggleToolbarAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ToggleToolbarAction.java @@ -18,6 +18,7 @@ package com.intellij.ide.actions; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.impl.LaterInvocator; +import com.intellij.openapi.editor.impl.EditorHeaderComponent; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.wm.ToolWindow; @@ -25,38 +26,43 @@ import com.intellij.ui.content.Content; import com.intellij.ui.content.ContentManager; import com.intellij.ui.content.ContentManagerAdapter; import com.intellij.ui.content.ContentManagerEvent; +import com.intellij.util.Producer; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.JBIterable; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; import java.util.List; /** -* @author gregsh -*/ + * @author gregsh + */ public class ToggleToolbarAction extends ToggleAction implements DumbAware { @NotNull public static ActionGroup createToggleToolbarGroup(@NotNull Project project, @NotNull ToolWindow toolWindow) { return new DefaultActionGroup(new OptionsGroup(toolWindow), - new ToggleToolbarAction(toolWindow, PropertiesComponent.getInstance(project)), + createToolWindowAction(toolWindow, PropertiesComponent.getInstance(project)), Separator.getInstance()); } - private final PropertiesComponent myPropertiesComponent; - private final ToolWindow myToolWindow; + @NotNull + public static ToggleToolbarAction createAction(@NotNull String id, + @NotNull PropertiesComponent properties, + @NotNull Producer> components) { + return new ToggleToolbarAction(properties, getShowToolbarProperty(id), components); + } - private ToggleToolbarAction(@NotNull ToolWindow toolWindow, @NotNull PropertiesComponent propertiesComponent) { - super("Show Toolbar"); - myPropertiesComponent = propertiesComponent; - myToolWindow = toolWindow; - myToolWindow.getContentManager().addContentManagerListener(new ContentManagerAdapter() { + @NotNull + public static ToggleToolbarAction createToolWindowAction(@NotNull ToolWindow toolWindow, @NotNull PropertiesComponent properties) { + toolWindow.getContentManager().addContentManagerListener(new ContentManagerAdapter() { @Override public void contentAdded(ContentManagerEvent event) { JComponent component = event.getContent().getComponent(); - setContentToolbarVisible(component, getVisibilityValue()); + setToolbarVisible(JBIterable.of(component), isToolbarVisible(toolWindow, properties)); // support nested content managers, e.g. RunnerLayoutUi as content component ContentManager contentManager = @@ -64,57 +70,105 @@ public class ToggleToolbarAction extends ToggleAction implements DumbAware { if (contentManager != null) contentManager.addContentManagerListener(this); } }); + return new ToggleToolbarAction(properties, getShowToolbarProperty(toolWindow), + () -> JBIterable.of(toolWindow.getContentManager().getComponent())); + } + + public static void setToolbarVisible(@NotNull ToolWindow toolWindow, + @NotNull PropertiesComponent properties, + @Nullable Boolean visible) { + boolean state = visible == null ? isToolbarVisible(toolWindow, properties) : visible; + setToolbarVisibleImpl(getShowToolbarProperty(toolWindow), properties, JBIterable.of(toolWindow.getComponent()), state); + } + + public static void setToolbarVisible(@NotNull String id, + @NotNull PropertiesComponent properties, + @NotNull Iterable components, + @Nullable Boolean visible) { + boolean state = visible == null ? isToolbarVisible(id, properties) : visible; + setToolbarVisibleImpl(getShowToolbarProperty(id), properties, components, state); + } + + public static void setToolbarVisible(@NotNull Iterable roots, boolean state) { + for (ActionToolbar toolbar : iterateToolbars(roots)) { + JComponent c = toolbar.getComponent(); + c.setVisible(state); + Container parent = c.getParent(); + if (parent instanceof EditorHeaderComponent) { + parent.setVisible(state); + } + } + } + + public static boolean isToolbarVisible(@NotNull String property, @NotNull PropertiesComponent properties) { + return isSelectedImpl(properties, getShowToolbarProperty(property)); + } + + public static boolean isToolbarVisible(@NotNull ToolWindow toolWindow, @NotNull PropertiesComponent properties) { + return isSelectedImpl(properties, getShowToolbarProperty(toolWindow)); + } + + + private final PropertiesComponent myPropertiesComponent; + private final String myProperty; + private final Producer> myProducer; + + private ToggleToolbarAction(@NotNull PropertiesComponent propertiesComponent, + @NotNull String property, + @NotNull Producer> producer) { + super("Show Toolbar"); + myPropertiesComponent = propertiesComponent; + myProperty = property; + myProducer = producer; } @Override public void update(@NotNull AnActionEvent e) { super.update(e); - boolean hasToolbars = iterateToolbars(myToolWindow.getContentManager().getComponent()).iterator().hasNext(); + boolean hasToolbars = iterateToolbars(myProducer.produce()).iterator().hasNext(); e.getPresentation().setVisible(hasToolbars); } @Override public boolean isSelected(AnActionEvent e) { - return getVisibilityValue(); + return isSelected(); } @Override public void setSelected(AnActionEvent e, boolean state) { - setToolbarVisible(myToolWindow, myPropertiesComponent, state); + setToolbarVisibleImpl(myProperty, myPropertiesComponent, myProducer.produce(), state); } - public static void setToolbarVisible(ToolWindow toolWindow, PropertiesComponent propertiesComponent, boolean state) { - String propertyName = getShowToolbarProperty(toolWindow); - propertiesComponent.setValue(propertyName, String.valueOf(state), String.valueOf(true)); - - for (Content content : toolWindow.getContentManager().getContents()) { - setContentToolbarVisible(content.getComponent(), state); - } + static void setToolbarVisibleImpl(@NotNull String property, + @NotNull PropertiesComponent propertiesComponent, + @NotNull Iterable components, + boolean visible) { + propertiesComponent.setValue(property, String.valueOf(visible), String.valueOf(true)); + setToolbarVisible(components, visible); + } + + + boolean isSelected() { + return isSelectedImpl(myPropertiesComponent, myProperty); + } + + static boolean isSelectedImpl(@NotNull PropertiesComponent properties, @NotNull String property) { + return properties.getBoolean(property, true); } @NotNull - private String getProperty() { - return getShowToolbarProperty(myToolWindow); - } - - private boolean getVisibilityValue() { - return myPropertiesComponent.getBoolean(getProperty(), true); - } - - private static void setContentToolbarVisible(@NotNull JComponent root, boolean state) { - for (ActionToolbar toolbar : iterateToolbars(root)) { - toolbar.getComponent().setVisible(state); - } + static String getShowToolbarProperty(@NotNull ToolWindow window) { + return getShowToolbarProperty("ToolWindow" + window.getStripeTitle()); } @NotNull - public static String getShowToolbarProperty(@NotNull ToolWindow window) { - return "ToolWindow" + window.getStripeTitle() + ".ShowToolbar"; + static String getShowToolbarProperty(@NotNull String s) { + return s + ".ShowToolbar"; } @NotNull - private static Iterable iterateToolbars(JComponent root) { - return UIUtil.uiTraverser(root).preOrderDfsTraversal().filter(ActionToolbar.class); + private static Iterable iterateToolbars(Iterable roots) { + return UIUtil.uiTraverser(null).withRoots(roots).preOrderDfsTraversal().filter(ActionToolbar.class); } private static class OptionsGroup extends ActionGroup implements DumbAware { @@ -139,7 +193,7 @@ public class ToggleToolbarAction extends ToggleAction implements DumbAware { JComponent contentComponent = selectedContent != null ? selectedContent.getComponent() : null; if (contentComponent == null) return EMPTY_ARRAY; List result = ContainerUtil.newSmartList(); - for (final ActionToolbar toolbar : iterateToolbars(contentComponent)) { + for (final ActionToolbar toolbar : iterateToolbars(JBIterable.of(contentComponent))) { JComponent c = toolbar.getComponent(); if (c.isVisible() || !c.isValid()) continue; if (!result.isEmpty() && !(ContainerUtil.getLastItem(result) instanceof Separator)) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java index 3d4a5a6eee6b..216ec593647d 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java @@ -153,7 +153,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab initComponent(); UISettings settings = UISettings.getInstance(); int _fontSize = getIntValue(myComponent.myFontSizeCombo, settings.FONT_SIZE); - int _presentationFontSize = getIntValue(myComponent.myPresentationModeFontSize, settings.PRESENTATION_MODE_FONT_SIZE); + int _presentationFontSize = getIntValue(myComponent.myPresentationModeFontSize, settings.getPresentationModeFontSize()); boolean update = false; boolean shouldUpdateUI = false; String _fontFace = myComponent.myFontCombo.getFontName(); @@ -165,8 +165,8 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab update = true; } - if (_presentationFontSize != settings.PRESENTATION_MODE_FONT_SIZE) { - settings.PRESENTATION_MODE_FONT_SIZE = _presentationFontSize; + if (_presentationFontSize != settings.getPresentationModeFontSize()) { + settings.setPresentationModeFontSize(_presentationFontSize); shouldUpdateUI = true; } @@ -190,28 +190,28 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab settings.setShowToolWindowsNumbers(myComponent.myWindowShortcutsCheckBox.isSelected()); update |= settings.getHideToolStripes() != !myComponent.myShowToolStripesCheckBox.isSelected(); settings.setHideToolStripes(!myComponent.myShowToolStripesCheckBox.isSelected()); - update |= settings.SHOW_ICONS_IN_MENUS != myComponent.myCbDisplayIconsInMenu.isSelected(); - settings.SHOW_ICONS_IN_MENUS = myComponent.myCbDisplayIconsInMenu.isSelected(); + update |= settings.getShowIconsInMenus() != myComponent.myCbDisplayIconsInMenu.isSelected(); + settings.setShowIconsInMenus(myComponent.myCbDisplayIconsInMenu.isSelected()); update |= settings.getShowMemoryIndicator() != myComponent.myShowMemoryIndicatorCheckBox.isSelected(); settings.setShowMemoryIndicator(myComponent.myShowMemoryIndicatorCheckBox.isSelected()); update |= settings.getAllowMergeButtons() != myComponent.myAllowMergeButtons.isSelected(); settings.setAllowMergeButtons(myComponent.myAllowMergeButtons.isSelected()); update |= settings.getCycleScrolling() != myComponent.myCycleScrollingCheckBox.isSelected(); settings.setCycleScrolling(myComponent.myCycleScrollingCheckBox.isSelected()); - if (settings.OVERRIDE_NONIDEA_LAF_FONTS != myComponent.myOverrideLAFFonts.isSelected()) { + if (settings.getOverrideLafFonts() != myComponent.myOverrideLAFFonts.isSelected()) { shouldUpdateUI = true; update = true; } - settings.OVERRIDE_NONIDEA_LAF_FONTS = myComponent.myOverrideLAFFonts.isSelected(); - settings.MOVE_MOUSE_ON_DEFAULT_BUTTON = myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected(); - settings.HIDE_NAVIGATION_ON_FOCUS_LOSS = myComponent.myHideNavigationPopupsCheckBox.isSelected(); - settings.DND_WITH_PRESSED_ALT_ONLY = myComponent.myAltDNDCheckBox.isSelected(); + settings.setOverrideLafFonts(myComponent.myOverrideLAFFonts.isSelected()); + settings.setMoveMouseOnDefaultButton(myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected()); + settings.setHideNavigationOnFocusLoss(myComponent.myHideNavigationPopupsCheckBox.isSelected()); + settings.setDndWithPressedAltOnly(myComponent.myAltDNDCheckBox.isSelected()); - update |= settings.DISABLE_MNEMONICS != myComponent.myDisableMnemonics.isSelected(); - settings.DISABLE_MNEMONICS = myComponent.myDisableMnemonics.isSelected(); + update |= settings.getDisableMnemonics() != myComponent.myDisableMnemonics.isSelected(); + settings.setDisableMnemonics(myComponent.myDisableMnemonics.isSelected()); - update |= settings.USE_SMALL_LABELS_ON_TABS != myComponent.myUseSmallLabelsOnTabs.isSelected(); - settings.USE_SMALL_LABELS_ON_TABS = myComponent.myUseSmallLabelsOnTabs.isSelected(); + update |= settings.getUseSmallLabelsOnTabs() != myComponent.myUseSmallLabelsOnTabs.isSelected(); + settings.setUseSmallLabelsOnTabs(myComponent.myUseSmallLabelsOnTabs.isSelected()); update |= settings.getWideScreenSupport() != myComponent.myWidescreenLayoutCheckBox.isSelected(); settings.setWideScreenSupport(myComponent.myWidescreenLayoutCheckBox.isSelected()); @@ -222,8 +222,8 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab update |= settings.getRightHorizontalSplit() != myComponent.myRightLayoutCheckBox.isSelected(); settings.setRightHorizontalSplit(myComponent.myRightLayoutCheckBox.isSelected()); - update |= settings.NAVIGATE_TO_PREVIEW != (myComponent.myNavigateToPreviewCheckBox.isVisible() && myComponent.myNavigateToPreviewCheckBox.isSelected()); - settings.NAVIGATE_TO_PREVIEW = myComponent.myNavigateToPreviewCheckBox.isSelected(); + update |= settings.getNavigateToPreview() != (myComponent.myNavigateToPreviewCheckBox.isVisible() && myComponent.myNavigateToPreviewCheckBox.isSelected()); + settings.setNavigateToPreview(myComponent.myNavigateToPreviewCheckBox.isSelected()); ColorBlindness blindness = myComponent.myColorBlindnessPanel.getColorBlindness(); boolean updateEditorScheme = false; @@ -234,11 +234,11 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab updateEditorScheme = true; } - update |= settings.DISABLE_MNEMONICS_IN_CONTROLS != myComponent.myDisableMnemonicInControlsCheckBox.isSelected(); - settings.DISABLE_MNEMONICS_IN_CONTROLS = myComponent.myDisableMnemonicInControlsCheckBox.isSelected(); + update |= settings.getDisableMnemonicsInControls() != myComponent.myDisableMnemonicInControlsCheckBox.isSelected(); + settings.setDisableMnemonicsInControls(myComponent.myDisableMnemonicInControlsCheckBox.isSelected()); - update |= settings.SHOW_ICONS_IN_QUICK_NAVIGATION != myComponent.myHideIconsInQuickNavigation.isSelected(); - settings.SHOW_ICONS_IN_QUICK_NAVIGATION = myComponent.myHideIconsInQuickNavigation.isSelected(); + update |= settings.getShowIconInQuickNavigation() != myComponent.myHideIconsInQuickNavigation.isSelected(); + settings.setShowIconInQuickNavigation(myComponent.myHideIconsInQuickNavigation.isSelected()); if (!Comparing.equal(myComponent.myLafComboBox.getSelectedItem(), lafManager.getCurrentLookAndFeel())) { final UIManager.LookAndFeelInfo lafInfo = (UIManager.LookAndFeelInfo)myComponent.myLafComboBox.getSelectedItem(); @@ -250,7 +250,6 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab } } - if (shouldUpdateUI) { lafManager.updateUI(); } @@ -263,12 +262,12 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab catch (NumberFormatException ignored) { } float ratio = myComponent.myAlphaModeRatioSlider.getValue() / 100f; - if (myComponent.myEnableAlphaModeCheckBox.isSelected() != settings.ENABLE_ALPHA_MODE || - delay != -1 && delay != settings.ALPHA_MODE_DELAY || ratio != settings.ALPHA_MODE_RATIO) { + if (myComponent.myEnableAlphaModeCheckBox.isSelected() != settings.getEnableAlphaMode() || + delay != -1 && delay != settings.getAlphaModeDelay() || ratio != settings.getAlphaModeRatio()) { update = true; - settings.ENABLE_ALPHA_MODE = myComponent.myEnableAlphaModeCheckBox.isSelected(); - settings.ALPHA_MODE_DELAY = delay; - settings.ALPHA_MODE_RATIO = ratio; + settings.setEnableAlphaMode(myComponent.myEnableAlphaModeCheckBox.isSelected()); + settings.setAlphaModeDelay(delay); + settings.setAlphaModeRatio(ratio); } } int tooltipDelay = Math.min(myComponent.myInitialTooltipDelaySlider.getValue(), 5000); @@ -314,7 +313,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab initComponent(); UISettings settings = UISettings.getInstance(); - if (settings.OVERRIDE_NONIDEA_LAF_FONTS) { + if (settings.getOverrideLafFonts()) { myComponent.myFontCombo.setFontName(settings.FONT_FACE); } else { myComponent.myFontCombo.setFontName(UIUtil.getLabelFont().getFamily()); @@ -327,45 +326,45 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab myComponent.myAntialiasingInEditor.setSelectedItem(settings.getEditorAAType()); myComponent.myFontSizeCombo.setSelectedItem(Integer.toString(settings.FONT_SIZE)); - myComponent.myPresentationModeFontSize.setSelectedItem(Integer.toString(settings.PRESENTATION_MODE_FONT_SIZE)); + myComponent.myPresentationModeFontSize.setSelectedItem(Integer.toString(settings.getPresentationModeFontSize())); myComponent.myAnimateWindowsCheckBox.setSelected(settings.getAnimateWindows()); myComponent.myWindowShortcutsCheckBox.setSelected(settings.getShowToolWindowsNumbers()); myComponent.myShowToolStripesCheckBox.setSelected(!settings.getHideToolStripes()); - myComponent.myCbDisplayIconsInMenu.setSelected(settings.SHOW_ICONS_IN_MENUS); + myComponent.myCbDisplayIconsInMenu.setSelected(settings.getShowIconsInMenus()); myComponent.myShowMemoryIndicatorCheckBox.setSelected(settings.getShowMemoryIndicator()); myComponent.myAllowMergeButtons.setSelected(settings.getAllowMergeButtons()); myComponent.myCycleScrollingCheckBox.setSelected(settings.getCycleScrolling()); - myComponent.myHideIconsInQuickNavigation.setSelected(settings.SHOW_ICONS_IN_QUICK_NAVIGATION); - myComponent.myMoveMouseOnDefaultButtonCheckBox.setSelected(settings.MOVE_MOUSE_ON_DEFAULT_BUTTON); - myComponent.myHideNavigationPopupsCheckBox.setSelected(settings.HIDE_NAVIGATION_ON_FOCUS_LOSS); - myComponent.myAltDNDCheckBox.setSelected(settings.DND_WITH_PRESSED_ALT_ONLY); + myComponent.myHideIconsInQuickNavigation.setSelected(settings.getShowIconInQuickNavigation()); + myComponent.myMoveMouseOnDefaultButtonCheckBox.setSelected(settings.getMoveMouseOnDefaultButton()); + myComponent.myHideNavigationPopupsCheckBox.setSelected(settings.getHideNavigationOnFocusLoss()); + myComponent.myAltDNDCheckBox.setSelected(settings.getDndWithPressedAltOnly()); myComponent.myLafComboBox.setSelectedItem(LafManager.getInstance().getCurrentLookAndFeel()); - myComponent.myOverrideLAFFonts.setSelected(settings.OVERRIDE_NONIDEA_LAF_FONTS); - myComponent.myDisableMnemonics.setSelected(settings.DISABLE_MNEMONICS); - myComponent.myUseSmallLabelsOnTabs.setSelected(settings.USE_SMALL_LABELS_ON_TABS); + myComponent.myOverrideLAFFonts.setSelected(settings.getOverrideLafFonts()); + myComponent.myDisableMnemonics.setSelected(settings.getDisableMnemonics()); + myComponent.myUseSmallLabelsOnTabs.setSelected(settings.getUseSmallLabelsOnTabs()); myComponent.myWidescreenLayoutCheckBox.setSelected(settings.getWideScreenSupport()); myComponent.myLeftLayoutCheckBox.setSelected(settings.getLeftHorizontalSplit()); myComponent.myRightLayoutCheckBox.setSelected(settings.getRightHorizontalSplit()); - myComponent.myNavigateToPreviewCheckBox.setSelected(settings.NAVIGATE_TO_PREVIEW); + myComponent.myNavigateToPreviewCheckBox.setSelected(settings.getNavigateToPreview()); myComponent.myNavigateToPreviewCheckBox.setVisible(false);//disabled for a while myComponent.myColorBlindnessPanel.setColorBlindness(settings.COLOR_BLINDNESS); - myComponent.myDisableMnemonicInControlsCheckBox.setSelected(settings.DISABLE_MNEMONICS_IN_CONTROLS); + myComponent.myDisableMnemonicInControlsCheckBox.setSelected(settings.getDisableMnemonicsInControls()); boolean alphaModeEnabled = WindowManagerEx.getInstanceEx().isAlphaModeSupported(); if (alphaModeEnabled) { - myComponent.myEnableAlphaModeCheckBox.setSelected(settings.ENABLE_ALPHA_MODE); + myComponent.myEnableAlphaModeCheckBox.setSelected(settings.getEnableAlphaMode()); } else { myComponent.myEnableAlphaModeCheckBox.setSelected(false); } myComponent.myEnableAlphaModeCheckBox.setEnabled(alphaModeEnabled); - myComponent.myAlphaModeDelayTextField.setText(Integer.toString(settings.ALPHA_MODE_DELAY)); - myComponent.myAlphaModeDelayTextField.setEnabled(alphaModeEnabled && settings.ENABLE_ALPHA_MODE); - int ratio = (int)(settings.ALPHA_MODE_RATIO * 100f); + myComponent.myAlphaModeDelayTextField.setText(Integer.toString(settings.getAlphaModeDelay())); + myComponent.myAlphaModeDelayTextField.setEnabled(alphaModeEnabled && settings.getEnableAlphaMode()); + int ratio = (int)(settings.getAlphaModeRatio() * 100f); myComponent.myAlphaModeRatioSlider.setValue(ratio); myComponent.myAlphaModeRatioSlider.setToolTipText(ratio + "%"); - myComponent.myAlphaModeRatioSlider.setEnabled(alphaModeEnabled && settings.ENABLE_ALPHA_MODE); + myComponent.myAlphaModeRatioSlider.setEnabled(alphaModeEnabled && settings.getEnableAlphaMode()); myComponent.myInitialTooltipDelaySlider.setValue(Registry.intValue("ide.tooltip.initialDelay")); myComponent.updateCombo(); } @@ -398,33 +397,33 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab isModified |= myComponent.myAnimateWindowsCheckBox.isSelected() != settings.getAnimateWindows(); isModified |= myComponent.myWindowShortcutsCheckBox.isSelected() != settings.getShowToolWindowsNumbers(); isModified |= myComponent.myShowToolStripesCheckBox.isSelected() == settings.getHideToolStripes(); - isModified |= myComponent.myCbDisplayIconsInMenu.isSelected() != settings.SHOW_ICONS_IN_MENUS; + isModified |= myComponent.myCbDisplayIconsInMenu.isSelected() != settings.getShowIconsInMenus(); isModified |= myComponent.myShowMemoryIndicatorCheckBox.isSelected() != settings.getShowMemoryIndicator(); isModified |= myComponent.myAllowMergeButtons.isSelected() != settings.getAllowMergeButtons(); isModified |= myComponent.myCycleScrollingCheckBox.isSelected() != settings.getCycleScrolling(); - isModified |= myComponent.myOverrideLAFFonts.isSelected() != settings.OVERRIDE_NONIDEA_LAF_FONTS; + isModified |= myComponent.myOverrideLAFFonts.isSelected() != settings.getOverrideLafFonts(); - isModified |= myComponent.myDisableMnemonics.isSelected() != settings.DISABLE_MNEMONICS; - isModified |= myComponent.myDisableMnemonicInControlsCheckBox.isSelected() != settings.DISABLE_MNEMONICS_IN_CONTROLS; + isModified |= myComponent.myDisableMnemonics.isSelected() != settings.getDisableMnemonics(); + isModified |= myComponent.myDisableMnemonicInControlsCheckBox.isSelected() != settings.getDisableMnemonicsInControls(); - isModified |= myComponent.myUseSmallLabelsOnTabs.isSelected() != settings.USE_SMALL_LABELS_ON_TABS; + isModified |= myComponent.myUseSmallLabelsOnTabs.isSelected() != settings.getUseSmallLabelsOnTabs(); isModified |= myComponent.myWidescreenLayoutCheckBox.isSelected() != settings.getWideScreenSupport(); isModified |= myComponent.myLeftLayoutCheckBox.isSelected() != settings.getLeftHorizontalSplit(); isModified |= myComponent.myRightLayoutCheckBox.isSelected() != settings.getRightHorizontalSplit(); - isModified |= myComponent.myNavigateToPreviewCheckBox.isSelected() != settings.NAVIGATE_TO_PREVIEW; + isModified |= myComponent.myNavigateToPreviewCheckBox.isSelected() != settings.getNavigateToPreview(); isModified |= myComponent.myColorBlindnessPanel.getColorBlindness() != settings.COLOR_BLINDNESS; - isModified |= myComponent.myHideIconsInQuickNavigation.isSelected() != settings.SHOW_ICONS_IN_QUICK_NAVIGATION; + isModified |= myComponent.myHideIconsInQuickNavigation.isSelected() != settings.getShowIconInQuickNavigation(); - isModified |= !Comparing.equal(myComponent.myPresentationModeFontSize.getEditor().getItem(), Integer.toString(settings.PRESENTATION_MODE_FONT_SIZE)); + isModified |= !Comparing.equal(myComponent.myPresentationModeFontSize.getEditor().getItem(), Integer.toString(settings.getPresentationModeFontSize())); - isModified |= myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected() != settings.MOVE_MOUSE_ON_DEFAULT_BUTTON; - isModified |= myComponent.myHideNavigationPopupsCheckBox.isSelected() != settings.HIDE_NAVIGATION_ON_FOCUS_LOSS; - isModified |= myComponent.myAltDNDCheckBox.isSelected() != settings.DND_WITH_PRESSED_ALT_ONLY; + isModified |= myComponent.myMoveMouseOnDefaultButtonCheckBox.isSelected() != settings.getMoveMouseOnDefaultButton(); + isModified |= myComponent.myHideNavigationPopupsCheckBox.isSelected() != settings.getHideNavigationOnFocusLoss(); + isModified |= myComponent.myAltDNDCheckBox.isSelected() != settings.getDndWithPressedAltOnly(); isModified |= !Comparing.equal(myComponent.myLafComboBox.getSelectedItem(), LafManager.getInstance().getCurrentLookAndFeel()); if (WindowManagerEx.getInstanceEx().isAlphaModeSupported()) { - isModified |= myComponent.myEnableAlphaModeCheckBox.isSelected() != settings.ENABLE_ALPHA_MODE; + isModified |= myComponent.myEnableAlphaModeCheckBox.isSelected() != settings.getEnableAlphaMode(); int delay = -1; try { delay = Integer.parseInt(myComponent.myAlphaModeDelayTextField.getText()); @@ -432,10 +431,10 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab catch (NumberFormatException ignored) { } if (delay != -1) { - isModified |= delay != settings.ALPHA_MODE_DELAY; + isModified |= delay != settings.getAlphaModeDelay(); } float ratio = myComponent.myAlphaModeRatioSlider.getValue() / 100f; - isModified |= ratio != settings.ALPHA_MODE_RATIO; + isModified |= ratio != settings.getAlphaModeRatio(); } int tooltipDelay = myComponent.myInitialTooltipDelaySlider.getValue(); isModified |= tooltipDelay != Registry.intValue("ide.tooltip.initialDelay"); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java index dd8d1bc050e3..4535706bcc23 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java @@ -742,7 +742,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo // } //} else UISettings uiSettings = UISettings.getInstance(); - if (uiSettings.OVERRIDE_NONIDEA_LAF_FONTS) { + if (uiSettings.getOverrideLafFonts()) { storeOriginalFontDefaults(uiDefaults); JBUI.setUserScaleFactor(uiSettings.FONT_SIZE / UIUtil.DEF_SYSTEM_FONT_SIZE); initFontDefaults(uiDefaults, uiSettings.FONT_SIZE, new FontUIResource(uiSettings.FONT_FACE, Font.PLAIN, uiSettings.FONT_SIZE)); diff --git a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java index f3c698179c18..09bfc9ab713e 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -129,7 +129,7 @@ public class NotificationsUtil { @Nullable public static Pair getFontData() { UISettings uiSettings = UISettings.getInstance(); - if (uiSettings.OVERRIDE_NONIDEA_LAF_FONTS) { + if (uiSettings.getOverrideLafFonts()) { return Pair.create(uiSettings.FONT_FACE, uiSettings.FONT_SIZE); } return UIUtil.getSystemFontData(); @@ -147,6 +147,7 @@ public class NotificationsUtil { if (listener == null) return null; return new HyperlinkListener() { + @Override public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { final NotificationListener listener1 = notification.getListener(); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java index 8d3ff2d736c2..5ef89d53023d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -225,8 +225,8 @@ public final class ActionMenu extends JBMenu { } private void updateIcon() { - UISettings settings = UISettings.getInstance(); - if (settings != null && settings.SHOW_ICONS_IN_MENUS) { + UISettings settings = UISettings.getInstanceOrNull(); + if (settings != null && settings.getShowIconsInMenus()) { final Presentation presentation = myPresentation; final Icon icon = presentation.getIcon(); setIcon(icon); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java index c76cd15940e3..b43d40f98392 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,10 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.TransactionGuard; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.KeymapUtil; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.ActionCallback; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.SizedIcon; import com.intellij.ui.components.JBCheckBoxMenuItem; @@ -212,7 +215,7 @@ public class ActionMenuItem extends JBCheckBoxMenuItem { } private void updateIcon(AnAction action) { - if (isToggleable() && (myPresentation.getIcon() == null || myInsideCheckedGroup || !UISettings.getInstance().SHOW_ICONS_IN_MENUS)) { + if (isToggleable() && (myPresentation.getIcon() == null || myInsideCheckedGroup || !UISettings.getInstance().getShowIconsInMenus())) { action.update(myEvent); myToggled = Boolean.TRUE.equals(myEvent.getPresentation().getClientProperty(Toggleable.SELECTED_PROPERTY)); if (ActionPlaces.MAIN_MENU.equals(myPlace) && SystemInfo.isMacSystemMenu || @@ -232,7 +235,7 @@ public class ActionMenuItem extends JBCheckBoxMenuItem { } } else { - if (UISettings.getInstance().SHOW_ICONS_IN_MENUS) { + if (UISettings.getInstance().getShowIconsInMenus()) { Icon icon = myPresentation.getIcon(); if (action instanceof ToggleAction && ((ToggleAction)action).isSelected(myEvent)) { icon = new PoppedIcon(icon, 16, 16); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java index 2cc85907c203..3df6880cf715 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionPopupMenuImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,6 +58,7 @@ public final class ActionPopupMenuImpl extends ApplicationActivationListener.Ada myApp = ApplicationManager.getApplication(); } + @Override public JPopupMenu getComponent() { return myMenu; } @@ -79,6 +80,7 @@ public final class ActionPopupMenuImpl extends ApplicationActivationListener.Ada addPopupMenuListener(new MyPopupMenuListener()); } + @Override public void show(final Component component, int x, int y) { if (!component.isShowing()) { //noinspection HardCodedStringLiteral @@ -118,10 +120,12 @@ public final class ActionPopupMenuImpl extends ApplicationActivationListener.Ada } private class MyPopupMenuListener implements PopupMenuListener { + @Override public void popupMenuCanceled(PopupMenuEvent e) { disposeMenu(); } + @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { disposeMenu(); } @@ -134,9 +138,10 @@ public final class ActionPopupMenuImpl extends ApplicationActivationListener.Ada } } + @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { MyMenu.this.removeAll(); - Utils.fillMenu(myGroup, MyMenu.this, !UISettings.getInstance().DISABLE_MNEMONICS, myPresentationFactory, myContext, myPlace, false, + Utils.fillMenu(myGroup, MyMenu.this, !UISettings.getInstance().getDisableMnemonics(), myPresentationFactory, myContext, myPlace, false, false, LaterInvocator.isInModalContext()); myManager.addActionPopup(ActionPopupMenuImpl.this); } @@ -153,5 +158,4 @@ public final class ActionPopupMenuImpl extends ApplicationActivationListener.Ada myMenu.setVisible(false); } } - } diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MenuItemPresentationFactory.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MenuItemPresentationFactory.java index 54d83c762dce..debc0c75d480 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MenuItemPresentationFactory.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/MenuItemPresentationFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,7 +34,7 @@ public class MenuItemPresentationFactory extends PresentationFactory { } protected void processPresentation(Presentation presentation) { - if (!UISettings.getInstance().SHOW_ICONS_IN_MENUS || myForceHide) { + if (!UISettings.getInstance().getShowIconsInMenus() || myForceHide) { presentation.setIcon(null); presentation.setDisabledIcon(null); presentation.setHoveredIcon(null); diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 7e6b0c7221a1..8392bef30727 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -96,7 +96,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public class ApplicationImpl extends PlatformComponentManagerImpl implements ApplicationEx { private static final Logger LOG = Logger.getInstance("#com.intellij.application.impl.ApplicationImpl"); - private final ReadMostlyRWLock myLock; + final ReadMostlyRWLock myLock; private final ModalityInvokator myInvokator = new ModalityInvokatorImpl(); @@ -110,7 +110,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private final String myName; private final Stack myWriteActionsStack = new Stack<>(); // accessed from EDT only, no need to sync - private int myWriteStackBase = 0; + private int myWriteStackBase; private volatile Thread myWriteActionThread; private int myInEditorPaintCounter; // EDT only @@ -163,7 +163,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App AWTExceptionHandler.register(); // do not crash AWT on exceptions - Disposer.setDebugMode((isInternal || isUnitTestMode || Disposer.isDebugDisposerOn())); + Disposer.setDebugMode(isInternal || isUnitTestMode || Disposer.isDebugDisposerOn()); myStartTime = System.currentTimeMillis(); mySplash = splash; @@ -487,7 +487,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App @Override protected void setProgressDuringInit(@NotNull ProgressIndicator indicator) { float start = PluginManagerCore.PLUGINS_PROGRESS_PART + PluginManagerCore.LOADERS_PROGRESS_PART; - indicator.setFraction(start + (getPercentageOfComponentsLoaded() * (1 - start))); + indicator.setFraction(start + getPercentageOfComponentsLoaded() * (1 - start)); } private static void createLocatorFile() { @@ -1187,11 +1187,10 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App if (!myLock.isWriteLocked()) { assertNoPsiLock(); if (!myLock.tryWriteLock()) { - Future reportSlowWrite = ourDumpThreadsOnLongWriteActionWaiting > 0 ? - JobScheduler.getScheduler() - .scheduleWithFixedDelay(() -> PerformanceWatcher.getInstance().dumpThreads("waiting", true), - ourDumpThreadsOnLongWriteActionWaiting, - ourDumpThreadsOnLongWriteActionWaiting, TimeUnit.MILLISECONDS) : null; + Future reportSlowWrite = ourDumpThreadsOnLongWriteActionWaiting <= 0 ? null : + JobScheduler.getScheduler().scheduleWithFixedDelay(() -> PerformanceWatcher.getInstance().dumpThreads("waiting", true), + ourDumpThreadsOnLongWriteActionWaiting, + ourDumpThreadsOnLongWriteActionWaiting, TimeUnit.MILLISECONDS); myLock.writeLock(); if (reportSlowWrite != null) { reportSlowWrite.cancel(false); diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ReadMostlyRWLock.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ReadMostlyRWLock.java index 576a39db523b..7957069f212f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ReadMostlyRWLock.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ReadMostlyRWLock.java @@ -48,7 +48,7 @@ import java.util.concurrent.locks.LockSupport; class ReadMostlyRWLock { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.impl.ReadMostlyRWLock"); private final Thread writeThread; - private volatile boolean writeRequested; // this writer is requesting or obtained the write access + volatile boolean writeRequested; // this writer is requesting or obtained the write access private volatile boolean writeAcquired; // this writer obtained the write lock // All reader threads are registered here. Dead readers are garbage collected in writeUnlock(). private final ConcurrentList readers = ContainerUtil.createConcurrentList(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java index b95f082d6900..02bc235cfdef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/util/EditorUtil.java @@ -860,7 +860,7 @@ public final class EditorUtil { public static Font getEditorFont() { EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme(); int size = UISettings.getInstance().getPresentationMode() - ? UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE - 4 : scheme.getEditorFontSize(); + ? UISettings.getInstance().getPresentationModeFontSize() - 4 : scheme.getEditorFontSize(); return new Font(scheme.getEditorFontName(), Font.PLAIN, size); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index b1c876c40c5a..8297cb9c0d20 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -65,6 +65,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.*; import com.intellij.util.ui.JBUI.JBUIScaleTrackable; +import com.intellij.util.ui.JBUI.ScaleType; import gnu.trove.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -227,7 +228,11 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse }) .setImageProvider((NullableFunction)info -> { Image image = IconUtil.toImage(scaleIcon(getGutterRenderer(info.getPoint()).getIcon())); - return new DnDImage(ImageUtil.toBufferedImage(image), new Point(image.getWidth(null) / 2, image.getHeight(null) / 2)); + // [tav] temp workaround for JRE-224 + if (SystemInfo.isWindows && UIUtil.isJDKManagedHiDPI()) { + image = ImageUtil.toBufferedImage(image, !JBUI.isHiDPI((Graphics2D)GraphicsUtil.safelyGetGraphics(myEditor.getComponent()), ScaleType.SYS)); + } + return new DnDImage(image, new Point(image.getWidth(null) / 2, image.getHeight(null) / 2)); }) .enableAsNativeTarget() // required to accept dragging from editor (as editor component doesn't use DnDSupport to implement drag'n'drop) .install(); diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 0f619c7929be..d8bcd22d48b9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -536,7 +536,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi }, myCaretModel); if (UISettings.getInstance().getPresentationMode()) { - setFontSize(UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE); + setFontSize(UISettings.getInstance().getPresentationModeFontSize()); } myGutterComponent.updateSize(); @@ -548,7 +548,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi if (SystemInfo.isJavaVersionAtLeast("1.8") && SystemInfo.isMacIntel64 && SystemInfo.isJetbrainsJvm && Registry.is("ide.mac.forceTouch")) { new MacGestureSupportForEditor(getComponent()); } - } /** @@ -1517,7 +1516,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi assertIsDispatchThread(); if (!updatingSize) { updatingSize = true; - SwingUtilities.invokeLater(() -> { + ApplicationManager.getApplication().invokeLater(() -> { try { if (!isDisposed()) { myGutterComponent.updateSize(); @@ -1526,7 +1525,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi finally { updatingSize = false; } - }); + }, __->isDisposed()); } } @@ -1613,7 +1612,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi public void stopDumbLater() { if (ApplicationManager.getApplication().isUnitTestMode()) return; - ApplicationManager.getApplication().invokeLater(this::stopDumb, ModalityState.current()); + ApplicationManager.getApplication().invokeLater(this::stopDumb, ModalityState.current(), __ -> isDisposed()); } private void stopDumb() { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java index dad69dd5e80e..2aa6f419d302 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java @@ -777,8 +777,8 @@ class EditorPainter implements TextDrawingCallback { } } else if (startOffset < maxOffset && endOffset > minOffset) { - float x1 = fragment.offsetToX(Math.max(minOffset, startOffset)); - float x2 = fragment.offsetToX(Math.min(maxOffset, endOffset)); + float x1 = minOffset == maxOffset ? fragment.getStartX() : fragment.offsetToX(Math.max(minOffset, startOffset)); + float x2 = minOffset == maxOffset ? fragment.getEndX() : fragment.offsetToX(Math.min(maxOffset, endOffset)); if (x1 > x2) { float tmp = x1; x1 = x2; diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java index ea94541fbc52..9b2c25aa86e8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorWindow.java @@ -338,7 +338,7 @@ public class EditorWindow { return currentlySelectedIndex; } UISettings uiSettings = UISettings.getInstance(); - if (uiSettings.ACTIVATE_MRU_EDITOR_ON_CLOSE) { + if (uiSettings.getActiveMruEditorOnClose()) { // try to open last visited file final VirtualFile[] histFiles = EditorHistoryManager.getInstance(getManager ().getProject()).getFiles(); for (int idx = histFiles.length - 1; idx >= 0; idx--) { @@ -357,7 +357,7 @@ public class EditorWindow { } } } else - if (uiSettings.ACTIVATE_RIGHT_EDITOR_ON_CLOSE && fileIndex + 1 < myTabbedPane.getTabCount()) { + if (uiSettings.getActiveRigtEditorOnClose() && fileIndex + 1 < myTabbedPane.getTabCount()) { return fileIndex + 1; } @@ -856,7 +856,7 @@ public class EditorWindow { final int index = findEditorIndex(findFileComposite(file)); if (index != -1) { setTitleAt(index, EditorTabbedContainer.calcTabTitle(getManager().getProject(), file)); - setToolTipTextAt(index, UISettings.getInstance().SHOW_TABS_TOOLTIPS + setToolTipTextAt(index, UISettings.getInstance().getShowTabsTooltips() ? getManager().getFileTooltipText(file) : null); } @@ -887,9 +887,10 @@ public class EditorWindow { } final Icon modifiedIcon; - if (UISettings.getInstance().MARK_MODIFIED_TABS_WITH_ASTERISK || !UISettings.getInstance().getHideTabsIfNeed()) { + UISettings settings = UISettings.getInstance(); + if (settings.getMarkModifiedTabsWithAsterisk() || !settings.getHideTabsIfNeed()) { modifiedIcon = - UISettings.getInstance().MARK_MODIFIED_TABS_WITH_ASTERISK && composite != null && composite.isModified() ? MODIFIED_ICON : GAP_ICON; + settings.getMarkModifiedTabsWithAsterisk() && composite != null && composite.isModified() ? MODIFIED_ICON : GAP_ICON; count++; } else { @@ -900,7 +901,7 @@ public class EditorWindow { int i = 0; final LayeredIcon result = new LayeredIcon(count); - int xShift = !UISettings.getInstance().getHideTabsIfNeed() ? 4 : 0; + int xShift = !settings.getHideTabsIfNeed() ? 4 : 0; result.setIcon(baseIcon, i++, xShift, 0); if (pinIcon != null) result.setIcon(pinIcon, i++, xShift, 0); if (modifiedIcon != null) result.setIcon(modifiedIcon, i++); @@ -1068,7 +1069,7 @@ public class EditorWindow { FileEditorManagerEx.getInstanceEx(getManager().getProject()).getReady(this).doWhenDone(() -> { if (myTabbedPane == null) return; - final boolean closeNonModifiedFilesFirst = UISettings.getInstance().CLOSE_NON_MODIFIED_FILES_FIRST; + final boolean closeNonModifiedFilesFirst = UISettings.getInstance().getCloseNonModifiedFilesFirst(); final EditorComposite selectedComposite = getSelectedEditor(); try { doTrimSize(limit, fileToIgnore, closeNonModifiedFilesFirst, transferFocus); diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java index 33b498e8e3b0..7e01664416bf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ActionsTree.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -518,7 +518,7 @@ public class ActionsTree { myRow = row; myHaveLink = false; myLink.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); - final boolean showIcons = UISettings.getInstance().SHOW_ICONS_IN_MENUS; + final boolean showIcons = UISettings.getInstance().getShowIconsInMenus(); Keymap originalKeymap = myKeymap != null ? myKeymap.getParent() : null; Icon icon = null; String text; diff --git a/platform/platform-impl/src/com/intellij/openapi/preview/impl/PreviewManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/preview/impl/PreviewManagerImpl.java index da22f082236d..bd5dfc710715 100644 --- a/platform/platform-impl/src/com/intellij/openapi/preview/impl/PreviewManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/preview/impl/PreviewManagerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,7 +78,7 @@ public class PreviewManagerImpl implements PreviewManager, PersistentStateCompon private boolean myInnerSelectionChange; private static boolean isAvailable() { - return UISettings.getInstance().NAVIGATE_TO_PREVIEW; + return UISettings.getInstance().getNavigateToPreview(); } public PreviewManagerImpl(Project project) { @@ -91,12 +91,7 @@ public class PreviewManagerImpl implements PreviewManager, PersistentStateCompon Disposer.register(project, provider); } - project.getMessageBus().connect().subscribe(UISettingsListener.TOPIC, new UISettingsListener() { - @Override - public void uiSettingsChanged(UISettings uiSettings) { - checkGlobalState(); - } - }); + project.getMessageBus().connect().subscribe(UISettingsListener.TOPIC, uiSettings -> checkGlobalState()); checkGlobalState(); checkEmptyState(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java index 2b13ce37f5b2..c7d348ab7ff9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/ProjectManagerImpl.java @@ -19,7 +19,6 @@ import com.intellij.configurationStore.StorageUtilKt; import com.intellij.conversion.ConversionResult; import com.intellij.conversion.ConversionService; import com.intellij.ide.AppLifecycleListener; -import com.intellij.ide.IdeEventQueue; import com.intellij.ide.impl.ProjectUtil; import com.intellij.ide.plugins.PluginManager; import com.intellij.ide.startup.StartupManagerEx; @@ -385,9 +384,6 @@ public class ProjectManagerImpl extends ProjectManagerEx implements Disposable { return true; } - // process all pending events that can interrupt focus flow - IdeEventQueue.getInstance().flushQueue(); - boolean ok = myProgressManager.runProcessWithProgressSynchronously(process, ProjectBundle.message("project.load.progress"), canCancelProjectLoading(), project); if (!ok) { closeProject(project, false, false, true); diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateCheckerComponent.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateCheckerComponent.java index 2f0a878a5138..5aad05795105 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateCheckerComponent.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateCheckerComponent.java @@ -42,6 +42,8 @@ import org.jetbrains.annotations.NotNull; import javax.swing.event.HyperlinkEvent; +import static java.lang.Math.max; + /** * @author yole */ @@ -111,13 +113,13 @@ public class UpdateCheckerComponent implements ApplicationComponentAdapter, Disp public void appFrameCreated(String[] commandLineArgs, @NotNull Ref willOpenProject) { BuildNumber currentBuild = ApplicationInfo.getInstance().getBuild(); BuildNumber lastBuildChecked = BuildNumber.fromString(mySettings.getLasBuildChecked()); - long timeToNextCheck = mySettings.getLastTimeChecked() + CHECK_INTERVAL - System.currentTimeMillis(); + long timeSinceLastCheck = max(System.currentTimeMillis() - mySettings.getLastTimeChecked(), 0); - if (lastBuildChecked == null || currentBuild.compareTo(lastBuildChecked) > 0 || timeToNextCheck <= 0) { + if (lastBuildChecked == null || currentBuild.compareTo(lastBuildChecked) > 0 || timeSinceLastCheck >= CHECK_INTERVAL) { myCheckRunnable.run(); } else { - queueNextCheck(timeToNextCheck); + queueNextCheck(CHECK_INTERVAL - timeSinceLastCheck); } } }); diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java index bc59a01911c4..4eb05e96e20d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VirtualFileSystemEntry.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -389,7 +389,7 @@ public abstract class VirtualFileSystemEntry extends NewVirtualFile { @Override public String getPresentableName() { - if (UISettings.getInstance().HIDE_KNOWN_EXTENSION_IN_TABS && !isDirectory()) { + if (UISettings.getInstance().getHdeKnownExtensionInTabs() && !isDirectory()) { final String nameWithoutExtension = getNameWithoutExtension(); return nameWithoutExtension.isEmpty() ? getName() : nameWithoutExtension; } diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java index aa5114bc05eb..b6e4202c1448 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFSImpl.java @@ -16,6 +16,7 @@ package com.intellij.openapi.vfs.newvfs.persistent; import com.intellij.concurrency.JobSchedulerImpl; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.components.ApplicationComponent; @@ -53,7 +54,7 @@ import java.util.concurrent.atomic.AtomicBoolean; /** * @author max */ -public class PersistentFSImpl extends PersistentFS implements ApplicationComponent { +public class PersistentFSImpl extends PersistentFS implements ApplicationComponent, Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vfs.newvfs.persistent.PersistentFS"); private final MessageBus myEventBus; @@ -66,13 +67,12 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone private final Object myInputLock = new Object(); private final AtomicBoolean myShutDown = new AtomicBoolean(false); - @SuppressWarnings({"FieldCanBeLocal", "unused"}) - private final LowMemoryWatcher myWatcher = LowMemoryWatcher.register(this::clearIdCache); private volatile int myStructureModificationCount; public PersistentFSImpl(@NotNull MessageBus bus) { myEventBus = bus; ShutDownTracker.getInstance().registerShutdownTask(this::performShutdown); + LowMemoryWatcher.register(this::clearIdCache, this); } @Override @@ -85,6 +85,10 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone performShutdown(); } + @Override + public void dispose() { + } + private void performShutdown() { if (myShutDown.compareAndSet(false, true)) { LOG.info("VFS dispose started"); @@ -1252,7 +1256,7 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone @NotNull String pathBeforeSlash) { super(id, segment, data, null, fs); myName = name; - if (pathBeforeSlash.contains("..") || pathBeforeSlash.endsWith("/")) { + if (!looksCanonical(pathBeforeSlash)) { throw new IllegalArgumentException("path must be canonical but got: '" + pathBeforeSlash + "'"); } myPathBeforeSlash = pathBeforeSlash; @@ -1293,4 +1297,19 @@ public class PersistentFSImpl extends PersistentFS implements ApplicationCompone return getFileSystem().getProtocol() + "://" + getPath(); } } + + private static boolean looksCanonical(@NotNull String pathBeforeSlash) { + if (pathBeforeSlash.endsWith("/")) { + return false; + } + int start = 0; + while (true) { + int i = pathBeforeSlash.indexOf("..", start); + if (i == -1) break; + if (i != 0 && pathBeforeSlash.charAt(i-1) == '/') return false; // /.. + if (i < pathBeforeSlash.length() - 2 && pathBeforeSlash.charAt(i+2) == '/') return false; // ../ + start = i+1; + } + return true; + } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FloatingDecorator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FloatingDecorator.java index 588857533132..82d1dd6663fb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FloatingDecorator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FloatingDecorator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,18 +119,20 @@ public final class FloatingDecorator extends JDialog { apply(info); } + @Override public final void show(){ setFocusableWindowState(myInfo.isActive()); super.show(); - final UISettings uiSettings=UISettings.getInstance(); - if(uiSettings.ENABLE_ALPHA_MODE){ - final WindowManagerEx windowManager=WindowManagerEx.getInstanceEx(); - windowManager.setAlphaModeEnabled(this,true); - if(myInfo.isActive()){ - windowManager.setAlphaModeRatio(this,0.0f); - }else{ - windowManager.setAlphaModeRatio(this,uiSettings.ALPHA_MODE_RATIO); + final UISettings uiSettings = UISettings.getInstance(); + if (uiSettings.getEnableAlphaMode()) { + final WindowManagerEx windowManager = WindowManagerEx.getInstanceEx(); + windowManager.setAlphaModeEnabled(this, true); + if (myInfo.isActive()) { + windowManager.setAlphaModeRatio(this, 0.0f); + } + else { + windowManager.setAlphaModeRatio(this, uiSettings.getAlphaModeRatio()); } } paint(getGraphics()); // This prevents annoying flick @@ -140,6 +142,7 @@ public final class FloatingDecorator extends JDialog { ApplicationManager.getApplication().getMessageBus().connect(myDelayAlarm).subscribe(UISettingsListener.TOPIC, myUISettingsListener); } + @Override public final void dispose(){ if (ScreenUtil.isStandardAddRemoveNotify(getParent())) { Disposer.dispose(myDelayAlarm); @@ -157,28 +160,29 @@ public final class FloatingDecorator extends JDialog { myInfo=info; // Set alpha mode final UISettings uiSettings=UISettings.getInstance(); - if(uiSettings.ENABLE_ALPHA_MODE&&isShowing()&&isDisplayable()){ + if (uiSettings.getEnableAlphaMode() && isShowing() && isDisplayable()) { myDelayAlarm.cancelAllRequests(); - if(myInfo.isActive()){ // make window non transparent + if (myInfo.isActive()) { // make window non transparent myFrameTicker.cancelAllRequests(); - myStartRatio=getCurrentAlphaRatio(); - if(myCurrentFrame>0){ - myCurrentFrame=TOTAL_FRAME_COUNT-myCurrentFrame; + myStartRatio = getCurrentAlphaRatio(); + if (myCurrentFrame > 0) { + myCurrentFrame = TOTAL_FRAME_COUNT - myCurrentFrame; } - myEndRatio=.0f; - myFrameTicker.addRequest(myAnimator,DELAY); - }else{ // make window transparent + myEndRatio = .0f; + myFrameTicker.addRequest(myAnimator, DELAY); + } + else { // make window transparent myDelayAlarm.addRequest( () -> { myFrameTicker.cancelAllRequests(); - myStartRatio=getCurrentAlphaRatio(); - if(myCurrentFrame>0){ - myCurrentFrame=TOTAL_FRAME_COUNT-myCurrentFrame; + myStartRatio = getCurrentAlphaRatio(); + if (myCurrentFrame > 0) { + myCurrentFrame = TOTAL_FRAME_COUNT - myCurrentFrame; } - myEndRatio=uiSettings.ALPHA_MODE_RATIO; - myFrameTicker.addRequest(myAnimator,DELAY); + myEndRatio = uiSettings.getAlphaModeRatio(); + myFrameTicker.addRequest(myAnimator, DELAY); }, - uiSettings.ALPHA_MODE_DELAY + uiSettings.getAlphaModeDelay() ); } } @@ -206,6 +210,7 @@ public final class FloatingDecorator extends JDialog { enableEvents(MouseEvent.MOUSE_EVENT_MASK|MouseEvent.MOUSE_MOTION_EVENT_MASK); } + @Override protected final void processMouseMotionEvent(final MouseEvent e){ super.processMouseMotionEvent(e); if(MouseEvent.MOUSE_DRAGGED==e.getID() && myLastPoint != null){ @@ -268,6 +273,7 @@ public final class FloatingDecorator extends JDialog { } } + @Override protected final void processMouseEvent(final MouseEvent e){ super.processMouseEvent(e); switch(e.getID()){ @@ -324,6 +330,7 @@ public final class FloatingDecorator extends JDialog { } } + @Override public final Dimension getPreferredSize(){ final Dimension d=super.getPreferredSize(); if(ANCHOR_TOP==myAnchor||ANCHOR_BOTTOM==myAnchor){ @@ -334,6 +341,7 @@ public final class FloatingDecorator extends JDialog { return d; } + @Override public final void paint(final Graphics g){ super.paint(g); final JBColor lightGray = new JBColor(Color.lightGray, Gray._95); @@ -363,6 +371,7 @@ public final class FloatingDecorator extends JDialog { } private final class MyWindowListener extends WindowAdapter{ + @Override public void windowClosing(final WindowEvent e){ myInternalDecorator.fireResized(); myInternalDecorator.fireHidden(); @@ -370,6 +379,7 @@ public final class FloatingDecorator extends JDialog { } private final class MyAnimator implements Runnable{ + @Override public final void run(){ final WindowManagerEx windowManager=WindowManagerEx.getInstanceEx(); if(isDisplayable()&&isShowing()){ @@ -378,25 +388,28 @@ public final class FloatingDecorator extends JDialog { if(myCurrentFrame#ref #loc may produce j dataflow.message.unboxing.method.reference=Use of #ref #loc would need unboxing which may produce java.lang.NullPointerException dataflow.too.complex=Method #ref is too complex to analyze by data flow algorithm dataflow.method.fails.with.null.argument=Method will throw an exception when parameter is null +dataflow.message.optional.get.without.is.present={0}.#ref() without ''isPresent()'' check +dataflow.message.optional.get.definitely.absent={0}.#ref() will definitely fail as {0} is empty here #deprecated inspection.deprecated.display.name=Deprecated API usage diff --git a/platform/platform-resources-en/src/messages/UIBundle.properties b/platform/platform-resources-en/src/messages/UIBundle.properties index 289bb44d29f0..a3af80fecb9e 100644 --- a/platform/platform-resources-en/src/messages/UIBundle.properties +++ b/platform/platform-resources-en/src/messages/UIBundle.properties @@ -58,7 +58,7 @@ tool.window.name.version.control=Version Control tool.window.name.module.dependencies=Module Dependencies tool.window.name.tasks=Time Tracking tool.window.name.database=Database -tool.window.name.runtime.dashboard=Run Dashboard +tool.window.name.run.dashboard=Run Dashboard tool.window.move.to.action.group.name=Move to tool.window.move.to.top.action.name=Top tool.window.move.to.left.action.name=Left diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties index eeef9e62167d..24f92ac5d9fa 100644 --- a/platform/platform-resources-en/src/messages/VcsBundle.properties +++ b/platform/platform-resources-en/src/messages/VcsBundle.properties @@ -543,6 +543,8 @@ dialog.enable.version.control.integration.select.vcs.label.text=Select a version dialog.enable.version.control.integration.hint.text=Version control settings can be configured in 'Settings | Version Control' confirmation.text.add.file=Do you want to schedule the following file for addition to VCS?\n{0} confirmation.title.add.file=Schedule for Addition +confirmation.title.add.file.to=Add file to {0}? +confirmation.title.add.files.to=Add files to {0}? confirmation.title.add.multiple.files=Select Files to Add to VCS waiting.changelists.update.for.show.commit.dialog.message=Commit dialog add.confirmation.label.text=When files are created with {0}: diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml index 9c6fb4b0c70c..c16fc9edb85e 100644 --- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -459,9 +459,9 @@ - - + - - @@ -872,6 +870,7 @@ + @@ -952,11 +951,11 @@ - - - - - + + + + + diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 062d26196d96..8257d58e9d98 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -1019,15 +1019,15 @@ - - - - + + + + - - - + + + - + diff --git a/platform/platform-tests/testData/editor/painting/multilineBorderWithInlays.png b/platform/platform-tests/testData/editor/painting/multilineBorderWithInlays.png new file mode 100644 index 000000000000..b2ed7a1dc571 Binary files /dev/null and b/platform/platform-tests/testData/editor/painting/multilineBorderWithInlays.png differ diff --git a/platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java b/platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java index 9cb34506861c..05a35732aed0 100644 --- a/platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/execution/impl/ConsoleViewImplTest.java @@ -22,26 +22,33 @@ import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.ide.DataManager; import com.intellij.ide.ui.UISettings; -import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ActionUtil; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorActionManager; import com.intellij.openapi.editor.actionSystem.TypedAction; import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.impl.DocumentMarkupModel; +import com.intellij.openapi.editor.markup.MarkupModel; +import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.TextRange; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.testFramework.LightPlatformCodeInsightTestCase; -import com.intellij.testFramework.LightPlatformTestCase; -import com.intellij.testFramework.PlatformTestUtil; -import com.intellij.testFramework.TestDataProvider; +import com.intellij.testFramework.*; import com.intellij.util.Alarm; import com.intellij.util.Consumer; import com.intellij.util.TimeoutUtil; import com.intellij.util.ui.UIUtil; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import java.io.ByteArrayOutputStream; +import java.util.Arrays; +import java.util.List; +import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -207,7 +214,7 @@ public class ConsoleViewImplTest extends LightPlatformTestCase { GlobalSearchScope.allScope(project), false, false); - console.getComponent(); + console.getComponent(); // initConsoleEditor() ProcessHandler processHandler = new NopProcessHandler(); processHandler.startNotify(); console.attachToProcess(processHandler); @@ -228,6 +235,21 @@ public class ConsoleViewImplTest extends LightPlatformTestCase { }).cpuBound().assertTiming()); } + public void testPerformanceOfMergeableTokens() throws Exception { + withCycleConsole(1000, console -> + PlatformTestUtil.startPerformanceTest("console print", 5500, () -> { + console.clear(); + for (int i=0; i<10_000_000; i++) { + console.print("xxx\n", ConsoleViewContentType.NORMAL_OUTPUT); + } + UIUtil.dispatchAllInvocationEvents(); + console.waitAllRequests(); + MarkupModel model = DocumentMarkupModel.forDocument(console.getEditor().getDocument(), getProject(), true); + RangeHighlighter highlighter = assertOneElement(model.getAllHighlighters()); + assertEquals(new TextRange(0, console.getEditor().getDocument().getTextLength()), TextRange.create(highlighter)); + }).cpuBound().assertTiming()); + } + private static void withCycleConsole(int capacityKB, Consumer runnable) { boolean oldUse = UISettings.getInstance().OVERRIDE_CONSOLE_CYCLE_BUFFER_SIZE; int oldSize = UISettings.getInstance().CONSOLE_CYCLE_BUFFER_SIZE_KB; @@ -318,4 +340,38 @@ public class ConsoleViewImplTest extends LightPlatformTestCase { action.actionPerformed(editor, c, dataContext); } + + public void testBackspaceDoesDeleteTheLastTypedChar() throws Exception { + final ConsoleViewImpl console = myConsole; + final Editor editor = console.getEditor(); + console.print("xxxx", ConsoleViewContentType.NORMAL_OUTPUT); + console.print("a", ConsoleViewContentType.USER_INPUT); + console.print("b", ConsoleViewContentType.USER_INPUT); + console.print("c", ConsoleViewContentType.USER_INPUT); + console.print("d", ConsoleViewContentType.USER_INPUT); + console.flushDeferredText(); + assertEquals("xxxxabcd", editor.getDocument().getText()); + + backspace(console); + assertEquals("xxxxabc", editor.getDocument().getText()); + backspace(console); + assertEquals("xxxxab", editor.getDocument().getText()); + backspace(console); + assertEquals("xxxxa", editor.getDocument().getText()); + backspace(console); + assertEquals("xxxx", editor.getDocument().getText()); + } + + private static void backspace(ConsoleViewImpl consoleView) { + Editor editor = consoleView.getEditor(); + Set backShortcuts = new THashSet<>(Arrays.asList(ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_BACKSPACE).getShortcutSet().getShortcuts())); + List actions = ActionUtil.getActions(consoleView.getEditor().getContentComponent()); + AnAction handler = actions.stream() + .filter(a -> new THashSet<>(Arrays.asList(a.getShortcutSet().getShortcuts())).equals(backShortcuts)) + .findFirst() + .get(); + CommandProcessor.getInstance().executeCommand(getProject(), + () -> EditorTestUtil.executeAction(editor, true, handler), + "", null, editor.getDocument()); + } } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/ApplicationImplTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/ApplicationImplTest.java index c69992f75048..704ca0b40c4c 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/ApplicationImplTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/application/impl/ApplicationImplTest.java @@ -693,8 +693,8 @@ public class ApplicationImplTest extends LightPlatformTestCase { ); while (!readAcquired.get()); Future readAction2 = app.executeOnPooledThread(() -> { - // wait for write action attempt to start - while (!app.isWriteActionPending()); + // wait for write action attempt to start - i.e. app.myLock.writeLock() started to execute + while (!app.myLock.writeRequested); app.executeByImpatientReader(() -> { try { app.runReadAction(EmptyRunnable.getInstance()); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java index 8547ed233c30..02df76b1f93b 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/EditorPaintingTest.java @@ -116,6 +116,14 @@ public class EditorPaintingTest extends AbstractEditorTest { checkResult(); } + public void testMultilineBorderWithInlays() throws Exception { + initText("abc\ndef"); + myEditor.getInlayModel().addInlineElement(1, new MyInlayRenderer()); + myEditor.getInlayModel().addInlineElement(6, new MyInlayRenderer()); + addBorderHighlighter(0, 7, 0, Color.red); + checkResult(); + } + private static void setUniformEditorHighlighter(TextAttributes attributes) { ((EditorEx)myEditor).setHighlighter(new UniformHighlighter(attributes)); } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java index 66aa5d25bfae..ade0f0dfebd5 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/impl/VirtualFilePointerTest.java @@ -894,7 +894,7 @@ public class VirtualFilePointerTest extends PlatformTestCase { } }; - int N = Math.max(100, Timings.adjustAccordingToMySpeed(20_000, false)); + int N = Math.max(100, Timings.adjustAccordingToMySpeed(10_000, false)); System.out.println("N = " + N); for (int i=0; i getCached = { arg -> CachedValuesManager.getManager(project).getCachedValue(holder, { + log << "capturing " + arg + return CachedValueProvider.Result.create('result', dependency) + }) } + + assert 'result' == getCached.apply('foo') + + dependency.incModificationCount() + assert 'result' == getCached.apply('bar') + assert log == ['capturing foo', 'capturing bar'] + } + + void "test calculate value at most once per thread"() { + AtomicInteger calcCount = new AtomicInteger() + SimpleModificationTracker dependency = new SimpleModificationTracker() + Closure getCached = { CachedValuesManager.getManager(project).getCachedValue(holder, { + calcCount.incrementAndGet() + TimeoutUtil.sleep(10) + return CachedValueProvider.Result.create('result', dependency) + }) } + assert 'result' == getCached() + assert calcCount.getAndSet(0) == 1 + + dependency.incModificationCount() + + List jobs = (0..<10).collect { ApplicationManager.application.executeOnPooledThread { + for (i in 0..10) { + assert 'result' == getCached() + } + } } + jobs.forEach { it.get() } + + assert calcCount.get() <= jobs.size() + + } +} diff --git a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java index 97a98a704400..88c049ba09ae 100644 --- a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java +++ b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageNodeTreeBuilderTest.java @@ -23,15 +23,26 @@ import com.intellij.openapi.extensions.ExtensionsArea; import com.intellij.openapi.fileEditor.FileEditorLocation; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vcs.FileStatus; +import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.testFramework.LightPlatformTestCase; +import com.intellij.testFramework.VfsTestUtil; +import com.intellij.usageView.UsageInfo; import com.intellij.usages.*; +import com.intellij.usages.impl.rules.FileGroupingRule; import com.intellij.usages.rules.UsageGroupingRule; import com.intellij.usages.rules.UsageGroupingRuleProvider; +import com.intellij.util.ArrayUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import java.io.File; +import java.io.IOException; /** * @author max @@ -350,4 +361,27 @@ public class UsageNodeTreeBuilderTest extends LightPlatformTestCase { return false; } } + + public void testFilesWithTheSameNameButDifferentPathsEndUpInDifferentGroups() throws IOException { + File ioDir = FileUtil.createTempDirectory("t", null, false); + VirtualFile dir = null; + try { + dir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(ioDir); + PsiFile f1 = getPsiManager().findFile(VfsTestUtil.createFile(dir, "/x/X.java", "class X{}")); + PsiFile f2 = getPsiManager().findFile(VfsTestUtil.createFile(dir, "/y/X.java", "class X{}")); + PsiElement class1 = ArrayUtil.getLastElement(f1.getChildren()); + PsiElement class2 = ArrayUtil.getLastElement(f2.getChildren()); + FileGroupingRule fileGroupingRule = new FileGroupingRule(getProject()); + UsageGroup group1 = fileGroupingRule.groupUsage(new UsageInfo2UsageAdapter(new UsageInfo(class1))); + UsageGroup group2 = fileGroupingRule.groupUsage(new UsageInfo2UsageAdapter(new UsageInfo(class2))); + int compareTo = group1.compareTo(group2); + assertTrue(String.valueOf(compareTo), compareTo < 0); + } + finally { + if (dir != null) { + VfsTestUtil.deleteFile(dir); + } + FileUtil.delete(ioDir); + } + } } diff --git a/platform/projectModel-api/src/com/intellij/openapi/components/StoredProperty.kt b/platform/projectModel-api/src/com/intellij/openapi/components/StoredProperty.kt index 10393461ff59..dbf9f7437faa 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/components/StoredProperty.kt +++ b/platform/projectModel-api/src/com/intellij/openapi/components/StoredProperty.kt @@ -24,7 +24,7 @@ import kotlin.reflect.KProperty abstract class BaseState : SerializationFilter, ModificationTracker { // if property value differs from default - private val properties: MutableList> = SmartList() + private val properties: MutableList = SmartList() @Volatile internal var modificationCount: Long = 0 @@ -47,19 +47,25 @@ abstract class BaseState : SerializationFilter, ModificationTracker { } fun storedProperty(defaultValue: T? = null): ReadWriteProperty { - val result = StoredProperty(defaultValue) + val result = ObjectStoredProperty(defaultValue) properties.add(result) return result } fun storedProperty(defaultValue: Int = 0): ReadWriteProperty { - val result = StoredProperty(defaultValue) + val result = IntStoredProperty(defaultValue) + properties.add(result) + return result + } + + fun storedProperty(defaultValue: Float = 0f): ReadWriteProperty { + val result = FloatStoredProperty(defaultValue) properties.add(result) return result } fun storedProperty(defaultValue: Boolean = false): ReadWriteProperty { - val result = StoredProperty(defaultValue) + val result = ObjectStoredProperty(defaultValue) properties.add(result) return result } @@ -93,9 +99,16 @@ abstract class BaseState : SerializationFilter, ModificationTracker { } } -internal class StoredProperty(internal val defaultValue: T) : ReadWriteProperty { - internal var value = defaultValue - internal var name: String? = null +internal interface StoredProperty { + val defaultValue: Any? + val value: Any? + + val name: String? +} + +private class ObjectStoredProperty(override val defaultValue: T) : ReadWriteProperty, StoredProperty { + override var value = defaultValue + override var name: String? = null override operator fun getValue(thisRef: BaseState, property: KProperty<*>) = value @@ -109,9 +122,55 @@ internal class StoredProperty(internal val defaultValue: T) : ReadWriteProper } } - override fun equals(other: Any?) = this === other || (other is StoredProperty<*> && value == other.value) + override fun equals(other: Any?) = this === other || (other is ObjectStoredProperty<*> && value == other.value) override fun hashCode() = value?.hashCode() ?: 0 override fun toString() = if (value === defaultValue) "" else value?.toString() ?: super.toString() +} + +private class IntStoredProperty(override val defaultValue: Int) : ReadWriteProperty, StoredProperty { + override var value = defaultValue + override var name: String? = null + + override operator fun getValue(thisRef: BaseState, property: KProperty<*>) = value + + @Suppress("UNCHECKED_CAST") + override fun setValue(thisRef: BaseState, property: KProperty<*>, @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") newValue: Int) { + if (value != newValue) { + thisRef.modificationCount++ + + name = property.name + value = newValue + } + } + + override fun equals(other: Any?) = this === other || (other is IntStoredProperty && value == other.value) + + override fun hashCode() = value.hashCode() + + override fun toString() = if (value == defaultValue) "" else value.toString() +} + +private class FloatStoredProperty(override val defaultValue: Float) : ReadWriteProperty, StoredProperty { + override var value = defaultValue + override var name: String? = null + + override operator fun getValue(thisRef: BaseState, property: KProperty<*>) = value + + @Suppress("UNCHECKED_CAST") + override fun setValue(thisRef: BaseState, property: KProperty<*>, @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") newValue: Float) { + if (value != newValue) { + thisRef.modificationCount++ + + name = property.name + value = newValue + } + } + + override fun equals(other: Any?) = this === other || (other is FloatStoredProperty && value == other.value) + + override fun hashCode() = value.hashCode() + + override fun toString() = if (value == defaultValue) "" else value.toString() } \ No newline at end of file diff --git a/platform/projectModel-impl/src/com/intellij/configurationStore/xmlSerializer.kt b/platform/projectModel-impl/src/com/intellij/configurationStore/xmlSerializer.kt index 3be433b770a4..6171908b7f57 100644 --- a/platform/projectModel-impl/src/com/intellij/configurationStore/xmlSerializer.kt +++ b/platform/projectModel-impl/src/com/intellij/configurationStore/xmlSerializer.kt @@ -16,6 +16,9 @@ @file:JvmName("XmlSerializer") package com.intellij.configurationStore +import com.intellij.openapi.components.BaseState +import com.intellij.openapi.components.ComponentSerializationUtil +import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.util.JDOMUtil import com.intellij.reference.SoftReference import com.intellij.util.xmlb.* @@ -32,10 +35,25 @@ import kotlin.concurrent.read import kotlin.concurrent.write import kotlin.reflect.primaryConstructor -fun T.serialize(filter: SerializationFilter? = SkipDefaultValuesSerializationFilters()): Element = XmlSerializer.serialize(this, filter) - -fun serialize(`object`: Any): Element { - return XmlSerializer.serialize(`object`) +@JvmOverloads +fun T.serialize(filter: SerializationFilter? = SkipDefaultsSerializationFilter()): Element { + try { + val clazz = javaClass + val binding = getBinding(clazz) + if (binding is BeanBinding) { + // top level expects not null (null indicates error, empty element will be omitted) + return binding.serialize(this, true, filter) + } + else { + return binding.serialize(this, null, filter) as Element + } + } + catch (e: XmlSerializationException) { + throw e + } + catch (e: Exception) { + throw XmlSerializationException("Can't serialize instance of ${this.javaClass}", e) + } } inline fun Element.deserialize(): T = deserialize(T::class.java) @@ -79,6 +97,26 @@ fun Element.deserializeInto(bean: Any) { } } +fun PersistentStateComponent<*>.deserializeAndLoadState(element: Element) { + val state = element.deserialize(ComponentSerializationUtil.getStateClass(javaClass)) + (state as? BaseState)?.resetModificationCount() + @Suppress("UNCHECKED_CAST") + (this as PersistentStateComponent).loadState(state) +} + +fun T.serializeInto(element: Element) { + try { + val binding = getBinding(javaClass) + (binding as BeanBinding).serializeInto(this, element, null) + } + catch (e: XmlSerializationException) { + throw e + } + catch (e: Exception) { + throw XmlSerializationException(e) + } +} + private var _bindingCache: SoftReference>? = null private val bindingCache: MutableMap @@ -125,8 +163,7 @@ private class KotlinAwareBeanBinding(beanClass: Class<*>, accessor: MutableAcces override fun getBinding(accessor: MutableAccessor): Binding? { val type = accessor.genericType - val aClass = typeToClass(type) - return if (isPrimitive(aClass)) null else getBinding(aClass, type, accessor) + return getClassBinding(typeToClass(type), type, accessor) } private fun newInstance(): Any { @@ -142,13 +179,18 @@ private class KotlinAwareBeanBinding(beanClass: Class<*>, accessor: MutableAcces return constructor.newInstance() } catch (e: RuntimeException) { - // if cannot create data class - val kClass = clazz.kotlin - (kClass.primaryConstructor ?: kClass.constructors.firstOrNull())?.let { - return it.callBy(emptyMap()) - } - - throw e + return createUsingKotlin(clazz) ?: throw e + } + catch (e: NoSuchMethodException) { + return createUsingKotlin(clazz) ?: throw e } } -} \ No newline at end of file + + private fun createUsingKotlin(clazz: Class<*>): Any? { + // if cannot create data class + val kClass = clazz.kotlin + return (kClass.primaryConstructor ?: kClass.constructors.firstOrNull())?.callBy(emptyMap()) + } +} + +private fun getClassBinding(clazz: Class<*>, type: Type = clazz, accessor: MutableAccessor? = null) = if (isPrimitive(clazz)) null else getBinding(clazz, type, accessor) \ No newline at end of file diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java index 5072f414d2a2..569cfda2ad94 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ModuleRootManagerImpl.java @@ -34,6 +34,7 @@ import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; +import com.intellij.util.ExceptionUtil; import com.intellij.util.ThrowableRunnable; import gnu.trove.THashMap; import org.jdom.Element; @@ -113,14 +114,17 @@ public class ModuleRootManagerImpl extends ModuleRootManager implements Disposab @Override public void dispose() { super.dispose(); + Throwable created = null; if (Disposer.isDebugMode()) { synchronized (myModelCreations) { - myModelCreations.remove(this); + created = myModelCreations.remove(this); } } for (OrderEntry entry : ModuleRootManagerImpl.this.getOrderEntries()) { - assert !((RootModelComponentBase)entry).isDisposed() : String.format("%s is not disposed!", entry.getPresentableName()); + assert !((RootModelComponentBase)entry).isDisposed() : + entry + "(" + entry.getClass() + ") in " + myRootModel + " is already disposed." + + (created == null ? "" : "\nThis modifiable model was created at:\n" + ExceptionUtil.getThrowableText(created)); } } }; diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java index b67d9d1ad7c1..b508779cc23f 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootIndex.java @@ -86,6 +86,10 @@ public class RootIndex { }; } + public void onLowMemory() { + myPackageDirectoryCache.onLowMemory(); + } + @NotNull private RootInfo buildRootInfo(@NotNull Project project) { final RootInfo info = new RootInfo(); diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java index 355524868b3f..349767455f57 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/RootModelImpl.java @@ -16,7 +16,7 @@ package com.intellij.openapi.roots.impl; import com.intellij.configurationStore.Scheme_implKt; -import com.intellij.configurationStore.SerializationUtilKt; +import com.intellij.configurationStore.XmlSerializer; import com.intellij.openapi.CompositeDisposable; import com.intellij.openapi.Disposable; import com.intellij.openapi.components.PersistentStateComponent; @@ -38,7 +38,6 @@ import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager; import com.intellij.util.ArrayUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.xmlb.XmlSerializer; import gnu.trove.THashMap; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -134,7 +133,7 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel ModuleExtension model = extension.getModifiableModel(false); if (model instanceof PersistentStateComponent) { - SerializationUtilKt.deserializeAndLoadState((PersistentStateComponent)model, element); + XmlSerializer.deserializeAndLoadState((PersistentStateComponent)model, element); } else { //noinspection deprecation @@ -452,6 +451,7 @@ public class RootModelImpl extends RootModelBase implements ModifiableRootModel public void writeExternal(@NotNull Element element) { for (ModuleExtension extension : myExtensions) { if (extension instanceof PersistentStateComponent) { + //noinspection ConstantConditions XmlSerializer.serializeInto(((PersistentStateComponent)extension).getState(), element); } else { diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java index 19dbc5a82e2f..997289f46637 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/GeneralIdBasedToSMTRunnerEventsConvertor.java @@ -135,6 +135,7 @@ public class GeneralIdBasedToSMTRunnerEventsConvertor extends GeneralTestEventsP String nodeName = startedNodeEvent.getName(); SMTestProxy childProxy = new SMTestProxy(nodeName, suite, startedNodeEvent.getLocationUrl(), true); + childProxy.setTreeBuildBeforeStart(); TestProxyPrinterProvider printerProvider = myTestProxyPrinterProvider; String nodeType = startedNodeEvent.getNodeType(); if (printerProvider != null && nodeType != null && nodeName != null) { diff --git a/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java index cc46819bc025..01c6504693ec 100644 --- a/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/EditorTestUtil.java @@ -98,12 +98,17 @@ public class EditorTestUtil { ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); AnAction action = actionManager.getAction(actionId); assertNotNull(action); + executeAction(editor, assertActionIsEnabled, action); + } + + public static void executeAction(@NotNull Editor editor, boolean assertActionIsEnabled, @NotNull AnAction action) { AnActionEvent event = AnActionEvent.createFromAnAction(action, null, "", createEditorContext(editor)); action.beforeActionPerformedUpdate(event); if (!event.getPresentation().isEnabled()) { - assertFalse("Action " + actionId + " is disabled", assertActionIsEnabled); + assertFalse("Action " + action + " is disabled", assertActionIsEnabled); return; } + ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); actionManager.fireBeforeActionPerformed(action, event.getDataContext(), event); action.actionPerformed(event); actionManager.fireAfterActionPerformed(action, event.getDataContext(), event); diff --git a/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java b/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java index 604095ce672b..6edbba415677 100644 --- a/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java +++ b/platform/testFramework/src/com/intellij/testFramework/LightProjectDescriptor.java @@ -90,20 +90,29 @@ public class LightProjectDescriptor { VirtualFile dummyRoot = VirtualFileManager.getInstance().findFileByUrl("temp:///"); assert dummyRoot != null; dummyRoot.refresh(false, false); + VirtualFile srcRoot = doCreateSourceRoot(dummyRoot, srcPath); + registerSourceRoot(module.getProject(), srcRoot); + return srcRoot; + } + protected VirtualFile doCreateSourceRoot(VirtualFile root, String srcPath) { VirtualFile srcRoot; try { - srcRoot = dummyRoot.createChildDirectory(this, srcPath); + srcRoot = root.createChildDirectory(this, srcPath); cleanSourceRoot(srcRoot); } catch (IOException e) { throw new RuntimeException(e); } + return srcRoot; + } + + protected void registerSourceRoot(Project project, VirtualFile srcRoot) { IndexableFileSet indexableFileSet = new IndexableFileSet() { @Override public boolean isInSet(@NotNull VirtualFile file) { - return file.getFileSystem() == srcRoot.getFileSystem() && module.getProject().isOpen(); + return file.getFileSystem() == srcRoot.getFileSystem() && project.isOpen(); } @Override @@ -118,9 +127,7 @@ public class LightProjectDescriptor { } }; FileBasedIndex.getInstance().registerIndexableSet(indexableFileSet, null); - Disposer.register(module.getProject(), () -> FileBasedIndex.getInstance().removeIndexableSet(indexableFileSet)); - - return srcRoot; + Disposer.register(project, () -> FileBasedIndex.getInstance().removeIndexableSet(indexableFileSet)); } protected void createContentEntry(@NotNull Module module, @NotNull VirtualFile srcRoot) { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestUtil.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestUtil.java index d8ada560c849..c279454a1f09 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/CodeInsightTestUtil.java @@ -53,6 +53,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler; import com.intellij.testFramework.TestDataFile; +import com.intellij.ui.CollectionListModel; import com.intellij.ui.components.JBList; import com.intellij.ui.popup.AbstractPopup; import com.intellij.ui.popup.ComponentPopupBuilderImpl; @@ -66,6 +67,7 @@ import org.jetbrains.annotations.TestOnly; import org.junit.Assert; import java.io.File; +import java.util.ArrayList; import java.util.List; import static junit.framework.Assert.assertTrue; @@ -261,6 +263,8 @@ public class CodeInsightTestUtil { GotoTargetHandler.GotoData data = new GotoImplementationHandler().getSourceAndTargetElements(editor, file); if (data.listUpdaterTask != null) { JBList list = new JBList(); + CollectionListModel model = new CollectionListModel(new ArrayList()); + list.setModel(model); list.setModel(new NameFilteringListModel(list, Function.ID, Condition.FALSE, String::new)); JBPopup popup = new ComponentPopupBuilderImpl(list, null).createPopup(); data.listUpdaterTask.init((AbstractPopup)popup, list, new Ref<>()); diff --git a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java index c2f7fcd11401..d25b88929233 100644 --- a/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java +++ b/platform/usageView/src/com/intellij/usages/impl/SearchForUsagesRunnable.java @@ -53,6 +53,7 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; import com.intellij.util.Processors; import com.intellij.util.ui.RangeBlinker; +import com.intellij.util.ui.UIUtil; import com.intellij.xml.util.XmlStringUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -278,7 +279,9 @@ class SearchForUsagesRunnable implements Runnable { } } else { - Disposer.dispose(usageView); + UsageViewImpl finalUsageView = usageView; + // later because dispose does some sort of swing magic e.g. AnAction.unregisterCustomShortcutSet() + UIUtil.invokeLaterIfNeeded(() -> Disposer.dispose(finalUsageView)); } return myUsageViewRef.get(); } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index 1f34fa93ade0..bd6c0dc3d2e3 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -701,10 +701,6 @@ public class UsageViewImpl implements UsageView { } } - private void scheduleDisposeOnClose(@NotNull Disposable disposable) { - Disposer.register(this, disposable); - } - @NotNull protected AnAction[] createActions() { final TreeExpander treeExpander = new TreeExpander() { @@ -738,7 +734,7 @@ public class UsageViewImpl implements UsageView { final AnAction expandAllAction = actionsManager.createExpandAllAction(treeExpander, component); final AnAction collapseAllAction = actionsManager.createCollapseAllAction(treeExpander, component); - scheduleDisposeOnClose(() -> { + Disposer.register(this, () -> { expandAllAction.unregisterCustomShortcutSet(component); collapseAllAction.unregisterCustomShortcutSet(component); }); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 717fb4050d16..a2d0d498fbd7 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -595,9 +595,6 @@ ide.open.file.in.temp.project.dir.description=Enables opening file in temp proje embed.scene.builder=true embed.scene.builder.description=Show SceneBuilder embedded into IntelliJ IDEA frame -dsm.retina.darcula.legend=true -dsm.retina.darcula.legend.description=Experimental DSM legend component - new.retina.detection=false new.retina.detection.description=New implementation to detect retina devices @@ -918,10 +915,10 @@ dumb.aware.run.configurations.description=Enable executing run configurations in select.run.configuration.from.context=true select.run.configuration.from.context.description=Select run configuration when run from context (gutter icon, popup menu) -ide.runtime.dashboard=false -ide.runtime.dashboard.description=Enable Runtime Dashboard tool window -ide.runtime.dashboard.spring.boot.jmx=true -ide.runtime.dashboard.spring.boot.jmx.description=Enable JMX Remote with disabled security for Spring Boot applications to access runtime information +ide.run.dashboard=false +ide.run.dashboard.description=Enable Run Dashboard tool window +ide.run.dashboard.spring.boot.jmx=true +ide.run.dashboard.spring.boot.jmx.description=Enable JMX Remote with disabled security for Spring Boot applications to access runtime information focus.follows.mouse.workarounds=false focus.follows.mouse.workarounds.description=Enables some workarounds for Focus-follows-mouse issues, like IDEA-112015 diff --git a/platform/util/src/com/intellij/openapi/util/IconLoader.java b/platform/util/src/com/intellij/openapi/util/IconLoader.java index c29b57bd42eb..c244ec51a253 100644 --- a/platform/util/src/com/intellij/openapi/util/IconLoader.java +++ b/platform/util/src/com/intellij/openapi/util/IconLoader.java @@ -516,15 +516,11 @@ public final class IconLoader { } }); - private Image getOrLoadOrigImage(float pixScale) { - return getOrLoadOrigImage(pixScale, true); - } - /** * Retrieves the orig image based on the pixScale. */ private Image getOrLoadOrigImage(float pixScale, boolean allowFloatScaling) { - boolean needRetinaImage = ImageUtil.needRetinaImage(pixScale); + boolean needRetinaImage = JBUI.isHiDPI(pixScale); Image image = SoftReference.dereference(origImagesCache.get(needRetinaImage)); if (image != null) return image; @@ -621,7 +617,7 @@ public final class IconLoader { Icon icon = getOrComputeIcon(); if (icon != null) { if (icon instanceof CachedImageIcon) { - Image img = ((CachedImageIcon)icon).myScaledIconsCache.getOrLoadOrigImage(1f); + Image img = ((CachedImageIcon)icon).myScaledIconsCache.getOrLoadOrigImage(1f, false); if (img != null) { icon = new ImageIcon(img); } diff --git a/platform/util/src/com/intellij/openapi/util/io/BufferExposingByteArrayInputStream.java b/platform/util/src/com/intellij/openapi/util/io/BufferExposingByteArrayInputStream.java index 01180aaf5f71..f87a5d518137 100644 --- a/platform/util/src/com/intellij/openapi/util/io/BufferExposingByteArrayInputStream.java +++ b/platform/util/src/com/intellij/openapi/util/io/BufferExposingByteArrayInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,16 +19,12 @@ import com.intellij.util.io.UnsyncByteArrayInputStream; import org.jetbrains.annotations.NotNull; public class BufferExposingByteArrayInputStream extends UnsyncByteArrayInputStream { - public BufferExposingByteArrayInputStream(@NotNull byte[] bytes) { - super(bytes); - } - - public BufferExposingByteArrayInputStream(@NotNull byte[] buf, int length) { - super(buf, 0, length); + public BufferExposingByteArrayInputStream(@NotNull byte[] buf) { + super(buf); } @NotNull public byte[] getInternalBuffer() { return myBuffer; } -} +} \ No newline at end of file diff --git a/platform/util/src/com/intellij/openapi/vfs/CharsetToolkit.java b/platform/util/src/com/intellij/openapi/vfs/CharsetToolkit.java index 5758639f61dc..07d4f55b6784 100644 --- a/platform/util/src/com/intellij/openapi/vfs/CharsetToolkit.java +++ b/platform/util/src/com/intellij/openapi/vfs/CharsetToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -128,7 +128,10 @@ public class CharsetToolkit { @NotNull public static InputStream inputStreamSkippingBOM(@NotNull InputStream stream) throws IOException { - assert stream.markSupported() :stream; + if (!stream.markSupported()) { + return stream; + } + stream.mark(4); boolean mustReset = true; try { diff --git a/platform/util/src/com/intellij/util/ImageLoader.java b/platform/util/src/com/intellij/util/ImageLoader.java index 83cf0db0a1dd..ac7c6ba3cfad 100644 --- a/platform/util/src/com/intellij/util/ImageLoader.java +++ b/platform/util/src/com/intellij/util/ImageLoader.java @@ -292,9 +292,9 @@ public class ImageLoader implements Serializable { final boolean scaleImages = (scaleFactor > 1.0f && !UIUtil.isJDKManagedHiDPI()); - // For any scale factor > 1.0, always prefer retina images, because downscaling + // Prefer retina images for HiDPI scale, because downscaling // retina images provides a better result than upscaling non-retina images. - final boolean loadRetinaImages = (scaleFactor > 1.0f); + final boolean loadRetinaImages = JBUI.isHiDPI(scaleFactor); return ImageDescList.create(url.toString(), null, UIUtil.isUnderDarcula(), loadRetinaImages, allowFloatScaling, pixScale).load( ImageConverterChain.create(). @@ -314,7 +314,7 @@ public class ImageLoader implements Serializable { } private static float adjustScaleFactor(boolean allowFloatScaling, float scale) { - return allowFloatScaling ? scale : ImageUtil.needRetinaImage(scale) ? 2f : 1f; + return allowFloatScaling ? scale : JBUI.isHiDPI(scale) ? 2f : 1f; } @NotNull @@ -362,7 +362,7 @@ public class ImageLoader implements Serializable { @Nullable public static Image loadFromResource(@NonNls @NotNull String path, @NotNull Class aClass) { - return ImageDescList.create(path, aClass, UIUtil.isUnderDarcula(), ImageUtil.needRetinaImage(JBUI.pixScale()), true). + return ImageDescList.create(path, aClass, UIUtil.isUnderDarcula(), JBUI.isHiDPI(JBUI.pixScale()), true). load(ImageConverterChain.create().withRetina()); } diff --git a/platform/util/src/com/intellij/util/Producer.java b/platform/util/src/com/intellij/util/Producer.java index 8cce497ad24e..5f61acebd507 100644 --- a/platform/util/src/com/intellij/util/Producer.java +++ b/platform/util/src/com/intellij/util/Producer.java @@ -15,14 +15,11 @@ */ package com.intellij.util; -import org.jetbrains.annotations.Nullable; - /** * @author pegov */ public interface Producer { - @Nullable T produce(); } diff --git a/platform/util/src/com/intellij/util/concurrency/SchedulingWrapper.java b/platform/util/src/com/intellij/util/concurrency/SchedulingWrapper.java index 1ffe657220a5..caa00b377200 100644 --- a/platform/util/src/com/intellij/util/concurrency/SchedulingWrapper.java +++ b/platform/util/src/com/intellij/util/concurrency/SchedulingWrapper.java @@ -314,9 +314,9 @@ class SchedulingWrapper implements ScheduledExecutorService { throw new RejectedExecutionException("Already shutdown"); } delayQueue.add(t); - if (t.getDelay(TimeUnit.HOURS) > 24 && !t.isPeriodic()) { + if (t.getDelay(TimeUnit.DAYS) > 31 && !t.isPeriodic()) { // guard against inadvertent queue overflow - throw new IllegalArgumentException("Unsupported crazy delay " + t.getDelay(TimeUnit.MINUTES) + " minutes: " + BoundedTaskExecutor.info(t)); + throw new IllegalArgumentException("Unsupported crazy delay " + t.getDelay(TimeUnit.DAYS) + " days: " + BoundedTaskExecutor.info(t)); } return t; } diff --git a/platform/util/src/com/intellij/util/containers/Queue.java b/platform/util/src/com/intellij/util/containers/Queue.java index 44dc1eb2e53d..d9f2a64c401a 100644 --- a/platform/util/src/com/intellij/util/containers/Queue.java +++ b/platform/util/src/com/intellij/util/containers/Queue.java @@ -38,7 +38,7 @@ public class Queue { public void addLast(T object) { int currentSize = size(); if (currentSize == myArray.length) { - myArray = normalize(Math.max(currentSize * 2, 5)); + myArray = normalize(Math.max(currentSize * 3/2, 10)); myFirst = 0; myLast = currentSize; isWrapped = false; diff --git a/platform/util/src/com/intellij/util/containers/RecentStringInterner.java b/platform/util/src/com/intellij/util/containers/RecentStringInterner.java index 2d71a21ded3c..7f0c8f8cb3f8 100644 --- a/platform/util/src/com/intellij/util/containers/RecentStringInterner.java +++ b/platform/util/src/com/intellij/util/containers/RecentStringInterner.java @@ -15,6 +15,7 @@ */ package com.intellij.util.containers; +import com.intellij.openapi.Disposable; import com.intellij.openapi.util.LowMemoryWatcher; import org.jetbrains.annotations.NotNull; @@ -30,19 +31,13 @@ public class RecentStringInterner { private final int myStripeMask; private final SLRUCache[] myInterns; private final Lock[] myStripeLocks; - // LowMemoryWatcher relies on field holding it - @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) - private final LowMemoryWatcher myLowMemoryWatcher; - public RecentStringInterner() { - this(8192); - } - - public RecentStringInterner(int capacity) { + public RecentStringInterner(@NotNull Disposable parentDisposable) { final int stripes = 16; //noinspection unchecked myInterns = new SLRUCache[stripes]; myStripeLocks = new Lock[myInterns.length]; + int capacity = 8192; for(int i = 0; i < myInterns.length; ++i) { myInterns[i] = new SLRUCache(capacity / stripes, capacity / stripes) { @NotNull @@ -61,12 +56,12 @@ public class RecentStringInterner { assert Integer.highestOneBit(stripes) == stripes; myStripeMask = stripes - 1; - myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() { + LowMemoryWatcher.register(new Runnable() { @Override public void run() { clear(); } - }); + }, parentDisposable); } public String get(String s) { diff --git a/platform/util/src/com/intellij/util/io/CompressedAppendableFile.java b/platform/util/src/com/intellij/util/io/CompressedAppendableFile.java index 2698a6eae843..7bf6835e6742 100644 --- a/platform/util/src/com/intellij/util/io/CompressedAppendableFile.java +++ b/platform/util/src/com/intellij/util/io/CompressedAppendableFile.java @@ -15,6 +15,8 @@ */ package com.intellij.util.io; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.LowMemoryWatcher; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.util.ArrayUtil; @@ -46,17 +48,17 @@ public class CompressedAppendableFile { private static final int FACTOR = 32; private long [] myChunkOffsetTable; // one long offset per FACTOR compressed chunks private static final boolean doDebug = SystemProperties.getBooleanProperty("idea.compressed.file.self.check", false); - private TLongArrayList myCompressedChunksFileOffsets = doDebug ? new TLongArrayList() : null; + private final TLongArrayList myCompressedChunksFileOffsets = doDebug ? new TLongArrayList() : null; private static final int MAX_PAGE_LENGTH = 0xFFFF; private long myFileLength; private long myUncompressedFileLength = -1; - protected final int myAppendBufferLength; + private final int myAppendBufferLength; private static final int myMinAppendBufferLength = 1024; - public static final String INCOMPLETE_CHUNK_LENGTH_FILE_EXTENSION = ".s"; - private final LowMemoryWatcher myLowMemoryWatcher; + static final String INCOMPLETE_CHUNK_LENGTH_FILE_EXTENSION = ".s"; + private final Disposable myDisposable = Disposer.newDisposable(); public CompressedAppendableFile(File file) { this(file, PersistentBTreeEnumerator.PAGE_SIZE); @@ -66,13 +68,17 @@ public class CompressedAppendableFile { myBaseFile = file; myAppendBufferLength = bufferSize; assert bufferSize <= MAX_PAGE_LENGTH; // length of compressed buffer size should be in short range - myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() { + file.getParentFile().mkdirs(); + LowMemoryWatcher.register(new Runnable() { @Override public void run() { + synchronized (ourDecompressedCache) { + ourDecompressedCache.clear(); + } + dropCaches(); } - }); - file.getParentFile().mkdirs(); + }, myDisposable); } public synchronized Data read(final long addr, KeyDescriptor descriptor) throws IOException { @@ -105,7 +111,7 @@ public class CompressedAppendableFile { final DataInputStream chunkLengthStream = new DataInputStream(new BufferedInputStream( new LimitedInputStream(new FileInputStream(chunkLengthFile), (int)chunkLengthFile.length()) { @Override - public int available() throws IOException { + public int available() { return remainingLimit(); } }, 32768)); @@ -132,7 +138,7 @@ public class CompressedAppendableFile { for(int i = 0; i < chunkOffsetTable.length; ++i) { int start = i * FACTOR; for(int j = 0; j < FACTOR; ++j) { - offset += (chunkLengthTable[start + j] & MAX_PAGE_LENGTH); + offset += chunkLengthTable[start + j] & MAX_PAGE_LENGTH; } chunkOffsetTable[i] = offset; } @@ -222,11 +228,11 @@ public class CompressedAppendableFile { } private long calcOffsetOfPage(int pageNumber) { - final int calculatedOffset = ((pageNumber + 1) / FACTOR); + final int calculatedOffset = (pageNumber + 1) / FACTOR; long offset = calculatedOffset > 0 ? myChunkOffsetTable[calculatedOffset - 1]:0; final int baseOffset = calculatedOffset * FACTOR; for(int index = 0, len = (pageNumber + 1) % FACTOR; index < len; ++index) { - offset += (myChunkLengthTable[baseOffset + index] & MAX_PAGE_LENGTH); + offset += myChunkLengthTable[baseOffset + index] & MAX_PAGE_LENGTH; } if (doDebug) { assert myCompressedChunksFileOffsets.get(pageNumber) == offset; @@ -242,7 +248,7 @@ public class CompressedAppendableFile { } return new BufferedInputStream(new LimitedInputStream(in, pageSize) { @Override - public int available() throws IOException { + public int available() { return remainingLimit(); } }, 32768); @@ -440,7 +446,7 @@ public class CompressedAppendableFile { } public synchronized void dispose() { - myLowMemoryWatcher.stop(); + Disposer.dispose(myDisposable); force(); } @@ -463,17 +469,9 @@ public class CompressedAppendableFile { } private static class FileChunkReadCache extends SLRUMap, byte[]> { - @SuppressWarnings("unused") private final LowMemoryWatcher myLowMemoryWatcher = LowMemoryWatcher.register(new Runnable() { - @Override - public void run() { - synchronized (FileChunkReadCache.this) { - clear(); - } - } - }); private final FileChunkKey myKey = new FileChunkKey(null, 0); - public FileChunkReadCache() { + FileChunkReadCache() { super(64, 64); } @@ -513,7 +511,7 @@ public class CompressedAppendableFile { private int myCurrentPageNumber; private int myPageOffset; - public SegmentedChunkInputStream(long addr, int chunkLengthTableSnapshotLength, byte[] tableRef, int position) { + SegmentedChunkInputStream(long addr, int chunkLengthTableSnapshotLength, byte[] tableRef, int position) { myAddr = addr; myChunkLengthTableSnapshotLength = chunkLengthTableSnapshotLength; myNextChunkBufferSnapshot = tableRef; @@ -523,7 +521,7 @@ public class CompressedAppendableFile { } @Override - public int read(byte[] b, int off, int len) throws IOException { + public int read(@NotNull byte[] b, int off, int len) throws IOException { if (bytesFromCompressedBlock == null) { byte[] decompressedBytes = myCurrentPageNumber < myChunkLengthTableSnapshotLength ? ourDecompressedCache.get(CompressedAppendableFile.this, myCurrentPageNumber) : ArrayUtil.EMPTY_BYTE_ARRAY; diff --git a/platform/util/src/com/intellij/util/io/PersistentHashMap.java b/platform/util/src/com/intellij/util/io/PersistentHashMap.java index fd6a410555b2..b8fad0e934d1 100644 --- a/platform/util/src/com/intellij/util/io/PersistentHashMap.java +++ b/platform/util/src/com/intellij/util/io/PersistentHashMap.java @@ -667,7 +667,7 @@ public class PersistentHashMap extends PersistentEnumeratorDelegate< } } - protected void doClose() throws IOException { + private void doClose() throws IOException { myEnumerator.lockStorage(); try { try { diff --git a/platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java b/platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java index d35da96335da..53471c3293d4 100644 --- a/platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java +++ b/platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import org.jetbrains.annotations.NotNull; import java.io.InputStream; +@SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod") public class UnsyncByteArrayInputStream extends InputStream { protected byte[] myBuffer; private int myPosition; @@ -86,7 +87,7 @@ public class UnsyncByteArrayInputStream extends InputStream { } @Override - public void mark(int readlimit) { + public void mark(int readLimit) { myMarkedPosition = myPosition; } @@ -94,4 +95,4 @@ public class UnsyncByteArrayInputStream extends InputStream { public void reset() { myPosition = myMarkedPosition; } -} +} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/ui/ImageUtil.java b/platform/util/src/com/intellij/util/ui/ImageUtil.java index 8d84977784f3..38c6594e52c2 100644 --- a/platform/util/src/com/intellij/util/ui/ImageUtil.java +++ b/platform/util/src/com/intellij/util/ui/ImageUtil.java @@ -27,10 +27,18 @@ import java.awt.image.*; */ public class ImageUtil { public static BufferedImage toBufferedImage(@NotNull Image image) { + return toBufferedImage(image, false); + } + + public static BufferedImage toBufferedImage(@NotNull Image image, boolean inUserSize) { if (image instanceof JBHiDPIScaledImage) { Image img = ((JBHiDPIScaledImage)image).getDelegate(); + float scale = ((JBHiDPIScaledImage)image).getScale(); if (img != null) { image = img; + if (inUserSize) { + image = scaleImage(image, 1 / scale); + } } } if (image instanceof BufferedImage) { @@ -111,8 +119,4 @@ public class ImageUtil { public static Image scaleImage(Image image, float scale) { return ImageLoader.scaleImage(image, scale); } - - public static boolean needRetinaImage(float scale) { - return scale > 1.5f; - } } diff --git a/platform/util/src/com/intellij/util/ui/JBUI.java b/platform/util/src/com/intellij/util/ui/JBUI.java index bee65c45c04f..6cc81ecf0db4 100644 --- a/platform/util/src/com/intellij/util/ui/JBUI.java +++ b/platform/util/src/com/intellij/util/ui/JBUI.java @@ -432,16 +432,26 @@ public class JBUI { public static boolean isHiDPI(@Nullable GraphicsDevice gd, ScaleType type) { switch (type) { case USR: - return scale(1f) > 1f; + return isHiDPI(scale(1f)); case SYS: - return sysScale(gd) > 1f; + return isHiDPI(sysScale(gd)); case PIX: - return pixScale(gd) > 1f; + return isHiDPI(pixScale(gd)); default: return false; } } + /** + * Returns whether the scale factor assumes HiDPI-awareness. + * + * @param scale the scale factor + * @return whether HiDPI-awareness is assumed for the scale factor + */ + public static boolean isHiDPI(float scale) { + return scale > 1f; + } + /** * Equivalent of {@link #isHiDPI(Graphics2D, ScaleType)} called for the graphics of the default screen device. * @@ -452,7 +462,7 @@ public class JBUI { } /** - * Equivalent of {@link #isHiDPI(Graphics2D, ScaleType)} called for the graphics of specified component. + * Equivalent of {@link #isHiDPI(Graphics2D, ScaleType.USR)} called for the graphics of the specified component. * * @see #isHiDPI(Graphics2D, ScaleType) * @param component if it's {@code null} the graphics of the default screen device will be used diff --git a/platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java b/platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java index dd8ddadbf755..8b5a8cb6a9e2 100644 --- a/platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/AbstractCollectionBinding.java @@ -107,7 +107,7 @@ abstract class AbstractCollectionBinding extends NotNullDeserializeBinding imple @Nullable @Override - public Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter) { Collection collection = getIterable(o); String tagName = getTagName(o); @@ -163,7 +163,7 @@ abstract class AbstractCollectionBinding extends NotNullDeserializeBinding imple } @Nullable - private Object serializeItem(@Nullable Object value, Object context, @NotNull SerializationFilter filter) { + private Object serializeItem(@Nullable Object value, Object context, @Nullable SerializationFilter filter) { if (value == null) { LOG.warn("Collection " + myAccessor + " contains 'null' object"); return null; diff --git a/platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java b/platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java index 5a50da182a4c..3e66270a2806 100644 --- a/platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java +++ b/platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java @@ -32,7 +32,7 @@ class AccessorBindingWrapper extends Binding implements MultiNodeBinding { @Nullable @Override - public Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter) { Object value = myAccessor.read(o); if (value == null) { throw new XmlSerializationException("Property " + myAccessor + " of object " + o + " (" + o.getClass() + ") must not be null"); diff --git a/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java b/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java index e93d6557da8b..5c0fc9766d4a 100644 --- a/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java @@ -30,7 +30,7 @@ class AttributeBinding extends BasePrimitiveBinding { @Override @Nullable - public Object serialize(@NotNull Object o, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable SerializationFilter filter) { Object value = myAccessor.read(o); if (value == null) { return null; diff --git a/platform/util/src/com/intellij/util/xmlb/BasePrimitiveBinding.java b/platform/util/src/com/intellij/util/xmlb/BasePrimitiveBinding.java index 6dc03b2cedc5..bb0c0e9b5498 100644 --- a/platform/util/src/com/intellij/util/xmlb/BasePrimitiveBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/BasePrimitiveBinding.java @@ -48,12 +48,12 @@ abstract class BasePrimitiveBinding extends Binding { @Nullable @Override - public final Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter) { + public final Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter) { return serialize(o, filter); } @Nullable - public abstract Object serialize(@NotNull Object o, @NotNull SerializationFilter filter); + public abstract Object serialize(@NotNull Object o, @Nullable SerializationFilter filter); @NotNull public Object deserialize(@NotNull Object context, @NotNull Element element) { diff --git a/platform/util/src/com/intellij/util/xmlb/BeanBinding.java b/platform/util/src/com/intellij/util/xmlb/BeanBinding.java index 1967d8797fa5..198495e07d6f 100644 --- a/platform/util/src/com/intellij/util/xmlb/BeanBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/BeanBinding.java @@ -76,16 +76,16 @@ public class BeanBinding extends NotNullDeserializeBinding { @Override @Nullable - public Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter) { return serializeInto(o, context == null ? null : new Element(myTagName), filter); } - public Element serialize(@NotNull Object object, boolean createElementIfEmpty, @NotNull SerializationFilter filter) { + public Element serialize(@NotNull Object object, boolean createElementIfEmpty, @Nullable SerializationFilter filter) { return serializeInto(object, createElementIfEmpty ? new Element(myTagName) : null, filter); } @Nullable - public Element serializeInto(@NotNull Object o, @Nullable Element element, @NotNull SerializationFilter filter) { + public Element serializeInto(@NotNull Object o, @Nullable Element element, @Nullable SerializationFilter filter) { for (Binding binding : myBindings) { Accessor accessor = binding.getAccessor(); @@ -93,14 +93,16 @@ public class BeanBinding extends NotNullDeserializeBinding { continue; } - if (filter instanceof SkipDefaultsSerializationFilter) { - if (((SkipDefaultsSerializationFilter)filter).equal(binding, o)) { + if (filter != null) { + if (filter instanceof SkipDefaultsSerializationFilter) { + if (((SkipDefaultsSerializationFilter)filter).equal(binding, o)) { + continue; + } + } + else if (!filter.accepts(accessor, o)) { continue; } } - else if (!filter.accepts(accessor, o)) { - continue; - } //todo: optimize. Cache it. Property property = accessor.getAnnotation(Property.class); diff --git a/platform/util/src/com/intellij/util/xmlb/Binding.java b/platform/util/src/com/intellij/util/xmlb/Binding.java index 20eb2d3a1ce6..0d186d2a98a3 100644 --- a/platform/util/src/com/intellij/util/xmlb/Binding.java +++ b/platform/util/src/com/intellij/util/xmlb/Binding.java @@ -38,7 +38,7 @@ public abstract class Binding { } @Nullable - public abstract Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter); + public abstract Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter); public boolean isBoundTo(@NotNull Element element) { return false; diff --git a/platform/util/src/com/intellij/util/xmlb/CompactCollectionBinding.java b/platform/util/src/com/intellij/util/xmlb/CompactCollectionBinding.java index 747ea23e671b..b2bda74b4462 100644 --- a/platform/util/src/com/intellij/util/xmlb/CompactCollectionBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/CompactCollectionBinding.java @@ -36,7 +36,7 @@ class CompactCollectionBinding extends NotNullDeserializeBinding { @Nullable @Override - public Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter) { Element result = new Element(name); @SuppressWarnings("unchecked") List list = (List)o; diff --git a/platform/util/src/com/intellij/util/xmlb/JDOMElementBinding.java b/platform/util/src/com/intellij/util/xmlb/JDOMElementBinding.java index 675bc0eca5d6..c559e9e8be4a 100644 --- a/platform/util/src/com/intellij/util/xmlb/JDOMElementBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/JDOMElementBinding.java @@ -41,7 +41,7 @@ class JDOMElementBinding extends NotNullDeserializeBinding implements MultiNodeB } @Override - public Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter) { Object value = myAccessor.read(o); if (value == null) { return null; diff --git a/platform/util/src/com/intellij/util/xmlb/MapBinding.java b/platform/util/src/com/intellij/util/xmlb/MapBinding.java index 5f33f1005acf..19d1ae98e4bc 100644 --- a/platform/util/src/com/intellij/util/xmlb/MapBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/MapBinding.java @@ -77,7 +77,7 @@ class MapBinding extends Binding implements MultiNodeBinding { @Nullable @Override - public Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter) { Element serialized = myMapAnnotation == null || myMapAnnotation.surroundWithTag() ? new Element(MAP) : (Element)context; assert serialized != null; @@ -163,7 +163,7 @@ class MapBinding extends Binding implements MultiNodeBinding { return map; } - private void serializeKeyOrValue(@NotNull Element entry, @NotNull String attributeName, @Nullable Object value, @Nullable Binding binding, @NotNull SerializationFilter filter) { + private void serializeKeyOrValue(@NotNull Element entry, @NotNull String attributeName, @Nullable Object value, @Nullable Binding binding, @Nullable SerializationFilter filter) { if (value == null) { return; } diff --git a/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java b/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java index f281f7e84402..06068650ac2f 100644 --- a/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/OptionTagBinding.java @@ -53,7 +53,7 @@ class OptionTagBinding extends BasePrimitiveBinding { @Override @Nullable - public Object serialize(@NotNull Object o, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable SerializationFilter filter) { Object value = myAccessor.read(o); Element targetElement = new Element(myTagName); diff --git a/platform/util/src/com/intellij/util/xmlb/TagBinding.java b/platform/util/src/com/intellij/util/xmlb/TagBinding.java index d1964955c730..dd0af3a8cd31 100644 --- a/platform/util/src/com/intellij/util/xmlb/TagBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/TagBinding.java @@ -36,7 +36,7 @@ class TagBinding extends BasePrimitiveBinding implements MultiNodeBinding { @Nullable @Override - public Object serialize(@NotNull Object o, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable SerializationFilter filter) { Object value = myAccessor.read(o); Element serialized = new Element(myName); if (value == null) { diff --git a/platform/util/src/com/intellij/util/xmlb/TextBinding.java b/platform/util/src/com/intellij/util/xmlb/TextBinding.java index 9a97b6a1cba5..076b556b6dc7 100644 --- a/platform/util/src/com/intellij/util/xmlb/TextBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/TextBinding.java @@ -31,7 +31,7 @@ class TextBinding extends Binding { @Nullable @Override - public Object serialize(@NotNull Object o, @Nullable Object context, @NotNull SerializationFilter filter) { + public Object serialize(@NotNull Object o, @Nullable Object context, @Nullable SerializationFilter filter) { Object value = myAccessor.read(o); return value == null ? null : new Text(XmlSerializerImpl.convertToString(value)); } diff --git a/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java b/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java index 7aba591922fe..16ec0931ad9e 100644 --- a/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java +++ b/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java @@ -40,7 +40,7 @@ public class XmlSerializerImpl { private static Reference, Binding>> ourBindings; @NotNull - static Element serialize(@NotNull Object object, @NotNull SerializationFilter filter) throws XmlSerializationException { + static Element serialize(@NotNull Object object, @Nullable SerializationFilter filter) throws XmlSerializationException { try { Class aClass = object.getClass(); Binding binding = getClassBinding(aClass, aClass, null); @@ -62,7 +62,7 @@ public class XmlSerializerImpl { } @Nullable - static Element serializeIfNotDefault(@NotNull Object object, @NotNull SerializationFilter filter) { + static Element serializeIfNotDefault(@NotNull Object object, @Nullable SerializationFilter filter) { Class aClass = object.getClass(); return (Element)getMainBinding(aClass, aClass, null).serialize(object, null, filter); } diff --git a/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java b/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java index e01b01477079..112caa1cb196 100644 --- a/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java +++ b/platform/util/testSrc/com/intellij/openapi/util/io/IoTestUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -223,7 +223,9 @@ public class IoTestUtil { String path = FileUtil.toSystemIndependentName(ObjectUtils.assertNotNull(FileUtil.getRelativePath(root, file))); try { stream.putNextEntry(new ZipEntry(path)); - stream.write(FileUtil.loadFileBytes(file)); + try (InputStream is = new FileInputStream(file)) { + FileUtil.copy(is, stream); + } stream.closeEntry(); } catch (IOException e) { diff --git a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangesUtil.java b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangesUtil.java index 34bbf97681d0..7775027e169b 100644 --- a/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangesUtil.java +++ b/platform/vcs-api/src/com/intellij/openapi/vcs/changes/ChangesUtil.java @@ -133,37 +133,27 @@ public class ChangesUtil { @NotNull public static Stream getAllPaths(@NotNull Stream changes) { - return changes - .flatMap(change -> Stream.of(getBeforePath(change), getAfterPath(change))) + return changes.flatMap(change -> + Stream.of(getBeforePath(change), getAfterPath(change)) + .filter(Objects::nonNull) + .distinct()); + } + + @NotNull + public static Stream getAllFiles(@NotNull Stream changes) { + return getAllPaths(changes) + .map(FilePath::getVirtualFile) .filter(Objects::nonNull); } /** - * @deprecated Use {@link ChangesUtil#getAfterRevisionsFiles(Stream)}. + * @deprecated Use {@link ChangesUtil#getAllFiles(Stream)}. */ @SuppressWarnings("unused") // Required for compatibility with external plugins. @Deprecated @NotNull public static VirtualFile[] getFilesFromChanges(@NotNull Collection changes) { - return getAfterRevisionsFiles(changes.stream()).toArray(VirtualFile[]::new); - } - - @NotNull - public static Stream getAfterRevisionsFiles(@NotNull Stream changes) { - return getAfterRevisionsFiles(changes, false); - } - - @NotNull - public static Stream getAfterRevisionsFiles(@NotNull Stream changes, boolean refresh) { - LocalFileSystem fileSystem = LocalFileSystem.getInstance(); - - return changes - .map(Change::getAfterRevision) - .filter(Objects::nonNull) - .map(ContentRevision::getFile) - .map(path -> refresh ? fileSystem.refreshAndFindFileByPath(path.getPath()) : path.getVirtualFile()) - .filter(Objects::nonNull) - .filter(VirtualFile::isValid); + return getAllFiles(changes.stream()).toArray(VirtualFile[]::new); } @NotNull diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesTreeBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesTreeBrowser.java index 390e3f7f4980..db8532d6e76a 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesTreeBrowser.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/CommittedChangesTreeBrowser.java @@ -67,8 +67,8 @@ import java.awt.*; import java.util.*; import java.util.List; -import static com.intellij.openapi.vcs.changes.ChangesUtil.getAfterRevisionsFiles; import static com.intellij.openapi.vcs.changes.ChangesUtil.getNavigatableArray; +import static com.intellij.openapi.vcs.changes.ChangesUtil.getAllFiles; import static com.intellij.util.WaitForProgressToShow.runOrInvokeLaterAboveProgress; /** @@ -446,7 +446,7 @@ public class CommittedChangesTreeBrowser extends JPanel implements TypeSafeDataP } else if (key.equals(CommonDataKeys.NAVIGATABLE_ARRAY)) { Collection changes = collectChanges(getSelectedChangeLists(), false); - sink.put(CommonDataKeys.NAVIGATABLE_ARRAY, getNavigatableArray(myProject, getAfterRevisionsFiles(changes.stream()))); + sink.put(CommonDataKeys.NAVIGATABLE_ARRAY, getNavigatableArray(myProject, getAllFiles(changes.stream()))); } else if (key.equals(PlatformDataKeys.HELP_ID)) { sink.put(PlatformDataKeys.HELP_ID, myHelpId); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RepositoryChangesBrowser.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RepositoryChangesBrowser.java index e48a331c0800..07cc51b6ca99 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RepositoryChangesBrowser.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/committed/RepositoryChangesBrowser.java @@ -43,8 +43,8 @@ import java.util.List; import java.util.Set; import java.util.stream.Stream; -import static com.intellij.openapi.vcs.changes.ChangesUtil.getAfterRevisionsFiles; import static com.intellij.openapi.vcs.changes.ChangesUtil.getNavigatableArray; +import static com.intellij.openapi.vcs.changes.ChangesUtil.getAllFiles; /** * @author yole @@ -140,7 +140,7 @@ public class RepositoryChangesBrowser extends ChangesBrowser implements DataProv protected Navigatable[] getNavigatables(final DataContext dataContext) { Change[] changes = VcsDataKeys.SELECTED_CHANGES.getData(dataContext); - return changes != null ? getNavigatableArray(myProject, getAfterRevisionsFiles(Stream.of(changes))) : null; + return changes != null ? getNavigatableArray(myProject, getAllFiles(Stream.of(changes))) : null; } } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java index f2be57d61cc9..90838a234bd5 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesBrowserBase.java @@ -53,8 +53,8 @@ import java.util.*; import java.util.List; import java.util.stream.Stream; -import static com.intellij.openapi.vcs.changes.ChangesUtil.getAfterRevisionsFiles; import static com.intellij.openapi.vcs.changes.ChangesUtil.getNavigatableArray; +import static com.intellij.openapi.vcs.changes.ChangesUtil.getAllFiles; import static com.intellij.openapi.vcs.changes.ui.ChangesBrowserNode.UNVERSIONED_FILES_TAG; import static com.intellij.openapi.vcs.changes.ui.ChangesListView.*; @@ -448,7 +448,7 @@ public abstract class ChangesBrowserBase extends JPanel implements TypeSafeDa @NotNull protected Stream getSelectedFiles() { return Stream.concat( - getAfterRevisionsFiles(getSelectedChanges().stream()), + getAllFiles(getSelectedChanges().stream()), getVirtualFiles(myViewer.getSelectionPaths(), null) ).distinct(); } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java index 8f62f9684dad..ce5aa0975b85 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ui/ChangesListView.java @@ -50,7 +50,7 @@ import java.util.List; import java.util.Objects; import java.util.stream.Stream; -import static com.intellij.openapi.vcs.changes.ChangesUtil.getAfterRevisionsFiles; +import static com.intellij.openapi.vcs.changes.ChangesUtil.getAllFiles; import static com.intellij.openapi.vcs.changes.ui.ChangesBrowserNode.*; import static com.intellij.util.containers.UtilKt.getIfSingle; import static com.intellij.util.containers.UtilKt.stream; @@ -304,7 +304,7 @@ public class ChangesListView extends Tree implements TypeSafeDataProvider, DnDAw @NotNull protected Stream getSelectedFiles() { return Stream.concat( - getAfterRevisionsFiles(getSelectedChanges()), + getAllFiles(getSelectedChanges()), getSelectedVirtualFiles(null) ).distinct(); } diff --git a/platform/vcs-impl/src/com/intellij/vcsUtil/VcsFileUtil.java b/platform/vcs-impl/src/com/intellij/vcsUtil/VcsFileUtil.java index 98a3d84eb6c2..98461e6818ca 100644 --- a/platform/vcs-impl/src/com/intellij/vcsUtil/VcsFileUtil.java +++ b/platform/vcs-impl/src/com/intellij/vcsUtil/VcsFileUtil.java @@ -15,15 +15,19 @@ */ package com.intellij.vcsUtil; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.ThrowableNotNullFunction; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vcs.FilePath; -import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; +import com.intellij.openapi.vcs.checkin.CheckinEnvironment; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.ThrowableConsumer; @@ -33,6 +37,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -379,4 +384,70 @@ public class VcsFileUtil { return null; } + + public static void addFilesToVcsWithConfirmation(@NotNull Project project, VirtualFile... virtualFiles) { + addFilesToVcsWithConfirmation(project, Arrays.asList(virtualFiles)); + } + + /** + * Finds all VCSs related to the passed files, suggests user to add files to the respected VCSs honoring addition and silence settings + * and adds them if user or settings confirmed addition. Because of potentially long operation of collecting files it's highly recommended + * to invoke it on the pooled thread. Method works synchronously. + * + * @param project project we work in + * @param virtualFiles collection of virtual files to add; directories being added recursively + */ + public static void addFilesToVcsWithConfirmation(@NotNull Project project, + @NotNull Collection virtualFiles) { + if (virtualFiles.isEmpty()) { + return; + } + ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); + Multimap vcsMap = ArrayListMultimap.create(); + for (VirtualFile createdFile : virtualFiles) { + AbstractVcs vcs = vcsManager.getVcsFor(createdFile); + if (vcs == null) { + continue; + } + VfsUtil.processFileRecursivelyWithoutIgnored(createdFile, (virtualFile) -> vcsMap.put(vcs, virtualFile)); + } + + for (AbstractVcs vcs : vcsMap.keySet()) { + VcsShowConfirmationOption addOption = + vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.ADD, vcs); + if (addOption.getValue() == VcsShowConfirmationOption.Value.DO_NOTHING_SILENTLY) return; + List filesList = new ArrayList<>(vcsMap.get(vcs)); + if (addOption.getValue() == VcsShowConfirmationOption.Value.DO_ACTION_SILENTLY) { + performAdditions(vcs, filesList); + } + else { + AbstractVcsHelper helper = AbstractVcsHelper.getInstance(project); + + Ref> filesToAdd = Ref.create(); + + ApplicationManager.getApplication().invokeAndWait(() -> filesToAdd.set( + helper + .selectFilesToProcess( + new ArrayList<>(filesList), + VcsBundle.message("confirmation.title.add.files.to", vcs.getDisplayName()), + null, + VcsBundle.message("confirmation.title.add.file.to", vcs.getDisplayName()), + null, + addOption)) + ); + + if (!filesToAdd.isNull()) { + performAdditions(vcs, new ArrayList<>(filesToAdd.get())); + } + } + } + } + + private static void performAdditions(@NotNull AbstractVcs vcs, + @NotNull List value) { + CheckinEnvironment checkinEnvironment = vcs.getCheckinEnvironment(); + if (checkinEnvironment != null) { + checkinEnvironment.scheduleUnversionedFilesForAddition(value); + } + } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml index 4b886a80666d..dce1a71a7fa9 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml @@ -320,10 +320,6 @@ - #ref optional.contains.array.problem.descriptor='Optional' contains array #ref -optional.get.without.is.present.display.name='Optional.get()' without 'isPresent()' check -optional.get.without.is.present.problem.descriptor={0}.#ref() without ''isPresent()'' check -optional.get.definitely.absent.problem.descriptor={0}.#ref() will definitely fail as {0} is empty here synchronization.on.get.class.display.name=Synchronization on 'getClass()' synchronization.on.get.class.problem.descriptor=Synchronization on #ref() #loc object.instantiation.inside.equals.or.hashcode.display.name=Object instantiation inside 'equals()' or 'hashCode()' diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/OptionalGetWithoutIsPresentInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/OptionalGetWithoutIsPresentInspection.java deleted file mode 100644 index b94cc58c970d..000000000000 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/OptionalGetWithoutIsPresentInspection.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.siyeh.ig.bugs; - -import com.intellij.codeInspection.dataFlow.*; -import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.ObjectUtils; -import com.intellij.util.ThreeState; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.BaseInspection; -import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.ParenthesesUtils; -import com.siyeh.ig.psiutils.TypeUtils; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; - -/** - * @author Bas Leijdekkers - */ -public class OptionalGetWithoutIsPresentInspection extends BaseInspection { - @Nls - @NotNull - @Override - public String getDisplayName() { - return InspectionGadgetsBundle.message("optional.get.without.is.present.display.name"); - } - - @NotNull - @Override - protected String buildErrorString(Object... infos) { - final PsiClassType aClass = (PsiClassType)infos[0]; - final ThreeState state = ((ThreeState)infos[1]); - if (state == ThreeState.NO) { - return InspectionGadgetsBundle.message("optional.get.definitely.absent.problem.descriptor", aClass.rawType().getClassName()); - } - else { - return InspectionGadgetsBundle.message("optional.get.without.is.present.problem.descriptor", aClass.rawType().getClassName()); - } - } - - @Override - public BaseInspectionVisitor buildVisitor() { - return new OptionalGetWithoutIsPresentVisitor(); - } - - private static class OptionalGetWithoutIsPresentVisitor extends BaseInspectionVisitor { - - private final Map seen = new HashMap<>(); - - @Override - public void visitMethodCallExpression(PsiMethodCallExpression expression) { - super.visitMethodCallExpression(expression); - final PsiReferenceExpression methodExpression = expression.getMethodExpression(); - final String name = methodExpression.getReferenceName(); - if (!isOptionalGetMethodName(name)) return; - final PsiExpression qualifier = ParenthesesUtils.stripParentheses(methodExpression.getQualifierExpression()); - if (qualifier == null) return; - final PsiType type = qualifier.getType(); - if (!TypeUtils.isOptional(type)) return; - ThreeState state = seen.get(expression); - if (state == null) { - PsiElement context = getContext(expression); - if (context == null) return; - analyze(context); - } - state = seen.get(expression); - if (state != null && state != ThreeState.YES) { - registerMethodCallError(expression, type, state); - } - } - - private void analyze(PsiElement context) { - final DataFlowRunner dfaRunner = new StandardDataFlowRunner(false, true, isOnTheFly()); - dfaRunner.analyzeMethod(context, new StandardInstructionVisitor() { - @Override - public DfaInstructionState[] visitMethodCall(MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { - PsiMethodCallExpression call = ObjectUtils.tryCast(instruction.getCallExpression(), PsiMethodCallExpression.class); - if (call != null) { - String methodName = call.getMethodExpression().getReferenceName(); - PsiExpression qualifier = call.getMethodExpression().getQualifierExpression(); - if (qualifier != null && TypeUtils.isOptional(qualifier.getType()) && isOptionalGetMethodName(methodName)) { - ThreeState state = memState.checkOptional(memState.peek()); - seen.merge(call, state, (s1, s2) -> s1 == s2 ? s1 : ThreeState.UNSURE); - } - } - return super.visitMethodCall(instruction, runner, memState); - } - }); - } - - @Nullable - private static PsiElement getContext(PsiMethodCallExpression expression) { - PsiElement context = PsiTreeUtil.getParentOfType(expression, PsiMember.class, PsiLambdaExpression.class); - if (context instanceof PsiMethod) { - return ((PsiMethod)context).getBody(); - } - else if (context instanceof PsiClassInitializer) { - return ((PsiClassInitializer)context).getBody(); - } - else if (context instanceof PsiField) { - return ((PsiField)context).getInitializer(); - } - return context; - } - - private static boolean isOptionalGetMethodName(String name) { - return "get".equals(name) || "getAsDouble".equals(name) || "getAsInt".equals(name) || "getAsLong".equals(name); - } - } -} diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ClassEscapesItsScopeInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ClassEscapesItsScopeInspection.java index bf669828a44f..d7ee6a4f5bda 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ClassEscapesItsScopeInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/visibility/ClassEscapesItsScopeInspection.java @@ -87,7 +87,7 @@ public class ClassEscapesItsScopeInspection extends BaseJavaBatchLocalInspection Set exportedPackageNames = new THashSet<>(ContainerUtil.mapNotNull(psiModule.getExports(), PsiPackageAccessibilityStatement::getPackageName)); if (exportedPackageNames.contains(javaFile.getPackageName())) { - checkers.add(new Java9NonAccessibleTypeExposedVisitor(holder, module, psiModule.getModuleName(), exportedPackageNames)); + checkers.add(new Java9NonAccessibleTypeExposedVisitor(holder, module, psiModule.getName(), exportedPackageNames)); } } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/OptionalGetWithoutIsPresent.html b/plugins/InspectionGadgets/src/inspectionDescriptions/OptionalGetWithoutIsPresent.html deleted file mode 100644 index ea2a82e4d881..000000000000 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/OptionalGetWithoutIsPresent.html +++ /dev/null @@ -1,9 +0,0 @@ - - -Reports calls to java.util.Optional.get() without first checking with a isPresent() call if a value is available. -If the Optional does not contain a value, get() will throw an exception. - -

-New in 16 - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/OptionalGetWithoutIsPresentInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/OptionalGetWithoutIsPresentInspectionTest.java deleted file mode 100644 index ec6b72183dfd..000000000000 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/OptionalGetWithoutIsPresentInspectionTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.siyeh.ig.bugs; - -import com.intellij.codeInspection.InspectionProfileEntry; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.testFramework.IdeaTestUtil; -import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.PsiTestUtil; -import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; -import com.siyeh.ig.LightInspectionTestCase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * @author Bas Leijdekkers - */ -@SuppressWarnings({"OptionalGetWithoutIsPresent", "OptionalUsedAsFieldOrParameterType"}) -public class OptionalGetWithoutIsPresentInspectionTest extends LightInspectionTestCase { - private static final DefaultLightProjectDescriptor PROJECT_DESCRIPTOR = new DefaultLightProjectDescriptor() { - @Override - public Sdk getSdk() { - return PsiTestUtil.addJdkAnnotations(IdeaTestUtil.getMockJdk18()); - } - }; - - @NotNull - @Override - protected LightProjectDescriptor getProjectDescriptor() { - return PROJECT_DESCRIPTOR; - } - - public void testSimple() { - doTest("import java.util.Optional;" + - "class X {" + - " void a(Optional o) {" + - " System.out.println(o./*'Optional.get()' without 'isPresent()' check*/get/**/());" + - " }" + - "}"); - } - - public void testOptionalDouble() { - doTest("import java.util.OptionalDouble;" + - "class X {" + - " double a(OptionalDouble d) {" + - " return d./*'OptionalDouble.getAsDouble()' without 'isPresent()' check*/getAsDouble/**/();" + - " }" + - "}"); - } - - public void testOptionalWithoutVariable() { - doTest("import java.util.Optional;" + - "class X {" + - " {" + - " System.out.println(getName()./*'Optional.get()' without 'isPresent()' check*/get/**/());" + - " }" + - " Optional getName() {" + - " return Optional.empty();" + - " }" + - "}"); - } - - public void testWhile1() { - doTest("import java.util.Optional;" + - "class X {" + - " void m() {" + - " Optional o = Optional.empty();" + - " while (!o.isPresent()){" + - " o = Optional.of(\"\");" + - " }" + - " o.get();" + - " }" + - "}"); - } - - public void testWhile2() { - doTest("import java.util.Optional;" + - "class X {" + - " void m() {" + - " Optional o = Optional.empty();" + - " while (o.isPresent()) {" + - " o.get();" + - " }" + - " }" + - "}"); - } - - public void testPolyadicExpression1() { - doTest("import java.util.Optional;" + - "class X {" + - " public void demo(Optional value) {\n" + - " boolean flag = value.isPresent() && \"Yes\".equals(value.get());\n" + - " }" + - "}"); - } - - public void testPolyadicExpression2() { - doTest("import java.util.Optional;" + - "class X {" + - " boolean m(Optional o) {" + - " return !o.isPresent() || o.get().equals(\"j\");" + - " }" + - "}"); - } - - public void testPolyadicExpression3() { - doTest("import java.util.Optional;" + - "class X {" + - " String g() {" + - " Optional o = Optional.empty();" + - " if(o == null || !o.isPresent()) {" + - " return \"\";" + - " }" + - " return o.get();" + - " }" + - "}"); - } - - public void testNested() { - doTest("import java.util.Optional;" + - "class X {" + - " void test(Optional opt, String action) {" + - " if(!opt.isPresent()) {" + - " throw new IllegalArgumentException();" + - " }" + - " switch(action) {" + - " case \"case\":" + - " System.out.println(opt.get());" + - " break;" + - " default:" + - " System.err.println(opt.get());" + - " }" + - " }" + - "}"); - } - - public void testOptionalGetWithoutIsPresent() { - doTest(); - } - - @Nullable - @Override - protected InspectionProfileEntry getInspection() { - return new OptionalGetWithoutIsPresentInspection(); - } - - @Override - protected String[] getEnvironmentClasses() { - return new String[] { - "package org.junit;" + - "public class Assert {" + - " public static void assertTrue(boolean b) {}" + - "}", - - "package org.testng;" + - "public class Assert {" + - " public static void assertTrue(boolean b) {}" + - "}" - }; - } -} \ No newline at end of file diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java index f958c30dbd0c..8898d5b7fdaf 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/conversion/IdeaSpecificSettings.java @@ -20,6 +20,7 @@ */ package org.jetbrains.idea.eclipse.conversion; +import com.intellij.configurationStore.XmlSerializer; import com.intellij.openapi.components.ComponentSerializationUtil; import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.diagnostic.Logger; @@ -39,7 +40,6 @@ import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.util.xmlb.XmlSerializer; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -264,7 +264,8 @@ public class IdeaSpecificSettings extends AbstractIdeaSpecificSettings commits = ContainerUtil.newArrayList(); - loadDetails(project, root, withRefs, withChanges, record -> commits.add(converter.fun(record)), parameters); + try { + loadDetails(project, root, withRefs, withChanges, record -> commits.add(converter.fun(record)), parameters); + } + catch (VcsException e) { + if (commits.isEmpty()) { + throw e; + } + LOG.warn("Error during loading details, returning partially loaded commits\n", e); + } return commits; } diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java index f45752e7c0e8..7db0a6cc5a76 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopup.java @@ -124,7 +124,7 @@ class GitBranchPopup extends DvcsBranchPopup { myMultiRootBranchConfig.getLocalBranchNames().stream().map(l -> createLocalBranchActions(allRepositories, l)).filter(Objects::nonNull) .collect(toList()); wrapWithMoreActionIfNeeded(myProject, popupGroup, ContainerUtil.sorted(localBranchActions, FAVORITE_BRANCH_COMPARATOR), - getNumOfTopShownBranches(localBranchActions), SHOW_ALL_LOCALS_KEY); + getNumOfTopShownBranches(localBranchActions), SHOW_ALL_LOCALS_KEY, true); popupGroup.addSeparator("Common Remote Branches"); List remoteBranchActions = map(((GitMultiRootBranchConfig)myMultiRootBranchConfig).getRemoteBranches(), diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java index 51a320d277ae..bce8008ea8fe 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitBranchPopupActions.java @@ -78,7 +78,8 @@ class GitBranchPopupActions { .collect(toList()); // if there are only a few local favorites -> show all; for remotes it's better to show only favorites; wrapWithMoreActionIfNeeded(myProject, popupGroup, ContainerUtil.sorted(localBranchActions, FAVORITE_BRANCH_COMPARATOR), - getNumOfTopShownBranches(localBranchActions), firstLevelGroup ? GitBranchPopup.SHOW_ALL_LOCALS_KEY : null); + getNumOfTopShownBranches(localBranchActions), firstLevelGroup ? GitBranchPopup.SHOW_ALL_LOCALS_KEY : null, + firstLevelGroup); popupGroup.addSeparator("Remote Branches" + repoInfo); List remoteBranchActions = diff --git a/platform/projectModel-impl/src/com/intellij/configurationStore/serializationUtil.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/ext/spock/SpockCantBeStaticExtension.kt similarity index 51% rename from platform/projectModel-impl/src/com/intellij/configurationStore/serializationUtil.kt rename to plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/ext/spock/SpockCantBeStaticExtension.kt index f4ef6672cb65..040de8216205 100644 --- a/platform/projectModel-impl/src/com/intellij/configurationStore/serializationUtil.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/ext/spock/SpockCantBeStaticExtension.kt @@ -13,16 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.configurationStore +package org.jetbrains.plugins.groovy.ext.spock -import com.intellij.openapi.components.BaseState -import com.intellij.openapi.components.ComponentSerializationUtil -import com.intellij.openapi.components.PersistentStateComponent -import org.jdom.Element +import com.intellij.openapi.util.Condition +import com.intellij.psi.PsiElement +import org.jetbrains.plugins.groovy.ext.spock.SpockUtils.* +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod -fun deserializeAndLoadState(component: PersistentStateComponent<*>, element: Element) { - val state = element.deserialize(ComponentSerializationUtil.getStateClass(component.javaClass)) - (state as? BaseState)?.resetModificationCount() - @Suppress("UNCHECKED_CAST") - (component as PersistentStateComponent).loadState(state) -} +class SpockCantBeStaticExtension : Condition { + + override fun value(element: PsiElement?): Boolean { + return element is GrMethod + && isSpecification(element.containingClass) + && (isFeatureMethod(element) || isFixtureMethod(element)) + } +} \ No newline at end of file diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java index 5a9f2aabb999..80497a9e1e01 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java @@ -633,12 +633,7 @@ public class PsiImplUtil { toplevel = (GrExpression)toplevel.getParent(); } - final PsiType normalized = doNormalizeWildcardByPosition(type, expression, toplevel); - if (normalized instanceof PsiClassType && !PsiUtil.isAccessedForWriting(toplevel)) { - return com.intellij.psi.util.PsiUtil.captureToplevelWildcards(normalized, expression); - } - - return normalized; + return doNormalizeWildcardByPosition(type, expression, toplevel); } @Nullable @@ -652,7 +647,7 @@ public class PsiImplUtil { final PsiWildcardType wildcardType = (PsiWildcardType)type; if (PsiUtil.isAccessedForWriting(toplevel)) { - return wildcardType.isSuper() ? wildcardType.getBound() : PsiCapturedWildcardType.create(wildcardType, expression); + return wildcardType.getBound(); } else { if (wildcardType.isExtends()) { diff --git a/plugins/groovy/src/META-INF/spock-support.xml b/plugins/groovy/src/META-INF/spock-support.xml index 770c423608e3..6fae11a91044 100644 --- a/plugins/groovy/src/META-INF/spock-support.xml +++ b/plugins/groovy/src/META-INF/spock-support.xml @@ -6,5 +6,6 @@ + \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java index ea9076f2a27d..7ce29c7546b2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrCreateFromUsageBaseFix.java @@ -102,7 +102,7 @@ public abstract class GrCreateFromUsageBaseFix extends Intention { final Project project = classes.get(0).getProject(); final JList list = new JBList(classes); - PsiElementListCellRenderer renderer = PsiClassListCellRenderer.INSTANCE; + PsiElementListCellRenderer renderer = new PsiClassListCellRenderer(); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setCellRenderer(renderer); final PopupChooserBuilder builder = new PopupChooserBuilder(list); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceFieldHandlerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceFieldHandlerBase.java index f7d8a0447cf6..4ecd9e053649 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceFieldHandlerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceFieldHandlerBase.java @@ -67,7 +67,7 @@ public abstract class GrIntroduceFieldHandlerBaseregularMethod() {} + def featureMethod() { + expect: 1 == 1 + } +} +''' + def inspection = new GrMethodMayBeStaticInspection() + inspection.myIgnoreEmptyMethods = false + myFixture.enableInspections inspection + myFixture.checkHighlighting() + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/CastToTypeTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/CastToTypeTest.groovy index fbb1d704711a..a6b912434ed9 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/CastToTypeTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/inspections/CastToTypeTest.groovy @@ -39,6 +39,6 @@ class CastToTypeTest extends LightCodeInsightFixtureTestCase { myFixture.checkResultByFile(getTestName(true) + '_after.groovy') } - void testSimple() {doTest('Cast to List')} + void testSimple() {doTest('Cast to List')} void testInReturnType() {doTest('Cast to int')} } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrGenericsInferringTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrGenericsInferringTest.groovy new file mode 100644 index 000000000000..fe2e7aad39c1 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GrGenericsInferringTest.groovy @@ -0,0 +1,281 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.lang.highlighting + +class GrGenericsInferringTest extends GrHighlightingTestBase { + void testMapExplicit() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + static void method() { + Map map = [:].collectEntries { k, v -> [:] } + + map.put(1, 2) + } + ''' + } + + void testMapImplicit() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + static void method() { + def map = [:].collectEntries { k, v -> [:] } + map.put(1, 2) + } + ''' + } + + void testMapChainCall() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + static void method() { + [:].collectEntries { k, v -> [:] }.put(1, 2) + } + ''' + } + + void testListWildcardExtends() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + static def method(List captured) { + captured.add('some string') + return captured + } + ''' + } + + void testListWildcardExtendsError() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + static def method(List captured) { + captured.add(new Object()) + return captured + } + ''' + } + + void testListWildcardExtendsAssign() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + static void method(List captured) { + Serializable s = captured.get(0); + } + ''' + } + + void testListWildcardSuper() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + static def method(List captured) { + captured.add('some string\') + return captured + } + ''' + } + + void testListWildcardSuperError() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + static void method(List captured) { + Serializable s = captured.get(0); + } + ''' + } + + void testDeclaration6() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + def m(){ + Map obj = new HashMap() + } + ''' + } + + void testAddOnList() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + def m(){ + List list = [] + list.add(1) + } + ''' + } + + void testAddOnListUsingLeftShift() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + def m(){ + List list = [] + list << 1 + } + ''' + } + + void testPutMethodWithWrongValueType() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + def m(){ + Map map = new HashMap() + map.put('hello', new Object()) + } + ''' + } + + void testPutMethodWithPrimitiveValueAndArrayPut() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + def m(){ + Map map = new HashMap() + map['hello'] = 1 + } + ''' + } + + + void testAddAllWithCollectionShouldNotBeAllowed() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + def m(){ + List list = ['a','b','c'] + Collection e = (Collection) [1,2,3] + boolean r = list.addAll(e) + } + ''' + } + + void testIncompatibleGenericsForTwoArgumentsUsingEmbeddedPlaceholder() { + testHighlighting ''' + import groovy.transform.CompileStatic + + @CompileStatic + public void printEqual(T arg1, List arg2) { + println arg1 == arg2 + } + @CompileStatic + def m() { + printEqual(1, ['foo']) + } + ''' + } + + void testConstructorArgumentsAgainstGenerics() { + testHighlighting ''' + class Foo{ Foo(T a, T b){} } + + @groovy.transform.CompileStatic + def bar() { + Foo f = new Foo("a",1) + } + + ''' + } + + void testMethodWithDefaultArgument() { + testHighlighting ''' + class A{} + class B extends A{} + def foo(List arg, String value='default'){1} + + List b = new ArrayList<>() + assert foo(b) == 1 + List a = new ArrayList<>() + assert foo(a) == 1 + ''' + + testHighlighting ''' + class A{} + class B extends A{} + def foo(List arg, String value='default'){1} + + @groovy.transform.CompileStatic + def m() { + List l = new ArrayList<>() + assert foo(l) == 1 + } + ''' + } + + void testMethodShadowGenerics() { + testHighlighting ''' + @groovy.transform.CompileStatic + public class GoodCodeRed { + Collection> attached = [] + public void attach(GoodCodeRed toAttach) { + attached.add(toAttach) + } + static void foo() { + def g1 = new GoodCodeRed() + def g2 = new GoodCodeRed() + g1.attach(g2); + } + } + GoodCodeRed.foo() + ''' + } + + void testGenericField() { + testHighlighting ''' + class MyClass { + static void main(args) { + Holder holder = new Holder() + holder.value = 5 + assert holder.value > 4 + } + private static class Holder { + T value + } + } + ''' + } + + void testReturnTypeChecking() { + testHighlighting ''' + @groovy.transform.CompileStatic + class Foo { + List run() { + [11, 12] + } + } + ''' + } +} diff --git a/plugins/java-decompiler/engine/readme.txt b/plugins/java-decompiler/engine/README.md similarity index 60% rename from plugins/java-decompiler/engine/readme.txt rename to plugins/java-decompiler/engine/README.md index cd4765664b06..28b82dcb9a55 100644 --- a/plugins/java-decompiler/engine/readme.txt +++ b/plugins/java-decompiler/engine/README.md @@ -1,4 +1,4 @@ -1. About the decompiler +## About fernflower Fernflower is the first actually working analytical decompiler for Java and probably for a high-level programming language in general. Naturally it is still @@ -6,12 +6,11 @@ under development, please send your bug reports and improvement suggestions at fernflower.decompiler@gmail.com -2. License +## Licence -http://www.apache.org/licenses/LICENSE-2.0 +Fernflower is licenced under the Apache Licence Version 2.0. It can be found here: http://www.apache.org/licenses/LICENSE-2.0 - -3. Running from the command line +## Running from command line java -jar fernflower.jar [-