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:
@@ -159,7 +159,7 @@ public class RedundantCastUtil {
|
||||
}
|
||||
|
||||
@Override public void visitReturnStatement(PsiReturnStatement statement) {
|
||||
final PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
|
||||
final PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, true, PsiLambdaExpression.class);
|
||||
if (method != null) {
|
||||
final PsiType returnType = method.getReturnType();
|
||||
final PsiExpression returnValue = statement.getReturnValue();
|
||||
|
||||
+9
@@ -71,6 +71,15 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
|
||||
|
||||
@Override
|
||||
public final CandidateInfo resolveConflict(@NotNull final List<CandidateInfo> conflicts){
|
||||
final MethodCandidateInfo.CurrentCandidateProperties properties = MethodCandidateInfo.getCurrentMethod(myArgumentsList);
|
||||
if (properties != null) {
|
||||
final PsiMethod method = properties.getMethod();
|
||||
for (CandidateInfo conflict : conflicts) {
|
||||
if (conflict.getElement() == method) {
|
||||
return conflict;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MethodCandidateInfo.ourOverloadGuard.doPreventingRecursion(myArgumentsList, true, new Computable<CandidateInfo>() {
|
||||
@Override
|
||||
public CandidateInfo compute() {
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class CommandTest {
|
||||
|
||||
public static class Command {
|
||||
public String[] getKeywords() { return new String[] {"GET", "PUT", "POST"}; }
|
||||
public String getDescription() { return "Some HTTP command"; }
|
||||
}
|
||||
|
||||
|
||||
public static void main(Stream<Command> stream) {
|
||||
stream.map(cmd -> Arrays.stream(cmd.getKeywords()).map(key -> String.format("%s -> %s", key, cmd.getDescription()))).flatMap(Function.identity());
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import java.util.Optional;
|
||||
|
||||
class CommandTest {
|
||||
public Object getObject() {
|
||||
Optional<Object> o = Optional.of("x");
|
||||
return o.map(bx -> {
|
||||
return (Object)"";
|
||||
})
|
||||
.orElse(new Integer(1));
|
||||
}
|
||||
|
||||
public Object getObject1() {
|
||||
Optional<Object> o = Optional.of("x");
|
||||
return o.map(bx -> {
|
||||
return (<warning descr="Casting 'new Object()' to 'Object' is redundant">Object</warning>)new Object();
|
||||
})
|
||||
.orElse(new Integer(1));
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import java.io.IOException;
|
||||
|
||||
class CommandTest {
|
||||
|
||||
public URL someFunction(URI uri) {
|
||||
return unchecked(uri::toURL);
|
||||
}
|
||||
|
||||
public interface UncheckedRun<T> {
|
||||
public T run() throws Throwable;
|
||||
}
|
||||
|
||||
public static <T> T unchecked(UncheckedRun<T> run) {
|
||||
try {
|
||||
return run.run();
|
||||
} catch (Throwable throwable) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class URI {
|
||||
abstract URL toURL() throws IOException;
|
||||
}
|
||||
|
||||
class URL {}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.codeInsight.daemon.lambda;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.psi.PsiMethodCallExpression;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class Java8ExpressionsCheckTest extends LightDaemonAnalyzerTestCase {
|
||||
@NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/expressions";
|
||||
|
||||
public void testSecondConflictResolutionOnSameMethodCall() throws Exception {
|
||||
doTestAllMethodCallExpressions();
|
||||
}
|
||||
|
||||
private void doTestAllMethodCallExpressions() {
|
||||
configureByFile(BASE_PATH + "/" + getTestName(false) + ".java");
|
||||
final Collection<PsiMethodCallExpression> methodCallExpressions = PsiTreeUtil.findChildrenOfType(getFile(), PsiMethodCallExpression.class);
|
||||
for (PsiMethodCallExpression expression : methodCallExpressions) {
|
||||
getPsiManager().dropResolveCaches();
|
||||
assertNotNull("Failed inference for: " + expression.getText(), expression.getType());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk18();
|
||||
}
|
||||
}
|
||||
+4
@@ -63,6 +63,10 @@ public class Java8RegressionTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIDEA138696() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
+1
@@ -37,6 +37,7 @@ public class LambdaRedundantCastTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testIntersection() { doTest(); }
|
||||
public void testSer() { doTest(); }
|
||||
public void testLambdaReturnExpressions() { doTest(); }
|
||||
public void testLambdaReturnExpressions1() { doTest(); }
|
||||
private void doTest() {
|
||||
doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false);
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ public class DiffDrawUtil {
|
||||
// TODO: diff looks cool with wide markers. Maybe we can keep them ?
|
||||
highlighter.setThinErrorStripeMark(true);
|
||||
|
||||
installGutterRenderer(highlighter, type);
|
||||
installGutterRenderer(highlighter, type, ignored);
|
||||
|
||||
return highlighter;
|
||||
}
|
||||
@@ -232,8 +232,15 @@ public class DiffDrawUtil {
|
||||
return highlighter;
|
||||
}
|
||||
|
||||
public static void installGutterRenderer(@NotNull RangeHighlighter highlighter, @NotNull TextDiffType type) {
|
||||
highlighter.setLineMarkerRenderer(new DiffLineMarkerRenderer(type));
|
||||
public static void installGutterRenderer(@NotNull RangeHighlighter highlighter,
|
||||
@NotNull TextDiffType type) {
|
||||
installGutterRenderer(highlighter, type, false);
|
||||
}
|
||||
|
||||
public static void installGutterRenderer(@NotNull RangeHighlighter highlighter,
|
||||
@NotNull TextDiffType type,
|
||||
boolean ignoredFoldingOutline) {
|
||||
highlighter.setLineMarkerRenderer(new DiffLineMarkerRenderer(type, ignoredFoldingOutline));
|
||||
}
|
||||
|
||||
public static void installEmptyRangeRenderer(@NotNull RangeHighlighter highlighter, @NotNull TextDiffType type) {
|
||||
|
||||
@@ -25,32 +25,50 @@ import java.awt.*;
|
||||
|
||||
public class DiffLineMarkerRenderer implements LineMarkerRenderer {
|
||||
@NotNull private final TextDiffType myDiffType;
|
||||
private final boolean myIgnoredFoldingOutline;
|
||||
|
||||
public DiffLineMarkerRenderer(@NotNull TextDiffType diffType) {
|
||||
myDiffType = diffType;
|
||||
this(diffType, false);
|
||||
}
|
||||
|
||||
public DiffLineMarkerRenderer(@NotNull TextDiffType diffType, boolean ignoredFoldingOutline) {
|
||||
myDiffType = diffType;
|
||||
myIgnoredFoldingOutline = ignoredFoldingOutline;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paint(Editor editor, Graphics g, Rectangle range) {
|
||||
Color color = myDiffType.getColor(editor);
|
||||
|
||||
EditorGutterComponentEx gutter = ((EditorEx)editor).getGutterComponentEx();
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
int x = 0;
|
||||
int x1 = 0;
|
||||
int x2 = x1 + gutter.getWidth();
|
||||
int y = range.y;
|
||||
int width = gutter.getWidth();
|
||||
int height = range.height;
|
||||
|
||||
if (height > 2) {
|
||||
g.setColor(color);
|
||||
g.fillRect(x, y, width, height);
|
||||
DiffDrawUtil.drawChunkBorderLine(g2, x, x + width, y - 1, color);
|
||||
DiffDrawUtil.drawChunkBorderLine(g2, x, x + width, y + height - 1, color);
|
||||
if (myIgnoredFoldingOutline) {
|
||||
int xOutline = gutter.getWhitespaceSeparatorOffset();
|
||||
|
||||
g.setColor(myDiffType.getIgnoredColor(editor));
|
||||
g.fillRect(xOutline, y, x2 - xOutline, height);
|
||||
|
||||
g.setColor(color);
|
||||
g.fillRect(x1, y, xOutline - x1, height);
|
||||
}
|
||||
else {
|
||||
g.setColor(color);
|
||||
g.fillRect(x1, y, x2 - x1, height);
|
||||
}
|
||||
DiffDrawUtil.drawChunkBorderLine(g2, x1, x2, y - 1, color);
|
||||
DiffDrawUtil.drawChunkBorderLine(g2, x1, x2, y + height - 1, color);
|
||||
}
|
||||
else {
|
||||
// range is empty - insertion or deletion
|
||||
// Draw 2 pixel line in that case
|
||||
DiffDrawUtil.drawDoubleChunkBorderLine(g2, x, x + width, y - 1, color);
|
||||
DiffDrawUtil.drawDoubleChunkBorderLine(g2, x1, x2, y - 1, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2608,7 +2608,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
});
|
||||
}*/
|
||||
|
||||
final Set<VirtualFile> visitedRoots = new THashSet<VirtualFile>();
|
||||
final Set<VirtualFile> visitedRoots = ContainerUtil.newConcurrentSet();
|
||||
for (IndexedRootsProvider provider : Extensions.getExtensions(IndexedRootsProvider.EP_NAME)) {
|
||||
//important not to depend on project here, to support per-project background reindex
|
||||
// each client gives a project to FileBasedIndex
|
||||
|
||||
+135
-7
@@ -132,35 +132,130 @@ public class ConfigurableExtensionPointUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param project the project used to load application settings
|
||||
* @param configurables a list of settings to process
|
||||
* @return the map of different groups of settings
|
||||
*/
|
||||
public static Map<String, List<Configurable>> groupConfigurables(@NotNull List<Configurable> configurables) {
|
||||
Map<String, Node<ConfigurableWrapper>> tree = ContainerUtil.newHashMap();
|
||||
for (Configurable configurable : configurables) {
|
||||
if (configurable instanceof ConfigurableWrapper) {
|
||||
ConfigurableWrapper wrapper = (ConfigurableWrapper)configurable;
|
||||
String id = wrapper.getId();
|
||||
Node<ConfigurableWrapper> node = Node.get(tree, id);
|
||||
if (node.myValue != null) {
|
||||
LOG.warn("ignore configurable with duplicated id: " + id);
|
||||
}
|
||||
else {
|
||||
String parentId = wrapper.getParentId();
|
||||
String groupId = wrapper.getExtensionPoint().groupId;
|
||||
if (groupId != null) {
|
||||
if (parentId != null) {
|
||||
LOG.warn("ignore deprecated groupId: " + groupId + " for id: " + id);
|
||||
}
|
||||
else {
|
||||
LOG.warn("use deprecated groupId instead of parentId: " + groupId + " for id: " + id);
|
||||
parentId = groupId;
|
||||
}
|
||||
}
|
||||
if (Node.cyclic(tree, parentId, node)) {
|
||||
LOG.warn("ignore cyclic dependency: " + parentId + " cannot contain " + id);
|
||||
parentId = null;
|
||||
}
|
||||
node.myParent = Node.add(tree, parentId, node);
|
||||
node.myValue = wrapper;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Node.add(tree, null, configurable);
|
||||
}
|
||||
}
|
||||
Map<String, List<Configurable>> map = ContainerUtil.newHashMap();
|
||||
for (String id : tree.keySet().toArray(new String[tree.size()])) {
|
||||
Node<ConfigurableWrapper> node = tree.get(id);
|
||||
if (node != null) {
|
||||
List<Configurable> list = getConfigurables(tree, node);
|
||||
if (list != null) {
|
||||
map.put(id, list);
|
||||
tree.remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param tree a map that represents a tree of nodes
|
||||
* @param node a current node to process children recursively
|
||||
* @return the list of settings for a group or {@code null} for internal node
|
||||
*/
|
||||
private static List<Configurable> getConfigurables(Map<String, Node<ConfigurableWrapper>> tree, Node<ConfigurableWrapper> node) {
|
||||
List<Configurable> list = ContainerUtil.newArrayListWithCapacity(node.myChildren.size());
|
||||
for (Iterator<Object> iterator = node.myChildren.iterator(); iterator.hasNext(); iterator.remove()) {
|
||||
Object child = iterator.next();
|
||||
if (child instanceof Configurable) {
|
||||
list.add((Configurable)child);
|
||||
}
|
||||
else {
|
||||
@SuppressWarnings("unchecked") // expected type
|
||||
Node<ConfigurableWrapper> value = (Node<ConfigurableWrapper>)child;
|
||||
if (getConfigurables(tree, value) != null) {
|
||||
throw new IllegalStateException("unexpected algorithm state");
|
||||
}
|
||||
list.add(value.myValue);
|
||||
tree.remove(value.myValue.getId());
|
||||
}
|
||||
}
|
||||
if (node.myValue == null) {
|
||||
return list; // for group only
|
||||
}
|
||||
for (Configurable configurable : list) {
|
||||
node.myValue = node.myValue.addChild(configurable);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param project a project used to load project settings or {@code null}
|
||||
* @param withIdeSettings specifies whether to load application settings or not
|
||||
* @param loadComponents specifies whether to load Configurable components or not
|
||||
* @return the list of all available settings according to parameters
|
||||
* @return the list of all valid settings according to parameters
|
||||
*/
|
||||
private static List<Configurable> getAllConfigurables(@Nullable Project project, boolean withIdeSettings, boolean loadComponents) {
|
||||
private static List<Configurable> getConfigurables(@Nullable Project project, boolean withIdeSettings, boolean loadComponents) {
|
||||
List<Configurable> list = ContainerUtil.newArrayList();
|
||||
if (withIdeSettings) {
|
||||
Application application = ApplicationManager.getApplication();
|
||||
if (application != null) {
|
||||
if (loadComponents) {
|
||||
ContainerUtil.addAll(list, application.getComponents(Configurable.class));
|
||||
addValid(list, application.getComponents(Configurable.class), null);
|
||||
}
|
||||
for (ConfigurableEP<Configurable> extension : application.getExtensions(Configurable.APPLICATION_CONFIGURABLE)) {
|
||||
ContainerUtil.addIfNotNull(list, ConfigurableWrapper.wrapConfigurable(extension));
|
||||
addValid(list, ConfigurableWrapper.wrapConfigurable(extension), null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (project != null) {
|
||||
if (loadComponents) {
|
||||
ContainerUtil.addAll(list, project.getComponents(Configurable.class));
|
||||
addValid(list, project.getComponents(Configurable.class), project);
|
||||
}
|
||||
for (ConfigurableEP<Configurable> extension : project.getExtensions(Configurable.PROJECT_CONFIGURABLE)) {
|
||||
ContainerUtil.addIfNotNull(list, ConfigurableWrapper.wrapConfigurable(extension));
|
||||
addValid(list, ConfigurableWrapper.wrapConfigurable(extension), project);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void addValid(List<Configurable> list, Configurable configurable, Project project) {
|
||||
if (isValid(configurable, project)) {
|
||||
list.add(configurable);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addValid(List<Configurable> list, Configurable[] configurables, Project project) {
|
||||
for (Configurable configurable : configurables) {
|
||||
addValid(list, configurable, project);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configurable settings component to validate
|
||||
* @param project current project, default template project or {@code null} for IDE settings
|
||||
@@ -285,4 +380,37 @@ public class ConfigurableExtensionPointUtil {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class that helps to build a tree.
|
||||
*/
|
||||
private static final class Node<V> {
|
||||
List<Object> myChildren = ContainerUtil.newArrayList();
|
||||
Node<V> myParent;
|
||||
V myValue;
|
||||
|
||||
private static <I, V> Node<V> get(Map<I, Node<V>> tree, I id) {
|
||||
Node<V> node = tree.get(id);
|
||||
if (node == null) {
|
||||
node = new Node<V>();
|
||||
tree.put(id, node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private static <I, V> Node<V> add(Map<I, Node<V>> tree, I id, Object child) {
|
||||
Node<V> node = get(tree, id);
|
||||
node.myChildren.add(child);
|
||||
return node;
|
||||
}
|
||||
|
||||
private static <I, V> boolean cyclic(Map<I, Node<V>> tree, I id, Node<V> parent) {
|
||||
for (Node<V> node = tree.get(id); node != null; node = node.myParent) {
|
||||
if (node == parent) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-28
@@ -60,10 +60,40 @@ public class ResourceBundleFileStructureViewElement implements StructureViewTree
|
||||
return myResourceBundle;
|
||||
}
|
||||
|
||||
private Map<String, IProperty> getChildrenIdShowOnlyIncomplete() {
|
||||
@NotNull
|
||||
public StructureViewTreeElement[] getChildren() {
|
||||
final Map<String, IProperty> propertyNames = getPropertiesMap(myResourceBundle, myShowOnlyIncomplete);
|
||||
List<StructureViewTreeElement> result = new ArrayList<StructureViewTreeElement>(propertyNames.size());
|
||||
for (IProperty property : propertyNames.values()) {
|
||||
result.add(new ResourceBundlePropertyStructureViewElement(myResourceBundle, property));
|
||||
}
|
||||
return result.toArray(new StructureViewTreeElement[result.size()]);
|
||||
}
|
||||
|
||||
public static Map<String, IProperty> getPropertiesMap(ResourceBundle resourceBundle, boolean onlyIncomplete) {
|
||||
List<PropertiesFile> propertiesFiles = resourceBundle.getPropertiesFiles();
|
||||
final Map<String, IProperty> propertyNames;
|
||||
if (onlyIncomplete) {
|
||||
propertyNames = getChildrenIdShowOnlyIncomplete(resourceBundle);
|
||||
} else {
|
||||
propertyNames = new LinkedHashMap<String, IProperty>();
|
||||
for (PropertiesFile propertiesFile : propertiesFiles) {
|
||||
List<IProperty> properties = propertiesFile.getProperties();
|
||||
for (IProperty property : properties) {
|
||||
String name = property.getKey();
|
||||
if (!propertyNames.containsKey(name)) {
|
||||
propertyNames.put(name, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return propertyNames;
|
||||
}
|
||||
|
||||
private static Map<String, IProperty> getChildrenIdShowOnlyIncomplete(ResourceBundle resourceBundle) {
|
||||
final Map<String, IProperty> propertyNames = new LinkedHashMap<String, IProperty>();
|
||||
TObjectIntHashMap<String> occurrences = new TObjectIntHashMap<String>();
|
||||
for (PropertiesFile file : myResourceBundle.getPropertiesFiles()) {
|
||||
for (PropertiesFile file : resourceBundle.getPropertiesFiles()) {
|
||||
Map<String, IProperty> currentFilePropertyNames = new LinkedHashMap<String, IProperty>();
|
||||
for (IProperty property : file.getProperties()) {
|
||||
String name = property.getKey();
|
||||
@@ -80,7 +110,7 @@ public class ResourceBundleFileStructureViewElement implements StructureViewTree
|
||||
}
|
||||
}
|
||||
}
|
||||
final int targetOccurrences = myResourceBundle.getPropertiesFiles().size();
|
||||
final int targetOccurrences = resourceBundle.getPropertiesFiles().size();
|
||||
occurrences.forEachEntry(new TObjectIntProcedure<String>() {
|
||||
@Override
|
||||
public boolean execute(String propertyName, int occurrences) {
|
||||
@@ -93,31 +123,6 @@ public class ResourceBundleFileStructureViewElement implements StructureViewTree
|
||||
return propertyNames;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StructureViewTreeElement[] getChildren() {
|
||||
List<PropertiesFile> propertiesFiles = myResourceBundle.getPropertiesFiles();
|
||||
final Map<String, IProperty> propertyNames;
|
||||
if (myShowOnlyIncomplete) {
|
||||
propertyNames = getChildrenIdShowOnlyIncomplete();
|
||||
} else {
|
||||
propertyNames = new LinkedHashMap<String, IProperty>();
|
||||
for (PropertiesFile propertiesFile : propertiesFiles) {
|
||||
List<IProperty> properties = propertiesFile.getProperties();
|
||||
for (IProperty property : properties) {
|
||||
String name = property.getKey();
|
||||
if (!propertyNames.containsKey(name)) {
|
||||
propertyNames.put(name, property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
List<StructureViewTreeElement> result = new ArrayList<StructureViewTreeElement>(propertyNames.size());
|
||||
for (IProperty property : propertyNames.values()) {
|
||||
result.add(new ResourceBundlePropertyStructureViewElement(myResourceBundle, property));
|
||||
}
|
||||
return result.toArray(new StructureViewTreeElement[result.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ItemPresentation getPresentation() {
|
||||
return new ItemPresentation() {
|
||||
|
||||
@@ -134,5 +134,9 @@
|
||||
description="Add Property to Resource Bundle">
|
||||
<add-to-group group-id="NewGroup" anchor="first"/>
|
||||
</action>
|
||||
<action id="GotoNextIncompletePropertyAction"
|
||||
class="com.intellij.lang.properties.editor.GotoNextIncompletePropertyAction"
|
||||
text="Go to next incomplete property"
|
||||
use-shortcut-of="GotoNextError"/>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2000-2015 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.lang.properties.editor;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class GotoNextIncompletePropertyAction extends AnAction {
|
||||
private final static Logger LOG = Logger.getInstance(GotoNextIncompletePropertyAction.class);
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final ResourceBundleEditor editor = (ResourceBundleEditor)PlatformDataKeys.FILE_EDITOR.getData(e.getDataContext());
|
||||
LOG.assertTrue(editor != null);
|
||||
editor.selectNextIncompleteProperty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(PlatformDataKeys.FILE_EDITOR.getData(e.getDataContext()) instanceof ResourceBundleEditor);
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,11 @@ import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeUi;
|
||||
import com.intellij.ide.util.treeView.smartTree.CachingChildrenTreeNode;
|
||||
import com.intellij.ide.util.treeView.smartTree.Sorter;
|
||||
import com.intellij.ide.util.treeView.smartTree.TreeElement;
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
import com.intellij.lang.properties.PropertiesImplUtil;
|
||||
import com.intellij.lang.properties.PropertiesUtil;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.lang.properties.psi.PropertiesResourceBundleUtil;
|
||||
@@ -682,6 +684,38 @@ public class ResourceBundleEditor extends UserDataHolderBase implements FileEdit
|
||||
return selectedElements.size() == 1 ? ContainerUtil.getFirstItem(selectedElements) : null;
|
||||
}
|
||||
|
||||
public void selectNextIncompleteProperty() {
|
||||
if (getSelectedNodes().size() != 1) {
|
||||
return;
|
||||
}
|
||||
final IProperty selectedProperty = getSelectedProperty();
|
||||
if (selectedProperty == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ResourceBundleFileStructureViewElement root =
|
||||
(ResourceBundleFileStructureViewElement)myStructureViewComponent.getTreeModel().getRoot();
|
||||
final Map<String, IProperty> propertiesMap =
|
||||
ResourceBundleFileStructureViewElement.getPropertiesMap(myResourceBundle, root.isShowOnlyIncomplete());
|
||||
final boolean isAlphaSorted = myStructureViewComponent.isActionActive(Sorter.ALPHA_SORTER_ID);
|
||||
final List<String> keysOrder = new ArrayList<String>(propertiesMap.keySet());
|
||||
if (isAlphaSorted) {
|
||||
Collections.sort(keysOrder);
|
||||
}
|
||||
|
||||
final String currentKey = selectedProperty.getKey();
|
||||
final int idx = keysOrder.indexOf(currentKey);
|
||||
LOG.assertTrue(idx != -1);
|
||||
for (int i = 1; i < keysOrder.size(); i++) {
|
||||
int trimmedIndex = (i + idx) % keysOrder.size();
|
||||
final String key = keysOrder.get(trimmedIndex);
|
||||
if (!PropertiesUtil.isPropertyComplete(myResourceBundle, key)) {
|
||||
selectProperty(key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public JComponent getComponent() {
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package com.jetbrains.numpy.codeInsight;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
@@ -46,7 +48,8 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("ndarray", "numpy.core.multiarray.ndarray");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("numpy.ndarray", "numpy.core.multiarray.ndarray");
|
||||
// 184 occurrences
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("array_like", "collections.Iterable or int or long or float or complex");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("array_like", "numpy.core.multiarray.ndarray or collections.Iterable");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("array-like", "numpy.core.multiarray.ndarray or collections.Iterable");
|
||||
// Parameters marked as 'data-type' actually get any Python type identifier such as 'bool' or
|
||||
// an instance of 'numpy.core.multiarray.dtype', however the type checker isn't able to check it.
|
||||
// 30 occurrences
|
||||
@@ -55,8 +58,8 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
// 16 occurrences
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("scalar", "int or long or float or complex");
|
||||
// 10 occurrences
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("array", "numpy.core.multiarray.ndarray");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("numpy.array", "numpy.core.multiarray.ndarray");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("array", "numpy.core.multiarray.ndarray or collections.Iterable");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("numpy.array", "numpy.core.multiarray.ndarray or collections.Iterable");
|
||||
// 9 occurrences
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("any", "object");
|
||||
// 5 occurrences
|
||||
@@ -68,7 +71,13 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
// 3 occurrences
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("number", "int or long or float or complex");
|
||||
|
||||
//treat all collections as iterable
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("sequence", "collections.Iterable");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("set", "collections.Iterable");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("list", "collections.Iterable");
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("tuple", "collections.Iterable");
|
||||
|
||||
NUMPY_ALIAS_TO_REAL_TYPE.put("ints", "int");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -82,23 +91,46 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
final PyPsiFacade facade = getPsiFacade(function);
|
||||
switch (returns.size()) {
|
||||
case 0:
|
||||
// Function returns nothing
|
||||
return facade.parseTypeAnnotation("None", function);
|
||||
return null;
|
||||
case 1:
|
||||
// Function returns single value
|
||||
final String typeName = returns.get(0).getType();
|
||||
if (typeName != null) {
|
||||
final PyType genericType = getPsiFacade(function).parseTypeAnnotation("T", function);
|
||||
if (isUfuncType(function, typeName)) return genericType;
|
||||
return parseNumpyDocType(function, typeName);
|
||||
}
|
||||
return null;
|
||||
default:
|
||||
// Function returns a tuple
|
||||
final ArrayList<PyType> unionMembers = new ArrayList<PyType>();
|
||||
|
||||
final List<PyType> members = new ArrayList<PyType>();
|
||||
for (NumPyDocStringParameter ret : returns) {
|
||||
|
||||
for (int i = 0; i < returns.size(); i++) {
|
||||
NumPyDocStringParameter ret = returns.get(i);
|
||||
final String memberTypeName = ret.getType();
|
||||
members.add(memberTypeName != null ? parseNumpyDocType(function, memberTypeName) : null);
|
||||
final PyType returnType = memberTypeName != null ? parseNumpyDocType(function, memberTypeName) : null;
|
||||
final boolean isOptional = memberTypeName != null && memberTypeName.contains("optional");
|
||||
|
||||
if (isOptional) {
|
||||
if (i != 0) {
|
||||
if(members.size() > 1)
|
||||
unionMembers.add(facade.createTupleType(members, function));
|
||||
else
|
||||
unionMembers.add(returnType);
|
||||
}
|
||||
}
|
||||
members.add(returnType);
|
||||
|
||||
if (i == returns.size() - 1 && isOptional) {
|
||||
unionMembers.add(facade.createTupleType(members, function));
|
||||
}
|
||||
}
|
||||
return facade.createTupleType(members, function);
|
||||
if (unionMembers.isEmpty()) {
|
||||
return facade.createTupleType(members, function);
|
||||
}
|
||||
return facade.createUnionType(unionMembers);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,13 +173,8 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
@Nullable
|
||||
private static PyType parseSingleNumpyDocType(@NotNull PsiElement anchor, @NotNull String typeString) {
|
||||
final PyPsiFacade facade = getPsiFacade(anchor);
|
||||
final String realTypeName = NUMPY_ALIAS_TO_REAL_TYPE.get(typeString);
|
||||
if (realTypeName != null) {
|
||||
final PyType type = facade.parseTypeAnnotation(realTypeName, anchor);
|
||||
if (type != null) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
typeString = getNumpyRealTypeName(typeString);
|
||||
|
||||
final PyType type = facade.parseTypeAnnotation(typeString, anchor);
|
||||
if (type != null) {
|
||||
return type;
|
||||
@@ -155,6 +182,22 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
return getNominalType(anchor, typeString);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getNumpyRealTypeName(@NotNull String typeString) {
|
||||
final String realTypeName = NUMPY_ALIAS_TO_REAL_TYPE.get(typeString);
|
||||
if (realTypeName != null) {
|
||||
return realTypeName;
|
||||
}
|
||||
final List<String> typeSubStrings = StringUtil.split(typeString, " ");
|
||||
List<String> typeParts = new ArrayList<String>();
|
||||
for (String string : typeSubStrings) {
|
||||
final String type = NUMPY_ALIAS_TO_REAL_TYPE.get(string);
|
||||
typeParts.add(type != null ? type : string);
|
||||
}
|
||||
typeString = StringUtil.join(typeParts, " ");
|
||||
return typeString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts literal into type, e.g. -1 -> int, 'fro' -> str
|
||||
*/
|
||||
@@ -188,6 +231,16 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
return getPsiFacade(anchor).createUnionType(types);
|
||||
}
|
||||
|
||||
private static boolean isUfuncType(@NotNull PsiElement anchor, @NotNull final String typeString) {
|
||||
for (String typeName : NumPyDocString.getNumpyUnionType(typeString)) {
|
||||
if (anchor instanceof PyFunction && NumpyUfuncs.isUFunc(((PyFunction)anchor).getName()) &&
|
||||
("array_like".equals(typeName) || "ndarray".equals(typeName))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyType getParameterType(@NotNull PyFunction function, @NotNull String parameterName) {
|
||||
final NumPyDocString docString = NumPyDocString.forFunction(function, function);
|
||||
@@ -200,7 +253,14 @@ public class NumpyDocStringTypeProvider extends PyTypeProviderBase {
|
||||
parameter = docString.getNamedParameter(parameterName.substring(2));
|
||||
}
|
||||
if (parameter != null) {
|
||||
return parseNumpyDocType(function, parameter.getType());
|
||||
if (isUfuncType(function, parameter.getType())) {
|
||||
return getPsiFacade(function).parseTypeAnnotation("T <= numbers.Number|numpy.core.multiarray.ndarray", function);
|
||||
}
|
||||
final PyType numpyDocType = parseNumpyDocType(function, parameter.getType());
|
||||
if ("size".equals(parameterName)) {
|
||||
return getPsiFacade(function).createUnionType(Lists.newArrayList(numpyDocType, PyBuiltinCache.getInstance(function).getIntType()));
|
||||
}
|
||||
return numpyDocType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.jetbrains.numpy.codeInsight;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NumpyUfuncs {
|
||||
private static final List<String> UFUNC_LIST = new ArrayList<String>();
|
||||
|
||||
public static boolean isUFunc(@Nullable final String name) {
|
||||
return UFUNC_LIST.contains(name);
|
||||
}
|
||||
|
||||
static {
|
||||
//Math operations
|
||||
UFUNC_LIST.add("add");
|
||||
UFUNC_LIST.add("subtract");
|
||||
UFUNC_LIST.add("multiply");
|
||||
UFUNC_LIST.add("divide");
|
||||
UFUNC_LIST.add("logaddexp");
|
||||
UFUNC_LIST.add("logaddexp2");
|
||||
UFUNC_LIST.add("true_divide");
|
||||
UFUNC_LIST.add("floor_divide");
|
||||
UFUNC_LIST.add("negative");
|
||||
UFUNC_LIST.add("power");
|
||||
UFUNC_LIST.add("remainder");
|
||||
UFUNC_LIST.add("mod");
|
||||
UFUNC_LIST.add("fmod");
|
||||
UFUNC_LIST.add("absolute");
|
||||
UFUNC_LIST.add("rint");
|
||||
UFUNC_LIST.add("sign");
|
||||
UFUNC_LIST.add("conj");
|
||||
UFUNC_LIST.add("exp");
|
||||
UFUNC_LIST.add("exp2");
|
||||
UFUNC_LIST.add("log");
|
||||
UFUNC_LIST.add("log2");
|
||||
UFUNC_LIST.add("log10");
|
||||
UFUNC_LIST.add("expm1");
|
||||
UFUNC_LIST.add("log1p");
|
||||
UFUNC_LIST.add("sqrt");
|
||||
UFUNC_LIST.add("square");
|
||||
UFUNC_LIST.add("reciprocal");
|
||||
UFUNC_LIST.add("ones_like");
|
||||
|
||||
//Trigonometric
|
||||
UFUNC_LIST.add("sin");
|
||||
UFUNC_LIST.add("cos");
|
||||
UFUNC_LIST.add("tan");
|
||||
UFUNC_LIST.add("arcsin");
|
||||
UFUNC_LIST.add("arccos");
|
||||
UFUNC_LIST.add("arctan");
|
||||
UFUNC_LIST.add("arctan2");
|
||||
UFUNC_LIST.add("hypot");
|
||||
UFUNC_LIST.add("sinh");
|
||||
UFUNC_LIST.add("cosh");
|
||||
UFUNC_LIST.add("tanh");
|
||||
UFUNC_LIST.add("arcsinh");
|
||||
UFUNC_LIST.add("arccosh");
|
||||
UFUNC_LIST.add("arctanh");
|
||||
UFUNC_LIST.add("deg2rad");
|
||||
UFUNC_LIST.add("rad2deg");
|
||||
|
||||
//Bit-twiddling functions
|
||||
UFUNC_LIST.add("bitwise_and");
|
||||
UFUNC_LIST.add("bitwise_or");
|
||||
UFUNC_LIST.add("bitwise_xor");
|
||||
UFUNC_LIST.add("invert");
|
||||
UFUNC_LIST.add("left_shift");
|
||||
UFUNC_LIST.add("right_shift");
|
||||
|
||||
//Comparison functions
|
||||
UFUNC_LIST.add("greater");
|
||||
UFUNC_LIST.add("greater_equal");
|
||||
UFUNC_LIST.add("less");
|
||||
UFUNC_LIST.add("less_equal");
|
||||
UFUNC_LIST.add("not_equal");
|
||||
UFUNC_LIST.add("equal");
|
||||
UFUNC_LIST.add("logical_and");
|
||||
UFUNC_LIST.add("logical_or");
|
||||
UFUNC_LIST.add("logical_xor");
|
||||
UFUNC_LIST.add("logical_not");
|
||||
UFUNC_LIST.add("maximum");
|
||||
UFUNC_LIST.add("minimum");
|
||||
UFUNC_LIST.add("fmax");
|
||||
UFUNC_LIST.add("fmin");
|
||||
|
||||
///Floating functions
|
||||
UFUNC_LIST.add("isreal");
|
||||
UFUNC_LIST.add("iscomplex");
|
||||
UFUNC_LIST.add("isfinite");
|
||||
UFUNC_LIST.add("isinf");
|
||||
UFUNC_LIST.add("isnan");
|
||||
UFUNC_LIST.add("signbit");
|
||||
UFUNC_LIST.add("copysign");
|
||||
UFUNC_LIST.add("nextafter");
|
||||
UFUNC_LIST.add("modf");
|
||||
UFUNC_LIST.add("ldexp");
|
||||
UFUNC_LIST.add("frexp");
|
||||
UFUNC_LIST.add("fmod");
|
||||
UFUNC_LIST.add("floor");
|
||||
UFUNC_LIST.add("ceil");
|
||||
UFUNC_LIST.add("trunc");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ public class NumPyDocString {
|
||||
private static final Pattern PARAMETER_WITHOUT_TYPE = Pattern.compile("^([^ :,]+)$");
|
||||
private static final Pattern REDIRECT = Pattern.compile("^Refer to `(.*)` for full documentation.$");
|
||||
private static final Pattern NUMPY_UNION_PATTERN = Pattern.compile("^\\{(.*)\\}$");
|
||||
private static final Pattern NUMPY_ARRAY_PATTERN = Pattern.compile("(\\(\\.\\.\\..*\\))(.*)");
|
||||
private static final Pattern QUOTED_STRING_PATTERN = Pattern.compile("^(?:\\\"(.*)\\\")|(?:\\'(.*)\\')$");
|
||||
|
||||
private final String mySignature;
|
||||
@@ -251,19 +252,21 @@ public class NumPyDocString {
|
||||
DocStringParameterBuilder builder = null;
|
||||
for (String line : lines) {
|
||||
if (!HAS_INDENT.matcher(line).find()) {
|
||||
if (builder != null) {
|
||||
parameters.add(builder.build());
|
||||
}
|
||||
builder = new DocStringParameterBuilder();
|
||||
Matcher parameterWithTypeMatcher = PARAMETER_WITH_TYPE.matcher(line);
|
||||
if (parameterWithTypeMatcher.matches()) {
|
||||
builder.setName(parameterWithTypeMatcher.group(1));
|
||||
builder.setType(parameterWithTypeMatcher.group(2));
|
||||
parameters.add(builder.build());
|
||||
} else {
|
||||
Matcher parameterWithoutTypeMatcher = PARAMETER_WITHOUT_TYPE.matcher(line);
|
||||
if (parameterWithoutTypeMatcher.matches()) {
|
||||
builder.setName(parameterWithoutTypeMatcher.group(1));
|
||||
builder.setType("object");
|
||||
parameters.add(builder.build());
|
||||
}
|
||||
else {
|
||||
builder.appendDescription(line.trim());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -272,9 +275,6 @@ public class NumPyDocString {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (builder != null) {
|
||||
parameters.add(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -283,15 +283,15 @@ public class NumPyDocString {
|
||||
if (index >= 0) {
|
||||
return typeString.substring(0, index);
|
||||
}
|
||||
index = typeString.indexOf(" of "); // e.g. ndarray of dtype float
|
||||
if (index >= 0) {
|
||||
return typeString.substring(0, index);
|
||||
}
|
||||
return typeString;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<String> getNumpyUnionType(@NotNull String typeString) {
|
||||
final Matcher arrayMatcher = NUMPY_ARRAY_PATTERN.matcher(typeString);
|
||||
if (arrayMatcher.matches()) {
|
||||
typeString = arrayMatcher.group(2);
|
||||
}
|
||||
Matcher matcher = NUMPY_UNION_PATTERN.matcher(typeString);
|
||||
if (matcher.matches()) {
|
||||
typeString = matcher.group(1);
|
||||
|
||||
@@ -93,20 +93,31 @@ public class PyTypeCheckerInspection extends PyInspection {
|
||||
boolean genericsCollected = false;
|
||||
for (Map.Entry<PyExpression, PyNamedParameter> entry : results.getArguments().entrySet()) {
|
||||
final PyNamedParameter p = entry.getValue();
|
||||
final PyExpression key = entry.getKey();
|
||||
if (p.isPositionalContainer() || p.isKeywordContainer()) {
|
||||
// TODO: Support *args, **kwargs
|
||||
continue;
|
||||
}
|
||||
if (p.hasDefaultValue()) {
|
||||
final PyExpression value = p.getDefaultValue();
|
||||
String keyName = key.getName();
|
||||
if (key instanceof PyKeywordArgument) {
|
||||
final PyExpression valueExpression = ((PyKeywordArgument)key).getValueExpression();
|
||||
keyName = valueExpression != null ? valueExpression.getName() : "";
|
||||
}
|
||||
if (value != null && keyName != null && keyName.equals(value.getName()))
|
||||
continue;
|
||||
}
|
||||
final PyType paramType = myTypeEvalContext.getType(p);
|
||||
if (paramType == null) {
|
||||
continue;
|
||||
}
|
||||
final PyType argType = myTypeEvalContext.getType(entry.getKey());
|
||||
final PyType argType = myTypeEvalContext.getType(key);
|
||||
if (!genericsCollected) {
|
||||
substitutions.putAll(PyTypeChecker.unifyReceiver(results.getReceiver(), myTypeEvalContext));
|
||||
genericsCollected = true;
|
||||
}
|
||||
checkTypes(paramType, argType, entry.getKey(), myTypeEvalContext, substitutions);
|
||||
checkTypes(paramType, argType, key, myTypeEvalContext, substitutions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
|
||||
def argsort(a, axis=-1, kind='quicksort', order=None):
|
||||
"""
|
||||
Returns the indices that would sort an array.
|
||||
|
||||
Perform an indirect sort along the given axis using the algorithm specified
|
||||
by the `kind` keyword. It returns an array of indices of the same shape as
|
||||
`a` that index data along the given axis in sorted order.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
a : array_like
|
||||
Array to sort.
|
||||
axis : int or None, optional
|
||||
Axis along which to sort. The default is -1 (the last axis). If None,
|
||||
the flattened array is used.
|
||||
kind : {'quicksort', 'mergesort', 'heapsort'}, optional
|
||||
Sorting algorithm.
|
||||
order : list, optional
|
||||
When `a` is an array with fields defined, this argument specifies
|
||||
which fields to compare first, second, etc. Not all fields need be
|
||||
specified.
|
||||
|
||||
Returns
|
||||
-------
|
||||
index_array : ndarray, int
|
||||
Array of indices that sort `a` along the specified axis.
|
||||
In other words, ``a[index_array]`` yields a sorted `a`.
|
||||
|
||||
See Also
|
||||
--------
|
||||
sort : Describes sorting algorithms used.
|
||||
lexsort : Indirect stable sort with multiple keys.
|
||||
ndarray.sort : Inplace sort.
|
||||
argpartition : Indirect partial sort.
|
||||
|
||||
Notes
|
||||
-----
|
||||
See `sort` for notes on the different sorting algorithms.
|
||||
|
||||
As of NumPy 1.4.0 `argsort` works with real/complex arrays containing
|
||||
nan values. The enhanced sort order is documented in `sort`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
One dimensional array:
|
||||
|
||||
>>> x = np.array([3, 1, 2])
|
||||
>>> np.argsort(x)
|
||||
array([1, 2, 0])
|
||||
|
||||
Two-dimensional array:
|
||||
|
||||
>>> x = np.array([[0, 3], [2, 2]])
|
||||
>>> x
|
||||
array([[0, 3],
|
||||
[2, 2]])
|
||||
|
||||
>>> np.argsort(x, axis=0)
|
||||
array([[0, 1],
|
||||
[1, 0]])
|
||||
|
||||
>>> np.argsort(x, axis=1)
|
||||
array([[0, 1],
|
||||
[0, 1]])
|
||||
|
||||
Sorting with keys:
|
||||
|
||||
>>> x = np.array([(1, 0), (0, 1)], dtype=[('x', '<i4'), ('y', '<i4')])
|
||||
>>> x
|
||||
array([(1, 0), (0, 1)],
|
||||
dtype=[('x', '<i4'), ('y', '<i4')])
|
||||
|
||||
>>> np.argsort(x, order=('x','y'))
|
||||
array([1, 0])
|
||||
|
||||
>>> np.argsort(x, order=('y','x'))
|
||||
array([0, 1])
|
||||
|
||||
"""
|
||||
try:
|
||||
argsort = a.argsort
|
||||
except AttributeError:
|
||||
return _wrapit(a, 'argsort', axis, kind, order)
|
||||
return argsort(axis, kind, order)
|
||||
|
||||
x = np.array([(1, 0), (0, 1)], dtype=[('x', '<i4'), ('y', '<i4')])
|
||||
argsort(x, order=('x', 'y'))
|
||||
@@ -0,0 +1,31 @@
|
||||
def lstrip(a, chars=None):
|
||||
"""
|
||||
For each element in `a`, return a copy with the leading characters
|
||||
removed.
|
||||
|
||||
Calls `str.lstrip` element-wise.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
a : array-like, {str, unicode}
|
||||
Input array.
|
||||
|
||||
chars : {str, unicode}, optional
|
||||
The `chars` argument is a string specifying the set of
|
||||
characters to be removed. If omitted or None, the `chars`
|
||||
argument defaults to removing whitespace. The `chars` argument
|
||||
is not a prefix; rather, all combinations of its values are
|
||||
stripped.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray, {str, unicode}
|
||||
Output array of str or unicode, depending on input type
|
||||
|
||||
|
||||
"""
|
||||
a_arr = numpy.asarray(a)
|
||||
return _vec_string(a_arr, a_arr.dtype, 'lstrip', (chars,))
|
||||
|
||||
c = np.array(['aAaAaA', ' aA ', 'abBABba'])
|
||||
lstrip(c, None)
|
||||
@@ -0,0 +1,59 @@
|
||||
def set_printoptions(precision=None, threshold=None, edgeitems=None,
|
||||
linewidth=None, suppress=None,
|
||||
nanstr=None, infstr=None,
|
||||
formatter=None):
|
||||
"""
|
||||
Set printing options.
|
||||
|
||||
These options determine the way floating point numbers, arrays and
|
||||
other NumPy objects are displayed.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
precision : int, optional
|
||||
Number of digits of precision for floating point output (default 8).
|
||||
threshold : int, optional
|
||||
Total number of array elements which trigger summarization
|
||||
rather than full repr (default 1000).
|
||||
edgeitems : int, optional
|
||||
Number of array items in summary at beginning and end of
|
||||
each dimension (default 3).
|
||||
linewidth : int, optional
|
||||
The number of characters per line for the purpose of inserting
|
||||
line breaks (default 75).
|
||||
suppress : bool, optional
|
||||
Whether or not suppress printing of small floating point values
|
||||
using scientific notation (default False).
|
||||
nanstr : str, optional
|
||||
String representation of floating point not-a-number (default nan).
|
||||
infstr : str, optional
|
||||
String representation of floating point infinity (default inf).
|
||||
formatter : dict of callables, optional
|
||||
If not None, the keys should indicate the type(s) that the respective
|
||||
formatting function applies to. Callables should return a string.
|
||||
Types that are not specified (by their corresponding keys) are handled
|
||||
by the default formatters. Individual types for which a formatter
|
||||
can be set are::
|
||||
|
||||
- 'bool'
|
||||
- 'int'
|
||||
- 'timedelta' : a `numpy.timedelta64`
|
||||
- 'datetime' : a `numpy.datetime64`
|
||||
- 'float'
|
||||
- 'longfloat' : 128-bit floats
|
||||
- 'complexfloat'
|
||||
- 'longcomplexfloat' : composed of two 128-bit floats
|
||||
- 'numpy_str' : types `numpy.string_` and `numpy.unicode_`
|
||||
- 'str' : all other strings
|
||||
|
||||
Other keys that can be used to set a group of types at once are::
|
||||
|
||||
- 'all' : sets all types
|
||||
- 'int_kind' : sets 'int'
|
||||
- 'float_kind' : sets 'float' and 'longfloat'
|
||||
- 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat'
|
||||
- 'str_kind' : sets 'str' and 'numpystr'
|
||||
"""
|
||||
pass
|
||||
|
||||
set_printoptions(formatter=None)
|
||||
@@ -0,0 +1,46 @@
|
||||
def empty(shape, dtype=None, order='C'): # real signature unknown; restored from __doc__
|
||||
"""
|
||||
empty(shape, dtype=float, order='C')
|
||||
|
||||
Return a new array of given shape and type, without initializing entries.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
shape : int or tuple of int
|
||||
Shape of the empty array
|
||||
dtype : data-type, optional
|
||||
Desired output data-type.
|
||||
order : {'C', 'F'}, optional
|
||||
Whether to store multi-dimensional data in C (row-major) or
|
||||
Fortran (column-major) order in memory.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
Array of uninitialized (arbitrary) data with the given
|
||||
shape, dtype, and order.
|
||||
|
||||
See Also
|
||||
--------
|
||||
empty_like, zeros, ones
|
||||
|
||||
Notes
|
||||
-----
|
||||
`empty`, unlike `zeros`, does not set the array values to zero,
|
||||
and may therefore be marginally faster. On the other hand, it requires
|
||||
the user to manually set all the values in the array, and should be
|
||||
used with caution.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> np.empty([2, 2])
|
||||
array([[ -9.74499359e+001, 6.69583040e-309],
|
||||
[ 2.13182611e-314, 3.06959433e-309]]) #random
|
||||
|
||||
>>> np.empty([2, 2], dtype=int)
|
||||
array([[-1073741821, -1067949133],
|
||||
[ 496041986, 19249760]]) #random
|
||||
"""
|
||||
pass
|
||||
|
||||
empty([2, 2])
|
||||
@@ -0,0 +1,43 @@
|
||||
def unique(ar, return_index=False, return_inverse=False, return_counts=False):
|
||||
"""
|
||||
Find the unique elements of an array.
|
||||
|
||||
Returns the sorted unique elements of an array. There are two optional
|
||||
outputs in addition to the unique elements: the indices of the input array
|
||||
that give the unique values, and the indices of the unique array that
|
||||
reconstruct the input array.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ar : array_like
|
||||
Input array. This will be flattened if it is not already 1-D.
|
||||
return_index : bool, optional
|
||||
If True, also return the indices of `ar` that result in the unique
|
||||
array.
|
||||
return_inverse : bool, optional
|
||||
If True, also return the indices of the unique array that can be used
|
||||
to reconstruct `ar`.
|
||||
return_counts : bool, optional
|
||||
.. versionadded:: 1.9.0
|
||||
If True, also return the number of times each unique value comes up
|
||||
in `ar`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
unique : ndarray
|
||||
The sorted unique values.
|
||||
unique_indices : ndarray, optional
|
||||
The indices of the first occurrences of the unique values in the
|
||||
(flattened) original array. Only provided if `return_index` is True.
|
||||
unique_inverse : ndarray, optional
|
||||
The indices to reconstruct the (flattened) original array from the
|
||||
unique array. Only provided if `return_inverse` is True.
|
||||
unique_counts : ndarray, optional
|
||||
.. versionadded:: 1.9.0
|
||||
The number of times each of the unique values comes up in the
|
||||
original array. Only provided if `return_counts` is True.
|
||||
|
||||
"""
|
||||
ar = np.asanyarray(ar).flatten()
|
||||
|
||||
u, indices = unique(a, return_index=True)
|
||||
@@ -0,0 +1,44 @@
|
||||
def unique(ar, return_index=False, return_inverse=False, return_counts=False):
|
||||
"""
|
||||
Find the unique elements of an array.
|
||||
|
||||
Returns the sorted unique elements of an array. There are two optional
|
||||
outputs in addition to the unique elements: the indices of the input array
|
||||
that give the unique values, and the indices of the unique array that
|
||||
reconstruct the input array.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ar : array_like
|
||||
Input array. This will be flattened if it is not already 1-D.
|
||||
return_index : bool, optional
|
||||
If True, also return the indices of `ar` that result in the unique
|
||||
array.
|
||||
return_inverse : bool, optional
|
||||
If True, also return the indices of the unique array that can be used
|
||||
to reconstruct `ar`.
|
||||
return_counts : bool, optional
|
||||
.. versionadded:: 1.9.0
|
||||
If True, also return the number of times each unique value comes up
|
||||
in `ar`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
unique : ndarray
|
||||
The sorted unique values.
|
||||
unique_indices : ndarray
|
||||
The indices of the first occurrences of the unique values in the
|
||||
(flattened) original array. Only provided if `return_index` is True.
|
||||
unique_inverse : ndarray
|
||||
The indices to reconstruct the (flattened) original array from the
|
||||
unique array. Only provided if `return_inverse` is True.
|
||||
unique_counts : ndarray
|
||||
.. versionadded:: 1.9.0
|
||||
The number of times each of the unique values comes up in the
|
||||
original array. Only provided if `return_counts` is True.
|
||||
|
||||
"""
|
||||
ar = np.asanyarray(ar).flatten()
|
||||
|
||||
a=1
|
||||
u, indices = <warning descr="Too many values to unpack">unique(a, return_index=True)</warning>
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
def slogdet(a):
|
||||
"""
|
||||
Compute the sign and (natural) logarithm of the determinant of an array.
|
||||
|
||||
If an array has a very small or very large determinant, than a call to
|
||||
`det` may overflow or underflow. This routine is more robust against such
|
||||
issues, because it computes the logarithm of the determinant rather than
|
||||
the determinant itself.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
a : (..., M, M) array_like
|
||||
Input array, has to be a square 2-D array.
|
||||
|
||||
Returns
|
||||
-------
|
||||
sign : (...) array_like
|
||||
A number representing the sign of the determinant. For a real matrix,
|
||||
this is 1, 0, or -1. For a complex matrix, this is a complex number
|
||||
with absolute value 1 (i.e., it is on the unit circle), or else 0.
|
||||
logdet : (...) array_like
|
||||
The natural log of the absolute value of the determinant.
|
||||
|
||||
If the determinant is zero, then `sign` will be 0 and `logdet` will be
|
||||
-Inf. In all cases, the determinant is equal to ``sign * np.exp(logdet)``.
|
||||
"""
|
||||
pass
|
||||
|
||||
(sign, logdet) = slogdet(a)
|
||||
@@ -0,0 +1,23 @@
|
||||
def sort(self, axis=-1, kind='quicksort', order=None): # real signature unknown; restored from __doc__
|
||||
"""
|
||||
a.sort(axis=-1, kind='quicksort', order=None)
|
||||
|
||||
Sort an array, in-place.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
axis : int, optional
|
||||
Axis along which to sort. Default is -1, which means sort along the
|
||||
last axis.
|
||||
kind : {'quicksort', 'mergesort', 'heapsort'}, optional
|
||||
Sorting algorithm. Default is 'quicksort'.
|
||||
order : list, optional
|
||||
When `a` is an array with fields defined, this argument specifies
|
||||
which fields to compare first, second, etc. Not all fields need be
|
||||
specified.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
a = np.array([('a', 2), ('c', 1)], dtype=[('x', 'S1'), ('y', int)])
|
||||
print(sort(a, order='y'))
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
def transpose(a, axes=None):
|
||||
"""
|
||||
Permute the dimensions of an array.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
a : array_like
|
||||
Input array.
|
||||
axes : list of ints, optional
|
||||
By default, reverse the dimensions, otherwise permute the axes
|
||||
according to the values given.
|
||||
|
||||
Returns
|
||||
-------
|
||||
p : ndarray
|
||||
`a` with its axes permuted. A view is returned whenever
|
||||
possible.
|
||||
|
||||
See Also
|
||||
--------
|
||||
rollaxis
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> x = np.arange(4).reshape((2,2))
|
||||
>>> x
|
||||
array([[0, 1],
|
||||
[2, 3]])
|
||||
|
||||
>>> np.transpose(x)
|
||||
array([[0, 2],
|
||||
[1, 3]])
|
||||
|
||||
>>> x = np.ones((1, 2, 3))
|
||||
>>> np.transpose(x, (1, 0, 2)).shape
|
||||
(2, 1, 3)
|
||||
|
||||
"""
|
||||
try:
|
||||
transpose = a.transpose
|
||||
except AttributeError:
|
||||
return _wrapit(a, 'transpose', axes)
|
||||
return transpose(axes)
|
||||
|
||||
x = np.ones((1, 2, 3))
|
||||
a = transpose(x, (1, 0, 2)).shape
|
||||
@@ -0,0 +1,31 @@
|
||||
def sqrt(x, out=None): # real signature unknown; restored from __doc__
|
||||
"""
|
||||
sqrt(x[, out])
|
||||
|
||||
Return the positive square-root of an array, element-wise.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : array_like
|
||||
The values whose square-roots are required.
|
||||
out : ndarray, optional
|
||||
Alternate array object in which to put the result; if provided, it
|
||||
must have the same shape as `x`
|
||||
|
||||
Returns
|
||||
-------
|
||||
y : ndarray
|
||||
An array of the same shape as `x`, containing the positive
|
||||
square-root of each element in `x`. If any element in `x` is
|
||||
complex, a complex array is returned (and the square-roots of
|
||||
negative reals are calculated). If all of the elements in `x`
|
||||
are real, so is `y`, with negative elements returning ``nan``.
|
||||
If `out` was provided, `y` is a reference to it.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
meanvalue = 1
|
||||
modevalue = sqrt(2 / np.pi) * meanvalue
|
||||
s = np.random.rayleigh(modevalue, 1000000)
|
||||
@@ -0,0 +1,122 @@
|
||||
|
||||
class vectorize(object):
|
||||
"""
|
||||
vectorize(pyfunc, otypes='', doc=None, excluded=None, cache=False)
|
||||
|
||||
Generalized function class.
|
||||
|
||||
Define a vectorized function which takes a nested sequence
|
||||
of objects or numpy arrays as inputs and returns a
|
||||
numpy array as output. The vectorized function evaluates `pyfunc` over
|
||||
successive tuples of the input arrays like the python map function,
|
||||
except it uses the broadcasting rules of numpy.
|
||||
|
||||
The data type of the output of `vectorized` is determined by calling
|
||||
the function with the first element of the input. This can be avoided
|
||||
by specifying the `otypes` argument.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
pyfunc : callable
|
||||
A python function or method.
|
||||
otypes : str or list of dtypes, optional
|
||||
The output data type. It must be specified as either a string of
|
||||
typecode characters or a list of data type specifiers. There should
|
||||
be one data type specifier for each output.
|
||||
doc : str, optional
|
||||
The docstring for the function. If `None`, the docstring will be the
|
||||
``pyfunc.__doc__``.
|
||||
excluded : set, optional
|
||||
Set of strings or integers representing the positional or keyword
|
||||
arguments for which the function will not be vectorized. These will be
|
||||
passed directly to `pyfunc` unmodified.
|
||||
|
||||
.. versionadded:: 1.7.0
|
||||
|
||||
cache : bool, optional
|
||||
If `True`, then cache the first function call that determines the number
|
||||
of outputs if `otypes` is not provided.
|
||||
|
||||
.. versionadded:: 1.7.0
|
||||
|
||||
Returns
|
||||
-------
|
||||
vectorized : callable
|
||||
Vectorized function.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> def myfunc(a, b):
|
||||
... "Return a-b if a>b, otherwise return a+b"
|
||||
... if a > b:
|
||||
... return a - b
|
||||
... else:
|
||||
... return a + b
|
||||
|
||||
>>> vfunc = np.vectorize(myfunc)
|
||||
>>> vfunc([1, 2, 3, 4], 2)
|
||||
array([3, 4, 1, 2])
|
||||
|
||||
The docstring is taken from the input function to `vectorize` unless it
|
||||
is specified
|
||||
|
||||
>>> vfunc.__doc__
|
||||
'Return a-b if a>b, otherwise return a+b'
|
||||
>>> vfunc = np.vectorize(myfunc, doc='Vectorized `myfunc`')
|
||||
>>> vfunc.__doc__
|
||||
'Vectorized `myfunc`'
|
||||
|
||||
The output type is determined by evaluating the first element of the input,
|
||||
unless it is specified
|
||||
|
||||
>>> out = vfunc([1, 2, 3, 4], 2)
|
||||
>>> type(out[0])
|
||||
<type 'numpy.int32'>
|
||||
>>> vfunc = np.vectorize(myfunc, otypes=[np.float])
|
||||
>>> out = vfunc([1, 2, 3, 4], 2)
|
||||
>>> type(out[0])
|
||||
<type 'numpy.float64'>
|
||||
|
||||
The `excluded` argument can be used to prevent vectorizing over certain
|
||||
arguments. This can be useful for array-like arguments of a fixed length
|
||||
such as the coefficients for a polynomial as in `polyval`:
|
||||
|
||||
>>> def mypolyval(p, x):
|
||||
... _p = list(p)
|
||||
... res = _p.pop(0)
|
||||
... while _p:
|
||||
... res = res*x + _p.pop(0)
|
||||
... return res
|
||||
>>> vpolyval = np.vectorize(mypolyval, excluded=['p'])
|
||||
>>> vpolyval(p=[1, 2, 3], x=[0, 1])
|
||||
array([3, 6])
|
||||
|
||||
Positional arguments may also be excluded by specifying their position:
|
||||
|
||||
>>> vpolyval.excluded.add(0)
|
||||
>>> vpolyval([1, 2, 3], x=[0, 1])
|
||||
array([3, 6])
|
||||
|
||||
Notes
|
||||
-----
|
||||
The `vectorize` function is provided primarily for convenience, not for
|
||||
performance. The implementation is essentially a for loop.
|
||||
|
||||
If `otypes` is not specified, then a call to the function with the
|
||||
first argument will be used to determine the number of outputs. The
|
||||
results of this call will be cached if `cache` is `True` to prevent
|
||||
calling the function twice. However, to implement the cache, the
|
||||
original function must be wrapped which will slow down subsequent
|
||||
calls, so only do this if your function is expensive.
|
||||
|
||||
The new keyword argument interface and `excluded` argument support
|
||||
further degrades performance.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, pyfunc, otypes='', doc=None, excluded=None,
|
||||
cache=False):
|
||||
pass
|
||||
|
||||
def mypolyval(): pass
|
||||
vpolyval = vectorize(mypolyval, excluded=['p'])
|
||||
@@ -86,7 +86,12 @@ public abstract class PyTestCase extends UsefulTestCase {
|
||||
|
||||
@Nullable
|
||||
protected static VirtualFile getVirtualFileByName(String fileName) {
|
||||
return LocalFileSystem.getInstance().refreshAndFindFileByPath(fileName.replace(File.separatorChar, '/'));
|
||||
final VirtualFile path = LocalFileSystem.getInstance().findFileByPath(fileName.replace(File.separatorChar, '/'));
|
||||
if (path != null) {
|
||||
refreshRecursively(path);
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,4 +33,54 @@ public class PyNumpyTypeTest extends PyTestCase {
|
||||
public void testDtype() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testEmpty() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testTranspose() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testArgSort() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testVectorize() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDefaultValue() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDefaultValueKeyword() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSort() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testUFunc() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testReturnOptional() {
|
||||
myFixture.configureByFile(TEST_DIRECTORY + getTestName(false) + ".py");
|
||||
myFixture.enableInspections(PyTupleAssignmentBalanceInspection.class);
|
||||
myFixture.checkHighlighting(true, false, true);
|
||||
}
|
||||
|
||||
public void testReturnTuple() {
|
||||
myFixture.configureByFile(TEST_DIRECTORY + getTestName(false) + ".py");
|
||||
myFixture.enableInspections(PyTupleAssignmentBalanceInspection.class);
|
||||
myFixture.checkHighlighting(true, false, true);
|
||||
}
|
||||
|
||||
public void testSlogdet() {
|
||||
myFixture.configureByFile(TEST_DIRECTORY + getTestName(false) + ".py");
|
||||
myFixture.enableInspections(PyTupleAssignmentBalanceInspection.class);
|
||||
myFixture.checkHighlighting(true, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user