From bcbcd5a38efe317d93dfe96f89cb5bd1ff55165d Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 5 Aug 2014 14:02:35 +0400 Subject: [PATCH 1/3] Disables HeavyWeightPopup cache in Swing (switched off by default) --- .../intellij/ide/ui/laf/LafManagerImpl.java | 4 +++ .../ui/popup/OurHeavyWeightPopup.java | 35 +++++++++++++++++++ .../com/intellij/ui/popup/PopupComponent.java | 3 ++ .../util/resources/misc/registry.properties | 3 ++ 4 files changed, 45 insertions(+) create mode 100644 platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java index 19d924dff777..1036307e97d7 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java @@ -46,6 +46,7 @@ import com.intellij.ui.JBColor; import com.intellij.ui.ScreenUtil; import com.intellij.ui.content.Content; import com.intellij.ui.mac.MacPopupMenuUI; +import com.intellij.ui.popup.OurHeavyWeightPopup; import com.intellij.util.IJSwingUtilities; import com.intellij.util.ObjectUtils; import com.intellij.util.PlatformUtils; @@ -853,6 +854,9 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo final Point point = fixPopupLocation(contents, x, y); final int popupType = UIUtil.isUnderGTKLookAndFeel() ? WEIGHT_HEAVY : PopupUtil.getPopupType(this); + if (popupType == WEIGHT_HEAVY && OurHeavyWeightPopup.isEnabled()) { + return new OurHeavyWeightPopup(owner, contents, point.x, point.y); + } if (popupType >= 0) { PopupUtil.setPopupType(myDelegate, popupType); } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java new file mode 100644 index 000000000000..2a79368f65bb --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ui/popup/OurHeavyWeightPopup.java @@ -0,0 +1,35 @@ +/* + * 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.ui.popup; + +import com.intellij.openapi.util.registry.Registry; + +import javax.swing.Popup; +import java.awt.Component; +import java.awt.GraphicsEnvironment; + +/** + * @author Sergey Malenkov + */ +public final class OurHeavyWeightPopup extends Popup { + public OurHeavyWeightPopup(Component owner, Component content, int x, int y) { + super(owner, content, x, y); + } + + public static boolean isEnabled() { + return !GraphicsEnvironment.isHeadless() && Registry.is("our.heavy.weight.popup"); + } +} diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java index 374712c03a3f..1670491b91bf 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java @@ -58,6 +58,9 @@ public interface PopupComponent { class AwtHeavyweight implements Factory { public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) { + if (OurHeavyWeightPopup.isEnabled()) { + return new AwtPopupWrapper(new OurHeavyWeightPopup(owner, content, x, y), jbPopup); + } final PopupFactory factory = PopupFactory.getSharedInstance(); final int oldType = PopupUtil.getPopupType(factory); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 52e3baa0b5fa..bbda04a2461a 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -370,6 +370,9 @@ allow.dialog.based.popups.description=Allows to use a JDialog as popup toplevel popup.fix.ide.frame.owner=false popup.fix.ide.frame.owner.description=Uses correct owner for IdeFrame, but can break some popups +our.heavy.weight.popup=false +our.heavy.weight.popup.description=Disables HeavyWeightPopup cache in Swing + focus.fix.lost.cursor=true focus.fix.lost.cursor.description=See IDEA-79312 From 08584067239704e757cc85964fd717f39c8d673a Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 5 Aug 2014 12:15:08 +0200 Subject: [PATCH 2/3] cleanup, canonicalRequestPath as CharSequence --- .../builtInWebServer/BuiltInWebServer.java | 15 +++++++-------- .../jetbrains/builtInWebServer/FileHandler.java | 2 +- .../org/jetbrains/io/fastCgi/FastCgiRequest.java | 14 ++++++++------ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/xml/impl/src/org/jetbrains/builtInWebServer/BuiltInWebServer.java b/xml/impl/src/org/jetbrains/builtInWebServer/BuiltInWebServer.java index c87c3096dca3..d47bebf9d116 100644 --- a/xml/impl/src/org/jetbrains/builtInWebServer/BuiltInWebServer.java +++ b/xml/impl/src/org/jetbrains/builtInWebServer/BuiltInWebServer.java @@ -30,7 +30,7 @@ import java.net.UnknownHostException; import static org.jetbrains.io.Responses.sendOptionsResponse; import static org.jetbrains.io.Responses.sendStatus; -public class BuiltInWebServer extends HttpRequestHandler { +public final class BuiltInWebServer extends HttpRequestHandler { private static final Logger LOG = Logger.getInstance(BuiltInWebServer.class); @Nullable @@ -67,7 +67,7 @@ public class BuiltInWebServer extends HttpRequestHandler { } @Override - public boolean process(@NotNull QueryStringDecoder urlDecoder, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context) throws IOException { + public boolean process(@NotNull QueryStringDecoder urlDecoder, @NotNull FullHttpRequest request, @NotNull ChannelHandlerContext context) { if (request.method() == HttpMethod.OPTIONS) { sendOptionsResponse("GET, POST, HEAD, OPTIONS", request, context); return true; @@ -123,7 +123,7 @@ public class BuiltInWebServer extends HttpRequestHandler { } } - private static boolean doProcess(FullHttpRequest request, Channel channel, @Nullable String projectName) { + private static boolean doProcess(@NotNull FullHttpRequest request, @NotNull Channel channel, @Nullable String projectName) { final String decodedPath = URLUtil.unescapePercentSequences(UriUtil.trimParameters(request.uri())); int offset; boolean emptyPath; @@ -155,7 +155,6 @@ public class BuiltInWebServer extends HttpRequestHandler { return true; } - final String path = FileUtil.toCanonicalPath(decodedPath.substring(offset + 1), '/'); LOG.assertTrue(path != null); PathToFileManager pathToFileManager = PathToFileManager.getInstance(project); @@ -213,7 +212,7 @@ public class BuiltInWebServer extends HttpRequestHandler { for (FileHandler fileHandler : FileHandler.EP_NAME.getExtensions()) { try { - if (fileHandler.process(result, canonicalRequestPath.toString(), project, request, channel)) { + if (fileHandler.process(result, canonicalRequestPath, project, request, channel)) { return true; } } @@ -232,7 +231,7 @@ public class BuiltInWebServer extends HttpRequestHandler { static final class StaticFileHandler extends FileHandler { @Override public boolean process(@NotNull VirtualFile file, - @NotNull String canonicalRequestPath, + @NotNull CharSequence canonicalRequestPath, @NotNull Project project, @NotNull FullHttpRequest request, @NotNull Channel channel) throws IOException { @@ -252,9 +251,9 @@ public class BuiltInWebServer extends HttpRequestHandler { } } - private static void redirectToDirectory(HttpRequest request, Channel channel, String path) { + private static void redirectToDirectory(@NotNull HttpRequest request, @NotNull Channel channel, @NotNull String path) { FullHttpResponse response = Responses.response(HttpResponseStatus.MOVED_PERMANENTLY); - URI url = VfsUtil.toUri("http://" + HttpHeaders.getHost(request) + "/" + path + "/"); + URI url = VfsUtil.toUri("http://" + HttpHeaders.getHost(request) + '/' + path + '/'); LOG.assertTrue(url != null); response.headers().add(HttpHeaders.Names.LOCATION, url.toASCIIString()); Responses.send(response, channel, request); diff --git a/xml/impl/src/org/jetbrains/builtInWebServer/FileHandler.java b/xml/impl/src/org/jetbrains/builtInWebServer/FileHandler.java index a122bf35719a..3b0ff4e4e55a 100644 --- a/xml/impl/src/org/jetbrains/builtInWebServer/FileHandler.java +++ b/xml/impl/src/org/jetbrains/builtInWebServer/FileHandler.java @@ -13,7 +13,7 @@ public abstract class FileHandler { static final ExtensionPointName EP_NAME = ExtensionPointName.create("org.jetbrains.webServerFileHandler"); public abstract boolean process(@NotNull VirtualFile file, - @NotNull String canonicalRequestPath, + @NotNull CharSequence canonicalRequestPath, @NotNull Project project, @NotNull FullHttpRequest request, @NotNull Channel channel) throws IOException; diff --git a/xml/impl/src/org/jetbrains/io/fastCgi/FastCgiRequest.java b/xml/impl/src/org/jetbrains/io/fastCgi/FastCgiRequest.java index 73dbcbf12b3a..fd268795945b 100644 --- a/xml/impl/src/org/jetbrains/io/fastCgi/FastCgiRequest.java +++ b/xml/impl/src/org/jetbrains/io/fastCgi/FastCgiRequest.java @@ -3,14 +3,16 @@ package org.jetbrains.io.fastCgi; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vfs.VirtualFile; -import org.jetbrains.builtInWebServer.PathToFileManager; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; +import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaders; +import io.netty.util.CharsetUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.builtInWebServer.PathToFileManager; import org.jetbrains.io.Responses; import java.net.InetSocketAddress; @@ -28,7 +30,7 @@ public class FastCgiRequest { private final ByteBuf buffer; final int requestId; - public FastCgiRequest(int requestId, ByteBufAllocator allocator) { + public FastCgiRequest(int requestId, @NotNull ByteBufAllocator allocator) { this.requestId = requestId; buffer = allocator.buffer(); @@ -38,7 +40,7 @@ public class FastCgiRequest { buffer.writeZero(5); } - public void writeFileHeaders(VirtualFile file, Project project, String canonicalRequestPath) { + public void writeFileHeaders(@NotNull VirtualFile file, @NotNull Project project, @NotNull CharSequence canonicalRequestPath) { Pair root = PathToFileManager.getInstance(project).getRoot(file); FastCgiService.LOG.assertTrue(root != null); addHeader("DOCUMENT_ROOT", root.first.getPath()); @@ -46,7 +48,7 @@ public class FastCgiRequest { addHeader("SCRIPT_NAME", canonicalRequestPath); } - public final void addHeader(@NotNull String key, @Nullable String value) { + public final void addHeader(@NotNull String key, @Nullable CharSequence value) { if (value == null) { return; } @@ -75,8 +77,8 @@ public class FastCgiRequest { buffer.writeByte(valLength); } - buffer.writeBytes(key.getBytes()); - buffer.writeBytes(value.getBytes()); + buffer.writeBytes(key.getBytes(CharsetUtil.US_ASCII)); + buffer.writeBytes(Unpooled.copiedBuffer(value, CharsetUtil.UTF_8)); } public void writeHeaders(FullHttpRequest request, Channel clientChannel) { From 08a8d68a6a20f4456e84256e925bff8677350734 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Tue, 5 Aug 2014 14:28:02 +0400 Subject: [PATCH 3/3] IDEA-127700 PSI/Formatter/XML performance --- .../psi/formatter/xml/AbstractXmlBlock.java | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/xml/impl/src/com/intellij/psi/formatter/xml/AbstractXmlBlock.java b/xml/impl/src/com/intellij/psi/formatter/xml/AbstractXmlBlock.java index 6e1b89912814..b2b5b5ff8eee 100644 --- a/xml/impl/src/com/intellij/psi/formatter/xml/AbstractXmlBlock.java +++ b/xml/impl/src/com/intellij/psi/formatter/xml/AbstractXmlBlock.java @@ -17,6 +17,7 @@ package com.intellij.psi.formatter.xml; import com.intellij.formatting.*; import com.intellij.lang.*; +import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.util.TextRange; @@ -464,11 +465,28 @@ public abstract class AbstractXmlBlock extends AbstractBlock { return myNode.getElementType() == XmlTokenType.XML_CDATA_END; } - public static boolean containsWhiteSpacesOnly(ASTNode node) { - WhiteSpaceFormattingStrategy strategy = WhiteSpaceFormattingStrategyFactory.getStrategy(node.getPsi().getLanguage()); - String nodeText = node.getText(); - int length = nodeText.length(); - return strategy.check(nodeText, 0, length) >= length; + public static boolean containsWhiteSpacesOnly(@NotNull ASTNode node) { + PsiElement psiElement = node.getPsi(); + if (psiElement instanceof PsiWhiteSpace) return true; + Language nodeLang = psiElement.getLanguage(); + if (!nodeLang.isKindOf(XMLLanguage.INSTANCE) || + isTextOnlyNode(node) || + node.getElementType() == XmlElementType.XML_PROLOG) { + WhiteSpaceFormattingStrategy strategy = WhiteSpaceFormattingStrategyFactory.getStrategy(nodeLang); + int length = node.getTextLength(); + return strategy.check(node.getChars(), 0, length) >= length; + } + return false; + } + + private static boolean isTextOnlyNode(@NotNull ASTNode node) { + if (node.getPsi() instanceof XmlText) return true; + ASTNode firstChild = node.getFirstChildNode(); + ASTNode lastChild = node.getLastChildNode(); + if (firstChild != null && firstChild == lastChild && firstChild.getPsi() instanceof XmlText) { + return true; + } + return false; } }