mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -169,7 +169,13 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
callback.evaluated(myValueDescriptor.getValueText());
|
||||
final ValueDescriptorImpl fullValueDescriptor = myValueDescriptor.getFullValueDescriptor();
|
||||
fullValueDescriptor.updateRepresentation(myEvaluationContext, new DescriptorLabelListener() {
|
||||
@Override
|
||||
public void labelChanged() {
|
||||
callback.evaluated(fullValueDescriptor.getValueText());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.intellij.util.IJSwingUtilities;
|
||||
import com.intellij.xdebugger.frame.XValueModifier;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -59,17 +58,30 @@ public class JavaValueModifier extends XValueModifier {
|
||||
myJavaValue = javaValue;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getInitialValueEditorText() {
|
||||
Value value = myJavaValue.getDescriptor().getValue();
|
||||
public void calculateInitialValueEditorText(final XInitialValueCallback callback) {
|
||||
final Value value = myJavaValue.getDescriptor().getValue();
|
||||
if (value instanceof PrimitiveValue) {
|
||||
return myJavaValue.getValueString();
|
||||
callback.setValue(myJavaValue.getValueString());
|
||||
}
|
||||
else if (value instanceof StringReference) {
|
||||
return StringUtil.wrapWithDoubleQuote(DebuggerUtils.translateStringValue(myJavaValue.getValueString()));
|
||||
final EvaluationContextImpl evaluationContext = myJavaValue.getEvaluationContext();
|
||||
evaluationContext.getManagerThread().schedule(new SuspendContextCommandImpl(evaluationContext.getSuspendContext()) {
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
return Priority.NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
callback.setValue(
|
||||
StringUtil.wrapWithDoubleQuote(DebuggerUtils.translateStringValue(DebuggerUtils.getValueAsString(evaluationContext, value))));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
callback.setValue(null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//public void update(AnActionEvent e) {
|
||||
|
||||
@@ -22,6 +22,7 @@ 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.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
||||
import com.intellij.debugger.settings.NodeRendererSettings;
|
||||
import com.intellij.debugger.ui.tree.DebuggerTreeNode;
|
||||
@@ -58,6 +59,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
|
||||
|
||||
private String myIdLabel;
|
||||
private String myValueText;
|
||||
private boolean myFullValue = false;
|
||||
|
||||
@Nullable
|
||||
private Icon myValueIcon;
|
||||
@@ -328,8 +330,32 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
|
||||
return calcValueName() + " = " + myIdLabel + myValueText;
|
||||
}
|
||||
|
||||
public ValueDescriptorImpl getFullValueDescriptor() {
|
||||
ValueDescriptorImpl descriptor = new ValueDescriptorImpl(myProject, myValue) {
|
||||
@Override
|
||||
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String calcValueName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
descriptor.myFullValue = true;
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueLabel(String label) {
|
||||
if (!myFullValue) {
|
||||
label = DebuggerUtilsEx.truncateString(label);
|
||||
}
|
||||
myValueText = label;
|
||||
myIdLabel = getIdLabel(label);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiElementFactory;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.xdebugger.settings.XDebuggerSettingsManager;
|
||||
import com.sun.jdi.*;
|
||||
import org.jdom.Element;
|
||||
@@ -112,42 +111,31 @@ public class ClassRenderer extends NodeRendererImpl{
|
||||
final ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)descriptor;
|
||||
final Value value = valueDescriptor.getValue();
|
||||
if (value instanceof ObjectReference) {
|
||||
final StringBuilder buf = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
if (value instanceof StringReference) {
|
||||
// no need to add quotes and escape characters here, XValueTextRendererImpl handles the presentation
|
||||
//buf.append('\"');
|
||||
//buf.append(DebuggerUtils.convertToPresentationString(((StringReference)value).value()));
|
||||
//buf.append('\"');
|
||||
buf.append(((StringReference)value).value());
|
||||
}
|
||||
else if (value instanceof ClassObjectReference) {
|
||||
ReferenceType type = ((ClassObjectReference)value).reflectedType();
|
||||
buf.append((type != null)?type.name():"{...}");
|
||||
}
|
||||
else {
|
||||
final ObjectReference objRef = (ObjectReference)value;
|
||||
final Type type = objRef.type();
|
||||
if (type instanceof ClassType && ((ClassType)type).isEnum()) {
|
||||
final String name = getEnumConstantName(objRef, (ClassType)type);
|
||||
if (name != null) {
|
||||
buf.append(name);
|
||||
}
|
||||
else {
|
||||
buf.append(type.name());
|
||||
}
|
||||
if (value instanceof StringReference) {
|
||||
return ((StringReference)value).value();
|
||||
}
|
||||
else if (value instanceof ClassObjectReference) {
|
||||
ReferenceType type = ((ClassObjectReference)value).reflectedType();
|
||||
return (type != null) ? type.name() : "{...}";
|
||||
}
|
||||
else {
|
||||
final ObjectReference objRef = (ObjectReference)value;
|
||||
final Type type = objRef.type();
|
||||
if (type instanceof ClassType && ((ClassType)type).isEnum()) {
|
||||
final String name = getEnumConstantName(objRef, (ClassType)type);
|
||||
if (name != null) {
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
buf.append(ValueDescriptorImpl.getIdLabel(objRef));
|
||||
return type.name();
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(buf);
|
||||
else {
|
||||
return ValueDescriptorImpl.getIdLabel(objRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(value == null) {
|
||||
else if (value == null) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
return "null";
|
||||
}
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ public class SegmentArrayWithData extends SegmentArray {
|
||||
}
|
||||
|
||||
public void setElementAt(int i, int startOffset, int endOffset, int data) {
|
||||
if (data < 0 && data > Short.MAX_VALUE) throw new IndexOutOfBoundsException("data out of short range" + data);
|
||||
if (data < 0 || data > Short.MAX_VALUE) throw new IndexOutOfBoundsException("data out of short range" + data);
|
||||
setElementAt(i, startOffset, endOffset);
|
||||
myData = reallocateArray(myData, i+1);
|
||||
myData[i] = (short)data;
|
||||
|
||||
+1
-1
@@ -349,7 +349,7 @@ public abstract class AbstractColorsScheme implements EditorColorsScheme {
|
||||
attr.setErrorStripeColor(defaultColor);
|
||||
}
|
||||
}
|
||||
private static final Map<String, Color> DEFAULT_ERROR_STRIPE_COLOR = new THashMap<String, Color>();
|
||||
public static final Map<String, Color> DEFAULT_ERROR_STRIPE_COLOR = new THashMap<String, Color>();
|
||||
static {
|
||||
DEFAULT_ERROR_STRIPE_COLOR.put(CodeInsightColors.ERRORS_ATTRIBUTES.getExternalName(), Color.red);
|
||||
DEFAULT_ERROR_STRIPE_COLOR.put(CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES.getExternalName(), Color.red);
|
||||
|
||||
@@ -36,6 +36,9 @@ public interface FoldingModelEx extends FoldingModel {
|
||||
|
||||
boolean intersectsRegion(int startOffset, int endOffset);
|
||||
|
||||
/**
|
||||
* @deprecated Use an equivalent method {@link FoldingModel#getCollapsedRegionAtOffset(int)} instead. To be removed in IDEA 16.
|
||||
*/
|
||||
FoldRegion fetchOutermost(int offset);
|
||||
|
||||
/**
|
||||
|
||||
@@ -269,7 +269,7 @@ public final class IterationState {
|
||||
advanceCurrentVirtualSelectionIndex();
|
||||
|
||||
if (!myUseOnlyFullLineHighlighters) {
|
||||
myCurrentFold = myFoldingModel.fetchOutermost(myStartOffset);
|
||||
myCurrentFold = myFoldingModel.getCollapsedRegionAtOffset(myStartOffset);
|
||||
}
|
||||
if (myCurrentFold != null) {
|
||||
myEndOffset = myCurrentFold.getEndOffset();
|
||||
|
||||
+3
-1
@@ -355,7 +355,9 @@ public class SoftWrapApplianceManager implements Dumpable {
|
||||
if (!foldRegion.isValid() ||
|
||||
foldRegion.getStartOffset() != myContext.tokenStartOffset
|
||||
|| foldRegion.getEndOffset() > document.getTextLength()) {
|
||||
LOG.error("Inconsistent fold region state: fold region: " + foldRegion + ", soft wrap model state: " + myEditor.getSoftWrapModel());
|
||||
LOG.error("Inconsistent fold region state: fold region: " + foldRegion
|
||||
+ ", soft wrap model state: " + myEditor.getSoftWrapModel()
|
||||
+ ", folding model state: " + myEditor.getFoldingModel());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -101,9 +101,13 @@ public class BuildInfo implements Comparable<BuildInfo> {
|
||||
|
||||
@Nullable
|
||||
public PatchInfo findPatchForCurrentBuild() {
|
||||
BuildNumber currentBuild = ApplicationInfo.getInstance().getBuild();
|
||||
return findPatchForBuild(ApplicationInfo.getInstance().getBuild());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PatchInfo findPatchForBuild(BuildNumber currentBuild) {
|
||||
for (PatchInfo each : myPatches) {
|
||||
if (each.isAvailable() && each.getFromBuild().asStringWithoutProductCode().equals(currentBuild.asStringWithoutProductCode()))
|
||||
if (each.isAvailable() && each.getFromBuild().asStringWithoutProductCode().equals(currentBuild.asStringWithoutProductCode()))
|
||||
return each;
|
||||
}
|
||||
return null;
|
||||
|
||||
+5
-1
@@ -89,7 +89,11 @@ public class UpdateStrategy {
|
||||
for (UpdateChannel channel : channels) {
|
||||
if ((channel.getMajorVersion() == myMajorVersion && channel.getStatus().compareTo(myChannelStatus) >= 0) ||
|
||||
(channel.getMajorVersion() > myMajorVersion && channel.getStatus() == ChannelStatus.EAP && myChannelStatus == ChannelStatus.EAP)) {
|
||||
result.add(channel);
|
||||
if (channel.getMajorVersion() == myMajorVersion && channel.getStatus().compareTo(myChannelStatus) == 0) {
|
||||
result.add(0, channel); // prefer channel that has same status as our selected channel status
|
||||
} else {
|
||||
result.add(channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -116,4 +116,16 @@ public class UpdateStrategyTest extends TestCase {
|
||||
Assert.assertEquals("IDEA10EAP", newChannel.getId());
|
||||
Assert.assertEquals("IntelliJ IDEA X EAP", newChannel.getName());
|
||||
}
|
||||
|
||||
public void testChannelWithCurrentStatusPreferred() {
|
||||
final TestUpdateSettings settings = new TestUpdateSettings(ChannelStatus.EAP);
|
||||
|
||||
BuildNumber currentBuild = BuildNumber.fromString("IU-139.658");
|
||||
UpdateStrategy strategy = new UpdateStrategy(14, currentBuild, UpdatesInfoXppParserTest.InfoReader.read("idea-patchAvailable.xml"), settings);
|
||||
|
||||
final CheckForUpdateResult result = strategy.checkForUpdates();
|
||||
Assert.assertEquals(UpdateStrategy.State.LOADED, result.getState());
|
||||
Assert.assertEquals(result.getUpdatedChannel().getStatus(), ChannelStatus.EAP);
|
||||
Assert.assertNotNull(result.getNewBuildInSelectedChannel().findPatchForBuild(currentBuild));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<products>
|
||||
<product name="IntelliJ IDEA">
|
||||
<code>IU</code>
|
||||
<code>IC</code>
|
||||
|
||||
<channel id="IDEA14" name="IntelliJ IDEA 14" status="release"
|
||||
url="http://www.jetbrains.com/idea/download"
|
||||
feedback="http://youtrack.jetbrains.net"
|
||||
majorVersion="14">
|
||||
<build number="139.659" version="14.0.2" releaseDate="20141103">
|
||||
<message>IntelliJ IDEA 14.0.2 build 139.659 is available.</message>
|
||||
<button name="Download" url="http://www.jetbrains.com/idea/download" download="true"/>
|
||||
<button name="What's New" url="http://www.jetbrains.com/idea/whatsnew/index.html"/>
|
||||
<button name="Release Notes" url="http://confluence.jetbrains.com/display/IDEADEV/IntelliJ+IDEA+14.0.2+Release+Notes"/>
|
||||
<patch from="139.224" size="30" />
|
||||
<patch from="139.225" size="30" />
|
||||
</build>
|
||||
</channel>
|
||||
|
||||
<channel id="IDEA_14_EAP" name="IntelliJ IDEA 14 EAP" status="eap"
|
||||
url="http://confluence.jetbrains.com/display/IDEADEV/IDEA+14+EAP"
|
||||
feedback="http://youtrack.jetbrains.net"
|
||||
majorVersion="14">
|
||||
<build number="139.659" version="14.0.2" releaseDate="20141103">
|
||||
<message>IntelliJ IDEA 14.0.2 build 139.659 is available.</message>
|
||||
<button name="Download" url="http://confluence.jetbrains.com/display/IDEADEV/IDEA+14+EAP" download="true"/>
|
||||
<button name="Release Notes" url="http://confluence.jetbrains.com/display/IDEADEV/IntelliJ+IDEA+14+139.659.2+Release+Notes"/>
|
||||
<patch from="139.658" size="10" />
|
||||
<patch from="139.224" size="30" />
|
||||
<patch from="139.225" size="30" />
|
||||
</build>
|
||||
</channel>
|
||||
|
||||
</product>
|
||||
|
||||
|
||||
</products>
|
||||
@@ -1040,6 +1040,17 @@ public class RangeMarkerTest extends LightPlatformTestCase {
|
||||
assertTrue(marker.isValid());
|
||||
}
|
||||
|
||||
public void testPersistentMarkerDoesntImpactNormalMarkers() {
|
||||
Document doc = new DocumentImpl("text");
|
||||
RangeMarker normal = doc.createRangeMarker(1, 3);
|
||||
RangeMarker persistent = doc.createRangeMarker(1, 3, true);
|
||||
|
||||
doc.replaceString(0, 4, "before\ntext\nafter");
|
||||
|
||||
assertTrue(persistent.isValid());
|
||||
assertFalse(normal.isValid());
|
||||
}
|
||||
|
||||
public void testMoveTextRetargetsMarkers() throws Exception {
|
||||
RangeMarkerEx marker1 = createMarker("01234567890", 1, 3);
|
||||
DocumentEx document = (DocumentEx)marker1.getDocument();
|
||||
|
||||
@@ -46,6 +46,9 @@ public class UrlClassLoader extends ClassLoader {
|
||||
@NonNls static final String CLASS_EXTENSION = ".class";
|
||||
|
||||
static {
|
||||
// Since Java 7 classloading is parallel on parallel capable classloader (http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html)
|
||||
// Parallel classloading avoids deadlocks like https://youtrack.jetbrains.com/issue/IDEA-131621
|
||||
// Unless explicitly disabled, request parallel loading capability via reflection due to current platform's Java 6 baseline
|
||||
// todo[r.sh] drop condition in IDEA 15
|
||||
// todo[r.sh] drop reflection after migrating to Java 7+
|
||||
boolean parallelLoader = Boolean.parseBoolean(System.getProperty("idea.parallel.class.loader", "true"));
|
||||
|
||||
@@ -430,7 +430,17 @@ public abstract class ChangesTreeList<T> extends JPanel implements TypeSafeDataP
|
||||
myList.setSelectedIndex(listSelection);
|
||||
myList.ensureIndexIsVisible(listSelection);
|
||||
|
||||
if (scrollRow >= 0) {
|
||||
if (scrollRow == -1) {
|
||||
TreeNode root = (TreeNode)model.getRoot();
|
||||
int childrenCount = root.getChildCount();
|
||||
TreePath[] selected = new TreePath[childrenCount];
|
||||
for (int i = 0; i < childrenCount; i++) {
|
||||
TreeNode child = root.getChildAt(i);
|
||||
// reverse order, because the last one will become "current" node. And we want it to be the first one.
|
||||
selected[childrenCount - i - 1] = new TreePath(model.getPathToRoot(child));
|
||||
}
|
||||
myTree.setSelectionPaths(selected);
|
||||
} else {
|
||||
myTree.setSelectionRow(scrollRow);
|
||||
}
|
||||
TreeUtil.showRowCentered(myTree, scrollRow, false);
|
||||
|
||||
@@ -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.
|
||||
@@ -38,7 +38,18 @@ public abstract class XValueModifier {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously calculates initial value
|
||||
*/
|
||||
public void calculateInitialValueEditorText(XInitialValueCallback callback) {
|
||||
callback.setValue(getInitialValueEditorText());
|
||||
}
|
||||
|
||||
public interface XModificationCallback extends XValueCallback {
|
||||
void valueModified();
|
||||
}
|
||||
|
||||
public interface XInitialValueCallback {
|
||||
void setValue(String initialValue);
|
||||
}
|
||||
}
|
||||
+29
-4
@@ -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.
|
||||
@@ -40,7 +40,7 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor {
|
||||
private final XValueModifier myModifier;
|
||||
private final XValueNodeImpl myValueNode;
|
||||
|
||||
public SetValueInplaceEditor(final XValueNodeImpl node, @NotNull final String nodeName) {
|
||||
private SetValueInplaceEditor(final XValueNodeImpl node, @NotNull final String nodeName) {
|
||||
super(node, "setValue");
|
||||
myValueNode = node;
|
||||
myModifier = myValueNode.getValueContainer().getModifier();
|
||||
@@ -57,9 +57,34 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor {
|
||||
myEditorPanel.add(nameLabel, BorderLayout.WEST);
|
||||
|
||||
myEditorPanel.add(myExpressionEditor.getComponent(), BorderLayout.CENTER);
|
||||
final String value = myModifier != null ? myModifier.getInitialValueEditorText() : null;
|
||||
myExpressionEditor.setExpression(XExpressionImpl.fromText(value));
|
||||
}
|
||||
|
||||
public static void show(final XValueNodeImpl node, @NotNull final String nodeName) {
|
||||
final SetValueInplaceEditor editor = new SetValueInplaceEditor(node, nodeName);
|
||||
|
||||
if (editor.myModifier != null) {
|
||||
editor.myModifier.calculateInitialValueEditorText(new XValueModifier.XInitialValueCallback() {
|
||||
@Override
|
||||
public void setValue(final String initialValue) {
|
||||
AppUIUtil.invokeOnEdt(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
editor.show(initialValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
editor.show(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void show(String initialValue) {
|
||||
myExpressionEditor.setExpression(XExpressionImpl.fromText(initialValue));
|
||||
myExpressionEditor.selectAll();
|
||||
|
||||
show();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
-3
@@ -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.
|
||||
@@ -47,7 +47,6 @@ public class XSetValueAction extends XDebuggerTreeActionBase {
|
||||
}
|
||||
|
||||
protected void perform(final XValueNodeImpl node, @NotNull final String nodeName, final AnActionEvent e) {
|
||||
XDebuggerTreeInplaceEditor editor = new SetValueInplaceEditor(node, nodeName);
|
||||
editor.show();
|
||||
SetValueInplaceEditor.show(node, nodeName);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 955 B |
@@ -91,6 +91,9 @@ target(name: "compile", description: "Compile module python") {
|
||||
fileset(dir: "${ideaPlugins}/IntelliLang/lib") {
|
||||
include(name: "*.jar")
|
||||
}
|
||||
fileset(dir: "${pluginHome}/ipnb/lib") {
|
||||
include(name: "*.jar")
|
||||
}
|
||||
}
|
||||
|
||||
ant.path(id: "sourcepath") {
|
||||
@@ -103,6 +106,7 @@ target(name: "compile", description: "Compile module python") {
|
||||
include(name: "openapi/src")
|
||||
include(name: "psi-api/src")
|
||||
include(name: "IntelliLang-python/src")
|
||||
include(name: "ipnb/src")
|
||||
}
|
||||
}
|
||||
//The task requires the following libraries from IntelliJ IDEA distribution:
|
||||
@@ -142,7 +146,7 @@ target(name: "compile", description: "Compile module python") {
|
||||
patternset(refid: "resources.pt")
|
||||
type(type: "file")
|
||||
}
|
||||
fileset(dir: "${pluginHome}/IntelliLang-python/src") {
|
||||
fileset(dir: "${pluginHome}/IntelliLang-python/resources") {
|
||||
patternset(refid: "resources.pt")
|
||||
type(type: "file")
|
||||
}
|
||||
@@ -151,6 +155,10 @@ target(name: "compile", description: "Compile module python") {
|
||||
type(type: "file")
|
||||
}
|
||||
fileset(dir: "${home}/colorSchemes/src")
|
||||
fileset(dir: "${pluginHome}/ipnb/resources") {
|
||||
patternset(refid: "resources.pt")
|
||||
type(type: "file")
|
||||
}
|
||||
}
|
||||
|
||||
//copy plugin.xml
|
||||
|
||||
@@ -13,7 +13,7 @@ public class StudyIcons {
|
||||
return IconLoader.getIcon(path, StudyIcons.class);
|
||||
}
|
||||
|
||||
public static final Icon EducationalProjectType = load("/icons/com/jetbrains/python/edu/EducationalProjectType.png"); // 32x32
|
||||
public static final Icon EducationalProjectType = load("/icons/com/jetbrains/python/edu/EducationalProjectType.png"); // 16x16
|
||||
public static final Icon Lesson = load("/icons/com/jetbrains/python/edu/Lesson.png"); // 16x16
|
||||
public static final Icon LessonCompl = load("/icons/com/jetbrains/python/edu/LessonCompl.png"); // 16x16
|
||||
public static final Icon Prev = load("/icons/com/jetbrains/python/edu/prev.png"); // 16x16
|
||||
|
||||
@@ -21,7 +21,8 @@ import java.io.IOException;
|
||||
public class StudyInitialConfigurator {
|
||||
private static final Logger LOG = Logger.getInstance(StudyInitialConfigurator.class.getName()
|
||||
);
|
||||
@NonNls private static final String CONFIGURED = "StudyPyCharm.InitialConfiguration";
|
||||
@NonNls private static final String CONFIGURED_V1 = "StudyPyCharm.InitialConfiguration";
|
||||
@NonNls private static final String CONFIGURED_V11 = "StudyPyCharm.InitialConfiguration1.1";
|
||||
|
||||
|
||||
/**
|
||||
@@ -34,21 +35,38 @@ public class StudyInitialConfigurator {
|
||||
FileTypeManager fileTypeManager,
|
||||
final ProjectManagerEx projectManager,
|
||||
RecentProjectsManager recentProjectsManager) {
|
||||
if (!propertiesComponent.getBoolean(CONFIGURED, false)) {
|
||||
final File file = new File(getCoursesRoot(), "introduction_course.zip");
|
||||
final File file = new File(getCoursesRoot(), "introduction_course.zip");
|
||||
if (!propertiesComponent.getBoolean(CONFIGURED_V1, false)) {
|
||||
final File newCourses = new File(PathManager.getConfigPath(), "courses");
|
||||
try {
|
||||
FileUtil.createDirectory(newCourses);
|
||||
String fileName = file.getName();
|
||||
String unzippedName = fileName.substring(0, fileName.indexOf("."));
|
||||
File courseDir = new File(newCourses, unzippedName);
|
||||
ZipUtil.unzip(null, courseDir, file, null, null, true);
|
||||
copyCourse(file, newCourses);
|
||||
propertiesComponent.setValue(CONFIGURED_V1, "true");
|
||||
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn("Couldn't copy bundled courses " + e);
|
||||
}
|
||||
}
|
||||
if (!propertiesComponent.getBoolean(CONFIGURED_V11, false)) {
|
||||
final File newCourses = new File(PathManager.getConfigPath(), "courses");
|
||||
if (newCourses.exists()) {
|
||||
try {
|
||||
copyCourse(file, newCourses);
|
||||
propertiesComponent.setValue(CONFIGURED_V11, "true");
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn("Couldn't copy bundled courses " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyCourse(File bundledCourse, File userCourseDir) throws IOException {
|
||||
String fileName = bundledCourse.getName();
|
||||
String unzippedName = fileName.substring(0, fileName.indexOf("."));
|
||||
File courseDir = new File(userCourseDir, unzippedName);
|
||||
ZipUtil.unzip(null, courseDir, bundledCourse, null, null, true);
|
||||
}
|
||||
|
||||
public static File getCoursesRoot() {
|
||||
|
||||
@@ -67,6 +67,7 @@ should import it explicitly. For example, in a skeleton for the `foo` module:
|
||||
```python
|
||||
import foo
|
||||
|
||||
|
||||
class C(foo.B):
|
||||
def bar():
|
||||
"""Do bar and return Bar.
|
||||
@@ -144,6 +145,7 @@ class C(object):
|
||||
pass
|
||||
```
|
||||
|
||||
|
||||
### Versioning
|
||||
|
||||
The recommended way of checking the version of Python is:
|
||||
@@ -151,10 +153,12 @@ The recommended way of checking the version of Python is:
|
||||
```python
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info >= (2, 7) and sys.version_info < (3,):
|
||||
def from_27_until_30():
|
||||
pass
|
||||
```
|
||||
|
||||
A skeleton should document the most recently released version of a library. Use
|
||||
deprecation warnings for functions that have been removed from the API.
|
||||
|
||||
@@ -214,6 +218,7 @@ the skeletons GitHub repository into your PyCharm/IntelliJ config directory:
|
||||
cd <config directory>
|
||||
git clone https://github.com/JetBrains/python-skeletons.git
|
||||
```
|
||||
|
||||
where `<config directory>` is:
|
||||
|
||||
* PyCharm
|
||||
|
||||
@@ -427,6 +427,24 @@ class int(object):
|
||||
"""
|
||||
pass
|
||||
|
||||
def __eq__(self, y):
|
||||
return False
|
||||
|
||||
def __ne__(self, y):
|
||||
return False
|
||||
|
||||
def __lt__(self, y):
|
||||
return False
|
||||
|
||||
def __gt__(self, y):
|
||||
return False
|
||||
|
||||
def __le__(self, y):
|
||||
return False
|
||||
|
||||
def __ge__(self, y):
|
||||
return False
|
||||
|
||||
def __add__(self, y):
|
||||
"""Sum of x and y.
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.jetbrains.python.codeInsight.userSkeletons;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
@@ -24,7 +23,6 @@ import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.SdkModificator;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -65,9 +63,7 @@ public class PyUserSkeletonsUtil {
|
||||
private static List<String> getPossibleUserSkeletonsPaths() {
|
||||
final List<String> result = new ArrayList<String>();
|
||||
result.add(PathManager.getConfigPath() + File.separator + USER_SKELETONS_DIR);
|
||||
result.add(ApplicationManager.getApplication().isInternal()
|
||||
? StringUtil.join(new String[]{PythonHelpersLocator.getPythonCommunityPath(), "helpers", USER_SKELETONS_DIR}, File.separator)
|
||||
: PythonHelpersLocator.getHelperPath(USER_SKELETONS_DIR));
|
||||
result.add(PythonHelpersLocator.getHelperPath(USER_SKELETONS_DIR));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ public class PyTypeCheckerInspection extends PyInspection {
|
||||
String msg= String.format("Expected type %s, got '%s' instead", quotedExpectedName, actualName);
|
||||
if (expected instanceof PyStructuralType) {
|
||||
final Set<String> expectedAttributes = ((PyStructuralType)expected).getAttributeNames();
|
||||
final Set<String> actualAttributes = getAttributes(actual);
|
||||
final Set<String> actualAttributes = getAttributes(actual, context);
|
||||
if (actualAttributes != null) {
|
||||
final Sets.SetView<String> missingAttributes = Sets.difference(expectedAttributes, actualAttributes);
|
||||
if (missingAttributes.size() == 1) {
|
||||
@@ -160,12 +160,12 @@ public class PyTypeCheckerInspection extends PyInspection {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Set<String> getAttributes(@NotNull PyType type) {
|
||||
private static Set<String> getAttributes(@NotNull PyType type, @NotNull TypeEvalContext context) {
|
||||
if (type instanceof PyStructuralType) {
|
||||
return ((PyStructuralType)type).getAttributeNames();
|
||||
}
|
||||
else if (type instanceof PyClassType) {
|
||||
return PyTypeChecker.getClassAttributes(((PyClassType)type).getPyClass(), true);
|
||||
return PyTypeChecker.getClassTypeAttributes((PyClassType)type, true, context);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1190,7 +1190,23 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
|
||||
continue;
|
||||
}
|
||||
final PyType type = context.getType(expression);
|
||||
result.add(type instanceof PyClassLikeType ? (PyClassLikeType)type : null);
|
||||
PyClassLikeType classLikeType = null;
|
||||
if (type instanceof PyClassLikeType) {
|
||||
classLikeType = (PyClassLikeType)type;
|
||||
}
|
||||
else {
|
||||
final PsiReference ref = expression.getReference();
|
||||
if (ref != null) {
|
||||
final PsiElement resolved = ref.resolve();
|
||||
if (resolved instanceof PyClass) {
|
||||
final PyType resolvedType = context.getType((PyClass)resolved);
|
||||
if (resolvedType instanceof PyClassLikeType) {
|
||||
classLikeType = (PyClassLikeType)resolvedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result.add(classLikeType);
|
||||
}
|
||||
}
|
||||
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(this);
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
*/
|
||||
package com.jetbrains.python.psi.types;
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.PyCustomMember;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
@@ -167,15 +169,15 @@ public class PyTypeChecker {
|
||||
return expectedStructural.getAttributeNames().containsAll(actualStructural.getAttributeNames());
|
||||
}
|
||||
if (expected instanceof PyStructuralType && actual instanceof PyClassType) {
|
||||
final PyClass cls = ((PyClassType)actual).getPyClass();
|
||||
if (overridesGetAttr(cls, context)) {
|
||||
final PyClassType actualClassType = (PyClassType)actual;
|
||||
if (overridesGetAttr(actualClassType.getPyClass(), context)) {
|
||||
return true;
|
||||
}
|
||||
final Set<String> actualAttributes = getClassAttributes(cls, true);
|
||||
final Set<String> actualAttributes = getClassTypeAttributes(actualClassType, true, context);
|
||||
return actualAttributes.containsAll(((PyStructuralType)expected).getAttributeNames());
|
||||
}
|
||||
if (actual instanceof PyStructuralType && expected instanceof PyClassType) {
|
||||
final Set<String> expectedAttributes = getClassAttributes(((PyClassType)expected).getPyClass(), true);
|
||||
final Set<String> expectedAttributes = getClassTypeAttributes((PyClassType)expected, true, context);
|
||||
return expectedAttributes.containsAll(((PyStructuralType)actual).getAttributeNames());
|
||||
}
|
||||
if (actual instanceof PyCallableType && expected instanceof PyCallableType) {
|
||||
@@ -205,7 +207,19 @@ public class PyTypeChecker {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Set<String> getClassAttributes(@NotNull PyClass cls, boolean inherited) {
|
||||
public static Set<String> getClassTypeAttributes(@NotNull PyClassType type, boolean inherited, @NotNull TypeEvalContext context) {
|
||||
final Set<String> attributes = getClassAttributes(type.getPyClass(), inherited, context);
|
||||
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
|
||||
final Collection<PyCustomMember> members = provider.getMembers(type, null);
|
||||
for (PyCustomMember member : members) {
|
||||
attributes.add(member.getName());
|
||||
}
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<String> getClassAttributes(@NotNull PyClass cls, boolean inherited, @NotNull TypeEvalContext context) {
|
||||
final Set<String> attributes = new HashSet<String>();
|
||||
for (PyFunction function : cls.getMethods(false)) {
|
||||
attributes.add(function.getName());
|
||||
@@ -218,7 +232,10 @@ public class PyTypeChecker {
|
||||
}
|
||||
if (inherited) {
|
||||
for (PyClass ancestor : cls.getAncestorClasses()) {
|
||||
attributes.addAll(getClassAttributes(ancestor, false));
|
||||
final PyType ancestorType = context.getType(ancestor);
|
||||
if (ancestorType instanceof PyClassType) {
|
||||
attributes.addAll(getClassTypeAttributes((PyClassType)ancestorType, false, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
return attributes;
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
def f(x):
|
||||
print(x < 0, x <= 0, x > 0, x >= 0, x != 0)
|
||||
print(x.foo)
|
||||
|
||||
|
||||
print(f(<warning descr="Type 'bool' doesn't have expected attribute 'foo'">True</warning>))
|
||||
print(f(<warning descr="Type 'int' doesn't have expected attribute 'foo'">0</warning>))
|
||||
print(f(<warning descr="Type 'float' doesn't have expected attribute 'foo'">3.14</warning>))
|
||||
@@ -267,4 +267,8 @@ public class PyTypeCheckerInspectionTest extends PyTestCase {
|
||||
public void testGetAttributeAgainstStructuralType() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testComparisonOperatorsForNumericTypes() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user