diff --git a/bin/scripts/unix/idea.sh b/bin/scripts/unix/idea.sh index 9c3ce47141c7..7df94672fb65 100755 --- a/bin/scripts/unix/idea.sh +++ b/bin/scripts/unix/idea.sh @@ -158,9 +158,9 @@ VM_OPTIONS_FILE="" if [ -n "$@@product_uc@@_VM_OPTIONS" -a -r "$@@product_uc@@_VM_OPTIONS" ]; then # explicit VM_OPTIONS_FILE="$@@product_uc@@_VM_OPTIONS" -elif [ -r "$HOME/.@@system_selector@@/@@vm_options@@$BITS.vmoptions" ]; then +elif [ -r "$HOME/.@@system_selector@@/config/@@vm_options@@$BITS.vmoptions" ]; then # user-overridden - VM_OPTIONS_FILE="$HOME/.@@system_selector@@/@@vm_options@@$BITS.vmoptions" + VM_OPTIONS_FILE="$HOME/.@@system_selector@@/config/@@vm_options@@$BITS.vmoptions" elif [ -r "$IDE_BIN_HOME/@@vm_options@@$BITS.vmoptions" ]; then # default, standard installation VM_OPTIONS_FILE="$IDE_BIN_HOME/@@vm_options@@$BITS.vmoptions" diff --git a/bin/scripts/win/idea.bat b/bin/scripts/win/idea.bat index 88ceb9b6d396..0069cef53a83 100644 --- a/bin/scripts/win/idea.bat +++ b/bin/scripts/win/idea.bat @@ -64,14 +64,14 @@ IF EXIST "%JRE%\lib\amd64" SET BITS=64 :: --------------------------------------------------------------------- IF NOT "%@@product_uc@@_PROPERTIES%" == "" SET IDE_PROPERTIES_PROPERTY="-Didea.properties.file=%@@product_uc@@_PROPERTIES%" -SET USER_VM_OPTIONS_FILE=%USERPROFILE%\.@@system_selector@@\@@vm_options@@.vmoptions +SET USER_VM_OPTIONS_FILE=%USERPROFILE%\.@@system_selector@@\config\@@vm_options@@.vmoptions SET VM_OPTIONS_FILE=%IDE_BIN_DIR%\@@vm_options@@.vmoptions IF EXIST "%IDE_BIN_DIR%\win\@@vm_options@@.vmoptions" SET VM_OPTIONS_FILE=%IDE_BIN_DIR%\win\@@vm_options@@.vmoptions IF EXIST %USER_VM_OPTIONS_FILE% SET VM_OPTIONS_FILE=%USER_VM_OPTIONS_FILE% IF NOT "%@@product_uc@@_VM_OPTIONS%" == "" SET VM_OPTIONS_FILE=%@@product_uc@@_VM_OPTIONS% SET ACC= -FOR /F "usebackq delims=" %%i IN ("%VM_OPTIONS_FILE%") DO CALL "%IDE_BIN_DIR%\append.bat" "%%i" +FOR /F "eol=# usebackq delims=" %%i IN ("%VM_OPTIONS_FILE%") DO CALL "%IDE_BIN_DIR%\append.bat" "%%i" IF EXIST "%VM_OPTIONS_FILE%" SET ACC=%ACC% -Djb.vmOptionsFile="%VM_OPTIONS_FILE%" SET COMMON_JVM_ARGS="-XX:ErrorFile=%USERPROFILE%\java_error_in_@@product_uc@@_%%p.log" "-XX:HeapDumpPath=%USERPROFILE%\java_error_in_@@product_uc@@.hprof" "-Xbootclasspath/a:%IDE_HOME%/lib/boot.jar" -Didea.paths.selector=@@system_selector@@ %IDE_PROPERTIES_PROPERTY% diff --git a/build/gant.xml b/build/gant.xml index f5d132f4df94..6e1e7c6c3efd 100644 --- a/build/gant.xml +++ b/build/gant.xml @@ -1,6 +1,5 @@ - @@ -21,16 +20,6 @@ - - - - - - - - - - diff --git a/build/scripts/idea_community.gant b/build/scripts/idea_community.gant index 8c0a6545572b..bd80d28014a3 100644 --- a/build/scripts/idea_community.gant +++ b/build/scripts/idea_community.gant @@ -42,4 +42,14 @@ target('update-from-sources': 'Update locally installed distribution from compil //when IDEA CE is updated from IDEA UE sources project should be loaded from IDEA UE directory String projectHome = isDefined("devIdeaHome") ? devIdeaHome : home new IdeaCommunityBuilder(home, binding, options, projectHome).buildUnpackedDistribution(deploy) -} \ No newline at end of file +} + +private boolean isDefined(String key) { + try { + this[key] + return true + } + catch (MissingPropertyException ignored) { + return false + } +} diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index c3d7002bf503..6bccdfbbf0d0 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -150,12 +150,9 @@ private void setupKotlin() { } private boolean ensureKotlinCompilerAddedToClassPath() { - try { - Class.forName("org.jetbrains.kotlin.jps.build.KotlinBuilder") + if (getClass().getResource("/org/jetbrains/kotlin/jps/build/KotlinBuilder.class") != null) { return true } - catch (ClassNotFoundException ignored) { - } def kotlinPluginLibPath = "$home/build/dependencies/build/Kotlin/lib" if (!new File(kotlinPluginLibPath).exists()) { diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index b1b0c24ac8c5..b40ec67fb65e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -160,8 +160,9 @@ public class BuildManager implements Disposable { private final BuildProcessClasspathManager myClasspathManager = new BuildProcessClasspathManager(); private final ExecutorService myRequestsProcessor = SequentialTaskExecutor.createSequentialApplicationPoolExecutor("BuildManager requestProcessor pool"); private final Map myProjectDataMap = Collections.synchronizedMap(new HashMap()); + private volatile int myFileChangeCounter = 0; - private final BuildManagerPeriodicTask myAutoMakeTask = new BuildManagerPeriodicTask(this) { + private final BuildManagerPeriodicTask myAutoMakeTask = new BuildManagerPeriodicTask() { @Override protected int getDelay() { return Registry.intValue("compiler.automake.trigger.delay"); @@ -173,7 +174,7 @@ public class BuildManager implements Disposable { } }; - private final BuildManagerPeriodicTask myDocumentSaveTask = new BuildManagerPeriodicTask(this) { + private final BuildManagerPeriodicTask myDocumentSaveTask = new BuildManagerPeriodicTask() { @Override protected int getDelay() { return Registry.intValue("compiler.document.save.trigger.delay"); @@ -303,8 +304,14 @@ public class BuildManager implements Disposable { conn.subscribe(BatchFileChangeListener.TOPIC, new BatchFileChangeListener.Adapter() { @Override public void batchChangeStarted(Project project) { + myFileChangeCounter++; cancelAutoMakeTasks(project); } + + @Override + public void batchChangeCompleted(Project project) { + myFileChangeCounter--; + } }); EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() { @@ -1438,7 +1445,7 @@ public class BuildManager implements Disposable { } } - private abstract static class BuildManagerPeriodicTask implements Runnable { + private abstract class BuildManagerPeriodicTask implements Runnable { private final Alarm myAlarm; private final AtomicBoolean myInProgress = new AtomicBoolean(false); private final Runnable myTaskRunnable = () -> { @@ -1450,8 +1457,8 @@ public class BuildManager implements Disposable { } }; - protected BuildManagerPeriodicTask(@NotNull Disposable disposable) { - myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, disposable); + protected BuildManagerPeriodicTask() { + myAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, BuildManager.this); } public final void schedule() { @@ -1470,7 +1477,7 @@ public class BuildManager implements Disposable { @Override public final void run() { - if (!HeavyProcessLatch.INSTANCE.isRunning() && !myInProgress.getAndSet(true)) { + if (!HeavyProcessLatch.INSTANCE.isRunning() && myFileChangeCounter <= 0 && !myInProgress.getAndSet(true)) { try { ApplicationManager.getApplication().executeOnPooledThread(myTaskRunnable); } diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/filtering/ConditionChecker.java b/java/debugger/impl/src/com/intellij/debugger/memory/filtering/ConditionChecker.java index 9dcbc4fdba22..50c6eb94b5aa 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/filtering/ConditionChecker.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/filtering/ConditionChecker.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. @@ -21,13 +21,9 @@ import org.jetbrains.annotations.NotNull; /** * @author Vitaliy.Bibaev */ +@FunctionalInterface public interface ConditionChecker { CheckingResult check(@NotNull ObjectReference ref); - ConditionChecker ALL_MATCHED_CHECKER = new ConditionChecker() { - @Override - public CheckingResult check(@NotNull ObjectReference ref) { - return CheckingResultImpl.SUCCESS; - } - }; + ConditionChecker ALL_MATCHED_CHECKER = ref -> CheckingResultImpl.SUCCESS; } diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/utils/InstancesProvider.java b/java/debugger/impl/src/com/intellij/debugger/memory/utils/InstancesProvider.java index 159c5884e5ff..43ea9f964b3f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/utils/InstancesProvider.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/utils/InstancesProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +@FunctionalInterface public interface InstancesProvider { @NotNull List getInstances(int limit); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java index 11d828cffe49..e260a8b6d000 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java @@ -32,6 +32,7 @@ import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.ui.JavaDebuggerSupport; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -42,7 +43,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; @@ -247,7 +247,7 @@ public class BreakpointManager { public ExceptionBreakpoint addExceptionBreakpoint(@NotNull final String exceptionClassName, final String packageName) { ApplicationManager.getApplication().assertIsDispatchThread(); final JavaExceptionBreakpointType type = XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class); - return ApplicationManager.getApplication().runWriteAction((Computable)() -> { + return WriteAction.compute(() -> { XBreakpoint xBreakpoint = XDebuggerManager.getInstance(myProject).getBreakpointManager() .addBreakpoint(type, new JavaExceptionBreakpointProperties(exceptionClassName, packageName)); Breakpoint javaBreakpoint = getJavaBreakpoint(xBreakpoint); @@ -279,7 +279,7 @@ public class BreakpointManager { private > XLineBreakpoint addXLineBreakpoint(Class> typeCls, Document document, final int lineIndex) { final XBreakpointType type = XDebuggerUtil.getInstance().findBreakpointType(typeCls); final VirtualFile file = FileDocumentManager.getInstance().getFile(document); - return ApplicationManager.getApplication().runWriteAction((Computable)() -> XDebuggerManager.getInstance(myProject).getBreakpointManager() + return WriteAction.compute(() -> XDebuggerManager.getInstance(myProject).getBreakpointManager() .addLineBreakpoint((XLineBreakpointType)type, file.getUrl(), lineIndex, ((XLineBreakpointType)type).createBreakpointProperties(file, lineIndex))); } @@ -443,7 +443,7 @@ public class BreakpointManager { private > XBreakpoint createXBreakpoint(Class> typeCls) { final XBreakpointType type = XDebuggerUtil.getInstance().findBreakpointType(typeCls); - return ApplicationManager.getApplication().runWriteAction((Computable)() -> XDebuggerManager.getInstance(myProject).getBreakpointManager().addBreakpoint((XBreakpointType)type, type.createProperties())); + return WriteAction.compute(() -> XDebuggerManager.getInstance(myProject).getBreakpointManager().addBreakpoint((XBreakpointType)type, type.createProperties())); } private > XLineBreakpoint createXLineBreakpoint(Class> typeCls, @@ -479,7 +479,7 @@ public class BreakpointManager { if (breakpoint == null) { return; } - ApplicationManager.getApplication().runWriteAction(() -> getXBreakpointManager().removeBreakpoint(breakpoint.myXBreakpoint)); + WriteAction.run(() -> getXBreakpointManager().removeBreakpoint(breakpoint.myXBreakpoint)); } public void writeExternal(@NotNull final Element parentNode) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java index d40bc8023c8c..410a8221b751 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ import com.intellij.CommonBundle; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.HelpID; import com.intellij.icons.AllIcons; -import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; @@ -146,7 +146,7 @@ public class JavaFieldBreakpointType extends JavaLineBreakpointTypeBase { + WriteAction.run(() -> { XLineBreakpoint fieldBreakpoint = XDebuggerManager.getInstance(project).getBreakpointManager() .addLineBreakpoint(JavaFieldBreakpointType.this, psiFile.getVirtualFile().getUrl(), line, new JavaFieldBreakpointProperties(fieldName, className)); result.set(fieldBreakpoint); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java index 990850708e55..ecab88d344bd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaWildcardMethodBreakpointType.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,8 @@ package com.intellij.debugger.ui.breakpoints; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.HelpID; import com.intellij.icons.AllIcons; -import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.registry.Registry; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.breakpoints.XBreakpoint; @@ -104,7 +103,7 @@ public class JavaWildcardMethodBreakpointType extends JavaBreakpointTypeBase>)() -> { + return WriteAction.compute(() -> { JavaMethodBreakpointProperties properties = new JavaMethodBreakpointProperties(dialog.getClassPattern(), dialog.getMethodName()); if (Registry.is("debugger.emulate.method.breakpoints")) { properties.EMULATED = true; // create all new emulated diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java index 27cb4d410370..d6d35f6ee017 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java @@ -45,6 +45,7 @@ import com.intellij.platform.ProjectTemplate; import com.intellij.platform.ProjectTemplateEP; import com.intellij.platform.ProjectTemplatesFactory; import com.intellij.platform.templates.*; +import com.intellij.psi.impl.DebugUtil; import com.intellij.ui.CollectionListModel; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ListSpeedSearch; @@ -233,6 +234,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D } final String groupId = PropertiesComponent.getInstance().getValue(PROJECT_WIZARD_GROUP); + LOG.debug("saved groupId=" + groupId); if (groupId != null) { TemplatesGroup group = ContainerUtil.find(groups, group1 -> groupId.equals(group1.getId())); if (group != null) { @@ -375,6 +377,9 @@ public class ProjectTypeStep extends ModuleWizardStep implements SettingsStep, D if (group == null || group == myLastSelectedGroup) return; myLastSelectedGroup = group; PropertiesComponent.getInstance().setValue(PROJECT_WIZARD_GROUP, group.getId() ); + if (LOG.isDebugEnabled()) { + LOG.debug("projectTypeChanged: " + group.getId() + " " + DebugUtil.currentStackTrace()); + } ModuleBuilder groupModuleBuilder = group.getModuleBuilder(); mySettingsStep = null; diff --git a/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.form b/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.form index 12d569c4dc71..3059e22370da 100644 --- a/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.form +++ b/java/idea-ui/src/com/intellij/jarRepository/propertiesEditor/RepositoryLibraryPropertiesEditor.form @@ -134,7 +134,7 @@ @@ -148,7 +148,7 @@ diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java index 7da422c36c5a..4cc52be1aa29 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/MarkerType.java @@ -462,7 +462,7 @@ public class MarkerType { return super.process(psiMethod); } }); - if (myMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + if (ReadAction.compute(() -> myMethod.hasModifierProperty(PsiModifier.ABSTRACT))) { PsiClass psiClass = ReadAction.compute(myMethod::getContainingClass); FunctionalExpressionSearch.search(psiClass).forEach(new CommonProcessors.CollectProcessor() { @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java index 13571b4dc8de..e41d9be7d87e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.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. @@ -22,6 +22,7 @@ import com.intellij.codeInsight.daemon.quickFix.ExternalLibraryResolver.External import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.DumbService; @@ -36,13 +37,15 @@ import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiJavaModuleReference; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.PsiShortNamesCache; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.ThreeState; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.uast.UAnnotation; +import org.jetbrains.uast.UImportStatement; +import org.jetbrains.uast.UastContextKt; import java.io.File; import java.util.*; @@ -219,13 +222,13 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { } private static ThreeState isReferenceToAnnotation(final PsiElement psiElement) { - if (!PsiUtil.isLanguageLevel5OrHigher(psiElement)) { + if (psiElement.getLanguage() == JavaLanguage.INSTANCE && !PsiUtil.isLanguageLevel5OrHigher(psiElement)) { return ThreeState.NO; } - if (PsiTreeUtil.getParentOfType(psiElement, PsiAnnotation.class) != null) { + if (UastContextKt.getUastParentOfType(psiElement, UAnnotation.class) != null) { return ThreeState.YES; } - if (PsiTreeUtil.getParentOfType(psiElement, PsiImportStatement.class) != null) { + if (UastContextKt.getUastParentOfType(psiElement, UImportStatement.class) != null) { return ThreeState.UNSURE; } return ThreeState.NO; diff --git a/java/java-impl/src/com/intellij/codeInspection/reflectiveAccess/JavaReflectionInvocationInspection.java b/java/java-impl/src/com/intellij/codeInspection/reflectiveAccess/JavaReflectionInvocationInspection.java index abd323f67c33..6d210a11311e 100644 --- a/java/java-impl/src/com/intellij/codeInspection/reflectiveAccess/JavaReflectionInvocationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/reflectiveAccess/JavaReflectionInvocationInspection.java @@ -115,7 +115,8 @@ public class JavaReflectionInvocationInspection extends BaseJavaBatchLocalInspec final PsiExpression[] expressions = argumentList.getExpressions(); final PsiElement element = expressions.length == argumentOffset + 1 ? expressions[argumentOffset] : argumentList; holder.registerProblem(element, InspectionsBundle.message( - "inspection.reflection.invocation.item.number.not.assignable", i, requiredType.getQualifiedName())); + "inspection.reflection.invocation.array.not.assignable", actualArguments.expressions.length)); + break; } } } diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java index 01d40e0e3f5b..e012812e3cf8 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValue.java @@ -21,7 +21,9 @@ import com.intellij.codeInspection.*; import com.intellij.codeInspection.reference.*; import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.openapi.util.WriteExternalException; -import com.intellij.psi.*; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiReference; import com.intellij.psi.util.PropertyUtil; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -55,6 +57,7 @@ public class UnusedReturnValue extends GlobalJavaBatchInspectionTool{ final boolean isNative = psiMethod.hasModifierProperty(PsiModifier.NATIVE); if (refMethod.isExternalOverride() && !isNative) return null; + if (RefUtil.isImplicitRead(psiMethod)) return null; return new ProblemDescriptor[]{createProblemDescriptor(psiMethod, manager, processor, isNative)}; } } diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java index 850e45c9db92..decd81176a26 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedReturnValue/UnusedReturnValueLocalInspection.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.impl.UnusedSymbolUtil; import com.intellij.codeInspection.BaseJavaLocalInspectionTool; import com.intellij.codeInspection.InspectionManager; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.reference.RefUtil; import com.intellij.openapi.progress.EmptyProgressIndicator; import com.intellij.patterns.PsiJavaPatterns; import com.intellij.psi.*; @@ -57,7 +58,8 @@ public class UnusedReturnValueLocalInspection extends BaseJavaLocalInspectionToo PsiType.VOID.equals(method.getReturnType()) || myGlobal.IGNORE_BUILDER_PATTERN && PropertyUtil.isSimplePropertySetter(method) || method.hasModifierProperty(PsiModifier.NATIVE) || - MethodUtils.hasSuper(method)) return null; + MethodUtils.hasSuper(method) || + RefUtil.isImplicitRead(method)) return null; final boolean[] atLeastOneUsageExists = new boolean[]{false}; if (UnusedSymbolUtil.processUsages(manager.getProject(), method.getContainingFile(), method, new EmptyProgressIndicator(), null, u -> { diff --git a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceUtil.java b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceUtil.java index 1328cb519c9c..670c5eae7d60 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceUtil.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/JavaReflectionReferenceUtil.java @@ -374,12 +374,15 @@ public class JavaReflectionReferenceUtil { if (type.equals(PsiType.NULL)) { return myPsiClass != null || myArrayDimensions != 0; } - if (type.getArrayDimensions() != myArrayDimensions) { - return false; + PsiType otherType = type; + for (int i = 0; i < myArrayDimensions; i++) { + if (!(otherType instanceof PsiArrayType)) { + return false; + } + otherType = ((PsiArrayType)otherType).getComponentType(); } - final PsiType otherType = type.getDeepComponentType(); if (myPrimitiveType != null) { - return myPrimitiveType.isAssignableFrom(otherType) || otherType.equalsToText(myPrimitiveType.getBoxedTypeName()); + return myPrimitiveType.isAssignableFrom(otherType); } final PsiElementFactory factory = JavaPsiFacade.getInstance(myPsiClass.getProject()).getElementFactory(); return factory.createType(myPsiClass).isAssignableFrom(otherType); diff --git a/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java b/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java index fdaa574c2871..d3c6c07977a0 100644 --- a/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java +++ b/java/java-impl/src/com/intellij/testIntegration/intention/MoveInitializerToSetUpMethodAction.java @@ -20,13 +20,11 @@ import com.intellij.codeInsight.TestFrameworks; import com.intellij.codeInsight.intention.impl.BaseMoveInitializerToMethodAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testIntegration.JavaTestFramework; import com.intellij.testIntegration.TestFramework; -import com.intellij.testIntegration.TestIntegrationUtils; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -53,25 +51,23 @@ public class MoveInitializerToSetUpMethodAction extends BaseMoveInitializerToMet @Override public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) { - final boolean isAvailable = super.isAvailable(project, editor, element) && TestIntegrationUtils.isTest(element); + final boolean isAvailable = super.isAvailable(project, editor, element); if (isAvailable) { final PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class); LOG.assertTrue(field != null); final PsiClass aClass = field.getContainingClass(); LOG.assertTrue(aClass != null); + TestFramework testFramework = TestFrameworks.detectFramework(aClass); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); - for (TestFramework framework : Extensions.getExtensions(TestFramework.EXTENSION_NAME)) { - if (framework instanceof JavaTestFramework && framework.isTestClass(aClass)) { - try { - ((JavaTestFramework)framework).createSetUpPatternMethod(elementFactory); - return true; - } - catch (Exception e) { - return false; - } + if (testFramework instanceof JavaTestFramework) { + try { + ((JavaTestFramework)testFramework).createSetUpPatternMethod(elementFactory); + return testFramework.isTestClass(aClass) || testFramework.findSetUpMethod(aClass) instanceof PsiMethod; + } + catch (Exception e) { + return false; } } - return true; } return false; } @@ -85,7 +81,14 @@ public class MoveInitializerToSetUpMethodAction extends BaseMoveInitializerToMet @NotNull @Override protected Collection getOrCreateMethods(@NotNull Project project, @NotNull Editor editor, PsiFile file, @NotNull PsiClass aClass) { - final PsiMethod setUpMethod = TestFrameworks.getInstance().findOrCreateSetUpMethod(aClass); - return setUpMethod == null ? Collections.emptyList() : Arrays.asList(setUpMethod); + TestFramework testFramework = TestFrameworks.detectFramework(aClass); + PsiElement setUpMethod = null; + if (testFramework != null) { + setUpMethod = testFramework.findSetUpMethod(aClass); + if (setUpMethod == null) { + setUpMethod = testFramework.findOrCreateSetUpMethod(aClass); + } + } + return setUpMethod instanceof PsiMethod ? Collections.singletonList((PsiMethod)setUpMethod) : Collections.emptyList(); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/TopLevelParentNoParameters.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/TopLevelParentNoParameters.java new file mode 100644 index 000000000000..0431d525cb85 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/TopLevelParentNoParameters.java @@ -0,0 +1,26 @@ + +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.logging.Logger; + +class MyTest +{ + private final static Logger LOGGER = Logger.getLogger(MyTest.class.getName()); + + public static void test(List> testList) { + testList.forEach( MyTest.bind(MyTest.cast(LOGGER::info), iterable -> "")); + } + + private static TestConsumer bind(Consumer delegate, Function function) { + return null; + } + + private static Consumer cast(Consumer consumer) + { + return consumer; + } + + private interface TestConsumer extends Consumer { } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveInitializerToSetUp/afterJUnit4WithBeforeOnly.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveInitializerToSetUp/afterJUnit4WithBeforeOnly.java new file mode 100644 index 000000000000..a693577921ce --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveInitializerToSetUp/afterJUnit4WithBeforeOnly.java @@ -0,0 +1,10 @@ +// "Move initializer to setUp method" "true" +public class X { + int i; + + @org.junit.Before + public void setUp() throws Exception { + + i = 7; + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveInitializerToSetUp/beforeJUnit4WithBeforeOnly.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveInitializerToSetUp/beforeJUnit4WithBeforeOnly.java new file mode 100644 index 000000000000..5af0027632a3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveInitializerToSetUp/beforeJUnit4WithBeforeOnly.java @@ -0,0 +1,9 @@ +// "Move initializer to setUp method" "true" +public class X { + int i = 7; + + @org.junit.Before + public void setUp() throws Exception { + + } +} diff --git a/java/java-tests/testData/inspection/javaReflectionInvocation/ConstructorParamTypes.java b/java/java-tests/testData/inspection/javaReflectionInvocation/ConstructorParamTypes.java index 57a33f282be6..c2a1c41fc07e 100644 --- a/java/java-tests/testData/inspection/javaReflectionInvocation/ConstructorParamTypes.java +++ b/java/java-tests/testData/inspection/javaReflectionInvocation/ConstructorParamTypes.java @@ -1,3 +1,4 @@ +import java.io.Serializable; import java.lang.reflect.Constructor; import java.util.*; @@ -32,9 +33,9 @@ class ConstructorParamTypes { c2.newInstance(new Object[] {"abc", Integer.valueOf(42)}); c3.newInstance(new Object[] {new int[]{42, 23}, Arrays.asList("x", "y")}); - c1.newInstance(a2); - c2.newInstance(a3); - c3.newInstance(a1); + c1.newInstance(a2); + c2.newInstance(a3); + c3.newInstance(a1); c1.newInstance(new Object[]{"42", "abc"}); c2.newInstance(new Object[]{42, 23}); @@ -46,9 +47,18 @@ class ConstructorParamTypes { cls.getConstructor(String[].class).newInstance((Object)new String[] {"abc"}); cls.getConstructor(String[].class).newInstance(new String[] {"abc"}); + + Constructor c4 = cls.getConstructor(Cloneable.class); + Constructor c5 = cls.getConstructor(Serializable.class); + + c4.newInstance(new C()); + c5.newInstance(new S()); + + c4.newInstance(new S()); + c5.newInstance(new C()); } - void arraySignatutre() throws Exception { + void arraySignature() throws Exception { Class cls = Test.class; Constructor c1 = cls.getConstructor(new Class[]{int.class, String.class}); @@ -73,9 +83,9 @@ class ConstructorParamTypes { c2.newInstance(new Object[] {"abc", Integer.valueOf(42)}); c3.newInstance(new Object[] {new int[]{42, 23}, Arrays.asList("x", "y")}); - c1.newInstance(a2); - c2.newInstance(a3); - c3.newInstance(a1); + c1.newInstance(a2); + c2.newInstance(a3); + c3.newInstance(a1); c1.newInstance(new Object[]{"42", "abc"}); c2.newInstance(new Object[]{42, 23}); @@ -87,6 +97,15 @@ class ConstructorParamTypes { cls.getConstructor(new Class[]{String[].class}).newInstance((Object)new String[] {"abc"}); cls.getConstructor(new Class[]{String[].class}).newInstance(new String[] {"abc"}); + + Constructor c4 = cls.getConstructor(new Class[]{Cloneable.class}); + Constructor c5 = cls.getConstructor(new Class[]{Serializable.class}); + + c4.newInstance(new C()); + c5.newInstance(new S()); + + c4.newInstance(new S()); + c5.newInstance(new C()); } void manyArguments() throws Exception { @@ -107,11 +126,38 @@ class ConstructorParamTypes { Object[] a5 = {0, (short)0, 0, 0.0f, "abc"}; m0.newInstance(a0); - m1.newInstance(a1); - m2.newInstance(a2); - m3.newInstance(a3); - m4.newInstance(a4); - m5.newInstance(a5); + m1.newInstance(a1); + m2.newInstance(a2); + m3.newInstance(a3); + m4.newInstance(a4); + m5.newInstance(a5); + } + + void arrayArguments() throws Exception { + Class cls = Test.class; + + Constructor c1 = cls.getConstructor(Object.class); + Constructor c2 = cls.getConstructor(Cloneable.class); + Constructor c3 = cls.getConstructor(Serializable.class); + + c1.newInstance((Object) new String[0]); + c2.newInstance((Object) new String[0]); + c3.newInstance((Object) new String[0]); + + c1.newInstance((Object) new String[][]{ new String[0] }); + c2.newInstance((Object) new String[][]{ new String[0] }); + c3.newInstance((Object) new String[][]{ new String[0] }); + + Constructor c4 = cls.getConstructor(Object[].class); + Constructor c5 = cls.getConstructor(String[].class); + + c4.newInstance((Object) new String[0]); + c4.newInstance((Object) new String[][]{ new String[0] }); + + c5.newInstance((Object) new String[0]); + c5.newInstance((Object) new String[][]{ new String[0] }); + c5.newInstance("abc"); + c5.newInstance(new Test(1, null)); } class Test { @@ -119,6 +165,11 @@ class ConstructorParamTypes { public Test(String s, Integer n) {} public Test(int[] n, List s) {} public Test(String[] s) {} + public Test(Object[] s) {} + + public Test(Object o) {} + public Test(Cloneable c) {} + public Test(Serializable s) {} } class M { @@ -128,4 +179,10 @@ class ConstructorParamTypes { public String m4(int a1, short a2, long a3, float a4) {return "";} public String m5(int a1, short a2, long a3, float a4, double a5) {return "";} } + + static class S implements Serializable { + } + + static class C implements Cloneable { + } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/javaReflectionInvocation/MethodParamTypes.java b/java/java-tests/testData/inspection/javaReflectionInvocation/MethodParamTypes.java index 261998ff30f4..836102c0de47 100644 --- a/java/java-tests/testData/inspection/javaReflectionInvocation/MethodParamTypes.java +++ b/java/java-tests/testData/inspection/javaReflectionInvocation/MethodParamTypes.java @@ -1,3 +1,4 @@ +import java.io.Serializable; import java.lang.reflect.Method; import java.util.*; @@ -33,9 +34,9 @@ class MethodParamTypes { m2.invoke(obj, new Object[] {"abc", Integer.valueOf(42)}); m3.invoke(obj, new Object[] {new int[]{42, 23}, Arrays.asList("x", "y")}); - m1.invoke(obj, a2); - m2.invoke(obj, a3); - m3.invoke(obj, a1); + m1.invoke(obj, a2); + m2.invoke(obj, a3); + m3.invoke(obj, a1); m1.invoke(obj, new Object[]{"42", "abc"}); m2.invoke(obj, new Object[]{42, 23}); @@ -47,9 +48,18 @@ class MethodParamTypes { cls.getMethod("str", String[].class).invoke(null, (Object)new String[] {"abc"}); cls.getMethod("str", String[].class).invoke(null, new String[] {"abc"}); + + Method m4 = cls.getMethod("obj", Cloneable.class); + Method m5 = cls.getMethod("obj", Serializable.class); + + m4.invoke(obj, new C()); + m5.invoke(obj, new S()); + + m4.invoke(obj, new S()); + m5.invoke(obj, new C()); } - void arraySignatutre() throws Exception { + void arraySignature() throws Exception { Class cls = Test.class; Object obj = new Test(); @@ -75,9 +85,9 @@ class MethodParamTypes { m2.invoke(obj, new Object[] {"abc", Integer.valueOf(42)}); m3.invoke(obj, new Object[] {new int[]{42, 23}, Arrays.asList("x", "y")}); - m1.invoke(obj, a2); - m2.invoke(obj, a3); - m3.invoke(obj, a1); + m1.invoke(obj, a2); + m2.invoke(obj, a3); + m3.invoke(obj, a1); m1.invoke(obj, new Object[]{"42", "abc"}); m2.invoke(obj, new Object[]{42, 23}); @@ -89,6 +99,15 @@ class MethodParamTypes { cls.getMethod("str", new Class[]{String[].class}).invoke(null, (Object)new String[] {"abc"}); cls.getMethod("str", new Class[]{String[].class}).invoke(null, new String[] {"abc"}); + + Method m4 = cls.getMethod("obj", new Class[]{Cloneable.class}); + Method m5 = cls.getMethod("obj", new Class[]{Serializable.class}); + + m4.invoke(obj, new C()); + m5.invoke(obj, new S()); + + m4.invoke(obj, new S()); + m5.invoke(obj, new C()); } void manyArguments() throws Exception { @@ -110,11 +129,39 @@ class MethodParamTypes { Object[] a5 = {0, (short)0, 0, 0.0f, "abc"}; m0.invoke(obj, a0); - m1.invoke(obj, a1); - m2.invoke(obj, a2); - m3.invoke(obj, a3); - m4.invoke(obj, a4); - m5.invoke(obj, a5); + m1.invoke(obj, a1); + m2.invoke(obj, a2); + m3.invoke(obj, a3); + m4.invoke(obj, a4); + m5.invoke(obj, a5); + } + + void arrayArguments() throws Exception { + Class cls = Test.class; + Object obj = new Test(); + + Method m1 = cls.getMethod("obj", Object.class); + Method m2 = cls.getMethod("obj", Cloneable.class); + Method m3 = cls.getMethod("obj", Serializable.class); + + m1.invoke(obj, (Object) new String[0]); + m2.invoke(obj, (Object) new String[0]); + m3.invoke(obj, (Object) new String[0]); + + m1.invoke(obj, (Object) new String[][]{ new String[0] }); + m2.invoke(obj, (Object) new String[][]{ new String[0] }); + m3.invoke(obj, (Object) new String[][]{ new String[0] }); + + Method m4 = cls.getMethod("array", Object[].class); + Method m5 = cls.getMethod("array", String[].class); + + m4.invoke(null, (Object) new String[0]); + m4.invoke(null, (Object) new String[][]{ new String[0] }); + + m5.invoke(null, (Object) new String[0]); + m5.invoke(null, (Object) new String[][]{ new String[0] }); + m5.invoke(null, "abc"); + m5.invoke(null, obj); } static class Test { @@ -123,6 +170,13 @@ class MethodParamTypes { public void bar(int[] n, List s) {} public static void str(String[] s) {} + + public void obj(Object o) {} + public void obj(Cloneable c) {} + public void obj(Serializable s) {} + + public static void array(Object[] a) {} + public static void array(String[] a) {} } class M { @@ -132,4 +186,10 @@ class MethodParamTypes { public String m4(int a1, short a2, long a3, float a4) {return "";} public String m5(int a1, short a2, long a3, float a4, double a5) {return "";} } + + static class S implements Serializable { + } + + static class C implements Cloneable { + } } \ No newline at end of file diff --git a/java/java-tests/testData/inspection/unusedReturnValue/quickFix/NoChangeForImplicitRead.java b/java/java-tests/testData/inspection/unusedReturnValue/quickFix/NoChangeForImplicitRead.java new file mode 100644 index 000000000000..3b544339d2ac --- /dev/null +++ b/java/java-tests/testData/inspection/unusedReturnValue/quickFix/NoChangeForImplicitRead.java @@ -0,0 +1,9 @@ +class Test { + public String implicitRead() { + return ""; + } + + { + implicitRead(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java index bf3d4c349a7e..50ae8601fd14 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GraphInferenceHighlightingTest.java @@ -178,6 +178,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase doTest(); } + public void testTopLevelParentNoParameters() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/UnusedReturnValueQuickFixTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/UnusedReturnValueQuickFixTest.java index 7048df0f57bb..dcff2ac300c4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/UnusedReturnValueQuickFixTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/UnusedReturnValueQuickFixTest.java @@ -16,7 +16,12 @@ package com.intellij.codeInspection; import com.intellij.JavaTestUtil; +import com.intellij.codeInsight.daemon.ImplicitUsageProvider; import com.intellij.codeInspection.unusedReturnValue.UnusedReturnValue; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiMethod; +import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; /** @@ -27,11 +32,33 @@ public class UnusedReturnValueQuickFixTest extends LightCodeInsightFixtureTestCa @Override protected void setUp() throws Exception { super.setUp(); + PlatformTestUtil.registerExtension(Extensions.getRootArea(), ImplicitUsageProvider.EP_NAME, new ImplicitUsageProvider() { + @Override + public boolean isImplicitUsage(PsiElement element) { + return false; + } + + @Override + public boolean isImplicitRead(PsiElement element) { + return element instanceof PsiMethod && ((PsiMethod)element).getName().equals("implicitRead"); + } + + @Override + public boolean isImplicitWrite(PsiElement element) { + return false; + } + }, getTestRootDisposable()); + myFixture.enableInspections(new UnusedReturnValue()); } public void testSideEffects() { doTest(); } public void testRedundantReturn() { doTest(); } + public void testNoChangeForImplicitRead() { + final String name = getTestName(false); + myFixture.configureByFile(name + ".java"); + assertEmpty(myFixture.filterAvailableIntentions(InspectionsBundle.message("inspection.unused.return.value.make.void.quickfix"))); + } private void doTest() { final String name = getTestName(false); diff --git a/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.java b/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.java deleted file mode 100644 index 3a7065e091d2..000000000000 --- a/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.java +++ /dev/null @@ -1,734 +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.application.ApplicationConfigurationType; -import com.intellij.execution.configurations.ConfigurationType; -import com.intellij.execution.junit.JUnitConfigurationType; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Trinity; -import com.intellij.testFramework.LightIdeaTestCase; -import com.intellij.ui.RowsDnDSupport; -import com.intellij.ui.treeStructure.Tree; -import com.intellij.util.JdomKt; -import org.jdom.Element; - -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.TreePath; -import java.util.ArrayList; -import java.util.List; - -import static com.intellij.execution.impl.RunConfigurable.NodeKind.*; -import static com.intellij.ui.RowsDnDSupport.RefinedDropSupport.Position.*; - -/** - * User: Vassiliy.Kudryashov - */ -public class RunConfigurableTest extends LightIdeaTestCase { - private static final RunConfigurable.NodeKind[] ORDER = { - CONFIGURATION_TYPE,//Application - FOLDER,//1 - CONFIGURATION, CONFIGURATION, CONFIGURATION, CONFIGURATION, CONFIGURATION, - TEMPORARY_CONFIGURATION, TEMPORARY_CONFIGURATION, - FOLDER,//2 - TEMPORARY_CONFIGURATION, - FOLDER,//3 - CONFIGURATION, - TEMPORARY_CONFIGURATION, - CONFIGURATION_TYPE,//JUnit - FOLDER,//4 - CONFIGURATION, CONFIGURATION, - FOLDER,//5 - CONFIGURATION, CONFIGURATION, - TEMPORARY_CONFIGURATION, - UNKNOWN//Defaults - }; - private MockRunConfigurable myConfigurable; - private Tree myTree; - private DefaultMutableTreeNode myRoot; - private RunConfigurable.MyTreeModel myModel; - - @Override - protected void setUp() throws Exception { - super.setUp(); - myConfigurable = new MockRunConfigurable(createRunManager(JdomKt.loadElement(FOLDERS_CONFIGURATION))); - myTree = myConfigurable.myTree; - myRoot = myConfigurable.myRoot; - myModel = myConfigurable.myTreeModel; - } - - @Override - protected void tearDown() throws Exception { - try { - if (myConfigurable != null) myConfigurable.disposeUIResources(); - myConfigurable = null; - myTree = null; - myRoot = null; - myModel = null; - } - finally { - super.tearDown(); - } - } - - public void testDND() throws Exception { - doExpand(); - int[] never = {-1, 0, 14, 22, 23, 999}; - for (int i = -1; i < 17; i++) { - for (int j : never) { - if ((j == 14 || j == 21) && i == j) { - continue; - } - assertCannot(j,i,ABOVE); - assertCannot(j,i,INTO); - assertCannot(j,i,BELOW); - } - } - assertCan(3, 3, BELOW); - assertCan(3, 3, ABOVE); - assertCannot(3, 2, BELOW); - assertCan(3, 2, ABOVE); - assertCannot(3, 1, BELOW); - assertCannot(3, 0, BELOW); - assertCan(2, 14, ABOVE); - assertCan(1, 14, ABOVE); - assertCan(1, 11, ABOVE); - assertCannot(1, 10, ABOVE); - assertCannot(1, 10, BELOW); - assertCannot(8, 6, ABOVE); - assertCan(8, 6, BELOW); - assertCannot(5, 7, BELOW); - assertCan(5, 7, ABOVE); - assertCannot(15, 11, INTO); - assertCannot(18, 21, ABOVE); - assertCan(15, 21, ABOVE); - - assertTrue(myModel.isDropInto(myTree, 2, 9)); - assertTrue(myModel.isDropInto(myTree, 2, 1)); - assertTrue(myModel.isDropInto(myTree, 12, 9)); - assertTrue(myModel.isDropInto(myTree, 12, 1)); - assertFalse(myModel.isDropInto(myTree, 999, 9)); - assertFalse(myModel.isDropInto(myTree, 999, 1)); - assertFalse(myModel.isDropInto(myTree, 2, 999)); - assertFalse(myModel.isDropInto(myTree, 2, -1)); - } - - private void doExpand() { - List toExpand = new ArrayList<>(); - RunConfigurable.collectNodesRecursively(myRoot, toExpand, FOLDER); - assertEquals(5, toExpand.size()); - List toExpand2 = new ArrayList<>(); - RunConfigurable.collectNodesRecursively(myRoot, toExpand2, CONFIGURATION_TYPE); - toExpand.addAll(toExpand2); - for (DefaultMutableTreeNode node : toExpand) { - myTree.expandPath(new TreePath(node.getPath())); - } - for (int i = 0; i < ORDER.length; i++) { - DefaultMutableTreeNode node = (DefaultMutableTreeNode)myTree.getPathForRow(i).getLastPathComponent(); - assertEquals("Row #" + i, RunConfigurable.getKind(node), ORDER[i]); - } - } - - private void assertCan(int oldIndex, int newIndex, RowsDnDSupport.RefinedDropSupport.Position position) { - assertDrop(oldIndex, newIndex, position, true); - } - - private void assertCannot(int oldIndex, int newIndex, RowsDnDSupport.RefinedDropSupport.Position position) { - assertDrop(oldIndex, newIndex, position, false); - } - - private void assertDrop(int oldIndex, int newIndex, RowsDnDSupport.RefinedDropSupport.Position position, boolean canDrop) { - StringBuilder message = new StringBuilder(); - message.append("(").append(oldIndex).append(")").append(myTree.getPathForRow(oldIndex)).append("->"); - message.append("(").append(newIndex).append(")").append(myTree.getPathForRow(newIndex)).append(position); - if (canDrop) { - assertTrue(message.toString(), myModel.canDrop(oldIndex, newIndex, position)); - } - else { - assertFalse(message.toString(), myModel.canDrop(oldIndex, newIndex, position)); - } - } - - public void testMoveUpDown() { - doExpand(); - checkPositionToMove(0, 1, null); - checkPositionToMove(2, 1, Trinity.create(2, 3, BELOW)); - checkPositionToMove(2, -1, null); - checkPositionToMove(14, 1, null); - checkPositionToMove(14, -1, null); - checkPositionToMove(15, -1, null); - checkPositionToMove(16, -1, null); - checkPositionToMove(3, -1, Trinity.create(3, 2, ABOVE)); - checkPositionToMove(6, 1, Trinity.create(6, 9, BELOW)); - checkPositionToMove(7, 1, Trinity.create(7, 8, BELOW)); - checkPositionToMove(10, -1, Trinity.create(10, 8, BELOW)); - checkPositionToMove(8, 1, Trinity.create(8, 9, BELOW)); - checkPositionToMove(21, -1, Trinity.create(21, 20, BELOW)); - checkPositionToMove(21, 1, null); - checkPositionToMove(20, 1, Trinity.create(20, 21, ABOVE)); - checkPositionToMove(20, -1, Trinity.create(20, 19, ABOVE)); - checkPositionToMove(19, 1, Trinity.create(19, 20, BELOW)); - checkPositionToMove(19, -1, Trinity.create(19, 17, BELOW)); - checkPositionToMove(17, -1, Trinity.create(17, 16, ABOVE)); - checkPositionToMove(17, 1, Trinity.create(17, 18, BELOW)); - } - - private void checkPositionToMove(int selectedRow, - int direction, - Trinity expected) { - myTree.setSelectionRow(selectedRow); - assertEquals(expected, myConfigurable.getAvailableDropPosition(direction)); - } - - private static RunManagerImpl createRunManager(Element element) { - Project project = getProject(); - RunManagerImpl runManager = new RunManagerImpl(project); - runManager.initializeConfigurationTypes(new ConfigurationType[]{ApplicationConfigurationType.getInstance(), JUnitConfigurationType.getInstance()}); - runManager.loadState(element); - return runManager; - } - - private static class MockRunConfigurable extends RunConfigurable { - private final RunManagerImpl myTestManager; - - private MockRunConfigurable(RunManagerImpl runManager) { - super(getProject()); - myTestManager = runManager; - createComponent(); - } - - @Override - RunManagerImpl getRunManager() { - return myTestManager; - } - } - - /* -00 Application -01 1 -02 CodeGenerator -03 Renamer -04 UI -05 AuTest -06 Simples -07 OutAndErr (tmp) -08 C148C_TersePrincess (tmp) -09 2 -10 Periods (tmp) -11 3 -12 C148E_Porcelain -13 ErrAndOut (tmp) -14 JUnit -15 4 -16 All in titled -17 All in titled2 -18 5 -19 All in titled3 -20 All in titled4 -21 All in titled5 -16 Defaults - ... - */ - private static final String FOLDERS_CONFIGURATION = " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " localhost\n" + - " 5050\n" + - " \n" + - " \n"; -} diff --git a/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.kt b/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.kt new file mode 100644 index 000000000000..a10c98304b95 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/execution/impl/RunConfigurableTest.kt @@ -0,0 +1,194 @@ +/* + * 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.application.ApplicationConfigurationType +import com.intellij.execution.impl.RunConfigurable.NodeKind.* +import com.intellij.execution.junit.JUnitConfigurationType +import com.intellij.openapi.util.Trinity +import com.intellij.testFramework.LightIdeaTestCase +import com.intellij.testFramework.LightPlatformTestCase +import com.intellij.testFramework.assertions.Assertions.assertThat +import com.intellij.ui.RowsDnDSupport +import com.intellij.ui.RowsDnDSupport.RefinedDropSupport.Position.* +import com.intellij.ui.treeStructure.Tree +import com.intellij.util.loadElement +import org.jdom.Element +import java.util.* +import javax.swing.tree.DefaultMutableTreeNode +import javax.swing.tree.TreePath +import kotlin.properties.Delegates + +private val ORDER = arrayOf(CONFIGURATION_TYPE, //Application + FOLDER, //1 + CONFIGURATION, CONFIGURATION, CONFIGURATION, CONFIGURATION, CONFIGURATION, TEMPORARY_CONFIGURATION, TEMPORARY_CONFIGURATION, FOLDER, //2 + TEMPORARY_CONFIGURATION, FOLDER, //3 + CONFIGURATION, TEMPORARY_CONFIGURATION, CONFIGURATION_TYPE, //JUnit + FOLDER, //4 + CONFIGURATION, CONFIGURATION, FOLDER, //5 + CONFIGURATION, CONFIGURATION, TEMPORARY_CONFIGURATION, UNKNOWN//Defaults +) + +private fun createRunManager(element: Element): RunManagerImpl { + val runManager = RunManagerImpl(LightPlatformTestCase.getProject()) + runManager.initializeConfigurationTypes(arrayOf(ApplicationConfigurationType.getInstance(), JUnitConfigurationType.getInstance())) + runManager.loadState(element) + return runManager +} + +class RunConfigurableTest : LightIdeaTestCase() { + private var configurable: MockRunConfigurable? = null + private var tree: Tree by Delegates.notNull() + private var root: DefaultMutableTreeNode? = null + private var model: RunConfigurable.MyTreeModel by Delegates.notNull() + + override fun setUp() { + super.setUp() + + configurable = MockRunConfigurable(createRunManager(loadElement(RunConfigurableTest::class.java.getResourceAsStream("folders.xml")))) + tree = configurable!!.myTree + root = configurable!!.myRoot + model = configurable!!.myTreeModel + } + + override fun tearDown() { + try { + if (configurable != null) { + configurable!!.disposeUIResources() + } + configurable = null + root = null + } + finally { + super.tearDown() + } + } + + fun testDND() { + doExpand() + val never = intArrayOf(-1, 0, 14, 22, 23, 999) + for (i in -1..16) { + for (j in never) { + if ((j == 14 || j == 21) && i == j) { + continue + } + assertCannot(j, i, ABOVE) + assertCannot(j, i, INTO) + assertCannot(j, i, BELOW) + } + } + assertCan(3, 3, BELOW) + assertCan(3, 3, ABOVE) + assertCannot(3, 2, BELOW) + assertCan(3, 2, ABOVE) + assertCannot(3, 1, BELOW) + assertCannot(3, 0, BELOW) + assertCan(2, 14, ABOVE) + assertCan(1, 14, ABOVE) + assertCan(1, 11, ABOVE) + assertCannot(1, 10, ABOVE) + assertCannot(1, 10, BELOW) + assertCannot(8, 6, ABOVE) + assertCan(8, 6, BELOW) + assertCannot(5, 7, BELOW) + assertCan(5, 7, ABOVE) + assertCannot(15, 11, INTO) + assertCannot(18, 21, ABOVE) + assertCan(15, 21, ABOVE) + + assertThat(model.isDropInto(tree, 2, 9)).isTrue() + assertThat(model.isDropInto(tree, 2, 1)).isTrue() + assertThat(model.isDropInto(tree, 12, 9)).isTrue() + assertThat(model.isDropInto(tree, 12, 1)).isTrue() + assertThat(model.isDropInto(tree, 999, 9)).isFalse() + assertThat(model.isDropInto(tree, 999, 1)).isFalse() + assertThat(model.isDropInto(tree, 2, 999)).isFalse() + assertThat(model.isDropInto(tree, 2, -1)).isFalse() + } + + private fun doExpand() { + val toExpand = ArrayList() + RunConfigurable.collectNodesRecursively(root, toExpand, FOLDER) + assertThat(toExpand).hasSize(5) + val toExpand2 = ArrayList() + RunConfigurable.collectNodesRecursively(root, toExpand2, CONFIGURATION_TYPE) + toExpand.addAll(toExpand2) + for (node in toExpand) { + tree.expandPath(TreePath(node.path)) + } + + assertThat(ORDER.mapIndexed { index, nodeKind -> RunConfigurable.getKind(tree.getPathForRow(index).lastPathComponent as DefaultMutableTreeNode) }).containsExactly(*ORDER) + } + + private fun assertCan(oldIndex: Int, newIndex: Int, position: RowsDnDSupport.RefinedDropSupport.Position) { + assertDrop(oldIndex, newIndex, position, true) + } + + private fun assertCannot(oldIndex: Int, newIndex: Int, position: RowsDnDSupport.RefinedDropSupport.Position) { + assertDrop(oldIndex, newIndex, position, false) + } + + private fun assertDrop(oldIndex: Int, newIndex: Int, position: RowsDnDSupport.RefinedDropSupport.Position, canDrop: Boolean) { + val message = StringBuilder() + message.append("(").append(oldIndex).append(")").append(tree.getPathForRow(oldIndex)).append("->") + message.append("(").append(newIndex).append(")").append(tree.getPathForRow(newIndex)).append(position) + if (canDrop) { + // message.toString() + assertThat(model.canDrop(oldIndex, newIndex, position)).isTrue() + } + else { + // message.toString() + assertThat(model.canDrop(oldIndex, newIndex, position)).isFalse() + } + } + + fun testMoveUpDown() { + doExpand() + checkPositionToMove(0, 1, null) + checkPositionToMove(2, 1, Trinity.create(2, 3, BELOW)) + checkPositionToMove(2, -1, null) + checkPositionToMove(14, 1, null) + checkPositionToMove(14, -1, null) + checkPositionToMove(15, -1, null) + checkPositionToMove(16, -1, null) + checkPositionToMove(3, -1, Trinity.create(3, 2, ABOVE)) + checkPositionToMove(6, 1, Trinity.create(6, 9, BELOW)) + checkPositionToMove(7, 1, Trinity.create(7, 8, BELOW)) + checkPositionToMove(10, -1, Trinity.create(10, 8, BELOW)) + checkPositionToMove(8, 1, Trinity.create(8, 9, BELOW)) + checkPositionToMove(21, -1, Trinity.create(21, 20, BELOW)) + checkPositionToMove(21, 1, null) + checkPositionToMove(20, 1, Trinity.create(20, 21, ABOVE)) + checkPositionToMove(20, -1, Trinity.create(20, 19, ABOVE)) + checkPositionToMove(19, 1, Trinity.create(19, 20, BELOW)) + checkPositionToMove(19, -1, Trinity.create(19, 17, BELOW)) + checkPositionToMove(17, -1, Trinity.create(17, 16, ABOVE)) + checkPositionToMove(17, 1, Trinity.create(17, 18, BELOW)) + } + + private fun checkPositionToMove(selectedRow: Int, direction: Int, expected: Trinity?) { + tree.setSelectionRow(selectedRow) + assertThat(configurable!!.getAvailableDropPosition(direction)).isEqualTo(expected) + } +} + +private class MockRunConfigurable(private val testManager: RunManagerImpl) : RunConfigurable(LightPlatformTestCase.getProject()) { + init { + createComponent() + } + + internal override fun getRunManager() = testManager +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/execution/impl/folders.xml b/java/java-tests/testSrc/com/intellij/execution/impl/folders.xml new file mode 100644 index 000000000000..a32681bd5e72 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/execution/impl/folders.xml @@ -0,0 +1,489 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java index 9681d9e2bc82..e7d41970d988 100644 --- a/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/impl/file/impl/PsiEventsTest.java @@ -16,6 +16,7 @@ package com.intellij.psi.impl.file.impl; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -814,4 +815,18 @@ public class PsiEventsTest extends PsiTestCase { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); assertEquals(" ", getPsiManager().findFile(vFile).getText()); } + + public void testCopyFile() throws Exception { + VirtualFile original = createFile(myModule, mySrcDir1, "a.xml", "").getVirtualFile(); + + EventsTestListener listener = new EventsTestListener(); + myPsiManager.addPsiTreeChangeListener(listener,getTestRootDisposable()); + + PsiDirectory psiDir2 = PsiManager.getInstance(myProject).findDirectory(mySrcDir2); + assertNotNull(psiDir2); + WriteAction.run(() -> original.copy(this, mySrcDir2, "b.xml")); + + assertEquals("beforeChildAddition\n" + + "childAdded\n", listener.getEventsString()); + } } diff --git a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java index 4833e351d2d0..ec90fa0f690f 100644 --- a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java +++ b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java @@ -512,7 +512,7 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas @Override public ConfigurationFactory getFactory() { - return null; + return UnknownConfigurationType.FACTORY; } @Override @@ -529,12 +529,6 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas return null; } - @Override - @NotNull - public ConfigurationType getType() { - return UnknownConfigurationType.INSTANCE; - } - @Override public RunConfiguration clone() { return null; diff --git a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java index d2d041879c76..576402bc645c 100644 --- a/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java +++ b/platform/analysis-api/src/com/intellij/codeInspection/InspectionProfileEntry.java @@ -49,10 +49,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.*; /** * @author anna @@ -177,26 +174,32 @@ public abstract class InspectionProfileEntry implements BatchSuppressableTool { @NotNull public static Set getSuppressors(@NotNull PsiElement element) { FileViewProvider viewProvider = element.getContainingFile().getViewProvider(); - final InspectionSuppressor elementLanguageSuppressor = LanguageInspectionSuppressors.INSTANCE.forLanguage(element.getLanguage()); + final List elementLanguageSuppressor = LanguageInspectionSuppressors.INSTANCE.allForLanguage(element.getLanguage()); if (viewProvider instanceof TemplateLanguageFileViewProvider) { Set suppressors = new LinkedHashSet<>(); - ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(viewProvider.getBaseLanguage())); + ContainerUtil.addAllNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.allForLanguage(viewProvider.getBaseLanguage())); for (Language language : viewProvider.getLanguages()) { - ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(language)); + ContainerUtil.addAllNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.allForLanguage(language)); } - ContainerUtil.addIfNotNull(suppressors, elementLanguageSuppressor); + ContainerUtil.addAllNotNull(suppressors, elementLanguageSuppressor); return suppressors; } if (!element.getLanguage().isKindOf(viewProvider.getBaseLanguage())) { // handling embedding elements {@link EmbeddingElementType Set suppressors = new LinkedHashSet<>(); - ContainerUtil.addIfNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.forLanguage(viewProvider.getBaseLanguage())); - ContainerUtil.addIfNotNull(suppressors, elementLanguageSuppressor); + ContainerUtil.addAllNotNull(suppressors, LanguageInspectionSuppressors.INSTANCE.allForLanguage(viewProvider.getBaseLanguage())); + ContainerUtil.addAllNotNull(suppressors, elementLanguageSuppressor); return suppressors; } - return elementLanguageSuppressor != null - ? Collections.singleton(elementLanguageSuppressor) - : Collections.emptySet(); + int size = elementLanguageSuppressor.size(); + switch (size) { + case 0: + return Collections.emptySet(); + case 1: + return Collections.singleton(elementLanguageSuppressor.get(0)); + default: + return new java.util.HashSet<>(elementLanguageSuppressor); + } } public void cleanup(@NotNull Project project) { diff --git a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java index fd6e9344201d..98cc641c3b6c 100644 --- a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.java +++ b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReference.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. @@ -41,6 +41,7 @@ import com.intellij.psi.search.PsiFileSystemItemProcessor; import com.intellij.refactoring.rename.BindablePsiReference; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -156,9 +157,18 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP final Collection result, final boolean caseSensitive) { if (isAllowedEmptyPath(text) || ".".equals(text) || "/".equals(text)) { + if (context instanceof FileReferenceResolver) { + ContainerUtil.addIfNotNull(result, resolveFileReferenceResolver((FileReferenceResolver)context, text)); + return; + } result.add(new PsiElementResolveResult(context)); } else if ("..".equals(text)) { + if (context instanceof FileReferenceResolver) { + ContainerUtil.addIfNotNull(result, resolveFileReferenceResolver((FileReferenceResolver)context, text)); + return; + } + final PsiFileSystemItem resolved = context.getParent(); if (resolved != null) { result.add(new PsiElementResolveResult(resolved)); @@ -189,9 +199,9 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP context = ((PackagePrefixFileSystemItem)context).getDirectory(); } else if (context instanceof FileReferenceResolver) { - PsiFileSystemItem child = ((FileReferenceResolver)context).resolveFileReference(this, decoded); + ResolveResult child = resolveFileReferenceResolver((FileReferenceResolver)context, decoded); if (child != null) { - result.add(new PsiElementResolveResult(getOriginalFile(child))); + result.add(child); return; } } @@ -241,6 +251,12 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP return null; } + @Nullable + private ResolveResult resolveFileReferenceResolver(@NotNull FileReferenceResolver fileReferenceResolver, @NotNull String text) { + PsiFileSystemItem resolve = fileReferenceResolver.resolveFileReference(this, text); + return resolve != null ? new PsiElementResolveResult(getOriginalFile(resolve)) : null; + } + private static boolean caseSensitivityApplies(PsiDirectory context, boolean caseSensitive) { VirtualFileSystem fs = context.getVirtualFile().getFileSystem(); return fs.isCaseSensitive() == caseSensitive; diff --git a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java index a4100b567f25..b1b831196e50 100644 --- a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java +++ b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.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. @@ -367,15 +367,23 @@ public class FileReferenceSet { final FileReferenceHelper[] helpers = FileReferenceHelperRegistrar.getHelpers(); final ArrayList list = new ArrayList<>(); final Project project = file.getProject(); + boolean hasRealContexts = false; for (FileReferenceHelper helper : helpers) { if (helper.isMine(project, virtualFile)) { if (!list.isEmpty() && helper.isFallback()) { continue; } - list.addAll(helper.getContexts(project, virtualFile)); + Collection contexts = helper.getContexts(project, virtualFile); + for (PsiFileSystemItem context : contexts) { + list.add(context); + hasRealContexts |= !(context instanceof FileReferenceResolver); + } } } if (!list.isEmpty()) { + if (!hasRealContexts) { + list.addAll(getParentDirectoryContext()); + } return list; } return getParentDirectoryContext(); 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 41064c16d540..5deb4016eedd 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 @@ -77,12 +77,9 @@ class CompilationTasksImpl extends CompilationTasks { } private void ensureKotlinCompilerAddedToClassPath() { - try { - Class.forName("org.jetbrains.kotlin.jps.build.KotlinBuilder") + if (getClass().getResource("/org/jetbrains/kotlin/jps/build/KotlinBuilder.class") != null) { return } - catch (ClassNotFoundException ignored) { - } def kotlinPluginLibPath = "$context.paths.communityHome/build/dependencies/build/Kotlin/lib" if (new File(kotlinPluginLibPath).exists()) { diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy index 5681bb964a61..df85abd7b929 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/impl/WindowsDistributionBuilder.groovy @@ -82,7 +82,7 @@ class WindowsDistributionBuilder extends OsSpecificDistributionBuilder { void buildArtifacts(String winDistPath) { def arch = customizer.bundledJreArchitecture def jreDirectoryPath64 = arch != null ? buildContext.bundledJreManager.extractWinJre(arch) : null - List jreDirectoryPaths = [jreDirectoryPath64]; + List jreDirectoryPaths = [jreDirectoryPath64] if (customizer.getBaseDownloadUrlForJre() != null && arch != JvmArchitecture.x32) { File archive = buildContext.bundledJreManager.findWinJreArchive(JvmArchitecture.x32) @@ -94,7 +94,7 @@ class WindowsDistributionBuilder extends OsSpecificDistributionBuilder { include(name: "**/**") } } - jreDirectoryPaths = [jreDirectoryPath64, jreDirectoryPath]; + jreDirectoryPaths = [jreDirectoryPath64, jreDirectoryPath] } } @@ -178,14 +178,14 @@ class WindowsDistributionBuilder extends OsSpecificDistributionBuilder { String vmOptions = "$buildContext.additionalJvmArguments -Didea.paths.selector=${buildContext.systemSelector}".trim() def productName = buildContext.applicationInfo.shortProductName - String jdkEnvVarSuffix = arch == JvmArchitecture.x64 && customizer.include32BitLauncher ? "_64" : ""; + String jdkEnvVarSuffix = arch == JvmArchitecture.x64 && customizer.include32BitLauncher ? "_64" : "" String vmOptionsEnvVarSuffix = arch == JvmArchitecture.x64 && customizer.include32BitLauncher ? "64" : "" def envVarBaseName = buildContext.productProperties.getEnvironmentVariableBaseName(buildContext.applicationInfo) new File(launcherPropertiesPath).text = """ IDS_JDK_ONLY=$buildContext.productProperties.toolsJarRequired IDS_JDK_ENV_VAR=${envVarBaseName}_JDK$jdkEnvVarSuffix IDS_APP_TITLE=$productName Launcher -IDS_VM_OPTIONS_PATH=%USERPROFILE%\\\\.$buildContext.systemSelector +IDS_VM_OPTIONS_PATH=%USERPROFILE%\\\\.$buildContext.systemSelector\\\\config IDS_VM_OPTION_ERRORFILE=-XX:ErrorFile=%USERPROFILE%\\\\java_error_in_${lowerCaseProductName}_%p.log IDS_VM_OPTION_HEAPDUMPPATH=-XX:HeapDumpPath=%USERPROFILE%\\\\java_error_in_${lowerCaseProductName}.hprof IDC_WINLAUNCHER=${upperCaseProductName}_LAUNCHER diff --git a/platform/core-api/src/com/intellij/psi/stubs/EmptyStubElementType.java b/platform/core-api/src/com/intellij/psi/stubs/EmptyStubElementType.java index 634b491854b3..6fcba842d7b3 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/EmptyStubElementType.java +++ b/platform/core-api/src/com/intellij/psi/stubs/EmptyStubElementType.java @@ -31,6 +31,7 @@ public abstract class EmptyStubElementType extends IStubEl super(debugName, language); } + @NotNull @Override public final EmptyStub createStub(@NotNull T psi, StubElement parentStub) { return createStub(parentStub); diff --git a/platform/core-api/src/com/intellij/psi/stubs/IStubElementType.java b/platform/core-api/src/com/intellij/psi/stubs/IStubElementType.java index bb3f87afa3b7..cfe36c13d63d 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/IStubElementType.java +++ b/platform/core-api/src/com/intellij/psi/stubs/IStubElementType.java @@ -22,24 +22,32 @@ package com.intellij.psi.stubs; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.Extensions; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Arrays; + public abstract class IStubElementType extends IElementType implements StubSerializer { - private static boolean ourInitializedStubs; + private static volatile boolean ourInitializedStubs; private static final Logger LOG = Logger.getInstance("#com.intellij.psi.stubs.IStubElementType"); public IStubElementType(@NotNull @NonNls final String debugName, @Nullable final Language language) { super(debugName, language); if (ourInitializedStubs) { - LOG.error("All stub element types should be created before index initialization is complete. Please add the class containing stub element type constants to \"stubElementTypeHolder\" extension."); + LOG.error("All stub element types should be created before index initialization is complete.\n" + + "Please add the class containing stub element type constants to \"stubElementTypeHolder\" extension.\n" + + "Registered extensions: " + Arrays.toString(StubElementTypeHolderEP.EP_NAME.getExtensions())); } } - static void markStubInitializationComplete() { + static void loadRegisteredStubElementTypes() { + for (StubElementTypeHolderEP holderEP : Extensions.getExtensions(StubElementTypeHolderEP.EP_NAME)) { + holderEP.initialize(); + } ourInitializedStubs = true; } diff --git a/platform/indexing-api/src/com/intellij/psi/stubs/StubElementTypeHolderEP.java b/platform/core-api/src/com/intellij/psi/stubs/StubElementTypeHolderEP.java similarity index 92% rename from platform/indexing-api/src/com/intellij/psi/stubs/StubElementTypeHolderEP.java rename to platform/core-api/src/com/intellij/psi/stubs/StubElementTypeHolderEP.java index 9d4f64ff1429..60fee521c764 100644 --- a/platform/indexing-api/src/com/intellij/psi/stubs/StubElementTypeHolderEP.java +++ b/platform/core-api/src/com/intellij/psi/stubs/StubElementTypeHolderEP.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,4 +40,9 @@ public class StubElementTypeHolderEP extends AbstractExtensionPointBean { LOG.error(e); } } + + @Override + public String toString() { + return holderClass; + } } diff --git a/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java b/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java index 481c376804d1..922145918392 100644 --- a/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java +++ b/platform/diff-impl/src/com/intellij/diff/util/DiffUtil.java @@ -120,7 +120,6 @@ public class DiffUtil { @NotNull private static List loadDiffFrameImages() { return ContainerUtil.list( - ImageLoader.loadFromResource("/diff_frame16.png"), ImageLoader.loadFromResource("/diff_frame32.png"), ImageLoader.loadFromResource("/diff_frame64.png"), ImageLoader.loadFromResource("/diff_frame128.png") diff --git a/platform/diff-impl/tests/com/intellij/diff/DiffTestCase.kt b/platform/diff-impl/tests/com/intellij/diff/DiffTestCase.kt index 6bcb79123e0c..bb501a53faa3 100644 --- a/platform/diff-impl/tests/com/intellij/diff/DiffTestCase.kt +++ b/platform/diff-impl/tests/com/intellij/diff/DiffTestCase.kt @@ -115,6 +115,18 @@ abstract class DiffTestCase : TestCase() { } } + fun assertSetsEquals(expected: BitSet, actual: BitSet, message: String = "") { + val sb = StringBuilder(message) + sb.append(": \"") + for (i in 0..actual.length()) { + sb.append(if (actual[i]) '-' else ' ') + } + sb.append('"') + val fullMessage = sb.toString() + + assertEquals(expected, actual, fullMessage) + } + // // Parsing // @@ -210,7 +222,7 @@ abstract class DiffTestCase : TestCase() { } } - class DebugData() { + class DebugData { private val data: MutableList> = ArrayList() fun put(key: String, value: Any) { diff --git a/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonMergeUtilTestBase.kt b/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonMergeUtilTestBase.kt index c116de58652e..249bf8674e48 100644 --- a/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonMergeUtilTestBase.kt +++ b/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonMergeUtilTestBase.kt @@ -73,12 +73,12 @@ abstract class ComparisonMergeUtilTestBase : DiffTestCase() { val sets = Trio(BitSet(), BitSet(), BitSet()) for (change in changes) { - sets.forEach({ set: BitSet, side: ThreeSide -> set.set(change.start(side), change.end(side)) }) + sets.forEach { set: BitSet, side: ThreeSide -> set.set(change.start(side), change.end(side)) } } - assertEquals(matchings.data1, sets.data1) - assertEquals(matchings.data2, sets.data2) - assertEquals(matchings.data3, sets.data3) + assertSetsEquals(matchings.data1, sets.data1, "Left") + assertSetsEquals(matchings.data2, sets.data2, "Base") + assertSetsEquals(matchings.data3, sets.data3, "Right") } private fun convertDiffFragments(fragments: List): List { diff --git a/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonUtilAutoTest.kt b/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonUtilAutoTest.kt index c415aa47ae47..b117f7261577 100644 --- a/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonUtilAutoTest.kt +++ b/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonUtilAutoTest.kt @@ -198,8 +198,8 @@ class ComparisonUtilAutoTest : DiffTestCase() { for (fragment in fragments) { if (fragment.innerFragments != null) { - val sequence1 = text1.subsequence(fragment.startOffset1, fragment.endOffset1) - val sequence2 = text2.subsequence(fragment.startOffset2, fragment.endOffset2) + val sequence1 = text1.subSequence(fragment.startOffset1, fragment.endOffset1) + val sequence2 = text2.subSequence(fragment.startOffset2, fragment.endOffset2) checkResultWord(sequence1, sequence2, fragment.innerFragments!!, policy) } @@ -538,7 +538,7 @@ class ComparisonUtilAutoTest : DiffTestCase() { return Couple.of(firstLine, lastLine) } - private fun Document.subsequence(start: Int, end: Int): CharSequence { + private fun Document.subSequence(start: Int, end: Int): CharSequence { return this.charsSequence.subSequence(start, end) } diff --git a/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonUtilTestBase.kt b/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonUtilTestBase.kt index 9d9bf6796202..f8750fc000dc 100644 --- a/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonUtilTestBase.kt +++ b/platform/diff-impl/tests/com/intellij/diff/comparison/ComparisonUtilTestBase.kt @@ -173,8 +173,8 @@ abstract class ComparisonUtilTestBase : DiffTestCase() { set2.set(fragment.startLine2, fragment.endLine2) } - assertEquals(matchings.first, set1, "Before") - assertEquals(matchings.second, set2, "After") + assertSetsEquals(matchings.first, set1, "Before") + assertSetsEquals(matchings.second, set2, "After") } private fun checkDiffMatching(fragments: List, matchings: Couple) { @@ -185,8 +185,8 @@ abstract class ComparisonUtilTestBase : DiffTestCase() { set2.set(fragment.startOffset2, fragment.endOffset2) } - assertEquals(matchings.first, set1, "Before") - assertEquals(matchings.second, set2, "After") + assertSetsEquals(matchings.first, set1, "Before") + assertSetsEquals(matchings.second, set2, "After") } private fun checkMergeMatching(fragments: List, matchings: Trio) { @@ -199,9 +199,9 @@ abstract class ComparisonUtilTestBase : DiffTestCase() { set3.set(fragment.getStartOffset(ThreeSide.RIGHT), fragment.getEndOffset(ThreeSide.RIGHT)) } - assertEquals(matchings.data1, set1, "Before") - assertEquals(matchings.data2, set2, "Base") - assertEquals(matchings.data3, set3, "After") + assertSetsEquals(matchings.data1, set1, "Left") + assertSetsEquals(matchings.data2, set2, "Base") + assertSetsEquals(matchings.data3, set3, "Right") } private fun convertDiffFragments(fragments: List): List> { diff --git a/platform/diff-impl/tests/com/intellij/diff/comparison/IgnoreComparisonUtilTest.kt b/platform/diff-impl/tests/com/intellij/diff/comparison/IgnoreComparisonUtilTest.kt index fce98b3c2574..825437f5cd43 100644 --- a/platform/diff-impl/tests/com/intellij/diff/comparison/IgnoreComparisonUtilTest.kt +++ b/platform/diff-impl/tests/com/intellij/diff/comparison/IgnoreComparisonUtilTest.kt @@ -401,28 +401,17 @@ class IgnoreComparisonUtilTest : DiffTestCase() { .run() } - private inner class Test(input1: String, input2: String, + private inner class Test(val input1: String, val input2: String, ignored1: String, ignored2: String, result1: String, result2: String) { - private val input1: String - private val input2: String - private val ignored1: String - private val ignored2: String - private val result1: String - private val result2: String + val ignored1: String = ignored1.filterNot { it == '.' } + val ignored2: String = ignored2.filterNot { it == '.' } + val result1: String = result1.filterNot { it == '.' } + val result2: String = result2.filterNot { it == '.' } private var inner = true private var changedLines: IntPair? = null - init { - this.input1 = input1 - this.input2 = input2 - this.ignored1 = ignored1.filterNot { it == '.' } - this.ignored2 = ignored2.filterNot { it == '.' } - this.result1 = result1.filterNot { it == '.' } - this.result2 = result2.filterNot { it == '.' } - } - fun noInnerChanges(): Test { inner = false return this diff --git a/platform/diff-impl/tests/com/intellij/diff/comparison/SplitComparisonUtilTest.kt b/platform/diff-impl/tests/com/intellij/diff/comparison/SplitComparisonUtilTest.kt index 0e52c2c09115..e25ec85c1243 100644 --- a/platform/diff-impl/tests/com/intellij/diff/comparison/SplitComparisonUtilTest.kt +++ b/platform/diff-impl/tests/com/intellij/diff/comparison/SplitComparisonUtilTest.kt @@ -74,6 +74,23 @@ class SplitComparisonUtilTest : ComparisonUtilTestBase() { default(del(0, 0, 1), mod(1, 0, 1, 1), del(2, 1, 1)) testAll() } + + splitter(trim = false) { + ("< i" - "" - "x'y'>") + (" " - " -- ").default() + testAll() + } + + lines_inner { + ("x'y'>" - "x'>") + (" -- " - " ").default() + testAll() + } } fun testWhitespaceOnlyChanges() { @@ -219,6 +252,12 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() { ("- -" - "- -").ignore() testIgnore() } + + words { + ("A_B_" - "X_") + ("--- " - "- ").default() + testAll() + } } fun testFixedBugs() { @@ -336,6 +375,26 @@ class WordComparisonUtilTest : ComparisonUtilTestBase() { (" ---" - "--- ").default() testDefault() } + + lines_inner { + ("A B_C D" - "A_B C_D") + (" -- - " - " -- - ").default() + (" -- - " - " -- ").trim() + (" - " - " - ").ignore() + testAll() + } + + lines_inner { + ("B_C_D_" - "X_Y_Z_") + ("- - - " - "- - - ").default() + testAll() + } + + words { + ("!x_!_z" - "!_!_y z") + (" - " - " -- ").default() + testDefault() + } } fun `test trailing punctuation`() { diff --git a/platform/icons/src/diff_frame128.png b/platform/icons/src/diff_frame128.png index 7fe30c294739..dea2af2cd39f 100644 Binary files a/platform/icons/src/diff_frame128.png and b/platform/icons/src/diff_frame128.png differ diff --git a/platform/icons/src/diff_frame16.png b/platform/icons/src/diff_frame16.png deleted file mode 100644 index b86600dd917b..000000000000 Binary files a/platform/icons/src/diff_frame16.png and /dev/null differ diff --git a/platform/icons/src/diff_frame32.png b/platform/icons/src/diff_frame32.png index 65bb77966fd3..8f09468171a0 100644 Binary files a/platform/icons/src/diff_frame32.png and b/platform/icons/src/diff_frame32.png differ diff --git a/platform/icons/src/diff_frame64.png b/platform/icons/src/diff_frame64.png index faab388ebb6a..754e9907427a 100644 Binary files a/platform/icons/src/diff_frame64.png and b/platform/icons/src/diff_frame64.png differ diff --git a/platform/indexing-api/src/com/intellij/psi/stubs/SerializationManager.java b/platform/indexing-api/src/com/intellij/psi/stubs/SerializationManager.java index 24e766db456e..b72f8bb57a5c 100644 --- a/platform/indexing-api/src/com/intellij/psi/stubs/SerializationManager.java +++ b/platform/indexing-api/src/com/intellij/psi/stubs/SerializationManager.java @@ -20,7 +20,6 @@ package com.intellij.psi.stubs; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.extensions.Extensions; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.StubFileElementType; import org.jetbrains.annotations.NotNull; @@ -45,10 +44,7 @@ public abstract class SerializationManager { if (mySerializersLoaded) return; synchronized (this) { if (mySerializersLoaded) return; - for (StubElementTypeHolderEP holderEP : Extensions.getExtensions(StubElementTypeHolderEP.EP_NAME)) { - holderEP.initialize(); - } - IStubElementType.markStubInitializationComplete(); + IStubElementType.loadRegisteredStubElementTypes(); final IElementType[] stubElementTypes = IElementType.enumerate(new IElementType.Predicate() { @Override public boolean matches(@NotNull final IElementType type) { diff --git a/platform/lang-api/src/com/intellij/execution/RunManager.kt b/platform/lang-api/src/com/intellij/execution/RunManager.kt index e3e9fe774988..2475e16d8670 100644 --- a/platform/lang-api/src/com/intellij/execution/RunManager.kt +++ b/platform/lang-api/src/com/intellij/execution/RunManager.kt @@ -176,6 +176,8 @@ abstract class RunManager { */ abstract fun refreshUsagesList(profile: RunProfile) + fun hasSettings(settings: RunnerAndConfigurationSettings) = allSettings.contains(settings) + fun suggestUniqueName(name: String?, type: ConfigurationType?): String { val settingsList = if (type == null) allSettings else getConfigurationSettingsList(type) return suggestUniqueName(name.nullize() ?: UNNAMED, settingsList.map { it.name }) diff --git a/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java b/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java index 8864b58aa612..555d9d1e10e9 100644 --- a/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java +++ b/platform/lang-api/src/com/intellij/execution/RunnerAndConfigurationSettings.java @@ -31,11 +31,8 @@ import org.jetbrains.annotations.Nullable; public interface RunnerAndConfigurationSettings { /** * Returns the type of the run configuration. - * - * @return the type of the run configuration, or null if the settings object was loaded from disk and no plugin corresponding to the - * stored type of the run configuration is loaded. */ - @Nullable + @NotNull ConfigurationType getType(); /** diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java index 4954fba83c6b..57299e47b8b6 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfiguration.java @@ -44,11 +44,11 @@ public interface RunConfiguration extends RunProfile, Cloneable { /** * Returns the type of the run configuration. - * - * @return the configuration type. */ @NotNull - ConfigurationType getType(); + default ConfigurationType getType() { + return getFactory().getType(); + } /** * Returns the factory that has created the run configuration. diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java index bcc8f1ac99ce..f0afd43073a5 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationBase.java @@ -98,12 +98,6 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements return myProject; } - @Override - @NotNull - public ConfigurationType getType() { - return myFactory.getType(); - } - @Override public Icon getIcon() { return myIcon; diff --git a/platform/lang-api/src/com/intellij/execution/configurations/UnknownRunConfiguration.java b/platform/lang-api/src/com/intellij/execution/configurations/UnknownRunConfiguration.java index 710d6038b5f9..55c9a96827c7 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/UnknownRunConfiguration.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/UnknownRunConfiguration.java @@ -83,12 +83,6 @@ public class UnknownRunConfiguration implements RunConfiguration, WithoutOwnBefo return myProject; } - @Override - @NotNull - public ConfigurationType getType() { - return UnknownConfigurationType.INSTANCE; - } - @Override public RunConfiguration clone() { try { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.java index 746054ae90bf..4c7ff762cdb7 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlighter.java @@ -23,11 +23,10 @@ import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.SelectionModel; import com.intellij.openapi.editor.event.*; import com.intellij.openapi.editor.ex.DocumentEx; -import com.intellij.openapi.editor.ex.EditorEventMulticasterEx; -import com.intellij.openapi.editor.ex.FocusChangeListener; -import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.FileEditorManagerEvent; import com.intellij.openapi.fileEditor.FileEditorManagerListener; +import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.startup.StartupActivity; import com.intellij.openapi.util.TextRange; @@ -96,27 +95,20 @@ public class BraceHighlighter implements StartupActivity { }; eventMulticaster.addDocumentListener(documentListener, project); - final FocusChangeListener myFocusChangeListener = new FocusChangeListener() { - @Override - public void focusLost(Editor editor) { - clearBraces(editor); - } - - @Override - public void focusGained(Editor editor) { - updateBraces(editor, myAlarm); - } - }; - ((EditorEventMulticasterEx)eventMulticaster).addFocusChangeListner(myFocusChangeListener, project); - - final FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); - - fileEditorManager.addFileEditorManagerListener(new FileEditorManagerListener() { + project.getMessageBus().connect().subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new FileEditorManagerListener() { @Override public void selectionChanged(@NotNull FileEditorManagerEvent e) { myAlarm.cancelAllRequests(); + FileEditor oldEditor = e.getOldEditor(); + if (oldEditor instanceof TextEditor) { + clearBraces(((TextEditor)oldEditor).getEditor()); + } + FileEditor newEditor = e.getNewEditor(); + if (newEditor instanceof TextEditor) { + updateBraces(((TextEditor)newEditor).getEditor(), myAlarm); + } } - }, project); + }); } static void updateBraces(@NotNull final Editor editor, @NotNull final Alarm alarm) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java index fda551d2546b..85850d103124 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java @@ -567,6 +567,7 @@ public class BraceHighlightingHandler { hint.hide(); myEditor.putUserData(HINT_IN_EDITOR_KEY, null); } + removeLineMarkers(); } private void lineMarkFragment(int startLine, int endLine, @NotNull Color color) { diff --git a/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java b/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java index cba123dcddf7..34a9f409641d 100644 --- a/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java +++ b/platform/lang-impl/src/com/intellij/execution/RunManagerEx.java @@ -97,8 +97,14 @@ public abstract class RunManagerEx extends RunManager { public abstract Icon getConfigurationIcon(@NotNull RunnerAndConfigurationSettings settings, boolean withLiveIndicator); + /** + * @deprecated Use {@link #getAllSettings()} + */ @NotNull - public abstract Collection getSortedConfigurations(); + @Deprecated + public final Collection getSortedConfigurations() { + return getAllSettings(); + } public abstract void removeConfiguration(@Nullable RunnerAndConfigurationSettings settings); diff --git a/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationsComboBoxAction.java b/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationsComboBoxAction.java index cf287e5f7f54..0779bb86c6b4 100644 --- a/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationsComboBoxAction.java +++ b/platform/lang-impl/src/com/intellij/execution/actions/RunConfigurationsComboBoxAction.java @@ -34,6 +34,7 @@ import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.SizedIcon; import com.intellij.ui.components.panels.NonOpaquePanel; import com.intellij.util.IconUtil; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.EmptyIcon; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; @@ -41,7 +42,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.util.Iterator; import java.util.List; import java.util.Map; @@ -225,8 +225,7 @@ public class RunConfigurationsComboBoxAction extends ComboBoxAction implements D if (selectedConfiguration != null && selectedConfiguration.isTemporary()) { return selectedConfiguration; } - Iterator iterator = RunManager.getInstance(project).getTempConfigurationsList().iterator(); - return iterator.hasNext() ? iterator.next() : null; + return ContainerUtil.getFirstItem(RunManager.getInstance(project).getTempConfigurationsList()); } } diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java index 903b5d104349..a4a023889730 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/CopyConfigurationAction.java @@ -49,8 +49,7 @@ public class CopyConfigurationAction extends RunConfigurationTreeAction { @Override protected boolean isEnabled4(DashboardRunConfigurationNode node) { - return RunManager.getInstance(node.getProject()).getAllConfigurationsList().contains( - node.getConfigurationSettings().getConfiguration()); + return RunManager.getInstance(node.getProject()).hasSettings(node.getConfigurationSettings()); } @Override diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/EditConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/EditConfigurationAction.java index 1622456db19a..680652cb74bf 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/EditConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/EditConfigurationAction.java @@ -41,8 +41,7 @@ public class EditConfigurationAction extends RunConfigurationTreeAction { @Override protected boolean isEnabled4(DashboardRunConfigurationNode node) { - return RunManager.getInstance(node.getProject()).getAllConfigurationsList().contains( - node.getConfigurationSettings().getConfiguration()); + return RunManager.getInstance(node.getProject()).hasSettings(node.getConfigurationSettings()); } @Override diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RemoveConfigurationAction.java b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RemoveConfigurationAction.java index d83295f0af97..3733e2f189be 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RemoveConfigurationAction.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/actions/RemoveConfigurationAction.java @@ -40,8 +40,7 @@ public class RemoveConfigurationAction extends RunConfigurationTreeAction { @Override protected boolean isEnabled4(DashboardRunConfigurationNode node) { - return RunManager.getInstance(node.getProject()).getAllConfigurationsList().contains( - node.getConfigurationSettings().getConfiguration()); + return RunManager.getInstance(node.getProject()).hasSettings(node.getConfigurationSettings()); } @Override diff --git a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/RunConfigurationNode.java b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/RunConfigurationNode.java index e0771d60f363..666c8a90067b 100644 --- a/platform/lang-impl/src/com/intellij/execution/dashboard/tree/RunConfigurationNode.java +++ b/platform/lang-impl/src/com/intellij/execution/dashboard/tree/RunConfigurationNode.java @@ -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. @@ -64,7 +64,7 @@ class RunConfigurationNode extends AbstractTreeNode settings != null && usesMyModule(settings.getConfiguration()); @NotNull private final RunManagerImpl myManager; - @Nullable - private List myUnloadedElements = null; public ModuleRunConfigurationManager(@NotNull final Module module, @NotNull final RunManagerImpl runManager) { myModule = module; @@ -99,7 +94,7 @@ public final class ModuleRunConfigurationManager implements PersistentStateCompo @NotNull private Collection getModuleRunConfigurationSettings() { - return ContainerUtil.filter(myManager.getConfigurationSettings(), myModuleConfigCondition); + return ContainerUtil.filter(myManager.getAllSettings(), myModuleConfigCondition); } private boolean usesMyModule(RunConfiguration config) { @@ -110,11 +105,6 @@ public final class ModuleRunConfigurationManager implements PersistentStateCompo public void writeExternal(@NotNull final Element element) throws WriteExternalException { LOG.debug("writeExternal(" + myModule + ")"); myManager.writeConfigurations(element, getModuleRunConfigurationSettings()); - if (myUnloadedElements != null) { - for (final Element unloadedElement : myUnloadedElements) { - element.addContent(unloadedElement.clone()); - } - } } public void readExternal(@NotNull final Element element) { @@ -125,33 +115,18 @@ public final class ModuleRunConfigurationManager implements PersistentStateCompo private void doReadExternal(@NotNull Element element) { LOG.debug("readExternal(" + myModule + ")"); - myUnloadedElements = null; - final Set existing = new HashSet<>(); + final Set existing = new SmartHashSet<>(); - for (final Element child : element.getChildren()) { - final RunnerAndConfigurationSettings configuration = myManager.loadConfiguration(child, true); - if (configuration == null && Comparing.strEqual(element.getName(), RunManagerImpl.CONFIGURATION)) { - if (myUnloadedElements == null) myUnloadedElements = new ArrayList<>(2); - myUnloadedElements.add(element); - } + for (final Element child : element.getChildren(RunManagerImpl.CONFIGURATION)) { + existing.add(myManager.loadConfiguration(child, true).getUniqueID()); + } - if (configuration != null) { - existing.add(configuration.getUniqueID()); + for (RunnerAndConfigurationSettings settings : myManager.getAllSettings()) { + if (!usesMyModule(settings.getConfiguration())) { + existing.add(settings.getUniqueID()); } } - for (final RunConfiguration configuration : myManager.getAllConfigurationsList()) { - if (!usesMyModule(configuration)) { - RunnerAndConfigurationSettings settings = myManager.getSettings(configuration); - if (settings != null) { - existing.add(settings.getUniqueID()); - } - } - } myManager.removeNotExistingSharedConfigurations(existing); - - // IDEA-60004: configs may never be sorted before write, so call it manually after shared configs read - myManager.setOrdered(false); - myManager.getSortedConfigurations(); } } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java index 8237bdafedad..7d95ada6252a 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ProjectRunConfigurationManager.java @@ -16,27 +16,22 @@ package com.intellij.execution.impl; import com.intellij.execution.RunnerAndConfigurationSettings; -import com.intellij.execution.configurations.RunConfiguration; 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 com.intellij.util.SmartList; -import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NotNull; -import java.util.Iterator; 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; - private List myUnloadedElements; public ProjectRunConfigurationManager(@NotNull RunManagerImpl manager) { myManager = manager; @@ -46,51 +41,26 @@ public class ProjectRunConfigurationManager implements PersistentStateComponent< public Element getState() { Element state = new Element("state"); myManager.writeConfigurations(state, myManager.getSharedConfigurations()); - if (!ContainerUtil.isEmpty(myUnloadedElements)) { - for (Element unloadedElement : myUnloadedElements) { - state.addContent(unloadedElement.clone()); - } - } return state; } @Override public void loadState(Element state) { - if (myUnloadedElements != null) { - myUnloadedElements.clear(); - } - Set existing = new THashSet<>(); - for (Iterator iterator = state.getChildren().iterator(); iterator.hasNext(); ) { - Element child = iterator.next(); - RunnerAndConfigurationSettings configuration = myManager.loadConfiguration(child, true); - if (configuration != null) { - existing.add(configuration.getUniqueID()); - } - else if (child.getName().equals(RunManagerImpl.CONFIGURATION)) { - if (myUnloadedElements == null) { - myUnloadedElements = new SmartList<>(); - } - iterator.remove(); - myUnloadedElements.add(child); - } + for (Element child : state.getChildren(RunManagerImpl.CONFIGURATION)) { + existing.add(myManager.loadConfiguration(child, true).getUniqueID()); } myManager.removeNotExistingSharedConfigurations(existing); + if (myManager.getSelectedConfiguration() == null) { - final List allConfigurations = myManager.getAllConfigurationsList(); - for (final RunConfiguration configuration : allConfigurations) { - final RunnerAndConfigurationSettings settings = myManager.getSettings(allConfigurations.get(0)); - if (!(configuration instanceof UnknownRunConfiguration)) { + for (RunnerAndConfigurationSettings settings : myManager.getAllSettings()) { + if (!(settings.getType() instanceof UnknownRunConfiguration)) { myManager.setSelectedConfiguration(settings); break; } } } - - // IDEA-60004: configs may never be sorted before write, so call it manually after shared configs read - myManager.setOrdered(false); - myManager.getSortedConfigurations(); } static class RunConfigurationStateSplitter extends StateSplitterEx { 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 f46d570fc6db..0728028149d5 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java @@ -704,7 +704,7 @@ class RunConfigurable extends BaseConfigurable { each.first.apply(); } - manager.saveOrder(); + manager.setOrder(null); } finally { getRunManager().fireEndUpdate(); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java index 440f12c2d6b6..d8112243eb87 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationBeforeRunProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -113,7 +113,7 @@ extends BeforeRunTaskProvider configurations = - RunManagerImpl.getInstanceImpl(runConfiguration.getProject()).getSortedConfigurations(); + RunManagerImpl.getInstanceImpl(runConfiguration.getProject()).getAllSettings(); if (configurations.isEmpty() || (configurations.size() == 1 && configurations.iterator().next().getConfiguration() == runConfiguration)) { return null; @@ -144,7 +144,7 @@ extends BeforeRunTaskProvider configurations = new ArrayList<>(RunManagerImpl.getInstanceImpl(project).getSortedConfigurations()); + List configurations = new ArrayList<>(RunManagerImpl.getInstanceImpl(project).getAllSettings()); String executorId = DefaultRunExecutor.getRunExecutorInstance().getId(); for (Iterator iterator = configurations.iterator(); iterator.hasNext();) { RunnerAndConfigurationSettings settings = iterator.next(); diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationRefactoringElementListenerProvider.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationRefactoringElementListenerProvider.java index 94571a9c1927..9a713784c1fe 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationRefactoringElementListenerProvider.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurationRefactoringElementListenerProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,6 @@ import com.intellij.refactoring.listeners.RefactoringElementListener; import com.intellij.refactoring.listeners.RefactoringElementListenerComposite; import com.intellij.refactoring.listeners.RefactoringElementListenerProvider; -import java.util.List; - /** * @author spleaner */ @@ -36,9 +34,7 @@ public class RunConfigurationRefactoringElementListenerProvider implements Refac @Override public RefactoringElementListener getListener(final PsiElement element) { RefactoringElementListenerComposite composite = null; - final List configurations = RunManager.getInstance(element.getProject()).getAllConfigurationsList(); - - for (RunConfiguration configuration : configurations) { + for (RunConfiguration configuration : RunManager.getInstance(element.getProject()).getAllConfigurationsList()) { if (configuration instanceof RefactoringListenerProvider) { // todo: perhaps better way to handle listeners? RefactoringElementListener listener; try { 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 3e1dc6729386..90b331b981a9 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunManagerImpl.kt @@ -31,7 +31,6 @@ import com.intellij.openapi.components.* import com.intellij.openapi.diagnostic.catchAndLog import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.extensions.Extensions -import com.intellij.openapi.options.Scheme import com.intellij.openapi.options.SchemeManagerFactory import com.intellij.openapi.project.IndexNotReadyException import com.intellij.openapi.project.Project @@ -39,9 +38,7 @@ import com.intellij.openapi.roots.ModuleRootEvent import com.intellij.openapi.roots.ModuleRootListener import com.intellij.openapi.updateSettings.impl.pluginsAdvertisement.UnknownFeaturesCollector import com.intellij.openapi.util.InvalidDataException -import com.intellij.openapi.util.JDOMExternalizableStringList import com.intellij.openapi.util.Key -import com.intellij.openapi.util.Pair import com.intellij.openapi.util.registry.Registry import com.intellij.util.EventDispatcher import com.intellij.util.IconUtil @@ -111,18 +108,16 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent private val iconCache = TimedIconCache() private val _config by lazy { RunManagerConfig(PropertiesComponent.getInstance(project)) } - @Suppress("DEPRECATION") - private val myOrder = JDOMExternalizableStringList() + private val customOrder = ArrayList() private val recentlyUsedTemporaries = ArrayList() - private var myOrdered = true private val myDispatcher = EventDispatcher.create(RunManagerListener::class.java)!! private val schemeManagerProvider = SchemeManagerIprProvider("configuration") private val schemeManager = SchemeManagerFactory.getInstance(project).create("workspace", - object : LazySchemeProcessor() { - override fun createScheme(dataHolder: SchemeDataHolder, name: String, attributeProvider: Function, isBundled: Boolean): RunConfigurationScheme { + object : LazySchemeProcessor() { + override fun createScheme(dataHolder: SchemeDataHolder, name: String, attributeProvider: Function, isBundled: Boolean): RunnerAndConfigurationSettingsImpl { val settings = RunnerAndConfigurationSettingsImpl(this@RunManagerImpl) val element = dataHolder.read() try { @@ -212,7 +207,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent */ override fun getConfigurationsList(type: ConfigurationType): List { var result: MutableList? = null - for (settings in sortedConfigurations) { + for (settings in allSettings) { val configuration = settings.configuration if (type.id == configuration.type.id) { if (result == null) { @@ -225,16 +220,11 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } override val allConfigurationsList: List - get() = sortedConfigurations.mapSmart { it.configuration } + get() = allSettings.mapSmart { it.configuration } - override val allSettings: List - get() = sortedConfigurations.toList() + fun getSettings(configuration: RunConfiguration) = allSettings.firstOrNull { it.configuration === configuration } as? RunnerAndConfigurationSettingsImpl - fun getSettings(configuration: RunConfiguration) = sortedConfigurations.firstOrNull { it.configuration === configuration } as? RunnerAndConfigurationSettingsImpl - - override fun getConfigurationSettingsList(type: ConfigurationType) = lock.read { sortedConfigurations.filterSmart { it.type?.id == type.id } } - - fun getConfigurationSettings() = idToSettings.values.toTypedArray() + override fun getConfigurationSettingsList(type: ConfigurationType) = allSettings.filterSmart { it.type.id == type.id } override fun getStructure(type: ConfigurationType): Map> { val result = LinkedHashMap>() @@ -275,6 +265,8 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent var existingSettings: RunnerAndConfigurationSettings? = null var existingId: String? = null lock.write { + immutableSortedSettingsList = null + existingId = findExistingConfigurationId(settings) existingId?.let { existingSettings = idToSettings.remove(it) @@ -286,11 +278,11 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent idToSettings.put(newId, settings) if (existingId == null) { - refreshUsagesList(settings.configuration) + refreshUsagesList(settings) } if (!settings.isShared && existingSettings !== settings) { - schemeManager.addScheme(settings as RunConfigurationScheme) + schemeManager.addScheme(settings as RunnerAndConfigurationSettingsImpl) } } @@ -305,11 +297,20 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } override fun refreshUsagesList(profile: RunProfile) { - if (profile !is RunConfiguration) return - val settings = getSettings(profile) - if (settings != null && settings.isTemporary) { - recentlyUsedTemporaries.remove(profile) - recentlyUsedTemporaries.add(0, profile) + if (profile !is RunConfiguration) { + return + } + + getSettings(profile)?.let { + refreshUsagesList(it) + } + } + + fun refreshUsagesList(settings: RunnerAndConfigurationSettings) { + if (settings.isTemporary) { + val configuration = settings.configuration + recentlyUsedTemporaries.remove(configuration) + recentlyUsedTemporaries.add(0, configuration) trimUsagesListToLimit() } } @@ -322,45 +323,38 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent fun checkRecentsLimit() { trimUsagesListToLimit() - val removed = SmartList() + var removed: MutableList? = null lock.write { - while (tempConfigurationsList.size > config.recentsLimit) { + while (idToSettings.values.count { it.isTemporary } > config.recentsLimit) { val it = idToSettings.values.iterator() while (it.hasNext()) { val settings = it.next() if (settings.isTemporary && !recentlyUsedTemporaries.contains(settings.configuration)) { - removed.add(settings) + if (removed == null) { + immutableSortedSettingsList = null + removed = SmartList() + } + removed!!.add(settings) it.remove() break } } } } - fireRunConfigurationsRemoved(removed) - } - - fun setOrdered(ordered: Boolean) { - myOrdered = ordered - } - - fun saveOrder() { - setOrder(null) - } - - private fun doSaveOrder(comparator: Comparator?) { - val sorted = idToSettings.values.filter { it.type !is UnknownConfigurationType } - if (comparator != null) { - sorted.sortedWith(comparator) - } - - myOrder.clear() - sorted.mapTo(myOrder) { it.uniqueID} + removed?.let { fireRunConfigurationsRemoved(it) } } fun setOrder(comparator: Comparator?) { - doSaveOrder(comparator) - // force recache of configurations list - setOrdered(false) + lock.write { + val sorted = idToSettings.values.filterTo(ArrayList(idToSettings.size)) { it.type !is UnknownConfigurationType } + if (comparator != null) { + sorted.sortWith(comparator) + } + customOrder.clear() + customOrder.ensureCapacity(sorted.size) + sorted.mapTo(customOrder) { it.uniqueID } + immutableSortedSettingsList = null + } } override var selectedConfiguration: RunnerAndConfigurationSettings? @@ -377,77 +371,94 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent private fun setSelectedConfigurationId(id: String?) { selectedConfigurationId = id - if (selectedConfigurationId != null) { + if (id != null) { loadedSelectedConfigurationUniqueName = null } } - override fun getSortedConfigurations(): MutableCollection { - if (myOrdered) { - return idToSettings.values - } + private data class OrderItem(val id: String, val settings: RunnerAndConfigurationSettings) - val order = ArrayList>(idToSettings.size) - val folderNames = SmartList() - for (each in idToSettings.values) { - order.add(Pair.create(each.uniqueID, each)) - val folderName = each.folderName - if (folderName != null && !folderNames.contains(folderName)) { - folderNames.add(folderName) + @Volatile + private var immutableSortedSettingsList: List? = null + + override val allSettings: List + get() { + immutableSortedSettingsList?.let { + return it + } + + lock.write { + immutableSortedSettingsList?.let { + return it + } + + if (idToSettings.isEmpty()) { + immutableSortedSettingsList = emptyList() + return immutableSortedSettingsList!! + } + + val order = ArrayList(idToSettings.size) + val folderNames = SmartList() + for (each in idToSettings.values) { + order.add(OrderItem(each.uniqueID, each)) + val folderName = each.folderName + if (folderName != null && !folderNames.contains(folderName)) { + folderNames.add(folderName) + } + } + folderNames.add(null) + idToSettings.clear() + + if (customOrder.isEmpty()) { + // IDEA-63663 Sort run configurations alphabetically if clean checkout + order.sortWith(Comparator { o1, o2 -> + val temporary1 = o1.settings.isTemporary + val temporary2 = o2.settings.isTemporary + when { + temporary1 == temporary2 -> o1.id.compareTo(o2.id) + temporary1 -> 1 + else -> -1 + } + }) + } + else { + order.sortWith(Comparator { o1, o2 -> + val i1 = folderNames.indexOf(o1.settings.folderName) + val i2 = folderNames.indexOf(o2.settings.folderName) + if (i1 != i2) { + return@Comparator i1 - i2 + } + + val temporary1 = o1.settings.isTemporary + val temporary2 = o2.settings.isTemporary + when { + temporary1 == temporary2 -> { + val index1 = customOrder.indexOf(o1.id) + val index2 = customOrder.indexOf(o2.id) + if (index1 == -1 && index2 == -1) { + o1.settings.name.compareTo(o2.settings.name) + } + else { + index1 - index2 + } + } + temporary1 -> 1 + else -> -1 + } + }) + } + + for (each in order) { + val setting = each.settings + idToSettings.put(setting.uniqueID, setting) + } + + val result = Collections.unmodifiableList(idToSettings.values.toList()) + immutableSortedSettingsList = result + return result } } - folderNames.add(null) - idToSettings.clear() - if (myOrder.isEmpty()) { - // IDEA-63663 Sort run configurations alphabetically if clean checkout - order.sortWith(Comparator { o1, o2 -> - val temporary1 = o1.getSecond().isTemporary - val temporary2 = o2.getSecond().isTemporary - when { - temporary1 == temporary2 -> o1.first.compareTo(o2.first) - temporary1 -> 1 - else -> -1 - } - }) - } - else { - order.sortWith(Comparator { o1, o2 -> - val i1 = folderNames.indexOf(o1.getSecond().folderName) - val i2 = folderNames.indexOf(o2.getSecond().folderName) - if (i1 != i2) { - return@Comparator i1 - i2 - } - - val temporary1 = o1.getSecond().isTemporary - val temporary2 = o2.getSecond().isTemporary - when { - temporary1 == temporary2 -> { - val index1 = myOrder.indexOf(o1.first) - val index2 = myOrder.indexOf(o2.first) - if (index1 == -1 && index2 == -1) { - o1.second.name.compareTo(o2.second.name) - } - else { - index1 - index2 - } - } - temporary1 -> 1 - else -> -1 - } - }) - } - - for (each in order) { - val setting = each.second - idToSettings.put(setting.uniqueID, setting) - } - - myOrdered = true - return idToSettings.values - } - - @Suppress("DEPRECATION") override fun getState(): Element { val element = Element("state") @@ -469,23 +480,24 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } if (idToSettings.size > 1) { - var order: JDOMExternalizableStringList? = null + var order: MutableList? = null for (each in idToSettings.values) { if (each.type is UnknownConfigurationType) { continue } if (order == null) { - order = JDOMExternalizableStringList() + order = ArrayList() } order.add(each.uniqueID) } if (order != null) { - order.writeExternal(element) + @Suppress("DEPRECATION") + com.intellij.openapi.util.JDOMExternalizableStringList.writeList(order, element) } } - val recentList = JDOMExternalizableStringList() + val recentList = SmartList() for (each in recentlyUsedTemporaries) { if (each.type is UnknownConfigurationType) { continue @@ -496,13 +508,18 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent if (!recentList.isEmpty()) { val recent = Element(RECENT) element.addContent(recent) - recentList.writeExternal(recent) + @Suppress("DEPRECATION") + com.intellij.openapi.util.JDOMExternalizableStringList.writeList(recentList, recent) } return element } fun writeContext(element: Element) { - writeConfigurations(element, lock.read { idToSettings.values.filterSmart { it.isTemporary } }) + for (setting in allSettings) { + if (setting.isTemporary) { + element.addContent((setting as RunnerAndConfigurationSettingsImpl).writeScheme()) + } + } selectedConfiguration?.let { element.setAttribute(SELECTED_ATTR, it.uniqueID) @@ -571,16 +588,17 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } schemeManager.reload() - myOrder.readExternal(parentNode) + @Suppress("DEPRECATION") + com.intellij.openapi.util.JDOMExternalizableStringList.readList(customOrder, parentNode) // migration (old ids to UUIDs) - readList(myOrder) + readList(customOrder) recentlyUsedTemporaries.clear() val recentNode = parentNode.getChild(RECENT) if (recentNode != null) { @Suppress("DEPRECATION") - val list = JDOMExternalizableStringList() + val list = com.intellij.openapi.util.JDOMExternalizableStringList() list.readExternal(recentNode) readList(list) for (name in list) { @@ -589,7 +607,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } } } - myOrdered = false + immutableSortedSettingsList = null loadedSelectedConfigurationUniqueName = parentNode.getAttributeValue(SELECTED_ATTR) setSelectedConfigurationId(loadedSelectedConfigurationUniqueName) @@ -598,7 +616,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent fireRunConfigurationSelected() } - private fun readList(@Suppress("DEPRECATION") list: JDOMExternalizableStringList) { + private fun readList(list: MutableList) { for (i in list.indices) { for (settings in idToSettings.values) { val configuration = settings.configuration @@ -614,12 +632,9 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent fun readContext(parentNode: Element) { loadedSelectedConfigurationUniqueName = parentNode.getAttributeValue(SELECTED_ATTR) - for (aChildren in parentNode.children) { - val element = aChildren + for (element in parentNode.children) { val config = loadConfiguration(element, false) - if (loadedSelectedConfigurationUniqueName == null - && config != null - && java.lang.Boolean.parseBoolean(element.getAttributeValue(SELECTED_ATTR))) { + if (loadedSelectedConfigurationUniqueName == null && element.getAttributeValue(SELECTED_ATTR).toBoolean()) { loadedSelectedConfigurationUniqueName = config.uniqueID } } @@ -648,39 +663,47 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } private fun clear(allConfigurations: Boolean) { - val configurations: MutableList - if (allConfigurations) { - this.idToSettings.clear() - selectedConfigurationId = null - configurations = ArrayList(this.idToSettings.values) - } - else { - configurations = SmartList() - val iterator = this.idToSettings.values.iterator() - while (iterator.hasNext()) { - val configuration = iterator.next() - if (configuration.isTemporary || !configuration.isShared) { - iterator.remove() + val configurations = lock.write { + immutableSortedSettingsList = null - configurations.add(configuration) - } - } + val configurations = if (allConfigurations) { + val configurations = idToSettings.values.toList() - if (selectedConfigurationId != null && this.idToSettings.containsKey(selectedConfigurationId!!)) { + idToSettings.clear() selectedConfigurationId = null + + configurations } + else { + val configurations = SmartList() + val iterator = idToSettings.values.iterator() + while (iterator.hasNext()) { + val configuration = iterator.next() + if (configuration.isTemporary || !configuration.isShared) { + iterator.remove() + + configurations.add(configuration) + } + } + + if (selectedConfigurationId != null && this.idToSettings.containsKey(selectedConfigurationId!!)) { + selectedConfigurationId = null + } + + configurations + } + + templateIdToConfiguration.clear() + configurations } - lock.write { - templateIdToConfiguration.clear() - } loadedSelectedConfigurationUniqueName = null iconCache.clear() recentlyUsedTemporaries.clear() fireRunConfigurationsRemoved(configurations) } - fun loadConfiguration(element: Element, isShared: Boolean): RunnerAndConfigurationSettings? { + fun loadConfiguration(element: Element, isShared: Boolean): RunnerAndConfigurationSettings { val settings = RunnerAndConfigurationSettingsImpl(this) LOG.catchAndLog { settings.readExternal(element, isShared) @@ -763,25 +786,20 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent } fun getSharedConfigurations(): List { - lock.read { - var result: MutableList? = null - for (configuration in idToSettings.values) { - if (configuration.isShared) { - if (result == null) { - result = ArrayList() - } - result.add(configuration) + var result: MutableList? = null + for (configuration in allSettings) { + if (configuration.isShared) { + if (result == null) { + result = ArrayList() } + result.add(configuration) } - return result ?: emptyList() } + return result ?: emptyList() } - internal val configurationSettings: Collection - get() = idToSettings.values - override val tempConfigurationsList: List - get() = idToSettings.values.filter { it.isTemporary } + get() = allSettings.filterSmart { it.isTemporary } override fun makeStable(settings: RunnerAndConfigurationSettings) { settings.isTemporary = false @@ -791,8 +809,8 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent private fun doMakeStable(settings: RunnerAndConfigurationSettings) { recentlyUsedTemporaries.remove(settings.configuration) - if (!myOrder.isEmpty()) { - setOrdered(false) + if (!customOrder.isEmpty()) { + immutableSortedSettingsList = null } } @@ -807,7 +825,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent val tasks = SmartList() val checkedTemplates = SmartList() lock.read { - for (settings in idToSettings.values.toTypedArray()) { + for (settings in allSettings) { val configuration = settings.configuration for (task in getBeforeRunTasks(configuration)) { if (task.isEnabled && task.providerId === taskProviderId) { @@ -852,21 +870,16 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent return icon } - fun getConfigurationById(id: String) = idToSettings.get(id) + fun getConfigurationById(id: String) = lock.read { idToSettings.get(id) } override fun findConfigurationByName(name: String?): RunnerAndConfigurationSettings? { if (name == null) { return null } - return idToSettings.values.firstOrNull { it.name == name } + return allSettings.firstOrNull { it.name == name } } - fun findConfigurationByTypeAndName(typeId: String, name: String): RunnerAndConfigurationSettings? { - return sortedConfigurations.firstOrNull { - val t = it.type - t != null && typeId == t.id && name == it.name - } - } + fun findConfigurationByTypeAndName(typeId: String, name: String) = allSettings.firstOrNull { typeId == it.type.id && name == it.name } override fun > getBeforeRunTasks(settings: RunConfiguration, taskProviderId: Key): List { if (settings is WrappingRunConfiguration<*>) { @@ -998,7 +1011,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent // we must update all existing configuration tasks to ensure that effective tasks (own + template) are the same as before template configuration change // see testTemplates test lock.read { - for (otherSettings in idToSettings.values) { + for (otherSettings in allSettings) { val otherConfiguration = otherSettings.configuration if (otherConfiguration !is WrappingRunConfiguration<*> && otherConfiguration.factory === templateConfiguration.factory) { otherConfiguration.beforeRunTasks = getEffectiveBeforeRunTasks(otherConfiguration, ownIsOnlyEnabled = false, isDisableTemplateTasks = true, newTemplateTasks = tasks) @@ -1028,6 +1041,7 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent val settings = entry.value if (!settings.isTemplate && settings.isShared && !existing.contains(settings.uniqueID)) { if (removed == null) { + immutableSortedSettingsList = null removed = SmartList() } removed!!.add(settings) @@ -1080,6 +1094,8 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent val changedSettings = SmartList() lock.write { + immutableSortedSettingsList = null + val iterator = idToSettings.values.iterator() for (otherSettings in iterator) { if (otherSettings === settings) { @@ -1111,14 +1127,4 @@ class RunManagerImpl(internal val project: Project) : RunManagerEx(), Persistent changedSettings.forEach { myDispatcher.multicaster.runConfigurationChanged(it, null) } } -} - -internal interface RunConfigurationScheme : Scheme - -//private class UnknownRunConfigurationScheme(private val name: String) : RunConfigurationScheme, SerializableScheme { -// override fun getSchemeState() = SchemeState.UNCHANGED -// -// override fun writeScheme() = throw AssertionError("Must be not called") -// -// override fun getName() = name -//} \ No newline at end of file +} \ 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 7bbecd80d1cc..26d8bf785632 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunnerAndConfigurationSettingsImpl.kt @@ -26,6 +26,7 @@ import com.intellij.openapi.components.PathMacroManager import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.diagnostic.logger import com.intellij.openapi.extensions.ExtensionException +import com.intellij.openapi.options.Scheme import com.intellij.openapi.options.SchemeState import com.intellij.openapi.util.* import com.intellij.openapi.util.text.StringUtil @@ -56,7 +57,7 @@ val SINGLETON = "singleton" 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, RunConfigurationScheme, SerializableScheme { + private var singleton: Boolean = false) : Cloneable, RunnerAndConfigurationSettings, Comparable, Scheme, SerializableScheme { enum class Level { WORKSPACE, PROJECT, TEMPORARY } @@ -293,7 +294,7 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m override fun getConfigurationSettings(runner: ProgramRunner<*>) = configurationPerRunnerSettings.getOrCreateSettings(runner) - override fun getType() = _configuration?.type + override fun getType(): ConfigurationType = _configuration?.type ?: UnknownConfigurationType.INSTANCE public override fun clone(): RunnerAndConfigurationSettings { val copy = RunnerAndConfigurationSettingsImpl(manager, _configuration!!.clone(), false) @@ -337,10 +338,7 @@ class RunnerAndConfigurationSettingsImpl @JvmOverloads constructor(private val m override fun compareTo(other: Any) = if (other is RunnerAndConfigurationSettings) name.compareTo(other.name) else 0 - override fun toString(): String { - val type = type - return "${if (type == null) "" else "${type.displayName}: "}${if (isTemplate) "