diff --git a/RegExpSupport/src/org/intellij/lang/regexp/inspection/SingleCharAlternationInspection.java b/RegExpSupport/src/org/intellij/lang/regexp/inspection/SingleCharAlternationInspection.java index ef981cea5c37..2027351f6fd1 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/inspection/SingleCharAlternationInspection.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/inspection/SingleCharAlternationInspection.java @@ -28,6 +28,8 @@ import org.intellij.lang.regexp.psi.*; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; +import java.util.stream.Stream; + /** * @author Bas Leijdekkers */ @@ -60,17 +62,19 @@ public class SingleCharAlternationInspection extends LocalInspectionTool { if (branches.length < 2) { return; } - for (RegExpBranch branch : branches) { - final RegExpAtom[] atoms = branch.getAtoms(); - if (atoms.length != 1 || !(atoms[0] instanceof RegExpChar)) { - return; - } + if (!Stream.of(branches).allMatch(SingleCharAlternationVisitor::isSingleChar)) { + return; } final String text = buildReplacementText(pattern); //noinspection DialogTitleCapitalization myHolder.registerProblem(pattern, "Single character alternation in RegExp", new SingleCharAlternationFix(text)); } + private static boolean isSingleChar(RegExpBranch branch) { + final RegExpAtom[] atoms = branch.getAtoms(); + return atoms.length == 1 && atoms[0] instanceof RegExpChar; + } + private static class SingleCharAlternationFix implements LocalQuickFix { private final String myText; diff --git a/build/dependencies/gradle.properties b/build/dependencies/gradle.properties index 285b865d0488..512b8b26ec8c 100644 --- a/build/dependencies/gradle.properties +++ b/build/dependencies/gradle.properties @@ -1,5 +1,5 @@ #The file might be automatically updated. Comments and empty lines will be removed. -#Mon Apr 10 12:16:24 MSK 2017 +#Thu Apr 13 15:04:25 MSK 2017 kotlinPluginBuild=1.1.2-eap-69-IJ2017.2-1:EAP-1.1 jetSignBuild=42.30 -jdkBuild=u152b819.1 +jdkBuild=u152b819.2 diff --git a/build/dependencies/setupJbre.gradle b/build/dependencies/setupJbre.gradle index d3235c4595d9..e9501e9b04e5 100644 --- a/build/dependencies/setupJbre.gradle +++ b/build/dependencies/setupJbre.gradle @@ -47,7 +47,12 @@ jrePlatformsToDownload(targetOs).each { platform -> doFirst { exec { commandLine 'mkdir', '-p', outputDir } } commandLine 'tar', '-xpf', "${downloadOutputs.singleFile.absolutePath}", '--directory', outputDir if (platform != 'osx') { - doLast { exec { commandLine 'mv', "$outputDir/lib/tools.jar", "$outputDir/jre/lib/" } } + doLast { + exec { + commandLine 'mv', "$outputDir/lib/tools.jar", "$outputDir/jre/lib/" + ignoreExitValue = true + } + } } } } diff --git a/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy b/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy index 3d57da02980a..f4652f52fd13 100644 --- a/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy +++ b/build/groovy/org/jetbrains/intellij/build/BaseIdeaProperties.groovy @@ -117,7 +117,7 @@ abstract class BaseIdeaProperties extends ProductProperties { } } context.ant.copy(todir: "$targetDirectory/plugins/Kotlin") { - fileset(dir: "$context.paths.communityHome/build/dependencies/build/kotlin/Kotlin") + fileset(dir: "$context.paths.kotlinHome") } context.ant.move(file: "$targetDirectory/lib/annotations-java8.jar", tofile: "$targetDirectory/redist/annotations-java8.jar") } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java index cefa3cecfef7..2e830e3d6013 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnBoxingEvaluator.java @@ -15,16 +15,14 @@ */ package com.intellij.debugger.engine.evaluation.expression; -import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Couple; import com.intellij.psi.CommonClassNames; +import com.intellij.psi.impl.PsiJavaParserFacadeImpl; import com.intellij.util.containers.HashMap; -import com.sun.jdi.ClassType; -import com.sun.jdi.Method; -import com.sun.jdi.ObjectReference; -import com.sun.jdi.Value; +import com.sun.jdi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,7 +33,9 @@ import java.util.Map; * @author Eugene Zhuravlev * Date: Feb 8, 2010 */ -public class UnBoxingEvaluator implements Evaluator{ +public class UnBoxingEvaluator implements Evaluator { + private static final Logger LOG = Logger.getInstance(UnBoxingEvaluator.class); + private final Evaluator myOperand; private static final Map> TYPES_TO_CONVERSION_METHOD_MAP = new HashMap<>(); static { @@ -77,14 +77,32 @@ public class UnBoxingEvaluator implements Evaluator{ private static Value convertToPrimitive(EvaluationContextImpl context, ObjectReference value, final String conversionMethodName, String conversionMethodSignature) throws EvaluateException { - final DebugProcessImpl process = context.getDebugProcess(); - final ClassType wrapperClass = (ClassType)value.referenceType(); - Method method = wrapperClass.concreteMethodByName(conversionMethodName, conversionMethodSignature); + // for speedup first try value field + Value primitiveValue = getInnerPrimitiveValue(value); + if (primitiveValue != null) { + return primitiveValue; + } + + Method method = ((ClassType)value.referenceType()).concreteMethodByName(conversionMethodName, conversionMethodSignature); if (method == null) { throw new EvaluateException("Cannot convert to primitive value of type " + value.type() + ": Unable to find method " + conversionMethodName + conversionMethodSignature); } - return process.invokeMethod(context, value, method, Collections.emptyList()); + return context.getDebugProcess().invokeMethod(context, value, method, Collections.emptyList()); + } + + @Nullable + public static PrimitiveValue getInnerPrimitiveValue(ObjectReference value) { + ReferenceType type = value.referenceType(); + Field valueField = type.fieldByName("value"); + if (valueField != null) { + Value primitiveValue = value.getValue(valueField); + if (primitiveValue instanceof PrimitiveValue) { + LOG.assertTrue(type.name().equals(PsiJavaParserFacadeImpl.getPrimitiveType(primitiveValue.type().name()).getBoxedTypeName())); + return (PrimitiveValue)primitiveValue; + } + } + return null; } } \ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/UnboxableTypeRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/UnboxableTypeRenderer.java new file mode 100644 index 000000000000..a76516600258 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/UnboxableTypeRenderer.java @@ -0,0 +1,99 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.ui.tree.render; + +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.engine.evaluation.expression.UnBoxingEvaluator; +import com.intellij.debugger.settings.NodeRendererSettings; +import com.intellij.debugger.ui.tree.ValueDescriptor; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.CommonClassNames; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.ReferenceType; +import com.sun.jdi.Type; + +/** + * @author egor + */ +public abstract class UnboxableTypeRenderer extends CompoundReferenceRenderer { + public UnboxableTypeRenderer(String className, NodeRendererSettings rendererSettings) { + super(rendererSettings, StringUtil.getShortName(className), new LabelRenderer() { + @Override + public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) + throws EvaluateException { + return DebuggerUtils.getValueAsString(evaluationContext, UnBoxingEvaluator.getInnerPrimitiveValue((ObjectReference)descriptor.getValue())); + } + }, null); + LOG.assertTrue(UnBoxingEvaluator.isTypeUnboxable(className)); + setClassName(className); + setEnabled(true); + } + + @Override + public boolean isApplicable(Type type) { + return type instanceof ReferenceType && StringUtil.equals(type.name(), getClassName()); + } + + public static class BooleanRenderer extends UnboxableTypeRenderer { + public BooleanRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_BOOLEAN, rendererSettings); + } + } + + public static class ByteRenderer extends UnboxableTypeRenderer { + public ByteRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_BYTE, rendererSettings); + } + } + + public static class CharacterRenderer extends UnboxableTypeRenderer { + public CharacterRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_CHARACTER, rendererSettings); + } + } + + public static class ShortRenderer extends UnboxableTypeRenderer { + public ShortRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_SHORT, rendererSettings); + } + } + + public static class IntegerRenderer extends UnboxableTypeRenderer { + public IntegerRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_INTEGER, rendererSettings); + } + } + + public static class LongRenderer extends UnboxableTypeRenderer { + public LongRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_LONG, rendererSettings); + } + } + + public static class FloatRenderer extends UnboxableTypeRenderer { + public FloatRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_FLOAT, rendererSettings); + } + } + + public static class DoubleRenderer extends UnboxableTypeRenderer { + public DoubleRenderer(NodeRendererSettings rendererSettings) { + super(CommonClassNames.JAVA_LANG_DOUBLE, rendererSettings); + } + } +} diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java index ef55ee92e099..a48a908d6c4c 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java @@ -72,20 +72,19 @@ public abstract class DebuggerUtils { return ((StringReference)value).value(); } if (isInteger(value)) { - long v = ((PrimitiveValue)value).longValue(); - return String.valueOf(v); + return String.valueOf(((PrimitiveValue)value).longValue()); } - if (isNumeric(value)) { - double v = ((PrimitiveValue)value).doubleValue(); - return String.valueOf(v); + if (value instanceof FloatValue) { + return String.valueOf(((FloatValue)value).floatValue()); + } + if (value instanceof DoubleValue) { + return String.valueOf(((DoubleValue)value).doubleValue()); } if (value instanceof BooleanValue) { - boolean v = ((PrimitiveValue)value).booleanValue(); - return String.valueOf(v); + return String.valueOf(((PrimitiveValue)value).booleanValue()); } if (value instanceof CharValue) { - char v = ((PrimitiveValue)value).charValue(); - return String.valueOf(v); + return String.valueOf(((PrimitiveValue)value).charValue()); } if (value instanceof ObjectReference) { if (value instanceof ArrayReference) { diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java index 2fa79311b8c6..91bcef935b00 100644 --- a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java +++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java @@ -219,7 +219,7 @@ public class JUnitUtil { return false; } - public static boolean isJUnit5TestClass(final PsiClass psiClass, boolean checkAbstract) { + public static boolean isJUnit5TestClass(@NotNull final PsiClass psiClass, boolean checkAbstract) { final PsiModifierList modifierList = psiClass.getModifierList(); if (modifierList == null) return false; diff --git a/java/idea-ui/src/com/intellij/jarRepository/JarRepositoryManager.java b/java/idea-ui/src/com/intellij/jarRepository/JarRepositoryManager.java index 1ee2fe74f79e..55e5fbbb9487 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/JarRepositoryManager.java +++ b/java/idea-ui/src/com/intellij/jarRepository/JarRepositoryManager.java @@ -42,7 +42,6 @@ import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.util.PairProcessor; import com.intellij.util.Processor; import com.intellij.util.concurrency.SequentialTaskExecutor; import gnu.trove.THashMap; @@ -67,7 +66,6 @@ import java.util.*; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; @@ -96,13 +94,14 @@ public class JarRepositoryManager { return null; } - final List repositories = dialog.getRepositories(); final String coord = dialog.getCoordinateText(); final boolean attachSources = dialog.getAttachSources(); final boolean attachJavaDoc = dialog.getAttachJavaDoc(); final String copyTo = dialog.getDirectoryPath(); - final NewLibraryConfiguration config = resolveAndDownload(project, coord, attachSources, attachJavaDoc, copyTo, repositories); + final NewLibraryConfiguration config = resolveAndDownload( + project, coord, attachSources, attachJavaDoc, copyTo, RemoteRepositoryDescription.DEFAULT_REPOSITORIES + ); if (config == null) { Messages.showErrorDialog(parentComponent, "No files were downloaded for " + coord, CommonBundle.getErrorTitle()); } @@ -277,7 +276,7 @@ public class JarRepositoryManager { Notifications.Bus.notify(new Notification("Repository", title, sb.toString(), NotificationType.INFORMATION), project); } - public static void searchArtifacts(final Project project, String coord, final PairProcessor>, Boolean> resultProcessor) { + public static void searchArtifacts(final Project project, String coord, final Consumer>> resultProcessor) { if (coord == null || coord.length() == 0) { return; } @@ -291,30 +290,18 @@ public class JarRepositoryManager { ProgressManager.getInstance().run(new Task.Backgroundable(project, "Maven", false) { public void run(@NotNull ProgressIndicator indicator) { - String[] urls = MavenRepositoryServicesManager.getServiceUrls(); - boolean tooManyResults = false; - final AtomicBoolean proceedFlag = new AtomicBoolean(true); - - for (int i = 0, length = urls.length; i < length; i++) { - if (!proceedFlag.get()) break; - final List> resultList = new ArrayList<>(); - try { - String serviceUrl = urls[i]; - final List artifacts = MavenRepositoryServicesManager.findArtifacts(template, serviceUrl); - if (!artifacts.isEmpty()) { - if (!proceedFlag.get()) { - break; - } - final List repositories = MavenRepositoryServicesManager.getRepositories(serviceUrl); - Map map = new THashMap<>(); - for (RemoteRepositoryDescription repository : repositories) { - map.put(repository.getId(), repository); - } - for (RepositoryArtifactDescription artifact : artifacts) { - if (artifact == null) { - tooManyResults = true; + final List> resultList = new ArrayList<>(); + try { + for (String serviceUrl : MavenRepositoryServicesManager.getServiceUrls()) { + try { + final List artifacts = MavenRepositoryServicesManager.findArtifacts(template, serviceUrl); + if (!artifacts.isEmpty()) { + final List repositories = MavenRepositoryServicesManager.getRepositories(serviceUrl); + final Map map = new THashMap<>(); + for (RemoteRepositoryDescription repository : repositories) { + map.put(repository.getId(), repository); } - else { + for (RepositoryArtifactDescription artifact : artifacts) { final RemoteRepositoryDescription repository = map.get(artifact.getRepositoryId()); // if the artifact is provided by an unsupported repository just skip it // because it won't be resolved anyway @@ -324,38 +311,32 @@ public class JarRepositoryManager { } } } - } - catch (Exception e) { - LOG.error(e); - } - finally { - if (!proceedFlag.get()) { - break; + catch (Exception e) { + LOG.error(e); } - final Boolean aBoolean = i == length - 1 ? tooManyResults : null; - ApplicationManager.getApplication().invokeLater( - () -> proceedFlag.set(resultProcessor.process(resultList, aBoolean)), o -> !proceedFlag.get() - ); } } + finally { + ApplicationManager.getApplication().invokeLater(() -> resultProcessor.accept(resultList)); + } } }); } - public static void searchRepositories(final Project project, final Collection nexusUrls, final Processor> resultProcessor) { + public static void searchRepositories(final Project project, final Collection serviceUrls, final Processor> resultProcessor) { ProgressManager.getInstance().run(new Task.Backgroundable(project, "Maven", false) { public void run(@NotNull ProgressIndicator indicator) { final Ref> result = Ref.create(Collections.emptyList()); try { final ArrayList repoList = new ArrayList<>(); - for (String nexusUrl : nexusUrls) { + for (String url : serviceUrls) { final List repositories; try { - repositories = MavenRepositoryServicesManager.getRepositories(nexusUrl); + repositories = MavenRepositoryServicesManager.getRepositories(url); } catch (Exception ex) { - LOG.warn("Accessing Service at: " + nexusUrl, ex); + LOG.warn("Accessing Service at: " + url, ex); continue; } repoList.addAll(repositories); diff --git a/java/idea-ui/src/com/intellij/jarRepository/RepositoryAddLibraryAction.java b/java/idea-ui/src/com/intellij/jarRepository/RepositoryAddLibraryAction.java index ef1812cd53ac..49a33579308e 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/RepositoryAddLibraryAction.java +++ b/java/idea-ui/src/com/intellij/jarRepository/RepositoryAddLibraryAction.java @@ -16,7 +16,7 @@ package com.intellij.jarRepository; import com.intellij.codeInspection.IntentionAndQuickFixAction; -import com.intellij.jarRepository.propertiesEditor.RepositoryLibraryPropertiesDialog; +import com.intellij.jarRepository.settings.RepositoryLibraryPropertiesDialog; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; diff --git a/java/idea-ui/src/com/intellij/jarRepository/RepositoryAttachDialog.java b/java/idea-ui/src/com/intellij/jarRepository/RepositoryAttachDialog.java index e9ae84194e41..7065d88883c4 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/RepositoryAttachDialog.java +++ b/java/idea-ui/src/com/intellij/jarRepository/RepositoryAttachDialog.java @@ -27,7 +27,6 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.ui.ValidationInfo; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; @@ -56,8 +55,10 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.Map; public class RepositoryAttachDialog extends DialogWrapper { @NonNls private static final String PROPERTY_DOWNLOAD_TO_PATH = "Downloaded.Files.Path"; @@ -79,8 +80,7 @@ public class RepositoryAttachDialog extends DialogWrapper { private final JComboBox myCombobox; - private final Map> myCoordinates = ContainerUtil.newTroveMap(); - private final Map myRepositories = new TreeMap<>(); + private final Map myCoordinates = ContainerUtil.newTroveMap(); private final List myShownItems = ContainerUtil.newArrayList(); private final String myDefaultDownloadFolder; @@ -203,7 +203,9 @@ public class RepositoryAttachDialog extends DialogWrapper { main: for (String coordinate : myCoordinates.keySet()) { for (String part : parts) { - if (!StringUtil.containsIgnoreCase(coordinate, part)) continue main; + if (!StringUtil.containsIgnoreCase(coordinate, part)) { + continue main; + } } myShownItems.add(coordinate); } @@ -267,41 +269,22 @@ public class RepositoryAttachDialog extends DialogWrapper { private boolean performSearch() { final String text = getCoordinateText(); - if (StringUtil.isEmptyOrSpaces(text)) return false; - if (myCoordinates.containsKey(text)) return false; - if (myProgressIcon.isRunning()) return false; + if (myProgressIcon.isRunning() || StringUtil.isEmptyOrSpaces(text) || myCoordinates.containsKey(text)) { + return false; + } myProgressIcon.resume(); - JarRepositoryManager.searchArtifacts(myProject, text, (artifacts, tooMany) -> { + JarRepositoryManager.searchArtifacts(myProject, text, (pairs) -> { if (myProgressIcon.isDisposed()) { - return false; - } - if (tooMany != null) { - myProgressIcon.suspend(); // finished + return; } + myProgressIcon.suspend(); // finished final int prevSize = myCoordinates.size(); - for (Pair each : artifacts) { - myCoordinates.put(each.first.getGroupId() + ":" + each.first.getArtifactId() + ":" + each.first.getVersion(), each); - String url = each.second != null? each.second.getUrl() : null; - if (StringUtil.isNotEmpty(url) && !myRepositories.containsKey(url)) { - myRepositories.put(url, each.second); - } - } - String title = getTitle(); - String tooManyMessage = ": too many results found"; - if (tooMany != null) { - boolean alreadyThere = title.endsWith(tooManyMessage); - if (tooMany.booleanValue() && !alreadyThere) { - setTitle(title + tooManyMessage); - } - else if (!tooMany.booleanValue() && alreadyThere) { - setTitle(title.substring(0, title.length() - tooManyMessage.length())); - } + for (Pair pair : pairs) { + final RepositoryArtifactDescription artifact = pair.first; + myCoordinates.put(artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(), artifact); } updateComboboxSelection(prevSize != myCoordinates.size()); - // tooMany != null on last call, so enable OK action to let - // local maven repo a chance even if all remote services failed - setOKActionEnabled(!myRepositories.isEmpty() || tooMany != null); - return true; + setOKActionEnabled(true); }); return true; } @@ -352,13 +335,6 @@ public class RepositoryAttachDialog extends DialogWrapper { return RepositoryAttachDialog.class.getName(); } - @NotNull - public List getRepositories() { - final Pair artifactAndRepo = myCoordinates.get(getCoordinateText()); - final RemoteRepositoryDescription repository = artifactAndRepo == null ? null : artifactAndRepo.second; - return repository != null ? Collections.singletonList(repository) : ContainerUtil.findAll(myRepositories.values(), Condition.NOT_NULL); - } - private boolean isValidCoordinateSelected() { final String text = getCoordinateText(); return text.split(":").length == 3; diff --git a/java/idea-ui/src/com/intellij/jarRepository/RepositoryLibrarySupportInModuleConfigurable.java b/java/idea-ui/src/com/intellij/jarRepository/RepositoryLibrarySupportInModuleConfigurable.java index bf6f57a1a1f4..b4a66448c248 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/RepositoryLibrarySupportInModuleConfigurable.java +++ b/java/idea-ui/src/com/intellij/jarRepository/RepositoryLibrarySupportInModuleConfigurable.java @@ -16,7 +16,7 @@ package com.intellij.jarRepository; import com.intellij.framework.addSupport.FrameworkSupportInModuleConfigurable; -import com.intellij.jarRepository.propertiesEditor.RepositoryLibraryPropertiesEditor; +import com.intellij.jarRepository.settings.RepositoryLibraryPropertiesEditor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModifiableModelsProvider; diff --git a/java/idea-ui/src/com/intellij/jarRepository/RepositoryLibraryWithDescriptionEditor.java b/java/idea-ui/src/com/intellij/jarRepository/RepositoryLibraryWithDescriptionEditor.java index ffee1c12e1a1..5c99fdc7928f 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/RepositoryLibraryWithDescriptionEditor.java +++ b/java/idea-ui/src/com/intellij/jarRepository/RepositoryLibraryWithDescriptionEditor.java @@ -15,7 +15,7 @@ */ package com.intellij.jarRepository; -import com.intellij.jarRepository.propertiesEditor.RepositoryLibraryPropertiesDialog; +import com.intellij.jarRepository.settings.RepositoryLibraryPropertiesDialog; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent; import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor; diff --git a/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesDialog.java b/java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesDialog.java similarity index 97% rename from java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesDialog.java rename to java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesDialog.java index d2d966ce58ef..601024874e7f 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesDialog.java +++ b/java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesDialog.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.jarRepository.propertiesEditor; +package com.intellij.jarRepository.settings; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; diff --git a/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.form b/java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesEditor.form similarity index 99% rename from java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.form rename to java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesEditor.form index 3059e22370da..cb1f7a895be3 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.form +++ b/java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesEditor.form @@ -1,5 +1,5 @@ -
+ diff --git a/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.java b/java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesEditor.java similarity index 99% rename from java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.java rename to java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesEditor.java index da1a579d765e..d4765db18b1f 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.java +++ b/java/idea-ui/src/com/intellij/jarRepository/settings/RepositoryLibraryPropertiesEditor.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.jarRepository.propertiesEditor; +package com.intellij.jarRepository.settings; import com.google.common.base.Strings; import com.intellij.jarRepository.JarRepositoryManager; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/HData.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/HData.java index f6f56da72dbc..6e77aa820636 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/HData.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/HData.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection.bytecodeAnalysis; +import com.intellij.util.ArrayFactory; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -90,6 +91,8 @@ final class HKey { * Represents a lattice product of a constant {@link #value} and all {@link #ids}. */ final class HComponent { + static final HComponent[] EMPTY_ARRAY = new HComponent[0]; + static final ArrayFactory ARRAY_FACTORY = count -> count == 0 ? EMPTY_ARRAY : new HComponent[count]; @NotNull Value value; @NotNull final HKey[] ids; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java index 79d8e339a27a..28b3753c2c42 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/Solver.java @@ -15,7 +15,6 @@ */ package com.intellij.codeInspection.bytecodeAnalysis; -import com.intellij.util.ArrayFactory; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException; @@ -101,7 +100,6 @@ class ResultUtil { class HResultUtil { private static final HKey[] EMPTY_PRODUCT = new HKey[0]; - private static final ArrayFactory HCOMPONENT_ARRAY_FACTORY = count -> new HComponent[count]; private final ELattice lattice; final Value top; @@ -138,7 +136,7 @@ class HResultUtil { } HPending pending1 = (HPending) r1; HPending pending2 = (HPending) r2; - return new HPending(ArrayUtil.mergeArrays(pending1.delta, pending2.delta, HCOMPONENT_ARRAY_FACTORY)); + return new HPending(ArrayUtil.mergeArrays(pending1.delta, pending2.delta, HComponent.ARRAY_FACTORY)); } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java index b4aa6c0f0f11..b78102907e7d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalInspection.java @@ -39,8 +39,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import java.awt.*; public class CanBeFinalInspection extends GlobalJavaBatchInspectionTool { @@ -70,34 +68,19 @@ public class CanBeFinalInspection extends GlobalJavaBatchInspectionTool { myReportClassesCheckbox = new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option")); myReportClassesCheckbox.setSelected(REPORT_CLASSES); - myReportClassesCheckbox.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_CLASSES = myReportClassesCheckbox.isSelected(); - } - }); + myReportClassesCheckbox.getModel().addItemListener(e -> REPORT_CLASSES = myReportClassesCheckbox.isSelected()); gc.gridy = 0; add(myReportClassesCheckbox, gc); myReportMethodsCheckbox = new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option1")); myReportMethodsCheckbox.setSelected(REPORT_METHODS); - myReportMethodsCheckbox.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_METHODS = myReportMethodsCheckbox.isSelected(); - } - }); + myReportMethodsCheckbox.getModel().addItemListener(e -> REPORT_METHODS = myReportMethodsCheckbox.isSelected()); gc.gridy++; add(myReportMethodsCheckbox, gc); myReportFieldsCheckbox = new JCheckBox(InspectionsBundle.message("inspection.can.be.final.option2")); myReportFieldsCheckbox.setSelected(REPORT_FIELDS); - myReportFieldsCheckbox.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_FIELDS = myReportFieldsCheckbox.isSelected(); - } - }); + myReportFieldsCheckbox.getModel().addItemListener(e -> REPORT_FIELDS = myReportFieldsCheckbox.isSelected()); gc.weighty = 1; gc.gridy++; diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java index 9d62dc7685ac..986d72a86368 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java @@ -155,21 +155,21 @@ public class DefUseInspectionBase extends BaseJavaBatchLocalInspectionTool { myReportInitializer = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option2")); myReportInitializer.setSelected(REPORT_REDUNDANT_INITIALIZER); - myReportInitializer.getModel().addChangeListener(e -> REPORT_REDUNDANT_INITIALIZER = myReportInitializer.isSelected()); + myReportInitializer.getModel().addItemListener(e -> REPORT_REDUNDANT_INITIALIZER = myReportInitializer.isSelected()); gc.insets = JBUI.insetsBottom(15); gc.gridy = 0; add(myReportInitializer, gc); myReportPrefix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option")); myReportPrefix.setSelected(REPORT_PREFIX_EXPRESSIONS); - myReportPrefix.getModel().addChangeListener(e -> REPORT_PREFIX_EXPRESSIONS = myReportPrefix.isSelected()); + myReportPrefix.getModel().addItemListener(e -> REPORT_PREFIX_EXPRESSIONS = myReportPrefix.isSelected()); gc.insets = JBUI.emptyInsets(); gc.gridy++; add(myReportPrefix, gc); myReportPostfix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option1")); myReportPostfix.setSelected(REPORT_POSTFIX_EXPRESSIONS); - myReportPostfix.getModel().addChangeListener(e -> REPORT_POSTFIX_EXPRESSIONS = myReportPostfix.isSelected()); + myReportPostfix.getModel().addItemListener(e -> REPORT_POSTFIX_EXPRESSIONS = myReportPostfix.isSelected()); gc.weighty = 1; gc.gridy++; add(myReportPostfix, gc); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaModuleImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaModuleImpl.java index 69d8ff16e6ca..e3273c4b553d 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaModuleImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaModuleImpl.java @@ -18,6 +18,7 @@ package com.intellij.codeInspection.reference; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.psi.*; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,7 +44,7 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule { @Override protected void initialize() { - + ((RefModuleImpl)myRefModule).add(this); } @Override @@ -115,7 +116,35 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule { } } } - ((RefModuleImpl)myRefModule).add(this); + for (PsiProvidesStatement statement : javaModule.getProvides()) { + final PsiJavaCodeReferenceElement interfaceReference = statement.getInterfaceReference(); + final PsiReferenceList implementationList = statement.getImplementationList(); + if (interfaceReference != null && implementationList != null) { + final PsiElement providerInterface = interfaceReference.resolve(); + if (providerInterface instanceof PsiClass) { + final RefElement refInterface = getRefManager().getReference(providerInterface); + if (refInterface instanceof RefJavaElementImpl) { + for (PsiJavaCodeReferenceElement implementationReference : implementationList.getReferenceElements()) { + final PsiElement implementationClass = implementationReference.resolve(); + if (implementationClass instanceof PsiClass) { + PsiElement targetElement = getProviderMethod((PsiClass)implementationClass); + if (targetElement == null) { + targetElement = getDefaultConstructor((PsiClass)implementationClass); + if (targetElement == null) { + targetElement = implementationClass; + } + } + final RefElement refTargetElement = getRefManager().getReference(targetElement); + if (refTargetElement != null) { + ((RefJavaElementImpl)refInterface) + .addReference(refTargetElement, targetElement, providerInterface, false, true, null); + } + } + } + } + } + } + } getRefManager().fireBuildReferences(this); } } @@ -150,4 +179,19 @@ public class RefJavaModuleImpl extends RefElementImpl implements RefJavaModule { } return !exportedPackages.isEmpty() ? exportedPackages : Collections.emptyMap(); } + + @Nullable + private static PsiMethod getProviderMethod(@NotNull PsiClass psiClass) { + final PsiMethod[] methods = psiClass.findMethodsByName("provider", false); + return ContainerUtil.find(methods, m -> m.hasModifierProperty(PsiModifier.PUBLIC) && + m.hasModifierProperty(PsiModifier.STATIC) && + m.getParameterList().getParametersCount() == 0); + } + + @Nullable + private static PsiMethod getDefaultConstructor(@NotNull PsiClass psiClass) { + final PsiMethod[] constructors = psiClass.getConstructors(); + return ContainerUtil.find(constructors, m -> m.hasModifierProperty(PsiModifier.PUBLIC) && + m.getParameterList().getParametersCount() == 0); + } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java index d6de5a38b1e9..071a8610b18a 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/VisibilityInspection.java @@ -84,7 +84,7 @@ public class VisibilityInspection extends GlobalJavaBatchInspectionTool { myPackageLocalForMembersCheckbox = new JCheckBox(InspectionsBundle.message("inspection.visibility.option")); myPackageLocalForMembersCheckbox.setSelected(SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS); - myPackageLocalForMembersCheckbox.getModel().addChangeListener( + myPackageLocalForMembersCheckbox.getModel().addItemListener( e -> SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS = myPackageLocalForMembersCheckbox.isSelected()); gc.gridy = 0; @@ -92,7 +92,7 @@ public class VisibilityInspection extends GlobalJavaBatchInspectionTool { myPackageLocalForTopClassesCheckbox = new JCheckBox(InspectionsBundle.message("inspection.visibility.option1")); myPackageLocalForTopClassesCheckbox.setSelected(SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES); - myPackageLocalForTopClassesCheckbox.getModel().addChangeListener( + myPackageLocalForTopClassesCheckbox.getModel().addItemListener( e -> SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES = myPackageLocalForTopClassesCheckbox.isSelected()); gc.gridy = 1; @@ -101,7 +101,7 @@ public class VisibilityInspection extends GlobalJavaBatchInspectionTool { myPrivateForInnersCheckbox = new JCheckBox(InspectionsBundle.message("inspection.visibility.option2")); myPrivateForInnersCheckbox.setSelected(SUGGEST_PRIVATE_FOR_INNERS); - myPrivateForInnersCheckbox.getModel().addChangeListener(e -> SUGGEST_PRIVATE_FOR_INNERS = myPrivateForInnersCheckbox.isSelected()); + myPrivateForInnersCheckbox.getModel().addItemListener(e -> SUGGEST_PRIVATE_FOR_INNERS = myPrivateForInnersCheckbox.isSelected()); gc.gridy = 2; add(myPrivateForInnersCheckbox, gc); diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java index 8a102e458e5a..f0f90b1c88b2 100644 --- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java @@ -25,8 +25,6 @@ import com.intellij.util.ui.JBUI; import com.siyeh.ig.fixes.IntroduceVariableFix; import javax.swing.*; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; import java.awt.*; import java.util.List; @@ -90,76 +88,39 @@ public class DataFlowInspection extends DataFlowInspectionBase { mySuggestNullables = new JCheckBox( InspectionsBundle.message("inspection.data.flow.nullable.quickfix.option")); mySuggestNullables.setSelected(SUGGEST_NULLABLE_ANNOTATIONS); - mySuggestNullables.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - SUGGEST_NULLABLE_ANNOTATIONS = mySuggestNullables.isSelected(); - } - }); + mySuggestNullables.getModel().addItemListener(e -> SUGGEST_NULLABLE_ANNOTATIONS = mySuggestNullables.isSelected()); myDontReportTrueAsserts = new JCheckBox( InspectionsBundle.message("inspection.data.flow.true.asserts.option")); myDontReportTrueAsserts.setSelected(DONT_REPORT_TRUE_ASSERT_STATEMENTS); - myDontReportTrueAsserts.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - DONT_REPORT_TRUE_ASSERT_STATEMENTS = myDontReportTrueAsserts.isSelected(); - } - }); + myDontReportTrueAsserts.getModel().addItemListener(e -> DONT_REPORT_TRUE_ASSERT_STATEMENTS = myDontReportTrueAsserts.isSelected()); myIgnoreAssertions = new JCheckBox("Ignore assert statements"); myIgnoreAssertions.setSelected(IGNORE_ASSERT_STATEMENTS); - myIgnoreAssertions.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - IGNORE_ASSERT_STATEMENTS = myIgnoreAssertions.isSelected(); - } - }); + myIgnoreAssertions.getModel().addItemListener(e -> IGNORE_ASSERT_STATEMENTS = myIgnoreAssertions.isSelected()); myReportConstantReferences = new JCheckBox("Warn when reading a value guaranteed to be constant"); myReportConstantReferences.setSelected(REPORT_CONSTANT_REFERENCE_VALUES); - myReportConstantReferences.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_CONSTANT_REFERENCE_VALUES = myReportConstantReferences.isSelected(); - } - }); + myReportConstantReferences.getModel().addItemListener( + e -> REPORT_CONSTANT_REFERENCE_VALUES = myReportConstantReferences.isSelected()); myTreatUnknownMembersAsNullable = new JCheckBox("Treat non-annotated members and parameters as @Nullable"); myTreatUnknownMembersAsNullable.setSelected(TREAT_UNKNOWN_MEMBERS_AS_NULLABLE); - myTreatUnknownMembersAsNullable.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - TREAT_UNKNOWN_MEMBERS_AS_NULLABLE = myTreatUnknownMembersAsNullable.isSelected(); - } - }); + myTreatUnknownMembersAsNullable.getModel().addItemListener( + e -> TREAT_UNKNOWN_MEMBERS_AS_NULLABLE = myTreatUnknownMembersAsNullable.isSelected()); myReportNullArguments = new JCheckBox("Report not-null required parameter with null-literal argument usages"); myReportNullArguments.setSelected(REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER); - myReportNullArguments.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER = myReportNullArguments.isSelected(); - } - }); + myReportNullArguments.getModel().addItemListener(e -> REPORT_NULLS_PASSED_TO_NOT_NULL_PARAMETER = myReportNullArguments.isSelected()); myReportNullableMethodsReturningNotNull = new JCheckBox("Report nullable methods that always return a non-null value"); myReportNullableMethodsReturningNotNull.setSelected(REPORT_NULLABLE_METHODS_RETURNING_NOT_NULL); - myReportNullableMethodsReturningNotNull.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_NULLABLE_METHODS_RETURNING_NOT_NULL = myReportNullableMethodsReturningNotNull.isSelected(); - } - }); + myReportNullableMethodsReturningNotNull.getModel().addItemListener( + e -> REPORT_NULLABLE_METHODS_RETURNING_NOT_NULL = myReportNullableMethodsReturningNotNull.isSelected()); myReportUncheckedOptionals = new JCheckBox("Report Optional.get() calls without previous isPresent check"); myReportUncheckedOptionals.setSelected(REPORT_UNCHECKED_OPTIONALS); - myReportUncheckedOptionals.getModel().addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - REPORT_UNCHECKED_OPTIONALS = myReportUncheckedOptionals.isSelected(); - } - }); + myReportUncheckedOptionals.getModel().addItemListener(e -> REPORT_UNCHECKED_OPTIONALS = myReportUncheckedOptionals.isSelected()); gc.insets = JBUI.emptyInsets(); gc.gridy = 0; diff --git a/java/java-impl/src/com/intellij/jarRepository/services/nexus/NexusRepositoryService.java b/java/java-impl/src/com/intellij/jarRepository/services/nexus/NexusRepositoryService.java index 2eb0f2c9bea1..10a7a785f619 100644 --- a/java/java-impl/src/com/intellij/jarRepository/services/nexus/NexusRepositoryService.java +++ b/java/java-impl/src/com/intellij/jarRepository/services/nexus/NexusRepositoryService.java @@ -98,7 +98,7 @@ public class NexusRepositoryService extends MavenRepositoryService { final SearchResults results = new Endpoint.DataIndex(url).getArtifactlistAsSearchResults( name, template.getGroupId(), template.getArtifactId(), template.getVersion(), null, template.getClassNames() ); - boolean tooManyResults = results.isTooManyResults(); + //boolean tooManyResults = results.isTooManyResults(); final SearchResults.Data data = results.getData(); final ArrayList result = new ArrayList<>(); if (data != null) { @@ -108,9 +108,9 @@ public class NexusRepositoryService extends MavenRepositoryService { } } } - if (tooManyResults) { - result.add(null); - } + //if (tooManyResults) { + // result.add(null); + //} return result; } catch (UnmarshalException e) { diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java index 4fe261b153de..f9edca96cfdf 100644 --- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesProcessor.java @@ -511,14 +511,14 @@ public class MoveClassesOrPackagesProcessor extends BaseRefactoringProcessor { myElementsToMove[idx] = element; } + myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); + for (PsiElement element : myElementsToMove) { if (element instanceof PsiClass) { MoveClassesOrPackagesUtil.finishMoveClass((PsiClass)element); } } - myNonCodeUsages = CommonMoveUtil.retargetUsages(usages, oldToNewElementsMapping); - if (myOpenInEditor) { EditorHelper.openFilesInEditor(myElementsToMove); } diff --git a/java/java-psi-api/src/com/intellij/psi/PsiClassType.java b/java/java-psi-api/src/com/intellij/psi/PsiClassType.java index 40715e11ffb9..ccd277dee6c8 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiClassType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiClassType.java @@ -31,7 +31,7 @@ import org.jetbrains.annotations.Nullable; */ public abstract class PsiClassType extends PsiType { public static final PsiClassType[] EMPTY_ARRAY = new PsiClassType[0]; - public static final ArrayFactory ARRAY_FACTORY = count -> new PsiClassType[count]; + public static final ArrayFactory ARRAY_FACTORY = count -> count == 0 ? EMPTY_ARRAY : new PsiClassType[count]; protected final LanguageLevel myLanguageLevel; @@ -289,7 +289,7 @@ public abstract class PsiClassType extends PsiType { }; } - public static abstract class Stub extends PsiClassType { + public abstract static class Stub extends PsiClassType { protected Stub(LanguageLevel languageLevel, @NotNull PsiAnnotation[] annotations) { super(languageLevel, annotations); } diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/constructor/MyServiceImpl.java b/java/java-tests/testData/inspection/unusedServiceImplementations/constructor/MyServiceImpl.java new file mode 100644 index 000000000000..2a507686b86f --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/constructor/MyServiceImpl.java @@ -0,0 +1,8 @@ +package my.impl; +import my.api.MyService; + +public class MyServiceImpl implements MyService { + public MyServiceImpl() {} + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/constructor/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/constructor/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/constructor/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/MyServiceExt.java new file mode 100644 index 000000000000..411a9b013a77 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/MyServiceExt.java @@ -0,0 +1,8 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt implements MyService { + public MyServiceExt() {} + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalConstructor/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/MyServiceExt.java new file mode 100644 index 000000000000..411a9b013a77 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/MyServiceExt.java @@ -0,0 +1,8 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt implements MyService { + public MyServiceExt() {} + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalImplementation/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/MyServiceExt.java new file mode 100644 index 000000000000..9f707509eee3 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/MyServiceExt.java @@ -0,0 +1,12 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt { + public static MyService provider() { + return new MyService() { + @Override + public void foo() { + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/externalProvider/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/implementation/MyServiceImpl.java b/java/java-tests/testData/inspection/unusedServiceImplementations/implementation/MyServiceImpl.java new file mode 100644 index 000000000000..0a3d1e4a0b63 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/implementation/MyServiceImpl.java @@ -0,0 +1,7 @@ +package my.impl; +import my.api.MyService; + +public class MyServiceImpl implements MyService { + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/implementation/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/implementation/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/implementation/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/provider/MyServiceImpl.java b/java/java-tests/testData/inspection/unusedServiceImplementations/provider/MyServiceImpl.java new file mode 100644 index 000000000000..0dcb7e99ce79 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/provider/MyServiceImpl.java @@ -0,0 +1,12 @@ +package my.impl; +import my.api.MyService; + +public class MyServiceImpl { + public static MyService provider() { + return new MyService() { + @Override + public void foo() { + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/provider/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/provider/expected.xml new file mode 100644 index 000000000000..5e933496b9cf --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/provider/expected.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/MyServiceImpl.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/MyServiceImpl.java new file mode 100644 index 000000000000..2a507686b86f --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/MyServiceImpl.java @@ -0,0 +1,8 @@ +package my.impl; +import my.api.MyService; + +public class MyServiceImpl implements MyService { + public MyServiceImpl() {} + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/expected.xml new file mode 100644 index 000000000000..ebefeeadcca9 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedConstructor/expected.xml @@ -0,0 +1,38 @@ + + + + MyServiceImpl.java + 5 + my.impl + + unused declaration + Constructor has usage(s) but they all belong to calls chain that has no members reachable from entry points. + + + + MyServiceImpl.java + 4 + my.impl + + unused declaration + Class has one instantiation but it is not reachable from entry points. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + + + MyService.java + 1 + my.api + + unused declaration + &nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/MyServiceExt.java new file mode 100644 index 000000000000..411a9b013a77 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/MyServiceExt.java @@ -0,0 +1,8 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt implements MyService { + public MyServiceExt() {} + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/expected.xml new file mode 100644 index 000000000000..decf67e8deb8 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalConstructor/expected.xml @@ -0,0 +1,38 @@ + + + + MyServiceExt.java + 5 + my.ext + + unused declaration + Constructor has usage(s) but they all belong to calls chain that has no members reachable from entry points. + + + + MyServiceExt.java + 4 + my.ext + + unused declaration + Class has one instantiation but it is not reachable from entry points. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + + + MyService.java + 1 + my.api + + unused declaration + &nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/MyServiceExt.java new file mode 100644 index 000000000000..443a299451f9 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/MyServiceExt.java @@ -0,0 +1,7 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt implements MyService { + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/expected.xml new file mode 100644 index 000000000000..4057c0b897a1 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalImplementation/expected.xml @@ -0,0 +1,20 @@ + + + + MyServiceExt.java + 4 + my.ext + + unused declaration + Class is not instantiated. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/MyServiceExt.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/MyServiceExt.java new file mode 100644 index 000000000000..9f707509eee3 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/MyServiceExt.java @@ -0,0 +1,12 @@ +package my.ext; +import my.api.MyService; + +public class MyServiceExt { + public static MyService provider() { + return new MyService() { + @Override + public void foo() { + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/expected.xml new file mode 100644 index 000000000000..c62bfe4b7c88 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedExternalProvider/expected.xml @@ -0,0 +1,29 @@ + + + + MyServiceExt.java + 5 + my.ext + + unused declaration + Method has one usage but it is not reachable from entry points. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + + + MyService.java + 1 + my.api + + unused declaration + &nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/MyServiceImpl.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/MyServiceImpl.java new file mode 100644 index 000000000000..0a3d1e4a0b63 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/MyServiceImpl.java @@ -0,0 +1,7 @@ +package my.impl; +import my.api.MyService; + +public class MyServiceImpl implements MyService { + @Override + public void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/expected.xml new file mode 100644 index 000000000000..0d81e05ee29e --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedImplementation/expected.xml @@ -0,0 +1,20 @@ + + + + MyServiceImpl.java + 4 + my.impl + + unused declaration + Class is not instantiated. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/MyServiceImpl.java b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/MyServiceImpl.java new file mode 100644 index 000000000000..0dcb7e99ce79 --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/MyServiceImpl.java @@ -0,0 +1,12 @@ +package my.impl; +import my.api.MyService; + +public class MyServiceImpl { + public static MyService provider() { + return new MyService() { + @Override + public void foo() { + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/expected.xml b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/expected.xml new file mode 100644 index 000000000000..a30bfd93dcce --- /dev/null +++ b/java/java-tests/testData/inspection/unusedServiceImplementations/unusedProvider/expected.xml @@ -0,0 +1,29 @@ + + + + MyServiceImpl.java + 5 + my.impl + + unused declaration + Method has one usage but it is not reachable from entry points. + + + + MyService.java + 1 + my.api + + unused declaration + <ul><li>Method owner class is never instantiated OR</li><li>An instantiation is not reachable from entry points.</li></ul> + + + + MyService.java + 1 + my.api + + unused declaration + &nbsp;Interface has an implementation but <ul><li>it is never instantiated OR</li><li>no instantiations are reachable from entry points.</li></ul> + + \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/B.java b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/B.java new file mode 100644 index 000000000000..d6457aef6e16 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/B.java @@ -0,0 +1,6 @@ +package b; + +import b.a.A; +public class B { + A aa; +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/C.java b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/C.java new file mode 100644 index 000000000000..beba5243f562 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/C.java @@ -0,0 +1,2 @@ +package b; +class C {} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/a/A.java b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/a/A.java new file mode 100644 index 000000000000..4cc1ad36b90a --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/after/b/a/A.java @@ -0,0 +1,2 @@ +package b.a; +public class A {} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/B.java b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/B.java new file mode 100644 index 000000000000..a17e968da5fa --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/B.java @@ -0,0 +1,4 @@ +import a.A; +public class B { + A aa; +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/a/A.java b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/a/A.java new file mode 100644 index 000000000000..c40d43155dc2 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/a/A.java @@ -0,0 +1,2 @@ +package a; +public class A {} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/b/C.java b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/b/C.java new file mode 100644 index 000000000000..beba5243f562 --- /dev/null +++ b/java/java-tests/testData/refactoring/movePackage/packageAndReferencedClass/before/b/C.java @@ -0,0 +1,2 @@ +package b; +class C {} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/Java9UnusedServiceImplementationsTest.kt b/java/java-tests/testSrc/com/intellij/codeInspection/Java9UnusedServiceImplementationsTest.kt new file mode 100644 index 000000000000..8a8be31ff7ef --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInspection/Java9UnusedServiceImplementationsTest.kt @@ -0,0 +1,114 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInspection + +import com.intellij.analysis.AnalysisScope +import com.intellij.openapi.application.ex.PathManagerEx +import com.intellij.openapi.module.ModuleManager +import com.intellij.openapi.roots.ModuleRootModificationUtil +import com.intellij.openapi.util.io.FileUtil +import com.intellij.testFramework.InspectionTestCase +import com.intellij.testFramework.InspectionTestUtil +import com.intellij.testFramework.createGlobalContextForTool +import com.intellij.testFramework.fixtures.LightJava9ModulesCodeInsightFixtureTestCase +import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor +import com.intellij.testFramework.fixtures.MultiModuleJava9ProjectDescriptor.ModuleDescriptor.* +import org.intellij.lang.annotations.Language + +/** + * @author Pavel.Dolgov + */ +class Java9UnusedServiceImplementationsTest : LightJava9ModulesCodeInsightFixtureTestCase() { + override fun getTestDataPath() = PathManagerEx.getTestDataPath() + "/inspection/unusedServiceImplementations/" + + override fun setUp() { + super.setUp() + + moduleInfo("module MAIN { requires API; }", MAIN) + + addFile("my/api/MyService.java", "package my.api; public interface MyService { void foo(); }", M2) + } + + fun testImplementation() = doTest() + + fun testConstructor() = doTest() + + fun testProvider() = doTest() + + fun testUnusedImplementation() = doTest(false) + + fun testUnusedConstructor() = doTest(false) + + fun testUnusedProvider() = doTest(false) + + fun testExternalImplementation() = doTest(sameModule = false) + + fun testExternalConstructor() = doTest(sameModule = false) + + fun testExternalProvider() = doTest(sameModule = false) + + fun testUnusedExternalImplementation() = doTest(false, sameModule = false) + + fun testUnusedExternalConstructor() = doTest(false, sameModule = false) + + fun testUnusedExternalProvider() = doTest(false, sameModule = false) + + + private fun doTest(withUsage: Boolean = true, sameModule: Boolean = true) { + @Language("JAVA") + val usageText = """ + import my.api.MyService; + public class MyApp { + public static void main(String[] args) { + for (MyService service : ServiceLoader.load(MyService.class)) { + service.foo(); + } + } + }""" + if (withUsage) addFile("my/app/MyApp.java", usageText, MAIN) + + if (sameModule) { + moduleInfo("module API { exports my.api; provides my.api.MyService with my.impl.MyServiceImpl; }", M2) + } + else { + val moduleManager = ModuleManager.getInstance(project) + val m2 = moduleManager.findModuleByName(M2.moduleName)!! + val m4 = moduleManager.findModuleByName(M4.moduleName)!! + ModuleRootModificationUtil.addDependency(m4, m2) + moduleInfo("module API { exports my.api; }", M2) + moduleInfo("module EXT { requires API; provides my.api.MyService with my.ext.MyServiceExt; }", M4) + } + + val testPath = testDataPath + "/" + getTestName(true) + val sourceFile = FileUtil.findFirstThatExist("$testPath/MyService${if (sameModule) "Impl" else "Ext"}.java") + assertNotNull("Test data: $testPath", sourceFile) + val implText = String(FileUtil.loadFileText(sourceFile!!)) + if (sameModule) + addFile("my/impl/MyServiceImpl.java", implText, M2) + else + addFile("my/ext/MyServiceExt.java", implText, M4) + + val toolWrapper = InspectionTestCase.getUnusedDeclarationWrapper() + val scope = AnalysisScope(project) + val globalContext = createGlobalContextForTool(scope, project, listOf(toolWrapper)) + InspectionTestUtil.runTool(toolWrapper, scope, globalContext) + InspectionTestUtil.compareToolResults(globalContext, toolWrapper, true, testPath) + } + + private fun moduleInfo(@Language("JAVA") moduleInfoText: String, descriptor: ModuleDescriptor) { + addFile("module-info.java", moduleInfoText, descriptor) + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MovePackageTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MovePackageTest.java index d60e7f0f90f4..caf741958725 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/MovePackageTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/MovePackageTest.java @@ -15,14 +15,16 @@ */ package com.intellij.refactoring; +import com.intellij.JavaTestUtil; import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiPackage; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassesOrPackagesProcessor; import com.intellij.refactoring.move.moveClassesOrPackages.SingleSourceRootMoveDestination; -import com.intellij.JavaTestUtil; import org.jetbrains.annotations.NotNull; public class MovePackageTest extends MultiFileTestCase { @@ -49,6 +51,12 @@ public class MovePackageTest extends MultiFileTestCase { doTest(new String[]{"a"}, "a.b"); } + public void testPackageAndReferencedClass() throws Exception { + Project project = myPsiManager.getProject(); + JavaPsiFacade facade = JavaPsiFacade.getInstance(project); + doTest((rootDir, rootAfter) -> performAction(new PsiElement[]{facade.findPackage("a"), facade.findClass("B", GlobalSearchScope.allScope(project))}, "b")); + } + @NotNull @Override protected String getTestRoot() { @@ -67,12 +75,16 @@ public class MovePackageTest extends MultiFileTestCase { assertNotNull("Package " + packageName + " not found", packages[i]); } + performAction(packages, newPackageName); + } + + private void performAction(PsiElement[] packagesAndClasses, String newPackageName) { PsiPackage newParentPackage = JavaPsiFacade.getInstance(myPsiManager.getProject()).findPackage(newPackageName); assertNotNull(newParentPackage); final PsiDirectory[] dirs = newParentPackage.getDirectories(); assertEquals(dirs.length, 1); - new MoveClassesOrPackagesProcessor(myProject, packages, + new MoveClassesOrPackagesProcessor(myProject, packagesAndClasses, new SingleSourceRootMoveDestination(PackageWrapper.create(newParentPackage), dirs[0]), true, false, null).run(); FileDocumentManager.getInstance().saveAllDocuments(); diff --git a/java/openapi/src/com/intellij/jarRepository/RemoteRepositoryDescription.java b/java/openapi/src/com/intellij/jarRepository/RemoteRepositoryDescription.java index 9988139d8c39..344ca732190c 100644 --- a/java/openapi/src/com/intellij/jarRepository/RemoteRepositoryDescription.java +++ b/java/openapi/src/com/intellij/jarRepository/RemoteRepositoryDescription.java @@ -28,7 +28,7 @@ public class RemoteRepositoryDescription { public static final RemoteRepositoryDescription MAVEN_CENTRAL = new RemoteRepositoryDescription( "central", "Maven Central repository", - "http://repo1.maven.org/maven2" + "https://repo1.maven.org/maven2" ); public static final RemoteRepositoryDescription JBOSS_COMMUNITY = new RemoteRepositoryDescription( "jboss.community", diff --git a/java/openapi/src/icons/OpenapiIcons.java b/java/openapi/src/icons/OpenapiIcons.java new file mode 100644 index 000000000000..eb9eb75de85a --- /dev/null +++ b/java/openapi/src/icons/OpenapiIcons.java @@ -0,0 +1,17 @@ +package icons; + +import com.intellij.openapi.util.IconLoader; + +import javax.swing.*; + +/** + * NOTE THIS FILE IS AUTO-GENERATED + * DO NOT EDIT IT BY HAND, run build/scripts/icons.gant instead + */ +public class OpenapiIcons { + private static Icon load(String path) { + return IconLoader.getIcon(path, OpenapiIcons.class); + } + + public static final Icon RepositoryLibraryLogo = load("/icons/repositoryLibraryLogo.png"); // 16x16 +} diff --git a/java/openapi/src/org/jetbrains/idea/maven/utils/library/RepositoryLibraryDescription.java b/java/openapi/src/org/jetbrains/idea/maven/utils/library/RepositoryLibraryDescription.java index 2153db6276c4..f5a0aef9f95c 100644 --- a/java/openapi/src/org/jetbrains/idea/maven/utils/library/RepositoryLibraryDescription.java +++ b/java/openapi/src/org/jetbrains/idea/maven/utils/library/RepositoryLibraryDescription.java @@ -18,8 +18,8 @@ package org.jetbrains.idea.maven.utils.library; import com.intellij.jarRepository.RemoteRepositoryDescription; import com.intellij.jarRepository.RepositoryLibraryDefinition; import com.intellij.openapi.roots.DependencyScope; -import com.intellij.openapi.util.IconLoader; import com.intellij.util.containers.HashMap; +import icons.OpenapiIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.library.JpsMavenRepositoryLibraryDescriptor; @@ -43,7 +43,7 @@ public class RepositoryLibraryDescription { @NotNull public static final String SnapshotVersionSuffix = "-SNAPSHOT"; - public static final Icon DEFAULT_ICON = IconLoader.getIcon("/icons/repositoryLibraryLogo.png"); + public static final Icon DEFAULT_ICON = OpenapiIcons.RepositoryLibraryLogo; private static volatile Map ourStaticallyDefinedLibraries; diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java index 08c456a9067e..f1d1f8ea7c28 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaStructuralSearchProfile.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.template.JavaCodeContextType; import com.intellij.codeInsight.template.TemplateContextType; import com.intellij.dupLocator.iterators.NodeIterator; +import com.intellij.dupLocator.util.NodeFilter; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.lang.Language; import com.intellij.lang.java.JavaLanguage; @@ -39,8 +40,6 @@ import com.intellij.structuralsearch.impl.matcher.*; import com.intellij.structuralsearch.impl.matcher.compiler.GlobalCompilingVisitor; import com.intellij.structuralsearch.impl.matcher.compiler.JavaCompilingVisitor; import com.intellij.structuralsearch.impl.matcher.compiler.PatternCompiler; -import com.intellij.structuralsearch.impl.matcher.filters.JavaLexicalNodesFilter; -import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter; import com.intellij.structuralsearch.plugin.replace.ReplaceOptions; import com.intellij.structuralsearch.plugin.replace.impl.ParameterInfo; import com.intellij.structuralsearch.plugin.replace.impl.ReplacementBuilder; @@ -51,6 +50,7 @@ import com.intellij.structuralsearch.plugin.ui.SearchContext; import com.intellij.structuralsearch.plugin.ui.UIUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -60,9 +60,16 @@ import java.util.*; * @author Eugene.Kudelevsky */ public class JavaStructuralSearchProfile extends StructuralSearchProfile { - private JavaLexicalNodesFilter myJavaLexicalNodesFilter; - public String getText(PsiElement match, int start,int end) { + private static final Set PRIMITIVE_TYPES = new THashSet<>(Arrays.asList( + PsiKeyword.SHORT, PsiKeyword.BOOLEAN, + PsiKeyword.DOUBLE, PsiKeyword.LONG, + PsiKeyword.INT, PsiKeyword.FLOAT, + PsiKeyword.CHAR, PsiKeyword.BYTE + )); + + @Override + public String getText(PsiElement match, int start, int end) { if (match instanceof PsiIdentifier) { PsiElement parent = match.getParent(); if (parent instanceof PsiJavaCodeReferenceElement && !(parent instanceof PsiExpression)) { @@ -74,6 +81,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { return matchText.substring(start,end == -1? matchText.length():end); } + @Override public Class getElementContextByPsi(PsiElement element) { if (element instanceof PsiIdentifier) { element = element.getParent(); @@ -86,6 +94,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { } } + @Override @NotNull public String getTypedVarString(final PsiElement element) { String text; @@ -187,10 +196,12 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { return element; } + @Override public void compile(PsiElement[] elements, @NotNull GlobalCompilingVisitor globalVisitor) { elements[0].getParent().accept(new JavaCompilingVisitor(globalVisitor)); } + @Override @NotNull public PsiElementVisitor createMatchingVisitor(@NotNull GlobalMatchingVisitor globalVisitor) { return new JavaMatchingVisitor(globalVisitor); @@ -198,18 +209,30 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { @NotNull @Override - public PsiElementVisitor getLexicalNodesFilter(@NotNull LexicalNodesFilter filter) { - if (myJavaLexicalNodesFilter == null) { - myJavaLexicalNodesFilter = new JavaLexicalNodesFilter(filter); - } - return myJavaLexicalNodesFilter; + public NodeFilter getLexicalNodesFilter() { + return element -> isLexicalNode(element); } + private static boolean isLexicalNode(PsiElement element) { + if (element instanceof PsiWhiteSpace) { + return true; + } + else if (element instanceof PsiJavaToken) { + // do not filter out type keyword of new primitive arrays (e.g. int in new int[10]) + return !(element instanceof PsiKeyword && + PRIMITIVE_TYPES.contains(element.getText()) && + element.getParent() instanceof PsiNewExpression); + } + return false; + } + + @Override @NotNull public CompiledPattern createCompiledPattern() { return new JavaCompiledPattern(); } + @Override public boolean isMyLanguage(@NotNull Language language) { return language == JavaLanguage.INSTANCE; } @@ -385,6 +408,7 @@ public class JavaStructuralSearchProfile extends StructuralSearchProfile { return JavaCodeContextType.class; } + @Override public PsiCodeFragment createCodeFragment(Project project, String text, PsiElement context) { final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(project); return factory.createCodeBlockCodeFragment(text, context, true); diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java index fd7228b3c07c..750216d34074 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.structuralsearch.MatchOptions; import com.intellij.structuralsearch.MatchResult; -import com.intellij.structuralsearch.impl.matcher.filters.LexicalNodesFilter; import com.intellij.structuralsearch.impl.matcher.handlers.MatchPredicate; import com.intellij.structuralsearch.impl.matcher.handlers.MatchingHandler; import com.intellij.structuralsearch.impl.matcher.handlers.SubstitutionHandler; @@ -1547,12 +1546,8 @@ public class JavaMatchingVisitor extends JavaElementVisitor { final PsiElement element = PsiTreeUtil.getNextSiblingOfType(newKeyword, PsiWhiteSpace.class); if (element != null && element.getNextSibling() instanceof PsiKeyword) { - ((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(true); - myMatchingVisitor.setResult(myMatchingVisitor.match(classReference, element.getNextSibling()) && myMatchingVisitor.matchSons(new1.getArrayInitializer(), new2.getArrayInitializer())); - - ((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(false); if (myMatchingVisitor.getResult()) { // matching dims matchArrayDims(new1, new2); @@ -1565,9 +1560,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor { if (classReference == new2.getClassReference()) { // probably anonymous class or array of primitive type - ((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(true); myMatchingVisitor.setResult(myMatchingVisitor.matchSons(new1, new2)); - ((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(false); } else if (new1.getAnonymousClass() == null && classReference != null && diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaLexicalNodesFilter.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaLexicalNodesFilter.java deleted file mode 100644 index 2e190b7063a5..000000000000 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/JavaLexicalNodesFilter.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.structuralsearch.impl.matcher.filters; - -import com.intellij.psi.*; -import com.intellij.psi.javadoc.PsiDocComment; - -/** -* @author Eugene.Kudelevsky -*/ -public class JavaLexicalNodesFilter extends JavaElementVisitor { - private final LexicalNodesFilter myLexicalNodesFilter; - - public JavaLexicalNodesFilter(LexicalNodesFilter lexicalNodesFilter) { - this.myLexicalNodesFilter = lexicalNodesFilter; - } - - @Override public void visitJavaToken(final PsiJavaToken t) { - myLexicalNodesFilter.setResult(true); - } - - @Override public void visitComment(final PsiComment comment) { - } - - @Override public void visitDocComment(final PsiDocComment comment) { - } - - @Override public void visitKeyword(PsiKeyword keyword) { - myLexicalNodesFilter.setResult(!myLexicalNodesFilter.isCareKeyWords()); - } - - @Override public void visitWhiteSpace(final PsiWhiteSpace space) { - myLexicalNodesFilter.setResult(true); - } - - @Override public void visitErrorElement(final PsiErrorElement element) { - } -} diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/StatementFilter.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/StatementFilter.java index 91abc96139e1..87beb0e148bc 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/StatementFilter.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/filters/StatementFilter.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.structuralsearch.impl.matcher.filters; import com.intellij.dupLocator.util.NodeFilter; @@ -10,24 +25,14 @@ import com.intellij.psi.*; * Time: 17:46:10 * To change this template use Options | File Templates. */ -public class StatementFilter extends JavaElementVisitor implements NodeFilter { - protected boolean result; - - @Override public void visitReferenceExpression(PsiReferenceExpression psiReferenceExpression) { - result = false; - } - - @Override public void visitStatement(PsiStatement psiStatement) { - result = true; - } - - @Override public void visitComment(PsiComment comment) { - result = true; - } +public class StatementFilter implements NodeFilter { + @Override public boolean accepts(PsiElement element) { - result = false; - if (element!=null) element.accept(this); - return result; + if (element instanceof PsiComment && element.getParent() instanceof PsiCodeBlock) { + // only allow comments in statement context + return true; + } + return element instanceof PsiStatement; } } diff --git a/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java index 5ad8b8655f5b..5f384c27294e 100644 --- a/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java +++ b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java @@ -62,7 +62,7 @@ public abstract class InspectionTestCase extends PsiTestCase { private EntryPoint myUnusedCodeExtension; private VirtualFile ext_src; - protected static GlobalInspectionToolWrapper getUnusedDeclarationWrapper() { + public static GlobalInspectionToolWrapper getUnusedDeclarationWrapper() { InspectionEP ep = new InspectionEP(); ep.presentation = UnusedDeclarationPresentation.class.getName(); ep.implementationClass = UnusedDeclarationInspection.class.getName(); diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildPaths.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildPaths.groovy index 0e23f8b8f0a2..ee941d67ce8d 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildPaths.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/BuildPaths.groovy @@ -58,4 +58,9 @@ abstract class BuildPaths { * Path to a directory containing JDK (currently Java 8) which is used to compile the project */ String jdkHome + + /** + * Path to a directory containing Kotlin plugin with compiler which is used to compile the project + */ + String kotlinHome } diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy index 635c44e563e3..9269a2908afa 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildContextImpl.groovy @@ -48,7 +48,6 @@ class BuildContextImpl extends BuildContext { def context = new BuildContextImpl(compilationContext, productProperties, windowsDistributionCustomizer, linuxDistributionCustomizer, macDistributionCustomizer, proprietaryBuildTools) - setupDependencies(context.messages, communityHome) return context } @@ -76,13 +75,6 @@ class BuildContextImpl extends BuildContext { bootClassPathJarNames = ["bootstrap.jar", "extensions.jar", "util.jar", "jdom.jar", "log4j.jar", "trove4j.jar", "jna.jar"] } - private static void setupDependencies(BuildMessages messages, String communityHome) { - messages.info("Setting up installer dependencies") - if (!BuildUtils.gradle(new File(communityHome, 'build/dependencies/'), 'setupDependencies')) { - messages.error("Cannot setup installer dependencies") - } - } - private String readSnapshotBuildNumber() { new File(paths.communityHome, "build.txt").text.trim() } diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy index 612c0f7a8128..20120f1a4aa7 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildTasksImpl.groovy @@ -17,11 +17,7 @@ package org.jetbrains.intellij.build.impl import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil -import org.jetbrains.intellij.build.BuildContext -import org.jetbrains.intellij.build.BuildOptions -import org.jetbrains.intellij.build.BuildTasks -import org.jetbrains.intellij.build.CompilationTasks -import org.jetbrains.intellij.build.ProductModulesLayout +import org.jetbrains.intellij.build.* import org.jetbrains.jps.model.java.JavaResourceRootType import org.jetbrains.jps.model.java.JavaSourceRootType import org.jetbrains.jps.model.module.JpsModule @@ -277,7 +273,7 @@ idea.fatal.error.notification=disabled if (buildContext.productProperties.scrambleMainJar) { scramble() } - + setupJbreDependencies() layoutShared() def propertiesFile = patchIdeaPropertiesFile() @@ -308,6 +304,13 @@ idea.fatal.error.notification=disabled } } } + + private void setupJbreDependencies() { + buildContext.messages.info("Setting up installer dependencies") + if (!BuildUtils.runDependenciesGradle(buildContext.paths.communityHome, 'setupJbre')) { + buildContext.messages.error("Cannot setup installer dependencies") + } + } private void scramble() { if (buildContext.proprietaryBuildTools.scrambleTool != null) { diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildUtils.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildUtils.groovy index fbd3309c0fd6..e39edfa79496 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildUtils.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/BuildUtils.groovy @@ -84,7 +84,11 @@ class BuildUtils { } } - static boolean gradle(File projectDir, String... tasks) { + static boolean runDependenciesGradle(String communityHome, String... tasks) { + return runGradle(new File(communityHome, 'build/dependencies/'), tasks) + } + + private static boolean runGradle(File projectDir, String... tasks) { def gradleScript = SystemInfo.isWindows ? "gradlew.bat" : "gradlew" List command = new ArrayList() command.add("${projectDir.absolutePath}/$gradleScript".toString()) diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy index f3d4b09dc50e..b0e54df9bd10 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationContextImpl.groovy @@ -66,26 +66,30 @@ class CompilationContextImpl implements CompilationContext { messages.error("communityHome ($communityHome) doesn't point to a directory containing IntelliJ Community sources") } + if (!options.isInDevelopmentMode) { + setupCompilationDependencies(messages, communityHome) + } + projectHome = toCanonicalPath(projectHome) def jdk8Home = toCanonicalPath(JdkUtils.computeJdkHome(messages, "jdk8Home", "$projectHome/build/jdk/1.8", "JDK_18_x64")) + def kotlinHome = toCanonicalPath("$communityHome/build/dependencies/build/kotlin/Kotlin") - setupDependencies(messages, communityHome) if (project.modules.isEmpty()) { - loadProject(communityHome, projectHome, jdk8Home, project, global, messages) + loadProject(projectHome, jdk8Home, kotlinHome, project, global, messages) } else { //todo[nik] currently we need this to build IDEA CE from IDEA UI build scripts. It would be better to create a separate JpsProject instance instead messages.info("Skipping loading project because it's already loaded") } - def context = new CompilationContextImpl(ant, projectBuilder, project, global, communityHome, projectHome, jdk8Home, messages, + def context = new CompilationContextImpl(ant, projectBuilder, project, global, communityHome, projectHome, jdk8Home, kotlinHome, messages, buildOutputRootEvaluator, options) context.prepareForBuild() return context } private CompilationContextImpl(AntBuilder ant, JpsGantProjectBuilder projectBuilder, JpsProject project, JpsGlobal global, - String communityHome, String projectHome, String jdk8Home, BuildMessages messages, + String communityHome, String projectHome, String jdk8Home, String kotlinHome, BuildMessages messages, BiFunction buildOutputRootEvaluator, BuildOptions options) { this.ant = ant this.project = project @@ -94,23 +98,18 @@ class CompilationContextImpl implements CompilationContext { this.projectBuilder = projectBuilder this.messages = messages String buildOutputRoot = options.outputRootPath ?: buildOutputRootEvaluator.apply(project, messages) - this.paths = new BuildPathsImpl(communityHome, projectHome, buildOutputRoot, jdk8Home) + this.paths = new BuildPathsImpl(communityHome, projectHome, buildOutputRoot, jdk8Home, kotlinHome) } CompilationContextImpl createCopy(AntBuilder ant, BuildMessages messages, BuildOptions options, BiFunction buildOutputRootEvaluator) { - return new CompilationContextImpl(ant, projectBuilder, project, global, paths.communityHome, paths.projectHome, paths.jdkHome, - messages, buildOutputRootEvaluator, options) + return new CompilationContextImpl(ant, projectBuilder, project, global, paths.communityHome, paths.projectHome, paths.jdkHome, + paths.kotlinHome, messages, buildOutputRootEvaluator, options) } - private static void loadProject(String communityHome, String projectHome, String jdkHome, JpsProject project, JpsGlobal global, + private static void loadProject(String projectHome, String jdkHome, String kotlinHome, JpsProject project, JpsGlobal global, BuildMessages messages) { - def bundledKotlinPath = "$communityHome/build/dependencies/build/kotlin/Kotlin/kotlinc" - if (!new File(bundledKotlinPath, "lib/kotlin-runtime.jar").exists()) { - messages.error( - "Could not find Kotlin runtime at $bundledKotlinPath/lib/kotlin-runtime.jar: run `./gradlew setupKotlin` in dependencies module to download Kotlin JARs") - } - JpsModelSerializationDataService.getOrCreatePathVariablesConfiguration(global).addPathVariable("KOTLIN_BUNDLED", bundledKotlinPath) + JpsModelSerializationDataService.getOrCreatePathVariablesConfiguration(global).addPathVariable("KOTLIN_BUNDLED", "$kotlinHome/kotlinc") JdkUtils.defineJdk(global, "IDEA jdk", JdkUtils.computeJdkHome(messages, "jdkHome", "$projectHome/build/jdk/1.6", "JDK_16_x64")) JdkUtils.defineJdk(global, "1.8", jdkHome) @@ -120,9 +119,12 @@ class CompilationContextImpl implements CompilationContext { messages.info("Loaded project $projectHome: ${project.modules.size()} modules, ${project.libraryCollection.libraries.size()} libraries") } - private static void setupDependencies(BuildMessages messages, String communityHome) { + static boolean dependenciesInstalled + static void setupCompilationDependencies(BuildMessages messages, String communityHome) { + if (dependenciesInstalled) return + dependenciesInstalled = true messages.info("Setting up compilation dependencies") - if (!BuildUtils.gradle(new File(communityHome, 'build/dependencies/'), 'setupJdks', 'setupKotlinPlugin')) { + if (!BuildUtils.runDependenciesGradle(communityHome, 'setupJdks', 'setupKotlinPlugin')) { messages.error("Cannot setup compilation dependencies") } } @@ -240,17 +242,18 @@ class CompilationContextImpl implements CompilationContext { messages.artifactBuild(relativePath) } - private static String toCanonicalPath(String communityHome) { - FileUtil.toSystemIndependentName(new File(communityHome).canonicalPath) + private static String toCanonicalPath(String path) { + FileUtil.toSystemIndependentName(new File(path).canonicalPath) } } class BuildPathsImpl extends BuildPaths { - BuildPathsImpl(String communityHome, String projectHome, String buildOutputRoot, String jdkHome) { + BuildPathsImpl(String communityHome, String projectHome, String buildOutputRoot, String jdkHome, String kotlinHome) { this.communityHome = communityHome this.projectHome = projectHome this.buildOutputRoot = buildOutputRoot this.jdkHome = jdkHome + this.kotlinHome = kotlinHome artifacts = "$buildOutputRoot/artifacts" distAll = "$buildOutputRoot/dist.all" temp = "$buildOutputRoot/temp" diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationTasksImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationTasksImpl.groovy index bcf6d160ab5d..e24efd606d84 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationTasksImpl.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/CompilationTasksImpl.groovy @@ -40,6 +40,7 @@ class CompilationTasksImpl extends CompilationTasks { return } + CompilationContextImpl.setupCompilationDependencies(context.messages, context.paths.communityHome) ensureKotlinCompilerAddedToClassPath() context.messages.progress("Compiling project") @@ -81,7 +82,7 @@ class CompilationTasksImpl extends CompilationTasks { return } - def kotlinPluginLibPath = "$context.paths.communityHome/build/dependencies/build/kotlin/Kotlin/lib" + def kotlinPluginLibPath = "$context.paths.kotlinHome/lib" if (new File(kotlinPluginLibPath).exists()) { ["jps/kotlin-jps-plugin.jar", "kotlin-plugin.jar", "kotlin-runtime.jar", "kotlin-reflect.jar"].each { BuildUtils.addToJpsClassPath("$kotlinPluginLibPath/$it", context.ant) diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/TestingTasksImpl.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/TestingTasksImpl.groovy index b1e0974acfeb..bbadf82786a9 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/TestingTasksImpl.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/TestingTasksImpl.groovy @@ -50,6 +50,7 @@ class TestingTasksImpl extends TestingTasks { else { compilationTasks.compileAllModulesAndTests() } + setupTestingDependencies() def mainModule = options.mainModule ?: defaultMainModule List testsClasspath = context.projectBuilder.moduleRuntimeClasspath(context.findRequiredModule(mainModule), true) @@ -171,6 +172,18 @@ class TestingTasksImpl extends TestingTasks { test(name: 'com.intellij.tests.BootstrapTests') } } + + static boolean dependenciesInstalled + + private def setupTestingDependencies() { + if (dependenciesInstalled) return + dependenciesInstalled = true + context.messages.info("Setting up testing dependencies") + if (!BuildUtils.runDependenciesGradle(context.paths.communityHome, 'setupKotlinPlugin')) { + context.messages.error("Cannot setup testing dependencies") + } + dependenciesInstalled = true + } static boolean taskDefined diff --git a/platform/core-api/src/com/intellij/psi/tree/IElementType.java b/platform/core-api/src/com/intellij/psi/tree/IElementType.java index 2a8f8a6c27b5..f468e70abfb7 100644 --- a/platform/core-api/src/com/intellij/psi/tree/IElementType.java +++ b/platform/core-api/src/com/intellij/psi/tree/IElementType.java @@ -40,24 +40,21 @@ public class IElementType { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.tree.IElementType"); public static final IElementType[] EMPTY_ARRAY = new IElementType[0]; + public static final ArrayFactory ARRAY_FACTORY = count -> count == 0 ? EMPTY_ARRAY : new IElementType[count]; /** * Default enumeration predicate which matches all token types. * * @see #enumerate(Predicate) */ - public static final Predicate TRUE = new Predicate() { - @Override - public boolean matches(@NotNull IElementType type) { - return true; - } - }; + public static final Predicate TRUE = type -> true; public static final short FIRST_TOKEN_INDEX = 1; private static final short MAX_INDEXED_TYPES = 15000; private static short size; // guarded by lock private static volatile IElementType[] ourRegistry = EMPTY_ARRAY; // writes are guarded by lock + @SuppressWarnings("RedundantStringConstructorCall") private static final Object lock = new String("registry lock"); static { @@ -91,7 +88,6 @@ public class IElementType { this(debugName, language, true); } - private static final ArrayFactory FACTORY = count -> new IElementType[count]; /** * Allows to construct element types for some temporary purposes without registering them. @@ -107,7 +103,7 @@ public class IElementType { myIndex = size++; LOG.assertTrue(myIndex < MAX_INDEXED_TYPES, "Too many element types registered. Out of (short) range."); IElementType[] newRegistry = - myIndex >= ourRegistry.length ? ArrayUtil.realloc(ourRegistry, ourRegistry.length * 3 / 2 + 1, FACTORY) : ourRegistry; + myIndex >= ourRegistry.length ? ArrayUtil.realloc(ourRegistry, ourRegistry.length * 3 / 2 + 1, ARRAY_FACTORY) : ourRegistry; newRegistry[myIndex] = this; ourRegistry = newRegistry; } @@ -189,6 +185,7 @@ public class IElementType { * * @see IElementType#enumerate(Predicate) */ + @FunctionalInterface public interface Predicate { boolean matches(@NotNull IElementType type); } diff --git a/platform/core-api/src/com/intellij/usageView/UsageInfo.java b/platform/core-api/src/com/intellij/usageView/UsageInfo.java index 2881d761b00b..78c1d854c196 100644 --- a/platform/core-api/src/com/intellij/usageView/UsageInfo.java +++ b/platform/core-api/src/com/intellij/usageView/UsageInfo.java @@ -35,7 +35,7 @@ public class UsageInfo { public final boolean isNonCodeUsage; protected boolean myDynamicUsage; - public UsageInfo(@NotNull PsiElement element, int startOffset, int endOffset, boolean isNonCodeUsage) { + public UsageInfo(@NotNull PsiElement element, final int startOffset, final int endOffset, boolean isNonCodeUsage) { element = element.getNavigationElement(); PsiFile file = element.getContainingFile(); PsiElement topElement = file == null ? element : file; @@ -45,30 +45,32 @@ public class UsageInfo { if (elementRange == null) { throw new IllegalArgumentException("text range null for " + element + "; " + element.getClass()); } + int effectiveStart; + int effectiveEnd; if (startOffset == -1 && endOffset == -1) { // calculate natural element range - startOffset = element.getTextOffset() - elementRange.getStartOffset(); - endOffset = elementRange.getEndOffset() - elementRange.getStartOffset(); + effectiveStart = element.getTextOffset() - elementRange.getStartOffset(); + effectiveEnd = elementRange.getLength(); + } + else { + effectiveStart = startOffset; + effectiveEnd = endOffset; } - if (startOffset < 0) { - throw new IllegalArgumentException("element " + element + "; startOffset " +startOffset); - } - if (startOffset > endOffset) { - throw new IllegalArgumentException("element " + element + "; diff " + (endOffset-startOffset)); + if (effectiveStart < 0 || effectiveStart > effectiveEnd) { + throw new IllegalArgumentException("element " + element + "; startOffset " +startOffset+"; endOffset="+endOffset+ + "; effectiveStart="+effectiveStart+"; effectiveEnd="+effectiveEnd+ + "; elementRange="+elementRange+"; element.getTextOffset()="+element.getTextOffset()); } Project project = topElement.getProject(); SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project); mySmartPointer = smartPointerManager.createSmartPsiElementPointer(element, file); - if (startOffset != element.getTextOffset() - elementRange.getStartOffset() || endOffset != elementRange.getLength()) { - TextRange rangeToStore; - if (file != null && InjectedLanguageManager.getInstance(project).isInjectedFragment(file)) { - rangeToStore = elementRange; - } - else { - rangeToStore = TextRange.create(startOffset, endOffset).shiftRight(elementRange.getStartOffset()); - } + if (file != null && + (effectiveStart != element.getTextOffset() - elementRange.getStartOffset() || effectiveEnd != elementRange.getLength())) { + TextRange rangeToStore = InjectedLanguageManager.getInstance(project).isInjectedFragment(file) + ? elementRange + : TextRange.create(effectiveStart, effectiveEnd).shiftRight(elementRange.getStartOffset()); myPsiFileRange = smartPointerManager.createSmartPsiFileRangePointer(file, rangeToStore); } else { diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index 65947401313e..3434df2dcb14 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -126,8 +126,6 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { doneMarker.clean(); } }); - private static final ArrayFactory myElementTypeArrayFactory = - count -> count == 0 ? IElementType.EMPTY_ARRAY : new IElementType[count]; public static void registerWhitespaceToken(@NotNull IElementType type) { ourAnyLanguageWhitespaceTokens = TokenSet.orSet(ourAnyLanguageWhitespaceTokens, TokenSet.create(type)); @@ -266,9 +264,10 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { int i = 0; int offset = 0; while (true) { - ProgressIndicatorProvider.checkCanceled(); IElementType type = myLexer.getTokenType(); if (type == null) break; + + if (i % 20 == 0) ProgressIndicatorProvider.checkCanceled(); if (i >= myLexTypes.length - 1) { resizeLexemes(i * 3 / 2); @@ -918,7 +917,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { private void resizeLexemes(final int newSize) { myLexStarts = ArrayUtil.realloc(myLexStarts, newSize+1); - myLexTypes = ArrayUtil.realloc(myLexTypes, newSize, myElementTypeArrayFactory); + myLexTypes = ArrayUtil.realloc(myLexTypes, newSize, IElementType.ARRAY_FACTORY); clearCachedTokenType(); } diff --git a/platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java b/platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java index 0e8ddb7c5d44..531a2f3bea72 100644 --- a/platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java +++ b/platform/core-impl/src/com/intellij/util/CachedValueLeakChecker.java @@ -43,7 +43,6 @@ class CachedValueLeakChecker { private static final Logger LOG = Logger.getInstance("#com.intellij.util.CachedValueChecker"); private static final boolean DO_CHECKS = ApplicationManager.getApplication().isUnitTestMode(); private static final Set ourCheckedKeys = ContainerUtil.newConcurrentSet(); - private static final boolean JAVA9 = SystemInfo.isJavaVersionAtLeast("9"); static void checkProvider(@NotNull final CachedValueProvider provider, @NotNull final Key key, @@ -51,7 +50,7 @@ class CachedValueLeakChecker { if (!DO_CHECKS || ApplicationInfoImpl.isInStressTest()) return; if (!ourCheckedKeys.add(key.toString())) return; // store strings because keys are created afresh in each (test) project - if (!JAVA9) { + if (!SystemInfo.IS_AT_LEAST_JAVA9) { findReferencedPsi(provider, userDataHolder, 5); } } diff --git a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeViewer.java b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeViewer.java index 7d1274659e29..cdecff9a2af6 100644 --- a/platform/diff-impl/src/com/intellij/diff/merge/TextMergeViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/merge/TextMergeViewer.java @@ -243,10 +243,10 @@ public class TextMergeViewer implements MergeTool.MergeViewer { group.add(myEditorSettingsAction); DefaultActionGroup diffGroup = new DefaultActionGroup("Compare With", true); - diffGroup.getTemplatePresentation().setIcon(AllIcons.Diff.Diff); - diffGroup.add(new TextShowPartialDiffAction(PartialDiffMode.LEFT_MIDDLE)); - diffGroup.add(new TextShowPartialDiffAction(PartialDiffMode.RIGHT_MIDDLE)); - diffGroup.add(new TextShowPartialDiffAction(PartialDiffMode.LEFT_RIGHT)); + diffGroup.getTemplatePresentation().setIcon(AllIcons.Actions.Diff); + diffGroup.add(new TextShowPartialDiffAction(PartialDiffMode.LEFT_MIDDLE, true)); + diffGroup.add(new TextShowPartialDiffAction(PartialDiffMode.RIGHT_MIDDLE, true)); + diffGroup.add(new TextShowPartialDiffAction(PartialDiffMode.LEFT_RIGHT, true)); diffGroup.add(new ShowDiffWithBaseAction(ThreeSide.LEFT)); diffGroup.add(new ShowDiffWithBaseAction(ThreeSide.BASE)); diffGroup.add(new ShowDiffWithBaseAction(ThreeSide.RIGHT)); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java index 8b96b57d2f5d..3e2c1321c9a0 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java @@ -64,9 +64,9 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewerEx { group.add(myEditorSettingsAction); group.add(Separator.getInstance()); - group.add(new TextShowPartialDiffAction(PartialDiffMode.MIDDLE_LEFT)); - group.add(new TextShowPartialDiffAction(PartialDiffMode.MIDDLE_RIGHT)); - group.add(new TextShowPartialDiffAction(PartialDiffMode.LEFT_RIGHT)); + group.add(new TextShowPartialDiffAction(PartialDiffMode.MIDDLE_LEFT, false)); + group.add(new TextShowPartialDiffAction(PartialDiffMode.MIDDLE_RIGHT, false)); + group.add(new TextShowPartialDiffAction(PartialDiffMode.LEFT_RIGHT, false)); group.add(Separator.getInstance()); group.addAll(super.createToolbarActions()); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/side/ThreesideDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/side/ThreesideDiffViewer.java index d66e650b6027..c8f9a3722fee 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/side/ThreesideDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/side/ThreesideDiffViewer.java @@ -30,6 +30,7 @@ import com.intellij.diff.tools.util.SimpleDiffPanel; import com.intellij.diff.tools.util.base.ListenerDiffViewerBase; import com.intellij.diff.util.DiffUtil; import com.intellij.diff.util.ThreeSide; +import com.intellij.icons.AllIcons; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.ex.ActionUtil; @@ -196,39 +197,46 @@ public abstract class ThreesideDiffViewer extends Listen @NotNull protected final ThreeSide mySide1; @NotNull protected final ThreeSide mySide2; - public ShowPartialDiffAction(@NotNull PartialDiffMode mode) { + public ShowPartialDiffAction(@NotNull PartialDiffMode mode, boolean hasFourSides) { String id; + Icon icon = null; switch (mode) { case LEFT_MIDDLE: mySide1 = ThreeSide.LEFT; mySide2 = ThreeSide.BASE; id = "Diff.ComparePartial.Base.Left"; + if (!hasFourSides) icon = AllIcons.Diff.LeftDiff; break; case RIGHT_MIDDLE: mySide1 = ThreeSide.RIGHT; mySide2 = ThreeSide.BASE; id = "Diff.ComparePartial.Base.Right"; + if (!hasFourSides) icon = AllIcons.Diff.RightDiff; break; case MIDDLE_LEFT: mySide1 = ThreeSide.BASE; mySide2 = ThreeSide.LEFT; id = "Diff.ComparePartial.Base.Left"; + if (!hasFourSides) icon = AllIcons.Diff.LeftDiff; break; case MIDDLE_RIGHT: mySide1 = ThreeSide.BASE; mySide2 = ThreeSide.RIGHT; id = "Diff.ComparePartial.Base.Right"; + if (!hasFourSides) icon = AllIcons.Diff.RightDiff; break; case LEFT_RIGHT: mySide1 = ThreeSide.LEFT; mySide2 = ThreeSide.RIGHT; id = "Diff.ComparePartial.Left.Right"; + if (!hasFourSides) icon = AllIcons.Diff.BranchDiff; break; default: throw new IllegalArgumentException(); } String text = ActionsBundle.message("action.Diff.ComparePartial.Generic", mySide1.getIndex(), mySide2.getIndex()); getTemplatePresentation().setText(text); + getTemplatePresentation().setIcon(icon); ActionUtil.mergeFrom(this, id); } diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/side/ThreesideTextDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/side/ThreesideTextDiffViewer.java index cfc8727b16ab..2cb02c6348e4 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/side/ThreesideTextDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/side/ThreesideTextDiffViewer.java @@ -364,8 +364,8 @@ public abstract class ThreesideTextDiffViewer extends ThreesideDiffViewer type instanceof StubSerializer); for (IElementType type : stubElementTypes) { if (type instanceof StubFileElementType && StubFileElementType.DEFAULT_EXTERNAL_ID.equals(((StubFileElementType)type).getExternalId())) { diff --git a/platform/lang-api/src/com/intellij/execution/RunManager.kt b/platform/lang-api/src/com/intellij/execution/RunManager.kt index 1fba62428fa0..9ceec45d788b 100644 --- a/platform/lang-api/src/com/intellij/execution/RunManager.kt +++ b/platform/lang-api/src/com/intellij/execution/RunManager.kt @@ -114,13 +114,6 @@ abstract class RunManager { */ abstract val tempConfigurationsList: List - /** - * Saves the specified temporary run configuration and makes it a permanent one. - * @param configuration the temporary run configuration to save. - */ - @Deprecated("") - abstract fun makeStable(configuration: RunConfiguration) - /** * Saves the specified temporary run settings and makes it a permanent one. * @param settings the temporary settings to save. diff --git a/platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java b/platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java index 0020ab937d30..0cbd1ae3ad06 100644 --- a/platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java +++ b/platform/lang-api/src/com/intellij/lang/surroundWith/Surrounder.java @@ -19,6 +19,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; +import com.intellij.util.ArrayFactory; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,6 +31,9 @@ import org.jetbrains.annotations.Nullable; * @see SurroundDescriptor */ public interface Surrounder { + Surrounder[] EMPTY_ARRAY = new Surrounder[0]; + ArrayFactory myArrayFactory = count -> count == 0 ? EMPTY_ARRAY : new Surrounder[count]; + /** * Returns the user-visible name of the Surround With template. * diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java index 7abc51bb7456..dbea5da7dd00 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/ColorAndFontOptions.java @@ -27,6 +27,8 @@ import com.intellij.ide.ui.laf.darcula.DarculaInstaller; import com.intellij.ide.ui.laf.darcula.DarculaLookAndFeelInfo; import com.intellij.ide.util.PropertiesComponent; import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.application.ApplicationBundle; import com.intellij.openapi.application.ApplicationNamesInfo; import com.intellij.openapi.editor.colors.*; @@ -40,6 +42,7 @@ import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.SchemeManager; import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.options.colors.*; +import com.intellij.openapi.options.ex.Settings; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.DialogWrapper; @@ -71,6 +74,7 @@ import javax.swing.*; import java.awt.*; import java.util.*; import java.util.List; +import java.util.function.Function; public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract implements EditorOptionsProvider, SchemesModel { @@ -1401,4 +1405,24 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract return "Color And Fonts for "+getDisplayName(); } } + + public static Runnable getColorSelector(DataProvider provider, String search, String name) { + return getSelector(Settings.KEY.getData(provider), search, options -> options.findSubConfigurable(name)); + } + + public static Runnable getColorSelector(DataContext context, String search, Class type) { + return getSelector(Settings.KEY.getData(context), search, options -> options.findSubConfigurable(type)); + } + + private static Runnable getSelector(Settings settings, String search, Function function) { + if (settings == null) return null; + + ColorAndFontOptions options = settings.find(ColorAndFontOptions.class); + if (options == null) return null; + + SearchableConfigurable page = function.apply(options); + if (page == null) return null; + + return () -> settings.select(page, search); + } } diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/JumpToColorsAndFontsAction.java b/platform/lang-impl/src/com/intellij/application/options/colors/JumpToColorsAndFontsAction.java index 047f24a8286e..d33363b579f5 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/JumpToColorsAndFontsAction.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/JumpToColorsAndFontsAction.java @@ -36,16 +36,13 @@ import com.intellij.openapi.editor.markup.EffectType; import com.intellij.openapi.editor.markup.MarkupModel; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.fileTypes.SyntaxHighlighter; -import com.intellij.openapi.options.SearchableConfigurable; import com.intellij.openapi.options.colors.AttributesDescriptor; import com.intellij.openapi.options.colors.ColorSettingsPage; import com.intellij.openapi.options.colors.ColorSettingsPages; -import com.intellij.openapi.options.ex.Settings; import com.intellij.openapi.options.newEditor.SettingsDialog; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.JBPopupFactory; -import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; @@ -65,6 +62,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import static com.intellij.application.options.colors.ColorAndFontOptions.getColorSelector; import static com.intellij.ui.SimpleTextAttributes.*; /** @@ -189,13 +187,9 @@ public class JumpToColorsAndFontsAction extends DumbAwareAction { private static boolean openSettingsAndSelectKey(@NotNull Project project, @NotNull ColorSettingsPage page, @NotNull AttributesDescriptor descriptor) { SettingsDialog dialog = (SettingsDialog)ShowSettingsUtilImpl.getDialog( project, ShowSettingsUtilImpl.getConfigurableGroups(project, true), null); - Settings settings = Settings.KEY.getData(dialog); - ColorAndFontOptions configurable0 = settings == null ? null : settings.find(ColorAndFontOptions.class); - SearchableConfigurable configurable = configurable0 == null ? null : configurable0.findSubConfigurable(page.getDisplayName()); - if (configurable == null) return false; - Runnable runnable = configurable.enableSearch(descriptor.getDisplayName()); - ActionCallback callback = settings.select(configurable); - if (runnable != null) callback.doWhenDone(runnable); + Runnable selector = getColorSelector(dialog, descriptor.getDisplayName(), page.getDisplayName()); + if (selector == null) return false; + selector.run(); dialog.show(); return true; } diff --git a/platform/lang-impl/src/com/intellij/application/options/editor/EditorAppearanceConfigurable.java b/platform/lang-impl/src/com/intellij/application/options/editor/EditorAppearanceConfigurable.java index 86da19a416b6..29c46fe3f239 100644 --- a/platform/lang-impl/src/com/intellij/application/options/editor/EditorAppearanceConfigurable.java +++ b/platform/lang-impl/src/com/intellij/application/options/editor/EditorAppearanceConfigurable.java @@ -179,8 +179,7 @@ public class EditorAppearanceConfigurable extends CompositeConfigurable { - final Runnable runnable = javaPage.enableSearch(toConfigure); - if (runnable != null) { - SwingUtilities.invokeLater(runnable); - } - }); + Runnable selector = ColorAndFontOptions.getColorSelector(dataContext, toConfigure, InspectionColorSettingsPage.class); + if (selector != null) { + selector.run(); } else { ColorAndFontOptions colorAndFontOptions = new ColorAndFontOptions(); diff --git a/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java b/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java index 34a9f409641d..26f6ae17400f 100644 --- a/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java +++ b/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java @@ -47,18 +47,9 @@ public abstract class RunManagerEx extends RunManager { @NotNull public abstract RunManagerConfig getConfig(); - public final void addConfiguration(@NotNull RunnerAndConfigurationSettings settings, boolean isShared) { - if (isShared) { - ((RunnerAndConfigurationSettingsImpl)settings).setLevel(RunnerAndConfigurationSettingsImpl.Level.PROJECT); - } - addConfiguration(settings); - } - @Deprecated public final void addConfiguration(RunnerAndConfigurationSettings settings, boolean isShared, List tasks, boolean addTemplateTasksIfAbsent) { - if (isShared) { - ((RunnerAndConfigurationSettingsImpl)settings).setLevel(RunnerAndConfigurationSettingsImpl.Level.PROJECT); - } + ((RunnerAndConfigurationSettingsImpl)settings).setShared(isShared); addConfiguration(settings, tasks, addTemplateTasksIfAbsent); } @@ -108,8 +99,9 @@ public abstract class RunManagerEx extends RunManager { public abstract void removeConfiguration(@Nullable RunnerAndConfigurationSettings settings); - public abstract void addRunManagerListener(RunManagerListener listener); - public abstract void removeRunManagerListener(RunManagerListener listener); + public abstract void addRunManagerListener(@NotNull RunManagerListener listener); + + public abstract void removeRunManagerListener(@NotNull RunManagerListener listener); @NotNull public abstract Map> getStructure(@NotNull ConfigurationType type); diff --git a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java index 8222f251da4c..0ea7db645d6a 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/ChooseRunConfigurationPopup.java @@ -205,8 +205,7 @@ public class ChooseRunConfigurationPopup implements ExecutorProvider { } private static void deleteConfiguration(final Project project, @NotNull final RunnerAndConfigurationSettings configurationSettings) { - final RunManagerEx manager = RunManagerEx.getInstanceEx(project); - manager.removeConfiguration(configurationSettings); + RunManagerEx.getInstanceEx(project).removeConfiguration(configurationSettings); } @Override diff --git a/platform/lang-impl/src/com/intellij/execution/impl/BaseRCSettingsConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/BaseRCSettingsConfigurable.java index 544397dbc357..61794c698cc5 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/BaseRCSettingsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/BaseRCSettingsConfigurable.java @@ -68,8 +68,7 @@ abstract class BaseRCSettingsConfigurable extends SettingsEditorConfigurable moduleRunConfigurations; synchronized (LOCK) { - for (final RunnerAndConfigurationSettings settings : getModuleRunConfigurationSettings()) { - myManager.removeConfiguration(settings); - } + moduleRunConfigurations = getModuleRunConfigurationSettings(); } + myManager.removeConfigurations(moduleRunConfigurations); } } }); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java deleted file mode 100644 index 1bdff14bb53e..000000000000 --- a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2000-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.execution.impl; - -import com.intellij.execution.RunnerAndConfigurationSettings; -import com.intellij.execution.configurations.UnknownRunConfiguration; -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.StateSplitterEx; -import com.intellij.openapi.components.Storage; -import com.intellij.openapi.util.Pair; -import gnu.trove.THashSet; -import org.jdom.Element; -import org.jetbrains.annotations.NotNull; - -import java.util.List; -import java.util.Set; - -@State(name = "ProjectRunConfigurationManager", storages = @Storage(value = "runConfigurations", stateSplitter = ProjectRunConfigurationManager.RunConfigurationStateSplitter.class)) -public class ProjectRunConfigurationManager implements PersistentStateComponent { - private final RunManagerImpl myManager; - - public ProjectRunConfigurationManager(@NotNull RunManagerImpl manager) { - myManager = manager; - } - - @Override - public Element getState() { - Element state = new Element("state"); - myManager.writeConfigurations(state, myManager.getSharedConfigurations()); - return state; - } - - @Override - public void loadState(Element state) { - Set existing = new THashSet<>(); - for (Element child : state.getChildren(RunManagerImpl.CONFIGURATION)) { - existing.add(myManager.loadConfiguration(child, true).getUniqueID()); - } - - myManager.removeNotExistingSharedConfigurations(existing); - myManager.requestSort(); - - if (myManager.getSelectedConfiguration() == null) { - for (RunnerAndConfigurationSettings settings : myManager.getAllSettings()) { - if (!(settings.getType() instanceof UnknownRunConfiguration)) { - myManager.setSelectedConfiguration(settings); - break; - } - } - } - } - - static class RunConfigurationStateSplitter extends StateSplitterEx { - @Override - public List> splitState(@NotNull Element state) { - return splitState(state, RunManagerImpl.NAME_ATTR); - } - } -} diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.kt b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.kt new file mode 100644 index 000000000000..7f204ceb7bad --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.execution.impl + +import com.intellij.execution.configurations.UnknownRunConfiguration +import com.intellij.openapi.components.PersistentStateComponent +import com.intellij.openapi.components.State +import com.intellij.openapi.components.StateSplitterEx +import com.intellij.openapi.components.Storage +import com.intellij.openapi.util.Pair +import gnu.trove.THashSet +import org.jdom.Element + +@State(name = "ProjectRunConfigurationManager", storages = arrayOf(Storage(value = "runConfigurations", stateSplitter = ProjectRunConfigurationManager.RunConfigurationStateSplitter::class))) +class ProjectRunConfigurationManager(private val manager: RunManagerImpl) : PersistentStateComponent { + + override fun getState(): Element? { + val state = Element("state") + manager.writeConfigurations(state, manager.getSharedConfigurations()) + return state + } + + override fun loadState(state: Element) { + val existing = THashSet() + for (child in state.getChildren(RunManagerImpl.CONFIGURATION)) { + existing.add(manager.loadConfiguration(child, true).uniqueID) + } + + manager.removeNotExistingSharedConfigurations(existing) + manager.requestSort() + + if (manager.selectedConfiguration == null) { + for (settings in manager.allSettings) { + if (settings.type !is UnknownRunConfiguration) { + manager.selectedConfiguration = settings + break + } + } + } + } + + internal class RunConfigurationStateSplitter : StateSplitterEx() { + override fun splitState(state: Element): List> { + return StateSplitterEx.splitState(state, RunManagerImpl.NAME_ATTR) + } + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java index 0728028149d5..22f1f19db84e 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java @@ -802,9 +802,7 @@ class RunConfigurable extends BaseConfigurable { toDeleteSettings.remove(each.getSettings()); } - for (RunnerAndConfigurationSettings each : toDeleteSettings) { - manager.removeConfiguration(each); - } + manager.removeConfigurations(toDeleteSettings); } static void collectNodesRecursively(DefaultMutableTreeNode parentNode, List nodes, NodeKind... allowed) { diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt index 3c04177d5dbc..8d5639db24a5 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt @@ -127,7 +127,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } private val customOrder = ObjectIntHashMap() - private val recentlyUsedTemporaries = ArrayList() + private val recentlyUsedTemporaries = ArrayList() private val myDispatcher = EventDispatcher.create(RunManagerListener::class.java)!! @@ -162,7 +162,9 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } return name ?: throw IllegalStateException("name is missed in the scheme data") } - }, streamProvider = schemeManagerProvider, autoSave = false) + + override fun isExternalizable(scheme: RunnerAndConfigurationSettingsImpl) = true + }, streamProvider = schemeManagerProvider, autoSave = false) private val stringIdToBeforeRunProvider by lazy { val result = ContainerUtil.newConcurrentMap>() @@ -265,8 +267,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent val key = "${factory.type.id}.${factory.name}" return lock.read { templateIdToConfiguration.get(key) } ?: lock.write { templateIdToConfiguration.getOrPut(key) { - val template = RunnerAndConfigurationSettingsImpl(this, factory.createTemplateConfiguration(project, this), true) - template.isSingleton = factory.isConfigurationSingletonByDefault + val template = createTemplateSettings(factory) (template.configuration as? UnknownRunConfiguration)?.let { it.isDoNotStore = true } @@ -278,6 +279,14 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } } + internal fun createTemplateSettings(factory: ConfigurationFactory) = RunnerAndConfigurationSettingsImpl(this, + factory.createTemplateConfiguration(project, this), isTemplate = true, singleton = factory.isConfigurationSingletonByDefault) + + override fun addConfiguration(settings: RunnerAndConfigurationSettings, isShared: Boolean) { + (settings as RunnerAndConfigurationSettingsImpl).isShared = isShared + addConfiguration(settings) + } + override fun addConfiguration(settings: RunnerAndConfigurationSettings) { val newId = settings.uniqueID var existingId: String? = null @@ -304,6 +313,9 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent if (!settings.isShared && existingId == null) { schemeManager.addScheme(settings as RunnerAndConfigurationSettingsImpl) } + if (settings.isShared && existingId != null) { + schemeManager.removeScheme(settings as RunnerAndConfigurationSettingsImpl) + } checkRecentsLimit() } @@ -329,9 +341,8 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent private fun refreshUsagesList(settings: RunnerAndConfigurationSettings) { if (settings.isTemporary) { lock.write { - val configuration = settings.configuration - recentlyUsedTemporaries.remove(configuration) - recentlyUsedTemporaries.add(0, configuration) + recentlyUsedTemporaries.remove(settings) + recentlyUsedTemporaries.add(0, settings) trimUsagesListToLimit() } } @@ -353,7 +364,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent val it = idToSettings.values.iterator() while (it.hasNext()) { val settings = it.next() - if (settings.isTemporary && !recentlyUsedTemporaries.contains(settings.configuration)) { + if (settings.isTemporary && !recentlyUsedTemporaries.contains(settings)) { if (removed == null) { immutableSortedSettingsList = null removed = SmartList() @@ -365,7 +376,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } } } - removed?.let { fireRunConfigurationsRemoved(it) } + removed?.forEach { myDispatcher.multicaster.runConfigurationRemoved(it) } } // comparator is null if want just to save current order (e.g. if want to keep order even after reload) @@ -532,7 +543,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } if (order == null) { - order = ArrayList() + order = ArrayList(idToSettings.size) } order.add(settings.uniqueID) } @@ -543,11 +554,10 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } val recentList = SmartList() - for (configuration in recentlyUsedTemporaries) { - if (configuration.type is UnknownConfigurationType) { + for (settings in recentlyUsedTemporaries) { + if (settings.type is UnknownConfigurationType) { continue } - val settings = getSettings(configuration) ?: continue recentList.add(settings.uniqueID) } if (!recentList.isEmpty()) { @@ -653,7 +663,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent @Suppress("DEPRECATION") com.intellij.openapi.util.JDOMExternalizableStringList.readList(list, recentNode) for (id in list) { - idToSettings.get(id)?.configuration?.let { + idToSettings.get(id)?.let { recentlyUsedTemporaries.add(it) } } @@ -702,7 +712,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } private fun clear(allConfigurations: Boolean) { - val configurations = lock.write { + val removedConfigurations = lock.write { immutableSortedSettingsList = null val configurations = if (allConfigurations) { @@ -739,7 +749,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } iconCache.clear() - fireRunConfigurationsRemoved(configurations) + removedConfigurations.forEach { myDispatcher.multicaster.runConfigurationRemoved(it) } } fun loadConfiguration(element: Element, isShared: Boolean): RunnerAndConfigurationSettings { @@ -749,7 +759,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } if (isShared) { - settings.level = RunnerAndConfigurationSettingsImpl.Level.PROJECT + settings.level = RunConfigurationLevel.PROJECT } doLoadConfiguration(element, settings) @@ -848,7 +858,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent private fun doMakeStable(settings: RunnerAndConfigurationSettings) { lock.write { - recentlyUsedTemporaries.remove(settings.configuration) + recentlyUsedTemporaries.remove(settings) immutableSortedSettingsList = null if (!customOrder.isEmpty) { isCustomOrderApplied = false @@ -856,13 +866,6 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } } - @Suppress("OverridingDeprecatedMember") - override fun makeStable(configuration: RunConfiguration) { - getSettings(configuration)?.let { - makeStable(it) - } - } - override fun > getBeforeRunTasks(taskProviderId: Key): List { val tasks = SmartList() val checkedTemplates = SmartList() @@ -1026,7 +1029,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent if (value && settings.isTemporary) { doMakeStable(settings) } - (settings as RunnerAndConfigurationSettingsImpl).level = RunnerAndConfigurationSettingsImpl.Level.PROJECT + (settings as RunnerAndConfigurationSettingsImpl).isShared = value fireRunConfigurationChanged(settings) } @@ -1077,21 +1080,19 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent fun removeNotExistingSharedConfigurations(existing: Set) { var removed: MutableList? = null lock.write { - val it = idToSettings.entries.iterator() - while (it.hasNext()) { - val entry = it.next() - val settings = entry.value + val iterator = idToSettings.values.iterator() + for (settings in iterator) { if (!settings.isTemplate && settings.isShared && !existing.contains(settings.uniqueID)) { if (removed == null) { immutableSortedSettingsList = null removed = SmartList() } removed!!.add(settings) - it.remove() + iterator.remove() } } } - fireRunConfigurationsRemoved(removed) + removed?.forEach { myDispatcher.multicaster.runConfigurationRemoved(it) } } fun fireBeginUpdate() { @@ -1106,13 +1107,6 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent myDispatcher.multicaster.runConfigurationChanged(settings, null) } - private fun fireRunConfigurationsRemoved(removed: List?) { - if (removed != null && !removed.isEmpty()) { - recentlyUsedTemporaries.removeAll(removed.map { it.configuration }) - removed.forEach { myDispatcher.multicaster.runConfigurationRemoved(it) } - } - } - private fun fireRunConfigurationSelected() { myDispatcher.multicaster.runConfigurationSelected() } @@ -1130,47 +1124,55 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } override fun removeConfiguration(settings: RunnerAndConfigurationSettings?) { - if (settings == null) { + if (settings != null) { + removeConfigurations(listOf(settings)) + } + } + + fun removeConfigurations(toRemove: Collection) { + if (toRemove.isEmpty()) { return } val changedSettings = SmartList() - var isRemoved = false + val removed = SmartList() lock.write { immutableSortedSettingsList = null val iterator = idToSettings.values.iterator() - for (otherSettings in iterator) { - if (otherSettings === settings) { - if (selectedConfigurationId === settings.uniqueID) { + for (settings in iterator) { + if (toRemove.contains(settings)) { + if (selectedConfigurationId == settings.uniqueID) { selectedConfiguration = null } iterator.remove() - recentlyUsedTemporaries.remove(settings.configuration) - isRemoved = true - } - - var changed = false - val otherConfiguration = otherSettings.configuration - val newList = otherConfiguration.beforeRunTasks.nullize()?.toMutableSmartList() ?: continue - val beforeRunTaskIterator = newList.iterator() - for (task in beforeRunTaskIterator) { - if (task is RunConfigurationBeforeRunProvider.RunConfigurableBeforeRunTask && task.settings === settings) { - beforeRunTaskIterator.remove() - changed = true - changedSettings.add(otherSettings) + if (!settings.isShared) { + schemeManager.removeScheme(settings as RunnerAndConfigurationSettingsImpl) } + recentlyUsedTemporaries.remove(settings) + removed.add(settings) } - if (changed) { - otherConfiguration.beforeRunTasks = newList + else { + var isChanged = false + val otherConfiguration = settings.configuration + val newList = otherConfiguration.beforeRunTasks.nullize()?.toMutableSmartList() ?: continue + val beforeRunTaskIterator = newList.iterator() + for (task in beforeRunTaskIterator) { + if (task is RunConfigurationBeforeRunProvider.RunConfigurableBeforeRunTask && toRemove.contains(task.settings)) { + beforeRunTaskIterator.remove() + isChanged = true + changedSettings.add(settings) + } + } + if (isChanged) { + otherConfiguration.beforeRunTasks = newList + } } } } - if (isRemoved) { - myDispatcher.multicaster.runConfigurationRemoved(settings) - } + removed.forEach { myDispatcher.multicaster.runConfigurationRemoved(it) } changedSettings.forEach { myDispatcher.multicaster.runConfigurationChanged(it, null) } } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt index fd6c6f261588..b65ba219805e 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt @@ -54,14 +54,15 @@ internal val TEMPLATE_FLAG_ATTRIBUTE = "default" val SINGLETON = "singleton" +enum class RunConfigurationLevel { + WORKSPACE, PROJECT, TEMPORARY +} + class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val manager: RunManagerImpl, private var _configuration: RunConfiguration? = null, private var isTemplate: Boolean = false, - private var singleton: Boolean = false) : Cloneable, RunnerAndConfigurationSettings, Comparable, Scheme, SerializableScheme { - enum class Level { - WORKSPACE, PROJECT, TEMPORARY - } - + private var singleton: Boolean = false, + var level: RunConfigurationLevel = RunConfigurationLevel.WORKSPACE) : Cloneable, RunnerAndConfigurationSettings, Comparable, Scheme, SerializableScheme { private val runnerSettings = object : RunnerItem("RunnerSettings") { override fun createSettings(runner: ProgramRunner<*>) = runner.createConfigurationData(InfoProvider(runner)) } @@ -70,7 +71,6 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m override fun createSettings(runner: ProgramRunner<*>) = configuration.createRunnerSettings(InfoProvider(runner)) } - var level = Level.WORKSPACE private var isEditBeforeRun = false private var isActivateToolWindowBeforeRun = true private var wasSingletonSpecifiedExplicitly = false @@ -82,12 +82,21 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m override fun isTemplate() = isTemplate - override fun isTemporary() = level == Level.TEMPORARY + override fun isTemporary() = level == RunConfigurationLevel.TEMPORARY - override fun isShared() = level == Level.PROJECT + override fun isShared() = level == RunConfigurationLevel.PROJECT override fun setTemporary(value: Boolean) { - level = if (value) Level.TEMPORARY else Level.WORKSPACE + level = if (value) RunConfigurationLevel.TEMPORARY else RunConfigurationLevel.WORKSPACE + } + + fun setShared(value: Boolean) { + if (value) { + level = RunConfigurationLevel.PROJECT + } + else if (level == RunConfigurationLevel.PROJECT) { + level = RunConfigurationLevel.WORKSPACE + } } override fun getConfiguration() = _configuration ?: UnknownConfigurationType.FACTORY.createTemplateConfiguration(manager.project) @@ -148,10 +157,10 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m isTemplate = element.getAttributeValue(TEMPLATE_FLAG_ATTRIBUTE).toBoolean() if (isShared) { - level = Level.PROJECT + level = RunConfigurationLevel.PROJECT } else { - level = if (element.getAttributeValue(TEMPORARY_ATTRIBUTE).toBoolean() || TEMP_CONFIGURATION == element.name) Level.TEMPORARY else Level.WORKSPACE + level = if (element.getAttributeValue(TEMPORARY_ATTRIBUTE).toBoolean() || TEMP_CONFIGURATION == element.name) RunConfigurationLevel.TEMPORARY else RunConfigurationLevel.WORKSPACE } isEditBeforeRun = (element.getAttributeValue(EDIT_BEFORE_RUN)).toBoolean() @@ -208,6 +217,7 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m } // do not call directly + // cannot be private - used externally fun writeExternal(element: Element) { val configuration = configuration val factory = configuration.factory @@ -248,6 +258,12 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m runnerSettings.getState(element) configurationPerRunnerSettings.getState(element) } + + if (configuration !is UnknownRunConfiguration) { + manager.writeBeforeRunTasks(this, configuration)?.let { + element.addContent(it) + } + } } private fun serializeConfigurationInto(configuration: RunConfiguration, element: Element) { @@ -262,13 +278,6 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m override fun writeScheme(): Element { val element = Element("configuration") writeExternal(element) - - val configuration = _configuration - if (configuration != null && configuration !is UnknownRunConfiguration) { - manager.writeBeforeRunTasks(this, configuration)?.let { - element.addContent(it) - } - } return element } @@ -367,13 +376,11 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m } if (isTemplate && _configuration != null) { - val templateConfiguration = configuration.factory.createTemplateConfiguration(manager.project, manager) - - val templateState = Element("state") - serializeConfigurationInto(templateConfiguration, templateState) - - val state = writeScheme() - if (JDOMUtil.areElementsEqual(state, templateState)) { + // todo optimize + val templateSettings = manager.createTemplateSettings(configuration.factory) + if (JDOMUtil.areElementsEqual(writeScheme(), templateSettings.writeScheme())) { + // this state doesn't mean that scheme will be removed - SchemeManager doesn't expect that scheme can be NON_PERSISTENT after UNCHANGED + // todo definitely, SchemeManager should be improved to support this case, but it is not safe to do right now return SchemeState.NON_PERSISTENT } } diff --git a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java index d1d65001330b..dde9ab53a120 100644 --- a/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java +++ b/platform/lang-impl/src/com/intellij/ide/bookmarks/actions/EditBookmarkDescriptionAction.java @@ -56,10 +56,12 @@ class EditBookmarkDescriptionAction extends DumbAwareAction { BookmarkManager.getInstance(myProject).editDescription(bookmark); - myPopup.setUiVisible(true); - final JComponent content = myPopup.getContent(); - if (content != null) { - myPopup.setSize(content.getPreferredSize()); + if (myPopup != null && !myPopup.isDisposed()) { + myPopup.setUiVisible(true); + final JComponent content = myPopup.getContent(); + if (content != null) { + myPopup.setSize(content.getPreferredSize()); + } } } diff --git a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index f456786637f4..2784fc130de6 100644 --- a/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/platform/lang-impl/src/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -251,7 +251,16 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre if (selectionPaths == null) return null; List result = new ArrayList<>(); for (TreePath selectionPath : selectionPaths) { - ContainerUtil.addIfNotNull(result, getNodeTreeValue((DefaultMutableTreeNode)selectionPath.getLastPathComponent())); + Object value = getNodeValue((DefaultMutableTreeNode)selectionPath.getLastPathComponent()); + if (value instanceof StructureViewTreeElement) { + ContainerUtil.addIfNotNull(result, ((StructureViewTreeElement)value).getValue()); + } + else if (value instanceof Group) { + ((Group)value).getChildren().stream() + .filter(element -> element instanceof StructureViewTreeElement) + .map(element -> ((StructureViewTreeElement)element).getValue()) + .forEach(element -> ContainerUtil.addIfNotNull(result, element)); + } } return ArrayUtil.toObjectArray(result); } @@ -275,12 +284,6 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre return userObject instanceof AbstractTreeNode ? ((AbstractTreeNode)userObject).getValue() : null; } - @Nullable - private static Object getNodeTreeValue(DefaultMutableTreeNode mutableTreeNode) { - Object value = getNodeValue(mutableTreeNode); - return value instanceof StructureViewTreeElement ? ((StructureViewTreeElement)value).getValue() : null; - } - private void addTreeMouseListeners() { EditSourceOnDoubleClickHandler.install(getTree()); CustomizationUtil.installPopupHandler(getTree(), IdeActions.GROUP_STRUCTURE_VIEW_POPUP, ActionPlaces.STRUCTURE_VIEW_POPUP); diff --git a/platform/platform-api/src/com/intellij/ui/ExpandedItemListCellRendererWrapper.java b/platform/platform-api/src/com/intellij/ui/ExpandedItemListCellRendererWrapper.java index 9833e17006ec..f9661958a26e 100644 --- a/platform/platform-api/src/com/intellij/ui/ExpandedItemListCellRendererWrapper.java +++ b/platform/platform-api/src/com/intellij/ui/ExpandedItemListCellRendererWrapper.java @@ -16,9 +16,9 @@ package com.intellij.ui; import com.intellij.ide.ui.AntialiasingType; +import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; -import sun.swing.SwingUtilities2; import javax.swing.*; import java.awt.*; @@ -34,7 +34,7 @@ public class ExpandedItemListCellRendererWrapper implements ListCellRenderer { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - list.putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, AntialiasingType.getAAHintForSwingComponent()); + GraphicsUtil.setAntialiasingType(list, AntialiasingType.getAAHintForSwingComponent()); Component result = myWrappee.getListCellRendererComponent(list, UIUtil.htmlInjectionGuard(value), index, isSelected, cellHasFocus); if (!myHandler.getExpandedItems().contains(index)) return result; Rectangle bounds = result.getBounds(); diff --git a/platform/platform-api/src/com/intellij/ui/components/breadcrumbs/Breadcrumbs.java b/platform/platform-api/src/com/intellij/ui/components/breadcrumbs/Breadcrumbs.java index 50c026a2b324..565bd84814d5 100644 --- a/platform/platform-api/src/com/intellij/ui/components/breadcrumbs/Breadcrumbs.java +++ b/platform/platform-api/src/com/intellij/ui/components/breadcrumbs/Breadcrumbs.java @@ -26,7 +26,6 @@ import com.intellij.ui.paint.RectanglePainter; import com.intellij.util.ui.AbstractLayoutManager; import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.MouseEventHandler; -import com.intellij.util.ui.RegionPainter; import org.intellij.lang.annotations.JdkConstants.FontStyle; import java.awt.Color; @@ -52,7 +51,7 @@ import static javax.swing.SwingUtilities.isLeftMouseButton; /** * @author Sergey.Malenkov */ -public class Breadcrumbs extends JComponent implements RegionPainter { +public class Breadcrumbs extends JComponent { @SuppressWarnings("FieldCanBeLocal") private final MouseHandler containerMouseHandler = new MouseHandler(event -> getCrumb(event.getX(), event.getY())); private final MouseHandler componentMouseHandler = new MouseHandler(event -> getCrumb(event.getComponent())); @@ -144,8 +143,7 @@ public class Breadcrumbs extends JComponent implements RegionPainter { super.paintComponent(g); } - @Override - public void paint(Graphics2D g, int x, int y, int width, int height, Crumb crumb) { + protected void paint(Graphics2D g, int x, int y, int width, int height, Crumb crumb) { int scale = getScale(this); EffectType type = getEffectType(crumb); Color color = getEffectColor(crumb); @@ -179,23 +177,27 @@ public class Breadcrumbs extends JComponent implements RegionPainter { } else if (background != null) { g.setColor(background); - g.fillRect(x + scale, y, width - 2 * scale, height); - } - else { - int thickness = scale * getThickness(crumb); - if (thickness > 0) { - Color foreground = getForeground(crumb); - if (foreground != null) { - g.setColor(ColorUtil.toAlpha(foreground, (int)(.6 * foreground.getAlpha()))); - paint(g, x, y, width, height, thickness); - } + g.fillRect(x, y, width, height); + if (isSelected(crumb)) { + paint(g, x, y, width, height, crumb, scale * 2); } } + else if (isSelected(crumb)) { + paint(g, x, y, width, height, crumb, scale * 2); + } + else if (isHovered(crumb)) { + paint(g, x, y, width, height, crumb, scale); + } } - protected void paint(Graphics2D g, int x, int y, int width, int height, int thickness) { - int offset = 4 * getScale(this); - g.fillRect(x + offset, y + height - thickness, width - offset - offset, thickness); + protected void paint(Graphics2D g, int x, int y, int width, int height, Crumb crumb, int thickness) { + if (thickness > 0) { + Color foreground = getForeground(crumb); + if (foreground != null) { + g.setColor(ColorUtil.toAlpha(foreground, (int)(.6 * foreground.getAlpha()))); + g.fillRect(x, y + height - thickness, width, thickness); + } + } } protected Font getFont(Crumb crumb) { @@ -267,12 +269,6 @@ public class Breadcrumbs extends JComponent implements RegionPainter { return EditorColors.BREADCRUMBS_DEFAULT; } - protected int getThickness(Crumb crumb) { - if (isSelected(crumb)) return 2; - if (isHovered(crumb)) return 1; - return 0; - } - private Crumb getCrumb(int x, int y) { return getCrumb(getComponentAt(x, y)); } diff --git a/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java b/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java index b62b821ec5e3..04e470ebf2f0 100644 --- a/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java +++ b/platform/platform-api/src/com/intellij/ui/components/editors/JBComboBoxTableCellEditorComponent.java @@ -20,7 +20,6 @@ import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupAdapter; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.LightweightWindowEvent; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.TableUtil; import com.intellij.ui.awt.RelativePoint; @@ -32,9 +31,12 @@ import com.intellij.util.Function; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.EmptyIcon; -import sun.swing.SwingUtilities2; +import com.intellij.util.ui.GraphicsUtil; -import javax.accessibility.*; +import javax.accessibility.AccessibleContext; +import javax.accessibility.AccessibleRole; +import javax.accessibility.AccessibleState; +import javax.accessibility.AccessibleStateSet; import javax.swing.*; import javax.swing.event.TableModelEvent; import java.awt.*; @@ -83,7 +85,7 @@ public class JBComboBoxTableCellEditorComponent extends JBLabel { } else { label.setIcon(getEmptyIcon()); } - label.putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, AntialiasingType.getAAHintForSwingComponent()); + GraphicsUtil.setAntialiasingType(label, AntialiasingType.getAAHintForSwingComponent()); return label; } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java index 85a0d1157d3b..e8184f6beb2e 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java @@ -34,9 +34,9 @@ import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.ui.FontComboBox; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.components.JBCheckBox; +import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; -import sun.swing.SwingUtilities2; import javax.swing.*; import javax.swing.event.ChangeEvent; @@ -174,7 +174,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab settings.setIdeAAType((AntialiasingType)myComponent.myAntialiasingInIDE.getSelectedItem()); for (Window w : Window.getWindows()) { for (JComponent c : UIUtil.uiTraverser(w).filter(JComponent.class)) { - c.putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, AntialiasingType.getAAHintForSwingComponent()); + GraphicsUtil.setAntialiasingType(c, AntialiasingType.getAAHintForSwingComponent()); } } shouldUpdateUI = true; @@ -522,10 +522,8 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab } private static class AAListCellRenderer extends ListCellRendererWrapper { - private static final SwingUtilities2.AATextInfo SUBPIXEL_HINT = new SwingUtilities2.AATextInfo( - RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB, UIUtil.getLcdContrastValue()); - private static final SwingUtilities2.AATextInfo GREYSCALE_HINT = new SwingUtilities2.AATextInfo( - RenderingHints.VALUE_TEXT_ANTIALIAS_ON, UIUtil.getLcdContrastValue()); + private static final Object SUBPIXEL_HINT = GraphicsUtil.createAATextInfo(RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); + private static final Object GREYSCALE_HINT = GraphicsUtil.createAATextInfo(RenderingHints.VALUE_TEXT_ANTIALIAS_ON); private final boolean useEditorAASettings; @@ -537,13 +535,13 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab @Override public void customize(JList list, AntialiasingType value, int index, boolean selected, boolean hasFocus) { if (value == AntialiasingType.SUBPIXEL) { - setClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, SUBPIXEL_HINT); + GraphicsUtil.generatePropertiesForAntialiasing(SUBPIXEL_HINT, this::setClientProperty); } else if (value == AntialiasingType.GREYSCALE) { - setClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, GREYSCALE_HINT); + GraphicsUtil.generatePropertiesForAntialiasing(GREYSCALE_HINT, this::setClientProperty); } else if (value == AntialiasingType.OFF) { - setClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, null); + GraphicsUtil.generatePropertiesForAntialiasing(null, this::setClientProperty); } if (useEditorAASettings) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/search.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/search.png index 55d706146b81..ba0da598e300 100644 Binary files a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/search.png and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/search.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/search@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/search@2x.png index 512008f94a0a..7e6e4bd3444b 100644 Binary files a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/search@2x.png and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/graphite/search@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/search.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/search.png index 55d706146b81..ba0da598e300 100644 Binary files a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/search.png and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/search.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/search@2x.png b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/search@2x.png index 512008f94a0a..7e6e4bd3444b 100644 Binary files a/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/search@2x.png and b/platform/platform-impl/src/com/intellij/ide/ui/laf/icons/search@2x.png differ diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJTextFieldUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJTextFieldUI.java index d23ed1c5d404..2c168afac37b 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJTextFieldUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJTextFieldUI.java @@ -85,7 +85,7 @@ public class MacIntelliJTextFieldUI extends TextFieldWithPopupHandlerUI { } private static Icon getSearchIcon(Component c) { - return MacIntelliJIconCache.getIcon(isSearchFieldWithHistoryPopup(c) ? "searchFieldWithHistory" : "searchFieldLabel"); + return MacIntelliJIconCache.getIcon(isSearchFieldWithHistoryPopup(c) ? "searchFieldWithHistory" : "search"); } protected Point getSearchIconCoord() { diff --git a/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java b/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java index 56bd4e922ca5..9fac86c7f8b2 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java @@ -1072,8 +1072,10 @@ public class NotificationsManagerImpl extends NotificationsManager { } private static void showPopup(@NotNull LinkLabel link, @NotNull DefaultActionGroup group) { - ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group); - menu.getComponent().show(link, JBUI.scale(-10), link.getHeight() + JBUI.scale(2)); + if (link.isShowing()) { + ActionPopupMenu menu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group); + menu.getComponent().show(link, JBUI.scale(-10), link.getHeight() + JBUI.scale(2)); + } } private static class MyNotificationListener extends NotificationsAdapter { diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 6de889d52422..1160dc20c6ae 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -110,7 +110,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private final boolean myIsInternal; private final String myName; - private final Stack myWriteActionsStack = new Stack<>(); // accessed from EDT only, no need to sync + private final Stack myWriteActionsStack = new Stack<>(); // contents modified in write action, read in read action private final TransactionGuardImpl myTransactionGuard = new TransactionGuardImpl(); private int myWriteStackBase; private volatile Thread myWriteActionThread; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ToggleShowBreadcrumbsGloballyAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ToggleShowBreadcrumbsGloballyAction.java index 4d610f8250bc..b536a9384950 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ToggleShowBreadcrumbsGloballyAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ToggleShowBreadcrumbsGloballyAction.java @@ -29,7 +29,8 @@ public class ToggleShowBreadcrumbsGloballyAction extends ToggleAction implements @Override public void setSelected(AnActionEvent event, boolean selected) { - EditorSettingsExternalizable.getInstance().setBreadcrumbsShown(selected); - UISettings.getInstance().fireUISettingsChanged(); + if (EditorSettingsExternalizable.getInstance().setBreadcrumbsShown(selected)) { + UISettings.getInstance().fireUISettingsChanged(); + } } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java index 1c113ed4479b..81d53d2f114a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/ex/EditorSettingsExternalizable.java @@ -31,6 +31,8 @@ import org.jetbrains.annotations.Nullable; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; import java.util.Set; @State(name = "EditorSettings", storages = @Storage("editor.xml")) @@ -96,6 +98,21 @@ public class EditorSettingsExternalizable implements PersistentStateComponent mapLanguageBreadcrumbs = new HashMap<>(); + + @SuppressWarnings("unused") + public Map getLanguageBreadcrumbsMap() { + return mapLanguageBreadcrumbs; + } + + @SuppressWarnings("unused") + public void setLanguageBreadcrumbsMap(Map map) { + if (this.mapLanguageBreadcrumbs != map) { + this.mapLanguageBreadcrumbs.clear(); + this.mapLanguageBreadcrumbs.putAll(map); + } + } } private static final String COMPOSITE_PROPERTY_SEPARATOR = ":"; @@ -242,12 +259,40 @@ public class EditorSettingsExternalizable implements PersistentStateComponent T unwrap(Configurable configurable, Class type) { diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/PotemkinProgress.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/PotemkinProgress.java index b78f1b570a4e..9e1caefe6072 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/PotemkinProgress.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/PotemkinProgress.java @@ -127,8 +127,8 @@ public class PotemkinProgress extends ProgressWindow { } @Nullable - private JRootPane considerShowingDialog(long now) { - if (now - myLastUiUpdate > DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS) { + protected JRootPane considerShowingDialog(long now) { + if (isReadyShowing(now)) { getDialog().myRepaintRunnable.run(); showDialog(); return getDialog().getPanel().getRootPane(); @@ -136,6 +136,10 @@ public class PotemkinProgress extends ProgressWindow { return null; } + protected boolean isReadyShowing(long now) { + return now - myLastUiUpdate > myDelayInMillis; + } + private boolean timeToPaint(long now) { if (now - myLastUiUpdate <= ProgressDialog.UPDATE_INTERVAL) { return false; diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index 9caffb4da0a3..8404c0b9e994 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -61,7 +61,7 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro protected boolean myBackgrounded; private String myProcessId = ""; @Nullable private volatile Runnable myBackgroundHandler; - private int myDelayInMillis = DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS; + protected int myDelayInMillis = DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS; @FunctionalInterface public interface Listener { @@ -293,7 +293,7 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro SwingUtilities.invokeLater(EmptyRunnable.INSTANCE); // Just to give blocking dispatching a chance to go out. } - private boolean isDialogShowing() { + protected boolean isDialogShowing() { return myDialog != null && myDialog.getPanel() != null && myDialog.getPanel().isShowing(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java index 2a4ba9550864..fd78f15ab9b8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java @@ -53,13 +53,13 @@ import com.intellij.ui.mac.foundation.ID; import com.intellij.ui.mac.foundation.MacUtil; import com.intellij.util.IJSwingUtilities; import com.intellij.util.ReflectionUtil; +import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.OwnerOptional; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import sun.swing.SwingUtilities2; import javax.swing.*; import java.awt.*; @@ -906,7 +906,7 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer implements FocusTra myOpened = true; final DialogWrapper activeWrapper = getActiveWrapper(); for (JComponent c : UIUtil.uiTraverser(e.getWindow()).filter(JComponent.class)) { - c.putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, AntialiasingType.getAAHintForSwingComponent()); + GraphicsUtil.setAntialiasingType(c, AntialiasingType.getAAHintForSwingComponent()); } if (activeWrapper == null) { myFocusedCallback.setRejected(); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java index d065dee27115..5960f8cd9e44 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java @@ -759,7 +759,7 @@ public final class WindowManagerImpl extends WindowManagerEx implements NamedCom private int updateFrameBounds(IdeFrameImpl frame) { int extendedState = frame.getExtendedState(); if (SystemInfo.isMacOSLion) { - @SuppressWarnings("deprecation") ComponentPeer peer = frame.getPeer(); + ComponentPeer peer = frame.getPeer(); if (peer instanceof FramePeer) { // frame.state is not updated by jdk so get it directly from peer extendedState = ((FramePeer)peer).getState(); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java index 9d3867022d19..f728b6a82e9e 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/X11UiUtil.java @@ -337,7 +337,7 @@ public class X11UiUtil { private static boolean hasWindowProperty(JFrame frame, long name, long expected) { if (X11 == null) return false; try { - @SuppressWarnings("deprecation") ComponentPeer peer = frame.getPeer(); + ComponentPeer peer = frame.getPeer(); long window = (Long)X11.getWindow.invoke(peer); long[] values = X11.getLongArrayProperty(window, name, XA_ATOM); if (values != null) { @@ -357,7 +357,7 @@ public class X11UiUtil { if (X11 == null) return; try { - @SuppressWarnings("deprecation") ComponentPeer peer = frame.getPeer(); + ComponentPeer peer = frame.getPeer(); long window = (Long)X11.getWindow.invoke(peer); long screen = (Long)X11.getScreenNumber.invoke(peer); long rootWindow = X11.getRootWindow(screen); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/BaseLabel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/BaseLabel.java index d5e16d371260..b7ce4d3448fa 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/BaseLabel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/content/BaseLabel.java @@ -21,9 +21,9 @@ import com.intellij.ui.EngravedTextGraphics; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.ui.content.Content; +import com.intellij.util.ui.GraphicsUtil; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.WatermarkIcon; -import sun.swing.SwingUtilities2; import javax.swing.*; import java.awt.*; @@ -75,7 +75,7 @@ public class BaseLabel extends JLabel { protected void paintComponent(final Graphics g) { final Color fore = myUi.myWindow.isActive() ? myActiveFg : myPassiveFg; setForeground(fore); - putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, AntialiasingType.getAAHintForSwingComponent()); + GraphicsUtil.setAntialiasingType(this, AntialiasingType.getAAHintForSwingComponent()); super.paintComponent(_getGraphics((Graphics2D)g)); } diff --git a/platform/platform-impl/src/com/intellij/ui/FrameState.java b/platform/platform-impl/src/com/intellij/ui/FrameState.java index 986d23b4d497..fcdf076419cd 100644 --- a/platform/platform-impl/src/com/intellij/ui/FrameState.java +++ b/platform/platform-impl/src/com/intellij/ui/FrameState.java @@ -60,7 +60,6 @@ public class FrameState { state = ((Frame)component).getExtendedState(); if (SystemInfo.isMacOSLion) { // workaround: frame.state is not updated by jdk so get it directly from peer - @SuppressWarnings("deprecation") ComponentPeer peer = component.getPeer(); if (peer instanceof FramePeer) { state = ((FramePeer)peer).getState(); diff --git a/platform/platform-impl/src/com/intellij/ui/Win7TaskBar.java b/platform/platform-impl/src/com/intellij/ui/Win7TaskBar.java index 04446cae547f..4aa7d317550a 100644 --- a/platform/platform-impl/src/com/intellij/ui/Win7TaskBar.java +++ b/platform/platform-impl/src/com/intellij/ui/Win7TaskBar.java @@ -27,6 +27,8 @@ import com.sun.jna.platform.win32.*; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.win32.StdCallLibrary; import com.sun.jna.win32.W32APIOptions; +import org.jetbrains.annotations.NotNull; +import sun.awt.AWTAccessor; import java.awt.*; import java.awt.peer.ComponentPeer; @@ -177,9 +179,10 @@ class Win7TaskBar { User32Ex.INSTANCE.FlashWindow(getHandle(frame), true); } - private static WinDef.HWND getHandle(IdeFrame frame) { + private static WinDef.HWND getHandle(@NotNull IdeFrame frame) { + Component component = (Component)frame; try { - ComponentPeer peer = ((Component)frame).getPeer(); + ComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(component); Method getHWnd = peer.getClass().getMethod("getHWnd"); return new WinDef.HWND(new Pointer((Long)getHWnd.invoke(peer))); } diff --git a/platform/platform-resources-en/src/messages/VcsBundle.properties b/platform/platform-resources-en/src/messages/VcsBundle.properties index d699c9bb44a9..f9e766056ddd 100644 --- a/platform/platform-resources-en/src/messages/VcsBundle.properties +++ b/platform/platform-resources-en/src/messages/VcsBundle.properties @@ -466,7 +466,7 @@ outdated.version.text.deleted=Outdated version. Deleted by {0} {1}: {2} current.version.text={4}

Current version is {3}.
Modified by {0}
{1}
{2} committed.changes.filter.title=Filter by committed.changes.group.title=Group by -committed.changes.regex.title=Regex +committed.changes.regex.title=Re&gex changelist.details.committed.format=Committed by {0} {1} incoming.changes.indicator.tooltip={0} incoming changelists available column.name.type=Type diff --git a/platform/platform-resources-en/src/tips/SelectTasks.html b/platform/platform-resources-en/src/tips/SelectTasks.html index 78f21d54b769..f1d7b6739913 100644 --- a/platform/platform-resources-en/src/tips/SelectTasks.html +++ b/platform/platform-resources-en/src/tips/SelectTasks.html @@ -7,7 +7,7 @@

When working with a lengthy list of tasks, you don't need to delete them one by one. Select several tasks, using Shift or Control/Command keys, click the right arrow, and then click -Remove. +Remove.

diff --git a/platform/platform-resources/src/DefaultColorSchemesManager.xml b/platform/platform-resources/src/DefaultColorSchemesManager.xml index 0cddc35dc6e1..474265c208a4 100644 --- a/platform/platform-resources/src/DefaultColorSchemesManager.xml +++ b/platform/platform-resources/src/DefaultColorSchemesManager.xml @@ -1045,7 +1045,7 @@