diff --git a/java/execution/impl/src/com/intellij/execution/applet/AppletConfiguration.java b/java/execution/impl/src/com/intellij/execution/applet/AppletConfiguration.java index 9d00cad60172..f69ad997c8dc 100644 --- a/java/execution/impl/src/com/intellij/execution/applet/AppletConfiguration.java +++ b/java/execution/impl/src/com/intellij/execution/applet/AppletConfiguration.java @@ -35,6 +35,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.refactoring.listeners.RefactoringElementListener; +import com.intellij.util.SmartList; import com.intellij.util.xmlb.SmartSerializer; import com.intellij.util.xmlb.annotations.Transient; import org.jdom.Element; @@ -46,7 +47,6 @@ import java.io.FileWriter; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -74,7 +74,7 @@ public class AppletConfiguration extends ModuleBasedConfiguration parameters = new ArrayList(); - for (final Element element : parentNode.getChildren(PARAMETER_ELEMENT_NAME)) { - parameters.add(new AppletParameter(element.getAttributeValue(NAME_ATTR), element.getAttributeValue(VALUE_ATTR))); + + List paramList = parentNode.getChildren(PARAMETER_ELEMENT_NAME); + if (paramList.isEmpty()) { + myAppletParameters = null; + } + else { + List parameters = new SmartList(); + for (Element element : paramList) { + parameters.add(new AppletParameter(element.getAttributeValue(NAME_ATTR), element.getAttributeValue(VALUE_ATTR))); + } + myAppletParameters = parameters.toArray(new AppletParameter[parameters.size()]); } - myAppletParameters = parameters.toArray(new AppletParameter[parameters.size()]); } @Override @@ -208,7 +214,6 @@ public class AppletConfiguration extends ModuleBasedConfiguration { - - private static final JavaMethodParameterTypesIndex ourInstance = new JavaMethodParameterTypesIndex(); - public static JavaMethodParameterTypesIndex getInstance() { - return ourInstance; - } - - @NotNull - @Override - public StubIndexKey getKey() { - return JavaStubIndexKeys.METHOD_TYPES; - } - - @Override - public Collection get(@NotNull final String s, @NotNull final Project project, @NotNull final GlobalSearchScope scope) { - return StubIndex.getElements(getKey(), s, project, new JavaSourceFilterScope(scope), PsiMethod.class); - } -} \ No newline at end of file diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java index cb5d6be103fd..2652cb3aa51d 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java @@ -15,37 +15,39 @@ */ package com.intellij.psi.impl.search; +import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.impl.scopes.ModulesScope; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.LanguageLevelModuleExtension; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; -import com.intellij.psi.impl.java.stubs.JavaMethodElementType; -import com.intellij.psi.impl.java.stubs.index.JavaMethodParameterTypesIndex; -import com.intellij.psi.search.EverythingGlobalScope; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.*; import com.intellij.psi.search.searches.FunctionalExpressionSearch; -import com.intellij.psi.search.searches.MethodReferencesSearch; -import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; import com.intellij.util.QueryExecutor; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import java.util.Collection; -import java.util.LinkedHashSet; import java.util.Set; public class JavaFunctionalExpressionSearcher implements QueryExecutor { + private static final Logger LOG = Logger.getInstance("#" + JavaFunctionalExpressionSearcher.class.getName()); + @Override public boolean execute(@NotNull final FunctionalExpressionSearch.SearchParameters queryParameters, @NotNull final Processor consumer) { @@ -98,102 +100,75 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor lambdaCandidates = ApplicationManager.getApplication().runReadAction(new Computable>() { + + final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); + CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor() { @Override - public Collection compute() { - final String functionalInterfaceName = aClass.getName(); - final GlobalSearchScope useClassScope = classScope instanceof GlobalSearchScope ? (GlobalSearchScope)classScope : scope; - JavaMethodParameterTypesIndex parameterTypesIndex = JavaMethodParameterTypesIndex.getInstance(); - LinkedHashSet methods = new LinkedHashSet(parameterTypesIndex.get(functionalInterfaceName, project, useClassScope)); - methods.addAll(parameterTypesIndex.get(JavaMethodElementType.TYPE_PARAMETER_PSEUDO_NAME, project, - GlobalSearchScope.allScope(project))); - return methods; + protected boolean accept(VirtualFile virtualFile) { + return scope.contains(virtualFile) && virtualFile.getFileType() == JavaFileType.INSTANCE && index.isInSource(virtualFile); } - }); - for (PsiMethod psiMethod : lambdaCandidates) { - for (final PsiReference ref : MethodReferencesSearch.search(psiMethod, scope, false)) { - boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - final PsiElement refElement = ref.getElement(); - if (refElement != null) { - final PsiElement candidateElement = refElement.getParent(); - if (candidateElement instanceof PsiCallExpression) { - final PsiExpressionList argumentList = ((PsiCallExpression)candidateElement).getArgumentList(); - if (argumentList != null) { - final PsiExpression[] args = argumentList.getExpressions(); - for (PsiExpression arg : args) { - if (arg instanceof PsiFunctionalExpression) { - final PsiFunctionalExpression functionalExpression = (PsiFunctionalExpression)arg; - final PsiType functionalType = functionalExpression.getFunctionalInterfaceType(); - if (PsiUtil.resolveClassInType(functionalType) == aClass) { - if (!consumer.process(functionalExpression)) return false; - } - } - } - } - } - } - return true; - } - }); - if (!accepted) return false; - } - } + }; - for (final PsiReference reference : ReferencesSearch.search(aClass, scope)) { - boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable() { + final PsiSearchHelperImpl helper = (PsiSearchHelperImpl)PsiSearchHelper.SERVICE.getInstance(project); + helper.processFilesWithText(scope, UsageSearchContext.IN_CODE, true, "::", processor); + helper.processFilesWithText(scope, UsageSearchContext.IN_CODE, true, "->", processor); + + Collection files = processor.getResults(); + LOG.info("#files: " + files.size()); + + final PsiManager psiManager = PsiManager.getInstance(project); + for (final VirtualFile file : files) { + if (!ApplicationManager.getApplication().runReadAction(new Computable() { @Override public Boolean compute() { - final PsiElement element = reference.getElement(); - if (element != null) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiTypeElement) { - final PsiElement gParent = parent.getParent(); - if (gParent instanceof PsiVariable) { - final PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(((PsiVariable)gParent).getInitializer()); - if (initializer instanceof PsiFunctionalExpression) { - if (!consumer.process((PsiFunctionalExpression)initializer)) return false; - } - for (PsiReference varRef : ReferencesSearch.search(parent, scope)) { - final PsiElement varElement = varRef.getElement(); - if (varElement != null) { - final PsiElement varElementParent = varElement.getParent(); - if (varElementParent instanceof PsiAssignmentExpression && - ((PsiAssignmentExpression)varElementParent).getLExpression() == varElement) { - final PsiExpression rExpression = PsiUtil.skipParenthesizedExprDown(((PsiAssignmentExpression)varElementParent).getRExpression()); - if (rExpression instanceof PsiFunctionalExpression) { - if (!consumer.process((PsiFunctionalExpression)rExpression)) return false; - } - } - } - } - } else if (gParent instanceof PsiMethod) { - final PsiReturnStatement[] returnStatements = ApplicationManager.getApplication().runReadAction( - new Computable() { - @Override - public PsiReturnStatement[] compute() { - return PsiUtil.findReturnStatements((PsiMethod)gParent); - } - }); - for (PsiReturnStatement returnStatement : returnStatements) { - final PsiExpression returnValue = returnStatement.getReturnValue(); - if (returnValue instanceof PsiFunctionalExpression) { - if (!consumer.process((PsiFunctionalExpression)returnValue)) return false; - } - } - } + return processFileWithFunctionalInterfaces(aClass, consumer, psiManager, file); + } + })) return false; + } + return true; + } + + private static boolean processFileWithFunctionalInterfaces(final PsiClass aClass, + final Processor consumer, + final PsiManager psiManager, VirtualFile file) { + final PsiFile psiFile = psiManager.findFile(file); + if (psiFile != null) { + final Ref ref = new Ref(true); + psiFile.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitElement(PsiElement element) { + if (!ref.get()) { + return; + } + super.visitElement(element); + } + + private void visitFunctionalExpression(PsiFunctionalExpression expression) { + PsiType functionalInterfaceType = expression.getFunctionalInterfaceType(); + if (psiManager.areElementsEquivalent(PsiUtil.resolveClassInType(functionalInterfaceType), aClass)) { + if (!consumer.process(expression)) { + ref.set(false); } } + } - return true; + @Override + public void visitLambdaExpression(PsiLambdaExpression expression) { + super.visitLambdaExpression(expression); + visitFunctionalExpression(expression); + } + + @Override + public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { + super.visitMethodReferenceExpression(expression); + visitFunctionalExpression(expression); } }); - if (!accepted) return false; - + if (!ref.get()) return false; } return true; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java index 53033115a85c..06369c9f7379 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java @@ -50,7 +50,6 @@ import java.util.Set; * @author max */ public abstract class JavaMethodElementType extends JavaStubElementType { - public static final String TYPE_PARAMETER_PSEUDO_NAME = "$TYPE_PARAMETER$"; public JavaMethodElementType(@NonNls final String name) { super(name); } @@ -150,35 +149,5 @@ public abstract class JavaMethodElementType extends JavaStubElementType methodTypeParams = null; - for (StubElement stubElement : stub.getChildrenStubs()) { - if (stubElement instanceof PsiTypeParameterListStub) { - for (Object tStub : stubElement.getChildrenStubs()) { - if (tStub instanceof PsiTypeParameterStub) { - if (methodTypeParams == null) { - methodTypeParams = new HashSet(); - } - methodTypeParams.add(((PsiTypeParameterStub)tStub).getName()); - } - } - } - else if (stubElement instanceof PsiParameterListStub) { - for (StubElement paramStub : ((PsiParameterListStub)stubElement).getChildrenStubs()) { - if (paramStub instanceof PsiParameterStub) { - TypeInfo type = ((PsiParameterStub)paramStub).getType(false); - if (type.arrayCount > 0) continue; - String typeName = type.getShortTypeText(); - if (TypeConversionUtil.isPrimitive(typeName) || TypeConversionUtil.isPrimitiveWrapper(typeName)) continue; - sink.occurrence(JavaStubIndexKeys.METHOD_TYPES, typeName); - if (methodTypeParams != null && methodTypeParams.contains(typeName)) { - sink.occurrence(JavaStubIndexKeys.METHOD_TYPES, TYPE_PARAMETER_PSEUDO_NAME); - methodTypeParams = null; - } - } - } - break; - } - } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java index a3e247f73de8..e8760f5f95fa 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java @@ -29,7 +29,6 @@ public class JavaStubIndexKeys { public static final StubIndexKey JVM_STATIC_MEMBERS_NAMES = StubIndexKey.createIndexKey("jvm.static.member.name"); public static final StubIndexKey JVM_STATIC_MEMBERS_TYPES = StubIndexKey.createIndexKey("jvm.static.member.type"); public static final StubIndexKey ANONYMOUS_BASEREF = StubIndexKey.createIndexKey("java.anonymous.baseref"); - public static final StubIndexKey METHOD_TYPES = StubIndexKey.createIndexKey("java.method.parameter.types"); public static final StubIndexKey CLASS_SHORT_NAMES = StubIndexKey.createIndexKey("java.class.shortname"); public static final StubIndexKey CLASS_FQN = StubIndexKey.createIndexKey("java.class.fqn"); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java index eedf4abf13cb..cec30eb3c8af 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java @@ -38,7 +38,7 @@ import java.io.IOException; * @author max */ public class JavaFileElementType extends ILightStubFileElementType { - public static final int STUB_VERSION = 18; + public static final int STUB_VERSION = 19; public JavaFileElementType() { super("java.FILE", JavaLanguage.INSTANCE); diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java index e963ec91c2fc..a540080d95d9 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/impl/matcher/JavaMatchingVisitor.java @@ -420,7 +420,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor { (elements2 != null) ? elements2.getReferenceElements() : PsiElement.EMPTY_ARRAY ); } - + private boolean compareClasses(final PsiClass clazz, final PsiClass clazz2) { final PsiClass saveClazz = this.myClazz; final MatchContext.MatchedElementsListener oldListener = myMatchingVisitor.getMatchContext().getMatchedElementsListener(); @@ -838,6 +838,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor { String text2; if (el2 instanceof PsiClass) { text2 = ((PsiClass)el2).getQualifiedName(); + if (text2 == null) text2 = el2.getText(); } else { text2 = el2.getText(); } diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java index b20ddf0ff9ae..796ad663129a 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/runConfigurations/JpsRunConfigurationSerializer.java @@ -15,6 +15,7 @@ */ package org.jetbrains.jps.model.serialization.runConfigurations; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMUtil; import com.intellij.util.containers.hash.HashMap; import org.jdom.Element; @@ -31,6 +32,8 @@ import java.util.Map; * @author nik */ public class JpsRunConfigurationSerializer { + private static final Logger LOG = Logger.getInstance(JpsRunConfigurationSerializer.class); + public static void loadRunConfigurations(@NotNull JpsProject project, @Nullable Element runManagerTag) { Map> serializers = new HashMap>(); for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { @@ -50,9 +53,12 @@ public class JpsRunConfigurationSerializer { if (serializer != null) { loadRunConfiguration(name, configurationTag, serializer, project); } - else { + else if (typeId != null) { project.addRunConfiguration(name, new JpsUnknownRunConfigurationType(typeId), JpsElementFactory.getInstance().createDummyElement()); } + else { + LOG.info("Run configuration '" + name + "' wasn't loaded because 'type' attribute is missing"); + } } } diff --git a/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/invalid.xml b/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/invalid.xml new file mode 100644 index 000000000000..7e0f311245cf --- /dev/null +++ b/jps/model-serialization/testData/run-configurations-dir/.idea/runConfigurations/invalid.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/jps/model-serialization/testData/run-configurations/run-configurations.ipr b/jps/model-serialization/testData/run-configurations/run-configurations.ipr index 93c6bd97232b..e20908c8a349 100644 --- a/jps/model-serialization/testData/run-configurations/run-configurations.ipr +++ b/jps/model-serialization/testData/run-configurations/run-configurations.ipr @@ -45,6 +45,8 @@ + + diff --git a/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java index 8c17715d696c..d1c83ec03952 100644 --- a/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java +++ b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java @@ -54,7 +54,9 @@ public class JsonStandardComplianceInspection extends LocalInspectionTool { @Override public void visitComment(PsiComment comment) { if (myWarnAboutComments) { - holder.registerProblem(comment, JsonBundle.message("msg.compliance.problem.comments"), ProblemHighlightType.WEAK_WARNING); + if (JsonStandardComplianceProvider.shouldWarnAboutComment(comment)) { + holder.registerProblem(comment, JsonBundle.message("msg.compliance.problem.comments"), ProblemHighlightType.WEAK_WARNING); + } } } diff --git a/json/src/com/intellij/json/codeinsight/JsonStandardComplianceProvider.java b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceProvider.java new file mode 100644 index 000000000000..996cc82a6867 --- /dev/null +++ b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceProvider.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 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.json.codeinsight; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiComment; +import org.jetbrains.annotations.NotNull; + +/** + * Allows to configure a compliance level for JSON. + * For example, some tools ignore comments in JSON silently when parsing, so there is no need to warn users about it. + */ +public abstract class JsonStandardComplianceProvider { + public static final ExtensionPointName EP_NAME = + ExtensionPointName.create("com.intellij.json.jsonStandardComplianceProvider"); + + public abstract boolean isCommentAllowed(@NotNull PsiComment comment); + + public static boolean shouldWarnAboutComment(@NotNull PsiComment comment) { + JsonStandardComplianceProvider[] providers = EP_NAME.getExtensions(); + if (providers.length == 0) { + return true; + } + for (JsonStandardComplianceProvider provider : providers) { + if (provider.isCommentAllowed(comment)) { + return false; + } + } + return true; + } +} diff --git a/platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java b/platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java index 9b74576176fb..832ce58167a2 100644 --- a/platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java +++ b/platform/core-api/src/com/intellij/openapi/util/SimpleModificationTracker.java @@ -23,14 +23,14 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; /** * Created by Max Medvedev on 28/03/14 */ +@Transient public class SimpleModificationTracker implements ModificationTracker { static { // field made public to workaround bug in JDK7 when AtomicIntegerFieldUpdater can't be created for private field, even from within its own class // fixed in JDK8 assert Patches.JDK_BUG_ID_7103570; } - - @Transient + public volatile int myCounter; @Override diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java index ff563a51b97e..17a4ea41eb30 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/colors/EditorColors.java @@ -61,5 +61,7 @@ public interface EditorColors { ColorKey MODIFIED_LINES_COLOR = ColorKey.createColorKey("MODIFIED_LINES_COLOR"); ColorKey DELETED_LINES_COLOR = ColorKey.createColorKey("DELETED_LINES_COLOR"); ColorKey WHITESPACES_MODIFIED_LINES_COLOR = ColorKey.createColorKey("WHITESPACES_MODIFIED_LINES_COLOR"); + ColorKey BORDER_LINES_COLOR = ColorKey.createColorKey("BORDER_LINES_COLOR"); + TextAttributesKey INJECTED_LANGUAGE_FRAGMENT = TextAttributesKey.createTextAttributesKey("INJECTED_LANGUAGE_FRAGMENT"); } diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java index af193348c71b..aed1ccf7277f 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java @@ -91,7 +91,7 @@ public class IdIndex extends FileBasedIndexExtension { @Override public int getVersion() { - return 13 + (ourSnapshotMappingsEnabled ? 0xFF:0); // TODO: version should enumerate all word scanner versions and build version upon that set + return 14 + (ourSnapshotMappingsEnabled ? 0xFF:0); // TODO: version should enumerate all word scanner versions and build version upon that set } @Override diff --git a/platform/lang-api/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java b/platform/lang-api/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java index 16b4d3a18c9b..9f640fb6a5b3 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/ModuleBasedConfiguration.java @@ -24,6 +24,7 @@ import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.util.xmlb.annotations.Property; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -39,7 +40,10 @@ import java.util.Set; */ public abstract class ModuleBasedConfiguration extends LocatableConfigurationBase implements Cloneable, ModuleRunConfiguration { private static final Logger LOG = Logger.getInstance("#com.intellij.execution.configurations.ModuleBasedConfiguration"); + + @Property(surroundWithTag = false) private final ConfigurationModule myModule; + @NonNls protected static final String TO_CLONE_ELEMENT_NAME = "toClone"; diff --git a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationModule.java b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationModule.java index 189696892b66..21292428f11d 100644 --- a/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationModule.java +++ b/platform/lang-api/src/com/intellij/execution/configurations/RunConfigurationModule.java @@ -26,6 +26,9 @@ import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.JDOMExternalizable; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.xmlb.annotations.Attribute; +import com.intellij.util.xmlb.annotations.Tag; +import com.intellij.util.xmlb.annotations.Transient; import org.jdom.Element; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -33,6 +36,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; +@Tag("module") public class RunConfigurationModule implements JDOMExternalizable { private static final Logger LOG = Logger.getInstance(RunConfigurationModule.class); @@ -40,7 +44,10 @@ public class RunConfigurationModule implements JDOMExternalizable { @NonNls private static final String ATTRIBUTE = "name"; private Module myModule = null; + + @Attribute("name") private String myModuleName; + private final Project myProject; public RunConfigurationModule(@NotNull Project project) { @@ -81,6 +88,7 @@ public class RunConfigurationModule implements JDOMExternalizable { } @Nullable + @Transient public Module getModule() { if (myModuleName != null) { //caching myModule = findModule(myModuleName); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java index b83d832f8348..38063e097f0d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java @@ -39,6 +39,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ListCellRendererWrapper; @@ -329,12 +330,26 @@ public class ImplementationViewComponent extends JPanel { if (element instanceof PsiNamedElement) { names.add(((PsiNamedElement)element).getName()); } + if (names.size() > 1) { + break; + } } + for (PsiElement element : elements) { PsiFile file = getContainingFile(element); if (file == null) continue; - final PsiElement parent = element.getParent(); - files.add(new FileDescriptor(file, names.size() > 1 || parent == file ? element : parent)); + if (names.size() > 1) { + files.add(new FileDescriptor(file, element)); + } + else { + final PsiElement parent = PsiTreeUtil.getStubOrPsiParent(element); + if (parent == file) { + files.add(new FileDescriptor(file, element)); + } + else { + files.add(new FileDescriptor(file, parent)); + } + } candidates.add(element); } diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java index 9b354805211b..f5c06224f8c7 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/ChooseByNameBase.java @@ -1192,6 +1192,10 @@ public abstract class ChooseByNameBase { myPostponedOkAction = null; } + public boolean hasPostponedAction() { + return myPostponedOkAction != null; + } + protected abstract void showList(); protected abstract void hideList(); diff --git a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java index 8ab353f7bc14..c0dd305dfb16 100644 --- a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java +++ b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java @@ -122,6 +122,7 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.modified.lines"), EditorColors.MODIFIED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND), new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.deleted.lines"), EditorColors.DELETED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND), new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.whitespaces.modified.lines"), EditorColors.WHITESPACES_MODIFIED_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND), + new ColorDescriptor(OptionsBundle.message("options.general.color.descriptor.border.lines"), EditorColors.BORDER_LINES_COLOR, ColorDescriptor.Kind.BACKGROUND), new ColorDescriptor(OptionsBundle.message("options.java.color.descriptor.method.separator.color"), CodeInsightColors.METHOD_SEPARATORS_COLOR, ColorDescriptor.Kind.FOREGROUND), new ColorDescriptor(OptionsBundle.message("options.general.color.soft.wrap.sign"), EditorColors.SOFT_WRAP_SIGN_COLOR, ColorDescriptor.Kind.FOREGROUND), }; diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties index 1906440c7ecc..e2475e4e5b8b 100644 --- a/platform/platform-resources-en/src/messages/OptionsBundle.properties +++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties @@ -126,10 +126,11 @@ options.general.color.descriptor.vcs.annotations=VCS annotations options.general.color.descriptor.vcs.annotations.merged=VCS annotations (merged from) options.general.color.descriptor.tearline=Tear line options.general.color.descriptor.tearline.selected=Selected tear line -options.general.color.descriptor.added.lines=Added lines -options.general.color.descriptor.modified.lines=Modified lines -options.general.color.descriptor.deleted.lines=Deleted lines -options.general.color.descriptor.whitespaces.modified.lines=Minor modified lines +options.general.color.descriptor.added.lines=Added lines in gutter +options.general.color.descriptor.modified.lines=Modified lines in gutter +options.general.color.descriptor.deleted.lines=Deleted lines in gutter +options.general.color.descriptor.whitespaces.modified.lines=Minor modified lines in gutter +options.general.color.descriptor.border.lines=Border for changed lines in gutter options.general.color.descriptor.console.background=Console background options.general.color.descriptor.console.stdout=Console standard output options.general.color.descriptor.console.stderr=Console error output diff --git a/platform/platform-resources/src/META-INF/JsonPlugin.xml b/platform/platform-resources/src/META-INF/JsonPlugin.xml index deeec3ad3fa2..c3d643a5d1da 100644 --- a/platform/platform-resources/src/META-INF/JsonPlugin.xml +++ b/platform/platform-resources/src/META-INF/JsonPlugin.xml @@ -58,4 +58,10 @@ implementationClass="com.intellij.json.psi.JsonStringLiteralManipulator"/> + + + + + \ No newline at end of file diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java b/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java index 64558ddc5889..99eec952f1d9 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java @@ -57,6 +57,7 @@ public interface FileIndex { /** * Returns true if file is a source file which belongs to sources of the content. + * (Returns true for both source and test source).

* Note that sometimes a file can belong to the content and be a source file but not belong to sources of the content. * This happens if sources of some library are located under the content (so they belong to the project content but not as sources). * diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java index fdae3317e74e..d47f640926d5 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/ProjectFileIndex.java @@ -125,7 +125,7 @@ public interface ProjectFileIndex extends FileIndex { boolean isLibraryClassFile(@NotNull VirtualFile file); /** - * Returns true if fileOrDir is a file or directory from the content source or library sources. + * Returns true if fileOrDir is a file or directory from the content production/test source or library source. * * @param fileOrDir the file or directory to check. * @return true if the file or directory belongs to project or library sources, false otherwise. diff --git a/platform/util/src/com/intellij/ui/JBColor.java b/platform/util/src/com/intellij/ui/JBColor.java index cd204b3c00d8..3669e725610d 100644 --- a/platform/util/src/com/intellij/ui/JBColor.java +++ b/platform/util/src/com/intellij/ui/JBColor.java @@ -250,11 +250,23 @@ public class JBColor extends Color { public static final Color CYAN = cyan; public static Color foreground() { - return UIUtil.getLabelForeground(); + return new JBColor(new NotNullProducer() { + @NotNull + @Override + public Color produce() { + return UIUtil.getLabelForeground(); + } + }); } public static Color background() { - return UIUtil.getListBackground(); + return new JBColor(new NotNullProducer() { + @NotNull + @Override + public Color produce() { + return UIUtil.getListBackground(); + } + }); } public static Color border() { diff --git a/platform/util/src/com/intellij/util/containers/LinkedMultiMap.java b/platform/util/src/com/intellij/util/containers/LinkedMultiMap.java index 9c780bc804fc..b778e4c63f2b 100644 --- a/platform/util/src/com/intellij/util/containers/LinkedMultiMap.java +++ b/platform/util/src/com/intellij/util/containers/LinkedMultiMap.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.containers; import com.intellij.util.containers.hash.LinkedHashMap; @@ -26,15 +25,15 @@ import java.util.Map; * @author Evgeny Gerashchenko */ public class LinkedMultiMap extends MultiMap { - @NotNull - @Override - protected Map> createMap() { - return new LinkedHashMap>(); - } + @NotNull + @Override + protected Map> createMap() { + return new LinkedHashMap>(); + } - @NotNull - @Override - protected Map> createMap(int initialCapacity, float loadFactor) { - return new LinkedHashMap>(initialCapacity, loadFactor); - } + @NotNull + @Override + protected Map> createMap(int initialCapacity, float loadFactor) { + return new LinkedHashMap>(initialCapacity, loadFactor); + } } diff --git a/platform/util/src/com/intellij/util/containers/MultiMap.java b/platform/util/src/com/intellij/util/containers/MultiMap.java index acd97a51268a..f14303607c26 100644 --- a/platform/util/src/com/intellij/util/containers/MultiMap.java +++ b/platform/util/src/com/intellij/util/containers/MultiMap.java @@ -63,7 +63,7 @@ public class MultiMap implements Serializable { @NotNull protected Collection createCollection() { - return new ArrayList(); + return new SmartList(); } @NotNull @@ -261,12 +261,6 @@ public class MultiMap implements Serializable { protected Map> createMap() { return new THashMap>(strategy); } - - @NotNull - @Override - protected Collection createCollection() { - return new SmartList(); - } }; } @@ -289,12 +283,6 @@ public class MultiMap implements Serializable { @NotNull public static MultiMap createSmartList() { return new MultiMap() { - @NotNull - @Override - protected Collection createCollection() { - return new SmartList(); - } - @NotNull @Override protected Map> createMap() { diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 893eb1d636b3..97352ca3ef1a 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -25,7 +25,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.ui.*; import com.intellij.util.*; -import com.intellij.util.containers.*; +import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.WeakHashMap; import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NonNls; @@ -75,7 +75,6 @@ import java.lang.reflect.Method; import java.net.URL; import java.text.NumberFormat; import java.util.*; -import java.util.HashMap; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -680,11 +679,11 @@ public class UIUtil { } public static Color getLabelBackground() { - return getColor("Label.background"); + return UIManager.getColor("Label.background"); } public static Color getLabelForeground() { - return getColor("Label.foreground"); + return UIManager.getColor("Label.foreground"); } public static Color getLabelDisabledForeground() { @@ -734,11 +733,11 @@ public class UIUtil { } public static Color getTableHeaderBackground() { - return getColor("TableHeader.background"); + return UIManager.getColor("TableHeader.background"); } public static Color getTreeTextForeground() { - return getColor("Tree.textForeground"); + return UIManager.getColor("Tree.textForeground"); } public static Color getTreeSelectionBackground() { @@ -748,22 +747,23 @@ public class UIUtil { color = UIManager.getColor("nimbusSelectionBackground"); if (color != null) return color; } - return getColor("Tree.selectionBackground"); + return UIManager.getColor("Tree.selectionBackground"); } public static Color getTreeTextBackground() { - return getColor("Tree.textBackground"); + return UIManager.getColor("Tree.textBackground"); } public static Color getListSelectionForeground() { - if (isUnderNimbusLookAndFeel()) { + final Color color = UIManager.getColor("List.selectionForeground"); + if (color == null) { return UIManager.getColor("List[Selected].textForeground"); // Nimbus } - return getColor("List.selectionForeground"); + return color; } public static Color getFieldForegroundColor() { - return getColor("field.foreground"); + return UIManager.getColor("field.foreground"); } public static Color getTableSelectionBackground() { @@ -773,23 +773,11 @@ public class UIUtil { color = UIManager.getColor("nimbusSelectionBackground"); if (color != null) return color; } - return getColor("Table.selectionBackground"); + return UIManager.getColor("Table.selectionBackground"); } public static Color getActiveTextColor() { - return getColor("textActiveText"); - } - - @NotNull - private static Color getColor(final String property) { - return new JBColor(new NotNullProducer() { - @NotNull - @Override - public Color produce() { - final Color color = UIManager.getColor(property); - return color == null ? Gray.TRANSPARENT : color; - } - }); + return UIManager.getColor("textActiveText"); } public static Color getInactiveTextColor() { @@ -809,7 +797,7 @@ public class UIUtil { } public static Color getInactiveTextFieldBackgroundColor() { - return getColor("TextField.inactiveBackground"); + return UIManager.getColor("TextField.inactiveBackground"); } public static Font getTreeFont() { @@ -821,7 +809,7 @@ public class UIUtil { } public static Color getTreeSelectionForeground() { - return getColor("Tree.selectionForeground"); + return UIManager.getColor("Tree.selectionForeground"); } /** @@ -840,7 +828,7 @@ public class UIUtil { } public static Color getTreeSelectionBorderColor() { - return getColor("Tree.selectionBorderColor"); + return UIManager.getColor("Tree.selectionBorderColor"); } public static int getTreeRightChildIndent() { @@ -852,23 +840,23 @@ public class UIUtil { } public static Color getToolTipBackground() { - return getColor("ToolTip.background"); + return UIManager.getColor("ToolTip.background"); } public static Color getToolTipForeground() { - return getColor("ToolTip.foreground"); + return UIManager.getColor("ToolTip.foreground"); } public static Color getComboBoxDisabledForeground() { - return getColor("ComboBox.disabledForeground"); + return UIManager.getColor("ComboBox.disabledForeground"); } public static Color getComboBoxDisabledBackground() { - return getColor("ComboBox.disabledBackground"); + return UIManager.getColor("ComboBox.disabledBackground"); } public static Color getButtonSelectColor() { - return getColor("Button.select"); + return UIManager.getColor("Button.select"); } public static Integer getPropertyMaxGutterIconWidth(final String propertyPrefix) { @@ -876,7 +864,7 @@ public class UIUtil { } public static Color getMenuItemDisabledForeground() { - return getColor("MenuItem.disabledForeground"); + return UIManager.getColor("MenuItem.disabledForeground"); } public static Object getMenuItemDisabledForegroundObject() { @@ -893,7 +881,7 @@ public class UIUtil { public static Color getTableBackground() { // Under GTK+ L&F "Table.background" often has main panel color, which looks ugly - return isUnderGTKLookAndFeel() ? getTreeTextBackground() : getColor("Table.background"); + return isUnderGTKLookAndFeel() ? getTreeTextBackground() : UIManager.getColor("Table.background"); } public static Color getTableBackground(final boolean isSelected) { @@ -904,11 +892,11 @@ public class UIUtil { if (isUnderNimbusLookAndFeel()) { return UIManager.getColor("Table[Enabled+Selected].textForeground"); } - return getColor("Table.selectionForeground"); + return UIManager.getColor("Table.selectionForeground"); } public static Color getTableForeground() { - return getColor("Table.foreground"); + return UIManager.getColor("Table.foreground"); } public static Color getTableForeground(final boolean isSelected) { @@ -916,7 +904,7 @@ public class UIUtil { } public static Color getTableGridColor() { - return getColor("Table.gridColor"); + return UIManager.getColor("Table.gridColor"); } public static Color getListBackground() { @@ -926,7 +914,7 @@ public class UIUtil { return new Color(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); } // Under GTK+ L&F "Table.background" often has main panel color, which looks ugly - return isUnderGTKLookAndFeel() ? getTreeTextBackground() : getColor("List.background"); + return isUnderGTKLookAndFeel() ? getTreeTextBackground() : UIManager.getColor("List.background"); } public static Color getListBackground(boolean isSelected) { @@ -934,7 +922,7 @@ public class UIUtil { } public static Color getListForeground() { - return getColor("List.foreground"); + return UIManager.getColor("List.foreground"); } public static Color getListForeground(boolean isSelected) { @@ -942,26 +930,26 @@ public class UIUtil { } public static Color getPanelBackground() { - return getColor("Panel.background"); + return UIManager.getColor("Panel.background"); } public static Color getTreeBackground() { - return getColor("Tree.background"); + return UIManager.getColor("Tree.background"); } public static Color getTreeForeground() { - return getColor("Tree.foreground"); + return UIManager.getColor("Tree.foreground"); } public static Color getTableFocusCellBackground() { - return getColor(TABLE_FOCUS_CELL_BACKGROUND_PROPERTY); + return UIManager.getColor(TABLE_FOCUS_CELL_BACKGROUND_PROPERTY); } public static Color getListSelectionBackground() { if (isUnderNimbusLookAndFeel()) { return UIManager.getColor("List[Selected].textBackground"); // Nimbus } - return getColor("List.selectionBackground"); + return UIManager.getColor("List.selectionBackground"); } public static Color getListUnfocusedSelectionBackground() { @@ -978,11 +966,11 @@ public class UIUtil { } public static Color getTextFieldForeground() { - return getColor("TextField.foreground"); + return UIManager.getColor("TextField.foreground"); } public static Color getTextFieldBackground() { - return isUnderGTKLookAndFeel() ? UIManager.getColor("EditorPane.background") : getColor("TextField.background"); + return isUnderGTKLookAndFeel() ? UIManager.getColor("EditorPane.background") : UIManager.getColor("TextField.background"); } public static Font getButtonFont() { @@ -994,7 +982,7 @@ public class UIUtil { } public static Color getTabbedPaneBackground() { - return getColor("TabbedPane.background"); + return UIManager.getColor("TabbedPane.background"); } public static void setSliderIsFilled(final JSlider slider, final boolean value) { @@ -1002,11 +990,11 @@ public class UIUtil { } public static Color getLabelTextForeground() { - return getColor("Label.textForeground"); + return UIManager.getColor("Label.textForeground"); } public static Color getControlColor() { - return getColor("control"); + return UIManager.getColor("control"); } public static Font getOptionPaneMessageFont() { @@ -1018,19 +1006,19 @@ public class UIUtil { } public static Color getSeparatorForeground() { - return getColor("Separator.foreground"); + return UIManager.getColor("Separator.foreground"); } public static Color getSeparatorBackground() { - return getColor("Separator.background"); + return UIManager.getColor("Separator.background"); } public static Color getSeparatorShadow() { - return getColor("Separator.shadow"); + return UIManager.getColor("Separator.shadow"); } public static Color getSeparatorHighlight() { - return getColor("Separator.highlight"); + return UIManager.getColor("Separator.highlight"); } public static Color getSeparatorColorUnderNimbus() { @@ -1065,7 +1053,7 @@ public class UIUtil { } public static Color getTableFocusCellForeground() { - return getColor("Table.focusCellForeground"); + return UIManager.getColor("Table.focusCellForeground"); } /** @@ -1160,15 +1148,15 @@ public class UIUtil { } public static Color getWindowColor() { - return getColor("window"); + return UIManager.getColor("window"); } public static Color getTextAreaForeground() { - return getColor("TextArea.foreground"); + return UIManager.getColor("TextArea.foreground"); } public static Color getOptionPaneBackground() { - return getColor("OptionPane.background"); + return UIManager.getColor("OptionPane.background"); } @SuppressWarnings({"HardCodedStringLiteral"}) diff --git a/platform/util/src/com/intellij/util/xmlb/Accessor.java b/platform/util/src/com/intellij/util/xmlb/Accessor.java index 02c007ffb85a..7e364b9b6105 100644 --- a/platform/util/src/com/intellij/util/xmlb/Accessor.java +++ b/platform/util/src/com/intellij/util/xmlb/Accessor.java @@ -39,4 +39,6 @@ public interface Accessor { Class getValueClass(); Type getGenericType(); + + boolean isFinal(); } diff --git a/platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java b/platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java index e071b6b915ec..c5be1e8f7e31 100644 --- a/platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java +++ b/platform/util/src/com/intellij/util/xmlb/AccessorBindingWrapper.java @@ -15,6 +15,7 @@ */ package com.intellij.util.xmlb; +import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,9 +42,14 @@ class AccessorBindingWrapper implements Binding { @Nullable public Object deserialize(Object context, @NotNull Object... nodes) { Object currentValue = myAccessor.read(context); - Object deserializedValue = myBinding.deserialize(currentValue, nodes); - if (currentValue != deserializedValue) { - myAccessor.write(context, deserializedValue); + if (myBinding instanceof BeanBinding && myAccessor.isFinal()) { + ((BeanBinding)myBinding).deserializeInto(currentValue, (Element)nodes[0], null); + } + else { + Object deserializedValue = myBinding.deserialize(currentValue, nodes); + if (currentValue != deserializedValue) { + myAccessor.write(context, deserializedValue); + } } return context; } diff --git a/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java b/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java index 578b9e12eb7b..c3cbeae595f3 100644 --- a/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/AttributeBinding.java @@ -86,4 +86,8 @@ public class AttributeBinding extends BasePrimitiveBinding { throw new XmlSerializationException("Can't use attribute binding for non-text content: " + myAccessor); } } + + public String toString() { + return "AttributeBinding[" + myName + ", binding=" + myBinding + "]"; + } } diff --git a/platform/util/src/com/intellij/util/xmlb/BeanBinding.java b/platform/util/src/com/intellij/util/xmlb/BeanBinding.java index c9078e63b009..7f7022e48c0e 100644 --- a/platform/util/src/com/intellij/util/xmlb/BeanBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/BeanBinding.java @@ -28,6 +28,7 @@ import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.util.xmlb.annotations.*; +import gnu.trove.TObjectDoubleHashMap; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,9 +38,8 @@ import java.beans.Introspector; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.*; import java.util.List; -import java.util.Map; -import java.util.Set; class BeanBinding implements Binding { private static final Logger LOG = Logger.getInstance(BeanBinding.class); @@ -81,23 +81,26 @@ class BeanBinding implements Binding { @Nullable public Element serializeInto(@NotNull Object o, @Nullable Element element, @NotNull SerializationFilter filter) { - for (Binding binding : myPropertyBindings.keySet()) { + return serializeInto(o, element, filter, myPropertyBindings.keySet()); + } + + @Nullable + Element serializeInto(@NotNull Object o, @Nullable Element element, @NotNull SerializationFilter filter, @Nullable Collection bindings) { + for (Binding binding : (bindings == null ? myPropertyBindings.keySet() : bindings)) { Accessor accessor = myPropertyBindings.get(binding); + if (accessor == null) { + LOG.warn("Illegal state: accessor null, " + binding.toString()); + continue; + } if (!filter.accepts(accessor, o)) { continue; } //todo: optimize. Cache it. Property property = accessor.getAnnotation(Property.class); - if (property != null && property.filter() != SerializationFilter.class) { - try { - if (!ReflectionUtil.newInstance(property.filter()).accepts(accessor, o)) { - continue; - } - } - catch (RuntimeException e) { - throw new XmlSerializationException(e); - } + if (property != null && property.filter() != SerializationFilter.class && + !ReflectionUtil.newInstance(property.filter()).accepts(accessor, o)) { + continue; } if (element == null) { @@ -130,14 +133,48 @@ class BeanBinding implements Binding { if (element == null) { return o; } - Object instance = XmlSerializerImpl.newInstance(myBeanClass); + Object instance = ReflectionUtil.newInstance(myBeanClass); deserializeInto(instance, element, null); return instance; } + @NotNull + List computeOrderedBindings(@NotNull LinkedHashSet accessorNameTracker) { + final TObjectDoubleHashMap weights = new TObjectDoubleHashMap(accessorNameTracker.size()); + double weight = 0; + double step = (double)myPropertyBindings.size() / (double)accessorNameTracker.size(); + for (String name : accessorNameTracker) { + weights.put(name, weight); + weight += step; + } + + weight = 0; + for (Accessor accessor : myPropertyBindings.values()) { + String name = accessor.getName(); + if (!weights.containsKey(name)) { + weights.put(name, weight); + } + + weight++; + } + + Binding[] result = myPropertyBindings.keySet().toArray(new Binding[myPropertyBindings.size()]); + Arrays.sort(result, new Comparator() { + @Override + public int compare(@NotNull Binding o1, @NotNull Binding o2) { + String n1 = myPropertyBindings.get(o1).getName(); + String n2 = myPropertyBindings.get(o2).getName(); + double w1 = weights.get(n1); + double w2 = weights.get(n2); + return (int)(w1 - w2); + } + }); + return Arrays.asList(result); + } + public void deserializeInto(@NotNull Object result, @NotNull Element element, @Nullable Set accessorNameTracker) { Set bindings = myPropertyBindings.keySet(); - MultiMap data = MultiMap.createSmartList(); + MultiMap data = MultiMap.createLinked(); nextNode: for (Object child : ContainerUtil.concat(element.getContent(), element.getAttributes())) { if (XmlSerializerImpl.isIgnoredNode(child)) { @@ -244,15 +281,25 @@ class BeanBinding implements Binding { } } - private static void collectFieldAccessors(Class aClass, List accessors) { - for (Field field : aClass.getFields()) { - final int modifiers = field.getModifiers(); - if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) && - !Modifier.isFinal(modifiers) && !Modifier.isTransient(modifiers) && - field.getAnnotation(Transient.class) == null) { - accessors.add(new FieldAccessor(field)); + private static void collectFieldAccessors(@NotNull Class aClass, @NotNull List accessors) { + Class currentClass = aClass; + do { + for (Field field : currentClass.getDeclaredFields()) { + int modifiers = field.getModifiers(); + if (!Modifier.isStatic(modifiers) && + (field.getAnnotation(OptionTag.class) != null || + field.getAnnotation(Tag.class) != null || + field.getAnnotation(Attribute.class) != null || + field.getAnnotation(Property.class) != null || + (Modifier.isPublic(modifiers) && + !Modifier.isFinal(modifiers) && + !Modifier.isTransient(modifiers) && + field.getAnnotation(Transient.class) == null))) { + accessors.add(new FieldAccessor(field)); + } } } + while ((currentClass = currentClass.getSuperclass()) != null && currentClass.getAnnotation(Transient.class) == null); } @Nullable diff --git a/platform/util/src/com/intellij/util/xmlb/FieldAccessor.java b/platform/util/src/com/intellij/util/xmlb/FieldAccessor.java index 172b5e364825..c7fd18abad65 100644 --- a/platform/util/src/com/intellij/util/xmlb/FieldAccessor.java +++ b/platform/util/src/com/intellij/util/xmlb/FieldAccessor.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.lang.reflect.Type; class FieldAccessor implements Accessor { @@ -81,6 +82,11 @@ class FieldAccessor implements Accessor { return myField.getGenericType(); } + @Override + public boolean isFinal() { + return Modifier.isFinal(myField.getModifiers()); + } + @NonNls public String toString() { return "FieldAccessor[" + myField.getDeclaringClass() + "." + myField.getName() + "]"; diff --git a/platform/util/src/com/intellij/util/xmlb/PrimitiveValueBinding.java b/platform/util/src/com/intellij/util/xmlb/PrimitiveValueBinding.java index 3c303b07b410..84e94ef4c216 100644 --- a/platform/util/src/com/intellij/util/xmlb/PrimitiveValueBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/PrimitiveValueBinding.java @@ -16,6 +16,8 @@ package com.intellij.util.xmlb; import com.intellij.openapi.util.JDOMUtil; +import org.jdom.Attribute; +import org.jdom.Content; import org.jdom.Text; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,8 +46,8 @@ class PrimitiveValueBinding implements Binding { value = JDOMUtil.concatTextNodesValues(nodes); } else { - assert nodes[0] != null; - value = JDOMUtil.getValue(nodes[0]); + Object node = nodes[0]; + value = node instanceof Attribute ? ((Attribute)node).getValue() : ((Content)node).getValue(); } return convertString(value); } diff --git a/platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java b/platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java index 9bef1ab7bf8a..9780e683154d 100644 --- a/platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java +++ b/platform/util/src/com/intellij/util/xmlb/PropertyAccessor.java @@ -110,6 +110,11 @@ class PropertyAccessor implements Accessor { return myGenericType; } + @Override + public boolean isFinal() { + return false; + } + @NonNls public String toString() { return "PropertyAccessor[" + myReadMethod.getDeclaringClass().getName() + "." + getName() +"]"; diff --git a/platform/util/src/com/intellij/util/xmlb/SkipEmptySerializationFilter.java b/platform/util/src/com/intellij/util/xmlb/SkipEmptySerializationFilter.java index 4a98cf7a5cb8..aec1ab68e74a 100644 --- a/platform/util/src/com/intellij/util/xmlb/SkipEmptySerializationFilter.java +++ b/platform/util/src/com/intellij/util/xmlb/SkipEmptySerializationFilter.java @@ -36,8 +36,8 @@ public class SkipEmptySerializationFilter extends SerializationFilterBase { if (Boolean.FALSE.equals(beanValue) || (beanValue instanceof String && ((String)beanValue).isEmpty()) || - (beanValue instanceof Map && ((Map)beanValue).isEmpty()) || - (beanValue instanceof Collection && ((Collection)beanValue).isEmpty())) { + beanValue instanceof Collection && ((Collection)beanValue).isEmpty() || + (beanValue instanceof Map && ((Map)beanValue).isEmpty())) { return false; } diff --git a/platform/util/src/com/intellij/util/xmlb/SmartSerializer.java b/platform/util/src/com/intellij/util/xmlb/SmartSerializer.java index dd6a7cb916d3..805934e3c76e 100644 --- a/platform/util/src/com/intellij/util/xmlb/SmartSerializer.java +++ b/platform/util/src/com/intellij/util/xmlb/SmartSerializer.java @@ -16,19 +16,20 @@ package com.intellij.util.xmlb; import com.intellij.util.ThreeState; -import gnu.trove.THashSet; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Set; +import java.util.LinkedHashSet; +import java.util.List; public final class SmartSerializer { - private final Set mySerializedAccessorNameTracker; + private final LinkedHashSet mySerializedAccessorNameTracker; + private List myOrderedBindings; private final SerializationFilter mySerializationFilter; public SmartSerializer(boolean trackSerializedNames, boolean useSkipEmptySerializationFilter) { - mySerializedAccessorNameTracker = trackSerializedNames ? new THashSet() : null; + mySerializedAccessorNameTracker = trackSerializedNames ? new LinkedHashSet() : null; mySerializationFilter = useSkipEmptySerializationFilter ? new SkipEmptySerializationFilter() { @@ -56,10 +57,16 @@ public final class SmartSerializer { if (mySerializedAccessorNameTracker != null) { mySerializedAccessorNameTracker.clear(); } - XmlSerializer.deserializeInto(bean, element, mySerializedAccessorNameTracker); + + BeanBinding beanBinding = (BeanBinding)XmlSerializerImpl.getBinding(bean.getClass()); + beanBinding.deserializeInto(bean, element, mySerializedAccessorNameTracker); + + if (mySerializedAccessorNameTracker != null) { + myOrderedBindings = beanBinding.computeOrderedBindings(mySerializedAccessorNameTracker); + } } public void writeExternal(@NotNull Object bean, @NotNull Element element) { - XmlSerializer.serializeInto(bean, element, mySerializationFilter); + ((BeanBinding)XmlSerializerImpl.getBinding(bean.getClass())).serializeInto(bean, element, mySerializationFilter, myOrderedBindings); } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/xmlb/TagBinding.java b/platform/util/src/com/intellij/util/xmlb/TagBinding.java index 78336be646fe..37b013b5333d 100644 --- a/platform/util/src/com/intellij/util/xmlb/TagBinding.java +++ b/platform/util/src/com/intellij/util/xmlb/TagBinding.java @@ -16,6 +16,7 @@ package com.intellij.util.xmlb; import com.intellij.openapi.util.JDOMUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.SmartList; import com.intellij.util.xmlb.annotations.Tag; @@ -25,6 +26,7 @@ import org.jdom.Text; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; class TagBinding extends BasePrimitiveBinding { @@ -33,7 +35,7 @@ class TagBinding extends BasePrimitiveBinding { public TagBinding(@NotNull Accessor accessor, @NotNull Tag tagAnnotation) { super(accessor, tagAnnotation.value(), null); - myTextIfEmpty = tagAnnotation.textIfEmpty(); + myTextIfEmpty = StringUtil.nullize(tagAnnotation.textIfEmpty()); } @Nullable @@ -57,28 +59,35 @@ class TagBinding extends BasePrimitiveBinding { @Nullable public Object deserialize(Object o, @NotNull Object... nodes) { assert nodes.length > 0; - Object[] children; + List children; + boolean isBeanBinding = myBinding instanceof BeanBinding; if (nodes.length == 1) { - children = JDOMUtil.getContent((Element)nodes[0]); + Element node = (Element)nodes[0]; + children = isBeanBinding ? node.getChildren() : node.getContent(); } else { String name = ((Element)nodes[0]).getName(); - List childrenList = new SmartList(); + children = new SmartList(); for (Object node : nodes) { - assert ((Element)node).getName().equals(name); - childrenList.addAll(((Element)node).getContent()); + Element element = (Element)node; + assert element.getName().equals(name); + //noinspection unchecked + children.addAll(((List)(isBeanBinding ? element.getChildren() : element.getContent()))); } - children = ArrayUtil.toObjectArray(childrenList); - } - - if (children.length == 0) { - children = new Object[] {new Text(myTextIfEmpty)}; } assert myBinding != null; - Object v = myBinding.deserialize(myAccessor.read(o), children); - Object value = XmlSerializerImpl.convert(v, myAccessor.getValueClass()); - myAccessor.write(o, value); + if (isBeanBinding && myAccessor.isFinal()) { + ((BeanBinding)myBinding).deserializeInto(o, (Element)children.get(0), null); + } + else { + if (children.isEmpty() && myTextIfEmpty != null) { + children = Collections.singletonList(new Text(myTextIfEmpty)); + } + + Object v = myBinding.deserialize(myAccessor.read(o), ArrayUtil.toObjectArray(children)); + myAccessor.write(o, XmlSerializerImpl.convert(v, myAccessor.getValueClass())); + } return o; } diff --git a/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java b/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java index ee16d1270500..fafaaaa93442 100644 --- a/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java +++ b/platform/util/src/com/intellij/util/xmlb/XmlSerializerImpl.java @@ -26,6 +26,7 @@ import java.lang.annotation.Annotation; import java.lang.ref.SoftReference; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -72,7 +73,18 @@ class XmlSerializerImpl { } static Binding getTypeBinding(@NotNull Type type, @Nullable Accessor accessor) { - return _getClassBinding(type instanceof Class ? (Class)type : (Class)((ParameterizedType)type).getRawType(), type, accessor); + Class aClass; + if (type instanceof Class) { + aClass = (Class)type; + } + else if (type instanceof TypeVariable) { + Type bound = ((TypeVariable)type).getBounds()[0]; + aClass = bound instanceof Class ? (Class)bound : (Class)((ParameterizedType)bound).getRawType(); + } + else { + aClass = (Class)((ParameterizedType)type).getRawType(); + } + return _getClassBinding(aClass, type, accessor); } private static synchronized Binding _getClassBinding(@NotNull Class aClass, @NotNull Type originalType, @Nullable Accessor accessor) { diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java index 0f7217c5241e..a5b8edc491aa 100644 --- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java +++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java @@ -24,9 +24,11 @@ import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.intellij.lang.annotations.Language; import org.jdom.Element; +import org.jdom.JDOMException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.*; import java.util.concurrent.atomic.AtomicReference; @@ -1219,6 +1221,37 @@ public class XmlSerializerTest extends TestCase { doSerializerTest("", bean); } + static class Bean2 { + @Attribute + public String ab; + + @Attribute + public String module; + + @Attribute + public String ac; + } + + public void testOrdered() throws IOException, JDOMException { + Bean2 bean = new Bean2(); + bean.module = "module"; + bean.ab = "ab"; + doSerializerTest("", bean); + + checkSmartSerialization(new Bean2(), ""); + checkSmartSerialization(new Bean2(), ""); + checkSmartSerialization(new Bean2(), ""); + checkSmartSerialization(new Bean2(), ""); + } + + private static void checkSmartSerialization(@NotNull Bean2 bean, @NotNull String serialized) throws IOException, JDOMException { + SmartSerializer serializer = new SmartSerializer(); + serializer.readExternal(bean, JDOMUtil.loadDocument(serialized).getRootElement()); + Element serializedState = new Element("Bean2"); + serializer.writeExternal(bean, serializedState); + assertEquals(serialized, JDOMUtil.writeElement(serializedState)); + } + //--------------------------------------------------------------------------------------------------- private static Element assertSerializer(Object bean, String expected, SerializationFilter filter) { return assertSerializer(bean, expected, "Serialization failure", filter); @@ -1232,6 +1265,7 @@ public class XmlSerializerTest extends TestCase { Element element = assertSerializer(bean, expectedText, filter); //test deserializer + @SuppressWarnings("unchecked") Class aClass = (Class)bean.getClass(); T o = XmlSerializer.deserialize(element, aClass); assertSerializer(o, expectedText, "Deserialization failure", filter); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java index ccf0a1560c8c..af016745218b 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTrackerDrawing.java @@ -46,6 +46,7 @@ import com.intellij.ui.HintListener; import com.intellij.ui.LightweightHint; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -70,43 +71,27 @@ public class LineStatusTrackerDrawing { private static void paintGutterFragment(final Editor editor, final Graphics g, final Rectangle r, final Range range) { final EditorGutterComponentEx gutter = ((EditorEx)editor).getGutterComponentEx(); - Color stripeColor = getDiffGutterColor(range); + Color gutterColor = getDiffGutterColor(range); + Color borderColor = getDiffGutterBorderColor(); + + final int x = r.x + r.width - 3; + final int endX = gutter.getWhitespaceSeparatorOffset(); - int triangle = 4; if (range.getInnerRanges() == null) { // actual painter - g.setColor(stripeColor); - - final int endX = gutter.getWhitespaceSeparatorOffset(); - final int x = r.x + r.width - 3; - final int width = endX - x; if (r.height > 0) { - g.fillRect(x, r.y, width, r.height); + paintRect(g, gutterColor, borderColor, x, r.y, endX, r.y + r.height); } else { - final int[] xPoints = new int[]{x, x, endX}; - final int[] yPoints = new int[]{r.y - triangle, r.y + triangle, r.y}; - g.fillPolygon(xPoints, yPoints, 3); + paintTriangle(g, gutterColor, borderColor, x, endX, r.y); } } else { // registry: diff.status.tracker.smart - final int x = gutter.getLineMarkerAreaOffset() + gutter.getIconsAreaWidth() + 1; - final int endX = gutter.getWhitespaceSeparatorOffset(); - final int width = endX - x; - if (range.getType() == Range.DELETED) { final int y = lineToY(editor, range.getLine1()); - - final int[] xPoints = new int[]{x, x, endX + 1}; - final int[] yPoints = new int[]{y - triangle, y + triangle, y}; - - g.setColor(stripeColor); - g.fillPolygon(xPoints, yPoints, 3); - - g.setColor(gutter.getOutlineColor(false)); - g.drawPolygon(xPoints, yPoints, 3); + paintTriangle(g, gutterColor, borderColor, x, endX, y); } else { - int y = lineToY(editor, range.getLine1()); + final int y = lineToY(editor, range.getLine1()); int endY = lineToY(editor, range.getLine2()); List innerRanges = range.getInnerRanges(); @@ -116,8 +101,7 @@ public class LineStatusTrackerDrawing { int start = lineToY(editor, innerRange.getLine1()); int end = lineToY(editor, innerRange.getLine2()); - g.setColor(getDiffColor(innerRange)); - g.fillRect(x, start, width, end - start); + paintRect(g, getDiffColor(innerRange), null, x, start, endX, end); } for (int i = 0; i < innerRanges.size(); i++) { @@ -140,14 +124,10 @@ public class LineStatusTrackerDrawing { end = lineToY(editor, innerRange.getLine2()) + 3; } - g.setColor(getDiffColor(innerRange)); - g.fillRect(x, start, width, end - start); + paintRect(g, getDiffColor(innerRange), null, x, start, endX, end); } - g.setColor(gutter.getOutlineColor(false)); - UIUtil.drawLine(g, x, y, endX - 1, y); - UIUtil.drawLine(g, x, y, x, endY - 1); - UIUtil.drawLine(g, x, endY - 1, endX - 1, endY - 1); + paintRect(g, null, borderColor, x, y, endX, endY); } } } @@ -161,6 +141,35 @@ public class LineStatusTrackerDrawing { return editor.logicalPositionToXY(editor.offsetToLogicalPosition(document.getLineStartOffset(line))).y; } + private static void paintRect(@NotNull Graphics g, @Nullable Color color, @Nullable Color borderColor, int x1, int y1, int x2, int y2) { + if (color != null) { + g.setColor(color); + g.fillRect(x1, y1, x2 - x1, y2 - y1); + } + if (borderColor != null) { + g.setColor(borderColor); + UIUtil.drawLine(g, x1, y1, x2 - 1, y1); + UIUtil.drawLine(g, x1, y1, x1, y2 - 1); + UIUtil.drawLine(g, x1, y2 - 1, x2 - 1, y2 - 1); + } + } + + private static void paintTriangle(@NotNull Graphics g, @Nullable Color color, @Nullable Color borderColor, int x1, int x2, int y) { + int size = 4; + + final int[] xPoints = new int[]{x1, x1, x2}; + final int[] yPoints = new int[]{y - size, y + size, y}; + + if (color != null) { + g.setColor(color); + g.fillPolygon(xPoints, yPoints, xPoints.length); + } + if (borderColor != null) { + g.setColor(borderColor); + g.drawPolygon(xPoints, yPoints, xPoints.length); + } + } + public static LineMarkerRenderer createRenderer(final Range range, final LineStatusTracker tracker) { return new ActiveGutterRenderer() { public void paint(final Editor editor, final Graphics g, final Rectangle r) { @@ -307,8 +316,9 @@ public class LineStatusTrackerDrawing { }); } - @NotNull + @Nullable private static Color getDiffColor(@NotNull Range.InnerRange range) { + // TODO: we should move color settings from Colors-General to Colors-Diff final EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme(); switch (range.getType()) { case Range.INSERTED: @@ -341,7 +351,7 @@ public class LineStatusTrackerDrawing { } } - @NotNull + @Nullable private static Color getDiffGutterColor(@NotNull Range range) { final EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme(); switch (range.getType()) { @@ -356,4 +366,10 @@ public class LineStatusTrackerDrawing { return null; } } + + @Nullable + private static Color getDiffGutterBorderColor() { + final EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme(); + return globalScheme.getColor(EditorColors.BORDER_LINES_COLOR); + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java index 05d56161bade..4d7d65fff3c5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java @@ -142,7 +142,7 @@ public abstract class XDebuggerEditorBase { public abstract JComponent getComponent(); - protected abstract void setEditorText(XExpression text); + protected abstract void doSetText(XExpression text); public void setExpression(@Nullable XExpression text) { if (text == null) { @@ -174,7 +174,7 @@ public abstract class XDebuggerEditorBase { myChooseFactory.setDisabledIcon(IconLoader.getDisabledIcon(icon)); } - setEditorText(text); + doSetText(text); } @Nullable diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java index eaff436919db..3039d2acda7f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java @@ -128,7 +128,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { } @Override - protected void setEditorText(XExpression text) { + protected void doSetText(XExpression text) { if (myComboBox.getItemCount() > 0) { myComboBox.setSelectedIndex(0); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java index 386bca17e856..b2222ce556c5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java @@ -69,7 +69,7 @@ public class XDebuggerMultilineEditor extends XDebuggerEditorBase { } @Override - protected void setEditorText(XExpression text) { + protected void doSetText(XExpression text) { myExpression = text; Language language = text.getLanguage(); FileType fileType = language != null ? language.getAssociatedFileType() : getEditorsProvider().getFileType(); diff --git a/plugins/git4idea/src/git4idea/GitUtil.java b/plugins/git4idea/src/git4idea/GitUtil.java index ffa394211faf..c0790eb6496b 100644 --- a/plugins/git4idea/src/git4idea/GitUtil.java +++ b/plugins/git4idea/src/git4idea/GitUtil.java @@ -15,7 +15,6 @@ */ package git4idea; -import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; import com.intellij.openapi.components.ServiceManager; @@ -26,7 +25,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.ex.MultiLineLabel; import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.AbstractVcsHelper; @@ -99,14 +97,9 @@ public class GitUtil { public static final Charset UTF8_CHARSET = Charset.forName(UTF8_ENCODING); public static final String DOT_GIT = ".git"; - private final static Logger LOG = Logger.getInstance(GitUtil.class); + public static final String ORIGIN_HEAD = "origin/HEAD"; - public static final Predicate NOT_NULL_PREDICATE = new Predicate() { - @Override - public boolean apply(@Nullable GitBranchTrackInfo input) { - return input != null; - } - }; + private final static Logger LOG = Logger.getInstance(GitUtil.class); /** * A private constructor to suppress instance creation @@ -226,22 +219,6 @@ public class GitUtil { return sortFilePathsByGitRoot(files, false); } - /** - * Sort files by vcs root - * - * @param files files to sort. - * @return the map from root to the files under the root - */ - public static Map> sortGitFilePathsByGitRoot(Collection files) { - try { - return sortFilePathsByGitRoot(files, true); - } - catch (VcsException e) { - throw new RuntimeException("Unexpected exception:", e); - } - } - - /** * Sort files by vcs root * @@ -687,8 +664,13 @@ public class GitUtil { @Nullable - public static GitRemote findRemoteByName(@NotNull GitRepository repository, @Nullable final String name) { - return ContainerUtil.find(repository.getRemotes(), new Condition() { + public static GitRemote findRemoteByName(@NotNull GitRepository repository, @NotNull final String name) { + return findRemoteByName(repository.getRemotes(), name); + } + + @Nullable + public static GitRemote findRemoteByName(Collection remotes, @NotNull final String name) { + return ContainerUtil.find(remotes, new Condition() { @Override public boolean value(GitRemote remote) { return remote.getName().equals(name); @@ -709,39 +691,6 @@ public class GitUtil { }); } - /** - * @deprecated Calls Git for tracked info, use {@link GitRepository#getBranchTrackInfos()} instead. - */ - @Nullable - @Deprecated - public static Pair findMatchingRemoteBranch(GitRepository repository, GitLocalBranch branch) - throws VcsException { - /* - from man git-push: - git push - Works like git push , where is the current branch's remote (or origin, if no - remote is configured for the current branch). - - */ - String remoteName = GitBranchUtil.getTrackedRemoteName(repository.getProject(), repository.getRoot(), branch.getName()); - GitRemote remote; - if (remoteName == null) { - remote = findOrigin(repository.getRemotes()); - } else { - remote = findRemoteByName(repository, remoteName); - } - if (remote == null) { - return null; - } - - for (GitRemoteBranch remoteBranch : repository.getBranches().getRemoteBranches()) { - if (remoteBranch.getName().equals(remote.getName() + "/" + branch.getName())) { - return Pair.create(remote, remoteBranch); - } - } - return null; - } - @Nullable private static GitRemote findOrigin(Collection remotes) { for (GitRemote remote : remotes) { @@ -752,10 +701,6 @@ public class GitUtil { return null; } - public static boolean repoContainsRemoteBranch(@NotNull GitRepository repository, @NotNull GitRemoteBranch dest) { - return repository.getBranches().getRemoteBranches().contains(dest); - } - @NotNull public static Collection getRootsFromRepositories(@NotNull Collection repositories) { Collection roots = new ArrayList(repositories.size()); diff --git a/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java b/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java index 7ee419e6ae9d..042b651c6840 100644 --- a/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java +++ b/plugins/git4idea/src/git4idea/actions/GitRepositoryAction.java @@ -18,9 +18,6 @@ package git4idea.actions; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; @@ -53,21 +50,10 @@ public abstract class GitRepositoryAction extends DumbAwareAction { */ final List myDelayedTasks = new ArrayList(); - /** - * {@inheritDoc} - */ - public void actionPerformed(final AnActionEvent e) { + public void actionPerformed(@NotNull final AnActionEvent e) { myDelayedTasks.clear(); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - FileDocumentManager.getInstance().saveAllDocuments(); - } - }); - DataContext dataContext = e.getDataContext(); - final Project project = CommonDataKeys.PROJECT.getData(dataContext); - if (project == null) { - return; - } + FileDocumentManager.getInstance().saveAllDocuments(); + final Project project = e.getRequiredData(CommonDataKeys.PROJECT); GitVcs vcs = GitVcs.getInstance(project); final List roots = getGitRoots(project, vcs); if (roots == null) return; @@ -196,9 +182,6 @@ public abstract class GitRepositoryAction extends DumbAwareAction { final Set affectedRoots, List exceptions) throws VcsException; - /** - * {@inheritDoc} - */ @Override public void update(final AnActionEvent e) { super.update(e); diff --git a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java index 4cc356e27df8..b996dea69e5f 100644 --- a/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java +++ b/plugins/git4idea/src/git4idea/branch/GitBranchUtil.java @@ -16,10 +16,8 @@ package git4idea.branch; import com.google.common.base.Function; -import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; -import com.google.common.collect.Iterables; import com.intellij.dvcs.DvcsUtil; import com.intellij.dvcs.repo.RepositoryUtil; import com.intellij.openapi.diagnostic.Logger; @@ -32,7 +30,6 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; -import com.intellij.vcs.log.Hash; import com.intellij.vcsUtil.VcsUtil; import git4idea.*; import git4idea.commands.GitCommand; @@ -47,7 +44,10 @@ import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; /** * @author Kirill Likhodedov @@ -208,46 +208,6 @@ public class GitBranchUtil { return remote; } - /** - * - * @return {@link git4idea.GitStandardRemoteBranch} or {@link GitSvnRemoteBranch}, or null in case of an error. The error is logged in this method. - * @deprecated Should be used only in the GitRepositoryReader, i. e. moved there once all other usages are removed. - */ - @Deprecated - @Nullable - public static GitRemoteBranch parseRemoteBranch(@NotNull String fullBranchName, @NotNull Hash hash, - @NotNull Collection remotes) { - String stdName = stripRefsPrefix(fullBranchName); - - int slash = stdName.indexOf('/'); - if (slash == -1) { // .git/refs/remotes/my_branch => git-svn - return new GitSvnRemoteBranch(fullBranchName, hash); - } - else { - String remoteName = stdName.substring(0, slash); - String branchName = stdName.substring(slash + 1); - GitRemote remote = findRemoteByName(remoteName, remotes); - if (remote == null) { - // user may remove the remote section from .git/config, but leave remote refs untouched in .git/refs/remotes - LOG.info(String.format("No remote found with the name [%s]. All remotes: %s", remoteName, remotes)); - GitRemote fakeRemote = new GitRemote(remoteName, ContainerUtil.emptyList(), Collections.emptyList(), - Collections.emptyList(), Collections.emptyList()); - return new GitStandardRemoteBranch(fakeRemote, branchName, hash); - } - return new GitStandardRemoteBranch(remote, branchName, hash); - } - } - - @Nullable - private static GitRemote findRemoteByName(@NotNull String remoteName, @NotNull Collection remotes) { - for (GitRemote remote : remotes) { - if (remote.getName().equals(remoteName)) { - return remote; - } - } - return null; - } - /** * Convert {@link git4idea.GitRemoteBranch GitRemoteBranches} to their names, and remove remote HEAD pointers: origin/HEAD. */ @@ -262,50 +222,6 @@ public class GitBranchUtil { }); } - /** - * @deprecated Don't use names, use {@link GitLocalBranch} objects. - */ - @Deprecated - @Nullable - public static GitLocalBranch findLocalBranchByName(@NotNull GitRepository repository, @NotNull final String branchName) { - Optional optional = Iterables.tryFind(repository.getBranches().getLocalBranches(), new Predicate() { - @Override - public boolean apply(@Nullable GitLocalBranch input) { - assert input != null; - return input.getName().equals(branchName); - } - }); - if (optional.isPresent()) { - return optional.get(); - } - LOG.info(String.format("Couldn't find branch with name %s in %s", branchName, repository)); - return null; - - } - - /** - * Looks through the remote branches in the given repository and tries to find the one from the given remote, - * which the given name. - * @return remote branch or null if such branch couldn't be found. - */ - @Nullable - public static GitRemoteBranch findRemoteBranchByName(@NotNull String remoteBranchName, @NotNull final String remoteName, - @NotNull final Collection remoteBranches) { - final String branchName = stripRefsPrefix(remoteBranchName); - Optional optional = Iterables.tryFind(remoteBranches, new Predicate() { - @Override - public boolean apply(@Nullable GitRemoteBranch input) { - assert input != null; - return input.getNameForRemoteOperations().equals(branchName) && input.getRemote().getName().equals(remoteName); - } - }); - if (optional.isPresent()) { - return optional.get(); - } - LOG.info(String.format("Couldn't find branch with name %s", branchName)); - return null; - } - @NotNull public static String stripRefsPrefix(@NotNull String branchName) { if (branchName.startsWith(GitBranch.REFS_HEADS_PREFIX)) { diff --git a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java index 1c310492059d..f50604bcf6d3 100644 --- a/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java +++ b/plugins/git4idea/src/git4idea/history/GitHistoryUtils.java @@ -585,7 +585,7 @@ public class GitHistoryUtils { public VcsRef fun(String refName) { VcsRefType type = GitRefManager.getRefType(refName); refName = GitBranchUtil.stripRefsPrefix(refName); - return factory.createRef(hash, refName, type, root); + return refName.equals(GitUtil.ORIGIN_HEAD) ? null : factory.createRef(hash, refName, type, root); } }); } diff --git a/plugins/git4idea/src/git4idea/merge/GitPullDialog.java b/plugins/git4idea/src/git4idea/merge/GitPullDialog.java index ee8ddf33e582..eaf372e5f4f7 100644 --- a/plugins/git4idea/src/git4idea/merge/GitPullDialog.java +++ b/plugins/git4idea/src/git4idea/merge/GitPullDialog.java @@ -22,6 +22,8 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.ListCellRendererWrapper; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import git4idea.GitBranch; import git4idea.GitRemoteBranch; import git4idea.GitUtil; @@ -170,11 +172,13 @@ public class GitPullDialog extends DialogWrapper { String currentRemoteBranch = trackInfo == null ? null : trackInfo.getRemoteBranch().getNameForLocalOperations(); List remoteBranches = new ArrayList(repository.getBranches().getRemoteBranches()); Collections.sort(remoteBranches); - for (GitBranch remoteBranch : remoteBranches) { - if (belongsToRemote(remoteBranch, selectedRemote)) { - myBranchChooser.addElement(remoteBranch.getName(), remoteBranch.getName().equals(currentRemoteBranch)); + myBranchChooser.setElements(ContainerUtil.map(remoteBranches, new Function() { + @Override + public String fun(GitRemoteBranch branch) { + return branch.getName(); } - } + }), false); + myBranchChooser.setElementMarked(currentRemoteBranch, true); validateDialog(); } diff --git a/plugins/git4idea/src/git4idea/repo/GitConfig.java b/plugins/git4idea/src/git4idea/repo/GitConfig.java index 4b0bdeadc8f9..aeb0bf8eb55c 100644 --- a/plugins/git4idea/src/git4idea/repo/GitConfig.java +++ b/plugins/git4idea/src/git4idea/repo/GitConfig.java @@ -158,7 +158,7 @@ public class GitConfig { Pair, Collection> remotesAndUrls = parseRemotes(ini, classLoader); Collection trackedInfos = parseTrackedInfos(ini, classLoader); - + return new GitConfig(remotesAndUrls.getFirst(), remotesAndUrls.getSecond(), trackedInfos); } @@ -201,12 +201,12 @@ public class GitConfig { boolean merge = mergeName != null; final String remoteBranchName = (merge ? mergeName : rebaseName); - assert remoteName != null; - assert remoteBranchName != null; GitLocalBranch localBranch = findLocalBranch(branchName, localBranches); - GitRemoteBranch remoteBranch = GitBranchUtil.findRemoteBranchByName(remoteBranchName, remoteName, remoteBranches); + GitRemoteBranch remoteBranch = findRemoteBranch(remoteBranchName, remoteName, remoteBranches); if (localBranch == null || remoteBranch == null) { + // obsolete record in .git/config: local or remote branch doesn't exist, but the tracking information wasn't removed + LOG.debug("localBranch: " + localBranch + ", remoteBranch: " + remoteBranch); return null; } return new GitBranchTrackInfo(localBranch, remoteBranch, merge); @@ -215,19 +215,25 @@ public class GitConfig { @Nullable private static GitLocalBranch findLocalBranch(@NotNull String branchName, @NotNull Collection localBranches) { final String name = GitBranchUtil.stripRefsPrefix(branchName); - try { - return ContainerUtil.find(localBranches, new Condition() { - @Override - public boolean value(@Nullable GitLocalBranch input) { - assert input != null; - return input.getName().equals(name); - } - }); - } - catch (NoSuchElementException e) { - LOG.info("Couldn't find branch with name " + name); - return null; - } + return ContainerUtil.find(localBranches, new Condition() { + @Override + public boolean value(@Nullable GitLocalBranch input) { + assert input != null; + return input.getName().equals(name); + } + }); + } + + @Nullable + public static GitRemoteBranch findRemoteBranch(@NotNull String remoteBranchName, @NotNull final String remoteName, + @NotNull final Collection remoteBranches) { + final String branchName = GitBranchUtil.stripRefsPrefix(remoteBranchName); + return ContainerUtil.find(remoteBranches, new Condition() { + @Override + public boolean value(GitRemoteBranch branch) { + return branch.getNameForRemoteOperations().equals(branchName) && branch.getRemote().getName().equals(remoteName); + } + }); } @Nullable diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java index 3f6f25f1dc46..30951670e079 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryImpl.java @@ -217,7 +217,7 @@ public class GitRepositoryImpl extends RepositoryImpl implements GitRepository { if (Disposer.isDisposed(repository.getProject())) { return; } - if (previousInfo != null && !info.equals(previousInfo)) { + if (!info.equals(previousInfo)) { repository.getProject().getMessageBus().syncPublisher(GIT_REPO_CHANGE).repositoryChanged(repository); } } diff --git a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java index 576f326a8ea3..66ce94172794 100644 --- a/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java +++ b/plugins/git4idea/src/git4idea/repo/GitRepositoryReader.java @@ -25,9 +25,7 @@ import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import com.intellij.vcs.log.Hash; import com.intellij.vcs.log.impl.HashImpl; -import git4idea.GitBranch; -import git4idea.GitLocalBranch; -import git4idea.GitRemoteBranch; +import git4idea.*; import git4idea.branch.GitBranchUtil; import git4idea.branch.GitBranchesCollection; import org.jetbrains.annotations.NonNls; @@ -349,7 +347,7 @@ class GitRepositoryReader { String hash = loadHashFromBranchFile(file); Hash h = createHash(hash); if (h != null) { - GitRemoteBranch remoteBranch = GitBranchUtil.parseRemoteBranch(branchName, h, remotes); + GitRemoteBranch remoteBranch = parseRemoteBranch(branchName, h, remotes); if (remoteBranch != null) { branches.add(remoteBranch); } @@ -386,7 +384,7 @@ class GitRepositoryReader { localBranches.add(new GitLocalBranch(branchName, hash)); } else if (branchName.startsWith(REFS_REMOTES_PREFIX)) { - GitRemoteBranch remoteBranch = GitBranchUtil.parseRemoteBranch(branchName, hash, remotes); + GitRemoteBranch remoteBranch = parseRemoteBranch(branchName, hash, remotes); if (remoteBranch != null) { remoteBranches.add(remoteBranch); } @@ -395,6 +393,31 @@ class GitRepositoryReader { return new GitBranchesCollection(localBranches, remoteBranches); } + @Nullable + private static GitRemoteBranch parseRemoteBranch(@NotNull String fullBranchName, + @NotNull Hash hash, + @NotNull Collection remotes) { + String stdName = GitBranchUtil.stripRefsPrefix(fullBranchName); + + int slash = stdName.indexOf('/'); + if (slash == -1) { // .git/refs/remotes/my_branch => git-svn + return new GitSvnRemoteBranch(fullBranchName, hash); + } + else { + String remoteName = stdName.substring(0, slash); + String branchName = stdName.substring(slash + 1); + GitRemote remote = GitUtil.findRemoteByName(remotes, remoteName); + if (remote == null) { + // user may remove the remote section from .git/config, but leave remote refs untouched in .git/refs/remotes + LOG.debug(String.format("No remote found with the name [%s]. All remotes: %s", remoteName, remotes)); + GitRemote fakeRemote = new GitRemote(remoteName, ContainerUtil.emptyList(), Collections.emptyList(), + Collections.emptyList(), Collections.emptyList()); + return new GitStandardRemoteBranch(fakeRemote, branchName, hash); + } + return new GitStandardRemoteBranch(remote, branchName, hash); + } + } + @NotNull private static String readBranchFile(@NotNull File branchFile) { return RepositoryUtil.tryLoadFile(branchFile); diff --git a/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java b/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java index 18076a1b9a61..360cf56fe505 100644 --- a/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java +++ b/plugins/git4idea/src/git4idea/ui/branch/GitMultiRootBranchConfig.java @@ -103,7 +103,7 @@ public class GitMultiRootBranchConfig extends DvcsMultiRootBranchConfigemptySet())); + assertFalse("origin/HEAD should be ignored", ContainerUtil.exists(block.getRefs(), new Condition() { + @Override + public boolean value(VcsRef ref) { + return ref.getName().equals("origin/HEAD"); + } + })); + } + private static void prepareSomeHistory() { tac("a.txt"); git("tag ATAG"); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java index 6174054be32f..40a9cf04afbc 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java @@ -54,7 +54,6 @@ public class GotoTaskAction extends GotoActionBase implements DumbAware { popup.setShowListForEmptyPattern(true); popup.setSearchInAnyPlace(true); - popup.setFixLostTyping(false); popup.setAlwaysHasMore(true); popup.setAdText("Press SHIFT to merge with current context
" + "Pressing " + diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java index 63bff938a26f..0bd5835cd1a6 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskItemProvider.java @@ -26,7 +26,7 @@ import java.util.concurrent.atomic.AtomicReference; class TaskItemProvider implements ChooseByNameItemProvider, Disposable { private static final Logger LOG = Logger.getInstance(TaskItemProvider.class); - private static final int DELAY_PERIOD = 1000; // ms + private static final int DELAY_PERIOD = 200; // ms private final Project myProject; @@ -76,19 +76,31 @@ class TaskItemProvider implements ChooseByNameItemProvider, Disposable { }); // Newer request always wins - Future> oldFeature = myFutureReference.getAndSet(future); - if (oldFeature != null) { + Future> oldFuture = myFutureReference.getAndSet(future); + if (oldFuture != null) { LOG.debug("Cancelling existing task"); - oldFeature.cancel(true); + oldFuture.cancel(true); } if (myAlarm.isDisposed()) { return false; } - myAlarm.addRequest(future, DELAY_PERIOD); + myAlarm.addRequest(future, oldFuture == null && pattern.length() > 5 ? 0 : DELAY_PERIOD); try { - List tasks = future.get(); + List tasks; + while (true) { + try { + tasks = future.get(10, TimeUnit.MILLISECONDS); + break; + } + catch (TimeoutException ignore) { + } + if (base.hasPostponedAction()) { + future.cancel(true); + return true; + } + } myFutureReference.compareAndSet(future, null); // Exclude *all* cached and local issues, not only those returned by TaskSearchSupport.getLocalAndCachedTasks(). diff --git a/python/edu/build/pycharm_edu_build.gant b/python/edu/build/pycharm_edu_build.gant index 356df8c7d4c7..85889184ab09 100644 --- a/python/edu/build/pycharm_edu_build.gant +++ b/python/edu/build/pycharm_edu_build.gant @@ -144,8 +144,11 @@ target('default': "Build artifacts") { layoutEducational("${paths.sandbox}/classes/production", usedJars) - def extraArgs = ["build.code": "pycharm${buildName}", "build.number": "PE-$buildNumber", "artifacts.path": "${paths.artifacts}"] + signMacZip("pycharm", extraArgs) + notifyArtifactBuilt("${paths.artifacts}/pycharm${buildName}.sit") + buildDmg("pycharm", "${pythonEduHome}/build/DMG_background.png", extraArgs) + signMacZip("pycharm", extraArgs + ["sitFileName": "pycharm${buildName}-jdk-bundled", "jdk_archive_name": "jdk_mac_redist_for_${buildNumber}.tar"]) buildDmg("pycharm", "${pythonEduHome}/build/DMG_background.png", extraArgs + ["sitFileName": "pycharm${buildName}-jdk-bundled", "jdk_archive_name": "jdk_mac_redist_for_${buildNumber}.tar"]) @@ -206,7 +209,7 @@ public layoutEducational(String classesPath, Set usedJars) { String macAppRoot = isEap() ? "PyCharm Educational ${p("component.version.major")}.${p("component.version.minor")} EAP.app/Contents" : "PyCharm Educational.app/Contents" buildMacZip(macAppRoot, "${paths.artifacts}/pycharm${buildName}.sit", [paths.distAll], paths.distMac) ant.copy(file: "${paths.artifacts}/pycharm${buildName}.sit", tofile: "${paths.artifacts}/pycharm${buildName}-jdk-bundled.sit") - ant.delete(file: "${paths.artifacts}/pycharm${buildName}.sit") + //ant.delete(file: "${paths.artifacts}/pycharm${buildName}.sit") } private layoutPlugins(layouts) { diff --git a/python/helpers/pydev/pydevd_vars.py b/python/helpers/pydev/pydevd_vars.py index d9e1d28c37c5..db297f991928 100644 --- a/python/helpers/pydev/pydevd_vars.py +++ b/python/helpers/pydev/pydevd_vars.py @@ -399,16 +399,17 @@ def array_to_xml(array, roffset, coffset, rows, cols, format): cols = 1 elif rows == 1 or cols == 1: is_row = True if (rows == 1) else False - pure_1d = False if (len(array) == 1) else True + if is_row: + array = array[roffset:] + else: + array = array[coffset:] - if not pure_1d: + if len(array) == 1: array = array[0] if is_row: - array = array[coffset:] cols = min(cols, len(array)) else: - array = array[roffset:] rows = min(rows, len(array)) else: array = array[roffset:, coffset:] diff --git a/python/src/com/jetbrains/python/debugger/array/ArrayTableCellEditor.java b/python/src/com/jetbrains/python/debugger/array/ArrayTableCellEditor.java index 6095d1d0047d..05ba00ebd17a 100644 --- a/python/src/com/jetbrains/python/debugger/array/ArrayTableCellEditor.java +++ b/python/src/com/jetbrains/python/debugger/array/ArrayTableCellEditor.java @@ -143,7 +143,7 @@ public class ArrayTableCellEditor extends AbstractCellEditor implements TableCel } @Override - protected void setEditorText(XExpression text) { + protected void doSetText(XExpression text) { myEditorTextField.setText(text.getExpression()); } diff --git a/python/src/com/jetbrains/python/debugger/array/ArrayTableForm.java b/python/src/com/jetbrains/python/debugger/array/ArrayTableForm.java index 90b6d1c1b75c..f50f0161034f 100644 --- a/python/src/com/jetbrains/python/debugger/array/ArrayTableForm.java +++ b/python/src/com/jetbrains/python/debugger/array/ArrayTableForm.java @@ -15,6 +15,8 @@ */ package com.jetbrains.python.debugger.array; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.ui.EditorTextField; import com.intellij.ui.components.JBScrollPane; @@ -31,6 +33,7 @@ import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import java.awt.*; +import java.awt.event.KeyListener; /** * @author amarch @@ -46,23 +49,41 @@ public class ArrayTableForm { private JTable myTable; private JBTable myBusyTable; private final Project myProject; + private KeyListener myResliceCallback; + private KeyListener myReformatCallback; private static final String DATA_LOADING_IN_PROCESS = "Please wait, load array data."; private static final String NOT_APPLICABLE = "View not applicable for "; - public ArrayTableForm(@NotNull Project project) { + public ArrayTableForm(@NotNull Project project, KeyListener resliceCallback, KeyListener reformatCallback) { myProject = project; + myResliceCallback = resliceCallback; + myReformatCallback = reformatCallback; } private void createUIComponents() { - mySliceTextField = new EditorTextField("", myProject, PythonFileType.INSTANCE); + mySliceTextField = new EditorTextField("", myProject, PythonFileType.INSTANCE) { + @Override + protected EditorEx createEditor() { + EditorEx editor = super.createEditor(); + editor.getContentComponent().addKeyListener(myResliceCallback); + return editor; + } + }; myTable = new JBTableWithRowHeaders(); myScrollPane = ((JBTableWithRowHeaders)myTable).getScrollPane(); - myFormatTextField = new EditorTextField("", myProject, PythonFileType.INSTANCE); + myFormatTextField = new EditorTextField("", myProject, PythonFileType.INSTANCE) { + @Override + protected EditorEx createEditor() { + EditorEx editor = super.createEditor(); + editor.getContentComponent().addKeyListener(myReformatCallback); + return editor; + } + }; myBusyTable = new JBTable(new DefaultTableModel()); myBusyTable.getEmptyText().setText(""); diff --git a/python/src/com/jetbrains/python/debugger/array/NumpyArrayTable.java b/python/src/com/jetbrains/python/debugger/array/NumpyArrayTable.java index 230e8c058974..dacf3d51a770 100644 --- a/python/src/com/jetbrains/python/debugger/array/NumpyArrayTable.java +++ b/python/src/com/jetbrains/python/debugger/array/NumpyArrayTable.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.hint.HintManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; @@ -76,7 +77,21 @@ public class NumpyArrayTable { @NotNull PyViewArrayAction.ViewArrayDialog dialog, @NotNull PyDebugValue value) { myValue = value; myDialog = dialog; - myComponent = new ArrayTableForm(project); + myComponent = new ArrayTableForm(project, new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + doReslice(getSliceText(), null); + } + } + }, new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + doApplyFormat(); + } + } + }); myTable = myComponent.getTable(); myProject = project; myEvaluator = new PyDebuggerEvaluator(project, getDebugValue().getFrameAccessor()); @@ -127,9 +142,6 @@ public class NumpyArrayTable { }); } - // add slice actions - initSliceFieldActions(); - //make value name read-only myComponent.getSliceTextField().addFocusListener(new FocusListener() { @Override @@ -145,9 +157,6 @@ public class NumpyArrayTable { } } }); - - //add format actions - initFormatFieldActions(); } public void disableColor() { @@ -166,28 +175,6 @@ public class NumpyArrayTable { }); } - private void initSliceFieldActions() { - myComponent.getSliceTextField().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - doReslice(getSliceText(), null); - } - } - }); - } - - private void initFormatFieldActions() { - myComponent.getFormatTextField().addKeyListener(new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - doApplyFormat(); - } - } - }); - } - public PyDebugValue getDebugValue() { return myValue; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java index 1fc91e0334ec..fd1126e64a2f 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java @@ -374,10 +374,19 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere return context.getType((PyTypedElement)target); } if (target instanceof PsiDirectory) { - PsiFile file = ((PsiDirectory)target).findFile(PyNames.INIT_DOT_PY); + final PsiDirectory dir = (PsiDirectory)target; + PsiFile file = dir.findFile(PyNames.INIT_DOT_PY); if (file != null) { return getTypeFromTarget(file, context, anchor); } + if (PyUtil.isPackage(dir, anchor)) { + final PsiFile containingFile = anchor.getContainingFile(); + if (containingFile instanceof PyFile) { + final QualifiedName qualifiedName = QualifiedName.fromComponents(dir.getName()); + final PyImportedModule module = new PyImportedModule(null, (PyFile)containingFile, qualifiedName); + return new PyImportedModuleType(module); + } + } } return null; } diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java b/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java index 69eb8a6dd0da..be7921bd6b22 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java @@ -157,8 +157,8 @@ public class PyImportReference extends PyReferenceImpl { } ASTNode node = myElement.getNode(); while (node != null) { - final IElementType node_type = node.getElementType(); - if (node_type == PyTokenTypes.IMPORT_KEYWORD) { + final IElementType nodeType = node.getElementType(); + if (nodeType == PyTokenTypes.IMPORT_KEYWORD) { return true; } node = node.getTreeNext(); @@ -175,7 +175,7 @@ public class PyImportReference extends PyReferenceImpl { public ImportVariantCollector(@NotNull TypeEvalContext context) { myContext = context; PsiFile currentFile = myElement.getContainingFile(); - if (currentFile != null) currentFile = currentFile.getOriginalFile(); + currentFile = currentFile.getOriginalFile(); myCurrentFile = currentFile; myNamesAlready = new HashSet(); myObjects = new ArrayList(); @@ -187,15 +187,15 @@ public class PyImportReference extends PyReferenceImpl { // NOTE: could use getPointInImport() // are we in "import _" or "from foo import _"? - PyFromImportStatement from_import = PsiTreeUtil.getParentOfType(myElement, PyFromImportStatement.class); - if (from_import != null && myElement.getParent() != from_import) { // in "from foo import _" - PyReferenceExpression src = from_import.getImportSource(); + PyFromImportStatement fromImport = PsiTreeUtil.getParentOfType(myElement, PyFromImportStatement.class); + if (fromImport != null && myElement.getParent() != fromImport) { // in "from foo import _" + PyReferenceExpression src = fromImport.getImportSource(); if (src != null) { - PsiElement mod_candidate = src.getReference().resolve(); - if (mod_candidate instanceof PyExpression) { - addImportedNames(from_import.getImportElements()); // don't propose already imported items + PsiElement modCandidate = src.getReference().resolve(); + if (modCandidate instanceof PyExpression) { + addImportedNames(fromImport.getImportElements()); // don't propose already imported items // try to collect submodules - PyExpression module = (PyExpression)mod_candidate; + PyExpression module = (PyExpression)modCandidate; PyType qualifierType = myContext.getType(module); if (qualifierType != null) { ProcessingContext ctx = new ProcessingContext(); @@ -204,18 +204,18 @@ public class PyImportReference extends PyReferenceImpl { } return myObjects.toArray(); } - else if (mod_candidate instanceof PsiDirectory) { - fillFromDir((PsiDirectory)mod_candidate, ImportKeywordHandler.INSTANCE); + else if (modCandidate instanceof PsiDirectory) { + fillFromDir((PsiDirectory)modCandidate, ImportKeywordHandler.INSTANCE); return myObjects.toArray(); } } else { // null source, must be a "from ... import" - relativeLevel = from_import.getRelativeLevel(); + relativeLevel = fromImport.getRelativeLevel(); if (relativeLevel > 0) { - PsiDirectory relative_dir = ResolveImportUtil.stepBackFrom(myCurrentFile, relativeLevel); - if (relative_dir != null) { - addImportedNames(from_import.getImportElements()); - fillFromDir(relative_dir, null); + PsiDirectory relativeDir = ResolveImportUtil.stepBackFrom(myCurrentFile, relativeLevel); + if (relativeDir != null) { + addImportedNames(fromImport.getImportElements()); + fillFromDir(relativeDir, null); } } } @@ -226,21 +226,21 @@ public class PyImportReference extends PyReferenceImpl { relativeLevel += 1; n = n.getTreePrev(); } - if (from_import != null) { - addImportedNames(from_import.getImportElements()); + if (fromImport != null) { + addImportedNames(fromImport.getImportElements()); if (!alreadyHasImportKeyword()) { insertHandler = ImportKeywordHandler.INSTANCE; } } else { myNamesAlready.add(PyNames.FUTURE_MODULE); // never add it to "import ..." - PyImportStatement import_stmt = PsiTreeUtil.getParentOfType(myElement, PyImportStatement.class); - if (import_stmt != null) { - addImportedNames(import_stmt.getImportElements()); + PyImportStatement importStatement = PsiTreeUtil.getParentOfType(myElement, PyImportStatement.class); + if (importStatement != null) { + addImportedNames(importStatement.getImportElements()); } } // look at dir by level - if (myCurrentFile != null && (relativeLevel >= 0 || !ResolveImportUtil.isAbsoluteImportEnabledFor(myCurrentFile))) { + if ((relativeLevel >= 0 || !ResolveImportUtil.isAbsoluteImportEnabledFor(myCurrentFile))) { final PsiDirectory containingDirectory = myCurrentFile.getContainingDirectory(); if (containingDirectory != null) { QualifiedName thisQName = QualifiedNameFinder.findShortestImportableQName(containingDirectory); @@ -268,9 +268,9 @@ public class PyImportReference extends PyReferenceImpl { } } - private void addImportedNames(@NotNull PyImportElement[] import_elts) { - for (PyImportElement ielt : import_elts) { - PyReferenceExpression ref = ielt.getImportReferenceExpression(); + private void addImportedNames(@NotNull PyImportElement[] importElements) { + for (PyImportElement element : importElements) { + PyReferenceExpression ref = element.getImportReferenceExpression(); if (ref != null) { String s = ref.getReferencedName(); if (s != null) myNamesAlready.add(s); @@ -278,22 +278,24 @@ public class PyImportReference extends PyReferenceImpl { } } - // adds variants found under given dir - private void fillFromDir(PsiDirectory target_dir, @Nullable InsertHandler insertHandler) { - if (target_dir != null) { - PsiFile initPy = target_dir.findFile(PyNames.INIT_DOT_PY); + /** + * Adds variants found under given dir. + */ + private void fillFromDir(PsiDirectory targetDir, @Nullable InsertHandler insertHandler) { + if (targetDir != null) { + PsiFile initPy = targetDir.findFile(PyNames.INIT_DOT_PY); if (initPy instanceof PyFile) { PyModuleType moduleType = new PyModuleType((PyFile)initPy); ProcessingContext context = new ProcessingContext(); context.put(PyType.CTX_NAMES, myNamesAlready); - Object[] completionVariants = moduleType.getCompletionVariants("", (PyExpression)getElement(), context); + Object[] completionVariants = moduleType.getCompletionVariants("", getElement(), context); if (insertHandler != null) { replaceInsertHandler(completionVariants, insertHandler); } myObjects.addAll(Arrays.asList(completionVariants)); } else { - myObjects.addAll(PyModuleType.getSubModuleVariants(target_dir, myElement, myNamesAlready)); + myObjects.addAll(PyModuleType.getSubModuleVariants(targetDir, myElement, myNamesAlready)); } } } diff --git a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java index 9fcbe52ed8d0..bc26a1a87ba2 100644 --- a/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyImportedModuleType.java @@ -19,15 +19,13 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; +import com.intellij.psi.util.QualifiedName; +import com.intellij.util.ArrayUtil; import com.intellij.util.ProcessingContext; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; -import com.jetbrains.python.psi.AccessDirection; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyFile; -import com.jetbrains.python.psi.PyImportElement; +import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyImportedModule; -import com.intellij.psi.util.QualifiedName; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; import com.jetbrains.python.psi.resolve.ResolveImportUtil; @@ -82,7 +80,14 @@ public class PyImportedModuleType implements PyType { } } } - return result.toArray(new Object[result.size()]); + final PsiElement resolved = myImportedModule.resolve(); + if (resolved instanceof PsiDirectory) { + final PsiDirectory dir = (PsiDirectory)resolved; + if (PyUtil.isPackage(dir, location)) { + result.addAll(PyModuleType.getSubModuleVariants(dir, location, null)); + } + } + return ArrayUtil.toObjectArray(result); } public String getName() { diff --git a/python/src/com/jetbrains/python/psi/types/PyModuleType.java b/python/src/com/jetbrains/python/psi/types/PyModuleType.java index 0aec8612c989..8db0b716194f 100644 --- a/python/src/com/jetbrains/python/psi/types/PyModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyModuleType.java @@ -245,7 +245,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje * not suitable for import. */ @NotNull - private static List getSubmodulesList(final PsiDirectory directory) { + private static List getSubmodulesList(final PsiDirectory directory, @Nullable PsiElement anchor) { List result = new ArrayList(); if (directory != null) { // just in case @@ -259,7 +259,9 @@ public class PyModuleType implements PyType { // Modules don't descend from obje } // dir modules for (PsiDirectory dir : directory.getSubdirectories()) { - if (dir.findFile(PyNames.INIT_DOT_PY) instanceof PyFile) result.add(dir); + if (PyUtil.isPackage(dir, anchor)) { + result.add(dir); + } } } return result; @@ -365,7 +367,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje PsiElement location, Set namesAlready) { List result = new ArrayList(); - for (PsiFileSystemItem item : getSubmodulesList(directory)) { + for (PsiFileSystemItem item : getSubmodulesList(directory, location)) { if (item != location.getContainingFile().getOriginalFile()) { LookupElement lookupElement = buildFileLookupElement(item, namesAlready); if (lookupElement != null) { diff --git a/python/src/com/jetbrains/python/refactoring/rename/RenamePyClassProcessor.java b/python/src/com/jetbrains/python/refactoring/rename/RenamePyClassProcessor.java index b4917dd0767c..3f11c0505ee5 100644 --- a/python/src/com/jetbrains/python/refactoring/rename/RenamePyClassProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/rename/RenamePyClassProcessor.java @@ -17,6 +17,7 @@ package com.jetbrains.python.refactoring.rename; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.util.Processor; import com.jetbrains.python.PyNames; @@ -67,7 +68,7 @@ public class RenamePyClassProcessor extends RenamePyElementProcessor { if (initMethod != null) { final List allRefs = Collections.synchronizedList(new ArrayList()); allRefs.addAll(super.findReferences(element)); - ReferencesSearch.search(initMethod).forEach(new Processor() { + ReferencesSearch.search(initMethod, GlobalSearchScope.projectScope(element.getProject())).forEach(new Processor() { @Override public boolean process(PsiReference psiReference) { if (psiReference.getCanonicalText().equals(((PyClass)element).getName())) { diff --git a/python/testData/completion/fromQualifiedNamespacePackageImport/a.after.py b/python/testData/completion/fromQualifiedNamespacePackageImport/a.after.py new file mode 100644 index 000000000000..08b9946188ab --- /dev/null +++ b/python/testData/completion/fromQualifiedNamespacePackageImport/a.after.py @@ -0,0 +1 @@ +from nspkg1.foo import diff --git a/python/testData/completion/fromQualifiedNamespacePackageImport/a.py b/python/testData/completion/fromQualifiedNamespacePackageImport/a.py new file mode 100644 index 000000000000..dc6e9e115236 --- /dev/null +++ b/python/testData/completion/fromQualifiedNamespacePackageImport/a.py @@ -0,0 +1 @@ +from nspkg1.f diff --git a/python/testData/completion/fromQualifiedNamespacePackageImport/nspkg1/bar.py b/python/testData/completion/fromQualifiedNamespacePackageImport/nspkg1/bar.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/fromQualifiedNamespacePackageImport/nspkg1/foo.py b/python/testData/completion/fromQualifiedNamespacePackageImport/nspkg1/foo.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/importNamespacePackage/a.after.py b/python/testData/completion/importNamespacePackage/a.after.py new file mode 100644 index 000000000000..3a900b8dcab9 --- /dev/null +++ b/python/testData/completion/importNamespacePackage/a.after.py @@ -0,0 +1 @@ +import nspkg1 diff --git a/python/testData/completion/importNamespacePackage/a.py b/python/testData/completion/importNamespacePackage/a.py new file mode 100644 index 000000000000..bbb3f11374c9 --- /dev/null +++ b/python/testData/completion/importNamespacePackage/a.py @@ -0,0 +1 @@ +import nspk diff --git a/python/testData/completion/importQualifiedNamespacePackage/a.after.py b/python/testData/completion/importQualifiedNamespacePackage/a.after.py new file mode 100644 index 000000000000..c0b0b049717a --- /dev/null +++ b/python/testData/completion/importQualifiedNamespacePackage/a.after.py @@ -0,0 +1 @@ +import nspkg1.foo diff --git a/python/testData/completion/importQualifiedNamespacePackage/a.py b/python/testData/completion/importQualifiedNamespacePackage/a.py new file mode 100644 index 000000000000..737dcb8bad5d --- /dev/null +++ b/python/testData/completion/importQualifiedNamespacePackage/a.py @@ -0,0 +1 @@ +import nspkg1.f diff --git a/python/testData/completion/importQualifiedNamespacePackage/nspkg1/bar.py b/python/testData/completion/importQualifiedNamespacePackage/nspkg1/bar.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testData/completion/importQualifiedNamespacePackage/nspkg1/foo.py b/python/testData/completion/importQualifiedNamespacePackage/nspkg1/foo.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/python/testSrc/com/jetbrains/python/Py3CompletionTest.java b/python/testSrc/com/jetbrains/python/Py3CompletionTest.java index ca7c3c2649f3..9c87e473dd56 100644 --- a/python/testSrc/com/jetbrains/python/Py3CompletionTest.java +++ b/python/testSrc/com/jetbrains/python/Py3CompletionTest.java @@ -69,6 +69,13 @@ public class Py3CompletionTest extends PyTestCase { myFixture.checkResultByFile(testName + ".after.py"); } + private void doMultiFileTest() { + myFixture.copyDirectoryToProject("completion/" + getTestName(true), ""); + myFixture.configureByFile("a.py"); + myFixture.completeBasic(); + myFixture.checkResultByFile("completion/" + getTestName(true) + "/a.after.py"); + } + private List doTestByText(String text) { myFixture.configureByText(PythonFileType.INSTANCE, text); myFixture.completeBasic(); @@ -93,4 +100,19 @@ public class Py3CompletionTest extends PyTestCase { setLanguageLevel(null); } } + + // PY-7375 + public void testImportNamespacePackage() { + doMultiFileTest(); + } + + // PY-5422 + public void testImportQualifiedNamespacePackage() { + doMultiFileTest(); + } + + // PY-6477 + public void testFromQualifiedNamespacePackageImport() { + doMultiFileTest(); + } } diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 4a9f2b5fe5cb..bae70d18ab02 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1375,7 +1375,6 @@ -