From 9142df3c73adc0187522cfdc28d700066a64ee07 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 6 Mar 2014 12:51:55 +0400 Subject: [PATCH 001/172] classes from old build system API marked as deprecated (to be removed in IDEA 14) --- .../intellij/openapi/compiler/generic/GenericCompiler.java | 4 ++++ .../openapi/compiler/ClassInstrumentingCompiler.java | 4 ++++ .../openapi/compiler/ClassPostProcessingCompiler.java | 4 ++++ .../src/com/intellij/openapi/compiler/CompilerManager.java | 4 ++++ .../src/com/intellij/openapi/compiler/CopyingCompiler.java | 4 ++++ .../com/intellij/openapi/compiler/GeneratingCompiler.java | 4 ++++ .../openapi/compiler/JavaSourceTransformingCompiler.java | 4 ++++ .../com/intellij/openapi/compiler/PackagingCompiler.java | 4 ++++ .../openapi/compiler/SourceGeneratingCompiler.java | 4 ++++ .../com/intellij/openapi/compiler/TranslatingCompiler.java | 4 ++++ .../intellij/openapi/compiler/make/BuildInstruction.java | 5 +++++ .../openapi/compiler/make/BuildInstructionVisitor.java | 6 +++++- .../intellij/openapi/compiler/make/BuildParticipant.java | 4 +++- .../openapi/compiler/make/BuildParticipantProvider.java | 4 +++- .../openapi/compiler/make/FileCopyInstruction.java | 7 +++++-- 15 files changed, 61 insertions(+), 5 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompiler.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompiler.java index b09c8e599626..87136283737b 100644 --- a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompiler.java +++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompiler.java @@ -25,6 +25,10 @@ import org.jetbrains.annotations.NotNull; /** * @author nik + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public abstract class GenericCompiler implements Compiler { protected static final KeyDescriptor STRING_KEY_DESCRIPTOR = new EnumeratorStringDescriptor(); diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java index cfcf3373fa3f..4e5143aee495 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java @@ -21,6 +21,10 @@ package com.intellij.openapi.compiler; * This affects the order of compiler calls: * The sequence in which compilers are called: * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public interface ClassInstrumentingCompiler extends FileProcessingCompiler { } diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java index 203facd2b02d..c4c3e8b40cf1 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java @@ -21,6 +21,10 @@ package com.intellij.openapi.compiler; * This affects the order of compiler calls: * The sequence in which compilers are called: * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public interface ClassPostProcessingCompiler extends FileProcessingCompiler { } diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java index 4456665ef4bd..03d9be241ffb 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java @@ -63,6 +63,10 @@ public abstract class CompilerManager { * @param compiler compiler implementation * @param inputTypes a set of filetypes that compiler accepts as input * @param outputTypes a set of filetypes that compiler can generate + * + * @deprecated this method is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public abstract void addTranslatingCompiler(@NotNull TranslatingCompiler compiler, Set inputTypes, Set outputTypes); diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java index 7d80c21daedf..758524e92426 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java @@ -32,6 +32,10 @@ import java.util.List; /** * Compiler which copies the compiled files to a different directory. + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public abstract class CopyingCompiler implements PackagingCompiler{ public abstract VirtualFile[] getFilesToCopy(CompileContext context); diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java index 962bcb218e5e..af1fb1eb8dd7 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java @@ -21,6 +21,10 @@ import com.intellij.openapi.vfs.VirtualFile; /** * A base interface for all compilers that generate new files. The generated files may be processed by other compilers. * Actual implementation should implement one of its subinterfaces. Currently only {@link SourceGeneratingCompiler} is available. + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public interface GeneratingCompiler extends Compiler, ValidityStateFactory, IntermediateOutputCompiler { /** diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java index 27a397569aad..1194efcccba3 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java @@ -19,6 +19,10 @@ import com.intellij.openapi.vfs.VirtualFile; /** * This compiler is called right before the java sources compiler. + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public interface JavaSourceTransformingCompiler extends Compiler { diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java index e7e1350b41b9..3055e0ff654f 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java @@ -23,6 +23,10 @@ import org.jetbrains.annotations.Nullable; * This affects the order of compiler calls. * The sequence in which compilers are called: * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public interface PackagingCompiler extends FileProcessingCompiler{ /** diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java index 4c0b646658f6..2fe36ba202ba 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java @@ -23,6 +23,10 @@ import com.intellij.openapi.vfs.VirtualFile; * This affects the order of compiler calls. * The sequence in which compilers are called: * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public interface SourceGeneratingCompiler extends GeneratingCompiler { diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java index 3c56f8d9f67d..c5ce012c9ce6 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java @@ -26,6 +26,10 @@ import java.util.Collection; * This affects the order of compiler calls. * The sequence in which compilers are called: * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler -> ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator + * + * @deprecated this interface is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public interface TranslatingCompiler extends Compiler { diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java index 148e1524e4a2..eed2e77c8030 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java @@ -15,6 +15,11 @@ */ package com.intellij.openapi.compiler.make; +/** + * @deprecated this class is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. + */ public interface BuildInstruction { String getOutputRelativePath(); diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java index 6ae9b33e062b..0bd62be958f7 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java @@ -15,7 +15,11 @@ */ package com.intellij.openapi.compiler.make; - +/** + * @deprecated this class is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. + */ public abstract class BuildInstructionVisitor { public boolean visitInstruction(BuildInstruction instruction) throws Exception { return true; diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java index 48022b6bf272..977772418589 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java @@ -20,7 +20,9 @@ import com.intellij.packaging.artifacts.Artifact; import org.jetbrains.annotations.Nullable; /** - * @deprecated use interfaces from {@link com.intellij.openapi.compiler.Compiler}'s hierarchy instead + * @deprecated this class is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public abstract class BuildParticipant { public static final BuildParticipant[] EMPTY_ARRAY = new BuildParticipant[0]; diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java index a0f46da79290..374e161549ad 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java @@ -24,7 +24,9 @@ import java.util.Collection; /** * @author nik * - * @deprecated use interfaces from {@link com.intellij.openapi.compiler.Compiler}'s hierarchy instead + * @deprecated this class is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. */ public abstract class BuildParticipantProvider { public static final ExtensionPointName EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.buildParticipantProvider"); diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java index 4109410aec00..c5636394cfe0 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java @@ -15,10 +15,13 @@ */ package com.intellij.openapi.compiler.make; -import org.jetbrains.annotations.Nullable; - import java.io.File; +/** + * @deprecated this class is part of the obsolete build system which runs as part of the IDE process. Since IDEA 12 plugins need to + * integrate into 'external build system' instead (http://confluence.jetbrains.com/display/IDEADEV/External+Builder+API+and+Plugins). + * Since IDEA 13 users cannot switch to the old build system via UI and it will be completely removed in IDEA 14. + */ public interface FileCopyInstruction extends BuildInstruction { File getFile(); From 2149ea34f33bc10ff0bd8014fe47832553eeaf20 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Thu, 6 Mar 2014 13:04:22 +0400 Subject: [PATCH 002/172] Fixed project leak --- .../file/exclude/EnforcedPlainTextFileTypeManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java index e8a18e423423..f40d069c83c1 100644 --- a/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java +++ b/platform/lang-impl/src/com/intellij/openapi/file/exclude/EnforcedPlainTextFileTypeManager.java @@ -28,7 +28,7 @@ import com.intellij.openapi.roots.ex.ProjectRootManagerEx; import com.intellij.openapi.util.EmptyRunnable; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileWithId; -import com.intellij.util.containers.ConcurrentHashMap; +import com.intellij.util.containers.ConcurrentWeakHashMap; import com.intellij.util.indexing.FileBasedIndex; import org.jetbrains.annotations.NotNull; @@ -43,7 +43,7 @@ import java.util.Map; * @author Rustam Vishnyakov */ public class EnforcedPlainTextFileTypeManager implements ProjectManagerListener { - private final Map> myPlainTextFileSets = new ConcurrentHashMap>(); + private final Map> myPlainTextFileSets = new ConcurrentWeakHashMap>(); private volatile boolean mySetsInitialized = false; private static final Object LOCK = new Object(); From a70f8239c8de35f69fb0004373990fa128cc77e9 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 5 Mar 2014 19:43:13 +0100 Subject: [PATCH 003/172] new inference: postpone argument types calculation --- .../psi/infos/MethodCandidateInfo.java | 51 ++++++++++--------- .../JavaMethodsConflictResolver.java | 41 ++++++++++----- .../processor/MethodCandidatesProcessor.java | 7 ++- 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java index 2afc76a5d060..2831025839e3 100644 --- a/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java +++ b/java/java-psi-api/src/com/intellij/psi/infos/MethodCandidateInfo.java @@ -82,9 +82,11 @@ public class MethodCandidateInfo extends CandidateInfo{ @ApplicabilityLevelConstant private int getApplicabilityLevelInner() { - if (myArgumentTypes == null) return ApplicabilityLevel.NOT_APPLICABLE; + final PsiType[] argumentTypes = getArgumentTypes(); - int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(), myArgumentTypes, myLanguageLevel); + if (argumentTypes == null) return ApplicabilityLevel.NOT_APPLICABLE; + + int level = PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(), argumentTypes, myLanguageLevel); if (level > ApplicabilityLevel.NOT_APPLICABLE && !isTypeArgumentsApplicable()) level = ApplicabilityLevel.NOT_APPLICABLE; return level; } @@ -104,18 +106,17 @@ public class MethodCandidateInfo extends CandidateInfo{ return getApplicabilityLevel(); } - if (myArgumentTypes == null) { - return ApplicabilityLevel.NOT_APPLICABLE; - } - @ApplicabilityLevelConstant int level; Integer boxedLevel = ourOverloadGuard.doPreventingRecursion(myArgumentList, false, new Computable() { @Override public Integer compute() { - - final PsiMethod method = getElement(); - if (method != null && method.hasTypeParameters() || myArgumentList == null || !PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) { - return PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(false), myArgumentTypes, myLanguageLevel); + if (PsiUtil.isLanguageLevel8OrHigher(myArgumentList)) { + final PsiType[] argumentTypes = getArgumentTypes(); + if (argumentTypes == null) { + return ApplicabilityLevel.NOT_APPLICABLE; + } + + return PsiUtil.getApplicabilityLevel(getElement(), getSubstitutor(false), argumentTypes, myLanguageLevel); } return getApplicabilityLevelInner(); } @@ -127,7 +128,17 @@ public class MethodCandidateInfo extends CandidateInfo{ } public PsiSubstitutor getSiteSubstitutor() { - return super.getSubstitutor(); + PsiSubstitutor incompleteSubstitutor = super.getSubstitutor(); + if (myTypeArguments != null) { + PsiMethod method = getElement(); + if (method != null) { + PsiTypeParameter[] typeParams = method.getTypeParameters(); + for (int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) { + incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]); + } + } + } + return incompleteSubstitutor; } @NotNull @@ -206,22 +217,10 @@ public class MethodCandidateInfo extends CandidateInfo{ return inferTypeArguments(policy, arguments, true); } else { - return typeArgumentsSubstitutor(); + return getSiteSubstitutor(); } } - public PsiSubstitutor typeArgumentsSubstitutor() { - PsiSubstitutor incompleteSubstitutor = super.getSubstitutor(); - PsiMethod method = getElement(); - if (method != null) { - PsiTypeParameter[] typeParams = method.getTypeParameters(); - for (int i = 0; i < myTypeArguments.length && i < typeParams.length; i++) { - incompleteSubstitutor = incompleteSubstitutor.put(typeParams[i], myTypeArguments[i]); - } - } - return incompleteSubstitutor; - } - @NotNull public PsiSubstitutor inferTypeArguments(@NotNull ParameterTypeInferencePolicy policy, @NotNull PsiExpression[] arguments, @@ -283,6 +282,10 @@ public class MethodCandidateInfo extends CandidateInfo{ } } + public PsiType[] getArgumentTypes() { + return myArgumentTypes; + } + public static class ApplicabilityLevel { public static final int NOT_APPLICABLE = 1; public static final int VARARGS = 2; diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java index 406abbf9ee7a..81cfc0ab4799 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java @@ -72,7 +72,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ if (conflicts.isEmpty()) return null; if (conflicts.size() == 1) return conflicts.get(0); - boolean atLeastOneMatch = checkParametersNumber(conflicts, getActualParameterTypes().length, true); + boolean atLeastOneMatch = checkParametersNumber(conflicts, getActualParametersLength(), true); if (conflicts.size() == 1) return conflicts.get(0); checkSameSignatures(conflicts); @@ -81,7 +81,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ checkAccessStaticLevels(conflicts, true); if (conflicts.size() == 1) return conflicts.get(0); - checkParametersNumber(conflicts, getActualParameterTypes().length, false); + checkParametersNumber(conflicts, getActualParametersLength(), false); if (conflicts.size() == 1) return conflicts.get(0); final int applicabilityLevel = checkApplicability(conflicts); @@ -97,7 +97,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ checkSpecifics(conflicts, applicabilityLevel, myLanguageLevel); if (conflicts.size() == 1) return conflicts.get(0); - checkPrimitiveVarargs(conflicts, getActualParameterTypes().length); + checkPrimitiveVarargs(conflicts, getActualParametersLength()); if (conflicts.size() == 1) return conflicts.get(0); checkAccessStaticLevels(conflicts, false); @@ -110,10 +110,19 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ private void checkLambdaApplicable(@NotNull List conflicts, @NotNull LanguageLevel languageLevel) { if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) return; - for (int i = 0; i < getActualParameterTypes().length; i++) { - PsiType parameterType = getActualParameterTypes()[i]; - if (parameterType instanceof PsiLambdaExpressionType) { - final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)parameterType).getExpression(); + for (int i = 0; i < getActualParametersLength(); i++) { + + PsiExpression expression; + if (myArgumentsList instanceof PsiExpressionList) { + expression = ((PsiExpressionList)myArgumentsList).getExpressions()[i]; + } + else { + final PsiType argType = getActualParameterTypes()[i]; + expression = argType instanceof PsiLambdaExpressionType ? ((PsiLambdaExpressionType)argType).getExpression() : null; + } + + if (expression instanceof PsiLambdaExpression) { + final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)expression; for (Iterator iterator = conflicts.iterator(); iterator.hasNext(); ) { ProgressManager.checkCanceled(); final CandidateInfo conflict = iterator.next(); @@ -411,6 +420,14 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ return myActualParameterTypes; } + private int getActualParametersLength() { + if (myActualParameterTypes == null) { + LOG.assertTrue(myArgumentsList instanceof PsiExpressionList, myArgumentsList); + return ((PsiExpressionList)myArgumentsList).getExpressions().length; + } + return myActualParameterTypes.length; + } + protected PsiType[] getArgumentTypes() { return ((PsiExpressionList)myArgumentsList).getExpressionTypes(); } @@ -500,8 +517,8 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ final PsiSubstitutor siteSubstitutor1 = info1.getSiteSubstitutor(); final PsiSubstitutor siteSubstitutor2 = info2.getSiteSubstitutor(); - final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2, typeParameters2); - final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1, typeParameters1); + final PsiType[] types2AtSite = typesAtSite(types2, siteSubstitutor2); + final PsiType[] types1AtSite = typesAtSite(types1, siteSubstitutor1); final PsiSubstitutor methodSubstitutor1 = calculateMethodSubstitutor(typeParameters1, method1, siteSubstitutor1, types1, types2AtSite, languageLevel); @@ -538,7 +555,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8) && myArgumentsList instanceof PsiExpressionList && (typeParameters1.length == 0 || typeParameters2.length == 0)) { boolean toCompareFunctional = false; - for (int i = 0; i < myActualParameterTypes.length; i++) { + for (int i = 0; i < getActualParametersLength(); i++) { if (types1.length > 0 && LambdaUtil.isFunctionalType(types1[Math.min(i, types1.length - 1)]) && types2.length > 0 && LambdaUtil.isFunctionalType(types2[Math.min(i, types2.length - 1)])) { types1AtSite[Math.min(i, types1.length - 1)] = PsiType.NULL; @@ -555,7 +572,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ if (applicable12ignoreFunctionalType || applicable21ignoreFunctionalType) { Specifics specifics = null; - for (int i = 0; i < myActualParameterTypes.length; i++) { + for (int i = 0; i < getActualParametersLength(); i++) { if (types1.length > 0 && types1AtSite[Math.min(i, types1.length - 1)] == PsiType.NULL && types2.length > 0 && types2AtSite[Math.min(i, types2.length - 1)] == PsiType.NULL) { Specifics specific = isFunctionalTypeMoreSpecific(info1, info2, ((PsiExpressionList)myArgumentsList).getExpressions()[i], i); @@ -642,7 +659,7 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{ return applicabilityLevel > MethodCandidateInfo.ApplicabilityLevel.NOT_APPLICABLE; } - private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1, PsiTypeParameter[] typeParameters1) { + private static PsiType[] typesAtSite(PsiType[] types1, PsiSubstitutor siteSubstitutor1) { final PsiType[] types = PsiType.createArray(types1.length); for (int i = 0; i < types1.length; i++) { types[i] = siteSubstitutor1.substitute(types1[i]); diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java index ad0e7358842c..8607ff43c60e 100644 --- a/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java +++ b/java/java-psi-impl/src/com/intellij/psi/scope/processor/MethodCandidatesProcessor.java @@ -63,7 +63,12 @@ public class MethodCandidatesProcessor extends MethodsProcessor{ final boolean staticProblem, final boolean accessible) { final PsiExpressionList argumentList = getArgumentList(); return new MethodCandidateInfo(method, substitutor, !accessible, staticProblem, argumentList, myCurrentFileContext, - getExpressionTypes(argumentList), getTypeArguments(), getLanguageLevel()); + null, getTypeArguments(), getLanguageLevel()) { + @Override + public PsiType[] getArgumentTypes() { + return getExpressionTypes(argumentList); + } + }; } protected PsiType[] getExpressionTypes(PsiExpressionList argumentList) { From 5029b3fc552374f34e3568450aaca8a2d6e14204 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 5 Mar 2014 19:52:17 +0100 Subject: [PATCH 004/172] new inference: do not prefer specifics based on void return type for both void and value compatible lambdas --- .../resolve/graphInference/InferenceSession.java | 12 ++++++------ .../lambda/highlighting/AmbiguityRawGenerics.java | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index 53911011bc17..62a588d4b940 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -995,8 +995,9 @@ public class InferenceSession { return true; } - if (sReturnType == PsiType.VOID && session != null) { - return false; + final List returnExpressions = LambdaUtil.getReturnExpressions((PsiLambdaExpression)arg); + if (sReturnType == PsiType.VOID) { + return returnExpressions.isEmpty() && session == null; } if (LambdaUtil.isFunctionalType(sReturnType) && LambdaUtil.isFunctionalType(tReturnType) && @@ -1005,15 +1006,14 @@ public class InferenceSession { //Otherwise, if R1 and R2 are functional interface types, and neither interface is a subinterface of the other, //then these rules are applied recursively to R1 and R2, for each result expression in expi. - final List returnExpressions = LambdaUtil.getReturnExpressions((PsiLambdaExpression)arg); if (!isFunctionalTypeMoreSpecific(sReturnType, tReturnType, session, returnExpressions.toArray(new PsiExpression[returnExpressions.size()]))) { return false; } } else { - final boolean sPrimitive = sReturnType instanceof PsiPrimitiveType; - final boolean tPrimitive = tReturnType instanceof PsiPrimitiveType; + final boolean sPrimitive = sReturnType instanceof PsiPrimitiveType && sReturnType != PsiType.VOID; + final boolean tPrimitive = tReturnType instanceof PsiPrimitiveType && tReturnType != PsiType.VOID; if (sPrimitive ^ tPrimitive) { - for (PsiExpression returnExpression : LambdaUtil.getReturnExpressions((PsiLambdaExpression)arg)) { + for (PsiExpression returnExpression : returnExpressions) { if (!PsiPolyExpressionUtil.isPolyExpression(returnExpression)) { final PsiType returnExpressionType = returnExpression.getType(); if (sPrimitive) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityRawGenerics.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityRawGenerics.java index 6c664dd9e65a..595787704437 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityRawGenerics.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/highlighting/AmbiguityRawGenerics.java @@ -22,6 +22,6 @@ class AmbiguityRawGenerics { void foo(I3 s) { } void bar() { - foo(()-> { throw new RuntimeException(); }); + foo(()-> { throw new RuntimeException(); }); } } \ No newline at end of file From 46112ee3ec9ea901b9fdd18efd80985b4f0ab8cd Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 5 Mar 2014 20:00:05 +0100 Subject: [PATCH 005/172] new inference: cache lambda functional type during expression constraints reduction (IDEA-121315) --- .../src/com/intellij/psi/LambdaUtil.java | 8 +++++++ .../graphInference/InferenceSession.java | 18 +++++++++------ .../InputOutputConstraintFormula.java | 10 ++++++--- .../lambda/newLambda/IDEA121315.java | 22 +++++++++++++++++++ .../lambda/NewLambdaHighlightingTest.java | 4 ++++ 5 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA121315.java diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 54bd0241e64e..e1a9469765d3 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -33,6 +33,7 @@ import java.util.*; * Date: 7/17/12 */ public class LambdaUtil { + public static ThreadLocal> ourFunctionTypes = new ThreadLocal>(); private static final Logger LOG = Logger.getInstance("#" + LambdaUtil.class.getName()); @NonNls public static final String JAVA_LANG_FUNCTIONAL_INTERFACE = "java.lang.FunctionalInterface"; @@ -318,6 +319,13 @@ public class LambdaUtil { final int finalLambdaIdx = adjustLambdaIdx(lambdaIdx, (PsiMethod)resolve, parameters); if (finalLambdaIdx < parameters.length) { if (!tryToSubstitute) return getNormalizedType(parameters[finalLambdaIdx]); + final Map map = ourFunctionTypes.get(); + if (map != null) { + final PsiType type = map.get(expression); + if (type != null) { + return type; + } + } return PsiResolveHelper.ourGraphGuard.doPreventingRecursion(expression, true, new Computable() { @Override public PsiType compute() { diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index 62a588d4b940..c2fe04bad07d 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -823,15 +823,19 @@ public class InferenceSession { MethodCandidateInfo.updateSubstitutor(argumentList, substitutor); } - for (ConstraintFormula additionalConstraint : subset) { - additionalConstraint.apply(substitutor); - } + try { + for (ConstraintFormula additionalConstraint : subset) { + additionalConstraint.apply(substitutor); + } - myConstraints.addAll(subset); - if (!repeatInferencePhases(true)) { - return false; + myConstraints.addAll(subset); + if (!repeatInferencePhases(true)) { + return false; + } + } + finally { + LambdaUtil.ourFunctionTypes.set(null); } - } return true; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java index 0a49428722a1..fbd04e531e22 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/constraints/InputOutputConstraintFormula.java @@ -22,9 +22,7 @@ import com.intellij.psi.impl.source.resolve.graphInference.InferenceVariable; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import java.util.*; /** * User: anna @@ -110,5 +108,11 @@ public abstract class InputOutputConstraintFormula implements ConstraintFormula @Override public void apply(PsiSubstitutor substitutor) { setT(substitutor.substitute(getT())); + Map map = LambdaUtil.ourFunctionTypes.get(); + if (map == null) { + map = new HashMap(); + LambdaUtil.ourFunctionTypes.set(map); + } + map.put(getExpression(), getT()); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA121315.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA121315.java new file mode 100644 index 000000000000..1c22302f2523 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA121315.java @@ -0,0 +1,22 @@ +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class IDEA121315 { + class Issue { + Long getId() { + return 1l; + } + } + + T id(T i) { + return i; + } + + void foo(Stream map){ + Map id2Issue = map.collect(Collectors.toMap(null, p -> id(p))); + Map id2Issue1 = map.collect(Collectors.toMap(null, p -> p)); + Map id2Issue2 = map.collect(Collectors.toMap(null, this::id)); + + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index 826193c90f90..fb193320ad2d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -146,6 +146,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIDEA121315() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } From e07fdee02a3aab5813e0d6d963b283320fe9347f Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 5 Mar 2014 20:10:05 +0100 Subject: [PATCH 006/172] testdata for IDEA-118965 --- .../lambda/newLambda/IDEA118965comment.java | 13 +++++++++++++ .../daemon/lambda/NewLambdaHighlightingTest.java | 4 ++++ 2 files changed, 17 insertions(+) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965comment.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965comment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965comment.java new file mode 100644 index 000000000000..501e5f8d51cc --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newLambda/IDEA118965comment.java @@ -0,0 +1,13 @@ +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +class IDEA118965 { + { + Stream words = Arrays.asList("one", "one", "two").stream(); + List> res = words.collect(Collectors.toMap(w -> w, w -> 1, (a, b) -> a + b)) + .entrySet().stream().filter(e -> e.getValue() > 1).collect(Collectors.toList()); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java index fb193320ad2d..a3c2b12515eb 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewLambdaHighlightingTest.java @@ -150,6 +150,10 @@ public class NewLambdaHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testIDEA118965comment() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } From f86ac6f741888b91c3030f23d5d582d9fdabf687 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 5 Mar 2014 20:45:47 +0100 Subject: [PATCH 007/172] new inference: use equals bounds during incorporation --- .../InferenceIncorporationPhase.java | 17 +++++++++-------- ...corporationWithEqualsBoundsSubstitution.java | 14 ++++++++++++++ .../lambda/GraphInferenceHighlightingTest.java | 4 ++++ 3 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncorporationWithEqualsBoundsSubstitution.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java index f30c7ae6382c..9766122e31d0 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceIncorporationPhase.java @@ -74,7 +74,9 @@ public class InferenceIncorporationPhase { } public boolean incorporate() { - for (InferenceVariable inferenceVariable : mySession.getInferenceVariables()) { + final Collection inferenceVariables = mySession.getInferenceVariables(); + final PsiSubstitutor substitutor = mySession.retrieveNonPrimitiveEqualsBounds(inferenceVariables); + for (InferenceVariable inferenceVariable : inferenceVariables) { if (inferenceVariable.getInstantiation() != PsiType.NULL) continue; final List eqBounds = inferenceVariable.getBounds(InferenceBound.EQ); final List upperBounds = inferenceVariable.getBounds(InferenceBound.UPPER); @@ -82,15 +84,14 @@ public class InferenceIncorporationPhase { eqEq(eqBounds); - upDown(lowerBounds, upperBounds); - upDown(eqBounds, upperBounds); - upDown(lowerBounds, eqBounds); + upDown(lowerBounds, upperBounds, substitutor); + upDown(eqBounds, upperBounds, substitutor); + upDown(lowerBounds, eqBounds, substitutor); upUp(upperBounds); for (PsiType eqBound : eqBounds) { if (mySession.isProperType(eqBound)) { - final PsiSubstitutor substitutor = PsiSubstitutor.EMPTY.put(inferenceVariable.getParameter(), eqBound); for (PsiType upperBound : upperBounds) { if (!mySession.isProperType(upperBound)) { addConstraint(new StrictSubtypingConstraint(substitutor.substitute(upperBound), eqBound)); @@ -274,12 +275,12 @@ public class InferenceIncorporationPhase { * or * S <: a & a <: T imply S <: T */ - private void upDown(List eqBounds, List upperBounds) { + private void upDown(List eqBounds, List upperBounds, PsiSubstitutor substitutor) { for (PsiType upperBound : upperBounds) { if (upperBound == null) continue; for (PsiType eqBound : eqBounds) { if (eqBound == null) continue; - addConstraint(new StrictSubtypingConstraint(upperBound, eqBound)); + addConstraint(new StrictSubtypingConstraint(substitutor.substitute(upperBound), substitutor.substitute(eqBound))); } } } @@ -289,7 +290,7 @@ public class InferenceIncorporationPhase { */ private void eqEq(List eqBounds) { for (int i = 0; i < eqBounds.size(); i++) { - PsiType sBound= eqBounds.get(i); + PsiType sBound = eqBounds.get(i); for (int j = i + 1; j < eqBounds.size(); j++) { final PsiType tBound = eqBounds.get(j); addConstraint(new TypeEqualityConstraint(tBound, sBound)); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncorporationWithEqualsBoundsSubstitution.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncorporationWithEqualsBoundsSubstitution.java new file mode 100644 index 000000000000..5f85bc0d79eb --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/graphInference/IncorporationWithEqualsBoundsSubstitution.java @@ -0,0 +1,14 @@ +abstract class Test { + abstract Tf foo(Class c); + abstract Tf1 foo1(Class c); + + abstract Class bar(Class clazz); + abstract Class bar1(Class clazz); + + { + foo(bar(String.class)); + foo(bar1(String.class)); + foo1(bar(String.class)); + foo1(bar1(String.class)); + } +} 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 8af0821571d6..9c7ec52e1323 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 @@ -168,6 +168,10 @@ public class GraphInferenceHighlightingTest extends LightDaemonAnalyzerTestCase doTest(); } + public void testIncorporationWithEqualsBoundsSubstitution() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(false); } From da637a46fd4497d2c6f9b3b769dcad6f981518a2 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 6 Mar 2014 09:48:42 +0100 Subject: [PATCH 008/172] IDEA-84705 Live Template: should be possible to reset the changes made in default templates --- .../impl/LiveTemplateSettingsEditor.java | 27 ++-- .../template/impl/TemplateContext.java | 32 +++-- .../template/impl/TemplateEditorUtil.java | 12 +- .../template/impl/TemplateImpl.java | 54 ++++---- .../template/impl/TemplateListPanel.java | 129 ++++++++++-------- .../template/impl/TemplateSettings.java | 2 +- resources/src/liveTemplates/surround.xml | 6 - xml/impl/resources/liveTemplates/html_xml.xml | 4 - 8 files changed, 141 insertions(+), 125 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java index fe0506e9ff34..efc279c49c85 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/LiveTemplateSettingsEditor.java @@ -65,6 +65,7 @@ import java.util.List; public class LiveTemplateSettingsEditor extends JPanel { private final TemplateImpl myTemplate; + private final Runnable myNodeChanged; private final JTextField myKeyField; private final JTextField myDescription; @@ -80,19 +81,20 @@ public class LiveTemplateSettingsEditor extends JPanel { private static final String TAB = CodeInsightBundle.message("template.shortcut.tab"); private static final String ENTER = CodeInsightBundle.message("template.shortcut.enter"); private final Map myOptions; - private final Map myContext; + private final TemplateContext myContext; private JBPopup myContextPopup; private Dimension myLastSize; public LiveTemplateSettingsEditor(TemplateImpl template, final String defaultShortcut, Map options, - Map context, final Runnable nodeChanged, boolean allowNoContext) { + TemplateContext context, final Runnable nodeChanged, boolean allowNoContext) { super(new BorderLayout()); myOptions = options; myContext = context; myTemplate = template; + myNodeChanged = nodeChanged; myDefaultShortcutItem = CodeInsightBundle.message("dialog.edit.template.shortcut.default", defaultShortcut); myKeyField=new JTextField(); @@ -106,14 +108,14 @@ public class LiveTemplateSettingsEditor extends JPanel { @Override protected void textChanged(javax.swing.event.DocumentEvent e) { myTemplate.setKey(myKeyField.getText().trim()); - nodeChanged.run(); + myNodeChanged.run(); } }); myDescription.getDocument().addDocumentListener(new com.intellij.ui.DocumentAdapter() { @Override protected void textChanged(javax.swing.event.DocumentEvent e) { myTemplate.setDescription(myDescription.getText().trim()); - nodeChanged.run(); + myNodeChanged.run(); } }); @@ -172,6 +174,7 @@ public class LiveTemplateSettingsEditor extends JPanel { myTemplate.setString(myTemplateEditor.getDocument().getText()); applyVariables(updateVariablesByTemplateText()); + myNodeChanged.run(); } } ); @@ -290,8 +293,8 @@ public class LiveTemplateSettingsEditor extends JPanel { private List getApplicableContexts() { ArrayList result = new ArrayList(); - for (TemplateContextType type : myContext.keySet()) { - if (myContext.get(type).booleanValue()) { + for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) { + if (myContext.isExplicitlyEnabled(type)) { result.add(type); } } @@ -379,11 +382,11 @@ public class LiveTemplateSettingsEditor extends JPanel { return false; } - static JPanel createPopupContextPanel(final Runnable onChange, final Map context) { + static JPanel createPopupContextPanel(final Runnable onChange, final TemplateContext context) { JPanel panel = new JPanel(new BorderLayout()); MultiMap hierarchy = MultiMap.createLinked(); - for (TemplateContextType type : context.keySet()) { + for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) { hierarchy.putValue(type.getBaseContextType(), type); } @@ -401,7 +404,7 @@ public class LiveTemplateSettingsEditor extends JPanel { protected void onNodeStateChanged(CheckedTreeNode node) { final TemplateContextType type = (TemplateContextType)((Pair)node.getUserObject()).first; if (type != null) { - context.put(type, node.isChecked()); + context.putValue(type, node.isChecked()); } onChange.run(); @@ -434,21 +437,21 @@ public class LiveTemplateSettingsEditor extends JPanel { private static void addContextNode(MultiMap hierarchy, CheckedTreeNode parent, - TemplateContextType type, Map context) { + TemplateContextType type, TemplateContext context) { final Collection children = hierarchy.get(type); final String name = UIUtil.removeMnemonic(type.getPresentableName()); final CheckedTreeNode node = new CheckedTreeNode(Pair.create(children.isEmpty() ? type : null, name)); parent.add(node); if (children.isEmpty()) { - node.setChecked(context.get(type)); + node.setChecked(context.isExplicitlyEnabled(type)); } else { for (TemplateContextType child : children) { addContextNode(hierarchy, node, child, context); } final CheckedTreeNode other = new CheckedTreeNode(Pair.create(type, "Other")); - other.setChecked(context.get(type)); + other.setChecked(context.isExplicitlyEnabled(type)); node.add(other); } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java index 7a814d2e3717..e632a6848d03 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java @@ -45,10 +45,11 @@ public class TemplateContext { //noinspection NestedSynchronizedStatement synchronized (defaultContext == null ? myContextStates : defaultContext.myContextStates) { for (TemplateContextType contextType : TemplateManagerImpl.getAllContextTypes()) { - String context = contextType.getContextId(); - Boolean myStateInContext = myContextStates.get(context); - if (myStateInContext != null && differsFromDefault(defaultContext, context, myStateInContext)) { - result.put(contextType, myStateInContext); + Boolean ownValue = getOwnValue(contextType); + if (ownValue != null) { + if (defaultContext == null || isEnabled(contextType) != defaultContext.isEnabled(contextType)) { + result.put(contextType, ownValue); + } } } } @@ -56,16 +57,8 @@ public class TemplateContext { return result; } - private static boolean differsFromDefault(@Nullable TemplateContext defaultContext, String context, boolean myStateInContext) { - Boolean defaultStateInContext = defaultContext == null ? null : defaultContext.myContextStates.get(context); - if (defaultStateInContext == null) { - return true; - } - return myStateInContext != defaultStateInContext; - } - public boolean isEnabled(TemplateContextType contextType) { - Boolean storedValue = isEnabledBare(contextType); + Boolean storedValue = getOwnValue(contextType); if (storedValue == null) { TemplateContextType baseContextType = contextType.getBaseContextType(); if (baseContextType != null && !(baseContextType instanceof EverywhereContextType)) { @@ -76,7 +69,18 @@ public class TemplateContext { return storedValue.booleanValue(); } - private Boolean isEnabledBare(TemplateContextType contextType) { + public void putValue(TemplateContextType context, boolean enabled) { + synchronized (myContextStates) { + myContextStates.put(context.getContextId(), enabled); + } + } + + public boolean isExplicitlyEnabled(TemplateContextType contextType) { + return Boolean.TRUE.equals(getOwnValue(contextType)); + } + + @Nullable + public Boolean getOwnValue(TemplateContextType contextType) { synchronized (myContextStates) { return myContextStates.get(contextType.getContextId()); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java index 2d7c74056e79..1570bb18c040 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateEditorUtil.java @@ -45,8 +45,6 @@ import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Map; - public class TemplateEditorUtil { private TemplateEditorUtil() {} @@ -54,16 +52,16 @@ public class TemplateEditorUtil { return createEditor(isReadOnly, text, null); } - public static Editor createEditor(boolean isReadOnly, CharSequence text, @Nullable Map context) { + public static Editor createEditor(boolean isReadOnly, CharSequence text, @Nullable TemplateContext context) { final Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext()); return createEditor(isReadOnly, createDocument(text, context, project), project); } - private static Document createDocument(CharSequence text, @Nullable Map context, Project project) { + private static Document createDocument(CharSequence text, @Nullable TemplateContext context, Project project) { if (context != null) { - for (Map.Entry entry : context.entrySet()) { - if (entry.getValue()) { - return entry.getKey().createDocument(text, project); + for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) { + if (context.isExplicitlyEnabled(type)) { + return type.createDocument(text, project); } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java index ee18f37a7990..48c98cdc170d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateImpl.java @@ -18,7 +18,6 @@ package com.intellij.codeInsight.template.impl; import com.intellij.codeInsight.template.Expression; import com.intellij.codeInsight.template.Template; -import com.intellij.codeInsight.template.TemplateContextType; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.options.SchemeElement; import com.intellij.openapi.util.text.StringUtil; @@ -176,24 +175,35 @@ public class TemplateImpl extends Template implements SchemeElement { @Override public TemplateImpl copy() { TemplateImpl template = new TemplateImpl(myKey, myString, myGroupName); - template.myId = myId; - template.myDescription = myDescription; - template.myShortcutChar = myShortcutChar; - template.isToReformat = isToReformat; - template.isToShortenLongNames = isToShortenLongNames; - template.myIsInline = myIsInline; - template.myTemplateContext = myTemplateContext.createCopy(); - template.isDeactivated = isDeactivated; + template.resetFrom(this); + return template; + } + + public void resetFrom(TemplateImpl another) { + removeAllParsed(); + toParseSegments = another.toParseSegments; + + myKey = another.getKey(); + myString = another.myString; + myTemplateText = another.myTemplateText; + myGroupName = another.myGroupName; + myId = another.myId; + myDescription = another.myDescription; + myShortcutChar = another.myShortcutChar; + isToReformat = another.isToReformat; + isToShortenLongNames = another.isToShortenLongNames; + myIsInline = another.myIsInline; + myTemplateContext = another.myTemplateContext.createCopy(); + isDeactivated = another.isDeactivated; for (Property property : Property.values()) { - boolean value = getValue(property); + boolean value = another.getValue(property); if (value != Template.getDefaultValue(property)) { - template.setValue(property, value); + setValue(property, value); } } - for (Variable variable : myVariables) { - template.addVariable(variable.getName(), variable.getExpressionString(), variable.getDefaultValueString(), variable.isAlwaysStopAt()); + for (Variable variable : another.myVariables) { + addVariable(variable.getName(), variable.getExpressionString(), variable.getDefaultValueString(), variable.isAlwaysStopAt()); } - return template; } public boolean isToReformat() { @@ -436,14 +446,8 @@ public class TemplateImpl extends Template implements SchemeElement { return context; } - public Map createContext(){ - - Map context = new LinkedHashMap(); - for (TemplateContextType processor : TemplateManagerImpl.getAllContextTypes()) { - context.put(processor, getTemplateContext().isEnabled(processor)); - } - return context; - + public TemplateContext createContext() { + return getTemplateContext().createCopy(); } public boolean contextsEqual(TemplateImpl defaultTemplate) { @@ -456,10 +460,8 @@ public class TemplateImpl extends Template implements SchemeElement { } } - public void applyContext(final Map context) { - for (Map.Entry entry : context.entrySet()) { - getTemplateContext().setEnabled(entry.getKey(), entry.getValue().booleanValue()); - } + public void applyContext(final TemplateContext context) { + myTemplateContext = context.createCopy(); } public boolean skipOnStart(int i) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java index 60b6755f53b5..1aed0f448a6f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateListPanel.java @@ -19,7 +19,6 @@ package com.intellij.codeInsight.template.impl; import com.intellij.application.options.ExportSchemeAction; import com.intellij.application.options.SchemesToImportPopup; import com.intellij.codeInsight.CodeInsightBundle; -import com.intellij.codeInsight.template.TemplateContextType; import com.intellij.ide.DataManager; import com.intellij.ide.dnd.*; import com.intellij.ide.dnd.aware.DnDAwareTree; @@ -45,6 +44,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Convertor; import com.intellij.util.ui.tree.TreeUtil; import com.intellij.util.ui.update.UiNotifyConnector; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -94,7 +94,7 @@ public class TemplateListPanel extends JPanel implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.template.impl.TemplateListPanel"); private final Map> myTemplateOptions = new LinkedHashMap>(); - private final Map> myTemplateContext = new LinkedHashMap>(); + private final Map myTemplateContext = ContainerUtil.newLinkedHashMap(); private final JPanel myDetailsPanel = new JPanel(new CardLayout()); private LiveTemplateSettingsEditor myCurrentTemplateEditor; @@ -152,7 +152,7 @@ public class TemplateListPanel extends JPanel implements Disposable { UiNotifyConnector.doWhenFirstShown(this, new Runnable() { @Override public void run() { - updateTemplateDetails(false); + updateTemplateDetails(false, false); } }); @@ -208,17 +208,22 @@ public class TemplateListPanel extends JPanel implements Disposable { List originalGroups = templateSettings.getTemplateGroups(); List newGroups = getTemplateGroups(); - if (checkAreEqual(collectTemplates(originalGroups), collectTemplates(newGroups))) return false; + List originalGroup = collectTemplates(originalGroups); + List newGroup = collectTemplates(newGroups); + + if (checkAreEqual(originalGroup, newGroup)) return false; + if (isTest) { //noinspection UseOfSystemOutOrSystemErr - System.err.println("LiveTemplatesConfig: originalGroups="+originalGroups+"; collectTemplates(originalGroups)="+collectTemplates(originalGroups)+";\n newGroups="+newGroups+"; collectTemplates(newGroups)="+collectTemplates(newGroups)); + System.err.println("LiveTemplatesConfig: originalGroups="+originalGroups+"; collectTemplates(originalGroups)="+ + originalGroup +";\n newGroups="+newGroups+"; collectTemplates(newGroups)="+ newGroup); } return true; } public void editTemplate(TemplateImpl template) { selectTemplate(template.getGroupName(), template.getKey()); - updateTemplateDetails(true); + updateTemplateDetails(true, false); } @Nullable @@ -247,43 +252,13 @@ public class TemplateListPanel extends JPanel implements Disposable { return result; } - private boolean checkAreEqual(final List originalGroup, final List newGroup) { + private boolean checkAreEqual(List originalGroup, List newGroup) { if (originalGroup.size() != newGroup.size()) return false; for (int i = 0; i < newGroup.size(); i++) { - TemplateImpl newTemplate = newGroup.get(i); - newTemplate.parseSegments(); - TemplateImpl originalTemplate = originalGroup.get(i); - originalTemplate.parseSegments(); - if (!originalTemplate.equals(newTemplate)) { + if (templatesDiffer(newGroup.get(i), originalGroup.get(i))) { return false; } - - if (originalTemplate.isDeactivated() != newTemplate.isDeactivated()) { - return false; - } - - if (!newTemplate.getVariables().equals(originalTemplate.getVariables())) { - return false; - } - - if (!areOptionsEqual(newTemplate, originalTemplate)) { - return false; - } - - if (!areContextsEqual(newTemplate, originalTemplate)) { - return false; - } - } - - return true; - } - - private boolean areContextsEqual(final TemplateImpl newTemplate, final TemplateImpl originalTemplate) { - Map templateContext = getTemplateContext(newTemplate); - for (TemplateContextType processor : templateContext.keySet()) { - if (originalTemplate.getTemplateContext().isEnabled(processor) != templateContext.get(processor).booleanValue()) - return false; } return true; } @@ -296,7 +271,7 @@ public class TemplateListPanel extends JPanel implements Disposable { return true; } - private Map getTemplateContext(final TemplateImpl newTemplate) { + private TemplateContext getTemplateContext(final TemplateImpl newTemplate) { return myTemplateContext.get(getKey(newTemplate)); } @@ -324,7 +299,7 @@ public class TemplateListPanel extends JPanel implements Disposable { private void createTemplateEditor(final TemplateImpl template, String shortcut, Map options, - Map context) { + TemplateContext context) { myCurrentTemplateEditor = new LiveTemplateSettingsEditor(template, shortcut, options, context, new Runnable() { @Override public void run() { @@ -482,7 +457,7 @@ public class TemplateListPanel extends JPanel implements Disposable { myTemplateContext.put(getKey(template), template.createContext()); registerTemplate(template); - updateTemplateDetails(true); + updateTemplateDetails(true, false); } private static int getKey(final TemplateImpl template) { @@ -498,10 +473,10 @@ public class TemplateListPanel extends JPanel implements Disposable { TemplateImpl template = orTemplate.copy(); template.setKey(ABBREVIATION); myTemplateOptions.put(getKey(template), new HashMap(getTemplateOptions(orTemplate))); - myTemplateContext.put(getKey(template), new HashMap(getTemplateContext(orTemplate))); + myTemplateContext.put(getKey(template), getTemplateContext(orTemplate).createCopy()); registerTemplate(template); - updateTemplateDetails(true); + updateTemplateDetails(true, false); } private int getSingleSelectedIndex() { @@ -554,9 +529,12 @@ public class TemplateListPanel extends JPanel implements Disposable { value = ((DefaultMutableTreeNode)value).getUserObject(); if (value instanceof TemplateImpl) { - getTextRenderer().append (((TemplateImpl)value).getKey(), SimpleTextAttributes.REGULAR_ATTRIBUTES); - String description = ((TemplateImpl)value).getDescription(); - if (description != null && description.length() > 0) { + TemplateImpl template = (TemplateImpl)value; + TemplateImpl defaultTemplate = TemplateSettings.getInstance().getDefaultTemplate(template); + Color fgColor = defaultTemplate != null && templatesDiffer(template, defaultTemplate) ? JBColor.BLUE : null; + getTextRenderer().append(template.getKey(), new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, fgColor)); + String description = template.getDescription(); + if (StringUtil.isNotEmpty(description)) { getTextRenderer().append (" (" + description + ")", SimpleTextAttributes.GRAY_ATTRIBUTES); } } @@ -612,7 +590,7 @@ public class TemplateListPanel extends JPanel implements Disposable { myAlarm.addRequest(new Runnable() { @Override public void run() { - updateTemplateDetails(false); + updateTemplateDetails(false, false); } }, 100); } @@ -679,6 +657,15 @@ public class TemplateListPanel extends JPanel implements Disposable { } + private boolean templatesDiffer(@NotNull TemplateImpl template, @NotNull TemplateImpl defaultTemplate) { + template.parseSegments(); + defaultTemplate.parseSegments(); + return !template.equals(defaultTemplate) || + !template.getVariables().equals(defaultTemplate.getVariables()) || + !areOptionsEqual(template, defaultTemplate) || + !getTemplateContext(template).getDifference(defaultTemplate.getTemplateContext()).isEmpty(); + } + private ToolbarDecorator initToolbar() { ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTree) .setAddAction(new AnActionButtonRunnable() { @@ -855,10 +842,7 @@ public class TemplateListPanel extends JPanel implements Disposable { @Override public void actionPerformed(AnActionEvent e) { Map templates = getSelectedTemplates(); - Map context = ContainerUtil.newHashMap(); - for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) { - context.put(type, Boolean.FALSE); - } + TemplateContext context = new TemplateContext(); JPanel contextPanel = LiveTemplateSettingsEditor.createPopupContextPanel(EmptyRunnable.INSTANCE, context); DialogBuilder builder = new DialogBuilder(TemplateListPanel.this); builder.setCenterPanel(contextPanel); @@ -866,9 +850,43 @@ public class TemplateListPanel extends JPanel implements Disposable { int result = builder.show(); if (result == DialogWrapper.OK_EXIT_CODE) { for (TemplateImpl template : templates.keySet()) { - getTemplateContext(template).putAll(context); + myTemplateContext.put(getKey(template), context); } - } + } + updateTemplateDetails(false, true); + myTree.repaint(); + } + }; + final DumbAwareAction revert = new DumbAwareAction("Restore defaults", "Restore default setting for the selected templates", null) { + + @Override + public void update(AnActionEvent e) { + boolean enabled = false; + Map templates = getSelectedTemplates(); + for (TemplateImpl template : templates.keySet()) { + TemplateImpl defaultTemplate = TemplateSettings.getInstance().getDefaultTemplate(template); + if (defaultTemplate != null && templatesDiffer(template, defaultTemplate)) { + enabled = true; + } + } + e.getPresentation().setEnabled(enabled); + e.getPresentation().setVisible(enabled); + super.update(e); + } + + @Override + public void actionPerformed(AnActionEvent e) { + Map templates = getSelectedTemplates(); + for (TemplateImpl template : templates.keySet()) { + TemplateImpl defaultTemplate = TemplateSettings.getInstance().getDefaultTemplate(template); + if (defaultTemplate != null) { + myTemplateOptions.put(getKey(template), defaultTemplate.createOptions()); + myTemplateContext.put(getKey(template), defaultTemplate.createContext()); + template.resetFrom(defaultTemplate); + } + } + updateTemplateDetails(false, true); + myTree.repaint(); } }; @@ -880,6 +898,7 @@ public class TemplateListPanel extends JPanel implements Disposable { group.add(rename); group.add(move); group.add(changeContext); + group.add(revert); ActionManager.getInstance().createActionPopupMenu(ActionPlaces.UNKNOWN, group).getComponent().show(comp, x, y); } }); @@ -925,7 +944,7 @@ public class TemplateListPanel extends JPanel implements Disposable { } } - private void updateTemplateDetails(boolean focusKey) { + private void updateTemplateDetails(boolean focusKey, boolean forceReload) { int selected = getSingleSelectedIndex(); CardLayout layout = (CardLayout)myDetailsPanel.getLayout(); if (selected < 0 || getTemplate(selected) == null) { @@ -933,7 +952,7 @@ public class TemplateListPanel extends JPanel implements Disposable { } else { TemplateImpl newTemplate = getTemplate(selected); - if (myCurrentTemplateEditor == null || myCurrentTemplateEditor.getTemplate() != newTemplate) { + if (myCurrentTemplateEditor == null || forceReload || myCurrentTemplateEditor.getTemplate() != newTemplate) { if (myCurrentTemplateEditor != null) { myCurrentTemplateEditor.dispose(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java index 846320c4c084..e5f2fd4ae23d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateSettings.java @@ -234,7 +234,7 @@ public class TemplateSettings implements PersistentStateComponent, Expo } @Nullable - private TemplateImpl getDefaultTemplate(TemplateImpl t) { + public TemplateImpl getDefaultTemplate(TemplateImpl t) { return myDefaultTemplates.get(TemplateKey.keyOf(t)); } diff --git a/resources/src/liveTemplates/surround.xml b/resources/src/liveTemplates/surround.xml index b5ce9669ee5e..f36ed502c448 100644 --- a/resources/src/liveTemplates/surround.xml +++ b/resources/src/liveTemplates/surround.xml @@ -2,7 +2,6 @@