diff --git a/java/compiler/tests/com/intellij/compiler/artifacts/ui/ArtifactEditorTestCase.java b/java/compiler/tests/com/intellij/compiler/artifacts/ui/ArtifactEditorTestCase.java index 9b18c4aa0e3a..3c74644ece14 100644 --- a/java/compiler/tests/com/intellij/compiler/artifacts/ui/ArtifactEditorTestCase.java +++ b/java/compiler/tests/com/intellij/compiler/artifacts/ui/ArtifactEditorTestCase.java @@ -11,7 +11,6 @@ import com.intellij.openapi.util.Ref; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.elements.PackagingElementFactory; import com.intellij.util.PathUtil; -import org.jetbrains.annotations.NotNull; import java.util.Arrays; import java.util.Collections; @@ -80,7 +79,7 @@ public abstract class ArtifactEditorTestCase extends PackagingElementsTestCase { final Ref dialogShown = Ref.create(false); final TestDialog oldDialog = Messages.setTestDialog(new TestDialog() { @Override - public int show(@NotNull String message) { + public int show(String message) { dialogShown.set(true); return 0; } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java index 8fffd0fcc2ef..03a223ad2080 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java @@ -2,7 +2,6 @@ package com.intellij.debugger.actions; import com.intellij.debugger.SourcePosition; -import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.SuspendContextImpl; import com.intellij.debugger.engine.evaluation.EvaluateException; @@ -27,10 +26,7 @@ import com.intellij.psi.*; import com.intellij.util.DocumentUtil; import com.intellij.util.Range; import com.intellij.util.ThreeState; -import com.intellij.util.containers.ContainerUtil; import com.sun.jdi.Location; -import com.sun.jdi.Method; -import com.sun.jdi.ReferenceType; import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -342,67 +338,42 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler { if (!targets.isEmpty()) { StackFrameProxyImpl frameProxy = suspendContext != null ? suspendContext.getFrameProxy() : null; if (frameProxy != null) { - // sanity check try { - List methodTargets = - StreamEx.of(targets) - .select(MethodSmartStepTarget.class) - .filter(target -> !target.needsBreakpointRequest()) - .toList(); - visitLinesMethods(frameProxy.location(), true, lines, (opcode, owner, name, desc, itf) -> { - if (name.startsWith("access$")) { // bridge method - ReferenceType cls = ContainerUtil.getFirstItem(frameProxy.getVirtualMachine().classesByName(owner)); - if (cls != null) { - Method method = DebuggerUtils.findMethod(cls, name, desc); - if (method != null) { - MethodBytecodeUtil.visit(method, new MethodVisitor(Opcodes.API_VERSION) { - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - if ("java/lang/AbstractMethodError".equals(owner)) { - return; - } - removeMatchingMethod(methodTargets, owner, name, desc, suspendContext.getDebugProcess()); - } - }, false); + Location location = frameProxy.location(); + MethodBytecodeUtil.visit(location.method(), location.codeIndex(), new MethodVisitor(Opcodes.API_VERSION) { + boolean myLineMatch = false; + + @Override + public void visitLineNumber(int line, Label start) { + myLineMatch = lines.isWithin(line - 1); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { + if (myLineMatch) { + Iterator iterator = targets.iterator(); + while (iterator.hasNext()) { + SmartStepTarget e = iterator.next(); + if (e instanceof MethodSmartStepTarget && + DebuggerUtilsEx.methodMatches(((MethodSmartStepTarget)e).getMethod(), + owner.replace("/", "."), name, desc, + suspendContext.getDebugProcess())) { + iterator.remove(); + MethodSmartStepTarget target = (MethodSmartStepTarget)e; + // fix ordinals + existingMethodCalls(targets, target.getMethod()) + .forEach(t -> { + int ordinal = t.getOrdinal(); + if (ordinal > target.getOrdinal()) { + t.setOrdinal(ordinal - 1); + } + }); + break; + } } } } - else { - removeMatchingMethod(methodTargets, owner, name, desc, suspendContext.getDebugProcess()); - } - }); - if (!methodTargets.isEmpty()) { - return Collections.emptyList(); - } - } - catch (Exception e) { - LOG.error(e); - } - - // remove already executed - try { - visitLinesMethods(frameProxy.location(), false, lines, (opcode, owner, name, desc, itf) -> { - Iterator iterator = targets.iterator(); - while (iterator.hasNext()) { - SmartStepTarget e = iterator.next(); - if (e instanceof MethodSmartStepTarget && - DebuggerUtilsEx.methodMatches(((MethodSmartStepTarget)e).getMethod(), - owner.replace("/", "."), name, desc, - suspendContext.getDebugProcess())) { - iterator.remove(); - MethodSmartStepTarget target = (MethodSmartStepTarget)e; - // fix ordinals - existingMethodCalls(targets, target.getMethod()) - .forEach(t -> { - int ordinal = t.getOrdinal(); - if (ordinal > target.getOrdinal()) { - t.setOrdinal(ordinal - 1); - } - }); - break; - } - } - }); + }, true); } catch (Exception e) { LOG.info(e); @@ -415,42 +386,6 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler { return Collections.emptyList(); } - private static void removeMatchingMethod(List targets, - String owner, - String name, - String desc, - DebugProcessImpl process) { - Iterator iterator = targets.iterator(); - while (iterator.hasNext()) { - if (DebuggerUtilsEx.methodMatches(iterator.next().getMethod(), owner.replace("/", "."), name, desc, process)) { - iterator.remove(); - break; - } - } - } - - private interface MethodInsnVisitor { - void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf); - } - - private static void visitLinesMethods(Location location, boolean full, Range lines, MethodInsnVisitor visitor) { - MethodBytecodeUtil.visit(location.method(), full ? Long.MAX_VALUE : location.codeIndex(), new MethodVisitor(Opcodes.API_VERSION) { - boolean myLineMatch = false; - - @Override - public void visitLineNumber(int line, Label start) { - myLineMatch = lines.isWithin(line - 1); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - if (myLineMatch) { - visitor.visitMethodInsn(opcode, owner, name, desc, itf); - } - } - }, true); - } - private static StreamEx existingMethodCalls(List targets, PsiMethod psiMethod) { return StreamEx.of(targets) .select(MethodSmartStepTarget.class) diff --git a/java/execution/impl/src/com/intellij/execution/testDiscovery/indices/TestFilesIndex.java b/java/execution/impl/src/com/intellij/execution/testDiscovery/indices/TestFilesIndex.java index ad96c0b44db2..8158d3d34cfe 100644 --- a/java/execution/impl/src/com/intellij/execution/testDiscovery/indices/TestFilesIndex.java +++ b/java/execution/impl/src/com/intellij/execution/testDiscovery/indices/TestFilesIndex.java @@ -38,7 +38,7 @@ public class TestFilesIndex extends MapReduceIndex { @Nullable Collection getTestDataFor(int testId) throws IOException { ForwardIndex forwardIndex = getForwardIndexMap(); - KeyCollectionForwardIndexAccessor forwardIndexAccessor = (KeyCollectionForwardIndexAccessor)getForwardIndexAccessor(); + KeyCollectionForwardIndexAccessor forwardIndexAccessor = (KeyCollectionForwardIndexAccessor)getForwardIndexAccessor(); return forwardIndexAccessor.deserializeData(forwardIndex.get(testId)); } diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.java index e0fefcf09d6e..465798769829 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.java +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTemplateList.java @@ -29,11 +29,11 @@ import com.intellij.ui.components.JBList; import com.intellij.ui.popup.list.GroupedItemsListRenderer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.JBUI; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import javax.swing.*; +import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.util.Collections; @@ -55,7 +55,7 @@ public class ProjectTemplateList extends JPanel { add(myPanel, BorderLayout.CENTER); GroupedItemsListRenderer renderer = new GroupedItemsListRenderer(new ListItemDescriptorAdapter() { - @NotNull + @Nullable @Override public String getTextFor(ProjectTemplate value) { return value.getName(); @@ -80,7 +80,12 @@ public class ProjectTemplateList extends JPanel { } }; myList.setCellRenderer(renderer); - myList.getSelectionModel().addListSelectionListener(__ -> updateSelection()); + myList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + updateSelection(); + } + }); Messages.installHyperlinkSupport(myDescriptionPane); } @@ -99,7 +104,7 @@ public class ProjectTemplateList extends JPanel { } } - public void setTemplates(List list, boolean preserveSelection) { + public void setTemplates(List list, boolean preserveSelection) { Collections.sort(list, (o1, o2) -> Comparing.compare(o1 instanceof ArchivedProjectTemplate, o2 instanceof ArchivedProjectTemplate)); int index = preserveSelection ? myList.getSelectedIndex() : -1; @@ -137,10 +142,13 @@ public class ProjectTemplateList extends JPanel { myList.setSelectedValue(template, true); } } - myList.getSelectionModel().addListSelectionListener(__ -> { - ProjectTemplate template = getSelectedTemplate(); - if (template != null) { - PropertiesComponent.getInstance().setValue(PROJECT_WIZARD_TEMPLATE, template.getName()); + myList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + ProjectTemplate template = getSelectedTemplate(); + if (template != null) { + PropertiesComponent.getInstance().setValue(PROJECT_WIZARD_TEMPLATE, template.getName()); + } } }); } @@ -158,7 +166,7 @@ public class ProjectTemplateList extends JPanel { } @TestOnly - boolean setSelectedTemplate(@NotNull String name) { + public boolean setSelectedTemplate(String name) { ListModel model1 = myList.getModel(); for (int j = 0; j < model1.getSize(); j++) { if (name.equals(((ProjectTemplate)model1.getElementAt(j)).getName())) { diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java index b0a6de73fd35..587722001237 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java @@ -54,6 +54,8 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; import java.awt.*; import java.net.URL; import java.util.HashMap; @@ -68,9 +70,9 @@ import java.util.*; public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, Disposable { private static final Logger LOG = Logger.getInstance(ProjectTypeStep.class); - private static final Convertor PROVIDER_STRING_CONVERTOR = + public static final Convertor PROVIDER_STRING_CONVERTOR = o -> o.getId(); - private static final Function NODE_STRING_FUNCTION = FrameworkSupportNodeBase::getId; + public static final Function NODE_STRING_FUNCTION = FrameworkSupportNodeBase::getId; private static final String TEMPLATES_CARD = "templates card"; private static final String FRAMEWORKS_CARD = "frameworks card"; private static final String PROJECT_WIZARD_GROUP = "project.wizard.group"; @@ -104,7 +106,12 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D myProjectTypeList.setModel(new CollectionListModel<>(groups)); myProjectTypeList.setSelectionModel(new SingleSelectionModel()); - myProjectTypeList.addListSelectionListener(__ -> updateSelection()); + myProjectTypeList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + updateSelection(); + } + }); myProjectTypeList.setCellRenderer(new GroupedItemsListRenderer(new ListItemDescriptorAdapter() { @Nullable @Override @@ -180,9 +187,19 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D } }; - myProjectTypeList.getSelectionModel().addListSelectionListener(__ -> projectTypeChanged()); + myProjectTypeList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + projectTypeChanged(); + } + }); - myTemplatesList.addListSelectionListener(__ -> updateSelection()); + myTemplatesList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + updateSelection(); + } + }); for (TemplatesGroup templatesGroup : myTemplatesMap.keySet()) { ModuleBuilder builder = templatesGroup.getModuleBuilder(); @@ -222,7 +239,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D return ContainerUtil.intersects(Arrays.asList(roles), acceptable); } - private static MultiMap getTemplatesMap(WizardContext context) { + public static MultiMap getTemplatesMap(WizardContext context) { ProjectTemplatesFactory[] factories = ProjectTemplatesFactory.EP_NAME.getExtensions(); final MultiMap groups = new MultiMap<>(); for (ProjectTemplatesFactory factory : factories) { @@ -334,7 +351,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D } // new TemplatesGroup selected - private void projectTypeChanged() { + public void projectTypeChanged() { TemplatesGroup group = getSelectedGroup(); if (group == null || group == myLastSelectedGroup) return; myLastSelectedGroup = group; @@ -414,7 +431,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D showCard(TEMPLATES_CARD); } - private void setTemplatesList(TemplatesGroup group, Collection templates, boolean preserveSelection) { + private void setTemplatesList(TemplatesGroup group, Collection templates, boolean preserveSelection) { List list = new ArrayList<>(templates); ModuleBuilder moduleBuilder = group.getModuleBuilder(); if (moduleBuilder != null && !(moduleBuilder instanceof TemplateModuleBuilder)) { @@ -446,7 +463,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D } @Nullable - private ProjectTemplate getSelectedTemplate() { + public ProjectTemplate getSelectedTemplate() { return myCurrentCard == TEMPLATES_CARD ? myTemplatesList.getSelectedTemplate() : null; } diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/UIRootConfigurationAccessor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/UIRootConfigurationAccessor.java index f6e038178ef9..f6e38b3d0a93 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/UIRootConfigurationAccessor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/UIRootConfigurationAccessor.java @@ -77,12 +77,14 @@ public class UIRootConfigurationAccessor extends RootConfigurationAccessor { @Override @Nullable public String getProjectSdkName(final Project project) { + final String projectJdkName = ProjectRootManager.getInstance(project).getProjectSdkName(); final Sdk projectJdk = getProjectSdk(project); if (projectJdk != null) { return projectJdk.getName(); } - final String projectJdkName = ProjectRootManager.getInstance(project).getProjectSdkName(); - final ProjectSdksModel projectJdksModel = ProjectStructureConfigurable.getInstance(project).getProjectJdksModel(); - return projectJdkName != null && projectJdksModel.findSdk(projectJdkName) == null ? projectJdkName : null; + else { + final ProjectSdksModel projectJdksModel = ProjectStructureConfigurable.getInstance(project).getProjectJdksModel(); + return projectJdksModel.findSdk(projectJdkName) == null ? projectJdkName : null; + } } } diff --git a/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java index cf95264bd20b..95efcaacb7f4 100644 --- a/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java +++ b/java/idea-ui/src/com/intellij/platform/templates/RemoteTemplatesFactory.java @@ -17,7 +17,6 @@ import com.intellij.util.NullableFunction; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.util.io.HttpRequests; -import org.intellij.lang.annotations.Language; import org.jdom.Element; import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; @@ -75,7 +74,7 @@ public class RemoteTemplatesFactory extends ProjectTemplatesFactory { @NotNull @TestOnly - public static MultiMap createFromText(@NotNull @Language("XML") String value) throws IOException, JDOMException { + public static MultiMap createFromText(@NotNull String value) throws IOException, JDOMException { return create(JDOMUtil.load(value)); } diff --git a/java/idea-ui/testSrc/com/intellij/ide/projectWizard/RemoteTemplatesTest.java b/java/idea-ui/testSrc/com/intellij/ide/projectWizard/RemoteTemplatesTest.java index a7a215254843..74d08af7eae8 100644 --- a/java/idea-ui/testSrc/com/intellij/ide/projectWizard/RemoteTemplatesTest.java +++ b/java/idea-ui/testSrc/com/intellij/ide/projectWizard/RemoteTemplatesTest.java @@ -19,25 +19,24 @@ import com.intellij.util.containers.MultiMap; */ public class RemoteTemplatesTest extends NewProjectWizardTestCase { public void testParsing() throws Exception { - MultiMap map = RemoteTemplatesFactory.createFromText( - "\n" + - " \n" + - " \n" + - ""); + MultiMap map = RemoteTemplatesFactory.createFromText("\n" + + " \n" + + " \n" + + ""); assertEquals(1, map.size()); ProjectTemplate facelets = map.values().iterator().next(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java index e407ca42b7e5..f5d1902c52d1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java @@ -65,7 +65,7 @@ public class AnnotateMethodFix implements LocalQuickFix { @Override public boolean startInWriteAction() { - return !annotateOverriddenMethods(); + return false; } @Override diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingDfaMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingDfaMemoryState.java index ac9b3667d3c5..c896c5bfc981 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingDfaMemoryState.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingDfaMemoryState.java @@ -7,11 +7,8 @@ import com.intellij.codeInspection.dataFlow.instructions.Instruction; import com.intellij.codeInspection.dataFlow.value.*; import com.intellij.codeInspection.dataFlow.value.DfaRelationValue.RelationType; import com.intellij.openapi.util.Pair; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ObjectUtils; -import com.siyeh.ig.psiutils.ExpressionUtils; import one.util.streamex.EntryStream; import one.util.streamex.StreamEx; import org.jetbrains.annotations.Contract; @@ -247,20 +244,6 @@ public class TrackingDfaMemoryState extends DfaMemoryStateImpl { return findChange(change -> change.getExpression() == expression, false); } - @Contract("null -> null") - @Nullable - MemoryStateChange findSubExpressionPush(@Nullable PsiExpression expression) { - if (expression == null) return null; - PsiElement topElement = ExpressionUtils.getPassThroughParent(expression); - return findChange(change -> { - PsiExpression changeExpression = change.getExpression(); - if (changeExpression == null) return false; - return changeExpression == expression || - (PsiTreeUtil.isAncestor(expression, changeExpression, true) && - ExpressionUtils.getPassThroughParent(changeExpression) == topElement); - }, false); - } - MemoryStateChange findRelation(DfaVariableValue value, @NotNull Predicate relationPredicate, boolean startFromSelf) { return findChange(change -> { Change varChange = change.myChanges.get(value); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java index 127e89f6a22c..e83126b62b61 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/TrackingRunner.java @@ -9,7 +9,6 @@ import com.intellij.codeInspection.dataFlow.instructions.*; import com.intellij.codeInspection.dataFlow.rangeSet.LongRangeSet; import com.intellij.codeInspection.dataFlow.value.*; import com.intellij.codeInspection.dataFlow.value.DfaRelationValue.RelationType; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Document; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.Pair; @@ -17,8 +16,6 @@ import com.intellij.openapi.util.Segment; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.impl.source.tree.ChildRole; -import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiUtil; import com.intellij.util.ArrayUtil; @@ -27,7 +24,6 @@ import com.intellij.util.containers.ContainerUtil; import com.siyeh.ig.psiutils.BoolUtils; import com.siyeh.ig.psiutils.ExpressionUtils; import one.util.streamex.StreamEx; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -337,10 +333,9 @@ public class TrackingRunner extends StandardDataFlowRunner { Warning caused by narrowing conversion Warning caused by unary minus Warning caused by final field initializer - Literal is not-null - TODO: 3. Check how it works with: + TODO: 3. Check how it works with Inliners (notably: Stream API) - Boxed numbers + Ternary operators TODO: 4. Check for possible performance disasters (likely on some code patterns current algo might blow up) TODO: 5. Problem when interesting state doesn't reach the current condition, need to do something with this */ @@ -375,8 +370,8 @@ public class TrackingRunner extends StandardDataFlowRunner { Instruction instruction = change.myInstruction; if (instruction instanceof AssignInstruction && change.myTopOfStack == value) { PsiExpression rValue = ((AssignInstruction)instruction).getRExpression(); - CauseItem item = createAssignmentCause((AssignInstruction)instruction, value); - MemoryStateChange push = change.findSubExpressionPush(rValue); + CauseItem item = new CauseItem("'" + value + "' was assigned", rValue); + MemoryStateChange push = change.findExpressionPush(rValue); if (push != null) { item.addChildren(findConstantValueCause(rValue, push, expectedValue)); } @@ -390,29 +385,6 @@ public class TrackingRunner extends StandardDataFlowRunner { return new CauseItem[0]; } - @NotNull - @Contract("_, _ -> new") - private static CauseItem createAssignmentCause(AssignInstruction instruction, DfaValue target) { - PsiExpression rExpression = instruction.getRExpression(); - PsiElement anchor = null; - if (rExpression != null) { - PsiElement parent = PsiUtil.skipParenthesizedExprUp(rExpression.getParent()); - if (parent instanceof PsiAssignmentExpression) { - anchor = ((PsiAssignmentExpression)parent).getOperationSign(); - } - else if (parent instanceof PsiVariable) { - ASTNode node = parent.getNode(); - if (node instanceof CompositeElement) { - anchor = ((CompositeElement)node).findChildByRoleAsPsiElement(ChildRole.INITIALIZER_EQ); - } - } - if (anchor == null) { - anchor = rExpression; - } - } - return new CauseItem("'" + target + "' was assigned", anchor); - } - private static CauseItem[] findBooleanResultCauses(PsiExpression expression, MemoryStateChange history, boolean value) { @@ -606,17 +578,17 @@ public class TrackingRunner extends StandardDataFlowRunner { } if (instruction instanceof AssignInstruction) { DfaValue target = change.myTopOfStack; - PsiExpression rValue = ((AssignInstruction)instruction).getRExpression(); - CauseItem item = createAssignmentCause((AssignInstruction)instruction, target); + PsiExpression rValue = PsiUtil.skipParenthesizedExprDown(((AssignInstruction)instruction).getRExpression()); if (target == value) { - MemoryStateChange rValuePush = change.findSubExpressionPush(rValue); + CauseItem item = new CauseItem("'" + target + "' was assigned", rValue); + MemoryStateChange rValuePush = change.findExpressionPush(rValue); if (rValuePush != null) { item.addChildren(findRelationCause(relation.myRelationType, rValuePush, counterPartChange)); } return item; } if (target == relation.myCounterpart) { - return item; + return new CauseItem("'" + target + "' was assigned", rValue); } } PsiExpression expression = change.getExpression(); @@ -645,11 +617,14 @@ public class TrackingRunner extends StandardDataFlowRunner { if (factDef != null && expression != null) { DfaValue value = factUse.myTopOfStack; if (factDef.myInstruction instanceof AssignInstruction && factDef.myTopOfStack == value) { - PsiExpression rExpression = ((AssignInstruction)factDef.myInstruction).getRExpression(); + PsiExpression rExpression = PsiUtil.skipParenthesizedExprDown(((AssignInstruction)factDef.myInstruction).getRExpression()); + while (rExpression instanceof PsiTypeCastExpression) { + rExpression = PsiUtil.skipParenthesizedExprDown(((PsiTypeCastExpression)rExpression).getOperand()); + } if (rExpression != null) { - MemoryStateChange rValuePush = factDef.findSubExpressionPush(rExpression); + MemoryStateChange rValuePush = factDef.findExpressionPush(rExpression); if (rValuePush != null) { - CauseItem assignmentItem = createAssignmentCause((AssignInstruction)factDef.myInstruction, value); + CauseItem assignmentItem = new CauseItem("'" + value + "' was assigned", rExpression); Pair rValueFact = rValuePush.findFact(rValuePush.myTopOfStack, DfaFactType.NULLABILITY); assignmentItem.addChildren(findNullabilityCause(rValuePush, rValueFact.first, nullability)); return assignmentItem; @@ -661,12 +636,6 @@ public class TrackingRunner extends StandardDataFlowRunner { return new CauseItem("'" + expression.getText() + "' is known to be '" + nullability.getPresentationName() + "' from #ref", defExpression); } } - if (expression instanceof PsiTypeCastExpression) { - MemoryStateChange operandPush = factUse.findSubExpressionPush(((PsiTypeCastExpression)expression).getOperand()); - if (operandPush != null) { - return findNullabilityCause(operandPush, factDef, nullability); - } - } if (expression instanceof PsiMethodCallExpression) { PsiMethodCallExpression call = (PsiMethodCallExpression)expression; PsiMethod method = call.resolveMethod(); @@ -822,11 +791,11 @@ public class TrackingRunner extends StandardDataFlowRunner { CauseItem item = new CauseItem(String.format(template, rangeText), factUse); if (factDef != null) { if (factDef.myInstruction instanceof AssignInstruction && factDef.myTopOfStack == value) { - PsiExpression rExpression = ((AssignInstruction)factDef.myInstruction).getRExpression(); + PsiExpression rExpression = PsiUtil.skipParenthesizedExprDown(((AssignInstruction)factDef.myInstruction).getRExpression()); if (rExpression != null) { - MemoryStateChange rValuePush = factDef.findSubExpressionPush(rExpression); + MemoryStateChange rValuePush = factDef.findExpressionPush(rExpression); if (rValuePush != null) { - CauseItem assignmentItem = createAssignmentCause((AssignInstruction)factDef.myInstruction, value); + CauseItem assignmentItem = new CauseItem("'" + value + "' was assigned", rExpression); Pair rValueFact = rValuePush.findFact(rValuePush.myTopOfStack, DfaFactType.RANGE); assignmentItem.addChildren(findRangeCause(rValuePush, rValueFact.first, range, "Value is %s")); item.addChildren(assignmentItem); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkingTimeMeasurer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java similarity index 56% rename from plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkingTimeMeasurer.java rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java index bdb795995bb0..b0c4f1808779 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkingTimeMeasurer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java @@ -1,5 +1,19 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.plugins.groovy.lang.psi.dataFlow; +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInspection.dataFlow; import org.jetbrains.annotations.Nullable; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java index e4245aedb290..f8c6df99fa65 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java @@ -550,19 +550,21 @@ public class RefJavaManagerImpl extends RefJavaManager { //TODO support suppressions by comment tag in kotlin private void processComments(@NotNull UElement node) { for (UComment comment : node.getComments()) { - PsiElement psi = comment.getSourcePsi(); - if (psi instanceof PsiDocComment) { - final PsiDocTag[] tags = ((PsiDocComment)psi).getTags(); - for (PsiDocTag tag : tags) { - if (Comparing.strEqual(tag.getName(), SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME)) { - final PsiElement[] dataElements = tag.getDataElements(); - if (dataElements.length > 0) { - final PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(psi, PsiModifierListOwner.class); - if (listOwner != null) { - final WritableRefElement element = (WritableRefElement)myRefManager.getReference(listOwner); - if (element != null) { - String suppression = StringUtil.join(dataElements, PsiElement::getText, ","); - element.addSuppression(suppression); + if (comment instanceof UComment) { + PsiElement psi = comment.getSourcePsi(); + if (psi instanceof PsiDocComment) { + final PsiDocTag[] tags = ((PsiDocComment)psi).getTags(); + for (PsiDocTag tag : tags) { + if (Comparing.strEqual(tag.getName(), SuppressionUtilCore.SUPPRESS_INSPECTIONS_TAG_NAME)) { + final PsiElement[] dataElements = tag.getDataElements(); + if (dataElements.length > 0) { + final PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(psi, PsiModifierListOwner.class); + if (listOwner != null) { + final WritableRefElement element = (WritableRefElement)myRefManager.getReference(listOwner); + if (element != null) { + String suppression = StringUtil.join(dataElements, PsiElement::getText, ","); + element.addSuppression(suppression); + } } } } diff --git a/java/java-impl/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java index 807c25dc7ea8..0096c12ebe6e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java +++ b/java/java-impl/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java @@ -240,10 +240,8 @@ public class NullableNotNullManagerImpl extends NullableNotNullManager implement if (container instanceof PsiPackage) { PsiFile file = annotation.getContainingFile(); ProjectFileIndex index = ProjectRootManager.getInstance(file.getProject()).getFileIndex(); - VirtualFile annotationFile = file.getVirtualFile(); - VirtualFile annotationRoot = annotationFile == null ? null : index.getClassRootForFile(annotationFile); - VirtualFile ownerFile = owner.getContainingFile().getVirtualFile(); - VirtualFile ownerRoot = ownerFile == null ? null : index.getClassRootForFile(ownerFile); + VirtualFile annotationRoot = index.getClassRootForFile(file.getVirtualFile()); + VirtualFile ownerRoot = index.getClassRootForFile(owner.getContainingFile().getVirtualFile()); if (ownerRoot != null && !ownerRoot.equals(annotationRoot)) { continue; } diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/fix/FindDfaProblemCauseFix.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/fix/FindDfaProblemCauseFix.java index c8a185c6e684..332648d6cb94 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/fix/FindDfaProblemCauseFix.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/fix/FindDfaProblemCauseFix.java @@ -147,7 +147,7 @@ public class FindDfaProblemCauseFix implements LocalQuickFix, LowPriorityAction highlighter.getAndSet(null).dropHighlight(); } }) - .setItemChosenCallback(cause -> navigate(editor, file, cause.myCauseItem)) + .setItemChosenCallback(cause -> ReadAction.run(() -> navigate(editor, file, cause.myCauseItem))) .createPopup(); popup.showInBestPositionFor(editor); } diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java index d0e29c8b26ae..937a159d39df 100644 --- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java +++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultClassNavigationContributor.java @@ -20,6 +20,7 @@ import com.intellij.lang.java.JavaLanguage; import com.intellij.navigation.ChooseByNameContributorEx; import com.intellij.navigation.GotoClassContributor; import com.intellij.navigation.NavigationItem; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; @@ -29,15 +30,41 @@ import com.intellij.psi.presentation.java.SymbolPresentationUtil; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.psi.util.ClassUtil; +import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; +import com.intellij.util.Processors; import com.intellij.util.indexing.FindSymbolParameters; import com.intellij.util.indexing.IdFilter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Matcher; public class DefaultClassNavigationContributor implements ChooseByNameContributorEx, GotoClassContributor { + @Override + @NotNull + public String[] getNames(Project project, boolean includeNonProjectItems) { + GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project); + List result = new ArrayList<>(); + Processor processor = Processors.cancelableCollectProcessor(result); + + processNames(processor, scope, IdFilter.getProjectIdFilter(project, includeNonProjectItems)); + + return ArrayUtil.toStringArray(result); + } + + @Override + @NotNull + public NavigationItem[] getItemsByName(String name, final String pattern, Project project, boolean includeNonProjectItems) { + List result = new ArrayList<>(); + Processor processor = Processors.cancelableCollectProcessor(result); + processElementsWithName(name, processor, FindSymbolParameters.wrap(pattern, project, includeNonProjectItems)); + + return result.isEmpty() ? NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY : + result.toArray(NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY); + } @Override public String getQualifiedName(final NavigationItem item) { diff --git a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java index e302d7363ed6..bba5b597d4b5 100644 --- a/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java +++ b/java/java-impl/src/com/intellij/ide/util/gotoByName/DefaultSymbolNavigationContributor.java @@ -30,13 +30,51 @@ import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Comparator; -import java.util.Iterator; -import java.util.Set; +import java.util.*; public class DefaultSymbolNavigationContributor implements ChooseByNameContributorEx, GotoClassContributor { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor"); + @Override + @NotNull + public String[] getNames(Project project, boolean includeNonProjectItems) { + PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project); + Set set = new HashSet<>(); + Collections.addAll(set, cache.getAllMethodNames()); + Collections.addAll(set, cache.getAllFieldNames()); + Collections.addAll(set, cache.getAllClassNames()); + return ArrayUtil.toStringArray(set); + } + + @Override + @NotNull + public NavigationItem[] getItemsByName(String name, final String pattern, Project project, boolean includeNonProjectItems) { + GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project); + PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project); + + Condition qualifiedMatcher = getQualifiedNameMatcher(pattern); + + List result = new ArrayList<>(); + for (PsiMethod method : cache.getMethodsByName(name, scope)) { + if (!method.isConstructor() && isOpenable(method) && !hasSuperMethod(method, scope, qualifiedMatcher, pattern)) { + result.add(method); + } + } + for (PsiField field : cache.getFieldsByName(name, scope)) { + if (isOpenable(field)) { + result.add(field); + } + } + for (PsiClass aClass : cache.getClassesByName(name, scope)) { + if (isOpenable(aClass)) { + result.add(aClass); + } + } + PsiMember[] array = result.toArray(PsiMember.EMPTY_ARRAY); + Arrays.sort(array, MyComparator.INSTANCE); + return array; + } + @Nullable @Override public String getQualifiedName(NavigationItem item) { diff --git a/java/java-impl/src/com/intellij/lang/java/actions/RangeExpression.kt b/java/java-impl/src/com/intellij/lang/java/actions/RangeExpression.kt index 89e4119bd8b2..996b598b53c7 100644 --- a/java/java-impl/src/com/intellij/lang/java/actions/RangeExpression.kt +++ b/java/java-impl/src/com/intellij/lang/java/actions/RangeExpression.kt @@ -29,5 +29,7 @@ internal class RangeExpression( override fun calculateQuickResult(context: ExpressionContext): Result? = calculateResult(context) + override fun requiresCommittedPSI(): Boolean = false + override fun calculateLookupItems(context: ExpressionContext): Array = LookupElement.EMPTY_ARRAY } diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/AndChainCause.java b/java/java-tests/testData/inspection/dataFlow/tracker/AndChainCause.java index 3d069abcaf51..049802081148 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/AndChainCause.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/AndChainCause.java @@ -2,7 +2,7 @@ Value is always false (x > 6 && y > 10) Operand #1 of &&-chain is false (x > 6) Left operand is 5 (x) - 'x' was assigned (=) + 'x' was assigned (5) */ class Test { diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/AssignTernaryNotNull.java b/java/java-tests/testData/inspection/dataFlow/tracker/AssignTernaryNotNull.java deleted file mode 100644 index c1714d2564cc..000000000000 --- a/java/java-tests/testData/inspection/dataFlow/tracker/AssignTernaryNotNull.java +++ /dev/null @@ -1,19 +0,0 @@ -/* -Value is always false (foo == null) - 'foo' was assigned (=) - One of the following happens: - Expression cannot be null as it's newly created object (new String("foo")) - or expression cannot be null as it's newly created object (new String("bar")) - */ - -import org.jetbrains.annotations.Nullable; - -class Test { - - void test(boolean b) { - String foo = b ? new String("foo") : new String("bar"); - if (foo == null) { - - } - } -} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/AssignTernaryNumeric.java b/java/java-tests/testData/inspection/dataFlow/tracker/AssignTernaryNumeric.java deleted file mode 100644 index 70f6d8cb7c0c..000000000000 --- a/java/java-tests/testData/inspection/dataFlow/tracker/AssignTernaryNumeric.java +++ /dev/null @@ -1,20 +0,0 @@ -/* -Value is always false (foo > 3) - One of the following happens: - Left operand is 1 (foo) - 'foo' was assigned (=) - or left operand is 2 (foo) - 'foo' was assigned (=) - */ - -import org.jetbrains.annotations.Nullable; - -class Test { - - void test(boolean b) { - int foo = b ? 1 : 2; - if (foo > 3) { - - } - } -} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/AssignTrue.java b/java/java-tests/testData/inspection/dataFlow/tracker/AssignTrue.java index 66e86679428a..aeda8421d734 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/AssignTrue.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/AssignTrue.java @@ -1,6 +1,6 @@ /* Value is always true (b) - 'b' was assigned (=) + 'b' was assigned (true) */ class Test { diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/AssignmentChain.java b/java/java-tests/testData/inspection/dataFlow/tracker/AssignmentChain.java index 10f926616c2c..c0e285d885f5 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/AssignmentChain.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/AssignmentChain.java @@ -1,6 +1,6 @@ /* Value is always false (s == null) - 's' was assigned (=) + 's' was assigned (s1) Condition 's1 != null' was checked before (s1 == null) */ class Test { diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/BooleanReassignedMultipleTimes.java b/java/java-tests/testData/inspection/dataFlow/tracker/BooleanReassignedMultipleTimes.java index 2e1873057cc1..d8c52295a223 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/BooleanReassignedMultipleTimes.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/BooleanReassignedMultipleTimes.java @@ -1,9 +1,9 @@ /* Value is always false (b4) - 'b4' was assigned (=) - 'b3' was assigned (=) - 'b2' was assigned (=) - 'b1' was assigned (=) + 'b4' was assigned (b3) + 'b3' was assigned (b2) + 'b2' was assigned (b1) + 'b1' was assigned (b) 'b == false' was established from condition (b) */ import org.jetbrains.annotations.NotNull; diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/IfBothNotNull.java b/java/java-tests/testData/inspection/dataFlow/tracker/IfBothNotNull.java index d98c29b51121..5c50466df0ae 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/IfBothNotNull.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/IfBothNotNull.java @@ -1,9 +1,9 @@ /* Value is always false (x == null) One of the following happens: - 'x' was assigned (=) + 'x' was assigned (new Object()) Expression cannot be null as it's newly created object (new Object()) - or 'x' was assigned (=) + or 'x' was assigned ("foo") Expression cannot be null as it's literal ("foo") */ diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/IfBothNotNullReassign.java b/java/java-tests/testData/inspection/dataFlow/tracker/IfBothNotNullReassign.java index a8600713f5be..4ec0164c1e60 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/IfBothNotNullReassign.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/IfBothNotNullReassign.java @@ -1,10 +1,10 @@ /* Value is always false (y == null) - 'y' was assigned (=) + 'y' was assigned (x) One of the following happens: - 'x' was assigned (=) + 'x' was assigned (new Object()) Expression cannot be null as it's newly created object (new Object()) - or 'x' was assigned (=) + or 'x' was assigned ("foo") Expression cannot be null as it's literal ("foo") */ diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/IndexOfPlusOne.java b/java/java-tests/testData/inspection/dataFlow/tracker/IndexOfPlusOne.java index cf76c452591e..723134684363 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/IndexOfPlusOne.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/IndexOfPlusOne.java @@ -1,10 +1,10 @@ /* Value is always true (j >= 0) Left operand is >= 0 (j) - 'j' was assigned (=) + 'j' was assigned (i + 1) Result of '+' is >= 0 (i + 1) Left operand is in {-1..Integer.MAX_VALUE-1} (i) - 'i' was assigned (=) + 'i' was assigned (s.indexOf(' ')) Value is in {-1..Integer.MAX_VALUE-1} (s.indexOf(' ')) */ diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/NotNullAnnotated.java b/java/java-tests/testData/inspection/dataFlow/tracker/NotNullAnnotated.java index fd9dc371bc76..3068cea4665e 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/NotNullAnnotated.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/NotNullAnnotated.java @@ -1,6 +1,6 @@ /* Value is always false (s1 == null) - 's1' was assigned (=) + 's1' was assigned (s.trim()) Method 'trim' is externally annotated as 'non-null' (trim) */ class Test { diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/NotNullAssignmentInside.java b/java/java-tests/testData/inspection/dataFlow/tracker/NotNullAssignmentInside.java index 33911032b225..dfd2f8826c6f 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/NotNullAssignmentInside.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/NotNullAssignmentInside.java @@ -1,6 +1,6 @@ /* Value is always true ((s = new Object()) != null) - 's' was assigned (=) + 's' was assigned (new Object()) Expression cannot be null as it's newly created object (new Object()) */ diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/NotNullObvious.java b/java/java-tests/testData/inspection/dataFlow/tracker/NotNullObvious.java index 0d91a307f444..f04337b8c62b 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/NotNullObvious.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/NotNullObvious.java @@ -1,6 +1,6 @@ /* Value is always true (s != null) - 's' was assigned (=) + 's' was assigned (new Object()) Expression cannot be null as it's newly created object (new Object()) */ diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/NotNullParameterAssigned.java b/java/java-tests/testData/inspection/dataFlow/tracker/NotNullParameterAssigned.java index 2bf593da57fc..93672617a45c 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/NotNullParameterAssigned.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/NotNullParameterAssigned.java @@ -1,6 +1,6 @@ /* Value is always true (null == s) - 's' was assigned (=) + 's' was assigned (null) */ import org.jetbrains.annotations.NotNull; diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/NpeAnnotation.java b/java/java-tests/testData/inspection/dataFlow/tracker/NpeAnnotation.java index 8c3b99bf7971..959ae680bb56 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/NpeAnnotation.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/NpeAnnotation.java @@ -1,6 +1,6 @@ /* May be null (s) - 's' was assigned (=) + 's' was assigned (loadString()) Method 'loadString' is annotated as 'nullable' (@Nullable) */ diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/NpeWithCast.java b/java/java-tests/testData/inspection/dataFlow/tracker/NpeWithCast.java index bcbea75779a7..0b29d755e77b 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/NpeWithCast.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/NpeWithCast.java @@ -1,6 +1,6 @@ /* May be null (foo) - 'foo' was assigned (=) + 'foo' was assigned (getFoo()) Method 'getFoo' is annotated as 'nullable' (@Nullable) */ diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/NullWasCheckedNullAssigned.java b/java/java-tests/testData/inspection/dataFlow/tracker/NullWasCheckedNullAssigned.java index 85422b9cf437..591e81dca8be 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/NullWasCheckedNullAssigned.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/NullWasCheckedNullAssigned.java @@ -1,6 +1,6 @@ /* Value is always false (s == s1) - 's1' was assigned (=) + 's1' was assigned (null) and condition 's != null' was checked before (null == s) */ class Test { diff --git a/java/java-tests/testData/inspection/dataFlow/tracker/OrChainCause.java b/java/java-tests/testData/inspection/dataFlow/tracker/OrChainCause.java index 593ef0c5b6a8..f69840cc093c 100644 --- a/java/java-tests/testData/inspection/dataFlow/tracker/OrChainCause.java +++ b/java/java-tests/testData/inspection/dataFlow/tracker/OrChainCause.java @@ -6,14 +6,14 @@ Value is always true (x || (a+b)+(c+d)==10) Result of '+' is 10 ((a+b)+(c+d)) Result of '+' is 3 (a+b) Left operand is 1 (a) - 'a' was assigned (=) + 'a' was assigned (1) and right operand is 2 (b) - 'b' was assigned (=) + 'b' was assigned (2) and result of '+' is 7 (c+d) Left operand is 3 (c) - 'c' was assigned (=) + 'c' was assigned (3) and right operand is 4 (d) - 'd' was assigned (=) + 'd' was assigned (4) */ class Test { diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java index ecd2335e9557..e6a5170a1421 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DataFlowInspectionTrackerTest.java @@ -149,6 +149,4 @@ public class DataFlowInspectionTrackerTest extends LightCodeInsightFixtureTestCa public void testNpeSimple() { doTest(); } public void testNpeAnnotation() { doTest(); } public void testNpeWithCast() { doTest(); } - public void testAssignTernaryNotNull() { doTest(); } - public void testAssignTernaryNumeric() { doTest(); } } diff --git a/java/java-tests/testSrc/com/intellij/openapi/command/undo/EditorTypingAndNavigationUndoTest.java b/java/java-tests/testSrc/com/intellij/openapi/command/undo/EditorTypingAndNavigationUndoTest.java index 6aad98050964..2a5767fb341b 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/command/undo/EditorTypingAndNavigationUndoTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/command/undo/EditorTypingAndNavigationUndoTest.java @@ -287,7 +287,7 @@ public class EditorTypingAndNavigationUndoTest extends EditorUndoTestCase { Ref message = new Ref<>(); Messages.setTestDialog(new TestDialog() { @Override - public int show(@NotNull String m) { + public int show(String m) { message.set(m); return Messages.YES; } diff --git a/java/java-tests/testSrc/com/intellij/openapi/command/undo/GlobalUndoTest.java b/java/java-tests/testSrc/com/intellij/openapi/command/undo/GlobalUndoTest.java index f59aa28e0520..3683c8ff0553 100644 --- a/java/java-tests/testSrc/com/intellij/openapi/command/undo/GlobalUndoTest.java +++ b/java/java-tests/testSrc/com/intellij/openapi/command/undo/GlobalUndoTest.java @@ -78,7 +78,7 @@ public class GlobalUndoTest extends UndoTestCase implements TestDialog { } @Override - public int show(@NotNull String message) { + public int show(String message) { myConfirmationWasRequested = true; return 0; } diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java index 08584124d808..75980c93b05f 100644 --- a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java +++ b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java @@ -127,18 +127,18 @@ public abstract class ProjectWizardTestCase ext return createModuleFromWizard(project); } - private Module createModuleFromWizard(@NotNull Project project) { + protected Module createModuleFromWizard(@NotNull Project project) { return new NewModuleAction().createModuleFromWizard(project, null, myWizard); } - private void runWizard(@NotNull String group, - @Nullable final String name, - @Nullable Project project, - @Nullable final Consumer adjuster) throws IOException { + protected void runWizard(@NotNull String group, + @Nullable final String name, + @Nullable Project project, + @Nullable final Consumer adjuster) throws IOException { createWizard(project); ProjectTypeStep step = (ProjectTypeStep)myWizard.getCurrentStepObject(); if (!step.setSelectedTemplate(group, name)) { - throw new IllegalArgumentException(group + '/' + name + " template not found. Available groups: " + step.availableTemplateGroupsToString()); + throw new IllegalArgumentException(group + '/' + name + " template not found, available groups " + step.availableTemplateGroupsToString()); } runWizard(step1 -> { @@ -151,7 +151,7 @@ public abstract class ProjectWizardTestCase ext }); } - private void runWizard(@Nullable Consumer adjuster) { + protected void runWizard(@Nullable Consumer adjuster) { while (true) { ModuleWizardStep currentStep = myWizard.getCurrentStepObject(); if (adjuster != null) { @@ -236,7 +236,7 @@ public abstract class ProjectWizardTestCase ext return ContainerUtil.getFirstItem(ImportModuleAction.createFromWizard(project, myWizard)); } - private static T computeInWriteSafeContext(Supplier supplier) { + private static T computeInWriteSafeContext(Supplier supplier) { Ref module = Ref.create(); ApplicationManager.getApplication().invokeLater(() -> module.set(supplier.get())); UIUtil.dispatchAllInvocationEvents(); diff --git a/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkReference.java b/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkReference.java index e7342c43c6c3..390fbdd6ca8d 100644 --- a/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkReference.java +++ b/jps/model-api/src/org/jetbrains/jps/model/library/sdk/JpsSdkReference.java @@ -15,7 +15,6 @@ */ package org.jetbrains.jps.model.library.sdk; -import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.JpsElementReference; import org.jetbrains.jps.model.library.JpsTypedLibrary; @@ -24,6 +23,5 @@ import org.jetbrains.jps.model.library.JpsTypedLibrary; * @author nik */ public interface JpsSdkReference

extends JpsElementReference>> { - @NotNull String getSdkName(); } diff --git a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java index 9a5e9207ef94..3822a0d9128b 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/impl/JpsNamedElementReferenceBase.java @@ -30,7 +30,6 @@ public abstract class JpsNamedElementReferenceBase implements JpsElementReference { private static final JpsElementChildRole> PARENT_REFERENCE_ROLE = JpsElementChildRoleBase .create("parent"); - @NotNull protected final String myElementName; protected JpsNamedElementReferenceBase(@NotNull String elementName, @NotNull JpsElementReference parentReference) { diff --git a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsWrappedJavaSdkReferenceImpl.java b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsWrappedJavaSdkReferenceImpl.java index a9fcd9c57aa6..fdc678f7b820 100644 --- a/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsWrappedJavaSdkReferenceImpl.java +++ b/jps/model-impl/src/org/jetbrains/jps/model/java/impl/JpsWrappedJavaSdkReferenceImpl.java @@ -53,7 +53,6 @@ public class JpsWrappedJavaSdkReferenceImpl extends JpsCompositeElementBase> sdk = resolve(); diff --git a/jvm/jvm-analysis-api/src/com/intellij/codeInspection/NlsCapitalizationUtil.java b/jvm/jvm-analysis-api/src/com/intellij/codeInspection/NlsCapitalizationUtil.java deleted file mode 100644 index 187512fa000b..000000000000 --- a/jvm/jvm-analysis-api/src/com/intellij/codeInspection/NlsCapitalizationUtil.java +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.codeInspection; - -import com.intellij.openapi.util.text.StringUtil; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class NlsCapitalizationUtil { - - public static boolean isCapitalizationSatisfied(String value, Nls.Capitalization capitalization) { - if (StringUtil.isEmpty(value) || capitalization == Nls.Capitalization.NotSpecified) { - return true; - } - value = value.replace("&", ""); - return capitalization == Nls.Capitalization.Title - ? StringUtil.wordsToBeginFromUpperCase(value).equals(value) - : checkSentenceCapitalization(value); - } - - private static boolean checkSentenceCapitalization(@NotNull String value) { - List words = StringUtil.split(value, " "); - if (words.size() == 0) return true; - if (Character.isLetter(words.get(0).charAt(0)) && !isCapitalizedWord(words.get(0))) return false; - if (words.size() == 1) return true; - int capitalized = 1; - for (int i = 1, size = words.size(); i < size; i++) { - String word = words.get(i); - if (isCapitalizedWord(word)) { - // check for abbreviations like SQL or I18n - if (word.length() == 1 || !Character.isLowerCase(word.charAt(1))) { - continue; - } - capitalized++; - } - } - return capitalized / words.size() < 0.2; // allow reasonable amount of capitalized words - } - - private static boolean isCapitalizedWord(String word) { - return word.length() > 0 && Character.isLetter(word.charAt(0)) && Character.isUpperCase(word.charAt(0)); - } - - @NotNull - public static String fixValue(String string, Nls.Capitalization capitalization) { - return capitalization == Nls.Capitalization.Title - ? StringUtil.wordsToBeginFromUpperCase(string) - : StringUtil.capitalize(StringUtil.wordsToBeginFromLowerCase(string)); - } -} diff --git a/jvm/jvm-analysis-java-tests/testSrc/com/intellij/codeInspection/NlsCapitalizationUtilTest.java b/jvm/jvm-analysis-java-tests/testSrc/com/intellij/codeInspection/NlsCapitalizationUtilTest.java deleted file mode 100644 index 2856e77576c5..000000000000 --- a/jvm/jvm-analysis-java-tests/testSrc/com/intellij/codeInspection/NlsCapitalizationUtilTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2000-2019 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; - -import junit.framework.TestCase; -import org.jetbrains.annotations.Nls; - -import static com.intellij.codeInspection.NlsCapitalizationUtil.isCapitalizationSatisfied; - -public class NlsCapitalizationUtilTest extends TestCase { - - public void testCapitalization() { - assertTrue(isCapitalizationSatisfied("Fix SQL issues", Nls.Capitalization.Sentence)); - assertTrue(isCapitalizationSatisfied("Fix I18n issues", Nls.Capitalization.Sentence)); - assertTrue(isCapitalizationSatisfied("Fix C issues", Nls.Capitalization.Sentence)); - assertTrue(isCapitalizationSatisfied("@charset is invalid", Nls.Capitalization.Sentence)); - assertTrue(isCapitalizationSatisfied("Add 'this' qualifier", Nls.Capitalization.Sentence)); - assertTrue(isCapitalizationSatisfied("Add 'this' qualifier", Nls.Capitalization.Sentence)); - assertTrue(isCapitalizationSatisfied("Please select the configuration file (usually named IntelliLang.xml) to import.", - Nls.Capitalization.Sentence)); - assertFalse(isCapitalizationSatisfied("Foo Bar", Nls.Capitalization.Sentence)); - assertTrue(isCapitalizationSatisfied("Foo", Nls.Capitalization.Sentence)); - } -} \ No newline at end of file diff --git a/platform/build-scripts/icons/intellij.platform.images.build.iml b/platform/build-scripts/icons/intellij.platform.images.build.iml index e230818c12e7..ad4ea565c164 100644 --- a/platform/build-scripts/icons/intellij.platform.images.build.iml +++ b/platform/build-scripts/icons/intellij.platform.images.build.iml @@ -10,12 +10,12 @@ + - \ No newline at end of file diff --git a/platform/built-in-server/src/org/jetbrains/ide/OpenFileHttpService.kt b/platform/built-in-server/src/org/jetbrains/ide/OpenFileHttpService.kt index 2630963c3bdf..14b92be3c6ae 100644 --- a/platform/built-in-server/src/org/jetbrains/ide/OpenFileHttpService.kt +++ b/platform/built-in-server/src/org/jetbrains/ide/OpenFileHttpService.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.ide import com.intellij.ide.impl.ProjectUtil.focusProjectWindow @@ -72,7 +72,7 @@ internal class OpenFileHttpService : RestService() { val apiRequest: OpenFileRequest if (request.method() === HttpMethod.POST) { - apiRequest = gson.fromJson(createJsonReader(request), OpenFileRequest::class.java) + apiRequest = gson.value.fromJson(createJsonReader(request), OpenFileRequest::class.java) } else { apiRequest = OpenFileRequest() @@ -82,7 +82,7 @@ internal class OpenFileHttpService : RestService() { apiRequest.focused = getBooleanParameter("focused", urlDecoder, true) } - val prefixLength = 1 + PREFIX.length + 1 + getServiceName().length + 1 + val prefixLength = 1 + PREFIX.length + 1 + serviceName.length + 1 val path = urlDecoder.path() if (path.length > prefixLength) { val matcher = LINE_AND_COLUMN.matcher(path).region(prefixLength, path.length) diff --git a/platform/built-in-server/src/org/jetbrains/ide/RestService.java b/platform/built-in-server/src/org/jetbrains/ide/RestService.java new file mode 100644 index 000000000000..f2fe5613f4d5 --- /dev/null +++ b/platform/built-in-server/src/org/jetbrains/ide/RestService.java @@ -0,0 +1,309 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.ide; + +import com.google.common.base.Supplier; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonWriter; +import com.google.gson.stream.MalformedJsonException; +import com.intellij.ide.IdeBundle; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.NotNullLazyValue; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; +import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.util.text.StringUtilRt; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.IdeFrame; +import com.intellij.ui.AppIcon; +import com.intellij.util.ExceptionUtil; +import com.intellij.util.ObjectUtils; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.io.NettyKt; +import com.intellij.util.net.NetUtils; +import io.netty.buffer.ByteBufInputStream; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.http.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.builtInWebServer.BuiltInWebServerKt; +import org.jetbrains.io.Responses; + +import javax.swing.*; +import java.awt.*; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.lang.reflect.InvocationTargetException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static com.intellij.ide.impl.ProjectUtil.showYesNoDialog; + +/** + * Document your service using apiDoc. To extract big example from source code, consider to use *.coffee file near your source file. + * (or Python/Ruby, but coffee recommended because it's plugin is lightweight). See {@link AboutHttpService} for example. + * + * Don't create JsonReader/JsonWriter directly, use only provided {@link #createJsonReader}, {@link #createJsonWriter} methods (to ensure that you handle in/out according to REST API guidelines). + * + * @see Best Practices for Designing a Pragmatic RESTful API. + */ +public abstract class RestService extends HttpRequestHandler { + protected static final Logger LOG = Logger.getInstance(RestService.class); + public static final String PREFIX = "api"; + + protected final NotNullLazyValue gson = new NotNullLazyValue() { + @NotNull + @Override + protected Gson compute() { + return new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); + } + }; + + private final LoadingCache abuseCounter = + CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).build(CacheLoader.from((Supplier)AtomicInteger::new)); + + private final Cache trustedOrigins = + CacheBuilder.newBuilder().maximumSize(1024).expireAfterWrite(1, TimeUnit.DAYS).build(); + + @Override + public final boolean isSupported(@NotNull FullHttpRequest request) { + if (!isMethodSupported(request.method())) { + return false; + } + + String uri = request.uri(); + + if (isPrefixlessAllowed() && checkPrefix(uri, getServiceName())) { + return true; + } + + String serviceName = getServiceName(); + int minLength = 1 + PREFIX.length() + 1 + serviceName.length(); + if (uri.length() >= minLength && + uri.charAt(0) == '/' && + uri.regionMatches(true, 1, PREFIX, 0, PREFIX.length()) && + uri.regionMatches(true, 2 + PREFIX.length(), serviceName, 0, serviceName.length())) { + if (uri.length() == minLength) { + return true; + } + else { + char c = uri.charAt(minLength); + return c == '/' || c == '?'; + } + } + return false; + } + + /** + * Service url must be "/api/$serviceName", but to preserve backward compatibility, prefixless path could be also supported + */ + protected boolean isPrefixlessAllowed() { + return false; + } + + /** + * Use human-readable name or UUID if it is an internal service. + */ + @NotNull + protected abstract String getServiceName(); + + protected boolean isMethodSupported(@NotNull HttpMethod method) { + return method == HttpMethod.GET; + } + + @Override + public final boolean process(@NotNull QueryStringDecoder urlDecoder, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context) { + try { + AtomicInteger counter = abuseCounter.get(((InetSocketAddress)context.channel().remoteAddress()).getAddress()); + if (counter.incrementAndGet() > Registry.intValue("ide.rest.api.requests.per.minute", 30)) { + Responses.send(Responses.orInSafeMode(HttpResponseStatus.TOO_MANY_REQUESTS, HttpResponseStatus.OK), context.channel(), request); + return true; + } + + if (!isHostTrusted(request, urlDecoder)) { + Responses.send(Responses.orInSafeMode(HttpResponseStatus.FORBIDDEN, HttpResponseStatus.OK), context.channel(), request); + return true; + } + + String error = execute(urlDecoder, request, context); + if (error != null) { + Responses.send(HttpResponseStatus.BAD_REQUEST, context.channel(), request, error); + } + } + catch (Throwable e) { + HttpResponseStatus status; + // JsonReader exception + //noinspection InstanceofCatchParameter + if (e instanceof MalformedJsonException || (e instanceof IllegalStateException && e.getMessage().startsWith("Expected a "))) { + LOG.warn(e); + status = HttpResponseStatus.BAD_REQUEST; + } + else { + LOG.error(e); + status = HttpResponseStatus.INTERNAL_SERVER_ERROR; + } + Responses.send(status, context.channel(), request, ExceptionUtil.getThrowableText(e)); + } + return true; + } + + @SuppressWarnings("deprecation") + protected boolean isHostTrusted(@NotNull FullHttpRequest request, @NotNull QueryStringDecoder urlDecoder) throws InterruptedException, InvocationTargetException { + return isHostTrusted(request); + } + + /** + * @deprecated Use {@link #isHostTrusted(FullHttpRequest, QueryStringDecoder)} + */ + @SuppressWarnings("DeprecatedIsStillUsed") + @Deprecated + // e.g. upsource trust to configured host + protected boolean isHostTrusted(@NotNull FullHttpRequest request) throws InterruptedException, InvocationTargetException { + if (BuiltInWebServerKt.isSignedRequest(request)) { + return true; + } + + String referrer = NettyKt.getOrigin(request); + if (referrer == null) { + referrer = NettyKt.getReferrer(request); + } + + String host; + try { + host = StringUtil.nullize(referrer == null ? null : new URI(referrer).getHost()); + } + catch (URISyntaxException ignored) { + return false; + } + + Ref isTrusted = Ref.create(); + if (host != null) { + if (NetUtils.isLocalhost(host)) { + isTrusted.set(true); + } + else { + isTrusted.set(trustedOrigins.getIfPresent(host)); + } + } + + if (isTrusted.isNull()) { + SwingUtilities.invokeAndWait(() -> { + AppIcon.getInstance().requestAttention(null, true); + isTrusted.set(showYesNoDialog( + IdeBundle.message("warning.use.rest.api", getServiceName(), ObjectUtils.chooseNotNull(host, "unknown host")), + "title.use.rest.api")); + if (host != null) { + trustedOrigins.put(host, isTrusted.get()); + } + }); + } + return isTrusted.get(); + } + + protected static void activateLastFocusedFrame() { + IdeFrame frame = IdeFocusManager.getGlobalInstance().getLastFocusedFrame(); + if (frame instanceof Window) { + ((Window)frame).toFront(); + } + } + + /** + * Return error or send response using {@link #sendOk(FullHttpRequest, ChannelHandlerContext)}, {@link #send(BufferExposingByteArrayOutputStream, HttpRequest, ChannelHandlerContext)} + */ + @Nullable("error text or null if successful") + public abstract String execute(@NotNull QueryStringDecoder urlDecoder, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context) throws IOException; + + @NotNull + protected static JsonReader createJsonReader(@NotNull FullHttpRequest request) { + JsonReader reader = new JsonReader(new InputStreamReader(new ByteBufInputStream(request.content()), StandardCharsets.UTF_8)); + reader.setLenient(true); + return reader; + } + + @NotNull + protected static JsonWriter createJsonWriter(@NotNull OutputStream out) { + JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); + writer.setIndent(" "); + return writer; + } + + @Nullable + protected static Project getLastFocusedOrOpenedProject() { + IdeFrame lastFocusedFrame = IdeFocusManager.getGlobalInstance().getLastFocusedFrame(); + Project project = lastFocusedFrame == null ? null : lastFocusedFrame.getProject(); + if (project == null) { + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); + return openProjects.length > 0 ? openProjects[0] : null; + } + return project; + } + + protected static void sendOk(@NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context) { + sendStatus(HttpResponseStatus.OK, HttpUtil.isKeepAlive(request), context.channel()); + } + + protected static void sendStatus(@NotNull HttpResponseStatus status, boolean keepAlive, @NotNull Channel channel) { + DefaultFullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status); + HttpUtil.setContentLength(response, 0); + Responses.addCommonHeaders(response); + Responses.addNoCache(response); + if (keepAlive) { + HttpUtil.setKeepAlive(response, true); + } + response.headers().set("X-Frame-Options", "Deny"); + Responses.send(response, channel, !keepAlive); + } + + protected static void send(@NotNull BufferExposingByteArrayOutputStream byteOut, @NotNull HttpRequest request, @NotNull ChannelHandlerContext context) { + HttpResponse response = Responses.response("application/json", Unpooled.wrappedBuffer(byteOut.getInternalBuffer(), 0, byteOut.size())); + sendResponse(request, context, response); + } + + protected static void sendResponse(@NotNull HttpRequest request, @NotNull ChannelHandlerContext context, @NotNull HttpResponse response) { + Responses.addNoCache(response); + response.headers().set("X-Frame-Options", "Deny"); + Responses.send(response, context.channel(), request); + } + + @Nullable + protected static String getStringParameter(@NotNull String name, @NotNull QueryStringDecoder urlDecoder) { + return ContainerUtil.getLastItem(urlDecoder.parameters().get(name)); + } + + protected static int getIntParameter(@NotNull String name, @NotNull QueryStringDecoder urlDecoder) { + return StringUtilRt.parseInt(StringUtil.nullize(ContainerUtil.getLastItem(urlDecoder.parameters().get(name)), true), -1); + } + + protected static boolean getBooleanParameter(@NotNull String name, @NotNull QueryStringDecoder urlDecoder) { + return getBooleanParameter(name, urlDecoder, false); + } + + protected static boolean getBooleanParameter(@NotNull String name, @NotNull QueryStringDecoder urlDecoder, boolean defaultValue) { + List values = urlDecoder.parameters().get(name); + if (ContainerUtil.isEmpty(values)) { + return defaultValue; + } + + String value = values.get(values.size() - 1); + // if just name specified, so, true + return value.isEmpty() || Boolean.parseBoolean(value); + } +} diff --git a/platform/built-in-server/src/org/jetbrains/ide/RestService.kt b/platform/built-in-server/src/org/jetbrains/ide/RestService.kt deleted file mode 100644 index fa2a6926ca4c..000000000000 --- a/platform/built-in-server/src/org/jetbrains/ide/RestService.kt +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package org.jetbrains.ide - -import com.google.common.base.Supplier -import com.google.common.cache.CacheBuilder -import com.google.common.cache.CacheLoader -import com.google.gson.Gson -import com.google.gson.GsonBuilder -import com.google.gson.stream.JsonReader -import com.google.gson.stream.JsonWriter -import com.google.gson.stream.MalformedJsonException -import com.intellij.ide.IdeBundle -import com.intellij.ide.impl.ProjectUtil.showYesNoDialog -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.application.ModalityState -import com.intellij.openapi.diagnostic.logger -import com.intellij.openapi.project.Project -import com.intellij.openapi.project.ProjectManager -import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream -import com.intellij.openapi.util.registry.Registry -import com.intellij.openapi.util.text.StringUtilRt -import com.intellij.openapi.wm.IdeFocusManager -import com.intellij.ui.AppIcon -import com.intellij.util.ExceptionUtil -import com.intellij.util.io.origin -import com.intellij.util.io.referrer -import com.intellij.util.net.NetUtils -import com.intellij.util.text.nullize -import io.netty.buffer.ByteBufInputStream -import io.netty.buffer.Unpooled -import io.netty.channel.Channel -import io.netty.channel.ChannelHandlerContext -import io.netty.handler.codec.http.* -import org.jetbrains.builtInWebServer.isSignedRequest -import org.jetbrains.io.* -import java.awt.Window -import java.io.IOException -import java.io.OutputStream -import java.lang.reflect.InvocationTargetException -import java.net.InetAddress -import java.net.InetSocketAddress -import java.net.URI -import java.net.URISyntaxException -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicInteger - -/** - * Document your service using [apiDoc](http://apidocjs.com). To extract big example from source code, consider to use *.coffee file near your source file. - * (or Python/Ruby, but coffee recommended because it's plugin is lightweight). See [AboutHttpService] for example. - * - * Don't create JsonReader/JsonWriter directly, use only provided [.createJsonReader], [.createJsonWriter] methods (to ensure that you handle in/out according to REST API guidelines). - * - * @see [Best Practices for Designing a Pragmatic REST API](http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api). - */ -abstract class RestService : HttpRequestHandler() { - companion object { - @JvmField - val LOG = logger() - - const val PREFIX = "api" - - @JvmStatic - protected fun activateLastFocusedFrame() { - (IdeFocusManager.getGlobalInstance().lastFocusedFrame as? Window)?.toFront() - } - - @JvmStatic - protected fun createJsonReader(request: FullHttpRequest): JsonReader { - val reader = JsonReader(ByteBufInputStream(request.content()).reader()) - reader.isLenient = true - return reader - } - - @JvmStatic - protected fun createJsonWriter(out: OutputStream): JsonWriter { - val writer = JsonWriter(out.writer()) - writer.setIndent(" ") - return writer - } - - @JvmStatic - fun getLastFocusedOrOpenedProject(): Project? { - return IdeFocusManager.getGlobalInstance().lastFocusedFrame?.project ?: ProjectManager.getInstance().openProjects.firstOrNull() - } - - @JvmStatic - protected fun sendOk(request: FullHttpRequest, context: ChannelHandlerContext) { - sendStatus(HttpResponseStatus.OK, HttpUtil.isKeepAlive(request), context.channel()) - } - - @JvmStatic - protected fun sendStatus(status: HttpResponseStatus, keepAlive: Boolean, channel: Channel) { - val response = DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status) - HttpUtil.setContentLength(response, 0) - response.addCommonHeaders() - response.addNoCache() - if (keepAlive) { - HttpUtil.setKeepAlive(response, true) - } - response.headers().set("X-Frame-Options", "Deny") - response.send(channel, !keepAlive) - } - - @JvmStatic - protected fun send(byteOut: BufferExposingByteArrayOutputStream, request: HttpRequest, context: ChannelHandlerContext) { - val response = response("application/json", Unpooled.wrappedBuffer(byteOut.internalBuffer, 0, byteOut.size())) - sendResponse(request, context, response) - } - - @JvmStatic - protected fun sendResponse(request: HttpRequest, context: ChannelHandlerContext, response: HttpResponse) { - response.addNoCache() - response.headers().set("X-Frame-Options", "Deny") - response.send(context.channel(), request) - } - - @Suppress("SameParameterValue") - @JvmStatic - protected fun getStringParameter(name: String, urlDecoder: QueryStringDecoder): String? { - return urlDecoder.parameters().get(name)?.lastOrNull() - } - - @JvmStatic - protected fun getIntParameter(name: String, urlDecoder: QueryStringDecoder): Int { - return StringUtilRt.parseInt(getStringParameter(name, urlDecoder).nullize(nullizeSpaces = true), -1) - } - - @JvmOverloads - @JvmStatic - protected fun getBooleanParameter(name: String, urlDecoder: QueryStringDecoder, defaultValue: Boolean = false): Boolean { - val values = urlDecoder.parameters().get(name) ?: return defaultValue - // if just name specified, so, true - val value = values.lastOrNull() ?: return true - return value.toBoolean() - } - } - - protected val gson: Gson by lazy { - GsonBuilder() - .setPrettyPrinting() - .disableHtmlEscaping() - .create() - } - - private val abuseCounter = CacheBuilder.newBuilder() - .expireAfterWrite(1, TimeUnit.MINUTES) - .build(CacheLoader.from(Supplier { AtomicInteger() })) - - private val trustedOrigins = CacheBuilder.newBuilder() - .maximumSize(1024) - .expireAfterWrite(1, TimeUnit.DAYS) - .build() - - /** - * Service url must be "/api/$serviceName", but to preserve backward compatibility, prefixless path could be also supported - */ - protected open val isPrefixlessAllowed: Boolean - get() = false - - /** - * Use human-readable name or UUID if it is an internal service. - */ - protected abstract fun getServiceName(): String - - override fun isSupported(request: FullHttpRequest): Boolean { - if (!isMethodSupported(request.method())) { - return false - } - - val uri = request.uri() - - if (isPrefixlessAllowed && checkPrefix(uri, getServiceName())) { - return true - } - - val serviceName = getServiceName() - val minLength = 1 + PREFIX.length + 1 + serviceName.length - if (uri.length >= minLength && - uri[0] == '/' && - uri.regionMatches(1, PREFIX, 0, PREFIX.length, ignoreCase = true) && - uri.regionMatches(2 + PREFIX.length, serviceName, 0, serviceName.length, ignoreCase = true)) { - if (uri.length == minLength) { - return true - } - else { - val c = uri[minLength] - return c == '/' || c == '?' - } - } - return false - } - - protected open fun isMethodSupported(method: HttpMethod): Boolean { - return method === HttpMethod.GET - } - - override fun process(urlDecoder: QueryStringDecoder, request: FullHttpRequest, context: ChannelHandlerContext): Boolean { - try { - val counter = abuseCounter.get((context.channel().remoteAddress() as InetSocketAddress).address) - if (counter.incrementAndGet() > Registry.intValue("ide.rest.api.requests.per.minute", 30)) { - HttpResponseStatus.TOO_MANY_REQUESTS.orInSafeMode(HttpResponseStatus.OK).send(context.channel(), request) - return true - } - - if (!isHostTrusted(request, urlDecoder)) { - HttpResponseStatus.FORBIDDEN.orInSafeMode(HttpResponseStatus.OK).send(context.channel(), request) - return true - } - - val error = execute(urlDecoder, request, context) - if (error != null) { - HttpResponseStatus.BAD_REQUEST.send(context.channel(), request, error) - } - } - catch (e: Throwable) { - val status: HttpResponseStatus? - // JsonReader exception - if (e is MalformedJsonException || e is IllegalStateException && e.message!!.startsWith("Expected a ")) { - LOG.warn(e) - status = HttpResponseStatus.BAD_REQUEST - } - else { - LOG.error(e) - status = HttpResponseStatus.INTERNAL_SERVER_ERROR - } - status.send(context.channel(), request, ExceptionUtil.getThrowableText(e)) - } - - return true - } - - @Throws(InterruptedException::class, InvocationTargetException::class) - protected open fun isHostTrusted(request: FullHttpRequest, urlDecoder: QueryStringDecoder): Boolean { - @Suppress("DEPRECATION") - return isHostTrusted(request) - } - - @Deprecated("Use {@link #isHostTrusted(FullHttpRequest, QueryStringDecoder)}") - @Throws(InterruptedException::class, InvocationTargetException::class) - // e.g. upsource trust to configured host - protected open fun isHostTrusted(request: FullHttpRequest): Boolean { - if (request.isSignedRequest()) { - return true - } - - val referrer = request.origin ?: request.referrer - val host = try { - if (referrer == null) null else URI(referrer).host.nullize() - } - catch (ignored: URISyntaxException) { - return false - } - - if (host != null) { - if (NetUtils.isLocalhost(host)) { - return true - } - else { - trustedOrigins.getIfPresent(host)?.let { - return it - } - } - } - - var isTrusted = false - ApplicationManager.getApplication().invokeAndWait({ - AppIcon.getInstance().requestAttention(null, true) - isTrusted = showYesNoDialog(IdeBundle.message("warning.use.rest.api", getServiceName(), host ?: "unknown host"), "title.use.rest.api") - if (host != null) { - trustedOrigins.put(host, isTrusted) - } - }, ModalityState.any()) - return isTrusted - } - - /** - * Return error or send response using [.sendOk], [.send] - */ - @Throws(IOException::class) - abstract fun execute(urlDecoder: QueryStringDecoder, request: FullHttpRequest, context: ChannelHandlerContext): String? -} diff --git a/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java b/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java index 44d4588d041a..7c7c256d94b7 100644 --- a/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java +++ b/platform/core-api/src/com/intellij/ide/util/PropertiesComponent.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.util; import com.intellij.openapi.components.ServiceManager; @@ -65,7 +65,7 @@ public abstract class PropertiesComponent extends SimpleModificationTracker { public abstract void setValues(@NonNls @NotNull String name, String[] values); - public static PropertiesComponent getInstance(@NotNull Project project) { + public static PropertiesComponent getInstance(Project project) { return ServiceManager.getService(project, PropertiesComponent.class); } diff --git a/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java b/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java index 043d809401cd..019ee46d8181 100644 --- a/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java +++ b/platform/core-impl/src/com/intellij/diagnostic/PerformanceWatcher.java @@ -33,7 +33,6 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.List; -import java.util.Objects; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -307,23 +306,13 @@ public class PerformanceWatcher implements Disposable { for (int i = 0; i < commonPart.size() && i < stackTraceElements.length; i++) { StackTraceElement el1 = commonPart.get(commonPart.size() - i - 1); StackTraceElement el2 = stackTraceElements[stackTraceElements.length - i - 1]; - if (!compareStackTraceElements(el1, el2)) { + if (!el1.equals(el2)) { return commonPart.subList(commonPart.size() - i, commonPart.size()); } } return commonPart; } - // same as java.lang.StackTraceElement.equals, but do not care about the line number - private static boolean compareStackTraceElements(StackTraceElement el1, StackTraceElement el2) { - if (el1 == el2) { - return true; - } - return el1.getClassName().equals(el2.getClassName()) && - Objects.equals(el1.getMethodName(), el2.getMethodName()) && - Objects.equals(el1.getFileName(), el2.getFileName()); - } - private class SwingThreadRunnable implements Runnable { private final long myCreationMillis; diff --git a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java index 01e6c9c598b6..4a0c8e7d7eb3 100644 --- a/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java +++ b/platform/external-system-impl/src/com/intellij/openapi/externalSystem/service/execution/ExternalSystemRunConfiguration.java @@ -424,9 +424,10 @@ public class ExternalSystemRunConfiguration extends LocatableConfigurationBase i DefaultActionGroup actionGroup = new DefaultActionGroup(); if (executionConsole instanceof BuildView) { actionGroup.addAll(((BuildView)executionConsole).getSwitchActions()); - actionGroup.add(BuildTreeFilters.createFilteringActionsGroup((BuildView)executionConsole)); + actionGroup.add(new ShowExecutionErrorsOnlyAction((BuildView)executionConsole)); } - DefaultExecutionResult executionResult = new DefaultExecutionResult(executionConsole, processHandler, actionGroup.getChildren(null)); + DefaultExecutionResult executionResult = + new DefaultExecutionResult(executionConsole, processHandler, actionGroup.getChildren(null)); executionResult.setRestartActions(restartActions); return executionResult; } diff --git a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java index abc9aef055a4..44acb1ff4036 100644 --- a/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java +++ b/platform/external-system-impl/testSrc/com/intellij/openapi/externalSystem/test/ExternalSystemImportingTestCase.java @@ -554,7 +554,7 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest final AtomicInteger counter = new AtomicInteger(); Messages.setTestDialog(new TestDialog() { @Override - public int show(@NotNull String message) { + public int show(String message) { counter.set(counter.get() + 1); return 0; } @@ -566,7 +566,7 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest final AtomicInteger counter = new AtomicInteger(); Messages.setTestDialog(new TestDialog() { @Override - public int show(@NotNull String message) { + public int show(String message) { counter.set(counter.get() + 1); return 1; } diff --git a/platform/lang-api/src/com/intellij/codeInsight/template/Expression.java b/platform/lang-api/src/com/intellij/codeInsight/template/Expression.java index 2cf64cce2e1e..853bb75d36ac 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/template/Expression.java +++ b/platform/lang-api/src/com/intellij/codeInsight/template/Expression.java @@ -32,4 +32,13 @@ public abstract class Expression { public String getAdvertisingText() { return null; } + + /** + * @return true if {@link Expression#calculateResult(com.intellij.codeInsight.template.ExpressionContext)} or + * {@link Expression#calculateQuickResult(com.intellij.codeInsight.template.ExpressionContext)} + * require committed PSI for their calculation or false otherwise + */ + public boolean requiresCommittedPSI() { + return true; + } } diff --git a/platform/lang-api/src/com/intellij/codeInsight/template/impl/TextExpression.java b/platform/lang-api/src/com/intellij/codeInsight/template/impl/TextExpression.java index 6a09c465aaac..c80a695ad13a 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/template/impl/TextExpression.java +++ b/platform/lang-api/src/com/intellij/codeInsight/template/impl/TextExpression.java @@ -37,6 +37,11 @@ public class TextExpression extends Expression { return calculateResult(expressionContext); } + @Override + public boolean requiresCommittedPSI() { + return false; + } + @Override public LookupElement[] calculateLookupItems(ExpressionContext expressionContext) { return LookupElement.EMPTY_ARRAY; diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java index 5c30c2847f95..2a29e38899c9 100644 --- a/platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java +++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/SdkType.java @@ -244,7 +244,7 @@ public abstract class SdkType implements SdkTypeId { * @param parentComponent the parent component for showing the dialog. * @param selectedSdk current selected sdk in parentComponent * @param sdkCreatedCallback the callback to which the created SDK is passed. - * @implSpec method's implementations should not add sdk to the jdkTable neither invoke {@link SdkType#setupSdkPaths}. Only create and + * @implSpec method's implementations should not add sdk to the jdkTable neither invoke {@link SdkType#setupSdkPaths}. Only create and * and pass to the callback. The rest is done by {@link com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel#setupSdk(Sdk, Consumer)} */ public void showCustomCreateUI(@NotNull SdkModel sdkModel, diff --git a/platform/lang-impl/src/com/intellij/application/options/CodeStyleAbstractPanel.java b/platform/lang-impl/src/com/intellij/application/options/CodeStyleAbstractPanel.java index 478266b4e72e..c6eab2b33fa1 100644 --- a/platform/lang-impl/src/com/intellij/application/options/CodeStyleAbstractPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/CodeStyleAbstractPanel.java @@ -64,7 +64,7 @@ public abstract class CodeStyleAbstractPanel implements Disposable, ComponentHig private final List myPreviewRangesToHighlight = new ArrayList<>(); - private final EditorEx myEditor; + private final Editor myEditor; private final CodeStyleSettings mySettings; private boolean myShouldUpdatePreview; protected static final int[] ourWrappings = @@ -134,7 +134,7 @@ public abstract class CodeStyleAbstractPanel implements Disposable, ComponentHig } @Nullable - private EditorEx createEditor() { + private Editor createEditor() { if (StringUtil.isEmpty(getPreviewText())) return null; EditorFactory editorFactory = EditorFactory.getInstance(); Document editorDocument = editorFactory.createDocument(""); @@ -159,7 +159,7 @@ public abstract class CodeStyleAbstractPanel implements Disposable, ComponentHig protected void updatePreview(boolean useDefaultSample) { if (myEditor == null) return; updateEditor(useDefaultSample); - updatePreviewHighlighter(myEditor); + updatePreviewHighlighter((EditorEx)myEditor); } private void updateEditor(boolean useDefaultSample) { @@ -167,6 +167,7 @@ public abstract class CodeStyleAbstractPanel implements Disposable, ComponentHig return; } + Project project = ProjectUtil.guessCurrentProject(getPanel()); if (myEditor.isDisposed()) return; if (myLastDocumentModificationStamp != myEditor.getDocument().getModificationStamp()) { @@ -176,19 +177,8 @@ public abstract class CodeStyleAbstractPanel implements Disposable, ComponentHig myTextToReformat = StringUtil.convertLineSeparators(ObjectUtils.notNull(getPreviewText(), "")); } - updateEditorState(true); - } - - protected void setEditorText(@NotNull String text, boolean updateHighlighter) { - myTextToReformat = StringUtil.convertLineSeparators(text); - if (updateHighlighter) updatePreviewHighlighter(myEditor); - updateEditorState(false); - } - - private void updateEditorState(boolean collectChanges) { int currOffs = myEditor.getScrollingModel().getVerticalScrollOffset(); - Project project = ProjectUtil.guessCurrentProject(getPanel()); - CommandProcessor.getInstance().executeCommand(project, () -> replaceText(project, collectChanges), null, null); + CommandProcessor.getInstance().executeCommand(project, () -> replaceText(project), null, null); myEditor.getSettings().setRightMargin(getAdjustedRightMargin()); myLastDocumentModificationStamp = myEditor.getDocument().getModificationStamp(); @@ -202,11 +192,11 @@ public abstract class CodeStyleAbstractPanel implements Disposable, ComponentHig protected abstract int getRightMargin(); - private void replaceText(final Project project, boolean collectChanges) { + private void replaceText(final Project project) { ApplicationManager.getApplication().runWriteAction(() -> { try { Document beforeReformat = null; - if (collectChanges && myEditor.getDocument().getTextLength() > 0) { + if (myEditor.getDocument().getTextLength() > 0) { beforeReformat = collectChangesBeforeCurrentSettingsAppliance(project); } @@ -606,12 +596,6 @@ public abstract class CodeStyleAbstractPanel implements Disposable, ComponentHig return myCurrentSettings; } -@Nullable - protected CodeStyleSettings getModelSettings() { - CodeStyleSchemesModel model = myModel; - return model != null ? model.getCloneSettings(model.getSelectedScheme()) : null; - } - public void setupCopyFromMenu(JPopupMenu copyMenu) { copyMenu.removeAll(); } diff --git a/platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java b/platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java index c535feda28fa..050a00ae98e1 100644 --- a/platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/TabbedLanguageCodeStylePanel.java @@ -584,7 +584,7 @@ public abstract class TabbedLanguageCodeStylePanel extends CodeStyleAbstractPane } @Nullable - protected CommonCodeStyleSettings.IndentOptions getIndentOptions(CodeStyleSettings settings) { + private CommonCodeStyleSettings.IndentOptions getIndentOptions(CodeStyleSettings settings) { return settings.getCommonSettings(getDefaultLanguage()).getIndentOptions(); } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/group/ArrangementGroupingRulesControl.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/group/ArrangementGroupingRulesControl.java index b07b2d41578b..02ce1aa65099 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/group/ArrangementGroupingRulesControl.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/arrangement/group/ArrangementGroupingRulesControl.java @@ -164,7 +164,6 @@ public class ArrangementGroupingRulesControl extends JBTable { ArrangementGroupingComponent component = (ArrangementGroupingComponent)value; component.setRowIndex(row + 1); component.setHighlight(myRowUnderMouse == row || table.isRowSelected(row)); - component.revalidate(); return component; } else if (value instanceof ArrangementRepresentationAware) { diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form index b76a6bd1f5d1..db842f605c07 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorOptionsPanel.form @@ -311,13 +311,12 @@ - - + @@ -421,7 +420,7 @@ - + diff --git a/platform/lang-impl/src/com/intellij/build/AbstractViewManager.java b/platform/lang-impl/src/com/intellij/build/AbstractViewManager.java index 3e10468e35ca..029d8a0d35d0 100644 --- a/platform/lang-impl/src/com/intellij/build/AbstractViewManager.java +++ b/platform/lang-impl/src/com/intellij/build/AbstractViewManager.java @@ -121,7 +121,7 @@ public abstract class AbstractViewManager implements ViewManager, BuildProgressL toolbarActions.removeAll(); toolbarActions.addAll(view.createConsoleActions()); toolbarActions.add(new PinBuildViewAction(buildsView)); - toolbarActions.add(BuildTreeFilters.createFilteringActionsGroup(view)); + toolbarActions.add(new ShowExecutionErrorsOnlyAction(view)); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/build/BuildTreeConsoleView.java b/platform/lang-impl/src/com/intellij/build/BuildTreeConsoleView.java index 39e771f2268f..533174c4c1e7 100644 --- a/platform/lang-impl/src/com/intellij/build/BuildTreeConsoleView.java +++ b/platform/lang-impl/src/com/intellij/build/BuildTreeConsoleView.java @@ -11,10 +11,6 @@ import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.ExecutionConsole; -import com.intellij.ide.CommonActionsManager; -import com.intellij.ide.IdeBundle; -import com.intellij.ide.OccurenceNavigator; -import com.intellij.ide.OccurenceNavigatorSupport; import com.intellij.ide.actions.EditSourceAction; import com.intellij.ide.ui.UISettings; import com.intellij.ide.util.treeView.NodeRenderer; @@ -60,8 +56,10 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import java.awt.*; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.*; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; @@ -79,7 +77,7 @@ import static com.intellij.util.ui.UIUtil.getTreeSelectionForeground; /** * @author Vladislav.Soroka */ -public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildConsoleView, Filterable, OccurenceNavigator { +public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildConsoleView, Filterable { private static final Logger LOG = Logger.getInstance(BuildTreeConsoleView.class); @NonNls private static final String TREE = "tree"; @@ -96,14 +94,13 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon private final Tree myTree; private final ExecutionNode myRootNode; private final ExecutionNode myBuildProgressRootNode; - private final Set> myNodeFilters; - private final ProblemOccurrenceNavigatorSupport myOccurrenceNavigatorSupport; + @Nullable + private volatile Predicate myExecutionTreeFilter; public BuildTreeConsoleView(Project project, BuildDescriptor buildDescriptor, @Nullable ExecutionConsole executionConsole, @NotNull BuildViewSettingsProvider buildViewSettingsProvider) { - myNodeFilters = ContainerUtil.newConcurrentSet(); myProject = project; myWorkingDir = FileUtil.toSystemIndependentName(buildDescriptor.getWorkingDir()); @@ -128,9 +125,6 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon new ConsoleViewHandler(myProject, myTree, myBuildProgressRootNode, this, executionConsole, buildViewSettingsProvider); myThreeComponentsSplitter.setSecondComponent(myConsoleViewHandler.getComponent()); myPanel.add(myThreeComponentsSplitter, BorderLayout.CENTER); - BuildTreeFilters.install(this); - myRootNode.setFilter(getFilter()); - myOccurrenceNavigatorSupport = new ProblemOccurrenceNavigatorSupport(myTree); } private void installContextMenu(@NotNull StartBuildEvent startBuildEvent) { @@ -149,14 +143,8 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon ActionUtil.copyFrom(edit, "EditSource"); group.add(edit); group.addSeparator(); - group.addAll(BuildTreeFilters.createFilteringActionsGroup(this)); - group.addSeparator(); - //Initializing prev and next occurrences actions - final CommonActionsManager actionsManager = CommonActionsManager.getInstance(); - final AnAction prevAction = actionsManager.createPrevOccurenceAction(this); - group.add(prevAction); - final AnAction nextAction = actionsManager.createNextOccurenceAction(this); - group.add(nextAction); + group.add(new ShowExecutionErrorsOnlyAction(this)); + PopupHandler.installPopupHandler(myTree, group, "BuildView"); }); } @@ -174,35 +162,20 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon return true; } - @NotNull @Override + @Nullable public Predicate getFilter() { - return executionNode -> executionNode == getBuildProgressRootNode() || - executionNode.isRunning() || - executionNode.isFailed() || - myNodeFilters.stream().anyMatch(predicate -> predicate.test(executionNode)); + return myExecutionTreeFilter; } @Override - public void addFilter(@NotNull Predicate executionTreeFilter) { - myNodeFilters.add(executionTreeFilter); - updateFilter(); - } - - @Override - public void removeFilter(@NotNull Predicate filter) { - myNodeFilters.remove(filter); - updateFilter(); - } - - @Override - public boolean contains(@NotNull Predicate filter) { - return myNodeFilters.contains(filter); - } - - private void updateFilter() { + public void setFilter(@Nullable Predicate executionTreeFilter) { + myExecutionTreeFilter = executionTreeFilter; + ExecutionNode buildProgressRootNode = getBuildProgressRootNode(); ExecutionNode rootElement = getRootElement(); - rootElement.setFilter(getFilter()); + Predicate predicate = executionTreeFilter == null ? null : + node -> node == buildProgressRootNode || executionTreeFilter.test(node); + rootElement.setFilter(predicate); scheduleUpdate(rootElement); } @@ -342,38 +315,6 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon } } - @Override - public boolean hasNextOccurence() { - return myOccurrenceNavigatorSupport.hasNextOccurence(); - } - - @Override - public boolean hasPreviousOccurence() { - return myOccurrenceNavigatorSupport.hasPreviousOccurence(); - } - - @Override - public OccurenceInfo goNextOccurence() { - return myOccurrenceNavigatorSupport.goNextOccurence(); - } - - @Override - public OccurenceInfo goPreviousOccurence() { - return myOccurrenceNavigatorSupport.goPreviousOccurence(); - } - - @NotNull - @Override - public String getNextOccurenceActionName() { - return myOccurrenceNavigatorSupport.getNextOccurenceActionName(); - } - - @NotNull - @Override - public String getPreviousOccurenceActionName() { - return myOccurrenceNavigatorSupport.getPreviousOccurenceActionName(); - } - @NotNull private static TreeVisitor visitor(@NotNull ExecutionNode executionNode) { return path -> { @@ -561,13 +502,7 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon if (eventKind == MessageEvent.Kind.ERROR || eventKind == MessageEvent.Kind.WARNING) { SimpleNode p = parentNode; do { - ExecutionNode executionNode = (ExecutionNode)p; - boolean warningUpdate = eventKind == MessageEvent.Kind.WARNING && !executionNode.hasWarnings(); - executionNode.reportChildMessageKind(eventKind); - if (warningUpdate) { - executionNode.cleanUpCache(); - scheduleUpdate(executionNode); - } + ((ExecutionNode)p).reportChildMessageKind(eventKind); } while ((p = p.getParent()) instanceof ExecutionNode); scheduleUpdate(getRootElement()); @@ -810,41 +745,6 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon } } - private static class ProblemOccurrenceNavigatorSupport extends OccurenceNavigatorSupport { - ProblemOccurrenceNavigatorSupport(final Tree tree) { - super(tree); - } - - @Override - protected Navigatable createDescriptorForNode(@NotNull DefaultMutableTreeNode node) { - Object userObject = node.getUserObject(); - if (!(userObject instanceof ExecutionNode)) { - return null; - } - final ExecutionNode executionNode = (ExecutionNode)userObject; - if (executionNode.getChildCount() > 0 || !executionNode.hasWarnings() && !executionNode.isFailed()) { - return null; - } - List navigatables = executionNode.getNavigatables(); - if (!navigatables.isEmpty()) { - return navigatables.get(0); - } - return null; - } - - @NotNull - @Override - public String getNextOccurenceActionName() { - return IdeBundle.message("action.next.problem"); - } - - @NotNull - @Override - public String getPreviousOccurenceActionName() { - return IdeBundle.message("action.previous.problem"); - } - } - private static class MyTree extends Tree { private MyTree(TreeModel treemodel) { super(treemodel); diff --git a/platform/lang-impl/src/com/intellij/build/BuildView.java b/platform/lang-impl/src/com/intellij/build/BuildView.java index 2e09cfec3765..8f8d586ada65 100644 --- a/platform/lang-impl/src/com/intellij/build/BuildView.java +++ b/platform/lang-impl/src/com/intellij/build/BuildView.java @@ -32,7 +32,6 @@ import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.actions.CloseAction; -import com.intellij.ide.OccurenceNavigator; import com.intellij.ide.actions.PinActiveTabAction; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; @@ -57,7 +56,7 @@ import java.util.function.Supplier; */ @ApiStatus.Experimental public class BuildView extends CompositeView - implements BuildProgressListener, ConsoleView, DataProvider, Filterable, OccurenceNavigator { + implements BuildProgressListener, ConsoleView, DataProvider, Filterable { public static final String CONSOLE_VIEW_NAME = "consoleView"; private final AtomicReference myStartBuildEventRef = new AtomicReference<>(); private final BuildDescriptor myBuildDescriptor; @@ -366,75 +365,17 @@ public class BuildView extends CompositeView return getEventView() != null; } - @NotNull @Override public Predicate getFilter() { BuildTreeConsoleView eventView = getEventView(); - return eventView == null ? executionNode -> true : eventView.getFilter(); + return eventView == null ? null : eventView.getFilter(); } @Override - public void addFilter(@NotNull Predicate filter) { + public void setFilter(Predicate filter) { BuildTreeConsoleView eventView = getEventView(); if (eventView != null) { - eventView.addFilter(filter); + eventView.setFilter(filter); } } - - @Override - public void removeFilter(@NotNull Predicate filter) { - BuildTreeConsoleView eventView = getEventView(); - if (eventView != null) { - eventView.removeFilter(filter); - } - } - - @Override - public boolean contains(@NotNull Predicate filter) { - BuildTreeConsoleView eventView = getEventView(); - return eventView != null && eventView.contains(filter); - } - - @NotNull - private OccurenceNavigator getOccurenceNavigator() { - BuildTreeConsoleView eventView = getEventView(); - if (eventView != null) return eventView; - ExecutionConsole executionConsole = getConsoleView(); - if (executionConsole instanceof OccurenceNavigator) { - return (OccurenceNavigator)executionConsole; - } - return EMPTY; - } - - @Override - public boolean hasNextOccurence() { - return getOccurenceNavigator().hasNextOccurence(); - } - - @Override - public boolean hasPreviousOccurence() { - return getOccurenceNavigator().hasPreviousOccurence(); - } - - @Override - public OccurenceInfo goNextOccurence() { - return getOccurenceNavigator().goNextOccurence(); - } - - @Override - public OccurenceInfo goPreviousOccurence() { - return getOccurenceNavigator().goPreviousOccurence(); - } - - @NotNull - @Override - public String getNextOccurenceActionName() { - return getOccurenceNavigator().getNextOccurenceActionName(); - } - - @NotNull - @Override - public String getPreviousOccurenceActionName() { - return getOccurenceNavigator().getPreviousOccurenceActionName(); - } } diff --git a/platform/lang-impl/src/com/intellij/build/ExecutionNode.java b/platform/lang-impl/src/com/intellij/build/ExecutionNode.java index d399faeade25..260851bd8472 100644 --- a/platform/lang-impl/src/com/intellij/build/ExecutionNode.java +++ b/platform/lang-impl/src/com/intellij/build/ExecutionNode.java @@ -57,7 +57,7 @@ public class ExecutionNode extends CachingSimpleNode { private static final Icon NODE_ICON_DEFAULT = ICON_16; private static final Icon NODE_ICON_RUNNING = new AnimatedIcon.FS(); - private final Collection myChildrenList = new ConcurrentLinkedDeque<>(); + private final Collection myChildrenList = new ConcurrentLinkedDeque<>(); //ContainerUtil.newSmartList(); private final AtomicInteger myErrors = new AtomicInteger(); private final AtomicInteger myWarnings = new AtomicInteger(); private long startTime; @@ -228,11 +228,6 @@ public class ExecutionNode extends CachingSimpleNode { return endTime <= 0 && !isSkipped(myResult) && !isFailed(myResult); } - public boolean hasWarnings() { - return myWarnings.get() > 0 || - (myResult instanceof MessageEventResult && ((MessageEventResult)myResult).getKind() == MessageEvent.Kind.WARNING); - } - public boolean isFailed() { return isFailed(myResult) || myErrors.get() > 0 || @@ -300,6 +295,25 @@ public class ExecutionNode extends CachingSimpleNode { } } + ExecutionNode copy(ExecutionNode parent) { + ExecutionNode copy = new ExecutionNode(myProject, parent); + copy.startTime = startTime; + copy.endTime = endTime; + copy.myTitle = myTitle; + copy.myTooltip = myTooltip; + copy.myHint = myHint; + copy.myResult = myResult; + copy.myAutoExpandNode = myAutoExpandNode; + copy.myNavigatable = myNavigatable; + copy.myPreferredIconValue = myPreferredIconValue; + copy.myErrors.set(myErrors.get()); + copy.myWarnings.set(myWarnings.get()); + copy.myFilter = myFilter; + copy.myName = myName; + copy.myClosedIcon = myClosedIcon; + return copy; + } + private String getCurrentHint() { String hint = myHint; int warnings = myWarnings.get(); diff --git a/platform/lang-impl/src/com/intellij/build/Filterable.java b/platform/lang-impl/src/com/intellij/build/Filterable.java index 06bf2def0732..2bcd1cf601a2 100644 --- a/platform/lang-impl/src/com/intellij/build/Filterable.java +++ b/platform/lang-impl/src/com/intellij/build/Filterable.java @@ -1,19 +1,12 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.build; -import org.jetbrains.annotations.NotNull; - import java.util.function.Predicate; public interface Filterable { boolean isFilteringEnabled(); - @NotNull Predicate getFilter(); - void addFilter(@NotNull Predicate filter); - - void removeFilter(@NotNull Predicate filter); - - boolean contains(@NotNull Predicate filter); + void setFilter(Predicate filter); } diff --git a/platform/lang-impl/src/com/intellij/build/ShowExecutionErrorsOnlyAction.java b/platform/lang-impl/src/com/intellij/build/ShowExecutionErrorsOnlyAction.java new file mode 100644 index 000000000000..4731037a3cf2 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/build/ShowExecutionErrorsOnlyAction.java @@ -0,0 +1,61 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.build; + +import com.intellij.icons.AllIcons; +import com.intellij.ide.util.PropertiesComponent; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.util.registry.Registry; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Predicate; + +/** + * @author Vladislav.Soroka + */ +@ApiStatus.Experimental +public class ShowExecutionErrorsOnlyAction extends ToggleAction implements DumbAware { + private static final Predicate ERROR_FILTER = node -> node.isRunning() || node.isFailed(); + private final Filterable myFilterable; + private final String mySelectionStateKey; + + public ShowExecutionErrorsOnlyAction(@NotNull Filterable filterable) { + this(filterable, "build.toolwindow.show.errors.only.selection.state"); + } + + public ShowExecutionErrorsOnlyAction(@NotNull Filterable filterable, @Nullable String selectionStateKey) { + super("Show Errors Only", "Show Errors Only", AllIcons.General.Error); + myFilterable = filterable; + mySelectionStateKey = selectionStateKey; + } + + @Override + public boolean isSelected(@NotNull AnActionEvent e) { + final Presentation presentation = e.getPresentation(); + if (!Registry.is("build.view.side-by-side", true)) { + presentation.setVisible(false); + return false; + } + boolean filteringEnabled = myFilterable.isFilteringEnabled(); + presentation.setEnabledAndVisible(filteringEnabled); + if (filteringEnabled && mySelectionStateKey != null && + PropertiesComponent.getInstance().getBoolean(mySelectionStateKey, true) && + myFilterable.getFilter() != ERROR_FILTER) { + setSelected(e, true); + } + + return myFilterable.getFilter() == ERROR_FILTER; + } + + @Override + public void setSelected(@NotNull AnActionEvent e, boolean state) { + myFilterable.setFilter(state ? ERROR_FILTER : null); + if (mySelectionStateKey != null) { + PropertiesComponent.getInstance().setValue(mySelectionStateKey, state, true); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/build/buildTreeFilters.kt b/platform/lang-impl/src/com/intellij/build/buildTreeFilters.kt deleted file mode 100644 index 4b5d73d7e217..000000000000 --- a/platform/lang-impl/src/com/intellij/build/buildTreeFilters.kt +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -@file:JvmName("BuildTreeFilters") -package com.intellij.build - -import com.intellij.icons.AllIcons -import com.intellij.ide.util.PropertiesComponent -import com.intellij.openapi.actionSystem.AnActionEvent -import com.intellij.openapi.actionSystem.DefaultActionGroup -import com.intellij.openapi.actionSystem.ToggleAction -import com.intellij.openapi.project.DumbAware -import com.intellij.openapi.util.registry.Registry -import org.jetbrains.annotations.ApiStatus -import java.util.function.Predicate - -private val SUCCESSFUL_STEPS_FILTER = Predicate { node: ExecutionNode -> !node.isFailed && !node.hasWarnings() } -private val WARNINGS_FILTER = Predicate { node: ExecutionNode -> node.hasWarnings() } - -@ApiStatus.Experimental -fun createFilteringActionsGroup(filterable: Filterable): DefaultActionGroup { - val actionGroup = DefaultActionGroup("Filters", true) - actionGroup.templatePresentation.icon = AllIcons.Actions.Show - actionGroup.add(WarningsToggleAction(filterable)) - actionGroup.add(SuccessfulStepsToggleAction(filterable)) - return actionGroup -} - -@ApiStatus.Experimental -fun install(filterable: Filterable) { - val filteringEnabled = filterable.isFilteringEnabled - if (!filteringEnabled) return - SuccessfulStepsToggleAction.install(filterable) - WarningsToggleAction.install(filterable) -} - -@ApiStatus.Experimental -open class FilterToggleAction constructor(text: String, - private val stateKey: String?, - private val filterable: Filterable, - private val filter: Predicate, - private val defaultState: Boolean) : ToggleAction(text), DumbAware { - override fun isSelected(e: AnActionEvent): Boolean { - val presentation = e.presentation - if (!Registry.`is`("build.view.side-by-side", true)) { - presentation.isVisible = false - return false - } - val filteringEnabled = filterable.isFilteringEnabled - presentation.isEnabledAndVisible = filteringEnabled - if (filteringEnabled && stateKey != null && - PropertiesComponent.getInstance().getBoolean(stateKey, defaultState) && - !filterable.contains(filter)) { - setSelected(e, true) - } - - return filterable.contains(filter) - } - - override fun setSelected(e: AnActionEvent, state: Boolean) { - if (state) { - filterable.addFilter(filter) - } - else { - filterable.removeFilter(filter) - } - if (stateKey != null) { - PropertiesComponent.getInstance().setValue(stateKey, state, defaultState) - } - } - - companion object { - fun install(filterable: Filterable, - filter: Predicate, - stateKey: String, - defaultState: Boolean) { - if (PropertiesComponent.getInstance().getBoolean(stateKey, defaultState) && - !filterable.contains(filter)) { - filterable.addFilter(filter) - } - } - } -} - -@ApiStatus.Experimental -class SuccessfulStepsToggleAction(filterable: Filterable) : - FilterToggleAction("Show Successful Steps", STATE_KEY, filterable, SUCCESSFUL_STEPS_FILTER, false), DumbAware { - companion object { - private const val STATE_KEY = "build.toolwindow.show.successful.steps.selection.state" - fun install(filterable: Filterable) { - install(filterable, SUCCESSFUL_STEPS_FILTER, STATE_KEY, false) - } - } -} - -@ApiStatus.Experimental -class WarningsToggleAction(filterable: Filterable) : - FilterToggleAction("Show Warnings", STATE_KEY, filterable, WARNINGS_FILTER, true), DumbAware { - companion object { - private const val STATE_KEY = "build.toolwindow.show.warnings.selection.state" - fun install(filterable: Filterable) { - install(filterable, WARNINGS_FILTER, STATE_KEY, true) - } - } -} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java index eb01d9da3f2e..c1b98e7bc53a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java @@ -6,7 +6,6 @@ import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.navigation.ChooseByNameContributor; -import com.intellij.navigation.ChooseByNameContributorEx; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileNameMatcher; @@ -34,10 +33,9 @@ import com.intellij.psi.impl.source.resolve.reference.impl.providers.*; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.ProjectScope; +import com.intellij.util.ArrayUtil; import com.intellij.util.ProcessingContext; -import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.indexing.FindSymbolParameters; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -118,15 +116,13 @@ public class FilePathCompletionContributor extends CompletionContributor { if (contextFile != null) { - Set resultNames = new TreeSet<>(); - String finalPrefix = prefix; - processAllNames(project, fileName -> { - if (filenameMatchesPrefixOrType(fileName, finalPrefix, set.getSuitableFileTypes(), - parameters.getInvocationCount())) { + final String[] fileNames = getAllNames(project); + final Set resultNames = new TreeSet<>(); + for (String fileName : fileNames) { + if (filenameMatchesPrefixOrType(fileName, prefix, set.getSuitableFileTypes(), parameters.getInvocationCount())) { resultNames.add(fileName); } - return true; - }); + } final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); @@ -184,19 +180,16 @@ public class FilePathCompletionContributor extends CompletionContributor { extend(CompletionType.BASIC, psiElement(), provider); } - private static boolean filenameMatchesPrefixOrType(String fileName, - String prefix, - FileType[] suitableFileTypes, - int invocationCount) { - boolean prefixMatched = prefix.length() == 0 || StringUtil.startsWithIgnoreCase(fileName, prefix); + private static boolean filenameMatchesPrefixOrType(final String fileName, final String prefix, final FileType[] suitableFileTypes, final int invocationCount) { + final boolean prefixMatched = prefix.length() == 0 || StringUtil.startsWithIgnoreCase(fileName, prefix); if (prefixMatched && (suitableFileTypes.length == 0 || invocationCount > 2)) return true; if (prefixMatched) { - String extension = FileUtilRt.getExtension(fileName); + final String extension = FileUtilRt.getExtension(fileName); if (extension.length() == 0) return false; - for (FileType fileType : suitableFileTypes) { - for (FileNameMatcher matcher : FileTypeManager.getInstance().getAssociations(fileType)) { + for (final FileType fileType : suitableFileTypes) { + for (final FileNameMatcher matcher : FileTypeManager.getInstance().getAssociations(fileType)) { if (FileNameMatcherEx.acceptsCharSequence(matcher, fileName)) return true; } } @@ -244,15 +237,12 @@ public class FilePathCompletionContributor extends CompletionContributor { return true; } - private static void processAllNames(@NotNull Project project, @NotNull Processor processor) { - for (ChooseByNameContributor contributor : ChooseByNameContributor.FILE_EP_NAME.getExtensionList()) { + private static String[] getAllNames(@NotNull final Project project) { + Set names = new HashSet<>(); + final ChooseByNameContributor[] nameContributors = ChooseByNameContributor.FILE_EP_NAME.getExtensions(); + for (final ChooseByNameContributor contributor : nameContributors) { try { - if (contributor instanceof ChooseByNameContributorEx) { - ((ChooseByNameContributorEx)contributor).processNames(processor, FindSymbolParameters.searchScopeFor(project, false), null); - } - else { - ContainerUtil.process(contributor.getNames(project, false), processor); - } + ContainerUtil.addAll(names, contributor.getNames(project, false)); } catch (ProcessCanceledException ex) { // index corruption detected, ignore @@ -261,6 +251,8 @@ public class FilePathCompletionContributor extends CompletionContributor { LOG.error(ex); } } + + return ArrayUtil.toStringArray(names); } @Nullable diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/EmptyExpression.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/EmptyExpression.java index 57e0881da359..d3ed5c500cac 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/EmptyExpression.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/EmptyExpression.java @@ -38,6 +38,11 @@ public class EmptyExpression extends Expression { return null; } + @Override + public boolean requiresCommittedPSI() { + return false; + } + @Override public LookupElement[] calculateLookupItems(ExpressionContext context) { return null; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/ConstantNode.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/ConstantNode.java index 6a9966f7ed3b..4448d0b6a1d0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/ConstantNode.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/ConstantNode.java @@ -39,6 +39,11 @@ public class ConstantNode extends Expression { return myValue; } + @Override + public boolean requiresCommittedPSI() { + return false; + } + @Override public LookupElement[] calculateLookupItems(ExpressionContext context) { return LookupElement.EMPTY_ARRAY; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/EmptyNode.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/EmptyNode.java index 95befd7418d3..1066c841d18e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/EmptyNode.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/EmptyNode.java @@ -35,6 +35,11 @@ public class EmptyNode extends Expression { return null; } + @Override + public boolean requiresCommittedPSI() { + return false; + } + @Override public LookupElement[] calculateLookupItems(ExpressionContext context) { return null; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/SelectionNode.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/SelectionNode.java index 040c4a9ff626..53c5b07c6302 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/SelectionNode.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/SelectionNode.java @@ -45,4 +45,8 @@ public class SelectionNode extends Expression { return calculateQuickResult(context); } + @Override + public boolean requiresCommittedPSI() { + return false; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java index 88a7d1de6d58..0f3079a4c6d9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateState.java @@ -832,11 +832,13 @@ public class TemplateState implements Disposable { int start = mySegments.getSegmentStart(segmentNumber); int end = mySegments.getSegmentEnd(segmentNumber); - PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + if(!isQuick || expressionNode.requiresCommittedPSI()) { + PsiDocumentManager.getInstance(myProject).commitDocument(myDocument); + } PsiFile psiFile = getPsiFile(); PsiElement element = psiFile != null ? psiFile.findElementAt(start) : null; - if (element != null) { - PsiUtilCore.ensureValid(element); + if (element != null && !element.isValid()) { + element = null; } ExpressionContext context = createExpressionContext(start); @@ -858,8 +860,8 @@ public class TemplateState implements Disposable { if (defaultValue != null && resultIsNullOrEmpty) { result = defaultValue.calculateResult(context); } - if (element != null) { - PsiUtilCore.ensureValid(element); + if (element != null && !element.isValid()) { + element = null; } if (result == null || result.equalsToText(oldValue, element)) return; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/VariableNode.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/VariableNode.java index 8dc75cc4e686..c1198c977201 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/VariableNode.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/VariableNode.java @@ -47,6 +47,11 @@ public class VariableNode extends Expression { return TemplateManagerImpl.getTemplateState(context.getEditor()).getVariableValue(getName()); } + @Override + public boolean requiresCommittedPSI() { + return myInitialValue != null && myInitialValue.requiresCommittedPSI(); + } + @Override public LookupElement[] calculateLookupItems(ExpressionContext context) { if (myInitialValue == null){ diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java index ea6408007b27..1ab856652a1a 100644 --- a/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ExecutorRegistryImpl.java @@ -332,8 +332,7 @@ public class ExecutorRegistryImpl extends ExecutorRegistry implements Disposable if (configuration instanceof CompoundRunConfiguration) { RunManager runManager = RunManager.getInstance(project); for (SettingsAndEffectiveTarget settingsAndEffectiveTarget : ((CompoundRunConfiguration)configuration).getConfigurationsWithEffectiveRunTargets()) { - RunConfiguration subConfiguration = settingsAndEffectiveTarget.getConfiguration(); - run(project, subConfiguration, runManager.findSettings(subConfiguration), dataContext); + run(project, settingsAndEffectiveTarget.getConfiguration(), runManager.findSettings(configuration), dataContext); } } else { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java index 20595163d120..3a0d2cf8464a 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java @@ -349,7 +349,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic @NotNull @Override public AnAction[] getChildren(@Nullable AnActionEvent e) { - if (e == null || mySelectedTab == null) return EMPTY_ARRAY; + if (e == null) return EMPTY_ARRAY; return mySelectedTab.actions.toArray(EMPTY_ARRAY); } }); @@ -424,6 +424,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic contributorsPanel.add(tab); myTabs.add(tab); }); + switchToTab(allTab); return contributorsPanel; } @@ -1426,8 +1427,8 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic @Override public void update(@NotNull AnActionEvent e) { - SearchEverywhereContributor contributor = mySelectedTab == null ? null : mySelectedTab.contributor; - e.getPresentation().setEnabled(contributor == null || contributor.showInFindResults()); + Boolean enabled = mySelectedTab.getContributor().map(contributor -> contributor.showInFindResults()).orElse(true); + e.getPresentation().setEnabled(enabled); } } diff --git a/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java b/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java index 05eb47b58d3c..e8b7f99b600a 100644 --- a/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java +++ b/platform/lang-impl/src/com/intellij/ide/extensionResources/ExtensionsRootType.java @@ -8,11 +8,7 @@ import com.intellij.ide.scratch.RootType; import com.intellij.ide.scratch.ScratchFileService; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.extensions.PluginDescriptor; import com.intellij.openapi.extensions.PluginId; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.io.FileUtil; @@ -23,7 +19,6 @@ import com.intellij.util.ObjectUtils; import com.intellij.util.PlatformUtils; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.io.DigestUtil; -import one.util.streamex.StreamEx; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,10 +28,8 @@ import java.io.IOException; import java.net.URL; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; -import java.util.Enumeration; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; /** *

Extensions root type provide a common interface for plugins to access resources that are modifiable by the user.

@@ -198,24 +191,17 @@ public class ExtensionsRootType extends RootType { private static List getBundledResourceUrls(@NotNull PluginId pluginId, @NotNull String path) throws IOException { String resourcesPath = EXTENSIONS_PATH + "/" + path; IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId); - if (plugin == null) return ContainerUtil.emptyList(); - ClassLoader pluginClassLoader = plugin.getPluginClassLoader(); - final Enumeration resources = pluginClassLoader.getResources(resourcesPath); - if (resources == null) return ContainerUtil.emptyList(); - if (plugin.getUseIdeaClassLoader()) return ContainerUtil.toList(resources); + ClassLoader pluginClassLoader = plugin != null ? plugin.getPluginClassLoader() : null; + Set urls = plugin == null ? null : ContainerUtil.newLinkedHashSet(ContainerUtil.toList(pluginClassLoader.getResources(resourcesPath))); + if (urls == null) return ContainerUtil.emptyList(); - final Set urls = ContainerUtil.newLinkedHashSet(ContainerUtil.toList(resources)); - // exclude parent classloader resources from list - final List dependentPluginClassLoaders = StreamEx.of(plugin.getDependentPluginIds()) - .map(PluginManager::getPlugin) - .nonNull() - .map(PluginDescriptor::getPluginClassLoader) - .without(pluginClassLoader) - .collect(Collectors.toList()); - - for (ClassLoader classLoader : dependentPluginClassLoaders) { - urls.removeAll(ContainerUtil.toList(classLoader.getResources(resourcesPath))); + PluginId corePluginId = PluginId.findId(PluginManagerCore.CORE_PLUGIN_ID); + IdeaPluginDescriptor corePlugin = ObjectUtils.notNull(PluginManager.getPlugin(corePluginId)); + ClassLoader coreClassLoader = corePlugin.getPluginClassLoader(); + if (coreClassLoader != pluginClassLoader && !plugin.getUseIdeaClassLoader() && !pluginId.equals(corePluginId)) { + urls.removeAll(ContainerUtil.toList(coreClassLoader.getResources(resourcesPath))); } + return ContainerUtil.newArrayList(urls); } @@ -283,23 +269,13 @@ public class ExtensionsRootType extends RootType { FileUtil.rename(file, newName); } - private void extractBundledExtensionsIfNeeded(@NotNull PluginId pluginId) { + private void extractBundledExtensionsIfNeeded(@NotNull PluginId pluginId) throws IOException { + if (!ApplicationManager.getApplication().isDispatchThread()) return; + IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId); if (plugin == null || !ResourceVersions.getInstance().shouldUpdateResourcesOf(plugin)) return; - Task.Backgroundable extractResourcesInBackground = - new Task.Backgroundable(null, "Extracting bundled extensions for plugin: " + pluginId.getIdString()) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - try { - extractBundledResources(pluginId, ""); - ApplicationManager.getApplication().invokeLater(() -> ResourceVersions.getInstance().resourcesUpdated(plugin)); - } - catch (IOException ex) { - LOG.warn("Failed to extract bundled extensions for plugin: " + plugin.getName(), ex); - } - } - }; - ProgressManager.getInstance().run(extractResourcesInBackground); + extractBundledResources(pluginId, ""); + ResourceVersions.getInstance().resourcesUpdated(plugin); } } diff --git a/platform/lang-impl/src/com/intellij/ide/extensionResources/RestoreBundledExtensionsAction.java b/platform/lang-impl/src/com/intellij/ide/extensionResources/RestoreBundledExtensionsAction.java index e5a8949da00c..e83bef678bad 100644 --- a/platform/lang-impl/src/com/intellij/ide/extensionResources/RestoreBundledExtensionsAction.java +++ b/platform/lang-impl/src/com/intellij/ide/extensionResources/RestoreBundledExtensionsAction.java @@ -4,12 +4,8 @@ package com.intellij.ide.extensionResources; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.extensions.PluginId; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -33,20 +29,11 @@ public class RestoreBundledExtensionsAction extends DumbAwareAction { assert file != null && pluginId != null && path != null; - Task.Backgroundable extractResourcesInBackground = new Task.Backgroundable( - e.getProject(), - "Extracting bundled extensions for plugin: " + pluginId.getIdString()) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - try { - extensionsRootType.extractBundledResources(pluginId, path); - VirtualFileManager.getInstance().refreshWithoutFileWatcher(true); - } - catch (IOException ex) { - ExtensionsRootType.LOG.warn("Failed to extract bundled extensions for " + file.getPath(), ex); - } - } - }; - ProgressManager.getInstance().run(extractResourcesInBackground); + try { + extensionsRootType.extractBundledResources(pluginId, path); + } + catch (IOException ex) { + ExtensionsRootType.LOG.warn("Failed to extract bundled extensions for " + file.getPath(), ex); + } } } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java index dfd2499ec4c3..711641ee0d0b 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ContributorsBasedGotoByModel.java @@ -16,10 +16,6 @@ import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.pom.PomTargetPsiElement; -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; import com.intellij.util.Processors; @@ -184,8 +180,7 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE if (LOG.isDebugEnabled()) { LOG.debug(System.currentTimeMillis() - contributorStarted + "," + contributor + ","); } - } - else { + } else { NavigationItem[] itemsByName = contributor.getItemsByName(name, parameters.getLocalPatternName(), myProject, searchInLibraries); for (NavigationItem item : itemsByName) { canceled.checkCanceled(); @@ -193,9 +188,6 @@ public abstract class ContributorsBasedGotoByModel implements ChooseByNameModelE PluginException.logPluginError(LOG, "null item from contributor " + contributor + " for name " + name, null, contributor.getClass()); continue; } - VirtualFile file = item instanceof PsiElement && !(item instanceof PomTargetPsiElement) - ? PsiUtilCore.getVirtualFile((PsiElement)item) : null; - if (file != null && !parameters.getSearchScope().contains(file)) continue; if (acceptItem(item)) { items.add(item); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java index 6e5aa1400628..2e15d71d6b3d 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/DefaultFileNavigationContributor.java @@ -19,18 +19,49 @@ import com.intellij.navigation.ChooseByNameContributorEx; import com.intellij.navigation.NavigationItem; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.PsiFileSystemItem; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; +import com.intellij.util.Processors; import com.intellij.util.indexing.FindSymbolParameters; import com.intellij.util.indexing.IdFilter; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; + public class DefaultFileNavigationContributor implements ChooseByNameContributorEx, DumbAware { private static final Logger LOG = Logger.getInstance(DefaultFileNavigationContributor.class); + @Override + @NotNull + public String[] getNames(Project project, boolean includeNonProjectItems) { + THashSet names = new THashSet<>(1000); + IdFilter filter = IdFilter.getProjectIdFilter(project, includeNonProjectItems); + processNames(s -> { + names.add(s); + return true; + }, FindSymbolParameters.searchScopeFor(project, includeNonProjectItems), filter); + if (LOG.isDebugEnabled()) { + LOG.debug("All names retrieved2:" + names.size()); + } + return ArrayUtil.toStringArray(names); + } + + @Override + @NotNull + public NavigationItem[] getItemsByName(String name, final String pattern, Project project, boolean includeNonProjectItems) { + List result = new ArrayList<>(); + Processor processor = Processors.cancelableCollectProcessor(result); + processElementsWithName(name, processor, FindSymbolParameters.wrap(pattern, project, includeNonProjectItems)); + + return result.isEmpty() ? NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY : result.toArray(NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY); + } @Override public void processNames(@NotNull final Processor processor, @NotNull GlobalSearchScope scope, IdFilter filter) { diff --git a/platform/lang-impl/src/com/intellij/navigation/ChooseByNameContributorEx.java b/platform/lang-impl/src/com/intellij/navigation/ChooseByNameContributorEx.java index 77df680dbd2a..f6e1f0aceba6 100644 --- a/platform/lang-impl/src/com/intellij/navigation/ChooseByNameContributorEx.java +++ b/platform/lang-impl/src/com/intellij/navigation/ChooseByNameContributorEx.java @@ -15,18 +15,13 @@ */ package com.intellij.navigation; -import com.intellij.openapi.project.Project; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.util.ArrayUtil; import com.intellij.util.Processor; import com.intellij.util.indexing.FindSymbolParameters; import com.intellij.util.indexing.IdFilter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - public interface ChooseByNameContributorEx extends ChooseByNameContributor { void processNames(@NotNull Processor processor, @@ -36,24 +31,4 @@ public interface ChooseByNameContributorEx extends ChooseByNameContributor { void processElementsWithName(@NotNull String name, @NotNull Processor processor, @NotNull FindSymbolParameters parameters); - - /** @deprecated Use {@link #processNames(Processor, GlobalSearchScope, IdFilter)} instead */ - @Deprecated - @Override - @NotNull - default String[] getNames(Project project, boolean includeNonProjectItems) { - List result = new ArrayList<>(); - processNames(result::add, FindSymbolParameters.searchScopeFor(project, includeNonProjectItems), null); - return ArrayUtil.toStringArray(result); - } - - /** @deprecated Use {@link #processElementsWithName(String, Processor, FindSymbolParameters)} instead */ - @Deprecated - @Override - @NotNull - default NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) { - List result = new ArrayList<>(); - processElementsWithName(name, result::add, FindSymbolParameters.simple(project, includeNonProjectItems)); - return result.isEmpty() ? NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY : result.toArray(NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY); - } } diff --git a/platform/lang-impl/src/com/intellij/navigation/JBProtocolNavigateCommand.kt b/platform/lang-impl/src/com/intellij/navigation/JBProtocolNavigateCommand.kt index 40dfdd130d7f..d1e1b6b26241 100644 --- a/platform/lang-impl/src/com/intellij/navigation/JBProtocolNavigateCommand.kt +++ b/platform/lang-impl/src/com/intellij/navigation/JBProtocolNavigateCommand.kt @@ -25,7 +25,7 @@ import com.intellij.openapi.wm.IdeFocusManager import java.io.File import java.util.regex.Pattern -internal class JBProtocolNavigateCommand : JBProtocolCommand(NAVIGATE_COMMAND) { +class JBProtocolNavigateCommand : JBProtocolCommand(NAVIGATE_COMMAND) { override fun perform(target: String, parameters: Map) { // handles URLs of the following types: diff --git a/platform/lang-impl/src/com/intellij/openapi/util/objectTree/DisposerDebugger.java b/platform/lang-impl/src/com/intellij/openapi/util/objectTree/DisposerDebugger.java index 839a3d91dab5..ce3b98b22fc5 100644 --- a/platform/lang-impl/src/com/intellij/openapi/util/objectTree/DisposerDebugger.java +++ b/platform/lang-impl/src/com/intellij/openapi/util/objectTree/DisposerDebugger.java @@ -255,7 +255,7 @@ public class DisposerDebugger implements UiDebuggerExtension, Disposable { } private void queueUpdate() { - UIUtil.invokeLaterIfNeeded(() -> myTreeBuilder.refilterAsync()); + UIUtil.invokeLaterIfNeeded(() -> myTreeBuilder.refilter()); } @Override @@ -275,7 +275,7 @@ public class DisposerDebugger implements UiDebuggerExtension, Disposable { public void clear() { myModificationToFilter = Disposer.getTree().getModification(); - myTreeBuilder.refilterAsync(); + myTreeBuilder.refilter(); } } diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingForwardIndexAccessor.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingForwardIndexAccessor.java index d3cbf854301a..be57c5c9296a 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingForwardIndexAccessor.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubUpdatingForwardIndexAccessor.java @@ -5,6 +5,7 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.FileContent; import com.intellij.util.indexing.ID; +import com.intellij.util.indexing.impl.InputData; import com.intellij.util.indexing.impl.InputDataDiffBuilder; import com.intellij.util.indexing.impl.forward.AbstractForwardIndexAccessor; import com.intellij.util.io.DataExternalizer; @@ -19,7 +20,7 @@ import java.io.IOException; import java.util.Collections; import java.util.Map; -class StubUpdatingForwardIndexAccessor extends AbstractForwardIndexAccessor { +class StubUpdatingForwardIndexAccessor extends AbstractForwardIndexAccessor { StubUpdatingForwardIndexAccessor() {super(new DataExternalizer() { private volatile boolean myEnsuredStubElementTypesLoaded; @@ -68,10 +69,10 @@ class StubUpdatingForwardIndexAccessor extends AbstractForwardIndexAccessor map, - @Nullable FileContent content) { - return getIndexedStubs(map); + public IndexedStubs convertToDataType(@NotNull InputData data) { + return getIndexedStubs(data.getKeyValues()); } @Override diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java index 1c3a7597b6d5..47666922659f 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MyLookupExpression.java @@ -97,6 +97,11 @@ public class MyLookupExpression extends Expression { return new TextResult(myName); } + @Override + public boolean requiresCommittedPSI() { + return false; + } + @Override public String getAdvertisingText() { return myAdvertisementText; diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FindSymbolParameters.java b/platform/lang-impl/src/com/intellij/util/indexing/FindSymbolParameters.java index b77176415d46..7618193430f5 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FindSymbolParameters.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FindSymbolParameters.java @@ -7,6 +7,7 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.search.EverythingGlobalScope; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.ProjectScope; +import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -68,12 +69,12 @@ public class FindSymbolParameters { } public static FindSymbolParameters wrap(@NotNull String pattern, @NotNull Project project, boolean searchInLibraries) { - return new FindSymbolParameters(pattern, pattern, searchScopeFor(project, searchInLibraries), - IdFilter.getProjectIdFilter(project, searchInLibraries)); + return new FindSymbolParameters(pattern, pattern, searchScopeFor(project, searchInLibraries), null); } public static FindSymbolParameters wrap(@NotNull String pattern, @NotNull GlobalSearchScope scope) { - return new FindSymbolParameters(pattern, pattern, scope, null); + IdFilter idFilter = IdFilter.getProjectIdFilter(ObjectUtils.notNull(scope.getProject()), scope.isSearchInLibraries()); + return new FindSymbolParameters(pattern, pattern, scope, idFilter); } public static FindSymbolParameters simple(@NotNull Project project, boolean searchInLibraries) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/HashIdForwardIndexAccessor.java b/platform/lang-impl/src/com/intellij/util/indexing/HashIdForwardIndexAccessor.java index ccad9895626b..0b97d75a0f57 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/HashIdForwardIndexAccessor.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/HashIdForwardIndexAccessor.java @@ -1,6 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.util.indexing; +import com.intellij.util.indexing.impl.InputData; import com.intellij.util.indexing.impl.InputDataDiffBuilder; import com.intellij.util.indexing.impl.MapInputDataDiffBuilder; import com.intellij.util.indexing.impl.forward.AbstractMapForwardIndexAccessor; @@ -13,8 +14,8 @@ import java.io.IOException; import java.util.Map; class HashIdForwardIndexAccessor - extends AbstractMapForwardIndexAccessor - implements IntForwardIndexAccessor { + extends AbstractMapForwardIndexAccessor + implements IntForwardIndexAccessor { private final UpdatableSnapshotInputMappingIndex mySnapshotInputMappingIndex; HashIdForwardIndexAccessor(@NotNull UpdatableSnapshotInputMappingIndex snapshotInputMappingIndex) { @@ -35,12 +36,13 @@ class HashIdForwardIndexAccessor } @Override - public int convertToInt(@Nullable Map map, @Nullable Input content) { - try { - return mySnapshotInputMappingIndex.getHashId(content); - } - catch (IOException e) { - throw new RuntimeException(e); - } + public int serializeIndexedDataToInt(@NotNull InputData data) { + return data == InputData.empty() ? 0 : ((HashedInputData)data).getHashId(); + } + + @Nullable + @Override + public Integer convertToDataType(@NotNull InputData data) { + return serializeIndexedDataToInt(data); } } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/HashedInputData.java b/platform/lang-impl/src/com/intellij/util/indexing/HashedInputData.java new file mode 100644 index 000000000000..017f4d824268 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/util/indexing/HashedInputData.java @@ -0,0 +1,20 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.util.indexing; + +import com.intellij.util.indexing.impl.InputData; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +public class HashedInputData extends InputData { + private final int myHashId; + + protected HashedInputData(@NotNull Map values, int hashId) { + super(values); + myHashId = hashId; + } + + public int getHashId() { + return myHashId; + } +} diff --git a/platform/lang-impl/src/com/intellij/util/indexing/SharedMapForwardIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/SharedMapForwardIndex.java index 4264e2da4149..2bad7017ab12 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/SharedMapForwardIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/SharedMapForwardIndex.java @@ -26,10 +26,10 @@ public class SharedMapForwardIndex implements ForwardIndex { // only verification purpose @Nullable - private final AbstractForwardIndexAccessor myAccessor; + private final AbstractForwardIndexAccessor myAccessor; public SharedMapForwardIndex(@NotNull IndexExtension extension, - @Nullable AbstractForwardIndexAccessor accessor, + @Nullable AbstractForwardIndexAccessor accessor, @Nullable File verificationIndexStorageFile, boolean verificationIndexHasChunks) throws IOException { myIndexId = (ID)extension.getName(); diff --git a/platform/lang-impl/src/com/intellij/util/indexing/SnapshotInputMappingIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/SnapshotInputMappingIndex.java index a72497ac243a..52c3575e4391 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/SnapshotInputMappingIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/SnapshotInputMappingIndex.java @@ -1,6 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.util.indexing; +import com.intellij.util.indexing.impl.InputData; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,5 +13,5 @@ import java.util.Map; @ApiStatus.Experimental public interface SnapshotInputMappingIndex extends Closeable { @Nullable - Map readData(@NotNull Input content) throws IOException; + InputData readData(@NotNull Input content) throws IOException; } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/SnapshotInputMappings.java b/platform/lang-impl/src/com/intellij/util/indexing/SnapshotInputMappings.java index 2962d50957ce..e0ebd2ed7634 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/SnapshotInputMappings.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/SnapshotInputMappings.java @@ -13,6 +13,7 @@ import com.intellij.util.CompressionUtil; import com.intellij.util.ExceptionUtil; import com.intellij.util.SystemProperties; import com.intellij.util.indexing.impl.DebugAssertions; +import com.intellij.util.indexing.impl.InputData; import com.intellij.util.indexing.impl.forward.AbstractForwardIndexAccessor; import com.intellij.util.indexing.impl.forward.PersistentMapBasedForwardIndex; import com.intellij.util.io.*; @@ -70,12 +71,13 @@ class SnapshotInputMappings implements UpdatableSnapshotInput @Nullable @Override - public Map readData(@NotNull Input content) throws IOException { + public InputData readData(@NotNull Input content) throws IOException { Map data = null; + int hashId = 0; if (doReadSavedPersistentData) { if (myContents == null || !myContents.isBusyReading() || DebugAssertions.EXTRA_SANITY_CHECKS) { // avoid blocking read, we can calculate index value - int hashId = getHashId(content); + hashId = getHashId(content); ByteArraySequence bytes = readContents(hashId); if (bytes != null) { @@ -96,25 +98,32 @@ class SnapshotInputMappings implements UpdatableSnapshotInput } } } - return data; + return data == null ? null : new HashedInputData<>(data, hashId); } @Override - public void putData(@Nullable Input content, @NotNull Map data) throws IOException { - int hashId = getHashId(content); - boolean saved = savePersistentData(data, hashId); + public InputData putData(@Nullable Input content, @NotNull InputData data) throws IOException { + int hashId; + InputData result; + if (data instanceof HashedInputData) { + hashId = ((HashedInputData)data).getHashId(); + result = data; + } else { + hashId = getHashId(content); + result = hashId == 0 ? InputData.empty() : new HashedInputData<>(data.getKeyValues(), hashId); + } + boolean saved = savePersistentData(data.getKeyValues(), hashId); if (DebugAssertions.EXTRA_SANITY_CHECKS) { if (saved) { try { - myIndexingTrace.put(hashId, getContentDebugData(content) + - "," + - ExceptionUtil.getThrowableText(new Throwable())); + myIndexingTrace.put(hashId, getContentDebugData(content) + "," + ExceptionUtil.getThrowableText(new Throwable())); } catch (IOException ex) { LOG.error(ex); } } } + return result; } @NotNull @@ -123,8 +132,7 @@ class SnapshotInputMappings implements UpdatableSnapshotInput return "[" + content.getFile().getPath() + ";" + content.getFileType().getName() + ";" + content.getCharset() + "]"; } - @Override - public int getHashId(@Nullable Input content) throws IOException { + private int getHashId(@Nullable Input content) throws IOException { return content == null ? 0 : getHashOfContent((FileContent) content); } diff --git a/platform/lang-impl/src/com/intellij/util/indexing/UpdatableSnapshotInputMappingIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/UpdatableSnapshotInputMappingIndex.java index 26176227537d..b9a467618a98 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/UpdatableSnapshotInputMappingIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/UpdatableSnapshotInputMappingIndex.java @@ -1,6 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.util.indexing; +import com.intellij.util.indexing.impl.InputData; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -13,9 +14,7 @@ public interface UpdatableSnapshotInputMappingIndex extends S @NotNull Map readData(int hashId) throws IOException; - void putData(@NotNull Input content, @NotNull Map data) throws IOException; - - int getHashId(@Nullable Input content) throws IOException; + InputData putData(@NotNull Input content, @NotNull InputData data) throws IOException; void flush() throws IOException; diff --git a/platform/lang-impl/src/com/intellij/util/indexing/VfsAwareMapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/VfsAwareMapReduceIndex.java index 13601fb70ff7..8045098dd39a 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/VfsAwareMapReduceIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/VfsAwareMapReduceIndex.java @@ -72,7 +72,7 @@ public class VfsAwareMapReduceIndex extends MapReduceIndex extension, @NotNull IndexStorage storage, @Nullable ForwardIndex forwardIndexMap, - @Nullable ForwardIndexAccessor forwardIndexAccessor, + @Nullable ForwardIndexAccessor forwardIndexAccessor, @Nullable SnapshotInputMappingIndex snapshotInputMappings) { super(extension, storage, forwardIndexMap, forwardIndexAccessor, null); SharedIndicesData.registerIndex((ID)myIndexId, extension); @@ -89,8 +89,8 @@ public class VfsAwareMapReduceIndex extends MapReduceIndex mapInput(@Nullable Input content) { - Map data; + protected InputData mapInput(@Nullable Input content) { + InputData data; boolean containsSnapshotData = true; if (mySnapshotInputMappings != null && !myInMemoryMode.get() && content != null) { try { @@ -108,7 +108,7 @@ public class VfsAwareMapReduceIndex extends MapReduceIndex extends MapReduceIndex data, @Nullable Object forwardIndexData) throws IOException { + protected void updateForwardIndex(int inputId, @NotNull InputData data) throws IOException { if (myInMemoryMode.get()) { synchronized (myInMemoryKeysAndValues) { - myInMemoryKeysAndValues.put(inputId, data); + myInMemoryKeysAndValues.put(inputId, data.getKeyValues()); } } else { - super.updateForwardIndex(inputId, data, forwardIndexData); + super.updateForwardIndex(inputId, data); } } @@ -248,7 +248,7 @@ public class VfsAwareMapReduceIndex extends MapReduceIndex forwardIndexAccessor = (AbstractMapForwardIndexAccessor)getForwardIndexAccessor(); + AbstractMapForwardIndexAccessor forwardIndexAccessor = (AbstractMapForwardIndexAccessor)getForwardIndexAccessor(); return forwardIndexAccessor.convertToInputDataMap(serializedInputData); } // in future we will get rid of forward index for SingleEntryFileBasedIndexExtension @@ -319,7 +319,7 @@ public class VfsAwareMapReduceIndex extends MapReduceIndex ForwardIndexAccessor getForwardIndexAccessor(@NotNull IndexExtension indexExtension) { + private static ForwardIndexAccessor getForwardIndexAccessor(@NotNull IndexExtension indexExtension) { if (!shouldCreateForwardIndex(indexExtension)) return null; return new MapForwardIndexAccessor<>(new InputMapExternalizer<>(indexExtension)); } diff --git a/platform/platform-api/src/com/intellij/ide/ui/search/ConfigurableHit.java b/platform/platform-api/src/com/intellij/ide/ui/search/ConfigurableHit.java new file mode 100644 index 000000000000..bf7f22b0e65d --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/ui/search/ConfigurableHit.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2009 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.ide.ui.search; + +import com.intellij.openapi.options.Configurable; + +import java.util.Set; +import java.util.LinkedHashSet; + +public final class ConfigurableHit { + + private final Set myNameHits = new LinkedHashSet<>(); + private final Set myContentHits = new LinkedHashSet<>(); + + private final Set myNameFullHit = new LinkedHashSet<>(); + + ConfigurableHit() { + } + + public Set getNameHits() { + return myNameHits; + } + + public Set getNameFullHits() { + return myNameFullHit; + } + + public Set getContentHits() { + return myContentHits; + } + + public Set getAll() { + final LinkedHashSet all = new LinkedHashSet<>(myNameHits.size() + myContentHits.size()); + all.addAll(myNameHits); + all.addAll(myContentHits); + return all; + } +} diff --git a/platform/platform-api/src/com/intellij/ide/ui/search/ConfigurableHit.kt b/platform/platform-api/src/com/intellij/ide/ui/search/ConfigurableHit.kt deleted file mode 100644 index 1b4d71d48cc8..000000000000 --- a/platform/platform-api/src/com/intellij/ide/ui/search/ConfigurableHit.kt +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.ide.ui.search - -import com.intellij.openapi.options.Configurable -import java.util.* - -data class ConfigurableHit(val contentHits: Set, val nameHits: Set, val nameFullHits: Set) { - val all: Set - get() { - val all = LinkedHashSet(nameHits.size + contentHits.size) - all.addAll(nameHits) - all.addAll(contentHits) - return all - } -} diff --git a/platform/platform-api/src/com/intellij/ide/ui/search/SearchableOptionsRegistrar.java b/platform/platform-api/src/com/intellij/ide/ui/search/SearchableOptionsRegistrar.java index 070b2b87f933..13dee75186b6 100644 --- a/platform/platform-api/src/com/intellij/ide/ui/search/SearchableOptionsRegistrar.java +++ b/platform/platform-api/src/com/intellij/ide/ui/search/SearchableOptionsRegistrar.java @@ -1,4 +1,5 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + package com.intellij.ide.ui.search; import com.intellij.openapi.components.ServiceManager; @@ -10,22 +11,22 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.event.DocumentEvent; -import java.util.List; +import java.util.Map; import java.util.Set; public abstract class SearchableOptionsRegistrar{ public static final String SEARCHABLE_OPTIONS_XML = "searchableOptions.xml"; - public static SearchableOptionsRegistrar getInstance() { + public static SearchableOptionsRegistrar getInstance(){ return ServiceManager.getService(SearchableOptionsRegistrar.class); } @NotNull - public abstract ConfigurableHit getConfigurables(@NotNull List groups, - final DocumentEvent.EventType type, - @Nullable Set configurables, - @NotNull String option, - @Nullable Project project); + public abstract ConfigurableHit getConfigurables(final ConfigurableGroup[] groups, + final DocumentEvent.EventType type, + final Set configurables, + final String option, + final Project project); @Nullable public abstract String getInnerPath(SearchableConfigurable configurable, String option); @@ -38,7 +39,11 @@ public abstract class SearchableOptionsRegistrar{ public abstract Set replaceSynonyms(Set options, SearchableConfigurable configurable); + public abstract Map> findPossibleExtension(@NotNull String prefix, final Project project); + + public abstract Set getProcessedWordsWithoutStemming(@NotNull String text); public abstract Set getProcessedWords(@NotNull String text); + } diff --git a/platform/platform-api/src/com/intellij/openapi/MnemonicHelper.java b/platform/platform-api/src/com/intellij/openapi/MnemonicHelper.java index 0a8858503f54..9d4fb44dbf63 100644 --- a/platform/platform-api/src/com/intellij/openapi/MnemonicHelper.java +++ b/platform/platform-api/src/com/intellij/openapi/MnemonicHelper.java @@ -22,6 +22,7 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; import com.intellij.ui.ComponentTreeWatcher; import com.intellij.util.ArrayUtil; +import com.intellij.util.containers.JBTreeTraverser; import com.intellij.util.ui.DialogUtil; import com.intellij.util.ui.UIUtil; import org.intellij.lang.annotations.MagicConstant; @@ -182,7 +183,9 @@ public class MnemonicHelper extends ComponentTreeWatcher { private static class MnemonicFixer implements ContainerListener { void addTo(Component component) { - for (Component c : UIUtil.uiTraverser(component)) { + JBTreeTraverser traverser = UIUtil.uiTraverser(component) + .expandAndFilter(o -> !(o instanceof CellRendererPane)); + for (Component c : traverser) { if (c instanceof Container) ((Container)c).addContainerListener(this); if (c instanceof ActionButtonComponent) fixMacMnemonicKeyStroke((JComponent)c, null); MnemonicWrapper.getWrapper(c); @@ -190,7 +193,9 @@ public class MnemonicHelper extends ComponentTreeWatcher { } void removeFrom(Component component) { - for (Container c : UIUtil.uiTraverser(component).filter(Container.class)) { + JBTreeTraverser traverser = UIUtil.uiTraverser(component) + .expandAndFilter(o -> !(o instanceof CellRendererPane)); + for (Container c : traverser.traverse().filter(Container.class)) { c.removeContainerListener(this); } } diff --git a/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java b/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java index 9ed57389c36c..d6e2aaca64d7 100644 --- a/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java +++ b/platform/platform-api/src/com/intellij/openapi/options/ShowSettingsUtil.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.options; import com.intellij.openapi.components.ServiceManager; @@ -23,7 +23,7 @@ public abstract class ShowSettingsUtil { public abstract void showSettingsDialog(@Nullable Project project, @NotNull String nameToSelect); - public abstract void showSettingsDialog(@NotNull Project project, @Nullable Configurable toSelect); + public abstract void showSettingsDialog(@NotNull final Project project, final Configurable toSelect); public abstract void showSettingsDialog(@Nullable Project project, @NotNull Class configurableClass, @@ -47,6 +47,13 @@ public abstract class ShowSettingsUtil { public abstract boolean editConfigurable(Component parent, String dimensionServiceKey, Configurable configurable); + /** + * @deprecated create a new instance of configurable instead + * to remove in IDEA 15 + */ + @Deprecated + public abstract T findProjectConfigurable(Project project, Class confClass); + public static String getSettingsMenuName() { return SystemInfo.isMac ? "Preferences" : "Settings"; } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/TestDialog.java b/platform/platform-api/src/com/intellij/openapi/ui/TestDialog.java index b3a4ce413b09..73b0999833eb 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/TestDialog.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/TestDialog.java @@ -1,14 +1,25 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.ui; -import org.jetbrains.annotations.NotNull; - public interface TestDialog { - TestDialog DEFAULT = message -> { - throw new RuntimeException(message); + TestDialog DEFAULT = new TestDialog() { + @Override + public int show(String message) { + throw new RuntimeException(message); + } + }; + TestDialog OK = new TestDialog() { + @Override + public int show(String message) { + return 0; + } + }; + TestDialog NO = new TestDialog() { + @Override + public int show(String message) { + return Messages.NO; + } }; - TestDialog OK = __ -> Messages.OK; - TestDialog NO = __ -> Messages.NO; - int show(@NotNull String message); + int show(String message); } diff --git a/platform/platform-api/src/com/intellij/ui/speedSearch/ElementFilter.java b/platform/platform-api/src/com/intellij/ui/speedSearch/ElementFilter.java index 60c5e681a2bc..4bc4961937fe 100644 --- a/platform/platform-api/src/com/intellij/ui/speedSearch/ElementFilter.java +++ b/platform/platform-api/src/com/intellij/ui/speedSearch/ElementFilter.java @@ -1,13 +1,24 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.ui.speedSearch; import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; -import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.concurrency.Promises; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -16,8 +27,7 @@ public interface ElementFilter { boolean shouldBeShowing(T value); interface Active extends ElementFilter { - @NotNull - Promise fireUpdate(@Nullable final T preferredSelection, final boolean adjustSelection, final boolean now); + ActionCallback fireUpdate(@Nullable final T preferredSelection, final boolean adjustSelection, final boolean now); void addListener(Listener listener, Disposable parent); @@ -25,9 +35,14 @@ public interface ElementFilter { Set> myListeners = new CopyOnWriteArraySet<>(); @Override - @NotNull - public Promise fireUpdate(@Nullable T preferredSelection, boolean adjustSelection, boolean now) { - return Promises.all(ContainerUtil.map(myListeners, listener -> listener.update(preferredSelection, adjustSelection, now))); + public ActionCallback fireUpdate(@Nullable final T preferredSelection, final boolean adjustSelection, final boolean now) { + final ActionCallback result = new ActionCallback(myListeners.size()); + + for (final Listener myListener : myListeners) { + myListener.update(preferredSelection, adjustSelection, now).doWhenProcessed(result.createSetDoneRunnable()); + } + + return result; } @Override @@ -44,7 +59,6 @@ public interface ElementFilter { } interface Listener { - @NotNull - Promise update(@Nullable final T preferredSelection, final boolean adjustSelection, final boolean now); + ActionCallback update(@Nullable final T preferredSelection, final boolean adjustSelection, final boolean now); } } \ No newline at end of file diff --git a/platform/platform-api/src/com/intellij/ui/tabs/newImpl/TabLabel.java b/platform/platform-api/src/com/intellij/ui/tabs/newImpl/TabLabel.java index cd1aaeeb322f..a22ad2262d3c 100644 --- a/platform/platform-api/src/com/intellij/ui/tabs/newImpl/TabLabel.java +++ b/platform/platform-api/src/com/intellij/ui/tabs/newImpl/TabLabel.java @@ -182,20 +182,14 @@ public class TabLabel extends JPanel implements Accessible { @Override public Insets getInsets() { Insets insets = super.getInsets(); - boolean hasCloseButtonOnTheLeft = false; if (myTabs.isEditorTabs() && UISettings.getShadowInstance().getShowCloseButton() && hasIcons()) { if (UISettings.getShadowInstance().getCloseTabButtonOnTheRight()) { insets.right -= JBUI.scale(4); } else { - hasCloseButtonOnTheLeft = true; insets.left -= JBUI.scale(4); } } - // We reserve extra space inside file icon for (*) marker but mostly this space looks like wasted one - if (myTabs.isEditorTabs() && UISettings.getShadowInstance().getMarkModifiedTabsWithAsterisk() && !hasCloseButtonOnTheLeft) { - insets.left -= JBUI.scale(7); - } return insets; } diff --git a/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java b/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java index 952d771ca137..8ae2e5bfb541 100644 --- a/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java +++ b/platform/platform-api/src/com/intellij/ui/treeStructure/filtered/FilteringTreeBuilder.java @@ -1,4 +1,18 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.ui.treeStructure.filtered; import com.intellij.ide.util.treeView.AbstractTreeBuilder; @@ -14,11 +28,7 @@ import com.intellij.ui.treeStructure.Tree; import com.intellij.util.ui.tree.TreeUtil; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.AsyncPromise; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.concurrency.Promises; import javax.swing.*; import javax.swing.event.TreeSelectionEvent; @@ -50,9 +60,8 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder { if (filter instanceof ElementFilter.Active) { ((ElementFilter.Active)filter).addListener(new ElementFilter.Listener() { - @NotNull @Override - public Promise update(final Object preferredSelection, final boolean adjustSelection, final boolean now) { + public ActionCallback update(final Object preferredSelection, final boolean adjustSelection, final boolean now) { return refilter(preferredSelection, adjustSelection, now); } }, this); @@ -107,65 +116,50 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder { return true; } - @NotNull - @Deprecated public ActionCallback refilter() { - //noinspection unchecked - return Promises.toActionCallback((Promise)refilter(null, true, false)); - } - - @SuppressWarnings("UnusedReturnValue") - @NotNull - public Promise refilterAsync() { return refilter(null, true, false); } - @NotNull - public Promise refilter(@Nullable final Object preferredSelection, final boolean adjustSelection, final boolean now) { + public ActionCallback refilter(@Nullable final Object preferredSelection, final boolean adjustSelection, final boolean now) { if (myRefilterQueue != null) { myRefilterQueue.cancelAllUpdates(); } - - AsyncPromise result = new AsyncPromise<>(); + final ActionCallback callback = new ActionCallback(); final Runnable afterCancelUpdate = new Runnable() { @Override public void run() { if (myRefilterQueue == null || now) { - refilterNow(preferredSelection, adjustSelection) - .onSuccess(o -> result.setResult(null)); + refilterNow(preferredSelection, adjustSelection).doWhenDone(callback.createSetDoneRunnable()); } else { myRefilterQueue.queue(new Update(this) { @Override public void run() { - refilterNow(preferredSelection, adjustSelection); + refilterNow(preferredSelection, adjustSelection).notifyWhenDone(callback); } @Override public void setRejected() { super.setRejected(); - result.setResult(null); + callback.setDone(); } }); } } }; - if (!isDisposed()) { if (!ApplicationManager.getApplication().isUnitTestMode()) { getUi().cancelUpdate().doWhenProcessed(afterCancelUpdate); - } - else { + } else { afterCancelUpdate.run(); } } - return result; + return callback; } - @NotNull - protected Promise refilterNow(Object preferredSelection, boolean adjustSelection) { + protected ActionCallback refilterNow(final Object preferredSelection, final boolean adjustSelection) { final ActionCallback selectionDone = new ActionCallback(); getFilteredStructure().refilter(); @@ -197,32 +191,28 @@ public class FilteringTreeBuilder extends AbstractTreeBuilder { }; if (!ApplicationManager.getApplication().isUnitTestMode()) { queueUpdate().doWhenProcessed(selectionRunnable); - } - else { + } else { selectionRunnable.run(); } - AsyncPromise result = new AsyncPromise<>(); - selectionDone - .doWhenDone(new Runnable() { + final ActionCallback result = new ActionCallback(); + + selectionDone.doWhenDone(new Runnable() { @Override public void run() { if (!ApplicationManager.getApplication().isUnitTestMode()) { scrollSelectionToVisible(new Runnable() { @Override public void run() { - getReady(this) - .doWhenDone(() -> result.setResult(null)) - .doWhenRejected(s -> result.setError(s)); + getReady(this).notify(result); } }, false); - } - else { - result.setResult(null); + } else { + result.setDone(); } } - }) - .doWhenRejected(() -> result.cancel(true)); + }).notifyWhenRejected(result); + return result; } diff --git a/platform/platform-impl/src/com/intellij/diagnostic/IdeaFreezeReporter.java b/platform/platform-impl/src/com/intellij/diagnostic/IdeaFreezeReporter.java index f468f5397e7f..8433e6538716 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/IdeaFreezeReporter.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/IdeaFreezeReporter.java @@ -50,7 +50,7 @@ public class IdeaFreezeReporter { if (Registry.is("performance.watcher.freeze.report") && lengthInSeconds > FREEZE_THRESHOLD && // check that we have at least half of the dumps required - myCurrentDumps.size() >= Math.max(3, lengthInSeconds * 500 / Registry.intValue("performance.watcher.unresponsive.interval.ms")) && + myCurrentDumps.size() >= lengthInSeconds * 500 / Registry.intValue("performance.watcher.unresponsive.interval.ms") && !ContainerUtil.isEmpty(myStacktraceCommonPart) && !DebugAttachDetector.isAttached()) { int size = Math.min(myCurrentDumps.size(), 20); // report up to 20 dumps diff --git a/platform/platform-impl/src/com/intellij/ide/IdePopupManager.java b/platform/platform-impl/src/com/intellij/ide/IdePopupManager.java index d14fa8820c49..30d1e03e8d52 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdePopupManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdePopupManager.java @@ -16,11 +16,8 @@ package com.intellij.ide; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher; import com.intellij.openapi.ui.popup.IdePopupEventDispatcher; import com.intellij.openapi.ui.popup.JBPopup; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.ex.IdeFrameEx; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.UIUtil; @@ -28,7 +25,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; @@ -39,7 +35,6 @@ public final class IdePopupManager implements IdeEventQueue.EventDispatcher { private static final Logger LOG = Logger.getInstance("com.intellij.ide.IdePopupManager"); private final List myDispatchStack = ContainerUtil.createLockFreeCopyOnWriteList(); - private boolean myIgnoreNextKeyTypedEvent; boolean isPopupActive() { for (IdePopupEventDispatcher each : myDispatchStack) { @@ -85,24 +80,6 @@ public final class IdePopupManager implements IdeEventQueue.EventDispatcher { closeAllPopups(); } } - else if (e instanceof KeyEvent) { - // the following is copied from IdeKeyEventDispatcher - KeyEvent keyEvent = (KeyEvent)e; - Object source = keyEvent.getSource(); - if (myIgnoreNextKeyTypedEvent) { - if (KeyEvent.KEY_TYPED == e.getID()) return true; - myIgnoreNextKeyTypedEvent = false; - } - else if (SystemInfo.isMac && InputEvent.ALT_DOWN_MASK == keyEvent.getModifiersEx() && - Registry.is("ide.mac.alt.mnemonic.without.ctrl") && source instanceof Component) { - // the myIgnoreNextKeyTypedEvent changes event processing to support Alt-based mnemonics on Mac only - if ((KeyEvent.KEY_TYPED == e.getID() && !IdeEventQueue.getInstance().isInputMethodEnabled()) || - IdeKeyEventDispatcher.hasMnemonicInWindow((Component)source, keyEvent)) { - myIgnoreNextKeyTypedEvent = true; - return false; - } - } - } if (e instanceof KeyEvent || e instanceof MouseEvent) { for (int i = myDispatchStack.size() - 1; (i >= 0 && i < myDispatchStack.size()); i--) { diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ProjectViewEditSourceAction.kt b/platform/platform-impl/src/com/intellij/ide/actions/ProjectViewEditSourceAction.kt deleted file mode 100644 index 23b2571e0f03..000000000000 --- a/platform/platform-impl/src/com/intellij/ide/actions/ProjectViewEditSourceAction.kt +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.ide.actions - -import com.intellij.openapi.actionSystem.AnActionEvent -import com.intellij.openapi.fileEditor.OpenFileDescriptor -import com.intellij.pom.NavigatableWithText - -/** - * @author yole - */ -class ProjectViewEditSourceAction : BaseNavigateToSourceAction(true) { - override fun update(e: AnActionEvent) { - super.update(e) - if (!e.presentation.isVisible || !e.presentation.isEnabled) return - val navigatables = getNavigatables(e.dataContext) - e.presentation.isEnabledAndVisible = - navigatables != null && - navigatables - .filterIsInstance() - .mapNotNull { it.getNavigateActionText(true) } - .isNotEmpty() - } -} diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java index 9366a085fc7b..35a2f3295ab6 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowSettingsUtilImpl.java @@ -22,8 +22,6 @@ import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.function.Consumer; import java.util.function.Predicate; @@ -40,8 +38,10 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { } @NotNull - public static DialogWrapper getDialog(@Nullable Project project, @NotNull List groups, @Nullable Configurable toSelect) { - return SettingsDialogFactory.getInstance().create(getProject(project), filterEmptyGroups(groups), toSelect, null); + public static DialogWrapper getDialog(@Nullable Project project, @NotNull ConfigurableGroup[] groups, @Nullable Configurable toSelect) { + project = getProject(project); + final ConfigurableGroup[] filteredGroups = filterEmptyGroups(groups); + return SettingsDialogFactory.getInstance().create(project, filteredGroups, toSelect, null); } /** @@ -81,7 +81,7 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { @Override public void showSettingsDialog(@NotNull Project project, @NotNull ConfigurableGroup... group) { try { - getDialog(project, Arrays.asList(group), null).show(); + getDialog(project, group, null).show(); } catch (Exception e) { LOG.error(e); @@ -125,53 +125,50 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { additionalConfiguration.accept(config); } - getDialog(project, Arrays.asList(groups), config).show(); + getDialog(project, groups, config).show(); } @Override - public void showSettingsDialog(@Nullable Project project, @NotNull String nameToSelect) { - ConfigurableGroup group = ConfigurableExtensionPointUtil.getConfigurableGroup(project, /* withIdeSettings = */ true); - List groups = group.getConfigurables().length == 0 ? Collections.emptyList() : Collections.singletonList(group); - getDialog(project, groups, findPreselectedByDisplayName(nameToSelect, groups)).show(); + public void showSettingsDialog(@Nullable final Project project, @NotNull final String nameToSelect) { + ConfigurableGroup[] groups = getConfigurableGroups(project, true); + Project actualProject = getProject(project); + + groups = filterEmptyGroups(groups); + getDialog(actualProject, groups, findPreselectedByDisplayName(nameToSelect, groups)).show(); } @Nullable - private static Configurable findPreselectedByDisplayName(@NotNull String preselectedConfigurableDisplayName, @NotNull List groups) { - for (ConfigurableGroup eachGroup : groups) { - for (Configurable configurable : SearchUtil.expandGroup(eachGroup)) { - if (preselectedConfigurableDisplayName.equals(configurable.getDisplayName())) { - return configurable; - } - } + private static Configurable findPreselectedByDisplayName(final String preselectedConfigurableDisplayName, ConfigurableGroup[] groups) { + final List all = SearchUtil.expand(groups); + for (Configurable each : all) { + if (preselectedConfigurableDisplayName.equals(each.getDisplayName())) return each; } return null; } - public static void showSettingsDialog(@Nullable Project project, @Nullable String idToSelect, final String filter) { - ConfigurableGroup group = ConfigurableExtensionPointUtil.getConfigurableGroup(project, /* withIdeSettings = */ true); - if (group.getConfigurables().length == 0) { - group = null; - } + public static void showSettingsDialog(@Nullable Project project, final String id2Select, final String filter) { + ConfigurableGroup[] group = getConfigurableGroups(project, true); - Configurable configurableToSelect = idToSelect == null ? null : new ConfigurableVisitor.ByID(idToSelect).find(group); - SettingsDialogFactory.getInstance().create(getProject(project), Collections.singletonList(group), configurableToSelect, filter).show(); + group = filterEmptyGroups(group); + final Configurable configurable2Select = id2Select == null ? null : new ConfigurableVisitor.ByID(id2Select).find(group); + + SettingsDialogFactory.getInstance().create(getProject(project), group, configurable2Select, filter).show(); } @Override - public void showSettingsDialog(@NotNull Project project, @Nullable Configurable toSelect) { - List groups = Collections.singletonList(ConfigurableExtensionPointUtil.getConfigurableGroup(project, /* withIdeSettings = */ true)); - getDialog(project, groups, toSelect).show(); + public void showSettingsDialog(@NotNull final Project project, final Configurable toSelect) { + getDialog(project, getConfigurableGroups(project, true), toSelect).show(); } @NotNull - private static List filterEmptyGroups(@NotNull List group) { + private static ConfigurableGroup[] filterEmptyGroups(@NotNull final ConfigurableGroup[] group) { List groups = new ArrayList<>(); for (ConfigurableGroup g : group) { if (g.getConfigurables().length > 0) { groups.add(g); } } - return groups; + return groups.toArray(new ConfigurableGroup[0]); } @Override @@ -179,6 +176,11 @@ public class ShowSettingsUtilImpl extends ShowSettingsUtil { return editConfigurable(project, createDimensionKey(configurable), configurable); } + @Override + public T findProjectConfigurable(final Project project, final Class confClass) { + return ConfigurableExtensionPointUtil.findProjectConfigurable(project, confClass); + } + @Override public boolean editConfigurable(Project project, String dimensionServiceKey, @NotNull Configurable configurable) { return editConfigurable(project, dimensionServiceKey, configurable, isWorthToShowApplyButton(configurable)); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/ConfigurableOptionsTopHitProvider.java b/platform/platform-impl/src/com/intellij/ide/ui/ConfigurableOptionsTopHitProvider.java index 20e33946a379..56bae505a2cd 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/ConfigurableOptionsTopHitProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/ConfigurableOptionsTopHitProvider.java @@ -3,7 +3,6 @@ package com.intellij.ide.ui; import com.intellij.ide.ui.search.BooleanOptionDescription; import com.intellij.ide.ui.search.OptionDescription; -import com.intellij.ide.ui.search.SearchUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.options.Configurable; @@ -11,7 +10,6 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.ex.ConfigurableVisitor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,7 +17,6 @@ import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.TitledBorder; import java.awt.*; -import java.util.List; import java.util.*; /** @@ -67,12 +64,7 @@ public abstract class ConfigurableOptionsTopHitProvider extends OptionsTopHitPro * @return an option prefix or {@code null} to ignore this option */ protected String getOptionName(JCheckBox checkbox) { - return getOptionName(checkbox.getText()); - } - - @Nullable - protected String getOptionName(@NotNull String text) { - String name = StringUtil.stripHtml(text, false); + String name = StringUtil.stripHtml(checkbox.getText(), false); if (StringUtil.isEmpty(name)) { return null; } @@ -103,21 +95,6 @@ public abstract class ConfigurableOptionsTopHitProvider extends OptionsTopHitPro options.add(new Option(configurable, checkbox, option)); } } - else if (component instanceof JComboBox) { - JComboBox combo = (JComboBox)component; - if (!combo.isEditable()) { - JLabel label = UIUtil.uiChildren(combo.getParent()).takeWhile(o -> o != combo).filter(JLabel.class).last(); - String baseName = label == null ? null : getOptionName(label.getText()); - if (baseName != null) { - String optionName = (baseName + " ").replace(": ", " | "); - List list = SearchUtil.getItemsFromComboBox(combo); - for (int i = 0, len = list.size(); i < len; i++) { - String s = optionName + list.get(i); - options.add(new Option2(configurable, combo, s, i)); - } - } - } - } else if (component instanceof Container) { Container container = (Container)component; for (int i = 0; i < container.getComponentCount(); i++) { @@ -152,10 +129,10 @@ public abstract class ConfigurableOptionsTopHitProvider extends OptionsTopHitPro } private static final class Option extends BooleanOptionDescription implements Disposable { - final Configurable myConfigurable; - final JCheckBox myCheckBox; + private final Configurable myConfigurable; + private final JCheckBox myCheckBox; - Option(Configurable configurable, JCheckBox checkbox, String option) { + private Option(Configurable configurable, JCheckBox checkbox, String option) { super(option, ConfigurableVisitor.ByID.getID(configurable)); myConfigurable = configurable; myCheckBox = checkbox; @@ -184,42 +161,4 @@ public abstract class ConfigurableOptionsTopHitProvider extends OptionsTopHitPro } } } - - private static final class Option2 extends BooleanOptionDescription implements Disposable { - final Configurable myConfigurable; - final JComboBox myComboBox; - final int myIndex; - final int myPrevIndex; - - Option2(Configurable configurable, JComboBox comboBox, String option, int index) { - super(option, ConfigurableVisitor.ByID.getID(configurable)); - myConfigurable = configurable; - myComboBox = comboBox; - myIndex = index; - myPrevIndex = myComboBox.getSelectedIndex(); - } - - @Override - public void dispose() { - myConfigurable.disposeUIResources(); - } - - @Override - public boolean isOptionEnabled() { - return myComboBox.getSelectedIndex() == myIndex; - } - - @Override - public void setOptionState(boolean selected) { - if (selected != (myComboBox.getSelectedIndex() == myIndex)) { - myComboBox.setSelectedIndex(selected ? myIndex : myPrevIndex); - try { - myConfigurable.apply(); - } - catch (ConfigurationException exception) { - LOG.debug(exception); - } - } - } - } } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java index 305dc51a8a10..0edf0a2d5d8c 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java @@ -12,7 +12,6 @@ import com.intellij.ui.JBColor; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; import com.intellij.ui.TabbedPaneWrapper; -import com.intellij.util.CollectConsumer; import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.Nls; @@ -26,7 +25,6 @@ import javax.swing.plaf.basic.BasicComboPopup; import java.awt.*; import java.util.List; import java.util.*; -import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -207,7 +205,7 @@ public class SearchUtil { } @NotNull - public static List getItemsFromComboBox(@NotNull JComboBox comboBox) { + private static List getItemsFromComboBox(@NotNull JComboBox comboBox) { ListCellRenderer renderer = comboBox.getRenderer(); if (renderer == null) renderer = new DefaultListCellRenderer(); @@ -555,37 +553,25 @@ public class SearchUtil { return withoutQuoted + " " + filter.substring(beg); } - @NotNull - public static List expand(@NotNull ConfigurableGroup[] groups) { - List result = new ArrayList<>(); - CollectConsumer consumer = new CollectConsumer<>(result); - for (ConfigurableGroup group : groups) { - processExpandedGroups(group, consumer); + public static List expand(ConfigurableGroup[] groups) { + final ArrayList result = new ArrayList<>(); + for (ConfigurableGroup eachGroup : groups) { + result.addAll(expandGroup(eachGroup)); } return result; } - @NotNull - public static List expandGroup(@NotNull ConfigurableGroup group) { - List result = new ArrayList<>(); - processExpandedGroups(group, new CollectConsumer<>(result)); - return result; - } - - public static void processExpandedGroups(@NotNull ConfigurableGroup group, @NotNull Consumer consumer) { - Configurable[] configurables = group.getConfigurables(); + public static List expandGroup(final ConfigurableGroup group) { + final Configurable[] configurables = group.getConfigurables(); List result = new ArrayList<>(); ContainerUtil.addAll(result, configurables); for (Configurable each : configurables) { addChildren(each, result); } - for (Configurable configurable : result) { - //noinspection deprecation - if (!(configurable instanceof SearchableConfigurable.Parent) || ((SearchableConfigurable.Parent)configurable).isVisible()) { - consumer.accept(configurable); - } - } + //noinspection deprecation + return ContainerUtil.filter(result, configurable -> !(configurable instanceof SearchableConfigurable.Parent) || + ((SearchableConfigurable.Parent)configurable).isVisible()); } private static void addChildren(Configurable configurable, List list) { @@ -599,6 +585,7 @@ public class SearchUtil { } private static final class SearchableConfigurableAdapter implements SearchableConfigurable { + private final SearchableConfigurable myOriginal; private final UnnamedConfigurable myDelegate; diff --git a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchableOptionsRegistrarImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchableOptionsRegistrarImpl.java index 52756f13c4ce..728f15111ed2 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchableOptionsRegistrarImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchableOptionsRegistrarImpl.java @@ -1,11 +1,13 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.ui.search; +import com.intellij.application.options.CodeStyle; import com.intellij.codeStyle.CodeStyleFacade; import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManagerConfigurable; import com.intellij.ide.plugins.PluginManagerCore; +import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.diagnostic.Logger; @@ -19,7 +21,6 @@ import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; -import com.intellij.util.CollectConsumer; import com.intellij.util.ObjectUtils; import com.intellij.util.ResourceUtil; import com.intellij.util.containers.ContainerUtil; @@ -68,6 +69,7 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar { }; private static final Logger LOG = Logger.getInstance("#com.intellij.ide.ui.search.SearchableOptionsRegistrarImpl"); + private static final int LOAD_FACTOR = 20; @NonNls private static final Pattern REG_EXP = Pattern.compile("[\\W&&[^-]]+"); @@ -287,71 +289,66 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar { myStorage.put(ByteArrayCharSequence.convertToBytesIfPossible(option), configs); } + @SuppressWarnings("StringToUpperCaseOrToLowerCaseWithoutLocale") @Override @NotNull - public ConfigurableHit getConfigurables(@NotNull List groups, + public ConfigurableHit getConfigurables(ConfigurableGroup[] groups, final DocumentEvent.EventType type, - @Nullable Set configurables, - @NotNull String option, - @Nullable Project project) { - Set contentHits = new LinkedHashSet<>(); + Set configurables, + String option, + Project project) { + + final ConfigurableHit hits = new ConfigurableHit(); + final Set contentHits = hits.getContentHits(); + + Set options = getProcessedWordsWithoutStemming(option); if (configurables == null) { - CollectConsumer consumer = new CollectConsumer<>(contentHits); for (ConfigurableGroup group : groups) { - SearchUtil.processExpandedGroups(group, consumer); + contentHits.addAll(SearchUtil.expandGroup(group)); } } else { contentHits.addAll(configurables); } - String optionToCheck = option.trim().toLowerCase(Locale.ENGLISH); - Set options = getProcessedWordsWithoutStemming(optionToCheck); - - Set nameHits = new LinkedHashSet<>(); - Set nameFullHits = new LinkedHashSet<>(); - + String optionToCheck = option.trim().toLowerCase(); for (Configurable each : contentHits) { if (each.getDisplayName() == null) continue; - final String displayName = each.getDisplayName().toLowerCase(Locale.ENGLISH); + final String displayName = each.getDisplayName().toLowerCase(); final List allWords = StringUtil.getWordsIn(displayName); if (displayName.contains(optionToCheck)) { - nameFullHits.add(each); - nameHits.add(each); + hits.getNameFullHits().add(each); + hits.getNameHits().add(each); } for (String eachWord : allWords) { if (eachWord.startsWith(optionToCheck)) { - nameHits.add(each); + hits.getNameHits().add(each); break; } } if (options.isEmpty()) { - nameHits.add(each); - nameFullHits.add(each); + hits.getNameHits().add(each); + hits.getNameFullHits().add(each); } } - final Set currentConfigurables = type == DocumentEvent.EventType.CHANGE ? new THashSet<>(contentHits) : null; - // operate with substring - if (options.isEmpty()) { + final Set currentConfigurables = new HashSet<>(contentHits); + if (options.isEmpty()) { //operate with substring String[] components = REG_EXP.split(optionToCheck); if (components.length > 0) { Collections.addAll(options, components); - } - else { + } else { options.add(option); } } - Set helpIds = null; for (String opt : options) { final Set optionIds = getAcceptableDescriptions(opt); if (optionIds == null) { contentHits.clear(); - return new ConfigurableHit(contentHits, nameHits, nameFullHits); + return hits; } - final Set ids = new HashSet<>(); for (OptionDescription id : optionIds) { ids.add(id.getConfigurableId()); @@ -361,7 +358,6 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar { } helpIds.retainAll(ids); } - if (helpIds != null) { for (Iterator it = contentHits.iterator(); it.hasNext();) { Configurable configurable = it.next(); @@ -374,13 +370,13 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar { } } } - - if (type == DocumentEvent.EventType.CHANGE && configurables != null && currentConfigurables.equals(contentHits)) { + if (currentConfigurables.equals(contentHits) && !(configurables == null && type == DocumentEvent.EventType.CHANGE)) { return getConfigurables(groups, DocumentEvent.EventType.CHANGE, null, option, project); } - return new ConfigurableHit(contentHits, nameHits, nameFullHits); + return hits; } + @Nullable public synchronized Set getAcceptableDescriptions(final String prefix) { if (prefix == null) return null; @@ -462,6 +458,43 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar { return myHighlightOption2Synonym.get(Couple.of(option, configurable.getId())); } + @Override + public Map> findPossibleExtension(@NotNull String prefix, final Project project) { + loadHugeFilesIfNecessary(); + final boolean perProject = CodeStyle.usesOwnSettings(project); + final Map> result = new THashMap<>(); + int count = 0; + final Set prefixes = getProcessedWordsWithoutStemming(prefix); + for (String opt : prefixes) { + Set configs = getAcceptableDescriptions(opt); + if (configs == null) continue; + for (OptionDescription description : configs) { + String groupName = description.getGroupName(); + if (perProject) { + if (Comparing.strEqual(groupName, ApplicationBundle.message("title.global.code.style"))) { + groupName = ApplicationBundle.message("title.project.code.style"); + } + } + else { + if (Comparing.strEqual(groupName, ApplicationBundle.message("title.project.code.style"))) { + groupName = ApplicationBundle.message("title.global.code.style"); + } + } + Set foundHits = result.get(groupName); + if (foundHits == null) { + foundHits = new THashSet<>(); + result.put(groupName, foundHits); + } + foundHits.add(description.getHit()); + count++; + } + } + if (count > LOAD_FACTOR) { + result.clear(); + } + return result; + } + @Override public void addOption(String option, String path, final String hit, final String configurableId, final String configurableDisplayName) { putOptionWithHelpId(option, configurableId, configurableDisplayName, hit, path); @@ -469,17 +502,13 @@ public class SearchableOptionsRegistrarImpl extends SearchableOptionsRegistrar { @Override public Set getProcessedWordsWithoutStemming(@NotNull String text) { - Set result = new THashSet<>(); - for (String opt : REG_EXP.split(text.toLowerCase(Locale.ENGLISH))) { - if (isStopWord(opt)) { - continue; - } - - String processed = PorterStemmerUtil.stem(opt); - if (isStopWord(processed)) { - continue; - } - + Set result = new HashSet<>(); + @NonNls final String toLowerCase = text.toLowerCase(); + final String[] options = REG_EXP.split(toLowerCase); + for (String opt : options) { + if (isStopWord(opt)) continue; + final String processed = PorterStemmerUtil.stem(opt); + if (isStopWord(processed)) continue; result.add(opt); } return result; diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/SensitiveDataValidator.java b/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/SensitiveDataValidator.java index 0badb50a5a3c..e7f0728f4c39 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/SensitiveDataValidator.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/SensitiveDataValidator.java @@ -3,116 +3,73 @@ package com.intellij.internal.statistic.eventLog.validator; import com.intellij.internal.statistic.eventLog.EventLogConfiguration; import com.intellij.internal.statistic.eventLog.EventLogGroup; -import com.intellij.internal.statistic.eventLog.FeatureUsageData; import com.intellij.internal.statistic.eventLog.validator.persistence.FUSWhiteListPersistence; import com.intellij.internal.statistic.eventLog.validator.rules.EventContext; import com.intellij.internal.statistic.eventLog.validator.rules.beans.WhiteListGroupRules; import com.intellij.internal.statistic.service.fus.FUStatisticsWhiteListGroupsService; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.BuildNumber; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; -import static com.intellij.internal.statistic.eventLog.validator.ValidationResultType.*; +import static com.intellij.internal.statistic.eventLog.validator.ValidationResultType.ACCEPTED; public class SensitiveDataValidator { - private static final NotNullLazyValue me = NotNullLazyValue.createValue( - () -> ApplicationManager.getApplication().isUnitTestMode() ? new BlindSensitiveDataValidator() : new SensitiveDataValidator() - ); - - private final Semaphore mySemaphore; - private final AtomicBoolean isWhiteListInitialized; + private static NotNullLazyValue me = NotNullLazyValue.createValue(() -> new SensitiveDataValidator()); public static SensitiveDataValidator getInstance() { return me.getValue(); } - protected SensitiveDataValidator() { - mySemaphore = new Semaphore(); - isWhiteListInitialized = new AtomicBoolean(false); - updateValidators(FUSWhiteListPersistence.getCachedWhiteList()); - } + protected SensitiveDataValidator() {} - protected final Map eventsValidators = ContainerUtil.newConcurrentMap(); + protected final Map eventsValidators = ContainerUtil.createConcurrentSoftMap(); public String guaranteeCorrectEventId(@NotNull EventLogGroup group, @NotNull EventContext context) { - if (isUnreachableWhitelist()) return UNREACHABLE_WHITELIST.getDescription(); - ValidationResultType validationResultType = validateEvent(group, context); return validationResultType == ACCEPTED ? context.eventId : validationResultType.getDescription(); } public Map guaranteeCorrectEventData(@NotNull EventLogGroup group, @NotNull EventContext context) { WhiteListGroupRules whiteListRule = eventsValidators.get(group.getId()); + if (whiteListRule == null || !whiteListRule.areEventDataRulesDefined()) return context.eventData; // there are no rules to validate - Map validatedData = - ContainerUtil.newConcurrentMap(); // TODO: don't create validatedData map if all keys are accepted (just return context.eventData) + Map validatedData = ContainerUtil.newConcurrentMap(); // TODO: don't create validatedData map if all keys are accepted (just return context.eventData) for (Map.Entry entry : context.eventData.entrySet()) { String key = entry.getKey(); Object entryValue = entry.getValue(); - - ValidationResultType resultType = validateEventData(context, whiteListRule, key, entryValue); + ValidationResultType resultType = whiteListRule.validateEventData(key, entryValue, context); validatedData.put(key, resultType == ACCEPTED ? entryValue : resultType.getDescription()); } return validatedData; } - private ValidationResultType validateEventData(@NotNull EventContext context, - @Nullable WhiteListGroupRules whiteListRule, - @NotNull String key, - @NotNull Object entryValue) { - if (isUnreachableWhitelist()) return UNREACHABLE_WHITELIST; - if (whiteListRule == null) return UNDEFINED_RULE; - if (FeatureUsageData.Companion.getPlatformDataKeys().contains(key)) return ACCEPTED; - return whiteListRule.validateEventData(key, entryValue, context); - } - public SensitiveDataValidator update() { - updateValidators(getWhiteListContent()); - return this; - } - - private void updateValidators(@Nullable String whiteListContent) { + String whiteListContent = getWhiteListContent(); if (whiteListContent != null) { - mySemaphore.down(); - try { + FUStatisticsWhiteListGroupsService.WLGroups groups = FUStatisticsWhiteListGroupsService.parseWhiteListContent(whiteListContent); + if (groups != null) { + final BuildNumber buildNumber = BuildNumber.fromString(EventLogConfiguration.INSTANCE.getBuild()); + final Map result = groups.groups.stream(). + filter(group -> group.accepts(buildNumber)). + collect(Collectors.toMap(group -> group.id, group -> createRules(group, groups.rules))); eventsValidators.clear(); - isWhiteListInitialized.set(false); - FUStatisticsWhiteListGroupsService.WLGroups groups = FUStatisticsWhiteListGroupsService.parseWhiteListContent(whiteListContent); - if (groups != null) { - final BuildNumber buildNumber = BuildNumber.fromString(EventLogConfiguration.INSTANCE.getBuild()); - final Map result = groups.groups.stream(). - filter(group -> group.accepts(buildNumber)). - collect(Collectors.toMap(group -> group.id, group -> createRules(group, groups.rules))); - - eventsValidators.putAll(result); - - isWhiteListInitialized.set(true); - } - } - finally { - mySemaphore.up(); + eventsValidators.putAll(result); } } - } - - private boolean isUnreachableWhitelist() { - return !isWhiteListInitialized.get(); + return this; } public ValidationResultType validateEvent(@NotNull EventLogGroup group, @NotNull EventContext context) { WhiteListGroupRules whiteListRule = eventsValidators.get(group.getId()); if (whiteListRule == null || !whiteListRule.areEventIdRulesDefined()) { - return UNDEFINED_RULE; // there are no rules (eventId and eventData) to validate + return ACCEPTED; // there are no rules (eventId and eventData) to validate } return whiteListRule.validateEventId(context); @@ -134,17 +91,4 @@ public class SensitiveDataValidator { } return FUSWhiteListPersistence.getCachedWhiteList(); } - - - private static class BlindSensitiveDataValidator extends SensitiveDataValidator { - @Override - public String guaranteeCorrectEventId(@NotNull EventLogGroup group, @NotNull EventContext context) { - return context.eventId; - } - - @Override - public Map guaranteeCorrectEventData(@NotNull EventLogGroup group, @NotNull EventContext context) { - return context.eventData; - } - } } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/ValidationResultType.java b/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/ValidationResultType.java index f8d34f1a6edd..114303a40963 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/ValidationResultType.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/eventLog/validator/ValidationResultType.java @@ -8,7 +8,6 @@ public enum ValidationResultType { REJECTED("validation.unmatched_rule"), INCORRECT_RULE("validation.incorrect_rule"), UNDEFINED_RULE("validation.undefined_rule"), - UNREACHABLE_WHITELIST("validation.unreachable.whitelist"), PERFORMANCE_ISSUE("validation.performance_issue"); private final String value; diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsJobsScheduler.java b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsJobsScheduler.java index cf2694b7b018..9b04777d05e8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsJobsScheduler.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsJobsScheduler.java @@ -74,7 +74,7 @@ public class StatisticsJobsScheduler implements ApplicationInitializedListener { } private static void runSensitiveDataValidatorUpdater() { - JobScheduler.getScheduler().scheduleWithFixedDelay(() -> SensitiveDataValidator.getInstance().update(), 3, 180, TimeUnit.MINUTES); + JobScheduler.getScheduler().scheduleWithFixedDelay(() -> SensitiveDataValidator.getInstance().update(), 1, 180, TimeUnit.MINUTES); } private static void runEventLogStatisticsService() { diff --git a/platform/platform-impl/src/com/intellij/openapi/application/JBProtocolCommand.java b/platform/platform-impl/src/com/intellij/openapi/application/JBProtocolCommand.java index 5edc20544e6c..f48b440f1a29 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/JBProtocolCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/JBProtocolCommand.java @@ -1,4 +1,18 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.openapi.application; import com.intellij.openapi.extensions.ExtensionPointName; @@ -11,7 +25,7 @@ import java.util.Map; * @author Konstantin Bulenkov */ public abstract class JBProtocolCommand { - private static final ExtensionPointName EP_NAME = new ExtensionPointName<>("com.intellij.jbProtocolCommand"); + public static final ExtensionPointName EP_NAME = new ExtensionPointName<>("com.intellij.jbProtocolCommand"); private final String myCommand; public JBProtocolCommand(@NotNull String command) { @@ -23,12 +37,12 @@ public abstract class JBProtocolCommand { return myCommand; } - public abstract void perform(String target, @NotNull Map parameters); + public abstract void perform(String target, Map parameters); @Nullable public static JBProtocolCommand findCommand(@Nullable String commandName) { if (commandName != null) { - for (JBProtocolCommand command : EP_NAME.getIterable()) { + for (JBProtocolCommand command : EP_NAME.getExtensions()) { if (command.getCommandName().equals(commandName)) { return command; } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/JBProtocolShutdownCommand.java b/platform/platform-impl/src/com/intellij/openapi/application/JBProtocolShutdownCommand.java index 8567eed53e2f..c463ee907d6e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/JBProtocolShutdownCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/JBProtocolShutdownCommand.java @@ -1,4 +1,18 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.openapi.application; import com.intellij.CommonBundle; @@ -6,24 +20,23 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.ui.MessageDialogBuilder; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; -import org.jetbrains.annotations.NotNull; import java.util.Map; /** * @author Konstantin Bulenkov */ -final class JBProtocolShutdownCommand extends JBProtocolCommand { - JBProtocolShutdownCommand() { +public class JBProtocolShutdownCommand extends JBProtocolCommand { + + public JBProtocolShutdownCommand() { super("shutdown"); } @Override - public void perform(String target, @NotNull Map parameters) { + public void perform(String target, Map parameters) { if (StringUtil.isEmpty(target)) { ApplicationManager.getApplication().exit(); - } - else { + } else { MessageDialogBuilder.YesNo confirmExitDialog = MessageDialogBuilder.yesNo(ApplicationBundle.message("exit.confirm.title"), target) .yesText(ApplicationBundle.message("command.exit")).noText( CommonBundle.message("button.cancel")); 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 2853fc4a7447..97e5e3ecde1a 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 @@ -2018,7 +2018,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse ActionGroup actionGroup = renderer.getPopupMenuActions(); if (actionGroup != null) { if (checkDumbAware(actionGroup)) { - actionManager.createActionPopupMenu(ActionPlaces.EDITOR_GUTTER_POPUP, actionGroup).getComponent().show(this, e.getX(), e.getY()); + actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, actionGroup).getComponent().show(this, e.getX(), e.getY()); } else { notifyNotDumbAware(); @@ -2033,7 +2033,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse group = (ActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(IdeActions.GROUP_EDITOR_GUTTER); } if (group != null) { - ActionPopupMenu popupMenu = actionManager.createActionPopupMenu(ActionPlaces.EDITOR_GUTTER_POPUP, group); + ActionPopupMenu popupMenu = actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, group); popupMenu.getComponent().show(this, e.getX(), e.getY()); } e.consume(); diff --git a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSaverDialogImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSaverDialogImpl.java index 120e3825b92b..4ce0e3ec90e6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSaverDialogImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileChooser/ex/FileSaverDialogImpl.java @@ -6,7 +6,6 @@ import com.intellij.openapi.fileChooser.FileSaverDialog; import com.intellij.openapi.fileChooser.FileSystemTree; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; -import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileWrapper; import com.intellij.ui.DocumentAdapter; @@ -109,12 +108,12 @@ public class FileSaverDialogImpl extends FileChooserDialogImpl implements FileSa private void updateFileName(List selection) { for (VirtualFile file : selection) { if (file.isDirectory()) { - myPathTextField.getField().setText(VfsUtil.getReadableUrl(file)); + myPathTextField.getField().setText(file.getPath()); } else { myFileName.setText(file.getName()); final VirtualFile parent = file.getParent(); if (parent != null) { - myPathTextField.getField().setText(VfsUtil.getReadableUrl(parent)); + myPathTextField.getField().setText(parent.getPath()); } } } 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 8f97a7966eec..5b77d2e77be8 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 @@ -900,7 +900,7 @@ public class EditorWindow { final Icon modifiedIcon; UISettings settings = UISettings.getInstance(); - if (settings.getMarkModifiedTabsWithAsterisk()) { + if (settings.getMarkModifiedTabsWithAsterisk() || !settings.getHideTabsIfNeed()) { Icon crop = IconUtil.cropIcon(AllIcons.General.Modified, new JBRectangle(3, 3, 7, 7)); modifiedIcon = settings.getMarkModifiedTabsWithAsterisk() && composite != null && composite.isModified() ? crop : new EmptyIcon(7, 7); count++; diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java index 18fb0f2f5a54..4e4ee541b22a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/IdeKeyEventDispatcher.java @@ -52,7 +52,6 @@ import com.intellij.util.ui.MacUIUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.plaf.basic.ComboPopup; @@ -438,8 +437,7 @@ public final class IdeKeyEventDispatcher implements Disposable { if (SystemInfo.isMac && InputEvent.ALT_DOWN_MASK == e.getModifiersEx() && Registry.is("ide.mac.alt.mnemonic.without.ctrl")) { // the myIgnoreNextKeyTypedEvent changes event processing to support Alt-based mnemonics on Mac only - if ((KeyEvent.KEY_TYPED == e.getID() && !IdeEventQueue.getInstance().isInputMethodEnabled()) || - hasMnemonicInWindow(focusOwner, e)) { + if ((KeyEvent.KEY_TYPED == e.getID() && !IdeEventQueue.getInstance().isInputMethodEnabled()) || hasMnemonicInWindow(focusOwner, e)) { myIgnoreNextKeyTypedEvent = true; return false; } @@ -523,7 +521,7 @@ public final class IdeKeyEventDispatcher implements Disposable { return secondKeyStrokes; } - public static boolean hasMnemonicInWindow(Component focusOwner, KeyEvent event) { + private static boolean hasMnemonicInWindow(Component focusOwner, KeyEvent event) { return KeyEvent.KEY_TYPED == event.getID() && hasMnemonicInWindow(focusOwner, event.getKeyChar()) || KeyEvent.KEY_PRESSED == event.getID() && hasMnemonicInWindow(focusOwner, event.getKeyCode()); } @@ -534,44 +532,43 @@ public final class IdeKeyEventDispatcher implements Disposable { return hasMnemonic(container, keyCode) || hasMnemonicInBalloons(container, keyCode); } - private static boolean hasMnemonic(@Nullable Container container, int keyCode) { - Component component = UIUtil.uiTraverser(container) - .traverse() - .find(c -> hasMnemonic(c, keyCode)); - return component != null; - } + private static boolean hasMnemonic(final Container container, final int keyCode) { + if (container == null) return false; - private static boolean hasMnemonic(@Nullable Component component, int keyCode) { - if (component instanceof AbstractButton) { - AbstractButton button = (AbstractButton)component; - if (button instanceof JBOptionButton) { - if (((JBOptionButton)button).isOkToProcessDefaultMnemonics() || - button.getMnemonic() == keyCode) { - return true; + final Component[] components = container.getComponents(); + for (Component component : components) { + if (component instanceof AbstractButton) { + final AbstractButton button = (AbstractButton)component; + if (button instanceof JBOptionButton) { + if (((JBOptionButton)button).isOkToProcessDefaultMnemonics() || + button.getMnemonic() == keyCode) + { + return true; + } + } else { + if (button.getMnemonic() == keyCode) return true; } } - else { - if (button.getMnemonic() == keyCode) return true; + if (component instanceof JLabel) { + final JLabel label = (JLabel)component; + if (label.getDisplayedMnemonic() == keyCode) return true; + } + if (component instanceof ActionButtonWithText) { + if (((ActionButtonWithText)component).getMnemonic() == keyCode) return true; + } + if (component instanceof Container) { + if (hasMnemonic((Container)component, keyCode)) return true; } - } - if (component instanceof JLabel) { - JLabel label = (JLabel)component; - if (label.getDisplayedMnemonic() == keyCode) return true; - } - if (component instanceof ActionButtonWithText) { - if (((ActionButtonWithText)component).getMnemonic() == keyCode) return true; } return false; } private static boolean hasMnemonicInBalloons(Container container, int code) { - Component parent = UIUtil.findUltimateParent(container); + final Component parent = UIUtil.findUltimateParent(container); if (parent instanceof RootPaneContainer) { final JLayeredPane pane = ((RootPaneContainer)parent).getLayeredPane(); for (Component component : pane.getComponents()) { - if (component instanceof ComponentWithMnemonics && - component instanceof Container && - hasMnemonic((Container)component, code)) { + if (component instanceof ComponentWithMnemonics && component instanceof Container && hasMnemonic((Container)component, code)) { return true; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java index 58f570240ba9..7f690a7cbae6 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java @@ -121,9 +121,7 @@ public class ConfigurableExtensionPointUtil { * @return the root configurable group that represents a tree of settings */ public static ConfigurableGroup getConfigurableGroup(@Nullable Project project, boolean withIdeSettings) { - if (!withIdeSettings && project == null) { - project = ProjectManager.getInstance().getDefaultProject(); - } + if (!withIdeSettings && project == null) project = ProjectManager.getInstance().getDefaultProject(); return getConfigurableGroup(getConfigurables(project, withIdeSettings), project); } @@ -134,16 +132,16 @@ public class ConfigurableExtensionPointUtil { */ public static ConfigurableGroup getConfigurableGroup(@NotNull List configurables, @Nullable Project project) { Map> map = groupConfigurables(configurables); - Map> tree = new THashMap<>(); + Map> tree = ContainerUtil.newHashMap(); for (Map.Entry> entry : map.entrySet()) { addGroup(tree, project, entry.getKey(), entry.getValue(), null); } - SortedConfigurableGroup root = getGroup(tree, "root"); if (!tree.isEmpty()) { - LOG.warn("ignore groups: " + tree.keySet()); + for (String groupId : tree.keySet()) { + LOG.warn("ignore group: " + groupId); + } } - if (root != null && root.myList != null && Registry.is("ide.settings.replace.group.with.single.configurable")) { replaceGroupWithSingleConfigurable(root.myList); } @@ -200,7 +198,7 @@ public class ConfigurableExtensionPointUtil { return node.myValue; } - private static void addGroup(@NotNull Map> tree, Project project, + private static void addGroup(Map> tree, Project project, String groupId, List configurables, ResourceBundle alternative) { String id = "configurable.group." + groupId; ResourceBundle bundle = getBundle(id + ".settings.display.name", configurables, alternative); @@ -252,7 +250,6 @@ public class ConfigurableExtensionPointUtil { * @param configurables a list of settings to process * @return the map of different groups of settings */ - @NotNull public static Map> groupConfigurables(@NotNull List configurables) { Map> tree = new THashMap<>(); for (Configurable configurable : configurables) { @@ -349,9 +346,8 @@ public class ConfigurableExtensionPointUtil { * @param withIdeSettings specifies whether to load application settings or not * @return the list of all valid settings according to parameters */ - @NotNull private static List getConfigurables(@Nullable Project project, boolean withIdeSettings) { - List list = new ArrayList<>(); + List list = ContainerUtil.newArrayList(); if (withIdeSettings) { Application application = ApplicationManager.getApplication(); if (application != null) { @@ -440,6 +436,81 @@ public class ConfigurableExtensionPointUtil { return !isValid(each, null) || (filter != null && !filter.isIncluded(each)); } + /* + private static void dumpConfigurable(ExtensionPointName> configurablesExtensionPoint, + ConfigurableEP ep, + Configurable configurable) { + if (configurable != null && !(configurable instanceof ConfigurableGroup)) { + if (ep.instanceClass != null && (configurable instanceof SearchableConfigurable) && (configurable instanceof Configurable.Composite)) { + Element element = dump(ep, configurable, StringUtil.getShortName(configurablesExtensionPoint.getName())); + final Configurable[] configurables = ((Configurable.Composite)configurable).getConfigurables(); + for (Configurable child : configurables) { + final Element dump = dump(null, child, "configurable"); + element.addContent(dump); + } + final StringWriter out = new StringWriter(); + try { + new XMLOutputter(Format.getPrettyFormat()).output(element, out); + } + catch (IOException e) { + } + System.out.println(out); + } + } + } + + private static Element dump(@Nullable ConfigurableEP ep, + Configurable configurable, String name) { + Element element = new Element(name); + if (ep != null) { + element.setAttribute("instance", ep.instanceClass); + String id = ep.id == null ? ((SearchableConfigurable)configurable).getId() : ep.id; + element.setAttribute("id", id); + } + else { + element.setAttribute("instance", configurable.getClass().getName()); + if (configurable instanceof SearchableConfigurable) { + element.setAttribute("id", ((SearchableConfigurable)configurable).getId()); + } + } + + CommonBundle.lastKey = null; + String displayName = configurable.getDisplayName(); + if (CommonBundle.lastKey != null) { + element.setAttribute("key", CommonBundle.lastKey).setAttribute("bundle", CommonBundle.lastBundle); + } + else { + element.setAttribute("displayName", displayName); + } + if (configurable instanceof NonDefaultProjectConfigurable) { + element.setAttribute("nonDefaultProject", "true"); + } + return element; + } + */ + + /** + * @deprecated create a new instance of configurable instead + */ + @Deprecated + @NotNull + public static T findProjectConfigurable(@NotNull Project project, @NotNull Class configurableClass) { + return findConfigurable(Configurable.PROJECT_CONFIGURABLE.getExtensionList(project), configurableClass); + } + + @NotNull + private static T findConfigurable(@NotNull List> extensions, Class configurableClass) { + for (ConfigurableEP extension : extensions) { + if (extension.canCreateConfigurable()) { + final Configurable configurable = extension.createConfigurable(); + if (configurableClass.isInstance(configurable)) { + return configurableClass.cast(configurable); + } + } + } + throw new IllegalArgumentException("Cannot find configurable of " + configurableClass); + } + @Nullable public static Configurable createProjectConfigurableForProvider(@NotNull Project project, Class providerClass) { return createConfigurableForProvider(Configurable.PROJECT_CONFIGURABLE.getExtensionList(project), providerClass); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableVisitor.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableVisitor.java index 08b11f2f9d96..3eb08decdf84 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableVisitor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableVisitor.java @@ -1,14 +1,26 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2014 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.openapi.options.ex; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; import com.intellij.openapi.options.SearchableConfigurable; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -24,13 +36,7 @@ public abstract class ConfigurableVisitor { protected abstract boolean accept(Configurable configurable); - @Nullable public final Configurable find(@NotNull ConfigurableGroup... groups) { - return find(Arrays.asList(groups)); - } - - @Nullable - public final Configurable find(@NotNull List groups) { for (ConfigurableGroup group : groups) { Configurable result = find(group.getConfigurables()); if (result != null) { @@ -58,7 +64,7 @@ public abstract class ConfigurableVisitor { return null; } - public final List findAll(@NotNull List groups) { + public final List findAll(@NotNull ConfigurableGroup... groups) { List list = new ArrayList<>(); for (ConfigurableGroup group : groups) { add(list, group.getConfigurables()); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/Settings.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/Settings.java index cab249e6709b..3cb6c0b46318 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/ex/Settings.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/Settings.java @@ -1,4 +1,18 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * 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.openapi.options.ex; import com.intellij.openapi.actionSystem.DataKey; @@ -9,11 +23,8 @@ import com.intellij.openapi.options.UnnamedConfigurable; import com.intellij.openapi.util.ActionCallback; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.concurrency.Promises; import java.util.IdentityHashMap; -import java.util.List; /** * @author Sergey.Malenkov @@ -21,11 +32,11 @@ import java.util.List; public abstract class Settings { public static final DataKey KEY = DataKey.create("settings.editor"); - private final List myGroups; + private final ConfigurableGroup[] myGroups; private final IdentityHashMap myMap = new IdentityHashMap<>(); - protected Settings(@NotNull List groups) { + protected Settings(@NotNull ConfigurableGroup... groups) { myGroups = groups; } @@ -41,7 +52,9 @@ public abstract class Settings { @NotNull public final ActionCallback select(Configurable configurable) { - return configurable == null ? ActionCallback.REJECTED : Promises.toActionCallback(selectImpl(choose(configurable, myMap.get(configurable)))); + return configurable != null + ? selectImpl(choose(configurable, myMap.get(configurable))) + : ActionCallback.REJECTED; } @NotNull @@ -55,8 +68,7 @@ public abstract class Settings { return callback; } - @NotNull - protected abstract Promise selectImpl(Configurable configurable); + protected abstract ActionCallback selectImpl(Configurable configurable); private T unwrap(Configurable configurable, Class type) { T result = ConfigurableWrapper.cast(type, configurable); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/AbstractEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/AbstractEditor.java index 4459d8431fb4..304978bd990f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/AbstractEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/AbstractEditor.java @@ -1,12 +1,27 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2014 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.openapi.options.newEditor; import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; -import org.jetbrains.annotations.NotNull; -import javax.swing.*; -import java.awt.*; +import javax.swing.Action; +import javax.swing.JComponent; +import javax.swing.JPanel; +import java.awt.BorderLayout; /** * @author Sergey.Malenkov @@ -14,9 +29,8 @@ import java.awt.*; abstract class AbstractEditor extends JPanel implements Disposable { volatile boolean myDisposed; - AbstractEditor(@NotNull Disposable parent) { + AbstractEditor(Disposable parent) { super(new BorderLayout()); - Disposer.register(parent, this); } diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java index 997126b2adfc..b2ffb310dec2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ConfigurableEditor.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.options.newEditor; import com.intellij.CommonBundle; @@ -29,8 +29,6 @@ import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.NotNull; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.concurrency.Promises; import javax.swing.*; import java.awt.*; @@ -237,20 +235,18 @@ class ConfigurableEditor extends AbstractEditor implements AnActionListener, AWT return true; } - @NotNull - final Promise select(final Configurable configurable) { + final ActionCallback select(final Configurable configurable) { assert !myDisposed : "Already disposed"; ActionCallback callback = myCardPanel.select(configurable, false); - callback - .doWhenDone(() -> { - myConfigurable = configurable; - updateCurrent(configurable, false); - postUpdateCurrent(configurable); - if (configurable != null) { - FeatureUsageUiEventsKt.getUiEventLogger().logSelectConfigurable(getConfigurableEventId(configurable), configurable.getClass()); - } - }); - return Promises.toPromise(callback); + callback.doWhenDone(() -> { + myConfigurable = configurable; + updateCurrent(configurable, false); + postUpdateCurrent(configurable); + if (configurable != null) { + FeatureUsageUiEventsKt.getUiEventLogger().logSelectConfigurable(getConfigurableEventId(configurable), configurable.getClass()); + } + }); + return callback; } final boolean setError(ConfigurationException exception) { diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ISettingsTreeViewFactory.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ISettingsTreeViewFactory.java index 5ac943096fae..7c0c36dedaab 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ISettingsTreeViewFactory.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/ISettingsTreeViewFactory.java @@ -1,11 +1,22 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * 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.openapi.options.newEditor; import com.intellij.openapi.options.ConfigurableGroup; -import org.jetbrains.annotations.NotNull; - -import java.util.List; public interface ISettingsTreeViewFactory { - SettingsTreeView createTreeView(SettingsFilter filter, @NotNull List groups); + SettingsTreeView createTreeView(SettingsFilter filter, ConfigurableGroup[] groups); } diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorColleague.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorColleague.java index 09e2e2128f96..3af12bf432b8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorColleague.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorColleague.java @@ -1,48 +1,39 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.options.newEditor; import com.intellij.openapi.options.Configurable; -import org.jetbrains.annotations.NotNull; +import com.intellij.openapi.util.ActionCallback; import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.concurrency.Promises; public interface OptionsEditorColleague { - @NotNull - Promise onSelected(@Nullable Configurable configurable, final Configurable oldConfigurable); + ActionCallback onSelected(@Nullable Configurable configurable, final Configurable oldConfigurable); - @NotNull - Promise onModifiedAdded(final Configurable configurable); + ActionCallback onModifiedAdded(final Configurable configurable); - @NotNull - Promise onModifiedRemoved(final Configurable configurable); + ActionCallback onModifiedRemoved(final Configurable configurable); - @NotNull - Promise onErrorsChanged(); + ActionCallback onErrorsChanged(); class Adapter implements OptionsEditorColleague { - @NotNull @Override - public Promise onSelected(@Nullable final Configurable configurable, final Configurable oldConfigurable) { - return Promises.resolvedPromise(); + public ActionCallback onSelected(@Nullable final Configurable configurable, final Configurable oldConfigurable) { + return ActionCallback.DONE; } - @NotNull @Override - public Promise onModifiedAdded(final Configurable configurable) { - return Promises.resolvedPromise(); + public ActionCallback onModifiedAdded(final Configurable configurable) { + return ActionCallback.DONE; } - @NotNull @Override - public Promise onModifiedRemoved(final Configurable configurable) { - return Promises.resolvedPromise(); + public ActionCallback onModifiedRemoved(final Configurable configurable) { + return ActionCallback.DONE; } - @NotNull @Override - public Promise onErrorsChanged() { - return Promises.resolvedPromise(); + public ActionCallback onErrorsChanged() { + return ActionCallback.DONE; } } + } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorContext.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorContext.java index a4a0a8a28b0a..adbdefd82987 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorContext.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/OptionsEditorContext.java @@ -1,15 +1,13 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.options.newEditor; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.MultiValuesMap; -import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.concurrency.Promises; import java.util.*; import java.util.concurrent.CopyOnWriteArraySet; @@ -24,80 +22,70 @@ public class OptionsEditorContext { private final Map myConfigurableToParentMap = new HashMap<>(); private final MultiValuesMap myParentToChildrenMap = new MultiValuesMap<>(); - @NotNull - Promise fireSelected(@Nullable final Configurable configurable, @NotNull OptionsEditorColleague requestor) { - if (myCurrentConfigurable == configurable) { - return Promises.rejectedPromise(); - } + ActionCallback fireSelected(@Nullable final Configurable configurable, @NotNull OptionsEditorColleague requestor) { + if (myCurrentConfigurable == configurable) return ActionCallback.REJECTED; final Configurable old = myCurrentConfigurable; myCurrentConfigurable = configurable; return notify(new ColleagueAction() { - @NotNull @Override - public Promise process(final OptionsEditorColleague colleague) { + public ActionCallback process(final OptionsEditorColleague colleague) { return colleague.onSelected(configurable, old); } }, requestor); + } - @NotNull - Promise fireModifiedAdded(@NotNull final Configurable configurable, @Nullable OptionsEditorColleague requestor) { - if (myModified.contains(configurable)) { - return Promises.rejectedPromise(); - } + ActionCallback fireModifiedAdded(@NotNull final Configurable configurable, @Nullable OptionsEditorColleague requestor) { + if (myModified.contains(configurable)) return ActionCallback.REJECTED; myModified.add(configurable); return notify(new ColleagueAction() { - @NotNull @Override - public Promise process(final OptionsEditorColleague colleague) { + public ActionCallback process(final OptionsEditorColleague colleague) { return colleague.onModifiedAdded(configurable); } }, requestor); } - @NotNull - Promise fireModifiedRemoved(@NotNull final Configurable configurable, @Nullable OptionsEditorColleague requestor) { - if (!myModified.contains(configurable)) { - return Promises.rejectedPromise(); - } + ActionCallback fireModifiedRemoved(@NotNull final Configurable configurable, @Nullable OptionsEditorColleague requestor) { + if (!myModified.contains(configurable)) return ActionCallback.REJECTED; myModified.remove(configurable); return notify(new ColleagueAction() { - @NotNull @Override - public Promise process(final OptionsEditorColleague colleague) { + public ActionCallback process(final OptionsEditorColleague colleague) { return colleague.onModifiedRemoved(configurable); } }, requestor); } - @NotNull - Promise fireErrorsChanged(final Map errors, OptionsEditorColleague requestor) { - if (myErrors.equals(errors)) { - return Promises.rejectedPromise(); - } + ActionCallback fireErrorsChanged(final Map errors, OptionsEditorColleague requestor) { + if (myErrors.equals(errors)) return ActionCallback.REJECTED; myErrors = errors != null ? errors : new HashMap<>(); return notify(new ColleagueAction() { - @NotNull @Override - public Promise process(final OptionsEditorColleague colleague) { + public ActionCallback process(final OptionsEditorColleague colleague) { return colleague.onErrorsChanged(); } }, requestor); } - @NotNull - Promise notify(@NotNull ColleagueAction action, OptionsEditorColleague requestor) { - //noinspection unchecked - return (Promise)Promises.all(ContainerUtil.mapNotNull(myColleagues, it -> it == requestor ? null : action.process(it))); + ActionCallback notify(ColleagueAction action, OptionsEditorColleague requestor) { + final ActionCallback.Chunk chunk = new ActionCallback.Chunk(); + for (OptionsEditorColleague each : myColleagues) { + if (each != requestor) { + chunk.add(action.process(each)); + } + } + + return chunk.getWhenProcessed(); } public void fireReset(final Configurable configurable) { @@ -139,8 +127,7 @@ public class OptionsEditorContext { } interface ColleagueAction { - @NotNull - Promise process(OptionsEditorColleague colleague); + ActionCallback process(OptionsEditorColleague colleague); } public Configurable getCurrentConfigurable() { diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialog.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialog.java index 90439b118368..89ce635a598c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialog.java @@ -27,7 +27,6 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.util.ArrayList; -import java.util.List; import static com.intellij.openapi.actionSystem.IdeActions.ACTION_FIND; @@ -57,17 +56,15 @@ public class SettingsDialog extends DialogWrapper implements DataProvider { init(configurable, null); } - public SettingsDialog(@NotNull Project project, @NotNull List groups, @Nullable Configurable configurable, @Nullable String filter) { + public SettingsDialog(@NotNull Project project, @NotNull ConfigurableGroup[] groups, Configurable configurable, String filter) { super(project, true); - myDimensionServiceKey = DIMENSION_KEY; myEditor = new SettingsEditor(myDisposable, project, groups, configurable, filter, this::treeViewFactory); myApplyButtonNeeded = true; init(null, project); } - @NotNull - protected SettingsTreeView treeViewFactory(SettingsFilter filter, List groups) { + protected SettingsTreeView treeViewFactory(SettingsFilter filter, ConfigurableGroup[] groups) { return new SettingsTreeView(filter, groups); } @@ -76,7 +73,7 @@ public class SettingsDialog extends DialogWrapper implements DataProvider { TransactionGuard.getInstance().submitTransactionAndWait(() -> super.show()); } - private void init(@Nullable Configurable configurable, @Nullable Project project) { + private void init(Configurable configurable, @Nullable Project project) { String name = configurable == null ? null : configurable.getDisplayName(); String title = CommonBundle.settingsTitle(); if (project != null && project.isDefault()) { @@ -84,12 +81,8 @@ public class SettingsDialog extends DialogWrapper implements DataProvider { title, StringUtil.capitalize(IdeUICustomization.getInstance().getProjectConceptName())); } setTitle(name == null ? title : name.replace('\n', ' ')); - ShortcutSet set = getFindActionShortcutSet(); - if (set != null) { - new FindAction().registerCustomShortcutSet(set, getRootPane(), myDisposable); - } - + if (set != null) new FindAction().registerCustomShortcutSet(set, getRootPane(), myDisposable); init(); } @@ -196,7 +189,6 @@ public class SettingsDialog extends DialogWrapper implements DataProvider { super.doCancelAction(source); } - @Nullable static ShortcutSet getFindActionShortcutSet() { AnAction action = ActionManager.getInstance().getAction(ACTION_FIND); return action == null ? null : action.getShortcutSet(); diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialogFactory.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialogFactory.java index c397e48ddc8f..92a74db36600 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialogFactory.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsDialogFactory.java @@ -1,4 +1,18 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * 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.openapi.options.newEditor; import com.intellij.openapi.components.ServiceManager; @@ -7,34 +21,23 @@ import com.intellij.openapi.options.ConfigurableGroup; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.awt.*; -import java.util.Arrays; -import java.util.List; public class SettingsDialogFactory { public static SettingsDialogFactory getInstance() { return ServiceManager.getService(SettingsDialogFactory.class); } - @NotNull public DialogWrapper create(Project project, String key, @NotNull Configurable configurable, boolean showApplyButton, boolean showResetButton){ return new SettingsDialog(project, key, configurable, showApplyButton, showResetButton); } - @NotNull public DialogWrapper create(@NotNull Component parent, String key, @NotNull Configurable configurable, boolean showApplyButton, boolean showResetButton){ return new SettingsDialog(parent, key, configurable, showApplyButton, showResetButton); } - @NotNull public DialogWrapper create(@NotNull Project project, @NotNull ConfigurableGroup[] groups, Configurable configurable, String filter){ - return create(project, Arrays.asList(groups), configurable, filter); - } - - @NotNull - public DialogWrapper create(@NotNull Project project, @NotNull List groups, @Nullable Configurable configurable, @Nullable String filter) { return new SettingsDialog(project, groups, configurable, filter); } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java index ebbc50e4aeb7..bf9eaffbd3a3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsEditor.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.options.newEditor; import com.intellij.ide.util.PropertiesComponent; @@ -12,6 +12,7 @@ import com.intellij.openapi.options.ex.ConfigurableWrapper; import com.intellij.openapi.options.ex.Settings; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.LoadingDecorator; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; @@ -26,16 +27,16 @@ import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.concurrency.Promises; import javax.swing.*; import java.awt.*; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; -import java.util.List; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; /** * @author Sergey.Malenkov @@ -48,6 +49,7 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { private final PropertiesComponent myProperties; private final Settings mySettings; private final SettingsSearch mySearch; + private final JPanel mySearchPanel; private final SettingsFilter myFilter; private final SettingsTreeView myTreeView; private final ConfigurableEditor myEditor; @@ -59,19 +61,18 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { private final Map myControllers = new HashMap<>(); private ConfigurableController myLastController; - SettingsEditor(@NotNull Disposable parent, - @NotNull Project project, - @NotNull List groups, - @Nullable Configurable configurable, + SettingsEditor(Disposable parent, + Project project, + ConfigurableGroup[] groups, + Configurable configurable, final String filter, final ISettingsTreeViewFactory factory) { super(parent); myProperties = PropertiesComponent.getInstance(project); mySettings = new Settings(groups) { - @NotNull @Override - protected Promise selectImpl(Configurable configurable) { + protected ActionCallback selectImpl(Configurable configurable) { myFilter.update(null, false, true); return myTreeView.select(configurable); } @@ -87,8 +88,8 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { myTreeView.myTree.processKeyEvent(event); } }; - JPanel searchPanel = new JPanel(new VerticalLayout(0)); - searchPanel.add(VerticalLayout.CENTER, mySearch); + mySearchPanel = new JPanel(new VerticalLayout(0)); + mySearchPanel.add(VerticalLayout.CENTER, mySearch); myFilter = new SettingsFilter(project, groups, mySearch) { @Override Configurable getConfigurable(SimpleNode node) { @@ -113,16 +114,15 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { } }; myFilter.myContext.addColleague(new OptionsEditorColleague() { - @NotNull @Override - public Promise onSelected(@Nullable Configurable configurable, Configurable oldConfigurable) { + public ActionCallback onSelected(@Nullable Configurable configurable, Configurable oldConfigurable) { if (configurable != null) { myProperties.setValue(SELECTED_CONFIGURABLE, ConfigurableVisitor.ByID.getID(configurable)); myLoadingDecorator.startLoading(false); } checkModified(oldConfigurable); - Promise result = myEditor.select(configurable); - result.onSuccess(it -> { + ActionCallback result = myEditor.select(configurable); + result.doWhenDone(() -> { updateController(configurable); //requestFocusToEditor(); // TODO myLoadingDecorator.stopLoading(); @@ -130,31 +130,28 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { return result; } - @NotNull @Override - public Promise onModifiedAdded(Configurable configurable) { + public ActionCallback onModifiedAdded(Configurable configurable) { return updateIfCurrent(configurable); } - @NotNull @Override - public Promise onModifiedRemoved(Configurable configurable) { + public ActionCallback onModifiedRemoved(Configurable configurable) { return updateIfCurrent(configurable); } - @NotNull @Override - public Promise onErrorsChanged() { + public ActionCallback onErrorsChanged() { return updateIfCurrent(myFilter.myContext.getCurrentConfigurable()); } - private Promise updateIfCurrent(Configurable configurable) { + private ActionCallback updateIfCurrent(Configurable configurable) { if (configurable != null && configurable == myFilter.myContext.getCurrentConfigurable()) { updateStatus(configurable); - return Promises.resolvedPromise(); + return ActionCallback.DONE; } else { - return Promises.rejectedPromise("rejected"); + return ActionCallback.REJECTED; } } }); @@ -209,12 +206,12 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { myEditor.setPreferredSize(JBUI.size(800, 600)); myLoadingDecorator = new LoadingDecorator(myEditor, this, 10, true); myBanner = new Banner(myEditor.getResetAction()); - searchPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + mySearchPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); myBanner.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 10)); mySearch.setBackground(UIUtil.SIDE_PANEL_BACKGROUND); - searchPanel.setBackground(UIUtil.SIDE_PANEL_BACKGROUND); + mySearchPanel.setBackground(UIUtil.SIDE_PANEL_BACKGROUND); JComponent left = new JPanel(new BorderLayout()); - left.add(BorderLayout.NORTH, searchPanel); + left.add(BorderLayout.NORTH, mySearchPanel); left.add(BorderLayout.CENTER, myTreeView); JComponent right = new JPanel(new BorderLayout()); right.add(BorderLayout.NORTH, myBanner); @@ -246,17 +243,11 @@ final class SettingsEditor extends AbstractEditor implements DataProvider { configurable = ConfigurableVisitor.ALL.find(groups); } } - - myTreeView.select(configurable) - .onSuccess(it -> myFilter.update(filter, false, true)); - + myTreeView.select(configurable).doWhenDone(() -> myFilter.update(filter, false, true)); Disposer.register(this, myTreeView); installSpotlightRemover(); - //noinspection CodeBlock2Expr - mySearch.getTextEditor().addActionListener(event -> { - myTreeView.select(myFilter.myContext.getCurrentConfigurable()) - .onSuccess(o -> requestFocusToEditor()); - }); + mySearch.getTextEditor().addActionListener( + event -> myTreeView.select(myFilter.myContext.getCurrentConfigurable()).doWhenDone(this::requestFocusToEditor)); } private void requestFocusToEditor() { diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java index ddefa9580112..ed742b6b99e8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsFilter.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.options.newEditor; import com.intellij.ide.ui.search.ConfigurableHit; @@ -8,6 +8,7 @@ import com.intellij.openapi.options.ConfigurableGroup; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.options.ex.ConfigurableWrapper; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.LightColors; @@ -20,7 +21,6 @@ import org.jetbrains.annotations.NotNull; import javax.swing.event.DocumentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.List; import java.util.Set; public abstract class SettingsFilter extends ElementFilter.Active.Impl { @@ -30,7 +30,7 @@ public abstract class SettingsFilter extends ElementFilter.Active.Impl myGroups; + private final ConfigurableGroup[] myGroups; private final SearchableOptionsRegistrar myRegistrar = SearchableOptionsRegistrar.getInstance(); private Set myFiltered; @@ -39,7 +39,7 @@ public abstract class SettingsFilter extends ElementFilter.Active.Impl groups, SearchTextField search) { + SettingsFilter(Project project, ConfigurableGroup[] groups, SearchTextField search) { myProject = project; myGroups = groups; mySearch = search; @@ -120,7 +120,7 @@ public abstract class SettingsFilter extends ElementFilter.Active.Impl configurables, Set hits) { diff --git a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java index 3d10d2b7bcd6..c421c10c563c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java +++ b/platform/platform-impl/src/com/intellij/openapi/options/newEditor/SettingsTreeView.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.options.newEditor; import com.intellij.icons.AllIcons; @@ -14,6 +14,7 @@ import com.intellij.openapi.options.*; import com.intellij.openapi.options.ex.ConfigurableWrapper; import com.intellij.openapi.options.ex.SortedConfigurableGroup; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.registry.Registry; @@ -37,9 +38,6 @@ import com.intellij.util.ui.update.MergingUpdateQueue; import com.intellij.util.ui.update.Update; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.AsyncPromise; -import org.jetbrains.concurrency.Promise; -import org.jetbrains.concurrency.Promises; import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; @@ -82,7 +80,7 @@ public class SettingsTreeView extends JComponent implements Accessible, Disposab private Configurable myQueuedConfigurable; private MyControl myControl; - public SettingsTreeView(SettingsFilter filter, List groups) { + public SettingsTreeView(SettingsFilter filter, ConfigurableGroup[] groups) { myFilter = filter; myRoot = new MyRoot(groups); myTree = new MyTree(); @@ -378,61 +376,49 @@ public class SettingsTreeView extends JComponent implements Accessible, Disposab myScroller.setBounds(0, 0, getWidth(), getHeight()); } - @NotNull - Promise select(@Nullable Configurable configurable) { + ActionCallback select(@Nullable final Configurable configurable) { if (myBuilder.isSelectionBeingAdjusted()) { - return Promises.rejectedPromise(); + return ActionCallback.REJECTED; } - - AsyncPromise promise = new AsyncPromise<>(); + final ActionCallback callback = new ActionCallback(); myQueuedConfigurable = configurable; myQueue.queue(new Update(this) { @Override public void run() { - if (configurable != myQueuedConfigurable) { - return; - } + if (configurable == myQueuedConfigurable) { + if (configurable == null) { + fireSelected(null, callback); + } + else { + myBuilder.getReady(this).doWhenDone(() -> { + if (configurable != myQueuedConfigurable) return; - if (configurable == null) { - fireSelected(null) - .processed(promise); - } - else { - myBuilder.getReady(this).doWhenDone(() -> { - if (configurable != myQueuedConfigurable) return; + MyNode editorNode = findNode(configurable); + FilteringTreeStructure.FilteringNode editorUiNode = myBuilder.getVisibleNodeFor(editorNode); + if (editorUiNode == null) return; - MyNode editorNode = findNode(configurable); - FilteringTreeStructure.FilteringNode editorUiNode = myBuilder.getVisibleNodeFor(editorNode); - if (editorUiNode == null) return; - - @SuppressWarnings("CodeBlock2Expr") - Runnable handler = () -> { - fireSelected(configurable) - .processed(promise); - }; - - if (myBuilder.getSelectedElements().contains(editorUiNode)) { - myBuilder.scrollSelectionToVisible(handler, false); - } - else { - myBuilder.select(editorUiNode, handler); - } - }); + if (!myBuilder.getSelectedElements().contains(editorUiNode)) { + myBuilder.select(editorUiNode, () -> fireSelected(configurable, callback)); + } + else { + myBuilder.scrollSelectionToVisible(() -> fireSelected(configurable, callback), false); + } + }); + } } } @Override public void setRejected() { super.setRejected(); - promise.setError("rejected"); + callback.setRejected(); } }); - return promise; + return callback; } - @NotNull - private Promise fireSelected(Configurable configurable) { - return myFilter.myContext.fireSelected(configurable, this); + private void fireSelected(Configurable configurable, ActionCallback callback) { + myFilter.myContext.fireSelected(configurable, this).doWhenProcessed(callback.createSetDoneRunnable()); } @Override @@ -440,43 +426,39 @@ public class SettingsTreeView extends JComponent implements Accessible, Disposab myQueuedConfigurable = null; } - @NotNull @Override - public Promise onSelected(@Nullable Configurable configurable, Configurable oldConfigurable) { + public ActionCallback onSelected(@Nullable Configurable configurable, Configurable oldConfigurable) { return select(configurable); } - @NotNull @Override - public Promise onModifiedAdded(Configurable configurable) { + public ActionCallback onModifiedAdded(Configurable configurable) { myTree.repaint(); - return Promises.resolvedPromise(); + return ActionCallback.DONE; } - @NotNull @Override - public Promise onModifiedRemoved(Configurable configurable) { + public ActionCallback onModifiedRemoved(Configurable configurable) { myTree.repaint(); - return Promises.resolvedPromise(); + return ActionCallback.DONE; } - @NotNull @Override - public Promise onErrorsChanged() { - return Promises.resolvedPromise(); + public ActionCallback onErrorsChanged() { + return ActionCallback.DONE; } private final class MyRoot extends CachingSimpleNode { - private final List myGroups; + private final ConfigurableGroup[] myGroups; - private MyRoot(List groups) { + private MyRoot(ConfigurableGroup[] groups) { super(null); myGroups = groups; } @Override protected SimpleNode[] buildChildren() { - if (myGroups == null || myGroups.isEmpty()) { + if (myGroups == null || myGroups.length == 0) { return NO_CHILDREN; } ArrayList list = new ArrayList<>(); @@ -940,9 +922,8 @@ public class SettingsTreeView extends JComponent implements Accessible, Disposab return false; } - @NotNull @Override - protected Promise refilterNow(Object preferredSelection, boolean adjustSelection) { + protected ActionCallback refilterNow(Object preferredSelection, boolean adjustSelection) { final List toRestore = new ArrayList<>(); if (myFilter.myContext.isHoldingFilter() && !myWasHoldingFilter && myToExpandOnResetFilter == null) { AbstractTreeUi ui = myBuilder.getUi(); @@ -955,14 +936,14 @@ public class SettingsTreeView extends JComponent implements Accessible, Disposab myWasHoldingFilter = myFilter.myContext.isHoldingFilter(); + ActionCallback result = super.refilterNow(preferredSelection, adjustSelection); myRefilteringNow = true; - return super.refilterNow(preferredSelection, adjustSelection) - .onSuccess(o -> { - myRefilteringNow = false; - if (!myFilter.myContext.isHoldingFilter() && getSelectedElements().isEmpty()) { - restoreExpandedState(toRestore); - } - }); + return result.doWhenDone(() -> { + myRefilteringNow = false; + if (!myFilter.myContext.isHoldingFilter() && getSelectedElements().isEmpty()) { + restoreExpandedState(toRestore); + } + }); } private void restoreExpandedState(List toRestore) { diff --git a/platform/platform-impl/src/com/intellij/openapi/project/impl/JBProtocolOpenProjectCommand.java b/platform/platform-impl/src/com/intellij/openapi/project/impl/JBProtocolOpenProjectCommand.java index a879e31e280a..9306509f500e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/impl/JBProtocolOpenProjectCommand.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/impl/JBProtocolOpenProjectCommand.java @@ -1,4 +1,18 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.openapi.project.impl; import com.intellij.ide.impl.ProjectUtil; @@ -7,31 +21,21 @@ import com.intellij.openapi.application.JBProtocolCommand; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; -import org.jetbrains.annotations.NotNull; -import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; import java.util.Map; /** * @author Konstantin Bulenkov */ -final class JBProtocolOpenProjectCommand extends JBProtocolCommand { - JBProtocolOpenProjectCommand() { +public class JBProtocolOpenProjectCommand extends JBProtocolCommand { + public JBProtocolOpenProjectCommand() { super("open"); } @Override - public void perform(String target, @NotNull Map parameters) { - String path; - try { - path = URLDecoder.decode(target, StandardCharsets.UTF_8.name()); - } - catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - + public void perform(String target, Map parameters) { + String path = URLDecoder.decode(target); String projectPath = StringUtil.trimStart(path, LocalFileSystem.PROTOCOL_PREFIX); ApplicationManager.getApplication().invokeLater( () -> ProjectUtil.openProject(projectPath, null, true), ModalityState.NON_MODAL); diff --git a/platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java index bf7bb0f78bf5..f7775fdb5cb6 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/tree/TreePopupImpl.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ui.popup.tree; import com.intellij.icons.AllIcons; @@ -18,6 +18,7 @@ import com.intellij.ui.popup.WizardPopup; import com.intellij.ui.treeStructure.SimpleTree; import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder; import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure; +import com.intellij.util.Range; import com.intellij.util.ui.tree.TreeUtil; import org.jetbrains.annotations.NotNull; @@ -455,7 +456,7 @@ public class TreePopupImpl extends WizardPopup implements TreePopup, NextStepHan @Override protected void onSpeedSearchPatternChanged() { - myBuilder.refilterAsync(); + myBuilder.refilter(); } @Override diff --git a/platform/platform-impl/src/org/jetbrains/io/Responses.kt b/platform/platform-impl/src/org/jetbrains/io/Responses.kt index 16567faae523..993b92653687 100644 --- a/platform/platform-impl/src/org/jetbrains/io/Responses.kt +++ b/platform/platform-impl/src/org/jetbrains/io/Responses.kt @@ -41,7 +41,6 @@ fun HttpResponse.setDate() { } fun HttpResponse.addNoCache(): HttpResponse { - @Suppress("SpellCheckingInspection") headers().add(HttpHeaderNames.CACHE_CONTROL, "no-cache, no-store, must-revalidate, max-age=0") headers().add(HttpHeaderNames.PRAGMA, "no-cache") return this @@ -122,10 +121,11 @@ fun HttpResponseStatus.send(channel: Channel, request: HttpRequest? = null, desc } fun HttpResponseStatus.orInSafeMode(safeStatus: HttpResponseStatus): HttpResponseStatus { - @Suppress("NullableBooleanElvis") - return when { - Registry.`is`("ide.http.server.response.actual.status", true) || ApplicationManager.getApplication()?.isUnitTestMode ?: false -> this - else -> safeStatus + if (Registry.`is`("ide.http.server.response.actual.status", true) || (ApplicationManager.getApplication()?.isUnitTestMode ?: false)) { + return this + } + else { + return safeStatus } } diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 1fa6abc3b54a..eb1737274c9d 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -785,7 +785,7 @@ settings.code.style.import.xml.error.can.not.load=Can''t load code style scheme group.richcopy=Rich-text copy combobox.enable.richcopy.by.default=Copy as rich text by default -combobox.richcopy.color.scheme=Color scheme: +combobox.richcopy.color.scheme=Color scheme combobox.richcopy.color.scheme.active=Active scheme settings.code.style.default.general=Default diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 8d05b2b51b77..82fad1f2f133 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -98,8 +98,6 @@ errortree.note=Note: action.show.warnings=Show warnings action.next.message=Next Message action.previous.message=Previous Message -action.next.problem=Next Problem -action.previous.problem=Previous Problem action.stop=Stop errortree.prefix.line=line ({0}) checkbox.errortree.export.details=Details diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties index bad56b3012cf..ac623b33d3e7 100644 --- a/platform/platform-resources-en/src/messages/OptionsBundle.properties +++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties @@ -299,9 +299,6 @@ configurable.group.profiler.settings.description=\ # for com.intellij.psi.css.codeStyle.CssLanguageCodeStyleSettingsProvider.STYLESHEET_GROUP stylesheet.code.style.group.settings.description=Configure the code style used in the style sheet languages. -# suppress inspection "UnusedProperty" - for generating list of inner configurables, see ConfigurableEditor#createDefaultContent -sql.code.style.group.settings.description=Configure the code style used in SQL dialects. - configurable.default.project.tooltip=For new {0}s configurable.current.project.tooltip=For current {0} diff --git a/platform/platform-resources/src/brokenPlugins.txt b/platform/platform-resources/src/brokenPlugins.txt index 1c67338a3899..bf71c48500c1 100644 --- a/platform/platform-resources/src/brokenPlugins.txt +++ b/platform/platform-resources/src/brokenPlugins.txt @@ -115,5 +115,4 @@ Bazel 2018.12.03.0.2 2018.11.12.0.4 ru.makkarpov.ucl 0.1 0.1.1 0.1.2 com.undo_software.clion.reverse 2.0.0 "Randori Compiler" 0.2.0 0.2.1 0.2.3 0.2.4 0.3.0 -Docker 173.2605 191.4212.41 191.4738.6 -"Log Support" 1.0.11-11_and_newer \ No newline at end of file +Docker 173.2605 191.4212.41 191.4738.6 \ No newline at end of file diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index cdd6722fa986..b372ab35d646 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -513,8 +513,6 @@ - diff --git a/platform/platform-tests/testSrc/com/intellij/ide/util/treeView/FilteringTreeBuilderTest.java b/platform/platform-tests/testSrc/com/intellij/ide/util/treeView/FilteringTreeBuilderTest.java index c6de34f5f6de..dfafa2598438 100644 --- a/platform/platform-tests/testSrc/com/intellij/ide/util/treeView/FilteringTreeBuilderTest.java +++ b/platform/platform-tests/testSrc/com/intellij/ide/util/treeView/FilteringTreeBuilderTest.java @@ -1,6 +1,7 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.ide.util.treeView; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Ref; import com.intellij.ui.TreeUIHelper; @@ -8,9 +9,7 @@ import com.intellij.ui.speedSearch.ElementFilter; import com.intellij.ui.treeStructure.*; import com.intellij.ui.treeStructure.filtered.FilteringTreeBuilder; import com.intellij.ui.treeStructure.filtered.FilteringTreeStructure; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.concurrency.Promise; import java.util.LinkedHashMap; @@ -176,7 +175,7 @@ public class FilteringTreeBuilderTest extends BaseTreeTestCase { myFilter.update(text, selection); } - private static class Node extends CachingSimpleNode { + private class Node extends CachingSimpleNode { private final LinkedHashMap myKids = new LinkedHashMap<>(); @@ -210,6 +209,7 @@ public class FilteringTreeBuilderTest extends BaseTreeTestCase { @Override protected void updateFileStatus() { + } } @@ -240,8 +240,7 @@ public class FilteringTreeBuilderTest extends BaseTreeTestCase { return value.toString().startsWith(myPattern); } - @NotNull - public Promise update(final String pattern, Object selection) { + public ActionCallback update(final String pattern, Object selection) { myPattern = pattern; return fireUpdate(selection, true, false); } diff --git a/platform/platform-tests/testSrc/com/intellij/internal/statistics/SensitiveDataValidatorTest.kt b/platform/platform-tests/testSrc/com/intellij/internal/statistics/SensitiveDataValidatorTest.kt index c0bac868ee95..14e7a145241e 100644 --- a/platform/platform-tests/testSrc/com/intellij/internal/statistics/SensitiveDataValidatorTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/internal/statistics/SensitiveDataValidatorTest.kt @@ -79,8 +79,8 @@ class SensitiveDataValidatorTest : UsefulTestCase() { assertEmpty(validator.getEventRules(eventLogGroup)) assertTrue(validator.getEventDataRules(eventLogGroup).isEmpty()) - assertUndefinedRule(validator, eventLogGroup, "") - assertEventDataUndefinedRule(validator, eventLogGroup, "", "") + assertEventAccepted(validator, eventLogGroup, "") + assertEventDataAccepted(validator, eventLogGroup, "", "") } @Test @@ -197,10 +197,6 @@ class SensitiveDataValidatorTest : UsefulTestCase() { TestCase.assertEquals(ValidationResultType.ACCEPTED, validator.validateEvent(eventLogGroup, EventContext.create(s, Collections.emptyMap()))) } - private fun assertUndefinedRule(validator: SensitiveDataValidator, eventLogGroup: EventLogGroup, s: String) { - TestCase.assertEquals(ValidationResultType.UNDEFINED_RULE, validator.validateEvent(eventLogGroup, EventContext.create(s, Collections.emptyMap()))) - } - private fun assertEventRejected(validator: SensitiveDataValidator, eventLogGroup: EventLogGroup, s: String) { TestCase.assertEquals(ValidationResultType.REJECTED, validator.validateEvent(eventLogGroup, EventContext.create(s, Collections.emptyMap()))) } @@ -208,10 +204,6 @@ class SensitiveDataValidatorTest : UsefulTestCase() { private fun assertEventDataAccepted(validator: TestSensitiveDataValidator, eventLogGroup: EventLogGroup, key: String, dataValue: String) { TestCase.assertEquals(ValidationResultType.ACCEPTED, validator.validateEventData(eventLogGroup, key, dataValue)) } - - private fun assertEventDataUndefinedRule(validator: TestSensitiveDataValidator, eventLogGroup: EventLogGroup, key: String, dataValue: String) { - TestCase.assertEquals(ValidationResultType.UNDEFINED_RULE, validator.validateEventData(eventLogGroup, key, dataValue)) - } private fun assertEventDataRejected(validator: TestSensitiveDataValidator, eventLogGroup: EventLogGroup, key: String, dataValue: String) { TestCase.assertEquals(ValidationResultType.REJECTED, validator.validateEventData(eventLogGroup, key, dataValue)) } @@ -253,7 +245,7 @@ class SensitiveDataValidatorTest : UsefulTestCase() { if (FeatureUsageData.platformDataKeys.contains(key)) return ValidationResultType.ACCEPTED val whiteListRule = eventsValidators[group.id] - return if (whiteListRule == null || !whiteListRule.areEventDataRulesDefined()) ValidationResultType.UNDEFINED_RULE + return if (whiteListRule == null || !whiteListRule.areEventDataRulesDefined()) ValidationResultType.ACCEPTED else whiteListRule.validateEventData(key, value, EventContext.create("", Collections.emptyMap())) // there are no configured rules } } diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/encoding/FileEncodingTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/encoding/FileEncodingTest.java index e3a606d73d50..3db58a3108fa 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/vfs/encoding/FileEncodingTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/vfs/encoding/FileEncodingTest.java @@ -79,7 +79,7 @@ public class FileEncodingTest extends PlatformTestCase implements TestDialog { private TestDialog myOldTestDialogValue; @Override - public int show(@NotNull String message) { + public int show(String message) { return 0; } diff --git a/platform/platform-tests/testSrc/com/intellij/search/SearchableOptionsTest.java b/platform/platform-tests/testSrc/com/intellij/search/SearchableOptionsTest.java index 562dc3aa8be6..a097867ad97d 100644 --- a/platform/platform-tests/testSrc/com/intellij/search/SearchableOptionsTest.java +++ b/platform/platform-tests/testSrc/com/intellij/search/SearchableOptionsTest.java @@ -1,17 +1,29 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * 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.search; +import com.intellij.ide.actions.ShowSettingsUtilImpl; import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable; import com.intellij.ide.ui.search.ConfigurableHit; import com.intellij.ide.ui.search.SearchableOptionsRegistrar; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableGroup; -import com.intellij.openapi.options.ex.ConfigurableExtensionPointUtil; import com.intellij.testFramework.LightPlatformTestCase; import javax.swing.event.DocumentEvent; -import java.util.Collections; -import java.util.List; import java.util.Set; /** @@ -19,7 +31,7 @@ import java.util.Set; */ public class SearchableOptionsTest extends LightPlatformTestCase { public void testFindCodeTemplates() { - List groups = Collections.singletonList(ConfigurableExtensionPointUtil.getConfigurableGroup(getProject(), false)); + ConfigurableGroup[] groups = ShowSettingsUtilImpl.getConfigurableGroups(getProject(), false); ConfigurableHit configurables = SearchableOptionsRegistrar.getInstance().getConfigurables(groups, DocumentEvent.EventType.INSERT, null, "method", getProject()); Set configurableSet = configurables.getAll(); for (Configurable configurable : configurableSet) { diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsOrderEntryFactory.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsOrderEntryFactory.java new file mode 100644 index 000000000000..0b83fe2e6cf0 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsOrderEntryFactory.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module; + +import com.intellij.project.model.impl.module.dependencies.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.module.*; + +/** + * @author nik + */ +public class JpsOrderEntryFactory { + public static JpsOrderEntry createOrderEntry(@NotNull JpsRootModel model, JpsDependencyElement dependencyElement) { + if (dependencyElement instanceof JpsModuleSourceDependency) { + return new JpsModuleSourceOrderEntry(model, (JpsModuleSourceDependency)dependencyElement); + } + if (dependencyElement instanceof JpsModuleDependency) { + return new JpsModuleOrderEntry(model, (JpsModuleDependency)dependencyElement); + } + if (dependencyElement instanceof JpsLibraryDependency) { + return new JpsLibraryOrderEntry(model, (JpsLibraryDependency)dependencyElement); + } + if (dependencyElement instanceof JpsSdkDependency) { + final JpsSdkDependency sdkDependency = (JpsSdkDependency)dependencyElement; + if (sdkDependency.isInherited()) { + return new JpsInheritedSdkOrderEntry(model, sdkDependency); + } + return new JpsModuleSdkOrderEntry(model, sdkDependency); + } + throw new UnsupportedOperationException(); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java index d43cb4aed55b..94309ab2f117 100644 --- a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/JpsRootModel.java @@ -21,8 +21,10 @@ import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModuleRootModel; import com.intellij.openapi.roots.OrderEntry; import com.intellij.openapi.roots.impl.RootModelBase; +import com.intellij.openapi.vfs.pointers.VirtualFilePointer; import com.intellij.project.model.impl.module.content.JpsContentEntry; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.module.JpsDependencyElement; import org.jetbrains.jps.model.module.JpsModule; import java.util.ArrayList; @@ -34,14 +36,26 @@ import java.util.List; */ public class JpsRootModel extends RootModelBase implements ModuleRootModel { private final Module myModule; + private final JpsModule myJpsModule; + public VirtualFilePointer myExplodedDirectoryPointer; private final List myContentEntries; + private final List myOrderEntries; public JpsRootModel(Module module, JpsModule jpsModule) { myModule = module; + myJpsModule = jpsModule; myContentEntries = new ArrayList<>(); - for (String contentRoot : jpsModule.getContentRootsList().getUrls()) { + for (String contentRoot : myJpsModule.getContentRootsList().getUrls()) { myContentEntries.add(new JpsContentEntry(jpsModule, this, contentRoot)); } + myOrderEntries = new ArrayList<>(); + for (JpsDependencyElement element : myJpsModule.getDependenciesList().getDependencies()) { + myOrderEntries.add(JpsOrderEntryFactory.createOrderEntry(this, element)); + } + } + + public JpsModule getJpsModule() { + return myJpsModule; } @NotNull @@ -58,7 +72,7 @@ public class JpsRootModel extends RootModelBase implements ModuleRootModel { @NotNull @Override public OrderEntry[] getOrderEntries() { - return OrderEntry.EMPTY_ARRAY; + return myOrderEntries.toArray(OrderEntry.EMPTY_ARRAY); } @Override @@ -69,4 +83,8 @@ public class JpsRootModel extends RootModelBase implements ModuleRootModel { public Project getProject() { return myModule.getProject(); } + + public boolean isExcludeExplodedDirectory() { + return false; + } } diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java new file mode 100644 index 000000000000..2ba7616617b1 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsExportableOrderEntry.java @@ -0,0 +1,64 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.roots.DependencyScope; +import com.intellij.openapi.roots.ExportableOrderEntry; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.java.JpsJavaDependencyExtension; +import org.jetbrains.jps.model.java.JpsJavaDependencyScope; +import org.jetbrains.jps.model.java.JpsJavaExtensionService; +import org.jetbrains.jps.model.module.JpsDependencyElement; + +/** + * @author nik + */ +public abstract class JpsExportableOrderEntry extends JpsOrderEntry implements ExportableOrderEntry { + public JpsExportableOrderEntry(@NotNull JpsRootModel rootModel, @NotNull E dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public boolean isExported() { + final JpsJavaDependencyExtension extension = getExtension(); + return extension != null && extension.isExported(); + } + + @Override + public void setExported(boolean value) { + JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(myDependencyElement).setExported(value); + } + + @NotNull + @Override + public DependencyScope getScope() { + final JpsJavaDependencyExtension extension = getExtension(); + return extension != null ? DependencyScope.valueOf(extension.getScope().name()) : DependencyScope.COMPILE; + } + + @Nullable + private JpsJavaDependencyExtension getExtension() { + return JpsJavaExtensionService.getInstance().getDependencyExtension(myDependencyElement); + } + + @Override + public void setScope(@NotNull DependencyScope scope) { + final JpsJavaDependencyExtension extension = JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(myDependencyElement); + extension.setScope(JpsJavaDependencyScope.valueOf(scope.name())); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsInheritedSdkOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsInheritedSdkOrderEntry.java new file mode 100644 index 000000000000..7008c3190f45 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsInheritedSdkOrderEntry.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.roots.InheritedJdkOrderEntry; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsSdkDependency; + +/** + * @author nik + */ +public class JpsInheritedSdkOrderEntry extends JpsSdkOrderEntryBase implements InheritedJdkOrderEntry { + public JpsInheritedSdkOrderEntry(@NotNull JpsRootModel rootModel, @NotNull JpsSdkDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public R accept(@NotNull RootPolicy policy, @Nullable R initialValue) { + return policy.visitInheritedJdkOrderEntry(this, initialValue); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsLibraryOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsLibraryOrderEntry.java new file mode 100644 index 000000000000..7b2046936450 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsLibraryOrderEntry.java @@ -0,0 +1,106 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.roots.LibraryOrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.project.model.impl.module.JpsRootModel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.JpsCompositeElement; +import org.jetbrains.jps.model.JpsElementReference; +import org.jetbrains.jps.model.JpsGlobal; +import org.jetbrains.jps.model.JpsProject; +import org.jetbrains.jps.model.module.JpsLibraryDependency; +import org.jetbrains.jps.model.module.JpsModule; + +/** + * @author nik + */ +public class JpsLibraryOrderEntry extends JpsExportableOrderEntry implements LibraryOrderEntry { + public JpsLibraryOrderEntry(@NotNull JpsRootModel rootModel, @NotNull JpsLibraryDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public Library getLibrary() { + return null; + } + + @Override + @NotNull + public String getLibraryName() { + return myDependencyElement.getLibraryReference().getLibraryName(); + } + + @NotNull + @Override + public String getPresentableName() { + return getLibraryName(); + } + + @NotNull + @Override + public VirtualFile[] getFiles(@NotNull OrderRootType type) { + return getRootFiles(type); + } + + @NotNull + @Override + public String[] getUrls(@NotNull OrderRootType rootType) { + return getRootUrls(rootType); + } + + @NotNull + @Override + public VirtualFile[] getRootFiles(@NotNull OrderRootType type) { + final Library library = getLibrary(); + return library != null ? library.getFiles(type) : VirtualFile.EMPTY_ARRAY; + } + + @NotNull + @Override + public String[] getRootUrls(@NotNull OrderRootType type) { + final Library library = getLibrary(); + return library != null ? library.getUrls(type) : ArrayUtil.EMPTY_STRING_ARRAY; + } + + @Override + public String getLibraryLevel() { + final JpsElementReference reference = myDependencyElement.getLibraryReference().getParentReference(); + final JpsCompositeElement parent = reference.resolve(); + if (parent instanceof JpsGlobal) return LibraryTablesRegistrar.APPLICATION_LEVEL; + if (parent instanceof JpsProject) return LibraryTablesRegistrar.PROJECT_LEVEL; + if (parent instanceof JpsModule) return LibraryTableImplUtil.MODULE_LEVEL; + return LibraryTablesRegistrar.PROJECT_LEVEL; + } + + @Override + public boolean isModuleLevel() { + return LibraryTableImplUtil.MODULE_LEVEL.equals(getLibraryLevel()); + } + + @Override + public R accept(@NotNull RootPolicy policy, @Nullable R initialValue) { + return policy.visitLibraryOrderEntry(this, initialValue); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java new file mode 100644 index 000000000000..540d4fe56dd5 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleOrderEntry.java @@ -0,0 +1,82 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.ModuleOrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.OrderRootsEnumerator; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.openapi.roots.impl.ModuleRootManagerImpl; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.project.model.impl.module.JpsRootModel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsModuleDependency; + +/** + * @author nik + */ +public class JpsModuleOrderEntry extends JpsExportableOrderEntry implements ModuleOrderEntry { + public JpsModuleOrderEntry(@NotNull JpsRootModel rootModel, JpsModuleDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public Module getModule() { + return null; + } + + @NotNull + @Override + public String getModuleName() { + return myDependencyElement.getModuleReference().getModuleName(); + } + + @NotNull + @Override + public String getPresentableName() { + return getModuleName(); + } + + @Override + @NotNull + public VirtualFile[] getFiles(@NotNull OrderRootType type) { + final OrderRootsEnumerator enumerator = getEnumerator(type); + return enumerator != null ? enumerator.getRoots() : VirtualFile.EMPTY_ARRAY; + } + + @Nullable + private OrderRootsEnumerator getEnumerator(OrderRootType type) { + final Module module = getModule(); + if (module == null) return null; + + return ModuleRootManagerImpl.getCachingEnumeratorForType(type, module); + } + + @Override + @NotNull + public String[] getUrls(@NotNull OrderRootType rootType) { + final OrderRootsEnumerator enumerator = getEnumerator(rootType); + return enumerator != null ? enumerator.getUrls() : ArrayUtil.EMPTY_STRING_ARRAY; + } + + @Override + public R accept(@NotNull RootPolicy policy, @Nullable R initialValue) { + return policy.visitModuleOrderEntry(this, initialValue); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSdkOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSdkOrderEntry.java new file mode 100644 index 000000000000..ce9d8dac2794 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSdkOrderEntry.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.roots.ModuleJdkOrderEntry; +import com.intellij.openapi.roots.RootPolicy; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsSdkDependency; + +/** + * @author nik + */ +public class JpsModuleSdkOrderEntry extends JpsSdkOrderEntryBase implements ModuleJdkOrderEntry { + public JpsModuleSdkOrderEntry(@NotNull JpsRootModel rootModel, @NotNull JpsSdkDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public R accept(@NotNull RootPolicy policy, @Nullable R initialValue) { + return policy.visitModuleJdkOrderEntry(this, initialValue); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSourceOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSourceOrderEntry.java new file mode 100644 index 000000000000..7cbacc265d83 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsModuleSourceOrderEntry.java @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.project.ProjectBundle; +import com.intellij.openapi.roots.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.project.model.impl.module.JpsRootModel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.model.module.JpsModuleSourceDependency; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author nik + */ +public class JpsModuleSourceOrderEntry extends JpsOrderEntry implements ModuleSourceOrderEntry { + public JpsModuleSourceOrderEntry(@NotNull JpsRootModel rootModel, @NotNull JpsModuleSourceDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public R accept(@NotNull RootPolicy policy, @Nullable R initialValue) { + return policy.visitModuleSourceOrderEntry(this, initialValue); + } + + @NotNull + @Override + public String getPresentableName() { + return ProjectBundle.message("project.root.module.source"); + } + + @Override + @NotNull + public VirtualFile[] getFiles(@NotNull OrderRootType type) { + if (OrderRootType.SOURCES.equals(type)) { + return getRootModel().getSourceRoots(); + } + return VirtualFile.EMPTY_ARRAY; + } + + @Override + @NotNull + public String[] getUrls(@NotNull OrderRootType type) { + if (OrderRootType.SOURCES.equals(type)) { + final ContentEntry[] content = getRootModel().getContentEntries(); + List result = new ArrayList<>(); + for (ContentEntry contentEntry : content) { + final SourceFolder[] sourceFolders = contentEntry.getSourceFolders(); + for (SourceFolder sourceFolder : sourceFolders) { + final String url = sourceFolder.getUrl(); + result.add(url); + } + } + return ArrayUtil.toStringArray(result); + } + return ArrayUtil.EMPTY_STRING_ARRAY; + } + + @Override + @NotNull + public ModuleRootModel getRootModel() { + return myRootModel; + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsOrderEntry.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsOrderEntry.java new file mode 100644 index 000000000000..b0d000aae13c --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsOrderEntry.java @@ -0,0 +1,58 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.roots.OrderEntry; +import com.intellij.project.model.impl.module.JpsRootModel; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.module.JpsDependencyElement; + +/** + * @author nik + */ +public abstract class JpsOrderEntry implements OrderEntry { + @NotNull + protected final JpsRootModel myRootModel; + @NotNull + protected final E myDependencyElement; + + protected JpsOrderEntry(@NotNull JpsRootModel rootModel, @NotNull E dependencyElement) { + myRootModel = rootModel; + myDependencyElement = dependencyElement; + } + + @NotNull + @Override + public Module getOwnerModule() { + return myRootModel.getModule(); + } + + @Override + public boolean isSynthetic() { + return false; + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public int compareTo(OrderEntry o) { + throw new UnsupportedOperationException("'compareTo' not implemented in " + getClass().getName()); + } +} diff --git a/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsSdkOrderEntryBase.java b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsSdkOrderEntryBase.java new file mode 100644 index 000000000000..0516e69e3c43 --- /dev/null +++ b/platform/projectModel-impl/src/com/intellij/project/model/impl/module/dependencies/JpsSdkOrderEntryBase.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.project.model.impl.module.dependencies; + +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.JdkOrderEntry; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.project.model.JpsSdkManager; +import com.intellij.project.model.impl.module.JpsRootModel; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.library.JpsLibrary; +import org.jetbrains.jps.model.library.sdk.JpsSdkReference; +import org.jetbrains.jps.model.module.JpsSdkDependency; + +/** + * @author nik + */ +public abstract class JpsSdkOrderEntryBase extends JpsOrderEntry implements JdkOrderEntry { + public JpsSdkOrderEntryBase(@NotNull JpsRootModel rootModel, @NotNull JpsSdkDependency dependencyElement) { + super(rootModel, dependencyElement); + } + + @Override + public String getJdkName() { + final JpsSdkReference reference = myDependencyElement.getSdkReference(); + return reference != null ? reference.getSdkName() : null; + } + + @NotNull + @Override + public VirtualFile[] getFiles(@NotNull OrderRootType type) { + return getRootFiles(type); + } + + @NotNull + @Override + public String[] getUrls(@NotNull OrderRootType rootType) { + return getRootUrls(rootType); + } + + @Override + public Sdk getJdk() { + final JpsLibrary library = myDependencyElement.resolveSdk(); + if (library == null) return null; + return JpsSdkManager.getInstance().getSdk(library); + } + + @NotNull + @Override + public String getPresentableName() { + return "< " + getJdkName() + " >"; + } + + @NotNull + @Override + public VirtualFile[] getRootFiles(@NotNull OrderRootType type) { + final Sdk sdk = getJdk(); + if (sdk == null) return VirtualFile.EMPTY_ARRAY; + return sdk.getRootProvider().getFiles(type); + } + + @NotNull + @Override + public String[] getRootUrls(@NotNull OrderRootType type) { + final Sdk jdk = getJdk(); + if (jdk == null) return ArrayUtil.EMPTY_STRING_ARRAY; + return jdk.getRootProvider().getUrls(type); + } + + @Override + public boolean isSynthetic() { + return true; + } +} diff --git a/platform/testFramework/src/com/intellij/testFramework/propertyBased/MadTestingUtil.java b/platform/testFramework/src/com/intellij/testFramework/propertyBased/MadTestingUtil.java index a1bb973e14e8..fe2572f26898 100644 --- a/platform/testFramework/src/com/intellij/testFramework/propertyBased/MadTestingUtil.java +++ b/platform/testFramework/src/com/intellij/testFramework/propertyBased/MadTestingUtil.java @@ -181,8 +181,6 @@ public class MadTestingUtil { for (String shortId : except) { disableInspection(project, profile, shortId); } - // instantiate all tools to avoid extension loading in inconvenient moment - profile.getAllEnabledInspectionTools(project).forEach(state -> state.getTool().getTool()); ProjectInspectionProfileManager manager = (ProjectInspectionProfileManager)InspectionProjectProfileManager.getInstance(project); manager.addProfile(profile); diff --git a/platform/util/src/com/intellij/openapi/application/JetBrainsProtocolHandler.java b/platform/util/src/com/intellij/openapi/application/JetBrainsProtocolHandler.java index 16c83f402704..d771b130938c 100644 --- a/platform/util/src/com/intellij/openapi/application/JetBrainsProtocolHandler.java +++ b/platform/util/src/com/intellij/openapi/application/JetBrainsProtocolHandler.java @@ -1,9 +1,22 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.openapi.application; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.containers.ContainerUtil; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Collections; @@ -51,8 +64,7 @@ public class JetBrainsProtocolHandler { } else { ourParameters.put(key, value); } - } - else { + } else { ourParameters.put(keyValue, ""); } } @@ -90,7 +102,6 @@ public class JetBrainsProtocolHandler { ourCommand = null; } - @NotNull public static Map getParameters() { init(); return Collections.unmodifiableMap(ourParameters); diff --git a/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java b/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java index 99d87d6b2542..d0fc924210b3 100644 --- a/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java +++ b/platform/util/src/com/intellij/openapi/util/registry/RegistryValue.java @@ -18,6 +18,7 @@ import java.util.MissingResourceException; * @author Konstantin Bulenkov */ public class RegistryValue { + private final Registry myRegistry; private final String myKey; @Nullable private final RegistryKeyDescriptor myKeyDescriptor; @@ -120,7 +121,7 @@ public class RegistryValue { if (myKeyDescriptor != null) { return myKeyDescriptor.isRestartRequired(); } - return Boolean.parseBoolean(get(myKey + ".restartRequired", "false", false)); + return Boolean.valueOf(get(myKey + ".restartRequired", "false", false)); } public boolean isChangedFromDefault() { @@ -190,22 +191,37 @@ public class RegistryValue { LOG.info("Registry value '" + myKey + "' has changed to '" + value + '\''); } - public void setValue(boolean value, @NotNull Disposable parentDisposable) { + public void setValue(boolean value, Disposable parentDisposable) { final boolean prev = asBoolean(); setValue(value); - Disposer.register(parentDisposable, () -> setValue(prev)); + Disposer.register(parentDisposable, new Disposable() { + @Override + public void dispose() { + setValue(prev); + } + }); } - public void setValue(int value, @NotNull Disposable parentDisposable) { + public void setValue(int value, Disposable parentDisposable) { final int prev = asInteger(); setValue(value); - Disposer.register(parentDisposable, () -> setValue(prev)); + Disposer.register(parentDisposable, new Disposable() { + @Override + public void dispose() { + setValue(prev); + } + }); } - public void setValue(String value, @NotNull Disposable parentDisposable) { + public void setValue(String value, Disposable parentDisposable) { final String prev = asString(); setValue(value); - Disposer.register(parentDisposable, () -> setValue(prev)); + Disposer.register(parentDisposable, new Disposable() { + @Override + public void dispose() { + setValue(prev); + } + }); } boolean isChangedSinceAppStart() { @@ -218,7 +234,12 @@ public class RegistryValue { public void addListener(@NotNull final RegistryValueListener listener, @NotNull Disposable parent) { myListeners.add(listener); - Disposer.register(parent, () -> myListeners.remove(listener)); + Disposer.register(parent, new Disposable() { + @Override + public void dispose() { + myListeners.remove(listener); + } + }); } @Override diff --git a/platform/util/src/com/intellij/util/indexing/impl/InputData.java b/platform/util/src/com/intellij/util/indexing/impl/InputData.java new file mode 100644 index 000000000000..1761f3a44217 --- /dev/null +++ b/platform/util/src/com/intellij/util/indexing/impl/InputData.java @@ -0,0 +1,28 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.util.indexing.impl; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Map; + +public class InputData { + private static final InputData EMPTY = new InputData<>(Collections.emptyMap()); + + @SuppressWarnings("unchecked") + public static InputData empty() { + return EMPTY; + } + + @NotNull + private final Map myKeyValues; + + protected InputData(@NotNull Map values) { + myKeyValues = values; + } + + @NotNull + public Map getKeyValues() { + return myKeyValues; + } +} diff --git a/platform/util/src/com/intellij/util/indexing/impl/MapReduceIndex.java b/platform/util/src/com/intellij/util/indexing/impl/MapReduceIndex.java index 1db858cf0985..4e3c0c544ade 100644 --- a/platform/util/src/com/intellij/util/indexing/impl/MapReduceIndex.java +++ b/platform/util/src/com/intellij/util/indexing/impl/MapReduceIndex.java @@ -56,7 +56,7 @@ public abstract class MapReduceIndex implements InvertedIndex< protected final ForwardIndex myForwardIndex; //new private final com.intellij.util.indexing.impl.forward.ForwardIndex myForwardIndexMap; - private final ForwardIndexAccessor myForwardIndexAccessor; + private final ForwardIndexAccessor myForwardIndexAccessor; private final ReentrantReadWriteLock myLock = createLock(); private final boolean myUseIntForwardIndex; @@ -85,7 +85,7 @@ public abstract class MapReduceIndex implements InvertedIndex< protected MapReduceIndex(@NotNull IndexExtension extension, @NotNull IndexStorage storage, @Nullable com.intellij.util.indexing.impl.forward.ForwardIndex forwardIndexMap, - @Nullable ForwardIndexAccessor forwardIndexAccessor, + @Nullable ForwardIndexAccessor forwardIndexAccessor, @Nullable ForwardIndex forwardIndex) { myIndexId = extension.getName(); myExtension = extension; @@ -102,7 +102,7 @@ public abstract class MapReduceIndex implements InvertedIndex< protected MapReduceIndex(@NotNull IndexExtension extension, @NotNull IndexStorage storage, @Nullable com.intellij.util.indexing.impl.forward.ForwardIndex forwardIndex, - @Nullable ForwardIndexAccessor forwardIndexAccessor) { + @Nullable ForwardIndexAccessor forwardIndexAccessor) { this(extension, storage, forwardIndex, forwardIndexAccessor, null); } @@ -117,7 +117,7 @@ public abstract class MapReduceIndex implements InvertedIndex< return myForwardIndexMap; } - public ForwardIndexAccessor getForwardIndexAccessor() { + public ForwardIndexAccessor getForwardIndexAccessor() { return myForwardIndexAccessor; } @@ -266,26 +266,19 @@ public abstract class MapReduceIndex implements InvertedIndex< @NotNull protected UpdateData calculateUpdateData(final int inputId, @Nullable Input content) { - final Map data = mapInput(content); - Object forwardIndexData; - if (myForwardIndexAccessor != null) { - forwardIndexData = myForwardIndexAccessor.convertToDataType(data, content); - } else { - forwardIndexData = null; - } - return createUpdateData(data, + final InputData data = mapInput(content); + return createUpdateData(data.getKeyValues(), () -> getKeysDiffBuilder(inputId), - () -> updateForwardIndex(inputId, data, forwardIndexData)); + () -> updateForwardIndex(inputId, data)); } - protected void updateForwardIndex(int inputId, @NotNull Map data, @Nullable Object forwardIndexData) throws IOException { - if (myForwardIndex != null) myForwardIndex.putInputData(inputId, data); + protected void updateForwardIndex(int inputId, @NotNull InputData data) throws IOException { + if (myForwardIndex != null) myForwardIndex.putInputData(inputId, data.getKeyValues()); if (myForwardIndexMap != null) { if (myUseIntForwardIndex) { - ((IntForwardIndex)myForwardIndexMap).putInt(inputId, (Integer)forwardIndexData); + ((IntForwardIndex)myForwardIndexMap).putInt(inputId, ((IntForwardIndexAccessor)myForwardIndexAccessor).serializeIndexedDataToInt(data)); } else { - //noinspection unchecked - myForwardIndexMap.put(inputId, ((ForwardIndexAccessor)myForwardIndexAccessor).serializeIndexedData(forwardIndexData)); + myForwardIndexMap.put(inputId, myForwardIndexAccessor.serializeIndexedData(data)); } } } @@ -313,14 +306,14 @@ public abstract class MapReduceIndex implements InvertedIndex< } @NotNull - protected Map mapInput(@Nullable Input content) { + protected InputData mapInput(@Nullable Input content) { if (content == null) { - return Collections.emptyMap(); + return InputData.empty(); } Map data = myIndexer.map(content); checkValuesHaveProperEqualsAndHashCode(data, myIndexId, myValueExternalizer); checkCanceled(); - return data; + return new InputData<>(data); } public abstract void checkCanceled(); diff --git a/platform/util/src/com/intellij/util/indexing/impl/forward/AbstractForwardIndexAccessor.java b/platform/util/src/com/intellij/util/indexing/impl/forward/AbstractForwardIndexAccessor.java index cb57a5b0c829..539b58e161a8 100644 --- a/platform/util/src/com/intellij/util/indexing/impl/forward/AbstractForwardIndexAccessor.java +++ b/platform/util/src/com/intellij/util/indexing/impl/forward/AbstractForwardIndexAccessor.java @@ -5,6 +5,7 @@ import com.intellij.openapi.util.ThreadLocalCachedByteArray; import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.ByteArraySequence; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.indexing.impl.InputData; import com.intellij.util.indexing.impl.InputDataDiffBuilder; import com.intellij.util.io.DataExternalizer; import com.intellij.util.io.DataOutputStream; @@ -18,7 +19,7 @@ import java.io.IOException; import java.util.Map; @ApiStatus.Experimental -public abstract class AbstractForwardIndexAccessor implements ForwardIndexAccessor { +public abstract class AbstractForwardIndexAccessor implements ForwardIndexAccessor { @NotNull private final DataExternalizer myDataTypeExternalizer; @@ -40,8 +41,16 @@ public abstract class AbstractForwardIndexAccessor return createDiffBuilder(inputId, deserializeData(sequence)); } + @Nullable + public abstract DataType convertToDataType(@NotNull InputData data); + @Nullable @Override + public ByteArraySequence serializeIndexedData(@NotNull InputData data) throws IOException { + return serializeIndexedData(convertToDataType(data)); + } + + @Nullable public ByteArraySequence serializeIndexedData(@Nullable DataType data) throws IOException { if (data == null) return null; return serializeToByteSeq(data, myDataTypeExternalizer, getBufferInitialSize(data)); diff --git a/platform/util/src/com/intellij/util/indexing/impl/forward/AbstractMapForwardIndexAccessor.java b/platform/util/src/com/intellij/util/indexing/impl/forward/AbstractMapForwardIndexAccessor.java index 8e67ffafdfc0..c09e785d53d0 100644 --- a/platform/util/src/com/intellij/util/indexing/impl/forward/AbstractMapForwardIndexAccessor.java +++ b/platform/util/src/com/intellij/util/indexing/impl/forward/AbstractMapForwardIndexAccessor.java @@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.Map; -public abstract class AbstractMapForwardIndexAccessor extends AbstractForwardIndexAccessor { +public abstract class AbstractMapForwardIndexAccessor extends AbstractForwardIndexAccessor { public AbstractMapForwardIndexAccessor(@NotNull DataExternalizer externalizer) { super(externalizer); } diff --git a/platform/util/src/com/intellij/util/indexing/impl/forward/ForwardIndexAccessor.java b/platform/util/src/com/intellij/util/indexing/impl/forward/ForwardIndexAccessor.java index cd1368cd51dc..e4b97517f88a 100644 --- a/platform/util/src/com/intellij/util/indexing/impl/forward/ForwardIndexAccessor.java +++ b/platform/util/src/com/intellij/util/indexing/impl/forward/ForwardIndexAccessor.java @@ -2,32 +2,26 @@ package com.intellij.util.indexing.impl.forward; import com.intellij.openapi.util.io.ByteArraySequence; +import com.intellij.util.indexing.impl.InputData; import com.intellij.util.indexing.impl.InputDataDiffBuilder; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.Map; -/** - * - * @param should not hold strong reference to Input because it may lead to OOMs - */ -public interface ForwardIndexAccessor { +@ApiStatus.Experimental +public interface ForwardIndexAccessor { /** * creates a diff builder for given inputId. */ @NotNull InputDataDiffBuilder getDiffBuilder(int inputId, @Nullable ByteArraySequence sequence) throws IOException; - /** - * convert mapped key-values and input to a data type before it will be serialized - */ - DataType convertToDataType(@Nullable Map map, @Nullable Input content); - /** * serialize indexed data to forward index format. */ @Nullable - ByteArraySequence serializeIndexedData(@Nullable DataType data) throws IOException; + ByteArraySequence serializeIndexedData(@NotNull InputData data) throws IOException; } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/indexing/impl/forward/IntForwardIndexAccessor.java b/platform/util/src/com/intellij/util/indexing/impl/forward/IntForwardIndexAccessor.java index 26501c30133a..e0404ae75ced 100644 --- a/platform/util/src/com/intellij/util/indexing/impl/forward/IntForwardIndexAccessor.java +++ b/platform/util/src/com/intellij/util/indexing/impl/forward/IntForwardIndexAccessor.java @@ -2,6 +2,7 @@ package com.intellij.util.indexing.impl.forward; import com.intellij.openapi.util.io.ByteArraySequence; +import com.intellij.util.indexing.impl.InputData; import com.intellij.util.indexing.impl.InputDataDiffBuilder; import com.intellij.util.io.EnumeratorIntegerDescriptor; import org.jetbrains.annotations.NotNull; @@ -10,22 +11,17 @@ import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.Map; -public interface IntForwardIndexAccessor extends ForwardIndexAccessor { +public interface IntForwardIndexAccessor extends ForwardIndexAccessor { @NotNull @Override default InputDataDiffBuilder getDiffBuilder(int inputId, @Nullable ByteArraySequence sequence) throws IOException { return getDiffBuilderFromInt(inputId, sequence == null ? 0 : AbstractForwardIndexAccessor.deserializeFromByteSeq(sequence, EnumeratorIntegerDescriptor.INSTANCE)); } - @Override - default Integer convertToDataType(@Nullable Map map, @Nullable Input content) { - return convertToInt(map, content); - } - @Nullable @Override - default ByteArraySequence serializeIndexedData(@Nullable Integer data) throws IOException { - return data == null ? null : AbstractForwardIndexAccessor.serializeToByteSeq(data, EnumeratorIntegerDescriptor.INSTANCE, 8); + default ByteArraySequence serializeIndexedData(@NotNull InputData data) throws IOException { + return AbstractForwardIndexAccessor.serializeToByteSeq(serializeIndexedDataToInt(data), EnumeratorIntegerDescriptor.INSTANCE, 8); } /** @@ -34,8 +30,5 @@ public interface IntForwardIndexAccessor extends ForwardIndex @NotNull InputDataDiffBuilder getDiffBuilderFromInt(int inputId, int value) throws IOException; - /** - * convert mapped key-values and input to a data type before it will be serialized - */ - int convertToInt(@Nullable Map map, @Nullable Input content); + int serializeIndexedDataToInt(@NotNull InputData data); } diff --git a/platform/util/src/com/intellij/util/indexing/impl/forward/KeyCollectionForwardIndexAccessor.java b/platform/util/src/com/intellij/util/indexing/impl/forward/KeyCollectionForwardIndexAccessor.java index ad3d2b862ede..e66324e782c4 100644 --- a/platform/util/src/com/intellij/util/indexing/impl/forward/KeyCollectionForwardIndexAccessor.java +++ b/platform/util/src/com/intellij/util/indexing/impl/forward/KeyCollectionForwardIndexAccessor.java @@ -5,6 +5,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.indexing.IndexExtension; import com.intellij.util.indexing.IndexId; import com.intellij.util.indexing.impl.CollectionInputDataDiffBuilder; +import com.intellij.util.indexing.impl.InputData; import com.intellij.util.indexing.impl.InputDataDiffBuilder; import com.intellij.util.indexing.impl.InputIndexDataExternalizer; import com.intellij.util.io.DataExternalizer; @@ -13,16 +14,18 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.Collection; import java.util.Map; +import java.util.Set; @ApiStatus.Experimental -public class KeyCollectionForwardIndexAccessor extends AbstractForwardIndexAccessor, Input> { +public class KeyCollectionForwardIndexAccessor extends AbstractForwardIndexAccessor> { public KeyCollectionForwardIndexAccessor(@NotNull DataExternalizer> externalizer) { super(externalizer); } - public KeyCollectionForwardIndexAccessor(@NotNull IndexExtension extension) { + public KeyCollectionForwardIndexAccessor(@NotNull IndexExtension extension) { this(extension.getKeyDescriptor(), extension.getName()); } @@ -35,9 +38,11 @@ public class KeyCollectionForwardIndexAccessor extends Abstra return new CollectionInputDataDiffBuilder<>(inputId, keys); } + @Nullable @Override - public Collection convertToDataType(@Nullable Map map, @Nullable Input content) { - return ContainerUtil.isEmpty(map) ? null : map.keySet(); + public Collection convertToDataType(@NotNull InputData data) { + Set keys = data.getKeyValues().keySet(); + return keys.isEmpty() ? null : keys; } @Override diff --git a/platform/util/src/com/intellij/util/indexing/impl/forward/MapForwardIndexAccessor.java b/platform/util/src/com/intellij/util/indexing/impl/forward/MapForwardIndexAccessor.java index fb907c0d3bc2..b15cc162d024 100644 --- a/platform/util/src/com/intellij/util/indexing/impl/forward/MapForwardIndexAccessor.java +++ b/platform/util/src/com/intellij/util/indexing/impl/forward/MapForwardIndexAccessor.java @@ -1,13 +1,15 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.util.indexing.impl.forward; +import com.intellij.util.indexing.impl.InputData; import com.intellij.util.io.DataExternalizer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.Map; -public class MapForwardIndexAccessor extends AbstractMapForwardIndexAccessor, Input> { +public class MapForwardIndexAccessor extends AbstractMapForwardIndexAccessor> { public MapForwardIndexAccessor(@NotNull DataExternalizer> externalizer) { super(externalizer); } @@ -22,9 +24,9 @@ public class MapForwardIndexAccessor extends AbstractMapForwa protected int getBufferInitialSize(@NotNull Map map) { return 4 * map.size(); } - + @Nullable @Override - public Map convertToDataType(@Nullable Map map, @Nullable Input content) { - return map; + public Map convertToDataType(@NotNull InputData data) { + return data.getKeyValues(); } } diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index df427c61f253..0017f236b94a 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -3520,7 +3520,7 @@ public class UIUtil { @NotNull public static JBTreeTraverser uiTraverser(@Nullable Component component) { - return UI_TRAVERSER.withRoot(component).expandAndFilter(o -> !(o instanceof CellRendererPane)); + return UI_TRAVERSER.withRoot(component); } public static final Key> NOT_IN_HIERARCHY_COMPONENTS = Key.create("NOT_IN_HIERARCHY_COMPONENTS"); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java index eca9658369c8..dc20db3c7065 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/UpdateRequestsQueue.java @@ -1,7 +1,6 @@ // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.openapi.vcs.changes; -import com.intellij.diagnostic.ThreadDumper; import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; @@ -140,7 +139,7 @@ public class UpdateRequestsQueue { myWaitingUpdateCompletionSemaphores.add(semaphore); } if (!semaphore.waitFor(100 * 1000)) { - LOG.error("Too long VCS update\n" + ThreadDumper.dumpThreadsToString()); + LOG.error("Too long VCS update"); return; } } diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkout/JBProtocolCheckoutCommand.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkout/JBProtocolCheckoutCommand.java index f0cf24069d40..0cd83adee2a5 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/checkout/JBProtocolCheckoutCommand.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/checkout/JBProtocolCheckoutCommand.java @@ -1,4 +1,18 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.openapi.vcs.checkout; import com.intellij.openapi.application.JBProtocolCommand; @@ -9,23 +23,22 @@ import com.intellij.openapi.vcs.CheckoutProvider; import com.intellij.openapi.vcs.CheckoutProviderEx; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.ui.AppIcon; -import org.jetbrains.annotations.NotNull; import java.util.Map; /** * @author Konstantin Bulenkov */ -final class JBProtocolCheckoutCommand extends JBProtocolCommand { +public class JBProtocolCheckoutCommand extends JBProtocolCommand { private static final String REPOSITORY_NAME_KEY = "checkout.repo"; - JBProtocolCheckoutCommand() { + public JBProtocolCheckoutCommand() { super("checkout"); } @Override - public void perform(String vcsId, @NotNull Map parameters) { + public void perform(String vcsId, Map parameters) { String repository = parameters.get(REPOSITORY_NAME_KEY); if (StringUtil.isEmpty(repository)) { diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java index 6569a4b83352..6ecbf8127f40 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/impl/VcsChangesLazilyParsedDetails.java @@ -20,13 +20,11 @@ import com.google.common.base.Suppliers; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.LocalFilePath; +import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; -import com.intellij.vcs.log.Hash; -import com.intellij.vcs.log.VcsFullCommitDetails; -import com.intellij.vcs.log.VcsShortCommitDetails; -import com.intellij.vcs.log.VcsUser; +import com.intellij.vcs.log.*; import com.intellij.vcs.log.impl.VcsStatusMerger.MergedStatusInfo; import org.jetbrains.annotations.NotNull; @@ -35,7 +33,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import java.util.function.BiFunction; /** * Allows to postpone changes parsing, which might take long for a large amount of commits, @@ -55,21 +52,31 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme @NotNull ChangesParser changesParser) { super(hash, parents, commitTime, root, subject, author, message, committer, authorTime); myChangesParser = changesParser; - myChanges.set(reportedChanges.isEmpty() ? EMPTY_CHANGES : new UnparsedChanges(project, reportedChanges, (sources, parent) -> { - return myChangesParser.parseStatusInfo(project, this, sources, parent); - })); + myChanges.set(reportedChanges.isEmpty() ? EMPTY_CHANGES : new UnparsedChanges(project, reportedChanges)); } @NotNull @Override public Collection getChanges() { - return myChanges.get().getMergedChanges(); + try { + return myChanges.get().getMergedChanges(); + } + catch (VcsException e) { + LOG.error("Error happened when parsing changes", e); + return Collections.emptyList(); + } } @NotNull @Override public Collection getChanges(int parent) { - return myChanges.get().getChanges(parent); + try { + return myChanges.get().getChanges(parent); + } + catch (VcsException e) { + LOG.error("Error happened when parsing changes", e); + return Collections.emptyList(); + } } public int size() { @@ -82,7 +89,11 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme } else { for (int i = 0; i < getParents().size(); i++) { - size += changes.getChanges(i).size(); + try { + size += changes.getChanges(i).size(); + } + catch (VcsException ignored) { + } } } return size; @@ -90,10 +101,10 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme public interface Changes { @NotNull - Collection getMergedChanges(); + Collection getMergedChanges() throws VcsException; @NotNull - Collection getChanges(int parent); + Collection getChanges(int parent) throws VcsException; } protected static class EmptyChanges implements Changes { @@ -114,18 +125,15 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme @NotNull protected final Project myProject; @NotNull protected final List> myChangesOutput; @NotNull private final VcsStatusMerger myStatusMerger = new VcsFileStatusInfoMerger(); - @NotNull private final BiFunction, Integer, List> myParser; public UnparsedChanges(@NotNull Project project, - @NotNull List> changesOutput, - @NotNull BiFunction, Integer, List> parser) { + @NotNull List> changesOutput) { myProject = project; myChangesOutput = changesOutput; - myParser = parser; } @NotNull - protected ParsedChanges parseChanges() { + protected ParsedChanges parseChanges() throws VcsException { List mergedChanges = parseMergedChanges(); List> changes = computeChanges(mergedChanges); ParsedChanges parsedChanges = new ParsedChanges(mergedChanges, changes); @@ -134,41 +142,43 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme } @NotNull - private List parseMergedChanges() { + private List parseMergedChanges() throws VcsException { List> statuses = getMergedStatusInfo(); - List changes = myParser.apply(ContainerUtil.map(statuses, MergedStatusInfo::getStatusInfo), 0); + List changes = myChangesParser.parseStatusInfo(myProject, VcsChangesLazilyParsedDetails.this, + ContainerUtil.map(statuses, MergedStatusInfo::getStatusInfo), 0); LOG.assertTrue(changes.size() == statuses.size(), "Incorrectly parsed statuses " + statuses + " to changes " + changes); if (getParents().size() <= 1) return changes; // each merge change knows about all changes to parents List wrappedChanges = new ArrayList<>(statuses.size()); for (int i = 0; i < statuses.size(); i++) { - wrappedChanges.add(new MyMergedChange(changes.get(i), statuses.get(i), myParser)); + wrappedChanges.add(new MyMergedChange(changes.get(i), statuses.get(i))); } return wrappedChanges; } @NotNull @Override - public Collection getMergedChanges() { + public Collection getMergedChanges() throws VcsException { return parseChanges().getMergedChanges(); } @NotNull @Override - public Collection getChanges(int parent) { + public Collection getChanges(int parent) throws VcsException { return parseChanges().getChanges(parent); } @NotNull - private List> computeChanges(@NotNull Collection mergedChanges) { + private List> computeChanges(@NotNull Collection mergedChanges) + throws VcsException { if (myChangesOutput.size() == 1) { return Collections.singletonList(mergedChanges); } else { List> changes = ContainerUtil.newArrayListWithCapacity(myChangesOutput.size()); for (int i = 0; i < myChangesOutput.size(); i++) { - changes.add(myParser.apply(myChangesOutput.get(i), i)); + changes.add(myChangesParser.parseStatusInfo(myProject, VcsChangesLazilyParsedDetails.this, myChangesOutput.get(i), i)); } return changes; } @@ -188,27 +198,34 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme public List> getChangesOutput() { return myChangesOutput; } - } - private static class MyMergedChange extends MergedChange { - @NotNull private final Supplier> mySourceChanges; + private class MyMergedChange extends MergedChange { + @NotNull private final MergedStatusInfo myStatusInfo; + @NotNull private final Supplier> mySourceChanges; - MyMergedChange(@NotNull Change change, @NotNull MergedStatusInfo statusInfo, - @NotNull BiFunction, Integer, List> parser) { - super(change); - mySourceChanges = Suppliers.memoize(() -> { - List sourceChanges = ContainerUtil.newArrayList(); - for (int parent = 0; parent < statusInfo.getMergedStatusInfos().size(); parent++) { - List statusInfos = Collections.singletonList(statusInfo.getMergedStatusInfos().get(parent)); - sourceChanges.addAll(parser.apply(statusInfos, parent)); - } - return sourceChanges; - }); - } + MyMergedChange(@NotNull Change change, @NotNull MergedStatusInfo statusInfo) { + super(change); + myStatusInfo = statusInfo; + mySourceChanges = Suppliers.memoize(() -> { + List sourceChanges = ContainerUtil.newArrayList(); + try { + for (int parent = 0; parent < myStatusInfo.getMergedStatusInfos().size(); parent++) { + List statusInfos = Collections.singletonList(myStatusInfo.getMergedStatusInfos().get(parent)); + sourceChanges.addAll(myChangesParser.parseStatusInfo(myProject, VcsChangesLazilyParsedDetails.this, statusInfos, + parent)); + } + } + catch (VcsException e) { + LOG.error(e); + } + return sourceChanges; + }); + } - @Override - public List getSourceChanges() { - return mySourceChanges.get(); + @Override + public List getSourceChanges() { + return mySourceChanges.get(); + } } } @@ -238,6 +255,6 @@ public class VcsChangesLazilyParsedDetails extends VcsCommitMetadataImpl impleme List parseStatusInfo(@NotNull Project project, @NotNull VcsShortCommitDetails commit, @NotNull List changes, - int parentIndex); + int parentIndex) throws VcsException; } } diff --git a/plugins/devkit/devkit-core/resources/META-INF/plugin.xml b/plugins/devkit/devkit-core/resources/META-INF/plugin.xml index a9530604fabf..797c505c6bba 100644 --- a/plugins/devkit/devkit-core/resources/META-INF/plugin.xml +++ b/plugins/devkit/devkit-core/resources/META-INF/plugin.xml @@ -75,32 +75,26 @@ language="XML"/> @@ -110,62 +104,61 @@ enabledByDefault="true" level="ERROR" implementationClass="org.jetbrains.idea.devkit.inspections.RegistrationProblemsInspection"/> diff --git a/plugins/devkit/devkit-core/resources/org/jetbrains/idea/devkit/DevKitBundle.properties b/plugins/devkit/devkit-core/resources/org/jetbrains/idea/devkit/DevKitBundle.properties index 64ab7ca9cf7c..51c3e35c8ab3 100644 --- a/plugins/devkit/devkit-core/resources/org/jetbrains/idea/devkit/DevKitBundle.properties +++ b/plugins/devkit/devkit-core/resources/org/jetbrains/idea/devkit/DevKitBundle.properties @@ -144,9 +144,6 @@ class.implementation=implementation structure.sort.alphabetically.in.groups=Sort Alphabetically in Groups inspections.group.name=Plugin DevKit -inspections.group.descriptor=Plugin Descriptor -inspections.group.description.file=Description File -inspections.group.code=Code inspections.plugin.xml.inner.class.must.be.separated.with.dollar=Inner class must be separated with '$' inspections.plugin.xml.plugin.should.have.jetbrains.vendor=Plugin developed as a part of IntelliJ IDEA project should specify 'JetBrains' as its vendor inspections.plugin.xml.plugin.should.include.jetbrains.vendor=Plugin developed as a part of IntelliJ IDEA project should include 'JetBrains' as one of its vendors diff --git a/plugins/devkit/devkit-core/src/projectRoots/IdeaJdk.java b/plugins/devkit/devkit-core/src/projectRoots/IdeaJdk.java index 8e2f7ef005f6..cb7083566fcd 100644 --- a/plugins/devkit/devkit-core/src/projectRoots/IdeaJdk.java +++ b/plugins/devkit/devkit-core/src/projectRoots/IdeaJdk.java @@ -331,7 +331,8 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType { String sdkHome = ObjectUtils.notNull(sdk.getHomePath()); JpsModel model = JpsSerializationManager.getInstance().loadModel(sdkHome, PathManager.getOptionsPath()); JpsSdkReference sdkRef = model.getProject().getSdkReferencesTable().getSdkReference(JpsJavaSdkType.INSTANCE); - Sdk internalJava = sdkRef == null ? null : sdkModel.findSdk(sdkRef.getSdkName()); + String sdkName = sdkRef == null ? null : sdkRef.getSdkName(); + Sdk internalJava = sdkModel.findSdk(sdkName); if (internalJava != null && isValidInternalJdk(sdk, internalJava)) { setInternalJdk(sdk, sdkModificator, internalJava); } diff --git a/plugins/git4idea/src/git4idea/GitCommit.java b/plugins/git4idea/src/git4idea/GitCommit.java index 1f0bbfad60e1..279e8473c8d3 100644 --- a/plugins/git4idea/src/git4idea/GitCommit.java +++ b/plugins/git4idea/src/git4idea/GitCommit.java @@ -49,7 +49,7 @@ public final class GitCommit extends VcsChangesLazilyParsedDetails { public List parseStatusInfo(@NotNull Project project, @NotNull VcsShortCommitDetails commit, @NotNull List changes, - int parentIndex) { + int parentIndex) throws VcsException { String parentHash = null; if (parentIndex < commit.getParents().size()) { parentHash = commit.getParents().get(parentIndex).asString(); diff --git a/plugins/git4idea/src/git4idea/GitContentRevision.java b/plugins/git4idea/src/git4idea/GitContentRevision.java index 76eba029b479..c42a78d174c0 100644 --- a/plugins/git4idea/src/git4idea/GitContentRevision.java +++ b/plugins/git4idea/src/git4idea/GitContentRevision.java @@ -126,19 +126,16 @@ public class GitContentRevision implements ByteBackedContentRevision { } @NotNull - public static FilePath createPathFromEscaped(@NotNull VirtualFile vcsRoot, @NotNull String path) throws VcsException { - String absolutePath = makeAbsolutePath(vcsRoot, GitUtil.unescapePath(path)); + public static FilePath createPath(@NotNull VirtualFile vcsRoot, + @NotNull String path, + boolean unescapePath) throws VcsException { + String absolutePath = makeAbsolutePath(vcsRoot, path, unescapePath); return VcsUtil.getFilePath(absolutePath, false); } @NotNull - public static FilePath createPath(@NotNull VirtualFile vcsRoot, @NotNull String unescapedPath) { - String absolutePath = makeAbsolutePath(vcsRoot, unescapedPath); - return VcsUtil.getFilePath(absolutePath, false); - } - - @NotNull - private static String makeAbsolutePath(@NotNull VirtualFile vcsRoot, @NotNull String unescapedPath) { + private static String makeAbsolutePath(@NotNull VirtualFile vcsRoot, @NotNull String path, boolean unescapePath) throws VcsException { + String unescapedPath = unescapePath ? GitUtil.unescapePath(path) : path; return vcsRoot.getPath() + "/" + unescapedPath; } @@ -176,8 +173,7 @@ public class GitContentRevision implements ByteBackedContentRevision { @Nullable Charset charset) { if (path.getFileType().isBinary()) { return new GitBinaryContentRevision(path, revisionNumber, project); - } - else { + } else { return new GitContentRevision(path, revisionNumber, project, charset); } } diff --git a/plugins/git4idea/src/git4idea/GitStatisticsCollector.kt b/plugins/git4idea/src/git4idea/GitStatisticsCollector.kt index 974fc29996bf..259b99e6ea9a 100644 --- a/plugins/git4idea/src/git4idea/GitStatisticsCollector.kt +++ b/plugins/git4idea/src/git4idea/GitStatisticsCollector.kt @@ -24,7 +24,7 @@ class GitStatisticsCollector : ProjectUsagesCollector() { val usages = hashSetOf() usages.add(UsageDescriptor("config.repo.sync." + settings.syncSetting.name, 1)) - usages.add(UsageDescriptor("config.update.type." + settings.updateMethod.name, 1)) + usages.add(UsageDescriptor("config.update.type." + settings.updateType.name, 1)) usages.add(UsageDescriptor("config.save.policy." + settings.updateChangesPolicy().name, 1)) usages.add(getBooleanUsage("config.ssh", appSettings.isUseIdeaSsh)) diff --git a/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java b/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java index fd212e646412..419b91d94ec2 100644 --- a/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java +++ b/plugins/git4idea/src/git4idea/changes/GitChangeUtils.java @@ -143,7 +143,7 @@ public class GitChangeUtils { final ContentRevision before; final ContentRevision after; final String path = tokens[tokens.length - 1]; - final FilePath filePath = GitContentRevision.createPathFromEscaped(vcsRoot, path); + final FilePath filePath = GitContentRevision.createPath(vcsRoot, path, true); switch (tokens[0].charAt(0)) { case 'C': case 'A': @@ -167,7 +167,7 @@ public class GitChangeUtils { break; case 'R': status = FileStatus.MODIFIED; - final FilePath oldFilePath = GitContentRevision.createPathFromEscaped(vcsRoot, tokens[1]); + final FilePath oldFilePath = GitContentRevision.createPath(vcsRoot, tokens[1], true); before = GitContentRevision.createRevision(oldFilePath, parentRevision, project); after = GitContentRevision.createRevision(filePath, thisRevision, project); break; diff --git a/plugins/git4idea/src/git4idea/config/GitVcsPanel.java b/plugins/git4idea/src/git4idea/config/GitVcsPanel.java index 3eb1eac393b6..6c1d83970935 100644 --- a/plugins/git4idea/src/git4idea/config/GitVcsPanel.java +++ b/plugins/git4idea/src/git4idea/config/GitVcsPanel.java @@ -186,7 +186,7 @@ public class GitVcsPanel implements ConfigurableUi, } @NotNull - public UpdateMethod getUpdateMethod() { + public UpdateMethod getUpdateType() { return myState.getUpdateMethod(); } - public void setUpdateMethod(UpdateMethod updateType) { + public void setUpdateType(UpdateMethod updateType) { myState.setUpdateMethod(updateType); } diff --git a/plugins/git4idea/src/git4idea/history/GitChangesParser.java b/plugins/git4idea/src/git4idea/history/GitChangesParser.java index 965341dda79b..f6e5dd02fbbb 100644 --- a/plugins/git4idea/src/git4idea/history/GitChangesParser.java +++ b/plugins/git4idea/src/git4idea/history/GitChangesParser.java @@ -43,7 +43,7 @@ public class GitChangesParser { @NotNull List statusInfos, @NotNull String hash, @NotNull Date date, - @Nullable String parentsHash) { + @Nullable String parentsHash) throws VcsException { GitRevisionNumber thisRevision = new GitRevisionNumber(hash, date); GitRevisionNumber parentRevision = parentsHash == null ? null : new GitRevisionNumber(parentsHash); @@ -59,11 +59,11 @@ public class GitChangesParser { @NotNull VirtualFile vcsRoot, @NotNull VcsRevisionNumber thisRevision, @Nullable VcsRevisionNumber parentRevision, - @NotNull VcsFileStatusInfo statusInfo) { + @NotNull VcsFileStatusInfo statusInfo) throws VcsException { final ContentRevision before; final ContentRevision after; final String path = statusInfo.getFirstPath(); - final FilePath filePath = GitContentRevision.createPath(vcsRoot, path); + final FilePath filePath = GitContentRevision.createPath(vcsRoot, path, false); FileStatus status; switch (statusInfo.getType()) { @@ -85,7 +85,7 @@ public class GitChangesParser { case MOVED: status = FileStatus.MODIFIED; String secondPath = statusInfo.getSecondPath(); - final FilePath filePathAfterRename = secondPath == null ? filePath : GitContentRevision.createPath(vcsRoot, secondPath); + final FilePath filePathAfterRename = secondPath == null ? filePath : GitContentRevision.createPath(vcsRoot, secondPath, false); before = GitContentRevision.createRevision(filePath, parentRevision, project); after = GitContentRevision.createRevision(filePathAfterRename, thisRevision, project); break; diff --git a/plugins/git4idea/src/git4idea/push/GitPushOperation.java b/plugins/git4idea/src/git4idea/push/GitPushOperation.java index 7df1ac031136..3efa12e0be8f 100644 --- a/plugins/git4idea/src/git4idea/push/GitPushOperation.java +++ b/plugins/git4idea/src/git4idea/push/GitPushOperation.java @@ -443,15 +443,15 @@ public class GitPushOperation { UpdateMethod updateMethod = settings.getUpdateMethod(); mySettings.setUpdateAllRootsIfPushRejected(settings.shouldUpdateAllRoots()); if (!rebaseOverMergeDetected // don't overwrite explicit "rebase" with temporary "merge" caused by merge commits - && mySettings.getUpdateMethod() != updateMethod && mySettings.getUpdateMethod() != UpdateMethod.BRANCH_DEFAULT) { // don't overwrite "branch default" setting - mySettings.setUpdateMethod(updateMethod); + && mySettings.getUpdateType() != updateMethod && mySettings.getUpdateType() != UpdateMethod.BRANCH_DEFAULT) { // don't overwrite "branch default" setting + mySettings.setUpdateType(updateMethod); } } @NotNull private PushUpdateSettings readPushUpdateSettings() { boolean updateAllRoots = mySettings.shouldUpdateAllRootsIfPushRejected(); - UpdateMethod updateMethod = mySettings.getUpdateMethod(); + UpdateMethod updateMethod = mySettings.getUpdateType(); if (updateMethod == UpdateMethod.BRANCH_DEFAULT) { // deliberate limitation: we have only 2 buttons => choose method from the 1st repo if different updateMethod = GitUpdater.resolveUpdateMethod(myPushSpecs.keySet().iterator().next()); diff --git a/plugins/git4idea/src/git4idea/status/GitChangesCollector.java b/plugins/git4idea/src/git4idea/status/GitChangesCollector.java index 5a3374f200e0..a063ccb1a6b7 100644 --- a/plugins/git4idea/src/git4idea/status/GitChangesCollector.java +++ b/plugins/git4idea/src/git4idea/status/GitChangesCollector.java @@ -235,7 +235,7 @@ class GitChangesCollector { final char xStatus = xyStatus.charAt(0); final char yStatus = xyStatus.charAt(1); - final FilePath filepath = GitContentRevision.createPath(myVcsRoot, path); + final FilePath filepath = GitContentRevision.createPath(myVcsRoot, path, false); switch (xStatus) { case ' ': @@ -308,7 +308,7 @@ class GitChangesCollector { case 'R': //noinspection AssignmentToForLoopParameter pos += 1; // read the "from" filepath which is separated also by NUL character. - FilePath oldFilepath = GitContentRevision.createPath(myVcsRoot, split[pos]); + FilePath oldFilepath = GitContentRevision.createPath(myVcsRoot, split[pos], false); if (yStatus == 'D') { reportDeleted(oldFilepath, head); diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java b/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java index 8480c55a584c..5ee76d76f688 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateEnvironment.java @@ -45,7 +45,7 @@ public class GitUpdateEnvironment implements UpdateEnvironment { final GitUpdateProcess gitUpdateProcess = new GitUpdateProcess(myProject, progressIndicator, getRepositoriesFromRoots(repositoryManager, roots), updatedFiles, true, true); - boolean result = gitUpdateProcess.update(mySettings.getUpdateMethod()).isSuccess(); + boolean result = gitUpdateProcess.update(mySettings.getUpdateType()).isSuccess(); return new GitUpdateSession(result, gitUpdateProcess.getSkippedRoots()); } diff --git a/plugins/git4idea/src/git4idea/update/GitUpdateOptionsPanel.java b/plugins/git4idea/src/git4idea/update/GitUpdateOptionsPanel.java index aa01fb3fa50f..ec03decba3e0 100644 --- a/plugins/git4idea/src/git4idea/update/GitUpdateOptionsPanel.java +++ b/plugins/git4idea/src/git4idea/update/GitUpdateOptionsPanel.java @@ -39,7 +39,7 @@ public class GitUpdateOptionsPanel { public boolean isModified(GitVcsSettings settings) { UpdateMethod type = getUpdateType(); - return type != settings.getUpdateMethod() || updateSaveFilesPolicy() != settings.updateChangesPolicy(); + return type != settings.getUpdateType() || updateSaveFilesPolicy() != settings.updateChangesPolicy(); } /** @@ -71,7 +71,7 @@ public class GitUpdateOptionsPanel { * Save configuration to settings object */ public void applyTo(GitVcsSettings settings) { - settings.setUpdateMethod(getUpdateType()); + settings.setUpdateType(getUpdateType()); settings.setUpdateChangesPolicy(updateSaveFilesPolicy()); } @@ -79,7 +79,7 @@ public class GitUpdateOptionsPanel { * Update panel according to settings */ public void updateFrom(GitVcsSettings settings) { - switch (settings.getUpdateMethod()) { + switch (settings.getUpdateType()) { case REBASE: myForceRebaseRadioButton.setSelected(true); break; @@ -90,7 +90,7 @@ public class GitUpdateOptionsPanel { myBranchDefaultRadioButton.setSelected(true); break; default: - assert false : "Unknown value of update type: " + settings.getUpdateMethod(); + assert false : "Unknown value of update type: " + settings.getUpdateType(); } UpdatePolicyUtils.updatePolicyItem(settings.updateChangesPolicy(), myStashRadioButton, myShelveRadioButton); } diff --git a/plugins/git4idea/tests/git4idea/push/GitPushOperationSingleRepoTest.kt b/plugins/git4idea/tests/git4idea/push/GitPushOperationSingleRepoTest.kt index 70a8c4c67946..8a85271ea246 100644 --- a/plugins/git4idea/tests/git4idea/push/GitPushOperationSingleRepoTest.kt +++ b/plugins/git4idea/tests/git4idea/push/GitPushOperationSingleRepoTest.kt @@ -298,7 +298,7 @@ class GitPushOperationSingleRepoTest : GitPushOperationBaseTest() { } fun `test dont silently update if force push is rejected`() { - settings.updateMethod = UpdateMethod.REBASE + settings.updateType = UpdateMethod.REBASE settings.setAutoUpdateIfPushRejected(true) val remoteTipAndPushResult = forcePushWithReject(true) @@ -311,7 +311,7 @@ class GitPushOperationSingleRepoTest : GitPushOperationBaseTest() { fun `test dont silently update if force with lease push is rejected`() { assumeForceWithLeaseSupported() - settings.updateMethod = UpdateMethod.REBASE + settings.updateType = UpdateMethod.REBASE settings.setAutoUpdateIfPushRejected(true) val remoteTipAndPushResult = forcePushWithReject(false) @@ -448,7 +448,7 @@ class GitPushOperationSingleRepoTest : GitPushOperationBaseTest() { generateUnpushedMergedCommitProblem() settings.setAutoUpdateIfPushRejected(true) - settings.updateMethod = UpdateMethod.REBASE + settings.updateType = UpdateMethod.REBASE var rebaseOverMergeProblemDetected = false dialogManager.onMessage { @@ -462,7 +462,7 @@ class GitPushOperationSingleRepoTest : GitPushOperationBaseTest() { fun `test dont overwrite rebase setting when chose to merge due to unpushed merge commits`() { generateUnpushedMergedCommitProblem() - settings.updateMethod = UpdateMethod.REBASE + settings.updateType = UpdateMethod.REBASE var rebaseOverMergeProblemDetected = false dialogManager.onDialog(GitRejectedPushUpdateDialog::class.java, { @@ -472,12 +472,12 @@ class GitPushOperationSingleRepoTest : GitPushOperationBaseTest() { push("master", "origin/master") assertTrue(rebaseOverMergeProblemDetected) assertEquals("Update method was overwritten by temporary update-via-merge decision", - UpdateMethod.REBASE, settings.updateMethod) + UpdateMethod.REBASE, settings.updateType) } fun `test respect branch default setting for rejected push dialog`() { generateUpdateNeeded() - settings.updateMethod = UpdateMethod.BRANCH_DEFAULT + settings.updateType = UpdateMethod.BRANCH_DEFAULT git("config branch.master.rebase true") var defaultActionName = "" @@ -498,7 +498,7 @@ class GitPushOperationSingleRepoTest : GitPushOperationBaseTest() { fun `test respect branch default setting for silent update when rejected push`() { generateUpdateNeeded() - settings.updateMethod = UpdateMethod.BRANCH_DEFAULT + settings.updateType = UpdateMethod.BRANCH_DEFAULT git("config branch.master.rebase true") settings.setAutoUpdateIfPushRejected(true) @@ -510,7 +510,7 @@ class GitPushOperationSingleRepoTest : GitPushOperationBaseTest() { // => simply don't rewrite the setting if the same value is chosen, as was default value initially fun `test dont overwrite branch default setting when agree in rejected push dialog`() { generateUpdateNeeded() - settings.updateMethod = UpdateMethod.BRANCH_DEFAULT + settings.updateType = UpdateMethod.BRANCH_DEFAULT git("config branch.master.rebase true") dialogManager.onDialog(GitRejectedPushUpdateDialog::class.java, { @@ -518,7 +518,7 @@ class GitPushOperationSingleRepoTest : GitPushOperationBaseTest() { }) push("master", "origin/master") - assertEquals(UpdateMethod.BRANCH_DEFAULT, settings.updateMethod) + assertEquals(UpdateMethod.BRANCH_DEFAULT, settings.updateType) } private fun generateUpdateNeeded() { diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkCounter.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkCounter.kt index abd686492eaa..11c6df9f8baa 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkCounter.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/dataFlow/WorkCounter.kt @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.psi.dataFlow +import com.intellij.codeInspection.dataFlow.WorkingTimeMeasurer import com.intellij.openapi.util.registry.Registry internal class WorkCounter { diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/uast/GroovyUastPlugin.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/uast/GroovyUastPlugin.kt index 11792ed9ee3f..4cf382ece532 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/uast/GroovyUastPlugin.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/uast/GroovyUastPlugin.kt @@ -2,7 +2,10 @@ package org.jetbrains.plugins.groovy.lang.psi.uast import com.intellij.lang.Language -import com.intellij.psi.* +import com.intellij.psi.PsiAnnotation +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiElement +import com.intellij.psi.ResolveResult import com.intellij.psi.impl.source.tree.LeafPsiElement import com.intellij.psi.util.strictParents import org.jetbrains.plugins.groovy.GroovyLanguage @@ -16,7 +19,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod import org.jetbrains.uast.* -import org.jetbrains.uast.expressions.UInjectionHost /** * This is a very limited implementation of UastPlugin for Groovy, @@ -65,16 +67,12 @@ class GroovyUastPlugin : UastLanguagePlugin { } -class GrULiteral(val grElement: GrLiteral, val parentProvider: () -> UElement?) : ULiteralExpression, UInjectionHost { +class GrULiteral(val grElement: GrLiteral, val parentProvider: () -> UElement?) : ULiteralExpression { override val value: Any? get() = grElement.value override fun evaluate(): Any? = value override val uastParent: UElement? by lazy(parentProvider) override val psi: PsiElement? = grElement override val annotations: List = emptyList() //not implemented - override val isString: Boolean - get() = super.isString - override val psiLanguageInjectionHost: PsiLanguageInjectionHost - get() = grElement } class GrUNamedExpression(val grElement: GrAnnotationNameValuePair, val parentProvider: () -> UElement?) : UNamedExpression { diff --git a/plugins/java-i18n/intellij.java.i18n.iml b/plugins/java-i18n/intellij.java.i18n.iml index 81ff6d9c441c..7118b70b6283 100644 --- a/plugins/java-i18n/intellij.java.i18n.iml +++ b/plugins/java-i18n/intellij.java.i18n.iml @@ -22,6 +22,5 @@ - \ No newline at end of file diff --git a/plugins/java-i18n/src/com/intellij/codeInspection/capitalization/TitleCapitalizationInspection.java b/plugins/java-i18n/src/com/intellij/codeInspection/capitalization/TitleCapitalizationInspection.java index 7a96010b8d1c..6ad7906fae8e 100644 --- a/plugins/java-i18n/src/com/intellij/codeInspection/capitalization/TitleCapitalizationInspection.java +++ b/plugins/java-i18n/src/com/intellij/codeInspection/capitalization/TitleCapitalizationInspection.java @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInspection.capitalization; import com.intellij.codeInsight.AnnotationUtil; @@ -80,7 +80,7 @@ public class TitleCapitalizationInspection extends AbstractBaseJavaLocalInspecti String titleValue, @NotNull ProblemsHolder holder, Nls.Capitalization capitalization) { - if (!NlsCapitalizationUtil.isCapitalizationSatisfied(titleValue, capitalization)) { + if (!isCapitalizationSatisfied(titleValue, capitalization)) { holder.registerProblem(e, "String '" + titleValue + "' is not properly capitalized. It should have " + StringUtil.toLowerCase(capitalization.toString()) + " capitalization", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new TitleCapitalizationFix(titleValue, capitalization)); @@ -141,6 +141,38 @@ public class TitleCapitalizationInspection extends AbstractBaseJavaLocalInspecti return null; } + public static boolean isCapitalizationSatisfied(String value, Nls.Capitalization capitalization) { + if (StringUtil.isEmpty(value) || capitalization == Nls.Capitalization.NotSpecified) { + return true; + } + value = value.replace("&", ""); + return capitalization == Nls.Capitalization.Title + ? StringUtil.wordsToBeginFromUpperCase(value).equals(value) + : checkSentenceCapitalization(value); + } + + private static boolean checkSentenceCapitalization(@NotNull String value) { + List words = StringUtil.split(value, " "); + if (words.size() == 0) return true; + if (Character.isLetter(words.get(0).charAt(0)) && !isCapitalizedWord(words.get(0))) return false; + if (words.size() == 1) return true; + int capitalized = 1; + for (int i = 1, size = words.size(); i < size; i++) { + String word = words.get(i); + if (isCapitalizedWord(word)) { + // check for abbreviations like SQL or I18n + if (word.length() == 1 || !Character.isLowerCase(word.charAt(1))) + continue; + capitalized++; + } + } + return capitalized / words.size() < 0.2; // allow reasonable amount of capitalized words + } + + private static boolean isCapitalizedWord(String word) { + return word.length() > 0 && Character.isLetter(word.charAt(0)) && Character.isUpperCase(word.charAt(0)); + } + private static class TitleCapitalizationFix implements LocalQuickFix { private final String myTitleValue; private final Nls.Capitalization myCapitalization; @@ -172,8 +204,7 @@ public class TitleCapitalizationInspection extends AbstractBaseJavaLocalInspecti } final String string = (String)value; final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); - final PsiExpression newExpression = - factory.createExpressionFromText('"' + NlsCapitalizationUtil.fixValue(string, myCapitalization) + '"', element); + final PsiExpression newExpression = factory.createExpressionFromText('"' + fixValue(string) + '"', element); literalExpression.replace(newExpression); } else if (element instanceof PsiMethodCallExpression) { @@ -191,7 +222,7 @@ public class TitleCapitalizationInspection extends AbstractBaseJavaLocalInspecti if (value == null) { return; } - property.setValue(NlsCapitalizationUtil.fixValue(value, myCapitalization)); + property.setValue(fixValue(value)); } else if (element instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)element; @@ -206,6 +237,13 @@ public class TitleCapitalizationInspection extends AbstractBaseJavaLocalInspecti } } + @NotNull + private String fixValue(String string) { + return myCapitalization == Nls.Capitalization.Title + ? StringUtil.wordsToBeginFromUpperCase(string) + : StringUtil.capitalize(StringUtil.wordsToBeginFromLowerCase(string)); + } + @NotNull @Override public String getFamilyName() { diff --git a/plugins/java-i18n/testSrc/com/intellij/codeInspection/CapitalizationTest.java b/plugins/java-i18n/testSrc/com/intellij/codeInspection/CapitalizationTest.java new file mode 100644 index 000000000000..0cbf18c6ff1c --- /dev/null +++ b/plugins/java-i18n/testSrc/com/intellij/codeInspection/CapitalizationTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInspection; + +import com.intellij.codeInspection.capitalization.TitleCapitalizationInspection; +import junit.framework.TestCase; +import org.jetbrains.annotations.Nls; + +public class CapitalizationTest extends TestCase { + + public void testCapitalization() { + assertTrue(TitleCapitalizationInspection.isCapitalizationSatisfied("Fix SQL issues", Nls.Capitalization.Sentence)); + assertTrue(TitleCapitalizationInspection.isCapitalizationSatisfied("Fix I18n issues", Nls.Capitalization.Sentence)); + assertTrue(TitleCapitalizationInspection.isCapitalizationSatisfied("Fix C issues", Nls.Capitalization.Sentence)); + assertTrue(TitleCapitalizationInspection.isCapitalizationSatisfied("@charset is invalid", Nls.Capitalization.Sentence)); + assertTrue(TitleCapitalizationInspection.isCapitalizationSatisfied("Add 'this' qualifier", Nls.Capitalization.Sentence)); + assertTrue(TitleCapitalizationInspection.isCapitalizationSatisfied("Add 'this' qualifier", Nls.Capitalization.Sentence)); + assertTrue(TitleCapitalizationInspection.isCapitalizationSatisfied("Please select the configuration file (usually named IntelliLang.xml) to import.", Nls.Capitalization.Sentence)); + assertFalse(TitleCapitalizationInspection.isCapitalizationSatisfied("Foo Bar", Nls.Capitalization.Sentence)); + assertTrue(TitleCapitalizationInspection.isCapitalizationSatisfied("Foo", Nls.Capitalization.Sentence)); + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/buildtool/BuildViewMavenConsole.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/buildtool/BuildViewMavenConsole.java index 0de3eb9e8d0e..fa58ab92576f 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/buildtool/BuildViewMavenConsole.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/buildtool/BuildViewMavenConsole.java @@ -89,7 +89,7 @@ public class BuildViewMavenConsole extends MavenConsole { ApplicationManager.getApplication().invokeLater(() -> { DefaultActionGroup actions = new DefaultActionGroup(); actions.addAll((myBuildView).getSwitchActions()); - actions.add(BuildTreeFilters.createFilteringActionsGroup(myBuildView)); + actions.add(new ShowExecutionErrorsOnlyAction(myBuildView)); JComponent consolePanel = createConsolePanel(myBuildView, actions); RunContentDescriptor descriptor = new RunContentDescriptor(myBuildView, processHandler, consolePanel, myTitle, MavenIcons.MavenLogo); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java index aa357926e765..808606d9efac 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunConfiguration.java @@ -1,9 +1,9 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.idea.maven.execution; -import com.intellij.build.BuildTreeFilters; import com.intellij.build.BuildView; import com.intellij.build.DefaultBuildDescriptor; +import com.intellij.build.ShowExecutionErrorsOnlyAction; import com.intellij.debugger.impl.DebuggerManagerImpl; import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.diagnostic.logging.LogConfigurationPanel; @@ -313,7 +313,7 @@ public class MavenRunConfiguration extends LocatableConfigurationBase implements final ConsoleView console = createConsoleViewAndAttachToProcess(executor, processHandler); AnAction[] actions = console instanceof BuildView ? - new AnAction[]{BuildTreeFilters.createFilteringActionsGroup((BuildView)console)} : AnAction.EMPTY_ARRAY; + new AnAction[]{new ShowExecutionErrorsOnlyAction((BuildView)console)} : AnAction.EMPTY_ARRAY; DefaultExecutionResult res = new DefaultExecutionResult(console, processHandler, actions); if (MavenResumeAction.isApplicable(getEnvironment().getProject(), getJavaParameters(), MavenRunConfiguration.this)) { MavenResumeAction resumeAction = new MavenResumeAction(res.getProcessHandler(), runner, getEnvironment()); diff --git a/python/testSrc/com/jetbrains/env/PyEnvTestCase.java b/python/testSrc/com/jetbrains/env/PyEnvTestCase.java index d1ddb541c644..1d169f5a1072 100644 --- a/python/testSrc/com/jetbrains/env/PyEnvTestCase.java +++ b/python/testSrc/com/jetbrains/env/PyEnvTestCase.java @@ -356,7 +356,7 @@ public abstract class PyEnvTestCase { private final List myExceptions = new ArrayList<>(); @Override - public int show(@NotNull final String message) { + public int show(final String message) { myMessages.add(message); return 0; }