From b7c9b0e672ce30bf1b41b95635e43c80f4c3e764 Mon Sep 17 00:00:00 2001 From: Danila Ponomarenko Date: Mon, 2 Jul 2012 15:16:58 +0400 Subject: [PATCH 01/25] IDEA-86455 "quick fix" suggestions should account for coding convention when creating a variable implemented --- .../quickfix/DefaultQuickFixProvider.java | 64 ++++++++++++- .../impl/PriorityIntentionActionWrapper.java | 96 +++++++++++++++++++ .../impl/PriorityLocalQuickFixWrapper.java | 85 ++++++++++++++++ 3 files changed, 241 insertions(+), 4 deletions(-) create mode 100644 platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityIntentionActionWrapper.java create mode 100644 platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityLocalQuickFixWrapper.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java index f084d975b7a0..71b3176e7a29 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DefaultQuickFixProvider.java @@ -17,13 +17,20 @@ package com.intellij.codeInsight.daemon.impl.quickfix; import com.intellij.codeInsight.daemon.QuickFixActionRegistrar; import com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.impl.PriorityIntentionActionWrapper; import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; +import java.util.HashMap; +import java.util.Map; + public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider { @Override public void registerFixes(PsiJavaCodeReferenceElement ref, QuickFixActionRegistrar registrar) { @@ -37,15 +44,13 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider PsiReferenceExpression refExpr = (PsiReferenceExpression)ref; registrar.register(fixRange, new CreateEnumConstantFromUsageFix(refExpr), null); - registrar.register(fixRange, new CreateConstantFieldFromUsageFix(refExpr), null); - registrar.register(fixRange, new CreateFieldFromUsageFix(refExpr), null); registrar.register(new RenameWrongRefFix(refExpr)); if (!ref.isQualified()) { registrar.register(fixRange, new BringVariableIntoScopeFix(refExpr), null); - registrar.register(fixRange, new CreateLocalFromUsageFix(refExpr), null); - registrar.register(fixRange, new CreateParameterFromUsageFix(refExpr), null); } + + registerPriorityActions(registrar,fixRange,refExpr); } registrar.register(new CreateClassFromUsageFix(ref, CreateClassKind.INTERFACE)); @@ -65,6 +70,57 @@ public class DefaultQuickFixProvider extends UnresolvedReferenceQuickFixProvider } } + private static void registerPriorityActions(@NotNull final QuickFixActionRegistrar registrar, + @NotNull final TextRange fixRange, + @NotNull final PsiReferenceExpression refExpr) { + final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(refExpr.getProject()); + + final Map map = new HashMap() { + { + put(VariableKind.FIELD, new CreateFieldFromUsageFix(refExpr)); + put(VariableKind.STATIC_FINAL_FIELD, new CreateConstantFieldFromUsageFix(refExpr)); + if (!refExpr.isQualified()) { + put(VariableKind.LOCAL_VARIABLE, new CreateLocalFromUsageFix(refExpr)); + put(VariableKind.PARAMETER, new CreateParameterFromUsageFix(refExpr)); + } + } + }; + + final VariableKind kind = getKind(styleManager, refExpr); + if (map.containsKey(kind)){ + map.put(kind, PriorityIntentionActionWrapper.highPriority(map.get(kind))); + } + + for (IntentionAction action : map.values()){ + registrar.register(fixRange, action, null); + } + } + + @NotNull + private static VariableKind getKind(@NotNull JavaCodeStyleManager styleManager, + @NotNull PsiReferenceExpression refExpr) { + final String reference = refExpr.getText(); + + if (reference.toUpperCase().equals(reference)){ + return VariableKind.STATIC_FINAL_FIELD; + } + + for (VariableKind kind : VariableKind.values()) { + final String prefix = styleManager.getPrefixByVariableKind(kind); + final String suffix = styleManager.getSuffixByVariableKind(kind); + + if (prefix.isEmpty() && suffix.isEmpty()) { + continue; + } + + if (reference.startsWith(prefix) && reference.endsWith(suffix)) { + return kind; + } + } + + return VariableKind.LOCAL_VARIABLE; + } + @Override @NotNull public Class getReferenceClass() { diff --git a/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityIntentionActionWrapper.java b/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityIntentionActionWrapper.java new file mode 100644 index 000000000000..4c6aa7cbb62d --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityIntentionActionWrapper.java @@ -0,0 +1,96 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.intention.impl; + +import com.intellij.codeInsight.intention.HighPriorityAction; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.LowPriorityAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; + +/** + * @author Danila Ponomarenko + */ +public abstract class PriorityIntentionActionWrapper implements IntentionAction { + private IntentionAction action; + + private PriorityIntentionActionWrapper(@NotNull IntentionAction action) { + this.action = action; + } + + @NotNull + @Override + public String getText() { + return action.getText(); + } + + @NotNull + @Override + public String getFamilyName() { + return action.getFamilyName(); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return action.isAvailable(project, editor, file); + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + action.invoke(project, editor, file); + } + + @Override + public boolean startInWriteAction() { + return action.startInWriteAction(); + } + + private static class HighPriorityIntentionActionWrapper extends PriorityIntentionActionWrapper implements HighPriorityAction { + protected HighPriorityIntentionActionWrapper(@NotNull IntentionAction action) { + super(action); + } + } + + private static class NormalPriorityIntentionActionWrapper extends PriorityIntentionActionWrapper { + protected NormalPriorityIntentionActionWrapper(@NotNull IntentionAction action) { + super(action); + } + } + + private static class LowPriorityIntentionActionWrapper extends PriorityIntentionActionWrapper implements LowPriorityAction { + protected LowPriorityIntentionActionWrapper(@NotNull IntentionAction action) { + super(action); + } + } + + @NotNull + public static IntentionAction highPriority(@NotNull IntentionAction action) { + return new HighPriorityIntentionActionWrapper(action); + } + + @NotNull + public static IntentionAction normalPriority(@NotNull IntentionAction action) { + return new NormalPriorityIntentionActionWrapper(action); + } + + @NotNull + public static IntentionAction lowPriority(@NotNull IntentionAction action) { + return new LowPriorityIntentionActionWrapper(action); + } +} diff --git a/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityLocalQuickFixWrapper.java b/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityLocalQuickFixWrapper.java new file mode 100644 index 000000000000..ba83bc5b324c --- /dev/null +++ b/platform/lang-api/src/com/intellij/codeInsight/intention/impl/PriorityLocalQuickFixWrapper.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.intention.impl; + +import com.intellij.codeInsight.intention.HighPriorityAction; +import com.intellij.codeInsight.intention.LowPriorityAction; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; + +/** + * @author Danila Ponomarenko + */ +public abstract class PriorityLocalQuickFixWrapper implements LocalQuickFix { + private LocalQuickFix fix; + + private PriorityLocalQuickFixWrapper(@NotNull LocalQuickFix fix) { + this.fix = fix; + } + + @NotNull + @Override + public String getName() { + return fix.getName(); + } + + @NotNull + @Override + public String getFamilyName() { + return fix.getFamilyName(); + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + fix.applyFix(project, descriptor); + } + + private static class HighPriorityLocalQuickFixWrapper extends PriorityLocalQuickFixWrapper implements HighPriorityAction { + protected HighPriorityLocalQuickFixWrapper(@NotNull LocalQuickFix fix) { + super(fix); + } + } + + private static class NormalPriorityLocalQuickFixWrapper extends PriorityLocalQuickFixWrapper { + protected NormalPriorityLocalQuickFixWrapper(@NotNull LocalQuickFix fix) { + super(fix); + } + } + + + private static class LowPriorityLocalQuickFixWrapper extends PriorityLocalQuickFixWrapper implements LowPriorityAction { + protected LowPriorityLocalQuickFixWrapper(@NotNull LocalQuickFix fix) { + super(fix); + } + } + + @NotNull + public static LocalQuickFix highPriority(@NotNull LocalQuickFix fix) { + return new HighPriorityLocalQuickFixWrapper(fix); + } + + @NotNull + public static LocalQuickFix normalPriority(@NotNull LocalQuickFix fix) { + return new NormalPriorityLocalQuickFixWrapper(fix); + } + + @NotNull + public static LocalQuickFix lowPriority(@NotNull LocalQuickFix fix) { + return new LowPriorityLocalQuickFixWrapper(fix); + } +} From a0aeb09b81d898793c893a10158180cd087c21ba Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Mon, 2 Jul 2012 15:43:37 +0400 Subject: [PATCH 02/25] #WI-11044 Instant search Structure won't start with id or class characters - Allow speed search initiating with dot or hash characters --- platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java b/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java index 70d44c53888f..06c0d2d3ddb2 100644 --- a/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java +++ b/platform/platform-impl/src/com/intellij/ui/SpeedSearchBase.java @@ -300,7 +300,7 @@ public abstract class SpeedSearchBase extends SpeedSear if (!UIUtil.isReallyTypedEvent(e)) return; char c = e.getKeyChar(); - if (Character.isLetterOrDigit(c) || c == '_' || c == '*' || c == '/' || c == ':') { + if (Character.isLetterOrDigit(c) || c == '_' || c == '*' || c == '/' || c == ':' || c == '.' || c == '#') { manageSearchPopup(new SearchPopup(String.valueOf(c))); e.consume(); } From 73ad6b6d890d4e8cb3dc14597d7098080e5113e8 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Mon, 2 Jul 2012 15:44:44 +0400 Subject: [PATCH 03/25] Smart copy-paste fixed PY-6410 Adding/Pasting text at the end of a class method causes the next class method to be moved outside the class --- .../CopyPasteIndentProcessor.java | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyPasteIndentProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyPasteIndentProcessor.java index 9476402c0c0a..1382508ea8b5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyPasteIndentProcessor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/CopyPasteIndentProcessor.java @@ -12,6 +12,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.util.text.CharArrayUtil; @@ -20,6 +21,7 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.io.IOException; +import java.util.List; /** * @author yole @@ -40,9 +42,9 @@ public class CopyPasteIndentProcessor implements CopyPastePostProcessor= document.getLineStartOffset(selStartLine); offset--) { if (!Character.isWhitespace(document.getCharsSequence().charAt(offset))) { @@ -132,20 +134,29 @@ public class CopyPasteIndentProcessor implements CopyPastePostProcessor strings = StringUtil.split(pastedText, "\n"); + //if (strings.get(strings.size() - 1)) + + if (strings.get(0).trim().startsWith("def") || + strings.get(0).trim().startsWith("class")) endLine -=1; + for (int i = startLine+1; i <= endLine; i++) { - EditorActionUtil.indentLine(project, editor, i, caretColumn - value.getIndent()); + EditorActionUtil.indentLine(project, editor, i, value.getIndent()); } indented.set(Boolean.TRUE); } From 68c017caef18576d41ca661ede994fa54d187876 Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Mon, 2 Jul 2012 14:41:57 +0400 Subject: [PATCH 04/25] IDEA-87991 Static type checking false negative ignoring automatic type conversion --- .../internal/FileEqualsUsageInspection.java | 2 +- .../com/intellij/psi/CommonClassNames.java | 1 + plugins/groovy/src/META-INF/plugin.xml | 1 + .../groovy/lang/psi/GrTypeConverter.java | 18 +++++++ .../psi/impl/types/GrStringTypeConverter.java | 48 +++++++++++++++++++ .../ClosureParameterEnhancer.java | 17 +++---- .../lang/psi/util/GroovyCommonClassNames.java | 1 + .../groovy/lang/GppFunctionalTest.groovy | 4 +- 8 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrStringTypeConverter.java diff --git a/java/java-impl/src/com/intellij/codeInspection/internal/FileEqualsUsageInspection.java b/java/java-impl/src/com/intellij/codeInspection/internal/FileEqualsUsageInspection.java index f9f5756581ba..08325f5c32cc 100644 --- a/java/java-impl/src/com/intellij/codeInspection/internal/FileEqualsUsageInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/internal/FileEqualsUsageInspection.java @@ -55,7 +55,7 @@ public class FileEqualsUsageInspection extends InternalInspection { if (clazz == null) return; String methodName = method.getName(); - if ("java.io.File".equals(clazz.getQualifiedName()) + if (CommonClassNames.JAVA_IO_FILE.equals(clazz.getQualifiedName()) && ("equals".equals(methodName) || "compareTo".equals(methodName) || "hashCode".equals(methodName))) { holder.registerProblem(methodExpression, "Do not use File.equals/hashCode/compareTo as they don't honor case-sensitivity on MacOS. Use FileUtil.filesEquals/fileHashCode/compareFiles instead", diff --git a/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java b/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java index 95d78fafed51..9a7c93449210 100644 --- a/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java +++ b/java/java-psi-api/src/com/intellij/psi/CommonClassNames.java @@ -87,4 +87,5 @@ public interface CommonClassNames { @NonNls String JAVA_LANG_INVOKE_MH_POLYMORPHIC = "java.lang.invoke.MethodHandle.PolymorphicSignature"; String TARGET_ANNOTATION_FQ_NAME = "java.lang.annotation.Target"; @NonNls String JAVA_LANG_RUNNABLE = "java.lang.Runnable"; + @NonNls String JAVA_IO_FILE = "java.io.File"; } diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index e956617d9901..d76c850c98e0 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -126,6 +126,7 @@ + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrTypeConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrTypeConverter.java index aad90873f1a1..07961dd39581 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrTypeConverter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GrTypeConverter.java @@ -1,6 +1,8 @@ package org.jetbrains.plugins.groovy.lang.psi; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassType; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,4 +21,20 @@ public abstract class GrTypeConverter { @Nullable public abstract Boolean isConvertible(@NotNull PsiType lType, @NotNull PsiType rType, @NotNull GroovyPsiElement context); + protected static boolean resolvesTo(PsiType type, String fqn) { + if (type instanceof PsiClassType) { + final PsiClass resolved = ((PsiClassType)type).resolve(); + return resolved != null && fqn.equals(resolved.getQualifiedName()); + } + return false; + } + + protected static boolean isEnum(PsiType type) { + if (type instanceof PsiClassType) { + final PsiClass resolved = ((PsiClassType)type).resolve(); + return resolved != null && resolved.isEnum(); + } + + return false; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrStringTypeConverter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrStringTypeConverter.java new file mode 100644 index 000000000000..d5c9b30e8392 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrStringTypeConverter.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.lang.psi.impl.types; + +import com.intellij.psi.PsiType; +import com.intellij.psi.util.InheritanceUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.config.GroovyConfigUtils; +import org.jetbrains.plugins.groovy.lang.psi.GrTypeConverter; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; + +import static com.intellij.psi.CommonClassNames.JAVA_LANG_BOOLEAN; +import static com.intellij.psi.CommonClassNames.JAVA_LANG_CLASS; +import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_GSTRING; +import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.JAVA_LANG_CHAR_SEQUENCE; + +/** + * @author Max Medvedev + */ +public class GrStringTypeConverter extends GrTypeConverter { + @Override + public Boolean isConvertible(@NotNull PsiType lType, @NotNull PsiType rType, @NotNull GroovyPsiElement context) { + if (isMethodCallConversion(context)) return null; + if (!GroovyConfigUtils.getInstance().isVersionAtLeast(context, GroovyConfigUtils.GROOVY1_8)) return null; + if (!(InheritanceUtil.isInheritor(rType, JAVA_LANG_CHAR_SEQUENCE) || InheritanceUtil.isInheritor(rType, GROOVY_LANG_GSTRING))) { + return null; + } + + if (lType == PsiType.BOOLEAN || resolvesTo(lType, JAVA_LANG_BOOLEAN)) return true; + if (resolvesTo(lType, JAVA_LANG_CLASS)) return true; + if (isEnum(lType)) return true; + + return null; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java index 2e4e919fecb8..8749f37ee5d2 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/typeEnhancers/ClosureParameterEnhancer.java @@ -23,6 +23,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import java.util.Map; import java.util.Set; +import static com.intellij.psi.CommonClassNames.JAVA_IO_FILE; import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.skipParentheses; /** @@ -44,13 +45,13 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { simpleTypes.put("withDataOutputStream", "java.io.DataOutputStream"); simpleTypes.put("withDataInputStream", "java.io.DataInputStream"); simpleTypes.put("eachLine", "java.lang.String"); - simpleTypes.put("eachFile", "java.io.File"); - simpleTypes.put("eachDir", "java.io.File"); - simpleTypes.put("eachFileRecurse", "java.io.File"); - simpleTypes.put("traverse", "java.io.File"); - simpleTypes.put("eachDirRecurse", "java.io.File"); - simpleTypes.put("eachFileMatch", "java.io.File"); - simpleTypes.put("eachDirMatch", "java.io.File"); + simpleTypes.put("eachFile", JAVA_IO_FILE); + simpleTypes.put("eachDir", JAVA_IO_FILE); + simpleTypes.put("eachFileRecurse", JAVA_IO_FILE); + simpleTypes.put("traverse", JAVA_IO_FILE); + simpleTypes.put("eachDirRecurse", JAVA_IO_FILE); + simpleTypes.put("eachFileMatch", JAVA_IO_FILE); + simpleTypes.put("eachDirMatch", JAVA_IO_FILE); simpleTypes.put("withReader", "java.io.Reader"); simpleTypes.put("withWriter", "java.io.Writer"); simpleTypes.put("withWriterAppend", "java.io.Writer"); @@ -259,7 +260,7 @@ public class ClosureParameterEnhancer extends AbstractClosureParameterEnhancer { return res; } - if (TypesUtil.isClassType(iterType, CommonClassNames.JAVA_LANG_STRING) || TypesUtil.isClassType(iterType, "java.io.File")) { + if (TypesUtil.isClassType(iterType, CommonClassNames.JAVA_LANG_STRING) || TypesUtil.isClassType(iterType, JAVA_IO_FILE)) { return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_STRING, context); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java index d939e0f36379..3c481fe510da 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GroovyCommonClassNames.java @@ -54,6 +54,7 @@ public final class GroovyCommonClassNames { @NonNls public static final String GROOVY_TRANSFORM_COMPILE_STATIC = "groovy.transform.CompileStatic"; @NonNls public static final String GROOVY_TRANSFORM_TYPE_CHECKED = "groovy.transform.TypeChecked"; @NonNls public static final String GROOVY_TRANSFORM_TYPE_CHECKING_MODE = "groovy.transform.TypeCheckingMode"; + @NonNls public static final String JAVA_LANG_CHAR_SEQUENCE = "java.lang.CharSequence"; private GroovyCommonClassNames() { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy index dc92c267363d..5b9058c1e562 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GppFunctionalTest.groovy @@ -604,11 +604,11 @@ println new Bar().zzz } class GppProjectDescriptor extends DefaultLightProjectDescriptor { - static def instance = new GppProjectDescriptor() + public static final instance = new GppProjectDescriptor() @Override public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { - final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY++").getModifiableModel(); + final Library.ModifiableModel modifiableModel = model.moduleLibraryTable.createLibrary("GROOVY++").modifiableModel; modifiableModel.addRoot(JarFileSystem.instance.refreshAndFindFileByPath(TestUtils.absoluteTestDataPath + "mockGroovypp/groovypp-0.9.0_1.8.2.jar!/"), OrderRootType.CLASSES) modifiableModel.addRoot(JarFileSystem.instance.refreshAndFindFileByPath(TestUtils.mockGroovy1_7LibraryName + "!/"), OrderRootType.CLASSES); modifiableModel.commit(); From 5a720a50b6c4daf18d16264b1f2bbd27a691226c Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Mon, 2 Jul 2012 16:20:50 +0400 Subject: [PATCH 05/25] Refactoring --- plugins/android-designer/android-designer.iml | 2 -- plugins/android-designer/src/META-INF/plugin.xml | 2 -- plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml | 3 +-- plugins/ui-designer/ui-designer-new/ui-designer-new.iml | 1 - 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/plugins/android-designer/android-designer.iml b/plugins/android-designer/android-designer.iml index 79c2e83dd1e8..1689926a1b9c 100644 --- a/plugins/android-designer/android-designer.iml +++ b/plugins/android-designer/android-designer.iml @@ -7,8 +7,6 @@ - - diff --git a/plugins/android-designer/src/META-INF/plugin.xml b/plugins/android-designer/src/META-INF/plugin.xml index 17837831aa63..9c052d7b6a00 100644 --- a/plugins/android-designer/src/META-INF/plugin.xml +++ b/plugins/android-designer/src/META-INF/plugin.xml @@ -5,8 +5,6 @@ messages.AndroidDesignerBundle - com.intellij.java-i18n - com.intellij.properties org.jetbrains.android com.intellij.ui-designer-new diff --git a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml index 4c98e602a95f..91ba9adfd851 100644 --- a/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml +++ b/plugins/ui-designer/ui-designer-new/src/META-INF/plugin.xml @@ -5,8 +5,7 @@ messages.DesignerBundle - com.intellij.java-i18n - com.intellij.properties + com.intellij.modules.lang diff --git a/plugins/ui-designer/ui-designer-new/ui-designer-new.iml b/plugins/ui-designer/ui-designer-new/ui-designer-new.iml index 7bde231bdcf7..a4fc33f15fce 100644 --- a/plugins/ui-designer/ui-designer-new/ui-designer-new.iml +++ b/plugins/ui-designer/ui-designer-new/ui-designer-new.iml @@ -14,7 +14,6 @@ - From 667a0e06d14f4947a37425d280ac274548e1ef12 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 2 Jul 2012 14:25:28 +0200 Subject: [PATCH 06/25] groovy tests logging --- .../src/org/jetbrains/jps/cmdline/BuildSession.java | 6 ++++++ .../plugins/groovy/compiler/GroovyCompilerTestCase.java | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index c441d770a610..c33ae9938e73 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -329,6 +329,9 @@ final class BuildSession implements Runnable, CanceledStatus { final File file = new File(deleted); final RootDescriptor rd = pd.rootsIndex.getModuleAndRoot(file); if (rd != null) { + if (Utils.IS_TEST_MODE) { + LOG.info("Applying deleted path from fs event: " + file.getPath()); + } pd.fsState.registerDeleted(rd.module, file, rd.isTestRoot, timestamps); } else { @@ -341,6 +344,9 @@ final class BuildSession implements Runnable, CanceledStatus { final File file = new File(changed); final RootDescriptor rd = pd.rootsIndex.getModuleAndRoot(file); if (rd != null) { + if (Utils.IS_TEST_MODE) { + LOG.info("Applying dirty path from fs event: " + file.getPath()); + } pd.fsState.markDirty(file, rd, timestamps); } else { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java index e17b4fc68070..b2983364fcb1 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java @@ -231,7 +231,9 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC @Override public void run() { try { - VfsUtil.saveText(ObjectUtils.assertNotNull(file.getVirtualFile()), barText); + final VirtualFile virtualFile = file.getVirtualFile(); + System.out.println("Changing file text: psiFile= " + file + "; vFile= " + virtualFile); + VfsUtil.saveText(ObjectUtils.assertNotNull(virtualFile), barText); } catch (IOException e) { throw new RuntimeException(e); From fe2dbcc62b2a10090c32627ba160b2b3a870b3ae Mon Sep 17 00:00:00 2001 From: irengrig Date: Mon, 2 Jul 2012 16:52:35 +0400 Subject: [PATCH 07/25] SVN: also repeat svn listener actions if WC LOCKED is thrown (similar as BUSY), repeat more --- .../org/jetbrains/idea/svn/RepeatSvnActionThroughBusy.java | 2 +- plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/RepeatSvnActionThroughBusy.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/RepeatSvnActionThroughBusy.java index 2d2a1b8fd962..91c21d74f9a2 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/RepeatSvnActionThroughBusy.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/RepeatSvnActionThroughBusy.java @@ -24,7 +24,7 @@ import org.tmatesoft.svn.core.SVNException; * Time: 3:45 PM */ public abstract class RepeatSvnActionThroughBusy { - public static final int REPEAT = 3; + public static final int REPEAT = 10; protected int myCnt = REPEAT; protected long myTimeout = 50; protected abstract void executeImpl() throws SVNException; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java index 2634f757e5d6..b23732e8cb9d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java @@ -163,7 +163,10 @@ public class SvnVcs extends AbstractVcs { @Override public boolean process(Exception e) { if (e instanceof SVNException) { - if (SVNErrorCode.SQLITE_ERROR.equals(((SVNException)e).getErrorMessage().getErrorCode())) { + final SVNErrorCode errorCode = ((SVNException)e).getErrorMessage().getErrorCode(); + if (SVNErrorCode.WC_LOCKED.equals(errorCode)) { + return true; + } else if (SVNErrorCode.SQLITE_ERROR.equals(errorCode)) { Throwable cause = ((SVNException)e).getErrorMessage().getCause(); if (cause instanceof SqlJetException) { return SqlJetErrorCode.BUSY.equals(((SqlJetException)cause).getErrorCode()); From f23caa73db0be073b36940e5d8ff2113ef3de456 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Mon, 2 Jul 2012 15:28:02 +0200 Subject: [PATCH 08/25] Local History: do not offer to create a bug report --- .../history/core/ChangeListStorageImpl.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java b/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java index a939c88f6204..1dcca83c303e 100644 --- a/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java +++ b/platform/lvcs-impl/src/com/intellij/history/core/ChangeListStorageImpl.java @@ -119,30 +119,33 @@ public class ChangeListStorageImpl implements ChangeListStorage { isCompletelyBroken = true; } - notifyUser("Local History storage file has become corrupted and was rebuilt."); + notifyUser("Local History storage file has become corrupted and will be rebuilt."); } public static void notifyUser(String message) { final String logFile = PathManager.getLogPath(); + String createIssuePart = "
" + + "
" + + "Please attach log files from " + logFile + "
" + + "to the YouTrack issue"; Notifications.Bus.notify(new Notification(Notifications.SYSTEM_MESSAGES_GROUP_ID, "Local History is broken", - message + "
" + - "
" + - "Please attach log files from " + logFile + "
" + - "to the YouTrack issue", + message /*+ createIssuePart*/, NotificationType.ERROR, new NotificationListener() { @Override public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { - if ("url".equals(event.getDescription())) { - BrowserUtil.launchBrowser("http://youtrack.jetbrains.net/issue/IDEA-71270"); - } - else { - File file = new File(logFile); - ShowFilePathAction.openFile(file); + if (event.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { + if ("url".equals(event.getDescription())) { + BrowserUtil.launchBrowser("http://youtrack.jetbrains.net/issue/IDEA-71270"); + } + else { + File file = new File(logFile); + ShowFilePathAction.openFile(file); + } } } }), null); From 3e881fda9db3f3166582ab244442152613b1c9a6 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 2 Jul 2012 17:36:55 +0400 Subject: [PATCH 09/25] reverted previous change ( abd1fcf - drop in memory cache for key upon removeAllValues value, fileId request) as in memory representation reflects unsaved document data --- .../src/com/intellij/util/indexing/MemoryIndexStorage.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java index 5f00aa52c9d1..e52744970aa4 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java @@ -150,8 +150,10 @@ public class MemoryIndexStorage implements IndexStorage getMemValueContainer(key).removeAssociatedValue(inputId); return; } - - myMap.remove(key); // + final ChangeTrackingValueContainer valueContainer = myMap.get(key); + if (valueContainer != null) { + valueContainer.dropMergedData(); + } myBackendStorage.removeAllValues(key, inputId); } From 809878d30268617650c2791c3f3f00519fc93233 Mon Sep 17 00:00:00 2001 From: irengrig Date: Mon, 2 Jul 2012 17:51:41 +0400 Subject: [PATCH 10/25] SVN: additional for: "SVN: make annotate revision action work for before-renames" --- .../org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java index c5fdc50b315b..6e0cd264f475 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java @@ -144,7 +144,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn } } catch (VcsException e1) { - // + exception[0] = e1; } catch (SVNException e1) { exception[0] = new VcsException(e); From 5b8b1e4a9aa4d1cbdfcefe72aaa22fac1885a105 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 2 Jul 2012 17:52:39 +0400 Subject: [PATCH 11/25] fix test by ensuring no unsaved documents exist --- .../codeInsight/completion/ClassNameCompletionTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java index c9b621160790..86e736bdc587 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java @@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; @@ -198,6 +199,7 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase { private void cleanupVfs() { ApplicationManager.getApplication().runWriteAction(new Runnable() { public void run() { + FileDocumentManager.getInstance().saveAllDocuments(); for (VirtualFile file : myFixture.getTempDirFixture().getFile("").getChildren()) { try { file.delete(this); From d0e003113d1a1b6a5e908b6573ca17c947176e14 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 2 Jul 2012 13:38:05 +0200 Subject: [PATCH 12/25] IDEA-87135 Mutual hotkey to clear log in tool-window logs --- .../openapi/actionSystem/IdeActions.java | 2 + .../notification/EventLogConsole.java | 52 +++++++++++-------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java index b6fa20a49a20..6d29fa5b3f2b 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java @@ -255,4 +255,6 @@ public interface IdeActions { String ACTION_REDO = "$Redo"; String GROUP_REFACTOR = "RefactoringMenu"; String CHANGES_VIEW_ROLLBACK = "ChangesView.Rollback"; + + String CONSOLE_CLEAR_ALL = "ConsoleView.ClearAll"; } diff --git a/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java b/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java index 25dbb98ea411..d1902e784f05 100644 --- a/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java +++ b/platform/platform-impl/src/com/intellij/notification/EventLogConsole.java @@ -88,10 +88,13 @@ class EventLogConsole { ((EditorMarkupModel)editor.getMarkupModel()).setErrorStripeVisible(true); + final ClearLog clearLog = new ClearLog(); + clearLog.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.CONSOLE_CLEAR_ALL).getShortcutSet(), editor.getContentComponent()); + editor.addEditorMouseListener(new EditorPopupHandler() { public void invokePopup(final EditorMouseEvent event) { final ActionManager actionManager = ActionManager.getInstance(); - final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, createPopupActions(actionManager)); + final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, createPopupActions(actionManager, clearLog)); final MouseEvent mouseEvent = event.getMouseEvent(); menu.getComponent().show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); } @@ -99,31 +102,12 @@ class EventLogConsole { return editor; } - private DefaultActionGroup createPopupActions(ActionManager actionManager) { + private DefaultActionGroup createPopupActions(ActionManager actionManager, ClearLog action) { DefaultActionGroup group = new DefaultActionGroup(); group.add(new EditorCopyAction()); group.add(actionManager.getAction(IdeActions.ACTION_COMPARE_CLIPBOARD_WITH_SELECTION)); group.addSeparator(); - group.add(new DumbAwareAction("Clear All") { - @Override - public void update(AnActionEvent e) { - final boolean enabled = e.getData(PlatformDataKeys.EDITOR) != null; - e.getPresentation().setEnabled(enabled); - e.getPresentation().setVisible(enabled); - } - - public void actionPerformed(final AnActionEvent e) { - for (Notification notification : myProjectModel.getNotifications()) { - notification.expire(); - myProjectModel.removeNotification(notification); - } - myProjectModel.setStatusMessage(null, 0); - final Editor editor = e.getData(PlatformDataKeys.EDITOR); - if (editor != null) { - editor.getDocument().deleteString(0, editor.getDocument().getTextLength()); - } - } - }); + group.add(action); return group; } @@ -240,4 +224,28 @@ class EventLogConsole { document.insertString(document.getTextLength(), s); } + private class ClearLog extends DumbAwareAction { + public ClearLog() { + super("Clear All"); + } + + @Override + public void update(AnActionEvent e) { + final boolean enabled = e.getData(PlatformDataKeys.EDITOR) != null; + e.getPresentation().setEnabled(enabled); + e.getPresentation().setVisible(enabled); + } + + public void actionPerformed(final AnActionEvent e) { + for (Notification notification : myProjectModel.getNotifications()) { + notification.expire(); + myProjectModel.removeNotification(notification); + } + myProjectModel.setStatusMessage(null, 0); + final Editor editor = e.getData(PlatformDataKeys.EDITOR); + if (editor != null) { + editor.getDocument().deleteString(0, editor.getDocument().getTextLength()); + } + } + } } From f1a73a6760069f0a36a75d90449d3450bf5d5e74 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 2 Jul 2012 14:27:21 +0200 Subject: [PATCH 13/25] less CLASS_NAME mentions --- .../AbstractBasicToClassNameDelegator.java | 62 ------------------- .../JavaClassNameCompletionContributor.java | 4 +- .../XmlBasicToClassNameDelegator.java | 49 +++++++++++---- .../completion/CompletionType.java | 9 ++- .../completion/CodeCompletionHandlerBase.java | 1 + .../GroovyCompletionContributor.java | 14 ----- 6 files changed, 48 insertions(+), 91 deletions(-) delete mode 100644 java/java-impl/src/com/intellij/codeInsight/completion/AbstractBasicToClassNameDelegator.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/AbstractBasicToClassNameDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/AbstractBasicToClassNameDelegator.java deleted file mode 100644 index ca918ed8109f..000000000000 --- a/java/java-impl/src/com/intellij/codeInsight/completion/AbstractBasicToClassNameDelegator.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2000-2010 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.codeInsight.completion; - -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.util.Consumer; - -/** - * @author nik - */ -public abstract class AbstractBasicToClassNameDelegator extends CompletionContributor { - protected abstract boolean isClassNameCompletionSupported(CompletionResultSet result, PsiFile file, PsiElement position); - - protected void updateProperties(LookupElement lookupElement) { - } - - @Override - public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { - if (parameters.getCompletionType() != CompletionType.BASIC || parameters.getInvocationCount() == 0) return; - - final PsiFile file = parameters.getOriginalFile(); - final PsiElement position = parameters.getPosition(); - if (!isClassNameCompletionSupported(result, file, position)) return; - - final boolean empty = result.runRemainingContributors(parameters, true).isEmpty(); - - final CompletionParameters classParams; - - final int invocationCount = parameters.getInvocationCount(); - if (empty) { - classParams = parameters.withType(CompletionType.CLASS_NAME); - } - else if (invocationCount > 1) { - classParams = parameters.withType(CompletionType.CLASS_NAME).withInvocationCount(invocationCount - 1); - } else { - return; - } - - - CompletionService.getCompletionService().getVariantsFromContributors(classParams, null, new Consumer() { - public void consume(final CompletionResult lookupElement) { - updateProperties(lookupElement.getLookupElement()); - result.passResult(lookupElement); - } - }); - } -} diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java index 8585eabb9c91..bce477cb79ed 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java @@ -179,8 +179,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { } private static boolean shouldShowSecondSmartCompletionHint(final CompletionParameters parameters) { - return parameters.getCompletionType() == CompletionType.CLASS_NAME && - parameters.getInvocationCount() == 1 && + return parameters.getCompletionType() == CompletionType.BASIC && + parameters.getInvocationCount() == 2 && parameters.getOriginalFile().getLanguage().isKindOf(JavaLanguage.INSTANCE); } } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java index 96e174e1eb04..515a4e101b97 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java @@ -19,27 +19,52 @@ import com.intellij.codeInsight.lookup.AutoCompletionPolicy; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.lang.StdLanguages; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.util.Consumer; /** * @author peter */ -public class XmlBasicToClassNameDelegator extends AbstractBasicToClassNameDelegator { +public class XmlBasicToClassNameDelegator extends CompletionContributor { @Override - protected boolean isClassNameCompletionSupported(CompletionResultSet result, PsiFile file, PsiElement position) { - if (!JavaCompletionContributor.mayStartClassName(result)) return false; + public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) { + PsiElement position = parameters.getPosition(); + if (parameters.getCompletionType() != CompletionType.BASIC || + !JavaCompletionContributor.mayStartClassName(result) || + !position.getContainingFile().getLanguage().isKindOf(StdLanguages.XML)) { + return; + } - return file.getLanguage().isKindOf(StdLanguages.XML); - } + final boolean empty = result.runRemainingContributors(parameters, true).isEmpty(); - @Override - protected void updateProperties(LookupElement lookupElement) { - JavaPsiClassReferenceElement classElement = lookupElement.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); - if (classElement != null) { - classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); + if (!empty && parameters.getInvocationCount() == 0) { + result.restartCompletionWhenNothingMatches(); + } + + if (empty || parameters.isExtendedCompletion()) { + final int invocationCount = parameters.getInvocationCount(); + CompletionParameters classParams; + if (empty) { + classParams = parameters.withType(CompletionType.CLASS_NAME); + } + else if (invocationCount > 1) { + classParams = parameters.withType(CompletionType.CLASS_NAME).withInvocationCount(invocationCount - 1); + } else { + return; + } + + CompletionService.getCompletionService().getVariantsFromContributors(classParams, null, new Consumer() { + public void consume(final CompletionResult completionResult) { + LookupElement lookupElement = completionResult.getLookupElement(); + JavaPsiClassReferenceElement classElement = lookupElement.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); + if (classElement != null) { + classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); + } + lookupElement.putUserData(XmlCompletionContributor.WORD_COMPLETION_COMPATIBLE, Boolean.TRUE); //todo think of a less dirty interaction + result.passResult(completionResult); + } + }); } - lookupElement.putUserData(XmlCompletionContributor.WORD_COMPLETION_COMPATIBLE, Boolean.TRUE); //todo think of a less dirty interaction } } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionType.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionType.java index 7e71d7326c94..23818c37f580 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionType.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionType.java @@ -4,5 +4,12 @@ package com.intellij.codeInsight.completion; * @author peter */ public enum CompletionType { - BASIC, SMART, @Deprecated CLASS_NAME + BASIC, + SMART, + + /** + * Only to be passed to {@link CompletionService#getVariantsFromContributors(CompletionParameters, CompletionContributor, com.intellij.util.Consumer)} + * to invoke special class-name providers for various file types where those class names are applicable (e.g. xml, txt, properties, custom) + */ + CLASS_NAME } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 913a89aa2bd3..8271124deabe 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -86,6 +86,7 @@ public class CodeCompletionHandlerBase { public CodeCompletionHandlerBase(CompletionType completionType, boolean invokedExplicitly, boolean autopopup, boolean synchronous) { myCompletionType = completionType; + LOG.assertTrue(myCompletionType != CompletionType.CLASS_NAME, "Class name completion shouldn't be invoked directly"); this.invokedExplicitly = invokedExplicitly; this.autopopup = autopopup; this.synchronous = synchronous; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index cf15f678bd2f..4bfe01cfe0e8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -261,20 +261,6 @@ public class GroovyCompletionContributor extends CompletionContributor { MapKeysCompletionProvider.register(this); GroovyDocCompletionProvider.register(this); - // class name stuff - - extend(CompletionType.CLASS_NAME, psiElement().withParent(GrReferenceElement.class), new GlobalStaticMembersProvider()); - - extend(CompletionType.CLASS_NAME, psiElement(), new CompletionProvider() { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet result) { - result.stopHere(); - addAllClasses(parameters, result.withPrefixMatcher(CompletionUtil.findJavaIdentifierPrefix(parameters)), new InheritorsHolder(parameters.getPosition(), result)); - } - }); - extend(CompletionType.BASIC, STATEMENT_START, new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, From 89f6e3153bbd7c265567735deb11e379e84f0aad Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 2 Jul 2012 15:19:23 +0200 Subject: [PATCH 14/25] don't show java class names in js on second completion --- .../JavaClassNameCompletionContributor.java | 19 ++++++++++++++--- .../XmlBasicToClassNameDelegator.java | 16 ++------------ .../completion/ClassNameCompletionTest.java | 6 ++++++ .../completion/CompletionParameters.java | 6 +++++- .../completion/SkipAutopopupInStrings.java | 18 ++++++++++------ .../FilePathCompletionContributor.java | 1 - .../GroovyCompletionContributor.java | 21 ------------------- .../PropertiesCompletionContributor.java | 16 +++++++++++--- 8 files changed, 54 insertions(+), 49 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java index bce477cb79ed..62999d5f611d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java @@ -22,6 +22,7 @@ import com.intellij.lang.LangBundle; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.actionSystem.IdeActions; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileTypes.impl.CustomSyntaxTableFileType; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.patterns.PsiJavaElementPattern; @@ -52,10 +53,10 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { @Override public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet _result) { - if (parameters.isExtendedCompletion()) { + if (parameters.getCompletionType() == CompletionType.CLASS_NAME || + parameters.isExtendedCompletion() && mayContainClassName(parameters)) { CompletionResultSet result = _result.withPrefixMatcher(CompletionUtil.findReferenceOrAlphanumericPrefix(parameters)); - addAllClasses(parameters, parameters.getInvocationCount() <= 1, - JavaCompletionSorting.addJavaSorting(parameters, result).getPrefixMatcher(), new Consumer() { + addAllClasses(parameters, parameters.getInvocationCount() <= 1, result.getPrefixMatcher(), new Consumer() { @Override public void consume(LookupElement element) { _result.addElement(element); @@ -64,6 +65,18 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { } } + private static boolean mayContainClassName(CompletionParameters parameters) { + PsiElement position = parameters.getPosition(); + PsiFile file = position.getContainingFile(); + if (file instanceof PsiPlainTextFile || file.getFileType() instanceof CustomSyntaxTableFileType) { + return true; + } + if (SkipAutopopupInStrings.isInStringLiteral(position)) { + return true; + } + return false; + } + public static void addAllClasses(CompletionParameters parameters, final boolean filterByScope, @NotNull final PrefixMatcher matcher, diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java index 515a4e101b97..cd6882ea27fd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java @@ -29,8 +29,7 @@ public class XmlBasicToClassNameDelegator extends CompletionContributor { @Override public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) { PsiElement position = parameters.getPosition(); - if (parameters.getCompletionType() != CompletionType.BASIC || - !JavaCompletionContributor.mayStartClassName(result) || + if (!JavaCompletionContributor.mayStartClassName(result) || !position.getContainingFile().getLanguage().isKindOf(StdLanguages.XML)) { return; } @@ -42,18 +41,7 @@ public class XmlBasicToClassNameDelegator extends CompletionContributor { } if (empty || parameters.isExtendedCompletion()) { - final int invocationCount = parameters.getInvocationCount(); - CompletionParameters classParams; - if (empty) { - classParams = parameters.withType(CompletionType.CLASS_NAME); - } - else if (invocationCount > 1) { - classParams = parameters.withType(CompletionType.CLASS_NAME).withInvocationCount(invocationCount - 1); - } else { - return; - } - - CompletionService.getCompletionService().getVariantsFromContributors(classParams, null, new Consumer() { + CompletionService.getCompletionService().getVariantsFromContributors(parameters.delegateToClassName(), null, new Consumer() { public void consume(final CompletionResult completionResult) { LookupElement lookupElement = completionResult.getLookupElement(); JavaPsiClassReferenceElement classElement = lookupElement.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java index 86e736bdc587..6c5768c0e9f1 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java @@ -95,6 +95,12 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase { checkResultByFile(getTestName(false) + "_after.txt"); } + public void testInPropertiesFile() throws Exception { + myFixture.configureByText("a.properties", "abc = StrinBui"); + complete(); + myFixture.checkResult("abc = java.lang.StringBuilder"); + } + public void testDoubleStringBuffer() throws Exception { createClass("package java.lang; public class StringBuffer {}"); doTest(); diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java index 971c86136a47..1058bdb15efe 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionParameters.java @@ -44,6 +44,10 @@ public final class CompletionParameters { myLookup = lookup; } + public CompletionParameters delegateToClassName() { + return withType(CompletionType.CLASS_NAME).withInvocationCount(myInvocationCount - 1); + } + public CompletionParameters withType(CompletionType type) { return new CompletionParameters(myPosition, myOriginalFile, type, myOffset, myInvocationCount, myLookup); } @@ -100,6 +104,6 @@ public final class CompletionParameters { } public boolean isExtendedCompletion() { - return myCompletionType == CompletionType.CLASS_NAME || myCompletionType == CompletionType.BASIC && myInvocationCount >= 2; + return myCompletionType == CompletionType.BASIC && myInvocationCount >= 2; } } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java b/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java index 7b50882ea357..8f3714dbda93 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java @@ -39,17 +39,23 @@ public class SkipAutopopupInStrings extends CompletionConfidence { @NotNull @Override public ThreeState shouldSkipAutopopup(@NotNull PsiElement contextElement, @NotNull PsiFile psiFile, int offset) { - ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(PsiUtilBase.getLanguageAtOffset(psiFile, offset)); - if (definition != null) { - if (isStringLiteral(contextElement, definition) || isStringLiteral(contextElement.getParent(), definition) || - isStringLiteralWithError(contextElement, definition) || isStringLiteralWithError(contextElement.getParent(), definition)) { - return ThreeState.YES; - } + if (isInStringLiteral(contextElement)) { + return ThreeState.YES; } return ThreeState.UNSURE; } + public static boolean isInStringLiteral(PsiElement element) { + ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(PsiUtilBase.findLanguageFromElement(element)); + if (definition == null) { + return false; + } + + return isStringLiteral(element, definition) || isStringLiteral(element.getParent(), definition) || + isStringLiteralWithError(element, definition) || isStringLiteralWithError(element.getParent(), definition); + } + private static boolean isStringLiteral(PsiElement element, ParserDefinition definition) { return PlatformPatterns.psiElement().withElementType(definition.getStringLiteralElements()).accepts(element); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java index 4c53bbb1e7aa..5dbe6a9c223a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java @@ -176,7 +176,6 @@ public class FilePathCompletionContributor extends CompletionContributor { } } }; - extend(CompletionType.CLASS_NAME, psiElement(), provider); extend(CompletionType.BASIC, psiElement(), provider); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 4bfe01cfe0e8..6d0ad639e0fc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -815,25 +815,4 @@ public class GroovyCompletionContributor extends CompletionContributor { } } } - - private static class GlobalStaticMembersProvider extends CompletionProvider { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull final CompletionResultSet result) { - if (!parameters.isExtendedCompletion()) return; - - final PsiElement position = parameters.getPosition(); - if (((GrReferenceElement)position.getParent()).getQualifier() != null) return; - - if (StringUtil.isEmpty(result.getPrefixMatcher().getPrefix())) return; - - completeStaticMembers(parameters).processStaticMethodsGlobally(result.getPrefixMatcher(), new Consumer() { - @Override - public void consume(LookupElement element) { - result.addElement(element); - } - }); - } - } } diff --git a/plugins/properties/src/com/intellij/lang/properties/PropertiesCompletionContributor.java b/plugins/properties/src/com/intellij/lang/properties/PropertiesCompletionContributor.java index a66cd2fd3748..370b6b6856c0 100644 --- a/plugins/properties/src/com/intellij/lang/properties/PropertiesCompletionContributor.java +++ b/plugins/properties/src/com/intellij/lang/properties/PropertiesCompletionContributor.java @@ -15,16 +15,26 @@ */ package com.intellij.lang.properties; -import com.intellij.codeInsight.completion.CompletionContributor; -import com.intellij.codeInsight.completion.CompletionInitializationContext; -import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.completion.*; import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; /** * @author peter */ public class PropertiesCompletionContributor extends CompletionContributor { + @Override + public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) { + if (parameters.isExtendedCompletion()) { + CompletionService.getCompletionService().getVariantsFromContributors(parameters.delegateToClassName(), null, new Consumer() { + public void consume(final CompletionResult completionResult) { + result.passResult(completionResult); + } + }); + } + } + @Override public void beforeCompletion(@NotNull CompletionInitializationContext context) { if (context.getFile() instanceof PropertiesFile) { From 2895fabd969263b951685883579b8aefddf84863 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 2 Jul 2012 16:18:38 +0200 Subject: [PATCH 15/25] another tweak in matching degree --- .../testSrc/com/intellij/psi/util/NameUtilTest.java | 6 ++++++ .../src/com/intellij/psi/codeStyle/MinusculeMatcher.java | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java index 2f5f17c32b8c..74d23da62ebd 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilTest.java @@ -377,6 +377,7 @@ public class NameUtilTest extends UsefulTestCase { } public void testMatchingDegree() { + assertPreference("jscote", "JsfCompletionTest", "JSCompletionTest", NameUtil.MatchingCaseSensitivity.NONE); assertPreference("OCO", "OneCoolObject", "OCObject"); assertPreference("MUp", "MavenUmlProvider", "MarkUp"); assertPreference("MUP", "MarkUp", "MavenUmlProvider"); @@ -400,6 +401,11 @@ public class NameUtilTest extends UsefulTestCase { assertPreference(" Boo", "boolean", "Boolean", NameUtil.MatchingCaseSensitivity.NONE); } + public void testPreferWordBoundaryMatch() { + assertPreference("*les", "configureByFiles", "getLookupElementStrings", NameUtil.MatchingCaseSensitivity.FIRST_LETTER); + assertPreference("*les", "configureByFiles", "getLookupElementStrings", NameUtil.MatchingCaseSensitivity.NONE); + } + public void testPreferEarlyMatching() { assertPreference(" path", "getAbsolutePath", "findPath"); } diff --git a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java index 59919fd3e0d0..91181db42432 100644 --- a/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java +++ b/platform/util/src/com/intellij/psi/codeStyle/MinusculeMatcher.java @@ -264,7 +264,9 @@ public class MinusculeMatcher implements Matcher { if (p < 0) { break; } - matchingCase += c == myPattern[p] ? 1 : 0; + if (Character.isUpperCase(myPattern[p]) || i == range.getStartOffset()) { + matchingCase += c == myPattern[p] ? 1 : 0; + } } fragmentCount++; } From 376bfbf056a458a869042195afeeaa548390a187 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 2 Jul 2012 16:28:00 +0200 Subject: [PATCH 16/25] don't SOE --- .../codeInsight/completion/XmlBasicToClassNameDelegator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java index cd6882ea27fd..cbfa168512f5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java @@ -29,7 +29,8 @@ public class XmlBasicToClassNameDelegator extends CompletionContributor { @Override public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) { PsiElement position = parameters.getPosition(); - if (!JavaCompletionContributor.mayStartClassName(result) || + if (parameters.getCompletionType() != CompletionType.BASIC || + !JavaCompletionContributor.mayStartClassName(result) || !position.getContainingFile().getLanguage().isKindOf(StdLanguages.XML)) { return; } From 6864c83b2746facc4a377ce7bddfadbd25863d60 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Mon, 2 Jul 2012 19:10:35 +0400 Subject: [PATCH 17/25] Symfony2/PSR-1/2 keep ')' and '{' on one line option --- .../src/com/intellij/formatting/DependentSpacingRule.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-api/src/com/intellij/formatting/DependentSpacingRule.java b/platform/lang-api/src/com/intellij/formatting/DependentSpacingRule.java index 643e08ed1049..a6fe9a2ddb8e 100644 --- a/platform/lang-api/src/com/intellij/formatting/DependentSpacingRule.java +++ b/platform/lang-api/src/com/intellij/formatting/DependentSpacingRule.java @@ -29,11 +29,11 @@ import org.jetbrains.annotations.NotNull; */ public class DependentSpacingRule { - enum Anchor { + public enum Anchor { MIN_LINE_FEEDS, MAX_LINE_FEEDS } - enum Trigger { + public enum Trigger { HAS_LINE_FEEDS, DOES_NOT_HAVE_LINE_FEEDS } From 22c2def2cf94e69bdd51f86b1a01d310903588ec Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 2 Jul 2012 19:28:10 +0400 Subject: [PATCH 18/25] IDEA-88053 VFS Indexing failure --- .../intellij/util/io/PagedFileStorage.java | 184 +++++++++++++----- 1 file changed, 135 insertions(+), 49 deletions(-) diff --git a/platform/util/src/com/intellij/util/io/PagedFileStorage.java b/platform/util/src/com/intellij/util/io/PagedFileStorage.java index 0539b85804ca..eaf2bbd87802 100644 --- a/platform/util/src/com/intellij/util/io/PagedFileStorage.java +++ b/platform/util/src/com/intellij/util/io/PagedFileStorage.java @@ -30,11 +30,9 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; /** * @author max @@ -441,13 +439,17 @@ public class PagedFileStorage implements Forceable { private static final int FILE_INDEX_SHIFT = 16; private final boolean checkThreadAccess; public final StorageLockContext myDefaultStorageLockContext; - - private int myMappingChangeCount; - private final LinkedHashMap myMap; - private long mySizeLimit; - private long mySize; private final ConcurrentHashMap myIndex2Storage = new ConcurrentHashMap(); + private final LinkedHashMap mySegments; + private final SequenceLock mySegmentsAccessLock = new SequenceLock(); // protects map operations of mySegments, needed for LRU order, mySize and myMappingChangeCount + + private final SequenceLock mySegmentsAllocationLock = new SequenceLock(); + private final ConcurrentLinkedQueue mySegmentsToRemove = new ConcurrentLinkedQueue(); + private volatile long mySize; + private volatile long mySizeLimit; + private volatile int myMappingChangeCount; + public StorageLock() { this(true); } @@ -457,7 +459,7 @@ public class PagedFileStorage implements Forceable { myDefaultStorageLockContext = new StorageLockContext(this); mySizeLimit = UPPER_LIMIT; - myMap = new LinkedHashMap(10, 0.75f) { + mySegments = new LinkedHashMap(10, 0.75f) { @Override protected boolean removeEldestEntry(Map.Entry eldest) { return mySize > mySizeLimit; @@ -469,8 +471,9 @@ public class PagedFileStorage implements Forceable { // this method can be called after removeEldestEntry ByteBufferWrapper wrapper = super.remove(key); if (wrapper != null) { + ++myMappingChangeCount; + mySegmentsToRemove.offer(wrapper); mySize -= wrapper.myLength; - wrapper.dispose(); } return wrapper; } @@ -502,33 +505,79 @@ public class PagedFileStorage implements Forceable { } private ByteBufferWrapper get(Integer key) { - ByteBufferWrapper wrapper = myMap.get(key); - if (wrapper != null) { + ByteBufferWrapper wrapper; + try { // fast path + mySegmentsAccessLock.lock(); + wrapper = mySegments.get(key); + if (wrapper != null) return wrapper; + } + finally { + mySegmentsAccessLock.unlock(); + } + + mySegmentsAllocationLock.lock(); + try { + // check if anybody cared about our segment + mySegmentsAccessLock.lock(); + try { + wrapper = mySegments.get(key); + if (wrapper != null) return wrapper; + } finally { + mySegmentsAccessLock.unlock(); + } + + long started = IOStatistics.DEBUG ? System.currentTimeMillis() : 0; + wrapper = createValue(key); + + if (IOStatistics.DEBUG) { + long finished = System.currentTimeMillis(); + if (finished - started > IOStatistics.MIN_IO_TIME_TO_REPORT) { + IOStatistics.dump( + "Mapping " + wrapper.myLength + " from " + wrapper.myPosition + " file:" + wrapper.myFile + " for " + (finished - started)); + } + } + + mySegmentsAccessLock.lock(); + try { + mySegments.put(key, wrapper); + mySize += wrapper.myLength; + } + finally { + mySegmentsAccessLock.unlock(); + } + + ensureSize(mySizeLimit); + return wrapper; } - - long started = IOStatistics.DEBUG ? System.currentTimeMillis() : 0; - wrapper = createValue(key); - mySize += wrapper.myLength; - - if (IOStatistics.DEBUG) { - long finished = System.currentTimeMillis(); - if (finished - started > IOStatistics.MIN_IO_TIME_TO_REPORT) { - IOStatistics.dump( - "Mapping " + wrapper.myLength + " from " + wrapper.myPosition + " file:" + wrapper.myFile + " for " + (finished - started)); - } + finally { + mySegmentsAllocationLock.unlock(); } - myMap.put(key, wrapper); + } - ensureSize(mySizeLimit); - return wrapper; + private void disposeRemovedSegments() { + assert mySegmentsAllocationLock.isHeldByCurrentThread(); + Iterator iterator = mySegmentsToRemove.iterator(); + while(iterator.hasNext()) { + iterator.next().dispose(); + iterator.remove(); + } } private void ensureSize(long sizeLimit) { - while (mySize > sizeLimit) { - // we still have to drop something - myMap.doRemoveEldestEntry(); + assert mySegmentsAllocationLock.isHeldByCurrentThread(); + + try { + mySegmentsAccessLock.lock(); + while (mySize > sizeLimit) { + // we still have to drop something + mySegments.doRemoveEldestEntry(); + } + } finally { + mySegmentsAccessLock.unlock(); } + + disposeRemovedSegments(); } @NotNull @@ -541,7 +590,7 @@ public class PagedFileStorage implements Forceable { if (off > owner.length()) { throw new IndexOutOfBoundsException("off=" + off + " key.owner.length()=" + owner.length()); } - ++myMappingChangeCount; + int min = Math.min((int)(owner.length() - off), owner.myPageSize); ByteBufferWrapper wrapper = ByteBufferWrapper.readWriteDirect(owner.myFile, off, min); IOException oome = null; @@ -586,30 +635,49 @@ public class PagedFileStorage implements Forceable { } private @Nullable Map getBuffersOrderedForOwner(int index, StorageLockContext storageLockContext) { - checkThreadAccess(storageLockContext); - Map mineBuffers = null; - for (Map.Entry entry : myMap.entrySet()) { - if ((entry.getKey() & FILE_INDEX_MASK) == index) { - if (mineBuffers == null) { - mineBuffers = new TreeMap(new Comparator() { - @Override - public int compare(Integer o1, Integer o2) { - return o1 - o2; - } - }); + mySegmentsAccessLock.lock(); + try { + checkThreadAccess(storageLockContext); + Map mineBuffers = null; + for (Map.Entry entry : mySegments.entrySet()) { + if ((entry.getKey() & FILE_INDEX_MASK) == index) { + if (mineBuffers == null) { + mineBuffers = new TreeMap(new Comparator() { + @Override + public int compare(Integer o1, Integer o2) { + return o1 - o2; + } + }); + } + mineBuffers.put(entry.getKey(), entry.getValue()); } - mineBuffers.put(entry.getKey(), entry.getValue()); } + return mineBuffers; + } + finally { + mySegmentsAccessLock.unlock(); } - return mineBuffers; } private void unmapBuffersForOwner(int index, StorageLockContext storageLockContext) { final Map buffers = getBuffersOrderedForOwner(index, storageLockContext); if (buffers != null) { - for (Integer key : buffers.keySet()) { - myMap.remove(key); + mySegmentsAccessLock.lock(); + try { + for (Integer key : buffers.keySet()) { + mySegments.remove(key); + } + } + finally { + mySegmentsAccessLock.unlock(); + } + + mySegmentsAllocationLock.lock(); + try { + disposeRemovedSegments(); + } finally { + mySegmentsAllocationLock.unlock(); } } } @@ -618,14 +686,32 @@ public class PagedFileStorage implements Forceable { Map buffers = getBuffersOrderedForOwner(index, storageLockContext); if (buffers != null) { - for(ByteBufferWrapper buffer:buffers.values()) { - buffer.flush(); + mySegmentsAllocationLock.lock(); + try { + for(ByteBufferWrapper buffer:buffers.values()) { + buffer.flush(); + } + } + finally { + mySegmentsAllocationLock.unlock(); } } } public void invalidateBuffer(int page) { - myMap.remove(page); + mySegmentsAccessLock.lock(); + try { + mySegments.remove(page); + } finally { + mySegmentsAccessLock.unlock(); + } + mySegmentsAllocationLock.lock(); + try { + disposeRemovedSegments(); + } + finally { + mySegmentsAllocationLock.unlock(); + } } } From 0d3bf08a852eefc4ba9a02d23b34624cb90a85dd Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Mon, 2 Jul 2012 19:46:32 +0400 Subject: [PATCH 19/25] [github] Fix GithubOpenInBrowserAction for organizational accounts * Don't use GithubUtil.getGithubUrl, since it assumes that repository should contain user name (which is not true for organizational accounts). * Get the url from config, don't form an url from username and repository name. * Form a valid HTTPS url from all three possible formats: https, git and ssh. * Refactor: extract a couple of methods. * Add +1 to the line retrieved from the LogicalPosition of the editor (since it counts from 0). --- .../github/GithubOpenInBrowserAction.java | 80 +++++++++++++++---- .../jetbrains/plugins/github/GithubUtil.java | 1 + 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java b/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java index eb12b099aa42..fd5bcc184dd7 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubOpenInBrowserAction.java @@ -29,9 +29,10 @@ import com.intellij.openapi.vcs.changes.ChangeListManager; import com.intellij.openapi.vfs.VirtualFile; import git4idea.GitBranch; import git4idea.GitUtil; -import git4idea.repo.GitRemote; import git4idea.repo.GitRepository; import git4idea.repo.GitRepositoryManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.github.ui.GithubLoginDialog; import static org.jetbrains.plugins.github.GithubUtil.*; @@ -106,8 +107,7 @@ public class GithubOpenInBrowserAction extends DumbAwareAction { } final GitRepository gitRepository = manager.getRepositoryForFile(root); // Check that given repository is properly configured git repository - final GitRemote gitRemote = findGitHubRemoteBranch(gitRepository); - final String pushUrl = getGithubUrl(gitRemote); + final String githubRemoteUrl = findGithubRemoteUrl(gitRepository); final VirtualFile virtualFile = e.getData(PlatformDataKeys.VIRTUAL_FILE); final String rootPath = root.getPath(); @@ -117,38 +117,84 @@ public class GithubOpenInBrowserAction extends DumbAwareAction { return; } - String userAndRepository = getUserAndRepositoryOrShowError(project, pushUrl); + String branch = getBranchNameOnRemote(project, root); + if (branch == null) { + return; + } - // Get current tracked branch + String relativePath = path.substring(rootPath.length()); + String urlToOpen = makeUrlToOpen(e, relativePath, branch, githubRemoteUrl); + BrowserUtil.launchBrowser(urlToOpen); + } + + private static String makeUrlToOpen(@NotNull AnActionEvent e, @NotNull String relativePath, @NotNull String branch, + @NotNull String githubRemoteUrl) { + final StringBuilder builder = new StringBuilder(); + builder.append(makeGithubRepoUrlFromRemoteUrl(githubRemoteUrl)).append("/blob/").append(branch).append(relativePath); + final Editor editor = e.getData(PlatformDataKeys.EDITOR); + if (editor != null) { + final int line = editor.getCaretModel().getLogicalPosition().line + 1; // lines are counted internally from 0, but from 1 on github + builder.append("#L").append(line); + } + return builder.toString(); + } + + @NotNull + private static String makeGithubRepoUrlFromRemoteUrl(@NotNull String remoteUrl) { + remoteUrl = removeEndingDotGit(remoteUrl); + if (remoteUrl.startsWith("http")) { + return remoteUrl; + } + if (remoteUrl.startsWith("git://")) { + return "https" + remoteUrl.substring(3); + } + return convertFromSshToHttp(remoteUrl); + } + + @NotNull + private static String convertFromSshToHttp(@NotNull String remoteUrl) { + // Format: git@github.com:account/repository + int indexOfAt = remoteUrl.indexOf("@"); + if (indexOfAt < 0) { + throw new IllegalStateException("Invalid remote Github SSH url: " + remoteUrl); + } + String withoutPrefix = remoteUrl.substring(indexOfAt + 1, remoteUrl.length()); + return "https://" + withoutPrefix.replace(':', '/'); + } + + @NotNull + private static String removeEndingDotGit(@NotNull String url) { + final String DOT_GIT = ".git"; + if (url.endsWith(DOT_GIT)) { + return url.substring(0, url.length() - DOT_GIT.length()); + } + return url; + } + + @Nullable + public static String getBranchNameOnRemote(@NotNull Project project, @NotNull VirtualFile root) { final GitBranch tracked; try { final GitBranch current = GitBranch.current(project, root); if (current == null) { Messages.showErrorDialog(project, "Cannot find local branch", CANNOT_OPEN_IN_BROWSER); - return; + return null; } tracked = current.tracked(project, root); if (tracked == null || !tracked.isRemote()) { Messages.showErrorDialog(project, "Cannot find tracked branch for branch: " + current.getFullName(), CANNOT_OPEN_IN_BROWSER); - return; + return null; } } catch (VcsException e1) { Messages.showErrorDialog(project, "Error occurred while inspecting branches: " + e1, CANNOT_OPEN_IN_BROWSER); - return; + return null; } String branch = tracked.getName(); if (branch.startsWith("origin/")) { branch = branch.substring(7); } - - final StringBuilder builder = new StringBuilder(); - builder.append("https://github.com/").append(userAndRepository).append("/blob/").append(branch).append(path.substring(rootPath.length())); - final Editor editor = e.getData(PlatformDataKeys.EDITOR); - if (editor != null) { - final int line = editor.getCaretModel().getLogicalPosition().line; - builder.append("#L").append(line); - } - BrowserUtil.launchBrowser(builder.toString()); + return branch; } + } diff --git a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java index 649e5482ae8e..52e9e6fcb215 100644 --- a/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java +++ b/plugins/github/src/org/jetbrains/plugins/github/GithubUtil.java @@ -450,6 +450,7 @@ public class GithubUtil { final String host = githubSettings.getHost(); final String username = githubSettings.getLogin(); + // TODO this doesn't work with organizational accounts final String userRepoMarkerSSHProtocol = host + ":" + username + "/"; final String userRepoMarkerOtherProtocols = host + "/" + username + "/"; for (String pushUrl : gitRemote.getUrls()) { From 2611f42ce4fd9269bdee6adbd545b46247771e64 Mon Sep 17 00:00:00 2001 From: irengrig Date: Mon, 2 Jul 2012 20:14:09 +0400 Subject: [PATCH 20/25] SVN: correctly append relative url part when calculating annotation for revision by URL --- .../jetbrains/idea/svn/annotate/SvnAnnotationProvider.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java index 6e0cd264f475..0e46f2f37849 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java @@ -215,7 +215,11 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn if (wcRootInfo == null || wcRootInfo.getURL() == null) { throw new VcsException("Can not find relative path for " + wasFile.getPath() + "@" + revision.getRevisionNumber().asString()); } - final SVNURL wasUrl = wcRootInfo.getURL().appendPath(relativePath, true); + SVNURL wasUrl = wcRootInfo.getURL(); + final String[] strings = relativePath.replace('\\','/').split("/"); + for (String string : strings) { + wasUrl = wasUrl.appendPath(string, true); + } final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); final SVNRevision svnRevision = ((SvnRevisionNumber)revision.getRevisionNumber()).getRevision(); From d75075c0c2e57f73dd275eee027b1ec9fd37d1fe Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 2 Jul 2012 18:25:09 +0200 Subject: [PATCH 21/25] suggest all visible classes everywhere (IDEA-87958) --- .../JavaClassNameCompletionContributor.java | 25 +++------------ .../completion/ClassNameCompletionTest.java | 2 ++ .../GroovyCompletionContributor.java | 31 ++----------------- .../completion/weighers/GrKindWeigher.java | 16 ++++++++-- .../GroovyClassNameCompletionTest.groovy | 4 +-- .../completion/GroovyCompletionTest.groovy | 8 +++-- 6 files changed, 31 insertions(+), 55 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java index 62999d5f611d..1c1cefe8ce8e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java @@ -31,7 +31,6 @@ import com.intellij.psi.filters.ClassFilter; import com.intellij.psi.filters.ElementFilter; import com.intellij.psi.filters.TrueFilter; import com.intellij.psi.filters.element.ExcludeDeclaredFilter; -import com.intellij.psi.filters.types.AssignableFromFilter; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; @@ -74,6 +73,9 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { if (SkipAutopopupInStrings.isInStringLiteral(position)) { return true; } + if (PsiTreeUtil.getParentOfType(position, PsiComment.class, false) != null) { + return true; + } return false; } @@ -83,22 +85,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { @NotNull final Consumer consumer) { final PsiElement insertedElement = parameters.getPosition(); - final ElementFilter filter; - if (JavaSmartCompletionContributor.AFTER_THROW_NEW.accepts(insertedElement) || - JavaCompletionContributor.INSIDE_METHOD_THROWS_CLAUSE.accepts(insertedElement) || - JavaCompletionContributor.IN_CATCH_TYPE.accepts(insertedElement) || - JavaCompletionContributor.IN_MULTI_CATCH_TYPE.accepts(insertedElement)) { - filter = new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE); - } - else if (JavaCompletionContributor.IN_RESOURCE_TYPE.accepts(insertedElement)) { - filter = new AssignableFromFilter(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE); - } - else if (IN_TYPE_PARAMETER.accepts(insertedElement)) { - filter = new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class)); - } - else { - filter = TrueFilter.INSTANCE; - } + final ElementFilter filter = + IN_TYPE_PARAMETER.accepts(insertedElement) ? new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class)) : TrueFilter.INSTANCE; final boolean inJavaContext = parameters.getPosition() instanceof PsiIdentifier; final boolean afterNew = AFTER_NEW.accepts(insertedElement); @@ -120,13 +108,10 @@ public class JavaClassNameCompletionContributor extends CompletionContributor { } } - final boolean lookingForAnnotations = psiElement().afterLeaf("@").accepts(insertedElement); final boolean pkgContext = JavaCompletionUtil.inSomePackage(insertedElement); AllClassesGetter.processJavaClasses(parameters, matcher, filterByScope, new Consumer() { @Override public void consume(PsiClass psiClass) { - if (lookingForAnnotations && !psiClass.isAnnotationType()) return; - if (filter.isAcceptable(psiClass, insertedElement)) { if (!inJavaContext) { consumer.consume(AllClassesGetter.createLookupItem(psiClass, AllClassesGetter.TRY_SHORTENING)); diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java index 6c5768c0e9f1..ce660ae3cddb 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/ClassNameCompletionTest.java @@ -65,6 +65,7 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase { String path = "/afterNewThrowable"; configureByFile(path + "/before1.java"); + myFixture.type('\n'); checkResultByFile(path + "/after1.java"); } @@ -81,6 +82,7 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase { String path = "/afterNewThrowable"; configureByFile(path + "/before2.java"); + myFixture.type('\n'); checkResultByFile(path + "/after2.java"); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index 6d0ad639e0fc..f433e8c8897f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -34,10 +34,7 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.SuggestedNameInfo; import com.intellij.psi.codeStyle.VariableKind; -import com.intellij.psi.filters.ElementFilter; import com.intellij.psi.filters.FilterPositionUtil; -import com.intellij.psi.filters.TrueFilter; -import com.intellij.psi.filters.types.AssignableFromFilter; import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.InheritanceUtil; @@ -177,8 +174,8 @@ public class GroovyCompletionContributor extends CompletionContributor { private static final ElementPattern AFTER_NUMBER_LITERAL = psiElement().afterLeaf( psiElement().withElementType(elementType().oneOf(mNUM_DOUBLE, mNUM_INT, mNUM_LONG, mNUM_FLOAT, mNUM_BIG_INT, mNUM_BIG_DECIMAL))); - private static final ElementPattern AFTER_AT = psiElement().afterLeaf("@"); - private static final ElementPattern IN_CATCH_TYPE = psiElement().afterLeaf(psiElement().withText("(").withParent(GrCatchClause.class)); + public static final ElementPattern AFTER_AT = psiElement().afterLeaf("@"); + public static final ElementPattern IN_CATCH_TYPE = psiElement().afterLeaf(psiElement().withText("(").withParent(GrCatchClause.class)); private static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritors) { @@ -194,7 +191,6 @@ public class GroovyCompletionContributor extends CompletionContributor { final Consumer consumer, final InheritorsHolder inheritors, final PrefixMatcher matcher) { final PsiElement position = parameters.getPosition(); - final ElementFilter filter = getClassFilter(position); final boolean afterNew = JavaClassNameCompletionContributor.AFTER_NEW.accepts(position); AllClassesGetter.processJavaClasses(parameters, matcher, parameters.getInvocationCount() <= 1, new Consumer() { @Override @@ -203,7 +199,7 @@ public class GroovyCompletionContributor extends CompletionContributor { .createClassLookupItems(psiClass, afterNew, new GroovyClassNameInsertHandler(), new Condition() { @Override public boolean value(PsiClass psiClass) { - return !inheritors.alreadyProcessed(psiClass) && filter.isAcceptable(psiClass, position); + return !inheritors.alreadyProcessed(psiClass); } })) { consumer.consume(element); @@ -212,16 +208,6 @@ public class GroovyCompletionContributor extends CompletionContributor { }); } - private static ElementFilter getClassFilter(PsiElement position) { - if (AFTER_AT.accepts(position)) { - return new AssignableFromFilter(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION); - } - if (IN_CATCH_TYPE.accepts(position)) { - return new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE); - } - return TrueFilter.INSTANCE; - } - public GroovyCompletionContributor() { //provide 'this' and 'super' completions in ClassName. extend(CompletionType.BASIC, AFTER_DOT, new CompletionProvider() { @@ -378,10 +364,6 @@ public class GroovyCompletionContributor extends CompletionContributor { } public static boolean isClassNamePossible(PsiElement position) { - if (PsiJavaPatterns.psiElement().inside(GrImportStatement.class).accepts(position)) { - return false; - } - if (position instanceof PsiComment) return false; PsiElement parent = position.getParent(); if (parent instanceof GrReferenceElement) { return ((GrReferenceElement)parent).getQualifier() == null; @@ -431,8 +413,6 @@ public class GroovyCompletionContributor extends CompletionContributor { } }; - final PsiElement position = parameters.getPosition(); - final Map staticMembers = hashMap(); final PsiElement qualifier = reference.getQualifier(); final PsiType qualifierType = qualifier instanceof GrExpression ? ((GrExpression)qualifier).getType() : null; @@ -455,8 +435,6 @@ public class GroovyCompletionContributor extends CompletionContributor { unresolvedProps = Collections.emptySet(); } - final ElementFilter classFilter = getClassFilter(position); - final List zeroPriority = arrayList(); reference.processVariants(matcher, parameters, new Consumer() { public void consume(LookupElement lookupElement) { @@ -489,9 +467,6 @@ public class GroovyCompletionContributor extends CompletionContributor { staticMembers.put(CompletionUtil.getOriginalOrSelf((PsiModifierListOwner)object), lookupElement); } } - if (object instanceof PsiClass && !classFilter.isAcceptable(object, position)) { - return; - } PrioritizedLookupElement prio = lookupElement.as(PrioritizedLookupElement.CLASS_CONDITION_KEY); if (prio == null || prio.getPriority() == 0) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java index dd469ca38610..f29092426b24 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/weighers/GrKindWeigher.java @@ -21,11 +21,13 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.PsiTypeLookupItem; import com.intellij.psi.*; import com.intellij.psi.impl.light.LightElement; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.CollectionFactory; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor; +import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionContributor; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; @@ -86,6 +88,15 @@ public class GrKindWeigher extends CompletionWeigher { if (isPriorityKeyword(o)) return NotQualifiedKind.local; if (isLightElement(o)) return NotQualifiedKind.unknown; + if (o instanceof PsiClass) { + if (((PsiClass)o).isAnnotationType() && GroovyCompletionContributor.AFTER_AT.accepts(position)) { + return NotQualifiedKind.restrictedClass; + } + if (GroovyCompletionContributor.IN_CATCH_TYPE.accepts(position) && + InheritanceUtil.isInheritor((PsiClass)o, CommonClassNames.JAVA_LANG_THROWABLE)) { + return NotQualifiedKind.restrictedClass; + } + } if (o instanceof PsiMember) { final PsiClass containingClass = ((PsiMember)o).getContainingClass(); if (isAccessor((PsiMember)o)) return NotQualifiedKind.accessor; @@ -145,18 +156,19 @@ public class GrKindWeigher extends CompletionWeigher { return qualifier.getManager().areElementsEquivalent(member.getContainingClass(), psiClass); } - private static enum NotQualifiedKind { + private enum NotQualifiedKind { arrayType, innerClass, unknown, accessor, member, currentClassMember, + restrictedClass, local, onTop } - private static enum QualifiedKind { + private enum QualifiedKind { innerClass, unknown, accessor, diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyClassNameCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyClassNameCompletionTest.groovy index 87023a3ac2d8..cbab89c619f8 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyClassNameCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyClassNameCompletionTest.groovy @@ -226,14 +226,14 @@ new Fxoo()\n""" myFixture.addClass "class AbcdClass {}; @interface AbcdAnno {}" myFixture.configureByText "a.groovy", "@Abcd" complete() - myFixture.checkResult "@AbcdAnno" + assert myFixture.lookupElementStrings[0] == 'AbcdAnno' } public void testOnlyExceptionsInCatch() { myFixture.addClass "class AbcdClass {}; class AbcdException extends Throwable {}" myFixture.configureByText "a.groovy", "try {} catch (Abcd" complete() - myFixture.checkResult "try {} catch (AbcdException" + assert myFixture.lookupElementStrings[0] == 'AbcdException' } public void testClassNameInMultilineString() { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index d84a161f0306..e480ac9d4cd3 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -712,17 +712,17 @@ format()""" } public void testOnlyAnnotationsAfterAt() { - myFixture.addClass "class AbcdClass {}; @interface AbcdAnno {}" + myFixture.addClass "class AbcdClass {}; @interface AbcdXAnno {}" myFixture.configureByText "a.groovy", "@Abcd class A {}" myFixture.completeBasic() - myFixture.checkResult "@AbcdAnno class A {}" + assert myFixture.lookupElementStrings[0] == 'AbcdXAnno' } public void testOnlyAnnotationsAfterAtInMethodParameters() { myFixture.addClass "class AbcdClass {}; @interface AbcdAnno {}" myFixture.configureByText "a.groovy", "def foo(@Abcd ) {}" myFixture.completeBasic() - myFixture.checkResult "def foo(@AbcdAnno ) {}" + assert myFixture.lookupElementStrings[0] == 'AbcdAnno' } public void testNoCompletionInClassBodyComments() { @@ -767,6 +767,8 @@ try {} catch (AbcdException""" myFixture.addClass "class AbcdClass {}; class AbcdException extends Throwable {}" myFixture.configureByText "a.groovy", "try {} catch (Abcd e) {}" myFixture.completeBasic() + assert myFixture.lookupElementStrings[0] == 'AbcdException' + myFixture.type('\n') myFixture.checkResult "try {} catch (AbcdException e) {}" } From 6ffd36caa3a04f8a250dfc5e3166fbbdd811d835 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Mon, 2 Jul 2012 20:56:35 +0400 Subject: [PATCH 22/25] Wrap In --- .../AndroidDesignerEditorPanel.java | 10 ++ .../designer/model/AndroidWrapInProvider.java | 48 +++++++++ .../android/designer/model/RadViewLayout.java | 3 + .../designer/model/views-meta-model.xml | 9 ++ .../designer/actions/DesignerActionPanel.java | 1 + .../designer/actions/WrapInAction.java | 102 ++++++++++++++++++ .../designSurface/DesignerEditorPanel.java | 6 ++ .../intellij/designer/model/MetaManager.java | 14 +++ .../intellij/designer/model/RadComponent.java | 5 + .../intellij/designer/model/RadLayout.java | 4 + .../designer/model/WrapInProvider.java | 35 ++++++ 11 files changed, 237 insertions(+) create mode 100644 plugins/android-designer/src/com/intellij/android/designer/model/AndroidWrapInProvider.java create mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/WrapInAction.java create mode 100644 plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/WrapInProvider.java diff --git a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java index 149f5ec81f3b..a01afc543447 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java +++ b/plugins/android-designer/src/com/intellij/android/designer/designSurface/AndroidDesignerEditorPanel.java @@ -31,6 +31,7 @@ import com.intellij.designer.designSurface.selection.NonResizeSelectionDecorator import com.intellij.designer.designSurface.tools.ComponentCreationFactory; import com.intellij.designer.designSurface.tools.ComponentPasteFactory; import com.intellij.designer.model.RadComponent; +import com.intellij.designer.model.WrapInProvider; import com.intellij.designer.palette.DefaultPaletteItem; import com.intellij.designer.palette.PaletteGroup; import com.intellij.designer.palette.PaletteItem; @@ -77,6 +78,7 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { private volatile RenderSession mySession; private boolean myParseTime; private int myProfileLastVersion; + private WrapInProvider myWrapInProvider; public AndroidDesignerEditorPanel(@NotNull DesignerEditor editor, @NotNull Project project, @@ -464,6 +466,14 @@ public final class AndroidDesignerEditorPanel extends DesignerEditorPanel { return myTreeDecorator; } + @Override + public WrapInProvider getWrapInProvider() { + if (myWrapInProvider == null) { + myWrapInProvider = new AndroidWrapInProvider(getProject()); + } + return myWrapInProvider; + } + private static final ComponentDecorator NON_RESIZE_DECORATOR = new NonResizeSelectionDecorator(Color.RED, 2); @Override diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/AndroidWrapInProvider.java b/plugins/android-designer/src/com/intellij/android/designer/model/AndroidWrapInProvider.java new file mode 100644 index 000000000000..46e20f726d8c --- /dev/null +++ b/plugins/android-designer/src/com/intellij/android/designer/model/AndroidWrapInProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.android.designer.model; + +import com.intellij.designer.model.MetaModel; +import com.intellij.designer.model.RadComponent; +import com.intellij.designer.model.WrapInProvider; +import com.intellij.openapi.project.Project; + +import java.util.List; + +/** + * @author Alexander Lobas + */ +public final class AndroidWrapInProvider extends WrapInProvider { + public AndroidWrapInProvider(Project project) { + super(ViewsMetaManager.getInstance(project)); + } + + @Override + public RadComponent wrapIn(RadViewComponent parent, List components, MetaModel target) throws Exception { + RadViewComponent newParent = ModelParser.createComponent(null, target); + + ModelParser.addComponent(parent, newParent, components.get(0)); + + for (RadViewComponent component : components) { + ModelParser.moveComponent(newParent, component, null); + } + + RadViewLayout layout = (RadViewLayout)parent.getLayout(); + layout.wrapIn(newParent, components); + + return newParent; + } +} \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/RadViewLayout.java b/plugins/android-designer/src/com/intellij/android/designer/model/RadViewLayout.java index 20a36399f595..08165feb0f80 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/RadViewLayout.java +++ b/plugins/android-designer/src/com/intellij/android/designer/model/RadViewLayout.java @@ -43,4 +43,7 @@ public class RadViewLayout extends RadLayout { JComponent shortcuts, List selection) { } + + public void wrapIn(RadViewComponent newParent, List components) throws Exception { + } } \ No newline at end of file diff --git a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml index eb369e8a4e9d..0311d7976093 100644 --- a/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml +++ b/plugins/android-designer/src/com/intellij/android/designer/model/views-meta-model.xml @@ -1447,6 +1447,15 @@ + + + + + + + + + diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/DesignerActionPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/DesignerActionPanel.java index 86c813b7cadc..24a15a36953b 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/DesignerActionPanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/DesignerActionPanel.java @@ -177,6 +177,7 @@ public class DesignerActionPanel implements DataProvider { myDynamicPopupGroup.removeAll(); } + WrapInAction.fill(myDesigner, myDynamicPopupGroup, area); MorphingAction.fill(myDesigner, myDynamicPopupGroup, area); return myPopupGroup; diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/WrapInAction.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/WrapInAction.java new file mode 100644 index 000000000000..92e5e6d26e5a --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/actions/WrapInAction.java @@ -0,0 +1,102 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.designer.actions; + +import com.intellij.designer.designSurface.DesignerEditorPanel; +import com.intellij.designer.designSurface.EditableArea; +import com.intellij.designer.model.MetaModel; +import com.intellij.designer.model.RadComponent; +import com.intellij.designer.model.RadLayout; +import com.intellij.designer.model.WrapInProvider; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.util.ThrowableRunnable; + +import java.util.List; +import java.util.Set; + +/** + * @author Alexander Lobas + */ +public class WrapInAction extends AnAction { + private final DesignerEditorPanel myDesigner; + private final EditableArea myArea; + private final WrapInProvider myProvider; + private final RadComponent myParent; + private final List myComponents; + private final MetaModel myTarget; + + public WrapInAction(DesignerEditorPanel designer, + EditableArea area, + WrapInProvider provider, + RadComponent parent, + List components, + MetaModel target) { + super(target.getTag(), null, target.getIcon()); + myDesigner = designer; + myArea = area; + myProvider = provider; + myParent = parent; + myComponents = components; + myTarget = target; + } + + @Override + public void actionPerformed(AnActionEvent e) { + myDesigner.getToolProvider().execute(new ThrowableRunnable() { + @Override + public void run() throws Exception { + myArea.select(myProvider.wrapIn(myParent, myComponents, myTarget)); + } + }, "Run Wrap In action", true); + } + + public static void fill(DesignerEditorPanel designer, DefaultActionGroup group, EditableArea area) { + List selection = area.getSelection(); + if (selection.isEmpty()) { + return; + } + + Set parents = RadComponent.getParents(selection); + if (parents.size() != 1) { + return; + } + + RadComponent parent = parents.iterator().next(); + RadLayout layout = parent.getLayout(); + if (layout != null && !layout.isWrapIn(selection)) { + return; + } + + WrapInProvider provider = designer.getWrapInProvider(); + if (provider == null) { + return; + } + + List models = provider.getModels(); + if (models.isEmpty()) { + return; + } + + DefaultActionGroup wrapGroup = new DefaultActionGroup("Wrap In", true); + for (MetaModel wrapModel : models) { + wrapGroup.add(new WrapInAction(designer, area, provider, parent, selection, wrapModel)); + } + + group.add(wrapGroup); + } +} \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java index b6dd0ebf50a4..3ec787cd1d48 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/designSurface/DesignerEditorPanel.java @@ -24,6 +24,7 @@ import com.intellij.designer.componentTree.TreeComponentDecorator; import com.intellij.designer.designSurface.tools.*; import com.intellij.designer.model.FindComponentVisitor; import com.intellij.designer.model.RadComponent; +import com.intellij.designer.model.WrapInProvider; import com.intellij.designer.palette.PaletteGroup; import com.intellij.designer.palette.PaletteItem; import com.intellij.designer.palette.PaletteToolWindowManager; @@ -729,6 +730,11 @@ public abstract class DesignerEditorPanel extends JPanel implements DataProvider Disposer.dispose(myProgressIcon); } + @Nullable + public WrapInProvider getWrapInProvider() { + return null; + } + public RadComponent getRootComponent() { return myRootComponent; } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java index a66a1c751b8b..08b69a16d928 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/MetaManager.java @@ -43,12 +43,14 @@ public abstract class MetaManager { private static final String NAME = "name"; private static final String ITEM = "item"; private static final String TAG = "tag"; + private static final String WRAP_IN = "wrap-in"; private static final Logger LOG = Logger.getInstance("#com.intellij.designer.model.MetaManager"); private final Map myTag2Model = new HashMap(); private final Map myTarget2Model = new HashMap(); private final List myPaletteGroups = new ArrayList(); + private final List myWrapModels = new ArrayList(); private PropertyChangeSupport myPaletteChangeSupport; @@ -73,6 +75,14 @@ public abstract class MetaManager { loadGroup((Element)element); } + Element wrapInElement = rootElement.getChild(WRAP_IN); + if (wrapInElement != null) { + for (Object element : wrapInElement.getChildren(ITEM)) { + Element item = (Element)element; + myWrapModels.add(myTag2Model.get(item.getAttributeValue("tag"))); + } + } + for (Map.Entry> entry : modelToMorphing.entrySet()) { MetaModel meta = entry.getKey(); List morphingModels = new ArrayList(); @@ -209,6 +219,10 @@ public abstract class MetaManager { return myTarget2Model.get(target); } + public List getWrapInModels() { + return myWrapModels; + } + public List getPaletteGroups() { return myPaletteGroups; } diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java index c5ceb44c64ab..72ae7bd8ad26 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadComponent.java @@ -265,6 +265,11 @@ public abstract class RadComponent { return null; } + @Nullable + public RadComponent wrapIn(MetaModel target) throws Exception { + return null; + } + ////////////////////////////////////////////////////////////////////////////////////////// // // Utils diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadLayout.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadLayout.java index d0c8f518da47..46feaa509946 100644 --- a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadLayout.java +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/RadLayout.java @@ -62,4 +62,8 @@ public abstract class RadLayout { public ICaption getCaption(RadComponent component) { return null; } + + public boolean isWrapIn(List components) { + return true; + } } \ No newline at end of file diff --git a/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/WrapInProvider.java b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/WrapInProvider.java new file mode 100644 index 000000000000..7ff3aa8a06fd --- /dev/null +++ b/plugins/ui-designer/ui-designer-new/src/com/intellij/designer/model/WrapInProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.designer.model; + +import java.util.List; + +/** + * @author Alexander Lobas + */ +public abstract class WrapInProvider { + private final List myModels; + + public WrapInProvider(MetaManager metaManager) { + myModels = metaManager.getWrapInModels(); + } + + public List getModels() { + return myModels; + } + + public abstract RadComponent wrapIn(T parent, List components, MetaModel target) throws Exception; +} \ No newline at end of file From c59bf451d01596434855e77895876f89cba100f5 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 2 Jul 2012 18:57:29 +0200 Subject: [PATCH 23/25] full project name --- .../actions/ShowFeatureUsageStatisticsDialog.java | 7 +++---- .../src/messages/FeatureStatisticsBundle.properties | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java b/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java index e858374f0768..f1823069d2b4 100644 --- a/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java +++ b/platform/platform-impl/src/com/intellij/featureStatistics/actions/ShowFeatureUsageStatisticsDialog.java @@ -149,12 +149,11 @@ public class ShowFeatureUsageStatisticsDialog extends DialogWrapper { long idleTime = app.getIdleTime(); final String uptimeS = FeatureStatisticsBundle.message("feature.statistics.application.uptime", - ApplicationNamesInfo.getInstance().getProductName(), + ApplicationNamesInfo.getInstance().getFullProductName(), DateFormatUtil.formatDuration(uptime)); - final String idleTimeS = FeatureStatisticsBundle .message("feature.statistics.application.idle.time", - ApplicationNamesInfo.getInstance().getProductName(), - DateFormatUtil.formatDuration(idleTime)); + final String idleTimeS = FeatureStatisticsBundle.message("feature.statistics.application.idle.time", + DateFormatUtil.formatDuration(idleTime)); String labelText = uptimeS + ", " + idleTimeS; CompletionStatistics stats = ((FeatureUsageTrackerImpl)FeatureUsageTracker.getInstance()).getCompletionStatistics(); diff --git a/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties b/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties index 14f3326d6b9d..490e76352d9d 100644 --- a/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties +++ b/platform/platform-resources-en/src/messages/FeatureStatisticsBundle.properties @@ -24,7 +24,7 @@ feature.statistics.not.applicable=N/A # {0} - application name (IntelliJ IDEA or Visual Fabrique or RubyMine or WebStorm or PhpStorm or PyCharm or CIDR) # {1} - formatted duration. feature.statistics.application.uptime={0} uptime: {1} -feature.statistics.application.idle.time={0} idle time: {1} +feature.statistics.application.idle.time=idle time: {0} # Names of features in the feature statistics bundle navigation.popup.class=Go to class From 13cf9329177feb031d09d97a671c4a28af6c8db1 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Mon, 2 Jul 2012 21:00:19 +0400 Subject: [PATCH 24/25] show description in tooltip --- .../src/com/intellij/execution/ui/layout/impl/GridCellImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java index f8089fc12254..8fb769c791f1 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java @@ -232,6 +232,7 @@ public class GridCellImpl implements GridCell { return info. setIcon(content.getIcon()). setText(content.getDisplayName()). + setTooltipText(content.getDescription()). setActionsContextComponent(content.getActionsContextComponent()). setActions(content.getActions(), content.getPlace()); } From b34c5707ea565b9963f69b02a9cb7f943ae2a0a7 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 2 Jul 2012 19:29:58 +0200 Subject: [PATCH 25/25] if there's no .idea, then just recreate it when reopening a recent directory project (IDEA-88153) --- .../src/com/intellij/ide/ReopenProjectAction.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ide/ReopenProjectAction.java b/platform/platform-impl/src/com/intellij/ide/ReopenProjectAction.java index 1f4c9175a7fe..81d1725549c8 100644 --- a/platform/platform-impl/src/com/intellij/ide/ReopenProjectAction.java +++ b/platform/platform-impl/src/com/intellij/ide/ReopenProjectAction.java @@ -25,6 +25,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.io.FileUtil; import java.awt.event.InputEvent; +import java.io.File; /** * @author yole @@ -50,8 +51,9 @@ public class ReopenProjectAction extends AnAction implements DumbAware { final int modifiers = e.getModifiers(); final boolean forceOpenInNewFrame = (modifiers & InputEvent.CTRL_MASK) != 0 || (modifiers & InputEvent.SHIFT_MASK) != 0; Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext()); - if (!RecentProjectsManagerBase.isValidProjectPath(myProjectPath)) { - Messages.showErrorDialog(project, "The project path " + FileUtil.toSystemDependentName(myProjectPath) + " does not exist.\n" + + File file = new File(myProjectPath); + if (!file.exists() || !file.isDirectory()) { + Messages.showErrorDialog(project, "The directory " + FileUtil.toSystemDependentName(myProjectPath) + " does not exist.\n" + "If it is on a removable or network drive, please make sure that the drive is connected.", "Reopen Project"); return;