Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vassiliy.Kudryashov
2018-03-23 21:50:33 +03:00
70 changed files with 520 additions and 597 deletions
+1
View File
@@ -471,6 +471,7 @@
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="WHILE_ON_NEW_LINE" value="true" />
<option name="CATCH_ON_NEW_LINE" value="true" />
@@ -26,7 +26,6 @@ import icons.ImagesIcons;
import org.intellij.images.ImagesBundle;
import org.intellij.images.fileTypes.ImageFileTypeManager;
import org.intellij.images.vfs.IfsUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.imageio.ImageIO;
@@ -39,7 +38,7 @@ import java.util.Set;
*/
final class ImageFileTypeManagerImpl extends ImageFileTypeManager {
@NonNls private static final String IMAGE_FILE_TYPE_NAME = "Images";
private static final String IMAGE_FILE_TYPE_NAME = "Image";
private static final String IMAGE_FILE_TYPE_DESCRIPTION = ImagesBundle.message("images.filetype.description");
private static final UserFileType imageFileType;
@@ -16,6 +16,7 @@
package org.intellij.images.index;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.indexing.*;
@@ -33,14 +34,7 @@ import java.io.IOException;
* @author spleaner
*/
public class ImageInfoIndex extends SingleEntryFileBasedIndexExtension<ImageInfoIndex.ImageInfo> {
private static final int ourMaxImageSize;
static {
int maxImageSize = 200;
try {
maxImageSize = Integer.parseInt(System.getProperty("idea.max.image.filesize", Integer.toString(maxImageSize)), 10);
} catch (NumberFormatException ex) {}
ourMaxImageSize = maxImageSize;
}
private static final long ourMaxImageSize = (long)(Registry.get("ide.index.image.max.size").asDouble() * 1024 * 1024);
public static final ID<Integer, ImageInfo> INDEX_ID = ID.create("ImageFileInfoIndex");
@@ -94,17 +88,15 @@ public class ImageInfoIndex extends SingleEntryFileBasedIndexExtension<ImageInfo
public FileBasedIndex.InputFilter getInputFilter() {
return new DefaultFileTypeSpecificInputFilter(ImageFileTypeManager.getInstance().getImageFileType()) {
@Override
public boolean acceptInput(@NotNull final VirtualFile file) {
return file.isInLocalFileSystem() &&
file.getLength() / 1024 < ourMaxImageSize
;
public boolean acceptInput(@NotNull VirtualFile file) {
return file.isInLocalFileSystem() && file.getLength() < ourMaxImageSize;
}
};
}
@Override
public int getVersion() {
return 5;
return 6;
}
public static class ImageInfo {
@@ -16,14 +16,16 @@
package org.intellij.images.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.io.UnsyncByteArrayInputStream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataInput;
import java.io.DataInputStream;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Iterator;
/**
* @author spleaner
@@ -35,207 +37,34 @@ public class ImageInfoReader {
}
@Nullable
public static Info getInfo(@NotNull final String file) {
return read(file);
public static Info getInfo(@NotNull String file) {
return read(new File(file));
}
@Nullable
public static Info getInfo(@NotNull final byte[] data) {
return read(data);
public static Info getInfo(@NotNull byte[] data) {
return read(new ByteArrayInputStream(data));
}
@Nullable
private static Info read(@NotNull final String file) {
final RandomAccessFile raf;
try {
//noinspection HardCodedStringLiteral
raf = new RandomAccessFile(file, "r");
try {
return readFileData(raf);
}
finally {
try {
raf.close();
}
catch (IOException e) {
// nothing
}
private static Info read(@NotNull Object input) {
try (ImageInputStream iis = ImageIO.createImageInputStream(input)) {
Iterator<ImageReader> it = ImageIO.getImageReaders(iis);
ImageReader reader = it.hasNext() ? it.next() : null;
if (reader != null) {
reader.setInput(iis, true);
int w = reader.getWidth(0);
int h = reader.getHeight(0);
int bpp = reader.getRawImageType(0).getColorModel().getPixelSize();
return new Info(w, h, bpp);
}
}
catch (IOException e) {
return null;
LOG.warn(e);
}
}
@Nullable
private static Info read(@NotNull final byte[] data) {
final DataInputStream is = new DataInputStream(new UnsyncByteArrayInputStream(data));
try {
return readFileData(is);
}
catch (IOException e) {
return null;
}
finally {
try {
is.close();
}
catch (IOException e) {
// nothing
}
}
}
@Nullable
private static Info readFileData(@NotNull final DataInput di) throws IOException {
final int b1 = di.readUnsignedByte();
final int b2 = di.readUnsignedByte();
if (b1 == 0x47 && b2 == 0x49) {
return readGif(di);
}
if (b1 == 0x89 && b2 == 0x50) {
return readPng(di);
}
if (b1 == 0xff && b2 == 0xd8) {
return readJpeg(di);
}
//if (b1 == 0x42 && b2 == 0x4d) {
// return readBmp(raf);
//}
return null;
}
@Nullable
private static Info readGif(DataInput di) throws IOException {
final byte[] GIF_MAGIC_87A = {0x46, 0x38, 0x37, 0x61};
final byte[] GIF_MAGIC_89A = {0x46, 0x38, 0x39, 0x61};
byte[] a = new byte[11]; // 4 from the GIF signature + 7 from the global header
di.readFully(a);
if ((!eq(a, 0, GIF_MAGIC_89A, 0, 4)) && (!eq(a, 0, GIF_MAGIC_87A, 0, 4))) {
return null;
}
final int width = getShortLittleEndian(a, 4);
final int height = getShortLittleEndian(a, 6);
int flags = a[8] & 0xff;
final int bpp = ((flags >> 4) & 0x07) + 1;
return new Info(width, height, bpp);
}
private static Info readBmp(RandomAccessFile raf) throws IOException {
byte[] a = new byte[44];
if (raf.read(a) != a.length) {
return null;
}
final int width = getIntLittleEndian(a, 16);
final int height = getIntLittleEndian(a, 20);
if (width < 1 || height < 1) {
return null;
}
final int bpp = getShortLittleEndian(a, 26);
if (bpp != 1 && bpp != 4 && bpp != 8 && bpp != 16 && bpp != 24 & bpp != 32) {
return null;
}
return new Info(width, height, bpp);
}
@Nullable
private static Info readJpeg(DataInput di) throws IOException {
byte[] a = new byte[13];
while (true) {
di.readFully(a, 0, 4);
int marker = getShortBigEndian(a, 0);
final int size = getShortBigEndian(a, 2);
if ((marker & 0xff00) != 0xff00) {
return null;
}
if (marker == 0xffe0) {
if (size < 14) {
di.skipBytes(size - 2);
continue;
}
di.readFully(a, 0, 12);
di.skipBytes(size - 14);
}
else if (marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 && marker != 0xffc8) {
di.readFully(a, 0, 6);
final int bpp = (a[0] & 0xff) * (a[5] & 0xff);
final int width = getShortBigEndian(a, 3);
final int height = getShortBigEndian(a, 1);
return new Info(width, height, bpp);
}
else {
di.skipBytes(size - 2);
}
}
}
@Nullable
private static Info readPng(DataInput di) throws IOException {
final byte[] PNG_MAGIC = {0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a};
byte[] a = new byte[27];
di.readFully(a);
if (!eq(a, 0, PNG_MAGIC, 0, 6)) {
return null;
}
final int width = getIntBigEndian(a, 14);
final int height = getIntBigEndian(a, 18);
int bpp = a[22] & 0xff;
int colorType = a[23] & 0xff;
if (colorType == 2 || colorType == 6) {
bpp *= 3;
}
return new Info(width, height, bpp);
}
private static int getShortBigEndian(byte[] a, int offset) {
return (a[offset] & 0xff) << 8 | (a[offset + 1] & 0xff);
}
private static boolean eq(byte[] a1, int offset1, byte[] a2, int offset2, int num) {
while (num-- > 0) {
if (a1[offset1++] != a2[offset2++]) {
return false;
}
}
return true;
}
private static int getIntBigEndian(byte[] a, int offset) {
return (a[offset] & 0xff) << 24 | (a[offset + 1] & 0xff) << 16 | (a[offset + 2] & 0xff) << 8 | a[offset + 3] & 0xff;
}
private static int getIntLittleEndian(byte[] a, int offset) {
return (a[offset + 3] & 0xff) << 24 | (a[offset + 2] & 0xff) << 16 | (a[offset + 1] & 0xff) << 8 | a[offset] & 0xff;
}
private static int getShortLittleEndian(byte[] a, int offset) {
return (a[offset] & 0xff) | (a[offset + 1] & 0xff) << 8;
}
public static class Info {
public int width;
public int height;
@@ -50,6 +50,7 @@ public abstract class JavaTestConfigurationBase extends ModuleBasedConfiguration
}
public abstract TestSearchScope getTestSearchScope();
public abstract void setSearchScope(TestSearchScope searchScope);
@Nullable
@Override
@@ -7,6 +7,7 @@ import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.configurations.*;
import com.intellij.execution.junit.JavaRunConfigurationProducerBase;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testframework.TestSearchScope;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleUtilCore;
@@ -25,7 +26,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.io.IOException;
import java.util.*;
public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigurationProducerBase<JavaTestConfigurationBase> {
@@ -59,27 +59,22 @@ public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigur
final PsiMethod sourceMethod = getSourceMethod(location);
final Pair<String, String> position = getPosition(sourceMethod);
if (sourceMethod != null && position != null) {
try {
final Project project = configuration.getProject();
final TestDiscoveryIndex testDiscoveryIndex = TestDiscoveryIndex.getInstance(project);
if (testDiscoveryIndex.getTestsByMethodName(position.first, position.second, configuration.getTestFrameworkId()).isEmpty()) {
return false;
}
Module targetModule = getTargetModule(configuration, configurationContext, position, project, testDiscoveryIndex);
setupDiscoveryConfiguration(configuration, sourceMethod, targetModule);
return true;
}
catch (IOException e) {
final Project project = configuration.getProject();
final TestDiscoveryIndex testDiscoveryIndex = TestDiscoveryIndex.getInstance(project);
if (testDiscoveryIndex.getTestsByMethodName(position.first, position.second, configuration.getTestFrameworkId()).isEmpty()) {
return false;
}
Module targetModule = getTargetModule(configuration, configurationContext, position, project, testDiscoveryIndex);
setupDiscoveryConfiguration(configuration, sourceMethod, targetModule);
return true;
}
return false;
}
private Module getTargetModule(JavaTestConfigurationBase configuration,
ConfigurationContext configurationContext,
Pair<String, String> position, Project project, TestDiscoveryIndex testDiscoveryIndex) throws IOException {
Pair<String, String> position, Project project, TestDiscoveryIndex testDiscoveryIndex) {
final RunnerAndConfigurationSettings template =
configurationContext.getRunManager().getConfigurationTemplate(getConfigurationFactory());
final Module predefinedModule = ((ModuleBasedConfiguration)template.getConfiguration()).getConfigurationModule().getModule();
@@ -120,6 +115,12 @@ public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigur
RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(context);
JavaTestConfigurationBase configuration = (JavaTestConfigurationBase)settings.getConfiguration();
configuration.setModule(module);
if (module == null) {
configuration.setSearchScope(TestSearchScope.WHOLE_PROJECT);
}
else {
configuration.setSearchScope(TestSearchScope.MODULE_WITH_DEPENDENCIES);
}
return new RunProfile() {
@Nullable
@Override
@@ -22,6 +22,7 @@ import com.intellij.ui.tree.AsyncTreeModel;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.FontUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.EdtInvocationManager;
import com.intellij.util.ui.tree.TreeModelAdapter;
import com.intellij.util.ui.tree.TreeUtil;
@@ -30,6 +31,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.TreeModelEvent;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.util.List;
@@ -118,6 +120,29 @@ class DiscoveredTestsTree extends Tree implements DataProvider {
@Nullable
@Override
public Object getData(String dataId) {
if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
TreePath[] paths = getSelectionModel().getSelectionPaths();
List<PsiElement> result = ContainerUtil.newSmartList();
TreeModel model = getModel();
for (TreePath p : paths) {
Object e = p.getLastPathComponent();
if (e instanceof PsiMethod) {
result.add((PsiMethod)e);
}
else {
int count = model.getChildCount(e);
if (count == 0 && e instanceof PsiElement) {
result.add((PsiElement)e);
}
else {
for (int i = 0; i < count; i++) {
ContainerUtil.addIfNotNull(result, ObjectUtils.tryCast(model.getChild(e, i), PsiMethod.class));
}
}
}
}
return result.toArray(PsiElement.EMPTY_ARRAY);
}
if (CommonDataKeys.PSI_ELEMENT.is(dataId)) {
return getSelectedElement();
}
@@ -2,6 +2,7 @@
package com.intellij.facet.impl.ui.libraries;
import com.google.common.io.BaseEncoding;
import com.intellij.facet.ui.libraries.LibraryInfo;
import com.intellij.openapi.roots.libraries.LibraryUtil;
import com.intellij.openapi.util.text.StringUtil;
@@ -14,7 +15,6 @@ import org.jetbrains.annotations.Nullable;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
/**
@@ -76,7 +76,7 @@ public class RequiredLibrariesInfo {
md5.update(file.contentsToByteArray());
final byte[] digest = md5.digest();
return Base64.getEncoder().encodeToString(digest);
return BaseEncoding.base16().lowerCase().encode(digest);
}
catch (Exception e) {
return null;
@@ -33,7 +33,7 @@ import java.util.List;
public class RedundantTypeArgsInspection extends GenericsInspectionToolBase {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.miscGenerics.RedundantTypeArgsInspection");
private final static LocalQuickFix ourQuickFixAction = new MyQuickFixAction();
private static final LocalQuickFix ourQuickFixAction = new MyQuickFixAction();
public static final String SHORT_NAME = "RedundantTypeArguments";
@Override
@@ -136,7 +136,7 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase {
final PsiTypeElement qualifierTypeElement = expression.getQualifierType();
if (qualifierTypeElement != null) {
final PsiType psiType = qualifierTypeElement.getType();
if (psiType instanceof PsiClassType && !(((PsiClassType)psiType).isRaw())) {
if (psiType instanceof PsiClassType && !((PsiClassType)psiType).isRaw()) {
PsiClass aClass = ((PsiClassType)psiType).resolve();
if (aClass == null) return;
final JavaResolveResult result = expression.advancedResolve(false);
@@ -164,7 +164,7 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase {
PsiTypeParameter[] typeParameters = resolve instanceof PsiClass ? PsiTypeParameter.EMPTY_ARRAY : ((PsiMethod)resolve).getTypeParameters();
if (typeParameters.length == 0 ||
typeParameters.length == typeArguments.length &&
PsiDiamondTypeUtil.areTypeArgumentsRedundant(typeArguments, expression, false, ((PsiMethod)resolve), typeParameters)) {
PsiDiamondTypeUtil.areTypeArgumentsRedundant(typeArguments, expression, false, (PsiMethod)resolve, typeParameters)) {
String key = typeParameters.length == 0 ? "inspection.redundant.type.no.generics.method.reference.problem.descriptor"
: "inspection.redundant.type.problem.descriptor";
final ProblemDescriptor descriptor =
@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.editorActions;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.template.impl.editorActions.TypedActionHandlerBase;
import com.intellij.lang.Language;
import com.intellij.lang.java.JavaLanguage;
@@ -185,7 +186,7 @@ public class AutoFormatTypedHandler extends TypedActionHandlerBase {
PsiFile file = project == null ? null : PsiUtilBase.getPsiFileInEditor(editor, project);
if (file != null) {
Language language = file.getLanguage();
CodeStyleSettings settings = CodeStyleSettingsManager.getInstance(project).getCurrentSettings();
CodeStyleSettings settings = CodeStyle.getSettings(editor);
CommonCodeStyleSettings common = settings.getCommonSettings(language);
return common.SPACE_AROUND_ASSIGNMENT_OPERATORS;
}
@@ -163,6 +163,11 @@ public class PsiTypeElementImpl extends CompositePsiElement implements PsiTypeEl
if (iteratedValue != null) {
return JavaGenericsUtil.getCollectionItemType(iteratedValue);
}
return null;
}
if (declarationScope instanceof PsiLambdaExpression) {
return ((PsiParameter)parent).getType();
}
}
else {
@@ -0,0 +1,7 @@
import java.util.function.Function;
class Main {
public static void main(String[] args) {
Function<String, String> f = (final v<caret>ar a) -> a;
}
}
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.completion.LightFixtureCompletionTestCase
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInspection.javaDoc.JavaDocLocalInspection
import com.intellij.lang.java.JavaLanguage
import com.intellij.patterns.PlatformPatterns
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.psi.PsiReferenceBase
@@ -610,7 +611,7 @@ class Foo {
}
}
try {
registrar.registerReferenceProvider(PsiDocTag.class, provider)
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiDocTag.class), provider)
configureByFile("ReferenceProvider.java")
assertStringItems("1", "2", "3")
}
@@ -18,6 +18,7 @@ package com.intellij.java.codeInsight.completion;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.completion.CompletionTestCase;
import com.intellij.lang.StdLanguages;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.PsiReferenceRegistrarImpl;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
@@ -89,8 +90,8 @@ public class WordCompletionTest extends CompletionTestCase {
PsiReferenceRegistrarImpl registrar =
(PsiReferenceRegistrarImpl)ReferenceProvidersRegistry.getInstance().getRegistrar(StdLanguages.JAVA);
try {
registrar.registerReferenceProvider(PsiLiteralExpression.class, softProvider);
registrar.registerReferenceProvider(PsiLiteralExpression.class, hardProvider);
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression.class), softProvider);
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralExpression.class), hardProvider);
configureByFile(BASE_PATH + "3.java");
checkResultByFile(BASE_PATH + "3_after.java");
@@ -0,0 +1,39 @@
// 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.java.codeInsight.daemon;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.CommonClassNames;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.testFramework.IdeaTestUtil;
public class LightAdvHighlightingJdk11Test extends LightDaemonAnalyzerTestCase {
private static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/advHighlighting11";
@Override
protected void setUp() throws Exception {
super.setUp();
setLanguageLevel(LanguageLevel.JDK_X);
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_10, getModule(), getTestRootDisposable());//todo
}
public void testGotoDeclarationOnLambdaVarParameter() {
configureByFile(BASE_PATH + "/" + getTestName(false) + ".java");
final int offset = getEditor().getCaretModel().getOffset();
final PsiElement[] elements =
GotoDeclarationAction.findAllTargetElements(getProject(), getEditor(), offset);
assertSize(1, elements);
PsiElement element = elements[0];
assertInstanceOf(element, PsiClass.class);
assertEquals(CommonClassNames.JAVA_LANG_STRING, ((PsiClass)element).getQualifiedName());
}
@Override
protected Sdk getProjectJDK() {
return IdeaTestUtil.getMockJdk9();
}
}
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.impl.source.resolve.reference;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.patterns.*;
@@ -46,15 +45,6 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
private final ConcurrentMap<Class, ProviderBinding[]> myBindingCache;
private boolean myInitialized;
/**
* @deprecated To be removed in 2018.2
*/
@Deprecated
@SuppressWarnings("unused")
public PsiReferenceRegistrarImpl(final Language language) {
this();
}
PsiReferenceRegistrarImpl() {
myBindingCache = ConcurrentFactoryMap.createMap(key-> {
List<ProviderBinding> result = ContainerUtil.newSmartList();
@@ -74,7 +64,7 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
);
}
public void markInitialized() {
void markInitialized() {
myInitialized = true;
}
@@ -143,18 +133,9 @@ public class PsiReferenceRegistrarImpl extends PsiReferenceRegistrar {
providerBinding.registerProvider(names, pattern, caseSensitive, provider, priority);
}
/**
* @see com.intellij.psi.PsiReferenceContributor
* @deprecated
*/
public void registerReferenceProvider(@NotNull Class scope, @NotNull PsiReferenceProvider provider) {
registerReferenceProvider(PlatformPatterns.psiElement(scope), provider, DEFAULT_PRIORITY);
}
@NotNull
List<ProviderBinding.ProviderInfo<ProcessingContext>> getPairsByElement(@NotNull PsiElement element,
@NotNull PsiReferenceService.Hints hints) {
@NotNull PsiReferenceService.Hints hints) {
final ProviderBinding[] bindings = myBindingCache.get(element.getClass());
if (bindings.length == 0) return Collections.emptyList();
@@ -67,9 +67,6 @@ public class CodeStyleSettingsManager implements PersistentStateComponent<Elemen
return ServiceManager.getService(AppCodeStyleSettingsManager.class);
}
@SuppressWarnings({"UnusedDeclaration"})
public CodeStyleSettingsManager(Project project) {
}
public CodeStyleSettingsManager() {}
/**
@@ -25,10 +25,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.Map;
import static com.intellij.psi.codeStyle.CodeStyleScheme.CODE_STYLE_NAME_ATTR;
import static com.intellij.psi.codeStyle.CodeStyleScheme.CODE_STYLE_TAG_NAME;
@State(
name = "ProjectCodeStyleConfiguration",
storages = @Storage(value = "codeStyles", stateSplitter = ProjectCodeStyleSettingsManager.StateSplitter.class)
@@ -36,21 +32,16 @@ import static com.intellij.psi.codeStyle.CodeStyleScheme.CODE_STYLE_TAG_NAME;
public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
private static final Logger LOG = Logger.getInstance("#" + ProjectCodeStyleSettingsManager.class);
public static final String MAIN_PROJECT_CODE_STYLE_NAME = "Project";
public static final String PROJECT_CODE_STYLE_CONFIG_FILE_NAME = "codeStyleConfig";
private static final String MAIN_PROJECT_CODE_STYLE_NAME = "Project";
private static final String PROJECT_CODE_STYLE_CONFIG_FILE_NAME = "codeStyleConfig";
private volatile boolean myIsLoaded;
private final static Object LEGACY_SETTINGS_IMPORT_LOCK = new Object();
private static final Object LEGACY_SETTINGS_IMPORT_LOCK = new Object();
private final Map<String,CodeStyleSettings> mySettingsMap = ContainerUtil.newHashMap();
private final static NotificationGroup NOTIFICATION_GROUP =
private static final NotificationGroup NOTIFICATION_GROUP =
new NotificationGroup("Code style settings migration", NotificationDisplayType.STICKY_BALLOON, true);
@SuppressWarnings("unused")
public ProjectCodeStyleSettingsManager(Project project) {
this();
}
public ProjectCodeStyleSettingsManager() {
setMainProjectCodeStyle(null);
}
@@ -89,7 +80,6 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
@Override
public void setMainProjectCodeStyle(@Nullable CodeStyleSettings settings) {
// TODO<rv>: Remove the assignment below when there are no direct usages of PER_PROJECT_SETTINGS.
//noinspection deprecation
PER_PROJECT_SETTINGS = settings;
mySettingsMap.put(MAIN_PROJECT_CODE_STYLE_NAME, settings != null ? settings : new CodeStyleSettings());
}
@@ -101,13 +91,12 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
}
private void initDefaults() {
@SuppressWarnings("deprecation")
CodeStyleSettingsManager appCodeStyleSettingsManager = CodeStyleSettingsManager.getInstance();
if (appCodeStyleSettingsManager != null) {
CodeStyleSettings defaultProjectSettings = appCodeStyleSettingsManager.getMainProjectCodeStyle();
setMainProjectCodeStyle(defaultProjectSettings != null ? defaultProjectSettings.clone() : null);
this.USE_PER_PROJECT_SETTINGS = appCodeStyleSettingsManager.USE_PER_PROJECT_SETTINGS;
this.PREFERRED_PROJECT_CODE_STYLE = appCodeStyleSettingsManager.PREFERRED_PROJECT_CODE_STYLE;
USE_PER_PROJECT_SETTINGS = appCodeStyleSettingsManager.USE_PER_PROJECT_SETTINGS;
PREFERRED_PROJECT_CODE_STYLE = appCodeStyleSettingsManager.PREFERRED_PROJECT_CODE_STYLE;
}
myIsLoaded = true;
}
@@ -116,8 +105,8 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
public void loadState(@NotNull Element state) {
super.loadState(state);
updateFromOldProjectSettings();
for (Element subStyle : state.getChildren(CODE_STYLE_TAG_NAME)) {
String name = subStyle.getAttributeValue(CODE_STYLE_NAME_ATTR);
for (Element subStyle : state.getChildren(CodeStyleScheme.CODE_STYLE_TAG_NAME)) {
String name = subStyle.getAttributeValue(CodeStyleScheme.CODE_STYLE_NAME_ATTR);
CodeStyleSettings settings = new CodeStyleSettings();
settings.readExternal(subStyle);
if (MAIN_PROJECT_CODE_STYLE_NAME.equals(name)) {
@@ -130,7 +119,6 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
myIsLoaded = true;
}
@SuppressWarnings("deprecation")
private void updateFromOldProjectSettings() {
CodeStyleSettings oldProjectSettings = PER_PROJECT_SETTINGS;
if (oldProjectSettings != null) oldProjectSettings.resetDeprecatedFields();
@@ -143,8 +131,8 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
if (e != null) {
for (String name : mySettingsMap.keySet()) {
CodeStyleSettings settings = mySettingsMap.get(name);
Element codeStyle = new Element(CODE_STYLE_TAG_NAME);
codeStyle.setAttribute(CODE_STYLE_NAME_ATTR, name);
Element codeStyle = new Element(CodeStyleScheme.CODE_STYLE_TAG_NAME);
codeStyle.setAttribute(CodeStyleScheme.CODE_STYLE_NAME_ATTR, name);
settings.writeExternal(codeStyle);
if (!codeStyle.getContent().isEmpty()) {
e.addContent(codeStyle);
@@ -155,7 +143,7 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
}
private static class CodeStyleMigrationNotification extends Notification {
public CodeStyleMigrationNotification(@NotNull String projectName) {
CodeStyleMigrationNotification(@NotNull String projectName) {
super(NOTIFICATION_GROUP.getDisplayId(),
ApplicationBundle.message("project.code.style.migration.title"),
ApplicationBundle.message("project.code.style.migration.message", projectName),
@@ -165,7 +153,7 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
}
private static class ShowMoreInfoAction extends DumbAwareAction {
public ShowMoreInfoAction() {
ShowMoreInfoAction() {
super("More info");
}
@@ -190,13 +178,13 @@ public class ProjectCodeStyleSettingsManager extends CodeStyleSettingsManager {
@NotNull
@Override
protected String getSubStateTagName() {
return CODE_STYLE_TAG_NAME;
return CodeStyleScheme.CODE_STYLE_TAG_NAME;
}
@NotNull
@Override
protected String getSubStateFileName(@NotNull Element element) {
return element.getAttributeValue(CODE_STYLE_NAME_ATTR);
return element.getAttributeValue(CodeStyleScheme.CODE_STYLE_NAME_ATTR);
}
}
}
@@ -1215,11 +1215,10 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
String text =
(withUrl ? file.getPresentableUrl() : "") +
"\n" +
"\nFile size is " + StringUtil.formatFileSize(attr.size()) +
"\n" + typeName + (type.isBinary() ? "" : " (" + psiFile.getLanguage().getDisplayName() + ")") +
"\n" + StringUtil.formatFileSize(attr.size()) + ", " + typeName + (type.isBinary() ? "" : " (" + psiFile.getLanguage().getDisplayName() + ")") +
"\nModified on " + DateFormatUtil.formatDateTime(attr.lastModifiedTime().toMillis()) +
"\nCreated on " + DateFormatUtil.formatDateTime(attr.creationTime().toMillis()) +
"\n";
return StringUtil.replace(StringUtil.escapeXml(text) + "&nbsp;", "\n", "<br>");
return StringUtil.replace(StringUtil.escapeXml(text) + "&nbsp;", "\n", "<p>");
}
}
@@ -275,10 +275,7 @@ public class ScopeChooserCombo extends ComboboxWithBrowseButton implements Dispo
private static class ScopeDescriptionWithDelimiterRenderer extends ListCellRendererWrapper<ScopeDescriptor> {
@Override
public void customize(JList list, ScopeDescriptor value, int index, boolean selected, boolean hasFocus) {
/*
SearchScope scope = value.getScope();
setIcon(scope == null ? null : scope.getDisplayIcon());
*/
setIcon(value.getDisplayIcon());
setText(value.getDisplay());
if (value instanceof ScopeSeparator) {
setSeparator();
@@ -1,23 +1,11 @@
/*
* 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.
*/
// 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.scopeChooser;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
/**
* @author anna
* @since 16-Jan-2008
@@ -30,7 +18,12 @@ public class ScopeDescriptor {
}
public String getDisplay() {
return myScope.getDisplayName();
return myScope == null ? null : myScope.getDisplayName();
}
@Nullable
public Icon getDisplayIcon() {
return myScope == null ? null : myScope.getDisplayIcon();
}
public SearchScope getScope() {
@@ -1,14 +0,0 @@
/*
* 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.injected.editor;
import com.intellij.openapi.util.UserDataHolderBase;
/**
* @deprecated use {@link DocumentWindow} instead
*/
@Deprecated
public abstract class DocumentWindowImpl extends UserDataHolderBase implements DocumentWindow {
public abstract int hostToInjectedUnescaped(int hostOffset);
}
@@ -6,12 +6,14 @@ import com.intellij.openapi.util.UserDataHolderBase;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link EditorWindow} instead. to be removed in IDEA 2018.1
* @deprecated Use {@link EditorWindow} instead. To be removed in IDEA 2018.1
*/
@Deprecated
public abstract class EditorWindowImpl extends UserDataHolderBase implements EditorWindow {
/**
* @deprecated Use {@link EditorWindow#getDelegate()} instead. to be removed in IDEA 2018.1
* @deprecated Use {@link EditorWindow#getDelegate()} instead. To be removed in IDEA 2018.1
*/
@Deprecated
@NotNull
@Override
public Editor getDelegate() {
@@ -7,8 +7,9 @@ import com.intellij.testFramework.LightVirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link VirtualFileWindow} instead. to be removed in IDEA 2018.1
* @deprecated Use {@link VirtualFileWindow} instead. To be removed in IDEA 2018.1
*/
@Deprecated
public abstract class VirtualFileWindowImpl extends LightVirtualFile implements VirtualFileWindow {
public VirtualFileWindowImpl(@NotNull String name,
Language language,
@@ -19,6 +20,7 @@ public abstract class VirtualFileWindowImpl extends LightVirtualFile implements
/**
* @deprecated Use {@link VirtualFileWindow#getDelegate()} instead. to be removed in IDEA 2018.1
*/
@Deprecated
@NotNull
@Override
public VirtualFile getDelegate() {
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.codeStyle;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -61,12 +62,11 @@ public class CodeStyleSettingsCodeFragmentFilter {
@NotNull
public CodeStyleSettingsToShow getFieldNamesAffectingCodeFragment(LanguageCodeStyleSettingsProvider.SettingsType... types) {
CodeStyleSettingsManager codeStyleSettingsManager = CodeStyleSettingsManager.getInstance(myProject);
CodeStyleSettings clonedSettings = codeStyleSettingsManager.getCurrentSettings().clone();
CodeStyleSettings clonedSettings = CodeStyle.getSettings(myFile).clone();
myCommonSettings = clonedSettings.getCommonSettings(myProvider.getLanguage());
try {
codeStyleSettingsManager.setTemporarySettings(clonedSettings);
CodeStyle.setTemporarySettings(myProject, clonedSettings);
String title = CodeInsightBundle.message("configure.code.style.on.fragment.dialog.title");
SequentialModalProgressTask progressTask = new SequentialModalProgressTask(myProject, StringUtil.capitalizeWords(title, true));
@@ -107,7 +107,7 @@ public class CodeStyleSettingsCodeFragmentFilter {
};
}
finally {
codeStyleSettingsManager.dropTemporarySettings();
CodeStyle.dropTemporarySettings(myProject);
}
}
@@ -29,7 +29,7 @@ import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
class DocumentWindowImpl extends com.intellij.injected.editor.DocumentWindowImpl implements Disposable, DocumentWindow, DocumentEx {
class DocumentWindowImpl extends UserDataHolderBase implements Disposable, DocumentWindow, DocumentEx {
private static final Logger LOG = Logger.getInstance("#com.intellij.injected.editor.DocumentWindowImpl");
private final DocumentEx myDelegate;
private final boolean myOneLine;
@@ -775,7 +775,7 @@ class DocumentWindowImpl extends com.intellij.injected.editor.DocumentWindowImpl
// result[i] == "" means delete
// result[i] == string means replace
@NotNull
public String[] calculateMinEditSequence(String newText) {
String[] calculateMinEditSequence(String newText) {
synchronized (myLock) {
String[] result = new String[myShreds.size()];
String hostText = myDelegate.getText();
@@ -915,7 +915,7 @@ class DocumentWindowImpl extends com.intellij.injected.editor.DocumentWindowImpl
}
}
public void setShreds(@NotNull Place shreds) {
void setShreds(@NotNull Place shreds) {
synchronized (myLock) {
myShreds.dispose();
myShreds = shreds;
@@ -923,7 +923,7 @@ class DocumentWindowImpl extends com.intellij.injected.editor.DocumentWindowImpl
}
@NotNull
public Place getShreds() {
Place getShreds() {
synchronized (myLock) {
return myShreds;
}
@@ -267,16 +267,15 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
place.add(shred);
info.newInjectionHostRange = shred.getSmartPointer().getRange();
}
DocumentWindowImpl documentWindow = new DocumentWindowImpl(hostDocument, place);
String fileName = PathUtil.makeFileName(hostVirtualFile.getName(), injectedFileExtension);
ASTNode parsedNode =
parseFile(language, forcedLanguage, documentWindow, hostVirtualFile, hostDocument, hostPsiFile, project, documentWindow.getText(),
placeInfos, decodedChars, fileName);
PsiFile psiFile = (PsiFile)parsedNode.getPsi();
InjectedFileViewProvider viewProvider = (InjectedFileViewProvider)psiFile.getViewProvider();
synchronized (InjectedLanguageManagerImpl.ourInjectionPsiLock) {
DocumentWindowImpl documentWindow = new DocumentWindowImpl(hostDocument, place);
String fileName = PathUtil.makeFileName(hostVirtualFile.getName(), injectedFileExtension);
ASTNode parsedNode =
parseFile(language, forcedLanguage, documentWindow, hostVirtualFile, hostDocument, hostPsiFile, project, documentWindow.getText(),
placeInfos, decodedChars, fileName);
PsiFile psiFile = (PsiFile)parsedNode.getPsi();
InjectedFileViewProvider viewProvider = (InjectedFileViewProvider)psiFile.getViewProvider();
cacheEverything(place, documentWindow, viewProvider, psiFile);
PsiFile cachedPsiFile = documentManager.getCachedPsiFile(documentWindow);
@@ -551,65 +550,64 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
@NotNull PsiFile hostPsiFile,
@NotNull ProgressIndicator indicator,
@NotNull ASTNode oldRoot, @NotNull ASTNode newRoot) {
synchronized (InjectedLanguageManagerImpl.ourInjectionPsiLock) {
Project project = hostPsiFile.getProject();
String newText = oldDocumentWindow.getText();
FileASTNode oldNode = oldInjectedPsi.getNode();
InjectedFileViewProvider oldInjectedPsiViewProvider = (InjectedFileViewProvider)oldInjectedPsi.getViewProvider();
String oldPsiText = oldNode.getText();
if (newText.equals(oldPsiText)) return ()->true;
if (oldDocumentWindow.isOneLine() && newText.contains("\n") != oldPsiText.contains("\n")) {
// one-lineness changed, e.g. when enter pressed in the middle of a string literal
Project project = hostPsiFile.getProject();
String newText = oldDocumentWindow.getText();
FileASTNode oldNode = oldInjectedPsi.getNode();
InjectedFileViewProvider oldInjectedPsiViewProvider = (InjectedFileViewProvider)oldInjectedPsi.getViewProvider();
String oldPsiText = oldNode.getText();
if (newText.equals(oldPsiText)) return ()->true;
if (oldDocumentWindow.isOneLine() && newText.contains("\n") != oldPsiText.contains("\n")) {
// one-lineness changed, e.g. when enter pressed in the middle of a string literal
return null;
}
Place oldPlace = oldDocumentWindow.getShreds();
// can be different from newText if decode fails in the middle and we'll have to shrink the document
StringBuilder newDocumentText = new StringBuilder(newText.length());
// we need escaper but it only works with committed PSI,
// so we get the committed (but not yet applied) PSI from the commit-document-in-the-background process
// and find the corresponding injection host there
// and create literal escaper from that new (dummy) psi
List<PlaceInfo> placeInfos = new SmartList<>();
StringBuilder chars = new StringBuilder();
for (PsiLanguageInjectionHost.Shred shred : oldPlace) {
PsiLanguageInjectionHost oldHost = shred.getHost();
if (oldHost == null) return null;
SmartPsiElementPointer<PsiLanguageInjectionHost> hostPointer = ((ShredImpl)shred).getSmartPointer();
Segment newInjectionHostRange = calcActualRange(hostPsiFile, oldDocumentWindow.getDelegate(), hostPointer.getPsiRange());
if (newInjectionHostRange == null) return null;
PsiLanguageInjectionHost newDummyInjectionHost = findNewInjectionHost(hostPsiFile, oldRoot, newRoot, oldHost, newInjectionHostRange);
if (newDummyInjectionHost == null) {
return null;
}
Place oldPlace = oldDocumentWindow.getShreds();
// can be different from newText if decode fails in the middle and we'll have to shrink the document
StringBuilder newDocumentText = new StringBuilder(newText.length());
// we need escaper but it only works with committed PSI,
// so we get the committed (but not yet applied) PSI from the commit-document-in-the-background process
// and find the corresponding injection host there
// and create literal escaper from that new (dummy) psi
List<PlaceInfo> placeInfos = new SmartList<>();
StringBuilder chars = new StringBuilder();
for (PsiLanguageInjectionHost.Shred shred : oldPlace) {
PsiLanguageInjectionHost oldHost = shred.getHost();
if (oldHost == null) return null;
SmartPsiElementPointer<PsiLanguageInjectionHost> hostPointer = ((ShredImpl)shred).getSmartPointer();
Segment newInjectionHostRange = calcActualRange(hostPsiFile, oldDocumentWindow.getDelegate(), hostPointer.getPsiRange());
if (newInjectionHostRange == null) return null;
PsiLanguageInjectionHost newDummyInjectionHost = findNewInjectionHost(hostPsiFile, oldRoot, newRoot, oldHost, newInjectionHostRange);
if (newDummyInjectionHost == null) {
return null;
}
newInjectionHostRange = newDummyInjectionHost.getTextRange().shiftRight(oldRoot.getTextRange().getStartOffset());
Segment hostInjectionRange = shred.getHostRangeMarker(); // in the new document
if (hostInjectionRange == null) return null;
TextRange rangeInsideHost = TextRange.create(hostInjectionRange).shiftLeft(newInjectionHostRange.getStartOffset());
newInjectionHostRange = newDummyInjectionHost.getTextRange().shiftRight(oldRoot.getTextRange().getStartOffset());
Segment hostInjectionRange = shred.getHostRangeMarker(); // in the new document
if (hostInjectionRange == null) return null;
TextRange rangeInsideHost = TextRange.create(hostInjectionRange).shiftLeft(newInjectionHostRange.getStartOffset());
PlaceInfo info = new PlaceInfo(shred.getPrefix(), shred.getSuffix(), newDummyInjectionHost, rangeInsideHost);
placeInfos.add(info);
info.newInjectionHostRange = newInjectionHostRange;
PlaceInfo info = new PlaceInfo(shred.getPrefix(), shred.getSuffix(), newDummyInjectionHost, rangeInsideHost);
placeInfos.add(info);
info.newInjectionHostRange = newInjectionHostRange;
decode(info, chars);
decode(info, chars);
// pass the old pointers because their offsets will be adjusted automatically (SmartPsiElementPointer does that)
TextRange rangeInHostElementPSI = info.rangeInHostElement;
// pass the old pointers because their offsets will be adjusted automatically (SmartPsiElementPointer does that)
TextRange rangeInHostElementPSI = info.rangeInHostElement;
newDocumentText.append(shred.getPrefix());
newDocumentText.append(newDummyInjectionHost.getText(), rangeInHostElementPSI.getStartOffset(), rangeInHostElementPSI.getEndOffset());
newDocumentText.append(shred.getSuffix());
}
// newDocumentText can be shorter if decode failed
//assert newText.equals(newDocumentText.toString()) : "-\n"+newText+"\n--\n"+newDocumentText+"\n---\n";
PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(project);
DocumentEx hostDocument = oldDocumentWindow.getDelegate();
assert documentManager.isUncommited(hostDocument);
String fileName = ((VirtualFileWindowImpl)oldInjectedVirtualFile).getName();
ASTNode parsedNode = parseFile(language, language, oldDocumentWindow,
hostVirtualFile, hostDocument, hostPsiFile, project, newDocumentText, placeInfos, chars,
fileName);
newDocumentText.append(shred.getPrefix());
newDocumentText.append(newDummyInjectionHost.getText(), rangeInHostElementPSI.getStartOffset(), rangeInHostElementPSI.getEndOffset());
newDocumentText.append(shred.getSuffix());
}
// newDocumentText can be shorter if decode failed
//assert newText.equals(newDocumentText.toString()) : "-\n"+newText+"\n--\n"+newDocumentText+"\n---\n";
PsiDocumentManagerBase documentManager = (PsiDocumentManagerBase)PsiDocumentManager.getInstance(project);
DocumentEx hostDocument = oldDocumentWindow.getDelegate();
assert documentManager.isUncommited(hostDocument);
String fileName = ((VirtualFileWindowImpl)oldInjectedVirtualFile).getName();
ASTNode parsedNode = parseFile(language, language, oldDocumentWindow,
hostVirtualFile, hostDocument, hostPsiFile, project, newDocumentText, placeInfos, chars,
fileName);
synchronized (InjectedLanguageManagerImpl.ourInjectionPsiLock) {
DiffLog diffLog = BlockSupportImpl.mergeTrees((PsiFileImpl)oldInjectedPsi, oldNode, parsedNode, indicator, oldPsiText);
return () -> {
@@ -682,7 +680,6 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
virtualFile.setContent(null, decodedChars, false);
virtualFile.setWritable(virtualFile.getDelegate().isWritable());
try {
List<InjectedLanguageUtil.TokenInfo> tokens = obtainHighlightTokensFromLexer(language, decodedChars, virtualFile, project, placeInfos);
InjectedLanguageUtil.setHighlightTokens(psiFile, tokens);
@@ -774,7 +771,7 @@ class InjectionRegistrarImpl extends MultiHostRegistrarImpl implements MultiHost
int suffixLength = 0;
TextRange rangeInsideHost = null;
int shredEndOffset = -1;
List<InjectedLanguageUtil.TokenInfo> tokens = new ArrayList<>(10);
List<InjectedLanguageUtil.TokenInfo> tokens = new ArrayList<>(outChars.length()/5); // avg. token per 5 chars
for (IElementType tokenType = lexer.getTokenType(); tokenType != null; lexer.advance(), tokenType = lexer.getTokenType()) {
TextRange range = new ProperTextRange(lexer.getTokenStart(), lexer.getTokenEnd());
while (range != null && !range.isEmpty()) {
@@ -77,9 +77,6 @@ public abstract class NewVirtualFile extends VirtualFile implements VirtualFileW
@Nullable @Deprecated
public NewVirtualFile findChildById(int id) {return null;}
@Nullable @Deprecated
public NewVirtualFile findChildByIdIfCached(int id) {return null;}
@Override
public void refresh(final boolean asynchronous, final boolean recursive, final Runnable postRunnable) {
RefreshQueue.getInstance().refresh(asynchronous, recursive, postRunnable, this);
@@ -9,9 +9,6 @@ import javax.swing.JLabel
// see com.intellij.uiDesigner.core.AbstractLayout.DEFAULT_HGAP and DEFAULT_VGAP
// https://docs.google.com/document/d/1DKnLkO-7_onA7_NCw669aeMH5ltNvw-QMiQHnXu8k_Y/edit
internal const val HORIZONTAL_GAP = 10
internal const val VERTICAL_GAP = 5
@PublishedApi
internal fun createLayoutBuilder() = LayoutBuilder(MigLayoutBuilder())
@@ -5,6 +5,7 @@ import com.intellij.icons.AllIcons
import com.intellij.ui.components.noteComponent
import com.intellij.ui.layout.*
import com.intellij.util.containers.ContainerUtil
import com.intellij.util.ui.UIUtil
import net.miginfocom.layout.*
import net.miginfocom.swing.MigLayout
import java.awt.Component
@@ -32,8 +33,8 @@ internal class MigLayoutBuilder : LayoutBuilderImpl {
newRow()
val cc = CC()
cc.vertical.gapBefore = gapToBoundSize(VERTICAL_GAP, false)
cc.vertical.gapAfter = gapToBoundSize(VERTICAL_GAP * 2, false)
cc.vertical.gapBefore = gapToBoundSize(UIUtil.DEFAULT_VGAP, false)
cc.vertical.gapAfter = gapToBoundSize(UIUtil.DEFAULT_VGAP * 2, false)
val row = rootRow.createChildRow(label = null, noGrid = true)
row.apply {
@@ -78,7 +79,7 @@ internal class MigLayoutBuilder : LayoutBuilderImpl {
// https://goo.gl/LDylKm
// gap = 10u where u = 4px
gapTop = VERTICAL_GAP * 3
gapTop = UIUtil.DEFAULT_VGAP * 3
}
var isSplitRequired = true
@@ -140,7 +141,7 @@ internal class MigLayoutBuilder : LayoutBuilderImpl {
// do not add gap if next component is gear action button
if (component !== lastComponent && !row.components.get(index + 1).let { it is JLabel && it.icon === AllIcons.General.Gear }) {
cc.horizontal.gapAfter = gapToBoundSize(HORIZONTAL_GAP * 2, true)
cc.horizontal.gapAfter = gapToBoundSize(UIUtil.DEFAULT_HGAP * 2, true)
}
}
}
@@ -190,7 +191,7 @@ internal fun gapToBoundSize(value: Int, isHorizontal: Boolean): BoundSize {
// default values differs to MigLayout - IntelliJ Platform defaults are used
// see com.intellij.uiDesigner.core.AbstractLayout.DEFAULT_HGAP and DEFAULT_VGAP (multiplied by 2 to achieve the same look (it seems in terms of MigLayout gap is both left and right space))
private fun createLayoutConstraints(gridGapX: Int = HORIZONTAL_GAP * 2, gridGapY: Int = VERTICAL_GAP): LC {
private fun createLayoutConstraints(gridGapX: Int = UIUtil.DEFAULT_HGAP * 2, gridGapY: Int = UIUtil.DEFAULT_VGAP): LC {
// no setter for gap, so, create string to parse
val lc = LC()
lc.gridGapX = gapToBoundSize(gridGapX, true)
@@ -12,6 +12,7 @@ import com.intellij.ui.components.Label
import com.intellij.ui.layout.*
import com.intellij.util.SmartList
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
import net.miginfocom.layout.BoundSize
import net.miginfocom.layout.CC
import net.miginfocom.layout.ConstraintParser
@@ -53,8 +54,8 @@ internal class MigLayoutRow(private val parent: MigLayoutRow?,
row.apply {
val separatorComponent = SeparatorComponent(0, OnePixelDivider.BACKGROUND, null)
val cc = CC()
cc.vertical.gapBefore = gapToBoundSize(VERTICAL_GAP * 3, false)
cc.vertical.gapAfter = gapToBoundSize(VERTICAL_GAP * 2, false)
cc.vertical.gapBefore = gapToBoundSize(UIUtil.LARGE_VGAP, false)
cc.vertical.gapAfter = gapToBoundSize(UIUtil.DEFAULT_VGAP * 2, false)
componentConstraints.put(separatorComponent, cc)
separatorComponent()
}
@@ -80,7 +81,7 @@ internal class MigLayoutRow(private val parent: MigLayoutRow?,
return ComponentPanelBuilder.computeCommentInsets(firstComponent, true).left
}
else {
return HORIZONTAL_GAP * 3
return UIUtil.DEFAULT_HGAP * 3
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@@ -39,5 +39,5 @@ componentConstrains:
skip: 1
spanX: 2097051
wrap: true
rectangles: '[0, 0, 512, 23], [0, 28, 132, 26], [152, 28, 360, 26], [152, 28, 360,
26], [0, 59, 132, 26], [152, 59, 360, 26], [152, 85, 360, 14]'
rectangles: '[0, 0, 512, 23], [0, 27, 132, 26], [152, 27, 360, 26], [152, 27, 360,
26], [0, 57, 132, 26], [152, 57, 360, 26], [152, 83, 360, 14]'
@@ -14,5 +14,5 @@ componentConstrains:
'JTextField #3':
horizontal: {grow: 100.0}
wrap: true
rectangles: '[0, 0, 145, 23], [165, 0, 347, 23], [0, 28, 145, 26], [165, 28, 347,
rectangles: '[0, 0, 145, 23], [165, 0, 347, 23], [0, 27, 145, 26], [165, 27, 347,
26]'
@@ -12,10 +12,10 @@ componentConstrains:
spanX: 2097051
vertical:
gapAfter:
min: &id001 {horizontal: false, operation: 100, unit: 0, unitString: px, value: 10.0}
min: &id001 {horizontal: false, operation: 100, unit: 0, unitString: px, value: 8.0}
preferred: *id001
gapBefore:
min: &id002 {horizontal: false, operation: 100, unit: 0, unitString: px, value: 5.0}
min: &id002 {horizontal: false, operation: 100, unit: 0, unitString: px, value: 4.0}
preferred: *id002
wrap: true
'JLabel #1': {}
@@ -25,11 +25,11 @@ componentConstrains:
spanX: 2097051
vertical:
gapAfter:
min: &id003 {horizontal: false, operation: 100, unit: 0, unitString: px, value: 10.0}
min: &id003 {horizontal: false, operation: 100, unit: 0, unitString: px, value: 8.0}
preferred: *id003
gapBefore:
min: &id004 {horizontal: false, operation: 100, unit: 0, unitString: px, value: 15.0}
min: &id004 {horizontal: false, operation: 100, unit: 0, unitString: px, value: 12.0}
preferred: *id004
wrap: true
rectangles: '[0, 0, 512, 47], [0, 52, 99, 26], [119, 52, 393, 26], [119, 83, 393,
23], [0, 111, 512, 41]'
rectangles: '[0, 0, 512, 44], [0, 48, 99, 26], [119, 48, 393, 26], [119, 78, 393,
23], [0, 105, 512, 36]'

Before

Width:  |  Height:  |  Size: 394 B

After

Width:  |  Height:  |  Size: 394 B

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before

Width:  |  Height:  |  Size: 277 B

After

Width:  |  Height:  |  Size: 277 B

Before

Width:  |  Height:  |  Size: 613 B

After

Width:  |  Height:  |  Size: 613 B

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 603 B

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

@@ -14,6 +14,7 @@ import com.intellij.util.io.exists
import com.intellij.util.io.outputStream
import com.intellij.util.io.sanitizeFileName
import com.intellij.util.io.write
import io.netty.util.internal.SystemPropertyUtil
import net.miginfocom.layout.Grid
import net.miginfocom.layout.LayoutUtil
import net.miginfocom.swing.MigLayout
@@ -139,11 +140,12 @@ class UiDslTest {
val actualLayoutJson = configurationToJson(component, component.layout as MigLayout, false, rectangles.joinToString(", ") { "[${it.joinToString(", ")}]" })
try {
val expectedLayoutDataFile = Paths.get(PlatformTestUtil.getPlatformTestDataPath(), "ui", "layout", "$imageName.yml")
if (expectedLayoutDataFile.exists()) {
Assertions.assertThat(actualLayoutJson).isEqualTo(expectedLayoutDataFile)
val isUpdateSnapshots = SystemPropertyUtil.getBoolean("test.update.snapshots", false)
if (!expectedLayoutDataFile.exists() || isUpdateSnapshots) {
expectedLayoutDataFile.write(actualLayoutJson)
}
else {
expectedLayoutDataFile.write(actualLayoutJson)
Assertions.assertThat(actualLayoutJson).isEqualTo(expectedLayoutDataFile)
}
if (imageDir.isNullOrEmpty()) {
@@ -151,7 +153,7 @@ class UiDslTest {
}
val imagePath = Paths.get(imageDir, "$imageName.png")
if (!imagePath.exists()) {
if (!imagePath.exists() || isUpdateSnapshots) {
System.out.println("Write a new snapshot image ${imagePath.fileName}")
saveImage(imagePath)
return
@@ -152,18 +152,17 @@ public class DrawImageTest extends TestScaleHelper {
testDrawImage(dest = new Dest(scale), bounds(dstCol, dstRow), bounds(srcCol, srcRow), colors);
}
private void testDrawImage(Dest dest, Rectangle dstBounds, Rectangle srcBounds, TestColor[] testColors) {
private static void testDrawImage(Dest dest, Rectangle dstBounds, Rectangle srcBounds, TestColor[] testColors) {
UIUtil.drawImage(dest.gr, source, dstBounds, srcBounds, null);
for (TestColor t : testColors) t.test();
dest.dispose();
}
@SuppressWarnings("SameParameterValue")
private static Pair<Image, Graphics2D> supplyImage(double scale, int width, int height, Color[] quarterColors, boolean supplyGraphics) {
@SuppressWarnings("UndesirableClassUsage")
BufferedImage image = new BufferedImage((int)ceil(width * scale), (int)ceil(height * scale), BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
double gScale = UIUtil.isJreHiDPIEnabled() ? scale : 1;
g.scale(gScale, gScale);
Pair<BufferedImage, Graphics2D> pair = createImageAndGraphics(scale, width, height);
BufferedImage image = pair.first;
Graphics2D g = pair.second;
int qw = JBUI.scale(width) / 2;
int qh = JBUI.scale(height) / 2;
@@ -184,15 +183,15 @@ public class DrawImageTest extends TestScaleHelper {
return new Pair<>(image, g);
}
private Rectangle bounds() {
private static Rectangle bounds() {
return bounds(0, 0, JBUI.scale(IMAGE_SIZE));
}
private Rectangle bounds(int col, int row) {
private static Rectangle bounds(int col, int row) {
return bounds(col, row, JBUI.scale(IMAGE_QUARTER_SIZE));
}
private Rectangle bounds(int col, int row, int size) {
private static Rectangle bounds(int col, int row, int size) {
return new Rectangle(col * size, row * size, size, size);
}
}
@@ -0,0 +1,79 @@
// 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.util.ui;
import com.intellij.openapi.util.IconLoader.CachedImageIcon;
import com.intellij.openapi.util.Pair;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.ui.JBUI.ScaleContext;
import com.intellij.util.ui.paint.ImageComparator;
import com.intellij.util.ui.paint.ImageComparator.AASmootherComparator;
import org.junit.Test;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.MalformedURLException;
import static com.intellij.util.ui.JBUI.ScaleType.PIX_SCALE;
import static com.intellij.util.ui.JBUI.ScaleType.SYS_SCALE;
import static com.intellij.util.ui.JBUI.ScaleType.USR_SCALE;
/**
* Tests {@link com.intellij.ui.LayeredIcon} painting.
*
* @author tav
*/
public class LayeredIconPaintTest extends TestScaleHelper {
@Test
public void test() throws MalformedURLException {
JBUI.setUserScaleFactor(1);
overrideJreHiDPIEnabled(true);
test(1, 1);
test(1, 2);
test(2, 1);
test(2, 2);
}
public void test(int usrScale, int sysScale) throws MalformedURLException {
LayeredIcon icon = new LayeredIcon(2);
CachedImageIcon icon1 = new CachedImageIcon(new File(getIcon1Path()).toURI().toURL());
CachedImageIcon icon2 = new CachedImageIcon(new File(getIcon2Path()).toURI().toURL());
ScaleContext ctx = ScaleContext.create(USR_SCALE.of(usrScale), SYS_SCALE.of(sysScale));
icon1.updateScaleContext(ctx.copy());
icon2.updateScaleContext(ctx.copy());
icon.setIcon(icon1, 0);
icon.setIcon(icon2, 1, 10, 6);
Icon scaledIcon = icon.scale(usrScale);
Pair<BufferedImage, Graphics2D> pair = createImageAndGraphics(sysScale, scaledIcon.getIconWidth(), scaledIcon.getIconHeight());
BufferedImage iconImage = pair.first;
Graphics2D g2d = pair.second;
scaledIcon.paintIcon(null, g2d, 0, 0);
//saveImage(iconImage, getGoldImagePath((int)ctx.getScale(PIX_SCALE))); // uncomment to save gold image
BufferedImage goldImage = loadImage(getGoldImagePath((int)ctx.getScale(PIX_SCALE)));
ImageComparator.compareAndAssert(
new AASmootherComparator(0.1, 0.1, new Color(0, 0, 0, 0)), goldImage, iconImage, null);
}
private static String getGoldImagePath(int scale) {
return PlatformTestUtil.getPlatformTestDataPath() + "ui/gold_LayeredIcon@" + scale + "x.png";
}
private static String getIcon1Path() {
return PlatformTestUtil.getPlatformTestDataPath() + "ui/db_set_breakpoint.png";
}
private static String getIcon2Path() {
return PlatformTestUtil.getPlatformTestDataPath() + "ui/question_badge.png";
}
}
@@ -4,9 +4,9 @@ package com.intellij.util.ui;
import com.intellij.openapi.util.IconLoader.CachedImageIcon;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.IconUtil;
import com.intellij.util.ImageLoader;
import com.intellij.util.ui.JBUI.ScaleContext;
import com.intellij.util.ui.paint.ImageComparator;
import com.intellij.util.ui.paint.ImageComparator.AASmootherComparator;
import org.junit.Before;
import org.junit.Test;
@@ -16,7 +16,6 @@ import java.io.File;
import java.net.MalformedURLException;
import static com.intellij.util.ui.JBUI.ScaleType.SYS_SCALE;
import static junit.framework.TestCase.assertTrue;
/**
* Tests SVG icon painting.
@@ -39,32 +38,13 @@ public class SvgIconPaintTest extends TestScaleHelper {
CachedImageIcon icon = new CachedImageIcon(new File(getSvgIconPath()).toURI().toURL());
icon.updateScaleContext(ScaleContext.create(SYS_SCALE.of(1)));
BufferedImage iconImage = ImageUtil.toBufferedImage(IconUtil.toImage(icon));
//save(iconImage);
BufferedImage goldImage = load();
ImageComparator comparator = new ImageComparator(new ImageComparator.ColorAASmoother(0, 0.3f));
StringBuilder sb = new StringBuilder("images mismatch: ");
assertTrue(sb.toString(), comparator.compare(iconImage, goldImage, sb));
}
//saveImage(iconImage, getGoldImagePath()); // uncomment to save gold image
@SuppressWarnings("unused")
private static void save(BufferedImage bi) {
try {
javax.imageio.ImageIO.write(bi, "png", new File(getGoldImagePath()));
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
BufferedImage goldImage = loadImage(getGoldImagePath());
private static BufferedImage load() {
try {
Image img = ImageLoader.loadFromUrl(
new File(getGoldImagePath()).toURI().toURL(), false, false, null, ScaleContext.createIdentity());
return ImageUtil.toBufferedImage(img);
}
catch (MalformedURLException e) {
throw new RuntimeException(e);
}
ImageComparator.compareAndAssert(
new AASmootherComparator(0.1, 0.1, new Color(0, 0, 0, 0)), iconImage, goldImage, null);
}
private static String getSvgIconPath() {
@@ -1,9 +1,12 @@
// 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.util.ui;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.registry.RegistryValue;
import com.intellij.util.ImageLoader;
import com.intellij.util.SystemProperties;
import com.intellij.util.ui.JBUI.ScaleContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.After;
@@ -12,6 +15,8 @@ import org.junit.Before;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
@@ -88,4 +93,33 @@ public class TestScaleHelper {
g.scale(scale, scale);
return g;
}
public static Pair<BufferedImage, Graphics2D> createImageAndGraphics(double scale, int width, int height) {
//noinspection UndesirableClassUsage
final BufferedImage image = new BufferedImage((int)Math.ceil(width * scale), (int)Math.ceil(height * scale), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
double gScale = UIUtil.isJreHiDPIEnabled() ? scale : 1;
g.scale(gScale, gScale);
return Pair.create(image, g);
}
@SuppressWarnings("unused")
public static void saveImage(BufferedImage image, String path) {
try {
javax.imageio.ImageIO.write(image, "png", new File(path));
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
public static BufferedImage loadImage(String path) {
try {
Image img = ImageLoader.loadFromUrl(
new File(path).toURI().toURL(), false, false, null, ScaleContext.createIdentity());
return ImageUtil.toBufferedImage(img);
}
catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
}
@@ -2,23 +2,16 @@
package com.intellij.util.ui.paint;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.util.ImageLoader;
import com.intellij.util.ui.ImageUtil;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.JBUI.ScaleContext;
import com.intellij.util.ui.TestScaleHelper;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.paint.ImageComparator.GreyscaleAASmoother;
import com.intellij.util.ui.paint.ImageComparator.AASmootherComparator;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.MalformedURLException;
import java.util.function.Function;
import static com.intellij.util.ui.JBUI.scale;
import static java.lang.Math.ceil;
import static junit.framework.TestCase.assertTrue;
/**
* Compares golden images with the images painted by the test.
@@ -28,7 +21,7 @@ import static junit.framework.TestCase.assertTrue;
public abstract class AbstractPainter2DTest extends TestScaleHelper {
public void testGoldenImages() {
ImageComparator comparator = new ImageComparator(
new GreyscaleAASmoother(0.15f, 0.5f));
new AASmootherComparator(0.15, 0.5, Color.BLACK));
// 1) IDE-HiDPI
for (int scale : getScales()) testGolden(comparator, scale, false);
@@ -46,9 +39,9 @@ public abstract class AbstractPainter2DTest extends TestScaleHelper {
BufferedImage image = supplyGraphics(scale, getImageSize().width, getImageSize().height, this::paint);
//save(image, scale); // uncomment to recreate golden image
//saveImage(image, getGoldenImagePath(scale)); // uncomment to recreate golden image
compare(image, load(scale), comparator, scale);
compare(image, loadImage(getGoldenImagePath(scale)), comparator, scale);
}
protected BufferedImage supplyGraphics(double scale, int width, int height, Function<Graphics2D, Void> consumeGraphics) {
@@ -81,30 +74,8 @@ public abstract class AbstractPainter2DTest extends TestScaleHelper {
return null;
}
@SuppressWarnings("unused")
private void save(BufferedImage bi, int scale) {
try {
javax.imageio.ImageIO.write(bi, "png", new File(getGoldenImagePath(scale)));
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
private BufferedImage load(int scale) {
try {
Image img = ImageLoader.loadFromUrl(
new File(getGoldenImagePath(scale)).toURI().toURL(), false, false, null, ScaleContext.createIdentity());
return ImageUtil.toBufferedImage(img);
}
catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
protected static void compare(BufferedImage img1, BufferedImage img2, ImageComparator comparator, double scale) {
StringBuilder sb = new StringBuilder("images mismatch: JreHiDPIEnabled=" + UIUtil.isJreHiDPIEnabled() + "; scale=" + scale + "; ");
boolean comparable = comparator.compare(img1, img2, sb);
assertTrue(sb.toString(), comparable);
comparator.compareAndAssert(img1, img2, "images mismatch: JreHiDPIEnabled=" + UIUtil.isJreHiDPIEnabled() + "; scale=" + scale + "; ");
}
private String getGoldenImagePath(int scale) {
@@ -1,6 +1,7 @@
// 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.util.ui.paint;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -8,6 +9,8 @@ import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import static junit.framework.TestCase.assertTrue;
/**
* @author tav
*/
@@ -19,88 +22,66 @@ public class ImageComparator {
}
/**
* Smooths difference b/w antialiased greyscale images.
* Used to smooth difference b/w antialiased images.
*/
public static class GreyscaleAASmoother implements ColorComparator {
private static final int FG_COLOR = Color.WHITE.getRGB();
private static final int BG_COLOR = Color.BLACK.getRGB();
private final float boundaryColorsDist;
private final float medianColorsDist;
public static class AASmootherComparator implements ColorComparator {
private final double backgroundColorsDist;
private final double inputColorsDist;
private final int backgroundRGB;
/**
* The distance b/w two colors are in [0..1]. It's assumed {@code boundaryColorDist} is relatively small,
* whereas {@code medianColorDist} is larger.
* The distance b/w two colors is in [0..1]. It's assumed {@code backgroundColorsDist} is less tolerant,
* whereas {@code inputColorDist} is more tolerant.
*
* @param boundaryColorsDist tolerant distance b/w the input color and the boundary (BG or FG) color
* @param medianColorsDist tolerant distance b/w the input colors on the median values (b/w the boundaries)
* @param backgroundColorsDist tolerant distance b/w the input color and the background color
* @param inputColorsDist tolerant distance b/w the input colors
*/
public GreyscaleAASmoother(float boundaryColorsDist, float medianColorsDist) {
this.boundaryColorsDist = boundaryColorsDist;
this.medianColorsDist = medianColorsDist;
public AASmootherComparator(double backgroundColorsDist, double inputColorsDist, Color background) {
this.backgroundColorsDist = backgroundColorsDist;
this.inputColorsDist = inputColorsDist;
this.backgroundRGB = background.getRGB();
}
@Override
public boolean compare(int argb1, int argb2) {
if (argb1 == argb2) return true;
if (isBoundColor(argb1) || isBoundColor(argb2)) {
return dist(argb1, argb2) <= boundaryColorsDist;
if (argb1 == backgroundRGB || argb2 == backgroundRGB) {
return dist(argb1, argb2) <= backgroundColorsDist;
}
return dist(argb1, argb2) <= medianColorsDist;
return dist(argb1, argb2) <= inputColorsDist;
}
protected float dist(int argb1, int argb2) {
int a1 = (argb1 >> 24 & 0xff) / 0xff;
int a2 = (argb2 >> 24 & 0xff) / 0xff;
// colors are grey
return Math.abs((argb1 & 0xff) * a1 - (argb2 & 0xff) * a2) / 255f;
private static double dist(int argb1, int argb2) {
double[] comp = diff(argb1, argb2);
// normalize dist to [0..1]
return Math.sqrt((comp[0] * comp[0] + comp[1] * comp[1] + comp[2] * comp[2] + comp[3] * comp[3]) / comp.length);
}
protected boolean isBoundColor(int argb) {
return FG_COLOR == argb || BG_COLOR == argb;
}
}
/**
* Smooths difference b/w antialiased colored images.
*/
public static class ColorAASmoother extends GreyscaleAASmoother {
private static final int BG_COLOR = 0x00000000;
/**
* {@inheritDoc}
*/
public ColorAASmoother(float boundaryColorsDist, float medianColorsDist) {
super(boundaryColorsDist, medianColorsDist);
}
@Override
protected float dist(int argb1, int argb2) {
float[] comp = diff(argb1, argb2);
return (float)Math.sqrt(comp[0] * comp[0] + comp[1] * comp[1] + comp[2] * comp[2]);
}
@Override
protected boolean isBoundColor(int argb) {
return BG_COLOR == argb;
}
private static float[] diff(int argb1, int argb2) {
int rgb1 = applyAlpha(argb1);
int rgb2 = applyAlpha(argb2);
return new float[] {
((rgb1 >> 16) & 0xFF - (rgb2 >> 16) & 0xFF) / 255f,
((rgb1 >> 8) & 0xFF - (rgb2 >> 8) & 0xFF) / 255f,
(rgb1 & 0xFF - rgb2 & 0xFF) / 255f
private static double[] diff(int argb1, int argb2) {
double a1 = a(argb1);
double a2 = a(argb2);
return new double[] {
Math.abs(a1 * a1 - a2 * a2),
Math.abs(r(argb1) * a1 - r(argb2) * a2),
Math.abs(g(argb1) * a1 - g(argb2) * a2),
Math.abs(b(argb1) * a1 - b(argb2) * a2)
};
}
private static int applyAlpha(int argb) {
float a = ((argb >> 24) & 0xFF) / 255f;
int r = (int)(((argb >> 16) & 0xFF) * a);
int g = (int)(((argb >> 8) & 0xFF) * a);
int b = (int)((argb & 0xFF) * a);
return (r << 16) | (g << 8) | b;
protected static double a(int argb) {
return ((argb >> 24) & 0xFF) / 255d;
}
protected static double r(int argb) {
return ((argb >> 16) & 0xFF) / 255d;
}
protected static double g(int argb) {
return ((argb >> 8) & 0xFF) / 255d;
}
protected static double b(int argb) {
return (argb & 0xFF) / 255d;
}
}
@@ -115,10 +96,25 @@ public class ImageComparator {
/**
* BufferedImage.TYPE_INT_ARGB is expected
*/
public boolean compare(@NotNull BufferedImage img1, @NotNull BufferedImage img2) {
return compare(img1, img2, null);
public static void compareAndAssert(@Nullable ColorComparator colorComparator,
@NotNull BufferedImage img1, @NotNull BufferedImage img2,
@Nullable String errMsgPrefix)
{
new ImageComparator(colorComparator).compareAndAssert(img1, img2, errMsgPrefix);
}
/**
* BufferedImage.TYPE_INT_ARGB is expected
*/
public void compareAndAssert(@NotNull BufferedImage img1, @NotNull BufferedImage img2, @Nullable String errMsgPrefix) {
StringBuilder sb = new StringBuilder(ObjectUtils.notNull(errMsgPrefix, "images mismatch: "));
boolean equal = compare(img1, img2, sb);
assertTrue(sb.toString(), equal);
}
/**
* BufferedImage.TYPE_INT_ARGB is expected
*/
public boolean compare(@NotNull BufferedImage img1, @NotNull BufferedImage img2, @Nullable /*OUT*/StringBuilder reason) {
int[] d1 = ((DataBufferInt)img1.getRaster().getDataBuffer()).getData();
int[] d2 = ((DataBufferInt)img2.getRaster().getDataBuffer()).getData();
@@ -35,13 +35,13 @@ public class LinePainter2DTest extends AbstractPainter2DTest {
JBUI.setUserScaleFactor(1);
overrideJreHiDPIEnabled(false);
supplyGraphics(1, 1, 1, this::testAlign);
supplyGraphics(1, 1, 1, LinePainter2DTest::testAlign);
overrideJreHiDPIEnabled(true);
supplyGraphics(2, 1, 1, this::testAlign);
supplyGraphics(2, 1, 1, LinePainter2DTest::testAlign);
}
private Void testAlign(Graphics2D g) {
private static Void testAlign(Graphics2D g) {
double scale = JBUI.ScaleContext.create(g).getScale(PIX_SCALE);
String msg = "LinePainter2D.align is incorrect (JreHiDPIEnabled: " + UIUtil.isJreHiDPIEnabled() + "; scale: " + scale + ")";
double delta = 0.000001;
@@ -100,7 +100,7 @@ public class LinePainter2DTest extends AbstractPainter2DTest {
return null;
}
private void paintLines(Graphics2D g, StrokeType type, float trX, float trY) {
private static void paintLines(Graphics2D g, StrokeType type, float trX, float trY) {
g.translate(scale(trX), scale(trY));
Object aa = RenderingHints.VALUE_ANTIALIAS_ON;
paintLine(g, 0, 0, 0, 0, type, 1, aa); // a dot
@@ -114,11 +114,12 @@ public class LinePainter2DTest extends AbstractPainter2DTest {
paintLine(g, -2, -2, -LINE_LEN, -LINE_LEN, type, 1, aa);
}
private void paintLine(Graphics2D g,
double x1, double y1, double x2, double y2,
StrokeType strokeType,
double strokeWidth,
Object valueAA)
@SuppressWarnings("SameParameterValue")
private static void paintLine(Graphics2D g,
double x1, double y1, double x2, double y2,
StrokeType strokeType,
double strokeWidth,
Object valueAA)
{
strokeWidth = scale((float)strokeWidth);
x1 = scale((float)x1);
@@ -135,7 +136,7 @@ public class LinePainter2DTest extends AbstractPainter2DTest {
@Override
protected String getGoldenImageName() {
return "LinePainter2D";
return "gold_LinePainter2D";
}
@Override
@@ -110,27 +110,28 @@ public class RectanglePainter2DTest extends AbstractPainter2DTest {
JBUI.setUserScaleFactor(jreHiDPIEnabled ? 1 : (float)scale);
BufferedImage rect = supplyGraphics(scale, 15, 15,
strokeType == StrokeType.INSIDE ? this::paintRectInside : this::paintRectCentered);
strokeType == StrokeType.INSIDE ? RectanglePainter2DTest::paintRectInside : RectanglePainter2DTest::paintRectCentered);
BufferedImage outline = supplyGraphics(scale, 15, 15,
strokeType == StrokeType.INSIDE ? this::outlineRectInside : this::outlineRectCentered);
strokeType == StrokeType.INSIDE ? RectanglePainter2DTest::outlineRectInside : RectanglePainter2DTest::outlineRectCentered);
compare(rect, outline, comparator, scale);
}
private Rectangle2D rectBounds(Graphics2D g) {
double x = PaintUtil.alignToInt(scale(3f), g), y = x;
double w = PaintUtil.alignToInt(scale(10f), g), h = w;
return new Rectangle2D.Double(x, y, w, h);
private static Rectangle2D rectBounds(Graphics2D g) {
double x = PaintUtil.alignToInt(scale(3f), g);
double w = PaintUtil.alignToInt(scale(10f), g);
//noinspection SuspiciousNameCombination
return new Rectangle2D.Double(x, x, w, w);
}
private Void paintRectInside(Graphics2D g) {
private static Void paintRectInside(Graphics2D g) {
return _paintRect(g, true);
}
private Void paintRectCentered(Graphics2D g) {
private static Void paintRectCentered(Graphics2D g) {
return _paintRect(g, false);
}
private Void _paintRect(Graphics2D g, boolean inside) {
private static Void _paintRect(Graphics2D g, boolean inside) {
Rectangle2D b = rectBounds(g);
RectanglePainter2D.DRAW.paint(g, b.getX(), b.getY(), b.getWidth(), b.getHeight(),
inside ? StrokeType.INSIDE : StrokeType.CENTERED,
@@ -138,7 +139,7 @@ public class RectanglePainter2DTest extends AbstractPainter2DTest {
return null;
}
private Void outlineRectInside(Graphics2D g) {
private static Void outlineRectInside(Graphics2D g) {
Rectangle2D b = rectBounds(g);
double x = b.getX();
double y = b.getY();
@@ -156,7 +157,7 @@ public class RectanglePainter2DTest extends AbstractPainter2DTest {
return null;
}
private Void outlineRectCentered(Graphics2D g) {
private static Void outlineRectCentered(Graphics2D g) {
Rectangle2D b = rectBounds(g);
double x = b.getX();
double y = b.getY();
@@ -176,7 +177,7 @@ public class RectanglePainter2DTest extends AbstractPainter2DTest {
@Override
protected String getGoldenImageName() {
return "RectanglePainter2D";
return "gold_RectanglePainter2D";
}
@Override
@@ -1,4 +1,4 @@
// 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.
// 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.util
import com.intellij.openapi.util.JDOMUtil
@@ -39,8 +39,8 @@ private fun getSaxBuilder(): SAXBuilder {
}
saxBuilder.ignoringBoundaryWhitespace = true
saxBuilder.ignoringElementContentWhitespace = true
saxBuilder.entityResolver = EntityResolver { publicId, systemId -> InputSource(CharArrayReader(ArrayUtil.EMPTY_CHAR_ARRAY)) }
cachedSaxBuilder.set(SoftReference<SAXBuilder>(saxBuilder))
saxBuilder.entityResolver = EntityResolver { _, _ -> InputSource(CharArrayReader(ArrayUtil.EMPTY_CHAR_ARRAY)) }
cachedSaxBuilder.set(SoftReference(saxBuilder))
}
return saxBuilder
}
@@ -165,10 +165,11 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
myRepositories.clear();
myRepositories.addAll(repositories);
List<TaskProjectConfiguration.SharedServer> servers = getProjectConfiguration().servers;
servers.clear();
reps:
for (T repository : repositories) {
if (repository.isShared() && repository.getUrl() != null) {
List<TaskProjectConfiguration.SharedServer> servers = getProjectConfiguration().servers;
TaskRepositoryType type = repository.getRepositoryType();
for (TaskProjectConfiguration.SharedServer server : servers) {
if (repository.getUrl().equals(server.url) && type.getName().equals(server.type)) {
@@ -91,8 +91,6 @@ import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static com.intellij.testFramework.TemporaryDirectoryKt.generateTemporaryPath;
/**
* @author yole
*/
@@ -308,7 +306,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
int hashCode = System.identityHashCode(leaked);
leakers.append("Leaked project found:").append(leaked).append("; hash: ").append(hashCode).append("; place: ")
.append(getCreationPlace(leaked)).append("\n");
leakers.append(backLink+"\n");
leakers.append(backLink).append("\n");
leakers.append(";-----\n");
hashCodes.remove(hashCode);
@@ -324,7 +322,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
@NotNull
@TestOnly
public static String getCreationPlace(@NotNull Project project) {
String place = project.getUserData(CREATION_PLACE);
Object base;
try {
base = project.isDisposed() ? "" : project.getBaseDir();
@@ -332,7 +329,8 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
catch (Exception e) {
base = " (" + e + " while getting base dir)";
}
return project + (place != null ? place : "") + base;
String place = project.getUserData(CREATION_PLACE);
return project + " " +(place == null ? "" : place) + base;
}
protected void runStartupActivities() {
@@ -364,7 +362,8 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
}
}
Path tempFile = generateTemporaryPath(FileUtil.sanitizeFileName(getName(), false) + (isDirectoryBasedProject ? "" : ProjectFileType.DOT_DEFAULT_EXTENSION));
Path tempFile = TemporaryDirectoryKt
.generateTemporaryPath(FileUtil.sanitizeFileName(getName(), false) + (isDirectoryBasedProject ? "" : ProjectFileType.DOT_DEFAULT_EXTENSION));
myFilesToDelete.add(tempFile.toFile());
return tempFile;
}
@@ -601,14 +600,8 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
resetClassFields(aClass.getSuperclass());
}
private String getFullName() {
return getClass().getName() + "." + getName();
}
protected void setUpJdk() {
//final ProjectJdkEx jdk = ProjectJdkUtil.getDefaultJdk("java 1.4");
final Sdk jdk = getTestProjectJdk();
// ProjectJdkImpl jdk = ProjectJdkTable.getInstance().addJdk(defaultJdk);
Module[] modules = ModuleManager.getInstance(myProject).getModules();
for (Module module : modules) {
ModuleRootModificationUtil.setModuleSdk(module, jdk);
@@ -635,8 +628,7 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
resetAllFields();
});
}
catch (Throwable e) {
// Ignore
catch (Throwable ignored) {
}
}
}
@@ -97,6 +97,8 @@ ide.javafx.tips.description=(Experimental) Use JavaFX Browser for 'Tips of the D
ide.svg.icon=true
ide.svg.icon.description=Load & auto-scale svg version of an icon if present
ide.index.image.max.size=10
ide.index.image.max.size.description=Max size of an image to index, in megabytes
ide.cached.image.max.size=1.5
ide.cached.image.max.size.description=Max size of an image to cache, in megabytes
@@ -1111,8 +1113,6 @@ cidr.navigation.gotoDeclaration.overrides.showUsages.description = \
cidr.debugger.value.numberFormatting.hex=false
cidr.debugger.value.numberFormatting.hex.description=Enable experimental hexadecimal number formatting
cidr.show.compiler.info=false
cidr.show.clangtidy.info=false
cidr.cygwin.cmakePermissionsFix=true
cidr.cygwin.cmakePermissionsFix.description=Update permissions for the bin/ folder inside the installed IDE so that the bundled CMake could run
cidr.indexer.thread.count=-1
@@ -46,12 +46,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import static com.intellij.util.ui.JBUI.ScaleType.*;
import static com.intellij.util.ui.JBUI.ScaleType.PIX_SCALE;
import static com.intellij.util.ui.JBUI.ScaleType.SYS_SCALE;
public class ImageLoader implements Serializable {
private static final Logger LOG = Logger.getInstance("#com.intellij.util.ImageLoader");
public static final int CACHED_IMAGE_MAX_SIZE = (int)Math.round(Registry.doubleValue("ide.cached.image.max.size") * 1024 * 1024);
public static final long CACHED_IMAGE_MAX_SIZE = (long)(Registry.doubleValue("ide.cached.image.max.size") * 1024 * 1024);
private static final ConcurrentMap<String, Image> ourCache = ContainerUtil.createConcurrentSoftValueMap();
@SuppressWarnings({"UnusedDeclaration"}) // set from com.intellij.internal.IconsLoadTime
@@ -12,6 +12,10 @@ operator fun <T> Consumer<in T>.plusAssign(elements: Iterable<T>) {
elements.forEach(this::plusAssign)
}
operator fun <T> Consumer<in T>.plusAssign(elements: Array<out T>) {
elements.forEach(this::plusAssign)
}
operator fun <T> Consumer<in T>.plusAssign(element: T) {
accept(element)
}
@@ -1,6 +1,7 @@
// 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.zmlx.hg4idea.repo;
import com.google.common.io.BaseEncoding;
import com.intellij.dvcs.DvcsUtil;
import com.intellij.dvcs.repo.RepoStateException;
import com.intellij.dvcs.repo.Repository;
@@ -104,7 +105,7 @@ public class HgRepositoryReader {
public String readCurrentRevision() {
if (!isDirStateInfoAvailable()) return null;
try {
return Base64.getEncoder().encodeToString(readHashBytesFromFile(myDirStateFile));
return BaseEncoding.base16().lowerCase().encode(readHashBytesFromFile(myDirStateFile));
}
catch (IOException e) {
// dirState exists if not fresh, if we could not load dirState info repository must be corrupted
@@ -325,6 +325,11 @@ public class JUnitConfiguration extends JavaTestConfigurationBase {
return getPersistentData().getScope();
}
@Override
public void setSearchScope(TestSearchScope searchScope) {
getPersistentData().setScope(searchScope);
}
public void beFromSourcePosition(PsiLocation<PsiMethod> sourceLocation) {
myData.setTestMethod(sourceLocation);
myData.TEST_OBJECT = BY_SOURCE_POSITION;
@@ -109,6 +109,17 @@ public class TaskManagerTest extends TaskManagerTestCase {
assertTrue(repositories[0].isShared());
}
public void testRemoveShared() {
TaskRepository repository = new YouTrackRepository(new YouTrackRepositoryType());
repository.setShared(true);
myTaskManager.setRepositories(Collections.singletonList(repository));
myTaskManager.setRepositories(Collections.emptyList());
TaskProjectConfiguration configuration = ServiceManager.getService(getProject(), TaskProjectConfiguration.class);
assertEquals(0, configuration.getState().servers.size());
}
public void testIssuesCacheSurvival() {
final Ref<Boolean> stopper = new Ref<>(Boolean.FALSE);
TestRepository repository = new TestRepository(new LocalTaskImpl("foo", "bar")) {
@@ -221,6 +221,11 @@ public class TestNGConfiguration extends JavaTestConfigurationBase {
return getPersistantData().getScope();
}
@Override
public void setSearchScope(TestSearchScope searchScope) {
getPersistantData().setScope(searchScope);
}
public void setPackageConfiguration(Module module, PsiPackage pkg) {
data.setPackage(pkg);
setModule(module);