Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2014-11-06 18:01:45 +01:00
80 changed files with 759 additions and 659 deletions
@@ -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<JavaRunConfigu
public AppletConfiguration(@NotNull Project project, ConfigurationFactory factory) {
super(new JavaRunConfigurationModule(project, false), factory);
mySerializer = new SmartSerializer(project.isDefault(), true);
mySerializer = new SmartSerializer(!project.isDefault(), true);
}
@Override
@@ -193,12 +193,18 @@ public class AppletConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
@Override
public void readExternal(final Element parentNode) throws InvalidDataException {
mySerializer.readExternal(this, parentNode);
readModule(parentNode);
final ArrayList<AppletParameter> parameters = new ArrayList<AppletParameter>();
for (final Element element : parentNode.getChildren(PARAMETER_ELEMENT_NAME)) {
parameters.add(new AppletParameter(element.getAttributeValue(NAME_ATTR), element.getAttributeValue(VALUE_ATTR)));
List<Element> paramList = parentNode.getChildren(PARAMETER_ELEMENT_NAME);
if (paramList.isEmpty()) {
myAppletParameters = null;
}
else {
List<AppletParameter> parameters = new SmartList<AppletParameter>();
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<JavaRunConfigu
@Override
public void writeExternal(final Element parentNode) throws WriteExternalException {
writeModule(parentNode);
mySerializer.writeExternal(this, parentNode);
if (myAppletParameters != null) {
for (AppletParameter myAppletParameter : myAppletParameters) {
@@ -227,6 +232,7 @@ public class AppletConfiguration extends ModuleBasedConfiguration<JavaRunConfigu
}
@Override
@Transient
public PsiClass getMainClass() {
return getConfigurationModule().findClass(MAIN_CLASS_NAME);
}
@@ -58,7 +58,9 @@ public class JavaFilterLexer extends BaseFilterLexer {
if (tokenType == JavaTokenType.IDENTIFIER
|| tokenType == JavaTokenType.LONG_LITERAL
|| tokenType == JavaTokenType.INTEGER_LITERAL
|| tokenType == JavaTokenType.CHARACTER_LITERAL) {
|| tokenType == JavaTokenType.CHARACTER_LITERAL
|| tokenType == JavaTokenType.ARROW
|| tokenType == JavaTokenType.DOUBLE_COLON) {
addOccurrenceInToken(UsageSearchContext.IN_CODE);
}
else if (tokenType == JavaTokenType.STRING_LITERAL) {
@@ -1,50 +0,0 @@
/*
* 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.
*/
/*
* @author max
*/
package com.intellij.psi.impl.java.stubs.index;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.impl.search.JavaSourceFilterScope;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.stubs.StringStubIndexExtension;
import com.intellij.psi.stubs.StubIndex;
import com.intellij.psi.stubs.StubIndexKey;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
public class JavaMethodParameterTypesIndex extends StringStubIndexExtension<PsiMethod> {
private static final JavaMethodParameterTypesIndex ourInstance = new JavaMethodParameterTypesIndex();
public static JavaMethodParameterTypesIndex getInstance() {
return ourInstance;
}
@NotNull
@Override
public StubIndexKey<String, PsiMethod> getKey() {
return JavaStubIndexKeys.METHOD_TYPES;
}
@Override
public Collection<PsiMethod> get(@NotNull final String s, @NotNull final Project project, @NotNull final GlobalSearchScope scope) {
return StubIndex.getElements(getKey(), s, project, new JavaSourceFilterScope(scope), PsiMethod.class);
}
}
@@ -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<PsiFunctionalExpression, FunctionalExpressionSearch.SearchParameters> {
private static final Logger LOG = Logger.getInstance("#" + JavaFunctionalExpressionSearcher.class.getName());
@Override
public boolean execute(@NotNull final FunctionalExpressionSearch.SearchParameters queryParameters,
@NotNull final Processor<PsiFunctionalExpression> consumer) {
@@ -98,102 +100,75 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor<PsiFuncti
return searchScope.intersectWith(classScope);
}
});
final Project project = PsiUtilCore.getProjectInReadAction(aClass);
final GlobalSearchScope scope = new ModulesScope(highLevelModules, project)
.intersectWith(useScope instanceof GlobalSearchScope ? (GlobalSearchScope)useScope : new EverythingGlobalScope(project));
final Collection<PsiMethod> lambdaCandidates = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiMethod>>() {
final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex();
CommonProcessors.CollectProcessor<VirtualFile> processor = new CommonProcessors.CollectProcessor<VirtualFile>() {
@Override
public Collection<PsiMethod> compute() {
final String functionalInterfaceName = aClass.getName();
final GlobalSearchScope useClassScope = classScope instanceof GlobalSearchScope ? (GlobalSearchScope)classScope : scope;
JavaMethodParameterTypesIndex parameterTypesIndex = JavaMethodParameterTypesIndex.getInstance();
LinkedHashSet<PsiMethod> methods = new LinkedHashSet<PsiMethod>(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<Boolean>() {
@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<Boolean>() {
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<VirtualFile> 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<Boolean>() {
@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<PsiReturnStatement[]>() {
@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<PsiFunctionalExpression> consumer,
final PsiManager psiManager, VirtualFile file) {
final PsiFile psiFile = psiManager.findFile(file);
if (psiFile != null) {
final Ref<Boolean> ref = new Ref<Boolean>(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;
}
@@ -50,7 +50,6 @@ import java.util.Set;
* @author max
*/
public abstract class JavaMethodElementType extends JavaStubElementType<PsiMethodStub, PsiMethod> {
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<PsiMetho
sink.occurrence(JavaStubIndexKeys.JVM_STATIC_MEMBERS_TYPES, stub.getReturnTypeText(false).getShortTypeText());
}
}
Set<String> 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<String>();
}
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;
}
}
}
}
@@ -29,7 +29,6 @@ public class JavaStubIndexKeys {
public static final StubIndexKey<String, PsiMember> JVM_STATIC_MEMBERS_NAMES = StubIndexKey.createIndexKey("jvm.static.member.name");
public static final StubIndexKey<String, PsiMember> JVM_STATIC_MEMBERS_TYPES = StubIndexKey.createIndexKey("jvm.static.member.type");
public static final StubIndexKey<String, PsiAnonymousClass> ANONYMOUS_BASEREF = StubIndexKey.createIndexKey("java.anonymous.baseref");
public static final StubIndexKey<String, PsiMethod> METHOD_TYPES = StubIndexKey.createIndexKey("java.method.parameter.types");
public static final StubIndexKey<String, PsiClass> CLASS_SHORT_NAMES = StubIndexKey.createIndexKey("java.class.shortname");
public static final StubIndexKey<Integer,PsiClass> CLASS_FQN = StubIndexKey.createIndexKey("java.class.fqn");
@@ -38,7 +38,7 @@ import java.io.IOException;
* @author max
*/
public class JavaFileElementType extends ILightStubFileElementType<PsiJavaFileStub> {
public static final int STUB_VERSION = 18;
public static final int STUB_VERSION = 19;
public JavaFileElementType() {
super("java.FILE", JavaLanguage.INSTANCE);
@@ -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();
}
@@ -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<String, JpsRunConfigurationPropertiesSerializer<?>> serializers = new HashMap<String, JpsRunConfigurationPropertiesSerializer<?>>();
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");
}
}
}
@@ -0,0 +1,4 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="invalid">
</configuration>
</component>
@@ -45,6 +45,8 @@
<patterns />
<method />
</configuration>
<configuration default="false" name="invalid">
</configuration>
</component>
</project>
@@ -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);
}
}
}
@@ -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<JsonStandardComplianceProvider> 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;
}
}
@@ -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
@@ -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");
}
@@ -91,7 +91,7 @@ public class IdIndex extends FileBasedIndexExtension<IdIndexEntry, Integer> {
@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
@@ -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<ConfigurationModule extends RunConfigurationModule> 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";
@@ -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);
@@ -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);
}
@@ -1192,6 +1192,10 @@ public abstract class ChooseByNameBase {
myPostponedOkAction = null;
}
public boolean hasPostponedAction() {
return myPostponedOkAction != null;
}
protected abstract void showList();
protected abstract void hideList();
@@ -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),
};
@@ -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
@@ -58,4 +58,10 @@
implementationClass="com.intellij.json.psi.JsonStringLiteralManipulator"/>
</extensions>
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.json.jsonStandardComplianceProvider"
interface="com.intellij.json.codeinsight.JsonStandardComplianceProvider"/>
</extensionPoints>
</idea-plugin>
@@ -57,6 +57,7 @@ public interface FileIndex {
/**
* Returns true if <code>file</code> is a source file which belongs to sources of the content.
* (Returns true for both source and test source).<p/>
* 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).
*
@@ -125,7 +125,7 @@ public interface ProjectFileIndex extends FileIndex {
boolean isLibraryClassFile(@NotNull VirtualFile file);
/**
* Returns true if <code>fileOrDir</code> is a file or directory from the content source or library sources.
* Returns true if <code>fileOrDir</code> 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.
+14 -2
View File
@@ -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<Color>() {
@NotNull
@Override
public Color produce() {
return UIUtil.getLabelForeground();
}
});
}
public static Color background() {
return UIUtil.getListBackground();
return new JBColor(new NotNullProducer<Color>() {
@NotNull
@Override
public Color produce() {
return UIUtil.getListBackground();
}
});
}
public static Color border() {
@@ -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<K, V> extends MultiMap<K, V> {
@NotNull
@Override
protected Map<K, Collection<V>> createMap() {
return new LinkedHashMap<K, Collection<V>>();
}
@NotNull
@Override
protected Map<K, Collection<V>> createMap() {
return new LinkedHashMap<K, Collection<V>>();
}
@NotNull
@Override
protected Map<K, Collection<V>> createMap(int initialCapacity, float loadFactor) {
return new LinkedHashMap<K, Collection<V>>(initialCapacity, loadFactor);
}
@NotNull
@Override
protected Map<K, Collection<V>> createMap(int initialCapacity, float loadFactor) {
return new LinkedHashMap<K, Collection<V>>(initialCapacity, loadFactor);
}
}
@@ -63,7 +63,7 @@ public class MultiMap<K, V> implements Serializable {
@NotNull
protected Collection<V> createCollection() {
return new ArrayList<V>();
return new SmartList<V>();
}
@NotNull
@@ -261,12 +261,6 @@ public class MultiMap<K, V> implements Serializable {
protected Map<K, Collection<V>> createMap() {
return new THashMap<K, Collection<V>>(strategy);
}
@NotNull
@Override
protected Collection<V> createCollection() {
return new SmartList<V>();
}
};
}
@@ -289,12 +283,6 @@ public class MultiMap<K, V> implements Serializable {
@NotNull
public static <K, V> MultiMap<K, V> createSmartList() {
return new MultiMap<K, V>() {
@NotNull
@Override
protected Collection<V> createCollection() {
return new SmartList<V>();
}
@NotNull
@Override
protected Map<K, Collection<V>> createMap() {
@@ -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<Color>() {
@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"})
@@ -39,4 +39,6 @@ public interface Accessor {
Class<?> getValueClass();
Type getGenericType();
boolean isFinal();
}
@@ -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;
}
@@ -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 + "]";
}
}
@@ -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<Binding> 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<Binding> computeOrderedBindings(@NotNull LinkedHashSet<String> accessorNameTracker) {
final TObjectDoubleHashMap<String> weights = new TObjectDoubleHashMap<String>(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<Binding>() {
@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<String> accessorNameTracker) {
Set<Binding> bindings = myPropertyBindings.keySet();
MultiMap<Binding, Object> data = MultiMap.createSmartList();
MultiMap<Binding, Object> 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<Accessor> 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<Accessor> 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
@@ -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() + "]";
@@ -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);
}
@@ -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() +"]";
@@ -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;
}
@@ -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<String> mySerializedAccessorNameTracker;
private final LinkedHashSet<String> mySerializedAccessorNameTracker;
private List<Binding> myOrderedBindings;
private final SerializationFilter mySerializationFilter;
public SmartSerializer(boolean trackSerializedNames, boolean useSkipEmptySerializationFilter) {
mySerializedAccessorNameTracker = trackSerializedNames ? new THashSet<String>() : null;
mySerializedAccessorNameTracker = trackSerializedNames ? new LinkedHashSet<String>() : 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);
}
}
@@ -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<? extends Content> 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<Content> childrenList = new SmartList<Content>();
children = new SmartList<Content>();
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.<Content>singletonList(new Text(myTextIfEmpty));
}
Object v = myBinding.deserialize(myAccessor.read(o), ArrayUtil.toObjectArray(children));
myAccessor.write(o, XmlSerializerImpl.convert(v, myAccessor.getValueClass()));
}
return o;
}
@@ -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) {
@@ -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("<BeanWithDefaultAttributeName foo=\"foo\" />", 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("<Bean2 ab=\"ab\" module=\"module\" />", bean);
checkSmartSerialization(new Bean2(), "<Bean2 module=\"1\" ab=\"2\" ac=\"32\" />");
checkSmartSerialization(new Bean2(), "<Bean2 ab=\"2\" module=\"1\" ac=\"32\" />");
checkSmartSerialization(new Bean2(), "<Bean2 ac=\"2\" module=\"1\" ab=\"32\" />");
checkSmartSerialization(new Bean2(), "<Bean2 ac=\"2\" ab=\"32\" />");
}
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<T> aClass = (Class<T>)bean.getClass();
T o = XmlSerializer.deserialize(element, aClass);
assertSerializer(o, expectedText, "Deserialization failure", filter);
@@ -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<Range.InnerRange> 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);
}
}
@@ -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
@@ -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);
}
@@ -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();
+9 -64
View File
@@ -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<GitBranchTrackInfo> NOT_NULL_PREDICATE = new Predicate<GitBranchTrackInfo>() {
@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<VirtualFile, List<FilePath>> sortGitFilePathsByGitRoot(Collection<FilePath> 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<GitRemote>() {
public static GitRemote findRemoteByName(@NotNull GitRepository repository, @NotNull final String name) {
return findRemoteByName(repository.getRemotes(), name);
}
@Nullable
public static GitRemote findRemoteByName(Collection<GitRemote> remotes, @NotNull final String name) {
return ContainerUtil.find(remotes, new Condition<GitRemote>() {
@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<GitRemote, GitRemoteBranch> findMatchingRemoteBranch(GitRepository repository, GitLocalBranch branch)
throws VcsException {
/*
from man git-push:
git push
Works like git push <remote>, where <remote> 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<GitRemote> 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<VirtualFile> getRootsFromRepositories(@NotNull Collection<GitRepository> repositories) {
Collection<VirtualFile> roots = new ArrayList<VirtualFile>(repositories.size());
@@ -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<TransactionRunnable> myDelayedTasks = new ArrayList<TransactionRunnable>();
/**
* {@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<VirtualFile> roots = getGitRoots(project, vcs);
if (roots == null) return;
@@ -196,9 +182,6 @@ public abstract class GitRepositoryAction extends DumbAwareAction {
final Set<VirtualFile> affectedRoots,
List<VcsException> exceptions) throws VcsException;
/**
* {@inheritDoc}
*/
@Override
public void update(final AnActionEvent e) {
super.update(e);
@@ -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<GitRemote> 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.<String>emptyList(), Collections.<String>emptyList(),
Collections.<String>emptyList(), Collections.<String>emptyList());
return new GitStandardRemoteBranch(fakeRemote, branchName, hash);
}
return new GitStandardRemoteBranch(remote, branchName, hash);
}
}
@Nullable
private static GitRemote findRemoteByName(@NotNull String remoteName, @NotNull Collection<GitRemote> 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<GitLocalBranch> optional = Iterables.tryFind(repository.getBranches().getLocalBranches(), new Predicate<GitLocalBranch>() {
@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<GitRemoteBranch> remoteBranches) {
final String branchName = stripRefsPrefix(remoteBranchName);
Optional<GitRemoteBranch> optional = Iterables.tryFind(remoteBranches, new Predicate<GitRemoteBranch>() {
@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)) {
@@ -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);
}
});
}
@@ -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<GitRemoteBranch> remoteBranches = new ArrayList<GitRemoteBranch>(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<GitRemoteBranch, String>() {
@Override
public String fun(GitRemoteBranch branch) {
return branch.getName();
}
}
}), false);
myBranchChooser.setElementMarked(currentRemoteBranch, true);
validateDialog();
}
@@ -158,7 +158,7 @@ public class GitConfig {
Pair<Collection<Remote>, Collection<Url>> remotesAndUrls = parseRemotes(ini, classLoader);
Collection<BranchConfig> 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<GitLocalBranch> localBranches) {
final String name = GitBranchUtil.stripRefsPrefix(branchName);
try {
return ContainerUtil.find(localBranches, new Condition<GitLocalBranch>() {
@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<GitLocalBranch>() {
@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<GitRemoteBranch> remoteBranches) {
final String branchName = GitBranchUtil.stripRefsPrefix(remoteBranchName);
return ContainerUtil.find(remoteBranches, new Condition<GitRemoteBranch>() {
@Override
public boolean value(GitRemoteBranch branch) {
return branch.getNameForRemoteOperations().equals(branchName) && branch.getRemote().getName().equals(remoteName);
}
});
}
@Nullable
@@ -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);
}
}
@@ -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<GitRemote> 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.<String>emptyList(), Collections.<String>emptyList(),
Collections.<String>emptyList(), Collections.<String>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);
@@ -103,7 +103,7 @@ public class GitMultiRootBranchConfig extends DvcsMultiRootBranchConfig<GitRepos
@Nullable
private static GitRemoteBranch getTrackedBranch(@NotNull GitRepository repository, @NotNull String branchName) {
GitLocalBranch branch = GitBranchUtil.findLocalBranchByName(repository, branchName);
GitLocalBranch branch = repository.getBranches().findLocalBranch(branchName);
return branch == null ? null : branch.findTrackedBranch(repository);
}
@@ -0,0 +1 @@
ref: refs/remotes/origin/master
@@ -131,6 +131,20 @@ public class GitLogProviderTest extends GitSingleRepoTest {
assertEquals("User email is incorrect", expected.getEmail(), user.getEmail());
}
public void test_dont_report_origin_HEAD() throws Exception {
prepareSomeHistory();
git("update-ref refs/remotes/origin/HEAD master");
VcsLogProvider.DetailedLogData block = myLogProvider.readFirstBlock(myProjectRoot,
new RequirementsImpl(1000, false, Collections.<VcsRef>emptySet()));
assertFalse("origin/HEAD should be ignored", ContainerUtil.exists(block.getRefs(), new Condition<VcsRef>() {
@Override
public boolean value(VcsRef ref) {
return ref.getName().equals("origin/HEAD");
}
}));
}
private static void prepareSomeHistory() {
tac("a.txt");
git("tag ATAG");
@@ -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("<html>Press SHIFT to merge with current context<br/>" +
"Pressing " +
@@ -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<List<Task>> oldFeature = myFutureReference.getAndSet(future);
if (oldFeature != null) {
Future<List<Task>> 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<Task> tasks = future.get();
List<Task> 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().
+5 -2
View File
@@ -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) {
+5 -4
View File
@@ -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:]
@@ -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());
}
@@ -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("");
@@ -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;
}
@@ -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;
}
@@ -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<String>();
myObjects = new ArrayList<Object>();
@@ -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<LookupElement> 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<LookupElement> 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));
}
}
}
@@ -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() {
@@ -245,7 +245,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje
* not suitable for import.
*/
@NotNull
private static List<PsiFileSystemItem> getSubmodulesList(final PsiDirectory directory) {
private static List<PsiFileSystemItem> getSubmodulesList(final PsiDirectory directory, @Nullable PsiElement anchor) {
List<PsiFileSystemItem> result = new ArrayList<PsiFileSystemItem>();
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<String> namesAlready) {
List<LookupElement> result = new ArrayList<LookupElement>();
for (PsiFileSystemItem item : getSubmodulesList(directory)) {
for (PsiFileSystemItem item : getSubmodulesList(directory, location)) {
if (item != location.getContainingFile().getOriginalFile()) {
LookupElement lookupElement = buildFileLookupElement(item, namesAlready);
if (lookupElement != null) {
@@ -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<PsiReference> allRefs = Collections.synchronizedList(new ArrayList<PsiReference>());
allRefs.addAll(super.findReferences(element));
ReferencesSearch.search(initMethod).forEach(new Processor<PsiReference>() {
ReferencesSearch.search(initMethod, GlobalSearchScope.projectScope(element.getProject())).forEach(new Processor<PsiReference>() {
@Override
public boolean process(PsiReference psiReference) {
if (psiReference.getCanonicalText().equals(((PyClass)element).getName())) {
@@ -0,0 +1 @@
from nspkg1.foo import
@@ -0,0 +1 @@
from nspkg1.f<caret>
@@ -0,0 +1 @@
import nspkg1
@@ -0,0 +1 @@
import nspk<caret>
@@ -0,0 +1 @@
import nspkg1.foo
@@ -0,0 +1 @@
import nspkg1.f<caret>
@@ -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<String> 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();
}
}
-1
View File
@@ -1375,7 +1375,6 @@
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaStaticMemberTypeIndex"/>
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaShortClassNameIndex"/>
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaSuperClassNameOccurenceIndex"/>
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaMethodParameterTypesIndex"/>
<fileBasedIndex implementation="com.intellij.codeInspection.bytecodeAnalysis.BytecodeAnalysisIndex"/>
<fileBasedIndex implementation="com.intellij.psi.RefQueueIndex"/>