diff --git a/python/openapi/src/com/jetbrains/python/module/PyModuleService.java b/python/openapi/src/com/jetbrains/python/module/PyModuleService.java new file mode 100644 index 000000000000..69214ec32be5 --- /dev/null +++ b/python/openapi/src/com/jetbrains/python/module/PyModuleService.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2013 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.jetbrains.python.module; + +import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.platform.DirectoryProjectGenerator; + +/** + * @author yole + */ +public abstract class PyModuleService { + public static PyModuleService getInstance() { + return ServiceManager.getService(PyModuleService.class); + } + + /** + * Creates a ModuleBuilder that creates a Python module and runs the specified DirectoryProjectGenerator to perform + * further initialization. The showGenerationSettings() method on the generator is not called, and the generateProject() method + * receives null as the 'settings' parameter. + * + * @param generator the generator to run for configuring the project + * @return the created module builder instance + */ + public abstract ModuleBuilder createPythonModuleBuilder(DirectoryProjectGenerator generator); +} diff --git a/python/pluginSrc/META-INF/plugin.xml b/python/pluginSrc/META-INF/plugin.xml index 43e155672c5a..f80bd2ad9048 100644 --- a/python/pluginSrc/META-INF/plugin.xml +++ b/python/pluginSrc/META-INF/plugin.xml @@ -4,9 +4,9 @@ Pythonid Python - + Smart editing for Python scripts - 2.10.0 + 2.10.1 com.intellij.modules.ultimate com.intellij.modules.java Coverage diff --git a/python/pluginSrc/com/jetbrains/python/facet/PythonSdkComboBox.java b/python/pluginSrc/com/jetbrains/python/facet/PythonSdkComboBox.java index d15dc5fe8000..fdc618439981 100644 --- a/python/pluginSrc/com/jetbrains/python/facet/PythonSdkComboBox.java +++ b/python/pluginSrc/com/jetbrains/python/facet/PythonSdkComboBox.java @@ -4,9 +4,9 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.projectRoots.ProjectJdkTable; import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.impl.SdkListCellRenderer; import com.intellij.openapi.projectRoots.ui.ProjectJdksEditor; import com.intellij.ui.ComboboxWithBrowseButton; +import com.jetbrains.python.sdk.PySdkListCellRenderer; import com.jetbrains.python.sdk.PythonSdkType; import javax.swing.*; @@ -21,7 +21,7 @@ public class PythonSdkComboBox extends ComboboxWithBrowseButton { private Project myProject; public PythonSdkComboBox() { - getComboBox().setRenderer(new SdkListCellRenderer("")); + getComboBox().setRenderer(new PySdkListCellRenderer("", null)); addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { Sdk selectedSdk = getSelectedSdk(); diff --git a/python/pluginSrc/com/jetbrains/python/module/PythonModuleBuilder.java b/python/pluginSrc/com/jetbrains/python/module/PythonModuleBuilder.java index 4705b895ad6c..fa0916a41a02 100644 --- a/python/pluginSrc/com/jetbrains/python/module/PythonModuleBuilder.java +++ b/python/pluginSrc/com/jetbrains/python/module/PythonModuleBuilder.java @@ -1,14 +1,7 @@ package com.jetbrains.python.module; -import com.intellij.ide.util.projectWizard.ModuleBuilder; import com.intellij.ide.util.projectWizard.SourcePathsBuilder; -import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.projectRoots.SdkTypeId; -import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.util.Pair; -import com.jetbrains.python.sdk.PythonSdkType; import java.util.ArrayList; import java.util.List; @@ -16,25 +9,8 @@ import java.util.List; /** * @author yole */ -public class PythonModuleBuilder extends ModuleBuilder implements SourcePathsBuilder { +public class PythonModuleBuilder extends PythonModuleBuilderBase implements SourcePathsBuilder { private List> mySourcePaths; - private Sdk mySdk; - private final List mySdkChangedListeners = new ArrayList(); - - public void setupRootModel(final ModifiableRootModel rootModel) throws ConfigurationException { - if (mySdk != null) { - rootModel.setSdk(mySdk); - } - else { - rootModel.inheritSdk(); - } - - doAddContentEntry(rootModel); - } - - public ModuleType getModuleType() { - return PythonModuleType.getInstance(); - } public List> getSourcePaths() { return mySourcePaths; @@ -50,26 +26,4 @@ public class PythonModuleBuilder extends ModuleBuilder implements SourcePathsBui } mySourcePaths.add(sourcePathInfo); } - - public Sdk getSdk() { - return mySdk; - } - - public void setSdk(final Sdk sdk) { - if (mySdk != sdk) { - mySdk = sdk; - for (Runnable runnable : mySdkChangedListeners) { - runnable.run(); - } - } - } - - public void addSdkChangedListener(Runnable runnable) { - mySdkChangedListeners.add(runnable); - } - - @Override - public boolean isSuitableSdkType(SdkTypeId sdk) { - return sdk instanceof PythonSdkType; - } } diff --git a/python/pluginSrc/com/jetbrains/python/module/PythonModuleType.java b/python/pluginSrc/com/jetbrains/python/module/PythonModuleType.java index 1c80deca9a3d..b877b374d3d4 100644 --- a/python/pluginSrc/com/jetbrains/python/module/PythonModuleType.java +++ b/python/pluginSrc/com/jetbrains/python/module/PythonModuleType.java @@ -6,7 +6,6 @@ import com.intellij.ide.util.frameworkSupport.FrameworkSupportUtil; import com.intellij.ide.util.newProjectWizard.SupportForFrameworksStep; import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.WizardContext; -import com.intellij.openapi.module.ModuleTypeManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.roots.ui.configuration.ModulesProvider; @@ -19,14 +18,10 @@ import java.util.List; /** * @author yole */ -public class PythonModuleType extends PythonModuleTypeBase { - public static PythonModuleType getInstance() { - return (PythonModuleType)ModuleTypeManager.getInstance().findByID(PYTHON_MODULE); - } - +public class PythonModuleType extends PythonModuleTypeBase { @Override public ModuleWizardStep[] createWizardSteps(final WizardContext wizardContext, - final PythonModuleBuilder moduleBuilder, + final PythonModuleBuilderBase moduleBuilder, final ModulesProvider modulesProvider) { ArrayList steps = new ArrayList(); final Project project = getProject(wizardContext); diff --git a/python/pluginSrc/com/jetbrains/python/module/PythonSdkSelectStep.java b/python/pluginSrc/com/jetbrains/python/module/PythonSdkSelectStep.java index b3526b050e4b..d9277d6f3f5d 100644 --- a/python/pluginSrc/com/jetbrains/python/module/PythonSdkSelectStep.java +++ b/python/pluginSrc/com/jetbrains/python/module/PythonSdkSelectStep.java @@ -13,11 +13,11 @@ import javax.swing.*; */ public class PythonSdkSelectStep extends ModuleWizardStep { protected final PythonSdkChooserPanel myPanel; - protected final PythonModuleBuilder mySettingsHolder; + protected final PythonModuleBuilderBase mySettingsHolder; private final String myHelp; - public PythonSdkSelectStep(@NotNull final PythonModuleBuilder settingsHolder, + public PythonSdkSelectStep(@NotNull final PythonModuleBuilderBase settingsHolder, @Nullable final String helpId, @Nullable final Project project) { super(); diff --git a/python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java b/python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java index 10df2be1d38f..b77d612da2d0 100644 --- a/python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java +++ b/python/pluginSrc/com/jetbrains/python/packaging/PyManagePackagesDialog.java @@ -7,6 +7,7 @@ import com.intellij.openapi.ui.LabeledComponent; import com.intellij.ui.CollectionComboBoxModel; import com.jetbrains.python.packaging.ui.PyPackagesNotificationPanel; import com.jetbrains.python.packaging.ui.PyPackagesPanel; +import com.jetbrains.python.sdk.PreferredSdkComparator; import com.jetbrains.python.sdk.PySdkListCellRenderer; import com.jetbrains.python.sdk.PythonSdkType; import org.jetbrains.annotations.NotNull; @@ -15,6 +16,8 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.*; +import java.util.List; /** * @author yole @@ -26,8 +29,10 @@ public class PyManagePackagesDialog extends DialogWrapper { super(project, true); setTitle("Manage Python Packages"); - final JComboBox sdkComboBox = new JComboBox(new CollectionComboBoxModel(PythonSdkType.getAllSdks(), sdk)); - sdkComboBox.setRenderer(new PySdkListCellRenderer(null)); + List sdks = PythonSdkType.getAllSdks(); + Collections.sort(sdks, new PreferredSdkComparator()); + final JComboBox sdkComboBox = new JComboBox(new CollectionComboBoxModel(sdks, sdk)); + sdkComboBox.setRenderer(new PySdkListCellRenderer()); PyPackagesNotificationPanel notificationPanel = new PyPackagesNotificationPanel(project); final PyPackagesPanel packagesPanel = new PyPackagesPanel(project, notificationPanel); diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java index d1667a07eed5..c9d212cb6ddd 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java @@ -7,9 +7,11 @@ import com.intellij.psi.ResolveState; import com.intellij.util.ProcessingContext; import com.jetbrains.python.psi.AccessDirection; import com.jetbrains.python.psi.PyExpression; +import com.jetbrains.python.psi.PyQualifiedExpression; import com.jetbrains.python.psi.resolve.CompletionVariantsProcessor; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; +import com.jetbrains.python.psi.types.PyCallableType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.NotNull; @@ -20,11 +22,13 @@ import java.util.List; /** * @author yole */ -public class PyJavaClassType implements PyType { +public class PyJavaClassType implements PyCallableType { private final PsiClass myClass; + private final boolean myDefinition; - public PyJavaClassType(final PsiClass aClass) { + public PyJavaClassType(final PsiClass aClass, boolean definition) { myClass = aClass; + myDefinition = definition; } @Nullable @@ -68,4 +72,18 @@ public class PyJavaClassType implements PyType { @Override public void assertValid(String message) { } + + @Override + public boolean isCallable() { + return myDefinition; + } + + @Nullable + @Override + public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { + if (myDefinition) { + return new PyJavaClassType(myClass, false); + } + return null; + } } diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaTypeProvider.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaTypeProvider.java index 369894203038..9d186f315c9e 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaTypeProvider.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaTypeProvider.java @@ -23,7 +23,7 @@ public class PyJavaTypeProvider extends PyTypeProviderBase { @Nullable public PyType getReferenceType(@NotNull final PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor) { if (referenceTarget instanceof PsiClass) { - return new PyJavaClassType((PsiClass) referenceTarget); + return new PyJavaClassType((PsiClass) referenceTarget, true); } if (referenceTarget instanceof PsiPackage) { return new PyJavaPackageType((PsiPackage) referenceTarget, anchor == null ? null : ModuleUtil.findModuleForPsiElement(anchor)); @@ -44,7 +44,7 @@ public class PyJavaTypeProvider extends PyTypeProviderBase { final PsiClassType classType = (PsiClassType)type; final PsiClass psiClass = classType.resolve(); if (psiClass != null) { - return new PyJavaClassType(psiClass); + return new PyJavaClassType(psiClass, false); } } return null; @@ -67,7 +67,7 @@ public class PyJavaTypeProvider extends PyTypeProviderBase { if (paramType instanceof PsiClassType) { final PsiClass psiClass = ((PsiClassType)paramType).resolve(); if (psiClass != null) { - superMethodParameterTypes.add(new PyJavaClassType(psiClass)); + superMethodParameterTypes.add(new PyJavaClassType(psiClass, false)); } } } diff --git a/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form b/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form index 0ab940aa09cf..ba62e38b0472 100644 --- a/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form +++ b/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.form @@ -1,114 +1,113 @@
- + - + - - + - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java b/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java index 55f62734aa76..4b29678cbcba 100644 --- a/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java +++ b/python/pluginSrc/com/jetbrains/python/run/PyPluginCommonOptionsForm.java @@ -2,10 +2,14 @@ package com.jetbrains.python.run; import com.intellij.execution.configuration.EnvironmentVariablesComponent; import com.intellij.ide.util.PropertiesComponent; +import com.intellij.execution.util.PathMappingsComponent; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.SdkListCellRenderer; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.io.FileUtil; @@ -14,6 +18,8 @@ import com.intellij.ui.HideableDecorator; import com.intellij.ui.RawCommandLineEditor; import com.intellij.ui.components.JBLabel; import com.intellij.util.PathMappingSettings; +import com.jetbrains.python.sdk.PreferredSdkComparator; +import com.jetbrains.python.sdk.PySdkUtil; import com.jetbrains.python.sdk.PythonSdkType; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -30,6 +36,7 @@ import java.util.Map; * @author yole */ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm { + private final Project myProject; private TextFieldWithBrowseButton myWorkingDirectoryTextField; private EnvironmentVariablesComponent myEnvsComponent; private RawCommandLineEditor myInterpreterOptionsTextField; @@ -42,11 +49,13 @@ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm { private JBLabel myInterpreterOptionsJBLabel; private JBLabel myWorkingDirectoryJBLabel; private JPanel myHideablePanel; + private PathMappingsComponent myPathMappingsComponent; private JComponent labelAnchor; private final HideableDecorator myDecorator; public PyPluginCommonOptionsForm(PyCommonOptionsFormData data) { // setting modules + myProject = data.getProject(); final List validModules = data.getValidModules(); Collections.sort(validModules, new ModulesAlphaComparator()); Module selection = validModules.size() > 0 ? validModules.get(0) : null; @@ -64,6 +73,8 @@ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm { }; myUseSpecifiedSdkRadioButton.addActionListener(listener); myUseModuleSdkRadioButton.addActionListener(listener); + myInterpreterComboBox.addActionListener(listener); + myModuleComboBox.addActionListener(listener); setAnchor(myEnvsComponent.getLabel()); @@ -86,11 +97,14 @@ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm { }; myDecorator.setOn(PropertiesComponent.getInstance().getBoolean(EXPAND_PROPERTY_KEY, true)); myDecorator.setContentComponent(myMainPanel); + myPathMappingsComponent.setAnchor(myEnvsComponent.getLabel()); + updateControls(); } private void updateControls() { myModuleComboBox.setEnabled(myUseModuleSdkRadioButton.isSelected()); myInterpreterComboBox.setEnabled(myUseSpecifiedSdkRadioButton.isSelected()); + myPathMappingsComponent.setVisible(PySdkUtil.isRemote(getSelectedSdk())); } public JPanel getMainPanel() { @@ -137,6 +151,7 @@ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm { List sdkList = new ArrayList(); sdkList.add(null); final List allSdks = PythonSdkType.getAllSdks(); + Collections.sort(allSdks, new PreferredSdkComparator()); Sdk selection = null; for (Sdk sdk : allSdks) { String homePath = sdk.getHomePath(); @@ -187,11 +202,24 @@ public class PyPluginCommonOptionsForm implements AbstractPyCommonOptionsForm { @Override public PathMappingSettings getMappingSettings() { - return null; //TODO: implement for plugin + return myPathMappingsComponent.getMappingSettings(); } @Override public void setMappingSettings(@Nullable PathMappingSettings mappingSettings) { + myPathMappingsComponent.setMappingSettings(mappingSettings); + } + + private Sdk getSelectedSdk() { + if (isUseModuleSdk()) { + Module module = getModule(); + return module == null ? null : ModuleRootManager.getInstance(module).getSdk(); + } + Sdk sdk = (Sdk)myInterpreterComboBox.getSelectedItem(); + if (sdk == null) { + return ProjectRootManager.getInstance(myProject).getProjectSdk(); + } + return sdk; } @Override diff --git a/python/pluginTestSrc/com/jetbrains/jython/PyJythonHighlightingTest.java b/python/pluginTestSrc/com/jetbrains/jython/PyJythonHighlightingTest.java new file mode 100644 index 000000000000..8ddd01f29daf --- /dev/null +++ b/python/pluginTestSrc/com/jetbrains/jython/PyJythonHighlightingTest.java @@ -0,0 +1,22 @@ +package com.jetbrains.jython; + +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import com.jetbrains.python.PythonTestUtil; +import com.jetbrains.python.inspections.PyCallingNonCallableInspection; + +/** + * @author yole + */ +public class PyJythonHighlightingTest extends LightCodeInsightFixtureTestCase { + public void testCallableJavaClass() { + myFixture.configureByFile("callableJavaClass.py"); + myFixture.enableInspections(PyCallingNonCallableInspection.class); + myFixture.checkHighlighting(true, false, false); + } + + + @Override + protected String getTestDataPath() { + return PythonTestUtil.getTestDataPath() + "/highlighting/jython/"; + } +} diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java index 6c594c0755a2..74d0c2e8637c 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java @@ -11,6 +11,11 @@ import org.jetbrains.annotations.Nullable; * @author yole */ public interface PyCallableType extends PyType { + /** + * Returns true if the type is callable. + */ + boolean isCallable(); + /** * Returns the type which is the result of calling an instance of this type. * diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index 46f1629c1e8b..079051743919 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -71,6 +71,8 @@ + extends ModuleType { + public static ModuleType getInstance() { + return ModuleTypeManager.getInstance().findByID(PYTHON_MODULE); + } + @NonNls public static final String PYTHON_MODULE = "PYTHON_MODULE"; protected PythonModuleTypeBase() { diff --git a/python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java b/python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java index fd215072fe78..63f8003108a3 100644 --- a/python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java +++ b/python/src/com/jetbrains/python/formatter/PythonFormattingModelBuilder.java @@ -84,6 +84,7 @@ public class PythonFormattingModelBuilder implements FormattingModelBuilderEx, C .afterInside(GT, ANNOTATION).spaces(1) .betweenInside(MINUS, GT, ANNOTATION).none() .beforeInside(ANNOTATION, FUNCTION_DECLARATION).spaces(1) + .beforeInside(ANNOTATION, NAMED_PARAMETER).none() .between(allButLambda(), PARAMETER_LIST).spaceIf(commonSettings.SPACE_BEFORE_METHOD_PARENTHESES) diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddIgnoredIdentifierQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddIgnoredIdentifierQuickFix.java index c38ff2ed26ec..3ae2e3c076aa 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddIgnoredIdentifierQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddIgnoredIdentifierQuickFix.java @@ -1,12 +1,11 @@ package com.jetbrains.python.inspections.quickfix; import com.intellij.codeInsight.intention.LowPriorityAction; -import com.intellij.codeInspection.InspectionProfile; -import com.intellij.codeInspection.LocalQuickFix; -import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.*; import com.intellij.openapi.project.Project; -import com.intellij.profile.codeInspection.InspectionProfileManager; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import com.intellij.psi.PsiElement; +import com.intellij.util.Consumer; import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection; import com.jetbrains.python.psi.impl.PyQualifiedName; import org.jetbrains.annotations.NotNull; @@ -44,15 +43,21 @@ public class AddIgnoredIdentifierQuickFix implements LocalQuickFix, LowPriorityA @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - final PyUnresolvedReferencesInspection instance = PyUnresolvedReferencesInspection.getInstance(descriptor.getPsiElement()); - String name = myIdentifier.toString(); - if (myIgnoreAllAttributes) { - name = name + END_WILDCARD; - } - if (!instance.ignoredIdentifiers.contains(name)) { - instance.ignoredIdentifiers.add(name); - final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(); - InspectionProfileManager.getInstance().fireProfileChanged(profile); - } + final PsiElement context = descriptor.getPsiElement(); + InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile(context); + profile.modifyProfile(new Consumer() { + @Override + public void consume(ModifiableModel model) { + PyUnresolvedReferencesInspection inspection = + (PyUnresolvedReferencesInspection)model.getUnwrappedTool(PyUnresolvedReferencesInspection.class.getSimpleName(), context); + String name = myIdentifier.toString(); + if (myIgnoreAllAttributes) { + name += END_WILDCARD; + } + if (!inspection.ignoredIdentifiers.contains(name)) { + inspection.ignoredIdentifiers.add(name); + } + } + }); } } diff --git a/python/src/com/jetbrains/python/module/PyModuleServiceImpl.java b/python/src/com/jetbrains/python/module/PyModuleServiceImpl.java new file mode 100644 index 000000000000..eea9bae38852 --- /dev/null +++ b/python/src/com/jetbrains/python/module/PyModuleServiceImpl.java @@ -0,0 +1,14 @@ +package com.jetbrains.python.module; + +import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.platform.DirectoryProjectGenerator; + +/** + * @author yole + */ +public class PyModuleServiceImpl extends PyModuleService { + @Override + public ModuleBuilder createPythonModuleBuilder(DirectoryProjectGenerator generator) { + return new PythonModuleBuilderBase(generator); + } +} diff --git a/python/src/com/jetbrains/python/module/PythonModuleBuilderBase.java b/python/src/com/jetbrains/python/module/PythonModuleBuilderBase.java new file mode 100644 index 000000000000..58490f68fc9f --- /dev/null +++ b/python/src/com/jetbrains/python/module/PythonModuleBuilderBase.java @@ -0,0 +1,97 @@ +package com.jetbrains.python.module; + +import com.intellij.ide.util.projectWizard.ModuleBuilder; +import com.intellij.openapi.module.ModifiableModuleModel; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.SdkTypeId; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.platform.DirectoryProjectGenerator; +import com.jetbrains.python.PythonModuleTypeBase; +import com.jetbrains.python.sdk.PythonSdkType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author yole + */ +public class PythonModuleBuilderBase extends ModuleBuilder { + private final List mySdkChangedListeners = new ArrayList(); + private final DirectoryProjectGenerator myGenerator; + private Sdk mySdk; + + public PythonModuleBuilderBase() { + myGenerator = null; + } + + public PythonModuleBuilderBase(DirectoryProjectGenerator generator) { + myGenerator = generator; + } + + @Override + public String getGroupName() { + return "Python"; + } + + public void setupRootModel(final ModifiableRootModel rootModel) throws ConfigurationException { + if (mySdk != null) { + rootModel.setSdk(mySdk); + } + else { + rootModel.inheritSdk(); + } + + doAddContentEntry(rootModel); + } + + @Override + public ModuleType getModuleType() { + return PythonModuleTypeBase.getInstance(); + } + + public Sdk getSdk() { + return mySdk; + } + + public void setSdk(final Sdk sdk) { + if (mySdk != sdk) { + mySdk = sdk; + for (Runnable runnable : mySdkChangedListeners) { + runnable.run(); + } + } + } + + public void addSdkChangedListener(Runnable runnable) { + mySdkChangedListeners.add(runnable); + } + + @Override + public boolean isSuitableSdkType(SdkTypeId sdk) { + return sdk instanceof PythonSdkType; + } + + @Nullable + @Override + public Module commitModule(@NotNull Project project, @Nullable ModifiableModuleModel model) { + Module module = super.commitModule(project, model); + if (module != null && myGenerator != null) { + ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); + VirtualFile[] contentRoots = moduleRootManager.getContentRoots(); + VirtualFile dir = module.getProject().getBaseDir(); + if (contentRoots.length > 0 && contentRoots[0] != null) { + dir = contentRoots[0]; + } + myGenerator.generateProject(project, dir, null, module); + } + return module; + } +} diff --git a/python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java b/python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java index 2eef93b5afd6..4122f513e4d2 100644 --- a/python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java +++ b/python/src/com/jetbrains/python/packaging/PyPIPackageUtil.java @@ -130,6 +130,7 @@ public class PyPIPackageUtil { myXmlRpcClient.executeAsync("release_data", params, callback); } catch (Exception ignored) { + LOG.info(ignored); } } else diff --git a/python/src/com/jetbrains/python/packaging/ui/ManagePackagesDialog.java b/python/src/com/jetbrains/python/packaging/ui/ManagePackagesDialog.java index 3be7eb610a10..6c35ecc9aedb 100644 --- a/python/src/com/jetbrains/python/packaging/ui/ManagePackagesDialog.java +++ b/python/src/com/jetbrains/python/packaging/ui/ManagePackagesDialog.java @@ -6,6 +6,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.ui.DialogWrapper; @@ -49,6 +50,8 @@ import java.util.List; */ @SuppressWarnings("UseOfObsoleteCollectionType") public class ManagePackagesDialog extends DialogWrapper { + private static final Logger LOG = Logger.getInstance(ManagePackagesDialog.class); + @NonNls private static final String TEXT_PREFIX = "" + "