Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ekaterina Tuzova
2014-08-18 15:32:21 +04:00
59 changed files with 690 additions and 214 deletions
@@ -0,0 +1,124 @@
/*
* 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.debugger.actions;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.psi.PsiExpression;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XInspectDialog;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* @author egor
*/
public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
private static final long MAX_REFERRING = 100;
@Override
public void update(AnActionEvent e) {
super.update(e);
}
@Override
protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
if (node.getValueContainer() instanceof JavaValue) {
JavaValue javaValue = ((JavaValue)node.getValueContainer());
XDebuggerTree tree = XDebuggerTree.getTree(e.getDataContext());
XInspectDialog dialog = new XInspectDialog(tree.getProject(),
tree.getEditorsProvider(),
tree.getSourcePosition(),
nodeName,
new ReferringObjectsValue(javaValue),
tree.getValueMarkers());
dialog.setTitle("Referring objects for " + nodeName);
dialog.show();
}
}
private static class ReferringObjectsValue extends XValue {
private final JavaValue myJavaValue;
public ReferringObjectsValue(JavaValue javaValue) {
myJavaValue = javaValue;
}
@Override
public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) {
myJavaValue.computePresentation(node, place);
}
@Override
public void computeChildren(@NotNull final XCompositeNode node) {
myJavaValue.getEvaluationContext().getDebugProcess().getManagerThread().schedule(
new SuspendContextCommandImpl(myJavaValue.getEvaluationContext().getSuspendContext()) {
@Override
public Priority getPriority() {
return Priority.NORMAL;
}
@Override
public void contextAction() throws Exception {
final XValueChildrenList children = new XValueChildrenList();
Value value = myJavaValue.getDescriptor().getValue();
List<ObjectReference> references = ((ObjectReference)value).referringObjects(MAX_REFERRING);
int i = 1;
for (final ObjectReference reference : references) {
ValueDescriptorImpl descriptor = new ValueDescriptorImpl(myJavaValue.getProject(), reference) {
@Override
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
return reference;
}
@Override
public String getName() {
return "Ref";
}
@Override
public String calcValueName() {
return "Ref";
}
@Override
public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
return null;
}
};
JavaValue jValue = JavaValue.create(descriptor, myJavaValue.getEvaluationContext(), null);
children.add("Referrer " + i++ ,new ReferringObjectsValue(jValue));
}
node.addChildren(children, true);
}
}
);
}
}
}
@@ -83,7 +83,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager);
}
static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor,
public static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor,
EvaluationContextImpl evaluationContext,
NodeManagerImpl nodeManager) {
return create(null, valueDescriptor, evaluationContext, nodeManager, true);
@@ -889,6 +889,11 @@ public class HighlightUtil extends HighlightUtilBase {
PsiModifier.STRICTFP.equals(modifier) || PsiModifier.SYNCHRONIZED.equals(modifier)) {
isAllowed &= modifierOwnerParent instanceof PsiClass && !((PsiClass)modifierOwnerParent).isInterface();
}
if (containingClass != null && containingClass.isAnnotationType()) {
isAllowed &= !PsiModifier.STATIC.equals(modifier);
isAllowed &= !PsiModifier.DEFAULT.equals(modifier);
}
}
else if (modifierOwner instanceof PsiField) {
if (PsiModifier.PRIVATE.equals(modifier) || PsiModifier.PROTECTED.equals(modifier) || PsiModifier.TRANSIENT.equals(modifier) ||
@@ -257,8 +257,13 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
}
myHolder.add(AnnotationsHighlightUtil.checkValidAnnotationType(method.getReturnTypeElement()));
myHolder.add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), method.getContainingClass()));
final PsiClass aClass = method.getContainingClass();
myHolder.add(AnnotationsHighlightUtil.checkCyclicMemberType(method.getReturnTypeElement(), aClass));
myHolder.add(AnnotationsHighlightUtil.checkClashesWithSuperMethods(method));
if (!myHolder.hasErrorResults() && aClass != null) {
myHolder.add(HighlightMethodUtil.checkDuplicateMethod(aClass, method, getDuplicateMethods(aClass)));
}
}
@Override
@@ -15,10 +15,7 @@
*/
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.generation.PsiGenerationInfo;
import com.intellij.codeInsight.generation.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.icons.AllIcons;
@@ -35,6 +32,7 @@ import com.intellij.util.containers.ContainerUtil;
import javax.swing.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -70,8 +68,8 @@ public class JavaGenerateMemberCompletionContributor {
List<PsiMethod> prototypes = ContainerUtil.newArrayList();
for (PsiField field : parent.getFields()) {
if (!(field instanceof PsiEnumConstant)) {
prototypes.add(GenerateMembersUtil.generateGetterPrototype(field));
prototypes.add(GenerateMembersUtil.generateSetterPrototype(field));
Collections.addAll(prototypes, GetterSetterPrototypeProvider.generateGetterSetters(field, true));
Collections.addAll(prototypes, GetterSetterPrototypeProvider.generateGetterSetters(field, true));
}
}
for (final PsiMethod prototype : prototypes) {
@@ -475,7 +475,7 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
} else {
while (true) {
final String paramName = idx > 0 ? "T" + idx : "T";
if (!typeParamNames.contains(paramName)) {
if (typeParamNames.add(paramName)) {
targetClass.getTypeParameterList().add(factory.createTypeParameterFromText(paramName, null));
break;
}
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.LowPriorityAction;
import com.intellij.openapi.editor.Editor;
@@ -29,6 +30,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -115,10 +117,10 @@ public class CreateGetterOrSetterFix implements IntentionAction, LowPriorityActi
PsiClass aClass = myField.getContainingClass();
final List<PsiMethod> methods = new ArrayList<PsiMethod>();
if (myCreateGetter) {
methods.add(GenerateMembersUtil.generateGetterPrototype(myField));
Collections.addAll(methods, GetterSetterPrototypeProvider.generateGetterSetters(myField, true));
}
if (myCreateSetter) {
methods.add(GenerateMembersUtil.generateSetterPrototype(myField));
Collections.addAll(methods, GetterSetterPrototypeProvider.generateGetterSetters(myField, false));
}
for (PsiMethod method : methods) {
aClass.add(method);
@@ -67,9 +67,8 @@ public class CreateInnerClassFromNewFix extends CreateClassFromNewFix {
}
created = (PsiClass)targetClass.add(created);
setupClassFromNewExpression(created, newExpression);
setupGenericParameters(created, ref);
setupClassFromNewExpression(created, newExpression);
}
private static boolean isInThisOrSuperCall(PsiNewExpression newExpression) {
@@ -0,0 +1,4 @@
@interface Example {
<error descr="'myMethod()' is already defined in 'Example'">public String myMethod()</error>;
<error descr="'myMethod()' is already defined in 'Example'">public int myMethod()</error>;
}
@@ -0,0 +1,9 @@
@interface Example {
public <error descr="Modifier 'static' not allowed here">static</error> String myMethod() {
return "";
}
public <error descr="Modifier 'default' not allowed here">default</error> String myMethod1() {
return "";
}
}
@@ -0,0 +1,11 @@
// "Create Inner Class 'AInner'" "true"
class Test {
{
AInner aInner = new AInner<String>(42);
}
private class AInner<T> {
public AInner(int i) {
}
}
}
@@ -0,0 +1,11 @@
// "Create Inner Class 'AInner'" "true"
class Test {
{
AInner aInner = new AInner<String, String>(42);
}
private class AInner<T, T1> {
public AInner(int i) {
}
}
}
@@ -0,0 +1,6 @@
// "Create Inner Class 'AInner'" "true"
class Test {
{
AInner aInner = new AIn<caret>ner<String>(42);
}
}
@@ -0,0 +1,6 @@
// "Create Inner Class 'AInner'" "true"
class Test {
{
AInner aInner = new AIn<caret>ner<String, String>(42);
}
}
@@ -41,6 +41,7 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testDuplicateTarget() { doTest(false); }
public void testPingPongAnnotationTypesDependencies() { doTest(false);}
public void testClashMethods() { doTest(false);}
public void testDupMethods() { doTest(false);}
public void testInvalidPackageAnnotationTarget() { doTest(BASE_PATH + "/" + getTestName(true) + "/package-info.java", false, false); }
public void testPackageAnnotationNotInPackageInfo() { doTest(BASE_PATH + "/" + getTestName(true) + "/notPackageInfo.java", false, false); }
@@ -43,6 +43,9 @@ public class Interface8MethodsHighlightingTest extends LightCodeInsightFixtureTe
public void testDefaultSupersInStaticContext() {
doTest(false, false);
}
public void testAnnotationTypeExtensionsNotSupported() {
doTest(false, false);
}
public void testSuperProtectedCalls() throws Exception {
myFixture.addClass("package p; public class Foo {" +
@@ -26,6 +26,7 @@ import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
@@ -77,4 +78,12 @@ public class ClassMappingNameConverter extends ResolvingConverter.StringConverte
assert parent != null;
return parent.getXmlElement();
}
@Override
public boolean isReferenceTo(@NotNull PsiElement element,
String stringValue,
@Nullable String resolveResult,
ConvertContext context) {
return element.getManager().areElementsEquivalent(element, resolve(stringValue, context));
}
}
@@ -81,6 +81,8 @@ import java.util.*;
import java.util.List;
public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract implements EditorOptionsProvider {
public static final String ID = "reference.settingsdialog.IDE.editor.colors";
private HashMap<String,MyColorScheme> mySchemes;
private MyColorScheme mySelectedScheme;
public static final String DIFF_GROUP = ApplicationBundle.message("title.diff");
@@ -999,7 +1001,7 @@ public class ColorAndFontOptions extends SearchableConfigurable.Parent.Abstract
@Override
@NotNull
public String getHelpTopic() {
return "reference.settingsdialog.IDE.editor.colors";
return ID;
}
private static class MyColorScheme extends EditorColorsSchemeImpl {
@@ -174,7 +174,7 @@ public class FoldingUpdate {
injectedFiles.add(injectedFile);
final FoldingMap map = new FoldingMap();
maps.add(map);
getFoldingsFor(injectedFile, injectedDocument, map, false);
getFoldingsFor(injectedFile, injectedEditor.getDocument(), map, false);
}
});
}
@@ -28,12 +28,12 @@ import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TemplateState;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class NextVariableAction extends EditorAction {
@@ -46,14 +46,15 @@ public class NextVariableAction extends EditorAction {
@Override
public void executeWriteAction(Editor editor, @Nullable Caret caret, DataContext dataContext) {
TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
assert templateState != null;
CommandProcessor.getInstance().setCurrentCommandName(CodeInsightBundle.message("template.next.variable.command"));
templateState.nextTab();
}
}
@Override
public void update(Editor editor, Presentation presentation, DataContext dataContext) {
TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
presentation.setEnabled(templateState != null && !templateState.isFinished() && templateState.isToProcessTab());
@Override
protected boolean isEnabledForCaret(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
return templateState != null && !templateState.isFinished() && templateState.isToProcessTab();
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* 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.
@@ -28,11 +28,12 @@ import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TemplateState;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import org.jetbrains.annotations.NotNull;
public class PreviousVariableAction extends EditorAction {
public PreviousVariableAction() {
@@ -42,16 +43,17 @@ public class PreviousVariableAction extends EditorAction {
private static class Handler extends EditorWriteActionHandler {
@Override
public void executeWriteAction(Editor editor, DataContext dataContext) {
public void executeWriteAction(Editor editor, Caret caret, DataContext dataContext) {
final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
assert templateState != null;
CommandProcessor.getInstance().setCurrentCommandName(CodeInsightBundle.message("template.previous.variable.command"));
templateState.previousTab();
}
}
@Override
public void update(Editor editor, Presentation presentation, DataContext dataContext) {
final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
presentation.setEnabled(templateState != null && !templateState.isFinished());
@Override
protected boolean isEnabledForCaret(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
final TemplateState templateState = TemplateManagerImpl.getTemplateState(editor);
return templateState != null && !templateState.isFinished();
}
}
}
@@ -37,6 +37,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.options.newEditor.OptionsEditor;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.InputValidator;
@@ -231,7 +232,8 @@ public class SeverityEditorDialog extends DialogWrapper {
final DataContext dataContext = DataManager.getInstance().getDataContext(myPanel);
final OptionsEditor optionsEditor = OptionsEditor.KEY.getData(dataContext);
if (optionsEditor != null) {
final ColorAndFontOptions colorAndFontOptions = optionsEditor.findConfigurable(ColorAndFontOptions.class);
final ColorAndFontOptions colorAndFontOptions =
(ColorAndFontOptions)((ConfigurableWrapper)optionsEditor.findConfigurableById(ColorAndFontOptions.ID)).getConfigurable();
assert colorAndFontOptions != null;
final SearchableConfigurable javaPage = colorAndFontOptions.findSubConfigurable(InspectionColorSettingsPage.class);
LOG.assertTrue(javaPage != null);
@@ -64,7 +64,7 @@ public class ScopesOrderDialog extends DialogWrapper {
ListUtil.moveSelectedItemsUp(myOptionsList);
}
}).disableRemoveAction().disableAddAction().createPanel();
final JLabel descr = new JLabel("<html><p>If file appears in two or more scopes, it will be" +
final JLabel descr = new JLabel("<html><p>If file appears in two or more scopes, it will be " +
"inspected with settings of the topmost scope in list above.</p><p/>" +
"<p>Scope order is set globally for all inspections in the profile.</p></html>");
descr.setPreferredSize(new Dimension(300, 100));
@@ -16,7 +16,6 @@
package com.intellij.profile.codeInspection.ui;
import com.intellij.CommonBundle;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
@@ -62,7 +61,6 @@ import com.intellij.profile.codeInspection.ui.table.ScopesAndSeveritiesTable;
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.ui.*;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Alarm;
import com.intellij.util.Function;
import com.intellij.util.config.StorageAccessors;
@@ -85,8 +83,6 @@ import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
@@ -811,7 +807,7 @@ public class SingleInspectionProfilePanel extends JPanel {
}
}
final JTable scopesAndScopesAndSeveritiesTable =
new ScopesAndSeveritiesTable(new ScopesAndSeveritiesTable.TableSettings(nodes, mySelectedProfile, myTreeTable, project) {
new ScopesAndSeveritiesTable(new ScopesAndSeveritiesTable.TableSettings(nodes, mySelectedProfile, project) {
@Override
protected void onScopeChosen(@NotNull final ScopeToolState state) {
setConfigPanel(configPanelAnchor, state);
@@ -64,8 +64,8 @@ public class InspectionsConfigTreeTable extends TreeTable {
final TableColumn isEnabledColumn = getColumnModel().getColumn(IS_ENABLED_COLUMN);
isEnabledColumn.setMaxWidth(20);
isEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer(false));
isEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer(true));
isEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer());
isEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer());
addMouseMotionListener(new MouseAdapter() {
@Override
@@ -20,11 +20,9 @@ import com.intellij.codeInsight.daemon.HighlightDisplayKey;
import com.intellij.codeInspection.ex.Descriptor;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.codeInspection.ex.ScopeToolState;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
import com.intellij.lang.annotation.HighlightSeverity;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopupFactory;
@@ -36,7 +34,6 @@ import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionConfigTr
import com.intellij.psi.search.scope.packageSet.NamedScope;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.table.JBTable;
import com.intellij.ui.treeStructure.treetable.TreeTable;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.SmartList;
@@ -77,8 +74,8 @@ public class ScopesAndSeveritiesTable extends JBTable {
final TableColumn scopeEnabledColumn = columnModel.getColumn(SCOPE_ENABLED_COLUMN);
scopeEnabledColumn.setMaxWidth(30);
scopeEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer(false));
scopeEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer(true));
scopeEnabledColumn.setCellRenderer(new ThreeStateCheckBoxRenderer());
scopeEnabledColumn.setCellEditor(new ThreeStateCheckBoxRenderer());
final TableColumn severityColumn = columnModel.getColumn(SEVERITY_COLUMN);
severityColumn.setCellRenderer(SeverityRenderer.create(tableSettings.getInspectionProfile()));
@@ -114,12 +111,10 @@ public class ScopesAndSeveritiesTable extends JBTable {
private final List<String> myKeyNames;
private final List<HighlightDisplayKey> myKeys;
private final InspectionProfileImpl myInspectionProfile;
private final TreeTable myTreeTable;
private final Project myProject;
protected TableSettings(final List<InspectionConfigTreeNode> nodes,
final InspectionProfileImpl inspectionProfile,
final TreeTable treeTable,
final Project project) {
myNodes = nodes;
myKeys = new ArrayList<HighlightDisplayKey>(myNodes.size());
@@ -131,7 +126,6 @@ public class ScopesAndSeveritiesTable extends JBTable {
}
myInspectionProfile = inspectionProfile;
myTreeTable = treeTable;
myProject = project;
}
@@ -151,10 +145,6 @@ public class ScopesAndSeveritiesTable extends JBTable {
return myInspectionProfile;
}
public TreeTable getTreeTable() {
return myTreeTable;
}
public Project getProject() {
return myProject;
}
@@ -187,8 +177,6 @@ public class ScopesAndSeveritiesTable extends JBTable {
private static class MyTableModel extends AbstractTableModel implements EditableModel {
private final InspectionProfileImpl myInspectionProfile;
private final List<String> myKeyNames;
private final List<InspectionConfigTreeNode> myNodes;
private final TreeTable myTreeTable;
private final Project myProject;
private final TableSettings myTableSettings;
private final List<HighlightDisplayKey> myKeys;
@@ -203,8 +191,6 @@ public class ScopesAndSeveritiesTable extends JBTable {
myInspectionProfile = tableSettings.getInspectionProfile();
myKeys = tableSettings.getKeys();
myKeyNames = tableSettings.getKeyNames();
myNodes = tableSettings.getNodes();
myTreeTable = tableSettings.getTreeTable();
myScopeComparator = new ScopeOrderComparator(myInspectionProfile);
refreshAggregatedScopes();
}
@@ -264,7 +250,7 @@ public class ScopesAndSeveritiesTable extends JBTable {
case SCOPE_ENABLED_COLUMN:
return isEnabled(rowIndex);
case SCOPE_NAME_COLUMN:
return rowIndex == lastRowIndex() ? "Everywhere else" : getScope(rowIndex).getName();
return rowIndex == lastRowIndex() ? "Everywhere else" : getScopeName(rowIndex);
case SEVERITY_COLUMN:
return getSeverityState(rowIndex);
default:
@@ -276,13 +262,17 @@ public class ScopesAndSeveritiesTable extends JBTable {
return getScopeToolState(rowIndex).getExistedStates().get(0).getScope(myProject);
}
private String getScopeName(final int rowIndex) {
return getScopeToolState(rowIndex).getExistedStates().get(0).getScopeName();
}
@NotNull
private SeverityState getSeverityState(final int rowIndex) {
final ExistedScopesStatesAndNonExistNames existedScopesStatesAndNonExistNames = getScopeToolState(rowIndex);
if (!existedScopesStatesAndNonExistNames.getNonExistNames().isEmpty()) {
return new SeverityState(MIXED_FAKE_SEVERITY, false);
}
return new SeverityState(ScopesAndSeveritiesTable.getSeverity(existedScopesStatesAndNonExistNames.getExistedStates()), true);
return new SeverityState(getSeverity(existedScopesStatesAndNonExistNames.getExistedStates()), true);
}
@Nullable
@@ -362,7 +352,7 @@ public class ScopesAndSeveritiesTable extends JBTable {
LOG.error("no display level found for name " + severityState.getSeverity().getName());
return;
}
final String scopeName = rowIndex == lastRowIndex() ? null : getScope(rowIndex).getName();
final String scopeName = rowIndex == lastRowIndex() ? null : getScopeName(rowIndex);
myInspectionProfile.setErrorLevel(myKeys, level, scopeName, myProject);
}
else if (columnIndex == SCOPE_ENABLED_COLUMN) {
@@ -418,7 +408,6 @@ public class ScopesAndSeveritiesTable extends JBTable {
}
};
DataContext dataContext = DataManager.getInstance().getDataContext(myTable);
final JComponent component = (JComponent)PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
final ListPopup popup = JBPopupFactory.getInstance()
.createActionGroupPopup(ScopesChooser.TITLE, scopesChooser.createPopupActionGroup(myTable), dataContext,
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false);
@@ -27,6 +27,7 @@ import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;
@@ -37,7 +38,7 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta
private final List<CellEditorListener> myListeners = new SmartList<CellEditorListener>();
public ThreeStateCheckBoxRenderer(final boolean isEditor) {
public ThreeStateCheckBoxRenderer() {
setThirdStateEnabled(false);
setHorizontalAlignment(CENTER);
setVerticalAlignment(CENTER);
@@ -95,7 +96,7 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta
@Override
public boolean stopCellEditing() {
final ChangeEvent e = new ChangeEvent(this);
for (final CellEditorListener listener : myListeners) {
for (final CellEditorListener listener : new ArrayList<CellEditorListener>(myListeners)) {
listener.editingStopped(e);
}
return true;
@@ -104,7 +105,7 @@ public class ThreeStateCheckBoxRenderer extends ThreeStateCheckBox implements Ta
@Override
public void cancelCellEditing() {
final ChangeEvent e = new ChangeEvent(this);
for (final CellEditorListener listener : myListeners) {
for (final CellEditorListener listener : new ArrayList<CellEditorListener>(myListeners)) {
listener.editingCanceled(e);
}
}
@@ -563,7 +563,7 @@ public class DocumentCommitThread extends DocumentCommitProcessor implements Run
int attempts = 0;
int delay = 100;
synchronized (documentsToCommit) {
while(!documentsToCommit.isEmpty()) {
while(!documentsToCommit.isEmpty() || currentTask != null) {
documentsToCommit.wait(delay);
if (delay * attempts > timeout) {
throw new RuntimeException("timeout");
@@ -117,7 +117,7 @@ public class ComboBoxTableRenderer<T> extends JLabel implements TableCellRendere
public Component getTableCellEditorComponent(JTable table, final Object value, boolean isSelected, final int row, final int column) {
@SuppressWarnings("unchecked") final T t = (T)value;
myValue = t;
customizeComponent(t, table, isSelected);
customizeComponent(t, table, true);
//noinspection SSBasedInspection
SwingUtilities.invokeLater(new Runnable() {
@@ -283,7 +283,7 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
if (myBusyIcon != null) {
if (myBusy) {
if (hasFocus()) {
if (shouldShowBusyIconIfNeeded()) {
myBusyIcon.resume();
myBusyIcon.setToolTipText("Update is in progress. Click to cancel");
}
@@ -305,6 +305,11 @@ public class Tree extends JTree implements ComponentWithEmptyText, ComponentWith
}
}
protected boolean shouldShowBusyIconIfNeeded() {
// http://youtrack.jetbrains.com/issue/IDEA-101422 "Rotating wait symbol in Project list whenever typing"
return hasFocus();
}
protected boolean paintNodes() {
return false;
}
@@ -71,7 +71,7 @@ public class AsyncProcessIcon extends AnimatedIcon {
return icons;
}
public void updateLocation(JComponent container) {
public void updateLocation(final JComponent container) {
final Rectangle rec = container.getVisibleRect();
final Dimension iconSize = getPreferredSize();
@@ -79,7 +79,14 @@ public class AsyncProcessIcon extends AnimatedIcon {
final Rectangle newBounds = new Rectangle(rec.x + rec.width - iconSize.width, rec.y, iconSize.width, iconSize.height);
if (!newBounds.equals(getBounds())) {
setBounds(newBounds);
container.repaint();
// painting problems with scrollpane
// repaint shouldn't be called from paint method
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
container.repaint();
}
});
}
}
@@ -939,6 +939,7 @@ action.Debugger.Inspect.text=Inspect
action.Debugger.CopyValue.text=Copy Value
action.Debugger.ViewText.text=View Text
action.Debugger.ViewText.description=View text value of selected node in a separate pane
action.Debugger.ShowReferring.text=Show Referring Objects
action.Debugger.CompareValueWithClipboard.text=Compare Value with Clipboard
action.Debugger.CompareValueWithClipboard.description=Compare value of selected node with clipboard text
action.Debugger.CustomizeContextView.text=Customize Data Views...
@@ -581,8 +581,8 @@
<action id="MaintenanceAction" class="com.intellij.ide.actions.MaintenanceAction"/>
<group id="MaintenanceGroup">
<action id="UiDebugger" class="com.intellij.ui.debugger.ShowUiDebuggerAction"/>
<action id="ShowRegistry" class="com.intellij.openapi.util.registry.ShowRegistryAction"/>
<action id="UiDebugger" class="com.intellij.ui.debugger.ShowUiDebuggerAction"/>
</group>
<action id="Console.Execute" class="com.intellij.openapi.actionSystem.EmptyAction"/>
@@ -120,22 +120,26 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
myValuePresentation = valuePresentation;
myRawValue = XValuePresentationUtil.computeValueText(valuePresentation);
if (Registry.is("ide.debugger.inline")) {
getValueContainer().computeSourcePosition(new XNavigatable() {
@Override
public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
if (map == null || sourcePosition == null) return;
VirtualFile file = sourcePosition.getFile();
int line = sourcePosition.getLine();
Pair<VirtualFile, Integer> key = Pair.create(file, line);
Set<XValueNodeImpl> presentations = map.get(key);
if (presentations == null) {
presentations = new LinkedHashSet<XValueNodeImpl>();
map.put(key, presentations);
try {
getValueContainer().computeSourcePosition(new XNavigatable() {
@Override
public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
if (map == null || sourcePosition == null) return;
VirtualFile file = sourcePosition.getFile();
int line = sourcePosition.getLine();
Pair<VirtualFile, Integer> key = Pair.create(file, line);
Set<XValueNodeImpl> presentations = map.get(key);
if (presentations == null) {
presentations = new LinkedHashSet<XValueNodeImpl>();
map.put(key, presentations);
}
presentations.add(XValueNodeImpl.this);
}
presentations.add(XValueNodeImpl.this);
}
});
});
}
catch (Exception ignore) {
}
}
updateText();
setLeaf(!hasChildren);
@@ -24,6 +24,7 @@ import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.PropertiesHighlighter;
import com.intellij.lang.properties.PropertiesUtil;
import com.intellij.lang.properties.ResourceBundle;
import com.intellij.lang.properties.psi.Property;
import com.intellij.navigation.ColoredItemPresentation;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -69,8 +70,8 @@ public class ResourceBundlePropertyStructureViewElement implements StructureView
}
@Override
public String getValue() {
return myProperty.getName();
public Property getValue() {
return (Property)myProperty.getPsiElement();
}
@Override
@@ -16,6 +16,7 @@
package com.intellij.lang.properties.structureView;
import com.intellij.icons.AllIcons;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.smartTree.*;
import com.intellij.lang.properties.IProperty;
@@ -65,14 +66,14 @@ public class GroupByWordPrefixes implements Grouper, Sorter {
parentPrefixLength = 0;
}
for (TreeElement element : children) {
String text = null;
if (element instanceof PropertiesStructureViewElement) {
IProperty property = ((PropertiesStructureViewElement)element).getValue();
text = property.getUnescapedKey();
if (!(element instanceof StructureViewTreeElement)) {
continue;
}
else if (element instanceof ResourceBundlePropertyStructureViewElement) {
text = ((ResourceBundlePropertyStructureViewElement)element).getValue();
final Object value = ((StructureViewTreeElement)element).getValue();
if (!(value instanceof IProperty)) {
continue;
}
final String text = ((IProperty) value).getUnescapedKey();
if (text == null) continue;
LOG.assertTrue(text.startsWith(parentPrefix) || text.startsWith(mySeparator));
List<String> words = StringUtil.split(text, mySeparator);
@@ -16,11 +16,13 @@
package com.intellij.lang.properties.structureView;
import com.intellij.icons.AllIcons;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.Group;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.lang.properties.IProperty;
import com.intellij.lang.properties.editor.ResourceBundleEditorViewElement;
import com.intellij.lang.properties.editor.ResourceBundlePropertyStructureViewElement;
import com.intellij.lang.properties.psi.Property;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
@@ -90,20 +92,14 @@ public class PropertiesPrefixGroup implements Group, ResourceBundleEditorViewEle
Collection<TreeElement> result = new ArrayList<TreeElement>();
List<String> prefixWords = StringUtil.split(myPrefix, mySeparator);
for (TreeElement treeElement : myProperties) {
String key;
if (treeElement instanceof PropertiesStructureViewElement) {
PropertiesStructureViewElement propertiesElement = (PropertiesStructureViewElement)treeElement;
IProperty property = propertiesElement.getValue();
key = property.getUnescapedKey();
}
else if (treeElement instanceof ResourceBundlePropertyStructureViewElement) {
key = ((ResourceBundlePropertyStructureViewElement)treeElement).getValue();
}
else {
if (!(treeElement instanceof StructureViewTreeElement)) {
continue;
}
final Object value = ((StructureViewTreeElement)treeElement).getValue();
if (!(value instanceof IProperty)) {
continue;
}
final String key = ((IProperty) value).getUnescapedKey();
if (key == null || key.equals(myPrefix)) {
continue;
}
@@ -170,7 +170,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
TreeElement[] children = myStructureViewComponent.getTreeModel().getRoot().getChildren();
if (children.length != 0) {
TreeElement child = children[0];
String propName = ((ResourceBundlePropertyStructureViewElement)child).getValue();
String propName = ((ResourceBundlePropertyStructureViewElement)child).getValue().getUnescapedKey();
setState(new ResourceBundleEditorState(propName));
}
myDataProviderPanel = new DataProviderPanel(splitPanel);
@@ -248,7 +248,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
DefaultMutableTreeNode node = toCheck.pop();
final ResourceBundleEditorViewElement element = getSelectedElement(node);
String value = element instanceof ResourceBundlePropertyStructureViewElement
? ((ResourceBundlePropertyStructureViewElement)element).getValue()
? ((ResourceBundlePropertyStructureViewElement)element).getValue().getUnescapedKey()
: null;
if (propertyName.equals(value)) {
nodeToSelect = node;
@@ -257,8 +257,8 @@ public class StudyDirectoryProjectGenerator extends PythonProjectGenerator imple
courseInfo = new CourseInfo(courseName, courseAuthor, courseDescription);
}
}
catch (FileNotFoundException e) {
LOG.error(e);
catch (Exception e) {
//error will be shown in UI
}
finally {
StudyUtils.closeSilently(reader);
@@ -1,23 +1,16 @@
package com.jetbrains.python.edu.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.edu.StudyTaskManager;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.StudyStatus;
import com.jetbrains.python.edu.course.TaskFile;
import com.jetbrains.python.edu.course.TaskWindow;
import com.jetbrains.python.edu.editor.StudyEditor;
import icons.StudyIcons;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* move caret to next task window
*/
public class StudyNextWindowAction extends DumbAwareAction {
public class StudyNextWindowAction extends StudyWindowNavigationAction {
public static final String ACTION_ID = "NextWindow";
public static final String SHORTCUT = "ctrl pressed PERIOD";
public static final String SHORTCUT2 = "ctrl pressed ENTER";
@@ -26,37 +19,14 @@ public class StudyNextWindowAction extends DumbAwareAction {
super("NextWindowAction", "Select next window", StudyIcons.Next);
}
public void actionPerformed(AnActionEvent e) {
Project project = e.getProject();
if (project != null) {
Editor selectedEditor = StudyEditor.getSelectedEditor(project);
if (selectedEditor != null) {
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
if (openedFile != null) {
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
if (selectedTaskFile != null) {
TaskWindow selectedTaskWindow = selectedTaskFile.getSelectedTaskWindow();
boolean ifDraw = false;
for (TaskWindow taskWindow : selectedTaskFile.getTaskWindows()) {
if (ifDraw) {
selectedTaskFile.setSelectedTaskWindow(taskWindow);
taskWindow.draw(selectedEditor, taskWindow.getStatus() != StudyStatus.Solved, true);
return;
}
if (taskWindow == selectedTaskWindow) {
ifDraw = true;
}
}
}
}
}
}
}
@Override
public void update(AnActionEvent e) {
StudyUtils.updateAction(e);
protected TaskWindow getNextTaskWindow(@NotNull final TaskWindow window) {
int index = window.getIndex();
List<TaskWindow> windows = window.getTaskFile().getTaskWindows();
if (StudyUtils.indexIsValid(index, windows)) {
int newIndex = index + 1;
return newIndex == windows.size() ? windows.get(0) : windows.get(newIndex);
}
return null;
}
}
@@ -1,24 +1,18 @@
package com.jetbrains.python.edu.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.edu.StudyTaskManager;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.StudyStatus;
import com.jetbrains.python.edu.course.TaskFile;
import com.jetbrains.python.edu.course.TaskWindow;
import com.jetbrains.python.edu.editor.StudyEditor;
import icons.StudyIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* author: liana
* data: 6/30/14.
*/
public class StudyPrevWindowAction extends DumbAwareAction {
public class StudyPrevWindowAction extends StudyWindowNavigationAction {
public static final String ACTION_ID = "PrevWindowAction";
public static final String SHORTCUT = "ctrl pressed COMMA";
@@ -26,37 +20,15 @@ public class StudyPrevWindowAction extends DumbAwareAction {
super("PrevWindowAction", "Select previous window", StudyIcons.Prev);
}
public void actionPerformed(AnActionEvent e) {
Project project = e.getProject();
assert project != null;
Editor selectedEditor = StudyEditor.getSelectedEditor(project);
if (selectedEditor != null) {
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
if (openedFile != null) {
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
if (selectedTaskFile != null) {
TaskWindow selectedTaskWindow = selectedTaskFile.getSelectedTaskWindow();
TaskWindow prev = null;
for (TaskWindow taskWindow : selectedTaskFile.getTaskWindows()) {
if (taskWindow == selectedTaskWindow) {
break;
}
prev = taskWindow;
}
if (prev != null) {
selectedTaskFile.setSelectedTaskWindow(prev);
prev.draw(selectedEditor, prev.getStatus() != StudyStatus.Solved, true);
}
}
}
}
}
@Nullable
@Override
public void update(AnActionEvent e) {
StudyUtils.updateAction(e);
protected TaskWindow getNextTaskWindow(@NotNull final TaskWindow window) {
int prevIndex = window.getIndex() - 1;
List<TaskWindow> windows = window.getTaskFile().getTaskWindows();
if (StudyUtils.indexIsValid(prevIndex, windows)) {
return windows.get(prevIndex);
}
return null;
}
}
@@ -0,0 +1,65 @@
package com.jetbrains.python.edu.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.python.edu.StudyTaskManager;
import com.jetbrains.python.edu.StudyUtils;
import com.jetbrains.python.edu.course.TaskFile;
import com.jetbrains.python.edu.course.TaskWindow;
import com.jetbrains.python.edu.editor.StudyEditor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
abstract public class StudyWindowNavigationAction extends DumbAwareAction {
public StudyWindowNavigationAction(String actionId, String description, Icon icon) {
super(actionId, description, icon);
}
public void navigateWindow(@NotNull final Project project) {
Editor selectedEditor = StudyEditor.getSelectedEditor(project);
if (selectedEditor != null) {
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
VirtualFile openedFile = fileDocumentManager.getFile(selectedEditor.getDocument());
if (openedFile != null) {
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
if (selectedTaskFile != null) {
TaskWindow selectedTaskWindow = selectedTaskFile.getSelectedTaskWindow();
if (selectedTaskWindow == null) {
return;
}
TaskWindow nextTaskWindow = getNextTaskWindow(selectedTaskWindow);
if (nextTaskWindow == null) {
return;
}
nextTaskWindow.draw(selectedEditor, true, true);
selectedTaskFile.setSelectedTaskWindow(nextTaskWindow);
}
}
}
}
@Nullable
protected abstract TaskWindow getNextTaskWindow(@NotNull final TaskWindow window);
@Override
public void actionPerformed(AnActionEvent e) {
Project project = e.getProject();
if (project == null) {
return;
}
navigateWindow(project);
}
@Override
public void update(AnActionEvent e) {
StudyUtils.updateAction(e);
}
}
@@ -50,6 +50,7 @@ public class TaskFile implements Stateful{
return myTask;
}
@Nullable
@Transient
public TaskWindow getSelectedTaskWindow() {
return mySelectedTaskWindow;
@@ -216,6 +217,7 @@ public class TaskFile implements Stateful{
public void navigateToFirstTaskWindow(@NotNull final Editor editor) {
if (!taskWindows.isEmpty()) {
TaskWindow firstTaskWindow = StudyUtils.getFirst(taskWindows);
mySelectedTaskWindow = firstTaskWindow;
LogicalPosition taskWindowStart = new LogicalPosition(firstTaskWindow.getLine(), firstTaskWindow.getStart());
editor.getCaretModel().moveToLogicalPosition(taskWindowStart);
int startOffset = firstTaskWindow.getRealStartOffset(editor.getDocument());
@@ -1009,6 +1009,8 @@ class ModuleRedeclarator(object):
self.classes_buf.out(0, txt)
txt = create_function()
self.classes_buf.out(0, txt)
txt = create_method()
self.classes_buf.out(0, txt)
# Fake <type 'namedtuple'>
if version[0] >= 3 or (version[0] == 2 and version[1] >= 6):
@@ -115,6 +115,25 @@ class __function(object):
"""
return txt
def create_method():
txt = """
class __method(object):
'''A mock class representing method type.'''
def __init__(self):
"""
if version[0] == 2:
txt += """
self.im_class = None
self.im_self = None
self.im_func = None
"""
if version[0] >= 3 or (version[0] == 2 and version[1] >= 6):
txt += """
self.__func__ = None
self.__self__ = None
"""
return txt
def _searchbases(cls, accum):
# logic copied from inspect.py
@@ -60,6 +60,7 @@ public class PyNames {
public static final String FAKE_OLD_BASE = "___Classobj";
public static final String FAKE_GENERATOR = "__generator";
public static final String FAKE_FUNCTION = "__function";
public static final String FAKE_METHOD = "__method";
public static final String FAKE_NAMEDTUPLE = "__namedtuple";
public static final String FUTURE_MODULE = "__future__";
@@ -471,4 +472,33 @@ public class PyNames {
public static boolean isRightOperatorName(@Nullable String name) {
return name != null && name.matches("__r[a-z]+__");
}
/**
* Available in Python 3 and Python 2 starting from 2.6.
* <p/>
* Attributes {@code __doc__}, {@code __dict__} and {@code __module__} should be inherited from object.
*/
public static final ImmutableSet<String> FUNCTION_SPECIAL_ATTRIBUTES = ImmutableSet.of(
"__defaults__",
"__globals__",
"__closure__",
"__code__",
"__name__"
);
public static final ImmutableSet<String> LEGACY_FUNCTION_SPECIAL_ATTRIBUTES = ImmutableSet.of(
"func_defaults",
"func_globals",
"func_closure",
"func_code",
"func_name",
"func_doc",
"func_dict"
);
public static final ImmutableSet<String> PY3_ONLY_FUNCTION_SPECIAL_ATTRIBUTES = ImmutableSet.of("__annotations__", "__kwdefaults__");
public static final ImmutableSet<String> METHOD_SPECIAL_ATTRIBUTES = ImmutableSet.of("__func__", "__self__");
public static final ImmutableSet<String> LEGACY_METHOD_SPECIAL_ATTRIBUTES = ImmutableSet.of("im_func", "im_self", "im_class");
}
@@ -18,10 +18,12 @@ package com.jetbrains.python.psi.types;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.QualifiedResolveResult;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,6 +32,9 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static com.jetbrains.python.psi.PyFunction.Modifier.STATICMETHOD;
import static com.jetbrains.python.psi.PyUtil.as;
/**
* Type of a particular function that is represented as a {@link Callable} in the PSI tree.
*
@@ -74,20 +79,79 @@ public class PyFunctionType implements PyCallableType {
@Nullable PyExpression location,
@NotNull AccessDirection direction,
@NotNull PyResolveContext resolveContext) {
final PyClassTypeImpl functionType = PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION);
if (functionType == null) {
final PyClassType delegate = selectFakeType(location, resolveContext.getTypeEvalContext());
if (delegate == null) {
return Collections.emptyList();
}
return functionType.resolveMember(name, location, direction, resolveContext);
return delegate.resolveMember(name, location, direction, resolveContext);
}
@Override
public Object[] getCompletionVariants(String completionPrefix, PsiElement location, ProcessingContext context) {
final PyClassTypeImpl functionType = PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION);
if (functionType == null) {
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(location.getContainingFile());
final PyClassType delegate;
if (location instanceof PyReferenceExpression) {
delegate = selectFakeType(((PyReferenceExpression)location).getQualifier(), typeEvalContext);
}
else {
delegate = PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION);
}
if (delegate == null) {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
return functionType.getCompletionVariants(completionPrefix, location, context);
return delegate.getCompletionVariants(completionPrefix, location, context);
}
/**
* Select either {@link PyNames#FAKE_FUNCTION} or {@link PyNames#FAKE_METHOD} fake class depending on concrete reference used and
* language level. Will fallback to fake function type.
*/
@Nullable
private PyClassTypeImpl selectFakeType(@Nullable PyExpression location, @NotNull TypeEvalContext context) {
if (location instanceof PyReferenceExpression && isBoundMethodReference(((PyReferenceExpression)location), context)) {
return PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_METHOD);
}
return PyBuiltinCache.getInstance(getCallable()).getObjectType(PyNames.FAKE_FUNCTION);
}
private boolean isBoundMethodReference(@NotNull PyReferenceExpression location, @NotNull TypeEvalContext context) {
final PyFunction function = as(getCallable(), PyFunction.class);
final boolean isNonStaticMethod = function != null && function.getContainingClass() != null && function.getModifier() != STATICMETHOD;
if (isNonStaticMethod) {
// In Python 2 unbound methods have __method fake type
if (LanguageLevel.forElement(location).isOlderThan(LanguageLevel.PYTHON30)) {
return true;
}
final PyExpression qualifier;
if (location.isQualified()) {
qualifier = location.getQualifier();
}
else {
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
final QualifiedResolveResult resolveResult = location.followAssignmentsChain(resolveContext);
final List<PyExpression> qualifiers = resolveResult.getQualifiers();
qualifier = ContainerUtil.isEmpty(qualifiers) ? null : qualifiers.get(qualifiers.size() - 1);
}
if (qualifier != null) {
//noinspection ConstantConditions
final PyType qualifierType = PyTypeChecker.toNonWeakType(context.getType(qualifier), context);
if (isInstanceType(qualifierType)) {
return true;
}
else if (qualifierType instanceof PyUnionType) {
for (PyType type : ((PyUnionType)qualifierType).getMembers()) {
if (isInstanceType(type)) {
return true;
}
}
}
}
}
return false;
}
private static boolean isInstanceType(@Nullable PyType type) {
return type instanceof PyClassType && !((PyClassType)type).isDefinition();
}
@Override
@@ -652,6 +652,19 @@ class __function(object):
self.__name__ = ''
class __method(object):
'''A mock class representing method type.'''
def __init__(self):
self.im_class = None
self.im_self = None
self.im_func = None
self.__func__ = None
self.__self__ = None
class __namedtuple(tuple):
'''A mock base class for named tuples.'''
@@ -613,14 +613,24 @@ class __function(object):
self.__dict__ = ''
self.__module__ = ''
self.__annotations__ = {}
self.__defaults__ = {}
self.__globals__ = {}
self.__kwdefaults__ = {}
self.__closure__ = None
self.__code__ = None
self.__name__ = ''
self.__annotations__ = {}
self.__kwdefaults__ = {}
class __method(object):
'''A mock class representing method type.'''
def __init__(self):
self.__func__ = None
self.__self__ = None
class __namedtuple(tuple):
'''A mock base class for named tuples.'''
@@ -0,0 +1,5 @@
class MyClass(object):
def method(self):
pass
MyClass().method.__<caret>
@@ -0,0 +1 @@
(lambda: 42).__<caret>
@@ -0,0 +1,6 @@
class MyClass(object):
def method(self):
pass
m = MyClass().method
m.__<caret>
@@ -0,0 +1,6 @@
class MyClass(object):
@staticmethod
def method(self):
pass
MyClass().method.__<caret>
@@ -0,0 +1,5 @@
class MyClass(object):
def method(self):
pass
MyClass.method.__<caret>
@@ -0,0 +1,10 @@
class MyClass(object):
def method(self):
pass
if True:
inst = MyClass()
else:
inst = unresolved
inst.method.__<caret>
@@ -0,0 +1,25 @@
class MyClass(object):
def method(self):
pass
@staticmethod
def static_method():
pass
# Unbound method still treated as __method in Python 2
MyClass.method.__func__
MyClass.method.<warning descr="Cannot find reference '__defaults__' in 'function'">__defaults__</warning>
# Bound method with qualifier
inst = MyClass()
inst.method.__func__
inst.method.<warning descr="Cannot find reference '__defaults__' in 'function'">__defaults__</warning>
# Reassigned bound method without qualifier
m = inst.method
# Static method
# This reference should be marked as unresolved, but such warnings are suppressed for methods with decorators
inst.static_method.__func__
inst.static_method.__defaults__
@@ -626,23 +626,85 @@ public class PythonCompletionTest extends PyTestCase {
}
// PY-4073
public void testSpecialFunctionAttributes() throws Exception {
setLanguageLevel(LanguageLevel.PYTHON27);
try {
List<String> suggested = doTestByText("def func(): pass; func.func_<caret>");
assertNotNull(suggested);
assertContainsElements(suggested,
"func_defaults", "func_globals", "func_closure",
"func_code", "func_name", "func_doc", "func_dict");
public void testFunctionSpecialAttributes() {
runWithLanguageLevel(LanguageLevel.PYTHON27, new Runnable() {
@Override
public void run() {
List<String> suggested = doTestByText("def func(): pass; func.func_<caret>");
assertNotNull(suggested);
assertContainsElements(suggested, PyNames.LEGACY_FUNCTION_SPECIAL_ATTRIBUTES);
suggested = doTestByText("def func(): pass; func.__<caret>");
assertNotNull(suggested);
assertContainsElements(suggested, "__defaults__", "__globals__", "__closure__",
"__code__", "__name__", "__doc__", "__dict__", "__module__");
assertDoesntContain(suggested, "__annotations__", "__kwdefaults__");
}
finally {
setLanguageLevel(null);
}
suggested = doTestByText("def func(): pass; func.__<caret>");
assertNotNull(suggested);
assertContainsElements(suggested, PyNames.FUNCTION_SPECIAL_ATTRIBUTES);
assertDoesntContain(suggested, PyNames.PY3_ONLY_FUNCTION_SPECIAL_ATTRIBUTES);
}
});
}
// PY-9342
public void testBoundMethodSpecialAttributes() {
List<String> suggested = doTestByText("{}.update.im_<caret>");
assertNotNull(suggested);
assertContainsElements(suggested, PyNames.LEGACY_METHOD_SPECIAL_ATTRIBUTES);
suggested = doTestByText("{}.update.__<caret>");
assertNotNull(suggested);
assertContainsElements(suggested, PyNames.METHOD_SPECIAL_ATTRIBUTES);
assertDoesntContain(suggested, PyNames.FUNCTION_SPECIAL_ATTRIBUTES);
}
// PY-9342
public void testWeakQualifierBoundMethodAttributes() {
assertUnderscoredMethodSpecialAttributesSuggested();
}
private void assertUnderscoredMethodSpecialAttributesSuggested() {
myFixture.configureByFile("completion/" + getTestName(true) + ".py");
myFixture.completeBasic();
final List<String> suggested = myFixture.getLookupElementStrings();
assertNotNull(suggested);
assertContainsElements(suggested, PyNames.METHOD_SPECIAL_ATTRIBUTES);
assertDoesntContain(suggested, PyNames.FUNCTION_SPECIAL_ATTRIBUTES);
}
// PY-9342
public void testUnboundMethodSpecialAttributes() {
runWithLanguageLevel(LanguageLevel.PYTHON27, new Runnable() {
@Override
public void run() {
assertUnderscoredMethodSpecialAttributesSuggested();
}
});
runWithLanguageLevel(LanguageLevel.PYTHON32, new Runnable() {
@Override
public void run() {
assertUnderscoredFunctionAttributesSuggested();
}
});
}
// PY-9342
public void testStaticMethodSpecialAttributes() {
assertUnderscoredFunctionAttributesSuggested();
}
// PY-9342
public void testLambdaSpecialAttributes() {
assertUnderscoredFunctionAttributesSuggested();
}
// PY-9342
public void testReassignedMethodSpecialAttributes() {
assertUnderscoredMethodSpecialAttributesSuggested();
}
private void assertUnderscoredFunctionAttributesSuggested() {
myFixture.configureByFile("completion/" + getTestName(true) + ".py");
myFixture.completeBasic();
final List<String> suggested = myFixture.getLookupElementStrings();
assertNotNull(suggested);
assertContainsElements(suggested, PyNames.FUNCTION_SPECIAL_ATTRIBUTES);
assertDoesntContain(suggested, PyNames.METHOD_SPECIAL_ATTRIBUTES);
}
}
@@ -371,6 +371,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
doMultiFileTest();
}
// PY-9342
public void testMethodSpecialAttributes() {
doTest();
}
// PY-11472
public void testUnusedImportBeforeStarImport() {
doMultiFileTest();
+3
View File
@@ -162,6 +162,9 @@
<action id="Debugger.ViewText" class="com.intellij.debugger.actions.ViewTextAction">
<add-to-group group-id="XDebugger.ValueGroup" anchor="last"/>
</action>
<action id="Debugger.ShowReferring" internal="true" class="com.intellij.debugger.actions.ShowReferringObjectsAction">
<add-to-group group-id="XDebugger.ValueGroup" anchor="last"/>
</action>
<action id="Debugger.CopyValue" class="com.intellij.debugger.actions.CopyValueAction"/>
<action id="Debugger.CompareValueWithClipboard" class="com.intellij.debugger.actions.CompareValueWithClipboardAction"/>
<action id="Debugger.CustomizeThreadsView" class="com.intellij.debugger.actions.CustomizeThreadsViewAction">