diff --git a/.idea/libraries/asm5.xml b/.idea/libraries/ASM.xml
similarity index 68%
rename from .idea/libraries/asm5.xml
rename to .idea/libraries/ASM.xml
index e4873676bb75..7ed029a31507 100644
--- a/.idea/libraries/asm5.xml
+++ b/.idea/libraries/ASM.xml
@@ -1,11 +1,11 @@
-
+
-
+
\ No newline at end of file
diff --git a/build/asm/1_version_check.patch b/build/asm/1_version_check.patch
index 63ec6e0278f8..45eb8373f4c7 100644
--- a/build/asm/1_version_check.patch
+++ b/build/asm/1_version_check.patch
@@ -5,7 +5,7 @@ Index: org/objectweb/asm/ClassReader.java
@@ -167,7 +167,7 @@
this.b = b;
// checks the class version
- if (readShort(off + 6) > Opcodes.V1_8) {
+ if (readShort(off + 6) > Opcodes.V1_9) {
- throw new IllegalArgumentException();
+ //[JB: accept any version] throw new IllegalArgumentException();
}
diff --git a/build/asm/repackage.xml b/build/asm/repackage.xml
index 75336cfbe16b..6d72c6d4c53a 100644
--- a/build/asm/repackage.xml
+++ b/build/asm/repackage.xml
@@ -19,7 +19,7 @@
-
+
@@ -41,6 +41,7 @@
+
diff --git a/build/build.iml b/build/build.iml
index 9eb5b9dfb1fb..71b5f94898ed 100644
--- a/build/build.iml
+++ b/build/build.iml
@@ -13,7 +13,7 @@
-
+
diff --git a/build/scripts/libLicenses.gant b/build/scripts/libLicenses.gant
index 88f3bf933756..a673f8f7cd9d 100644
--- a/build/scripts/libLicenses.gant
+++ b/build/scripts/libLicenses.gant
@@ -171,11 +171,7 @@ libraryLicense(name: "Apache Commons Net", libraryName: "commons-net", version:
libraryLicense(name: "Apache Lucene", libraryName: "lucene-core-2.4.1.jar", version: "2.4.1", license: "Apache 2.0", url: "http://lucene.apache.org/java")
libraryLicense(name: "Apache Sanselan", libraryName: "Sanselan", version: "0.98", license: "Apache 2.0", url: "https://commons.apache.org/proper/commons-imaging/")
libraryLicense(name: "Apache XML Graphics Commons", libraryName: "xmlgraphics-commons-1.3.1.jar", version: "1.3.1", license: "Apache 2.0", url: "http://xmlgraphics.apache.org/commons/", licenseUrl:"http://www.apache.org/licenses/LICENSE-2.0")
-libraryLicense(name: "asm-4.0-all", libraryName: "asm-4.0-all", version: "4.0", attachedTo: "ByteCodeViewer", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
-libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm-tools", version: "4.0", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
-libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm", version: "3.3", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
-libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm4", version: "4.0", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
-libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "asm5", version: "5.0.3 (with patches by JetBrains)", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
+libraryLicense(name: "ASM Bytecode Manipulation Framework", libraryName: "ASM", version: "6.0-ALPHA (with patches by JetBrains)", license: "BSD", url: "http://asm.objectweb.org/", licenseUrl: "http://asm.objectweb.org/license.html")
libraryLicense(name: "assertJ", version: "3", license: "Apache 2.0", url: "https://github.com/joel-costigliola/assertj-core")
libraryLicense(name: "Automaton", libraryName: "automaton.jar", version: "1.11", license: "BSD", url: "http://www.brics.dk/automaton/", licenseUrl: "http://www.opensource.org/licenses/bsd-license.php")
libraryLicense(name: "Axis", libraryName: "axis-1.4", version: "1.4", license: "Apache 2.0", url: "http://ws.apache.org/axis/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.html")
diff --git a/java/compiler/forms-compiler/forms-compiler.iml b/java/compiler/forms-compiler/forms-compiler.iml
index 111123aaf886..9eec06a77713 100644
--- a/java/compiler/forms-compiler/forms-compiler.iml
+++ b/java/compiler/forms-compiler/forms-compiler.iml
@@ -10,7 +10,7 @@
-
+
diff --git a/java/compiler/impl/compiler-impl.iml b/java/compiler/impl/compiler-impl.iml
index 481598a0c7ae..73e40393577b 100644
--- a/java/compiler/impl/compiler-impl.iml
+++ b/java/compiler/impl/compiler-impl.iml
@@ -16,7 +16,7 @@
-
+
diff --git a/java/compiler/instrumentation-util/instrumentation-util.iml b/java/compiler/instrumentation-util/instrumentation-util.iml
index 293410b8d23a..eb96516e2f04 100644
--- a/java/compiler/instrumentation-util/instrumentation-util.iml
+++ b/java/compiler/instrumentation-util/instrumentation-util.iml
@@ -7,7 +7,6 @@
-
+
-
-
+
\ No newline at end of file
diff --git a/java/compiler/javac2/javac2.iml b/java/compiler/javac2/javac2.iml
index 986d88e635fd..5376b3eff57f 100644
--- a/java/compiler/javac2/javac2.iml
+++ b/java/compiler/javac2/javac2.iml
@@ -10,7 +10,7 @@
-
+
@@ -165,5 +165,4 @@
-
-
+
\ No newline at end of file
diff --git a/java/java-analysis-impl/java-analysis-impl.iml b/java/java-analysis-impl/java-analysis-impl.iml
index 95c129baadfb..8fd2b1787902 100644
--- a/java/java-analysis-impl/java-analysis-impl.iml
+++ b/java/java-analysis-impl/java-analysis-impl.iml
@@ -17,7 +17,6 @@
-
+
-
-
+
\ No newline at end of file
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java
index 078e2fdff13d..d59741e42020 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/ModuleHighlightUtil.java
@@ -29,7 +29,6 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaModule;
-import com.intellij.psi.PsiJavaModuleReference;
import com.intellij.psi.search.FilenameIndex;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,15 +36,15 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
-public class ModuleHighlightUtil {
- private static final String MODULE_FILE_NAME = "module-info.java";
+import static com.intellij.psi.PsiJavaModule.MODULE_INFO_FILE;
+public class ModuleHighlightUtil {
@Nullable
static HighlightInfo checkFileName(@NotNull PsiJavaModule element, @NotNull PsiFile file) {
- if (!MODULE_FILE_NAME.equals(file.getName())) {
+ if (!MODULE_INFO_FILE.equals(file.getName())) {
String message = JavaErrorMessages.message("module.file.wrong.name");
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).description(message).create();
- QuickFixAction.registerQuickFixAction(info, factory().createRenameFileFix(MODULE_FILE_NAME));
+ QuickFixAction.registerQuickFixAction(info, factory().createRenameFileFix(MODULE_INFO_FILE));
return info;
}
@@ -60,7 +59,7 @@ public class ModuleHighlightUtil {
Module module = ProjectFileIndex.SERVICE.getInstance(project).getModuleForFile(vFile);
if (module != null) {
Collection others =
- FilenameIndex.getVirtualFilesByName(project, MODULE_FILE_NAME, new ModulesScope(Collections.singleton(module), project));
+ FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, new ModulesScope(Collections.singleton(module), project));
if (others.size() > 1) {
String message = JavaErrorMessages.message("module.file.duplicate");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(range(element)).description(message).create();
@@ -93,7 +92,6 @@ public class ModuleHighlightUtil {
}
private static TextRange range(PsiJavaModule module) {
- PsiJavaModuleReference name = module.getNameElement();
- return name != null ? new TextRange(module.getTextOffset(), name.getTextRange().getEndOffset()) : module.getTextRange();
+ return new TextRange(module.getTextOffset(), module.getNameElement().getTextRange().getEndOffset());
}
}
\ No newline at end of file
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
index 9300b954c488..624659f1c90a 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
@@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
-class JCiPUtil {
+public class JCiPUtil {
static boolean isJCiPAnnotation(String ref) {
return "Immutable".equals(ref) || "GuardedBy".equals(ref) || "ThreadSafe".equals(ref) || "NotThreadSafe".equals(ref);
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
index d3bcce5c3671..e1aefce0e557 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -59,7 +59,7 @@ public class NonFinalFieldInImmutableInspection extends BaseJavaBatchLocalInspec
if (!JCiPUtil.isImmutable(containingClass)) {
return;
}
- holder.registerProblem(field, "Non-final field #ref in @Immutable class #loc");
+ holder.registerProblem(field.getNameIdentifier(), "Non-final field #ref in @Immutable class #loc");
}
}
};
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java
index 36c8ea3485f6..198e462b1e77 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java
@@ -92,7 +92,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
List deadCodeAddIns = new ArrayList(extensions.length);
for (EntryPoint entryPoint : extensions) {
try {
- deadCodeAddIns.add(entryPoint);
+ deadCodeAddIns.add(entryPoint.clone());
}
catch (Exception e) {
LOG.error(e);
diff --git a/java/java-impl/java-impl.iml b/java/java-impl/java-impl.iml
index 1be708c7149c..1f9fd8301eef 100644
--- a/java/java-impl/java-impl.iml
+++ b/java/java-impl/java-impl.iml
@@ -42,7 +42,7 @@
-
+
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java
index 974e9af8e9cb..3656ce32aba5 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaModule.java
@@ -15,7 +15,7 @@
*/
package com.intellij.psi;
-import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
/**
* Represents a Java module declaration.
@@ -23,6 +23,9 @@ import org.jetbrains.annotations.Nullable;
* @since 2016.3
*/
public interface PsiJavaModule extends PsiElement {
- @Nullable PsiJavaModuleReference getNameElement();
- @Nullable String getModuleName();
+ String MODULE_INFO_CLASS = "module-info";
+ String MODULE_INFO_FILE = MODULE_INFO_CLASS + ".java";
+
+ @NotNull PsiJavaModuleReference getNameElement();
+ @NotNull String getModuleName();
}
\ No newline at end of file
diff --git a/java/java-psi-impl/java-psi-impl.iml b/java/java-psi-impl/java-psi-impl.iml
index 40064b497c8b..3efdb8fa9616 100644
--- a/java/java-psi-impl/java-psi-impl.iml
+++ b/java/java-psi-impl/java-psi-impl.iml
@@ -11,7 +11,7 @@
-
+
\ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java
index 4905a52c18c4..fccb8b1202ad 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleImpl.java
@@ -15,29 +15,30 @@
*/
package com.intellij.psi.impl.source;
-import com.intellij.psi.*;
+import com.intellij.psi.JavaElementVisitor;
+import com.intellij.psi.PsiElementVisitor;
+import com.intellij.psi.PsiJavaModule;
+import com.intellij.psi.PsiJavaModuleReference;
import com.intellij.psi.impl.source.tree.CompositePsiElement;
import com.intellij.psi.impl.source.tree.JavaElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
public class PsiJavaModuleImpl extends CompositePsiElement implements PsiJavaModule {
public PsiJavaModuleImpl() {
super(JavaElementType.MODULE);
}
- @Nullable
+ @NotNull
@Override
public PsiJavaModuleReference getNameElement() {
- return PsiTreeUtil.getChildOfType(this, PsiJavaModuleReference.class);
+ return PsiTreeUtil.getRequiredChildOfType(this, PsiJavaModuleReference.class);
}
- @Nullable
+ @NotNull
@Override
public String getModuleName() {
- PsiJavaModuleReference nameElement = getNameElement();
- return nameElement != null ? nameElement.getReferenceText() : null;
+ return getNameElement().getReferenceText();
}
@Override
diff --git a/java/java-tests/java-tests.iml b/java/java-tests/java-tests.iml
index b0496244a14f..1008e1276345 100644
--- a/java/java-tests/java-tests.iml
+++ b/java/java-tests/java-tests.iml
@@ -25,7 +25,7 @@
-
+
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsStubBuilderTest.java
similarity index 98%
rename from java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java
rename to java/java-tests/testSrc/com/intellij/psi/ClsStubBuilderTest.java
index 471f5e0ed630..d1d2f08d4559 100644
--- a/java/java-tests/testSrc/com/intellij/psi/ClsBuilderTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/ClsStubBuilderTest.java
@@ -31,7 +31,7 @@ import java.io.File;
/**
* @author max
*/
-public class ClsBuilderTest extends LightIdeaTestCase {
+public class ClsStubBuilderTest extends LightIdeaTestCase {
public void testUtilList() { doTest("java/util/List.class"); }
public void testNullable() { doTest("org/jetbrains/annotations/Nullable.class"); }
public void testUtilCollections() { doTest("java/util/Collections.class"); }
diff --git a/java/typeMigration/src/META-INF/TypeMigration.xml b/java/typeMigration/src/META-INF/TypeMigration.xml
index c27c63eb1afc..46042d875b03 100644
--- a/java/typeMigration/src/META-INF/TypeMigration.xml
+++ b/java/typeMigration/src/META-INF/TypeMigration.xml
@@ -8,6 +8,7 @@
+
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/VoidConversionRule.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/VoidConversionRule.java
new file mode 100644
index 000000000000..27fe8801bec4
--- /dev/null
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/VoidConversionRule.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2016 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.refactoring.typeMigration.rules;
+
+import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer;
+import com.intellij.psi.*;
+import com.intellij.psi.search.PsiElementProcessor;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
+import com.intellij.refactoring.typeMigration.TypeEvaluator;
+import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
+import com.intellij.util.IncorrectOperationException;
+import com.siyeh.ig.controlflow.UnnecessaryReturnInspection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class VoidConversionRule extends TypeConversionRule {
+ @Nullable
+ @Override
+ public TypeConversionDescriptorBase findConversion(PsiType from,
+ PsiType to,
+ PsiMember member,
+ PsiExpression context,
+ TypeMigrationLabeler labeler) {
+ if (PsiType.VOID.equals(to) && context.getParent() instanceof PsiReturnStatement) {
+ final boolean isPure = PsiTreeUtil.processElements(context, new PsiElementProcessor() {
+ @Override
+ public boolean execute(@NotNull PsiElement element) {
+ if (element instanceof PsiPrefixExpression) {
+ return analyzeUnaryExpressionOperand(((PsiPrefixExpression)element).getOperand());
+ }
+ if (element instanceof PsiPostfixExpression) {
+ return analyzeUnaryExpressionOperand(((PsiPostfixExpression)element).getOperand());
+ }
+ if (element instanceof PsiMethodCallExpression) {
+ final PsiMethod method = ((PsiMethodCallExpression)element).resolveMethod();
+ return method != null && ControlFlowAnalyzer.isPure(method);
+ }
+ return true;
+ }
+
+ private boolean analyzeUnaryExpressionOperand(PsiExpression operand) {
+ if (!(operand instanceof PsiReferenceExpression)) return false;
+ final PsiElement resolved = ((PsiReferenceExpression)operand).resolve();
+ return !(resolved instanceof PsiField);
+ }
+ });
+ if (isPure) {
+ return new TypeConversionDescriptorBase() {
+ @Override
+ public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException {
+ final PsiElement parent = expression.getParent();
+ if (parent instanceof PsiReturnStatement) {
+ expression.delete();
+ if (UnnecessaryReturnInspection.isReturnRedundant((PsiReturnStatement)parent, false, null)) {
+ parent.delete();
+ }
+ }
+ return null;
+ }
+ };
+ } else {
+ return null;
+ }
+ }
+ return null;
+ }
+}
diff --git a/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java b/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java
index 2d999892902a..e91b68c1ff1d 100644
--- a/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java
+++ b/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java
@@ -826,6 +826,10 @@ public class TypeMigrationTest extends TypeMigrationTestBase {
doTestFieldType("fooDontMigrateName", PsiType.BOOLEAN);
}
+ public void testMethodMigrationToVoidWithUnusedReturns() {
+ doTestMethodType("toVoidMethod", PsiType.VOID);
+ }
+
public void testMigrationToSuper() {
doTestFieldType("b", myJavaFacade.getElementFactory().createTypeFromText("Test.A", null));
}
diff --git a/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/after/Test.items b/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/after/Test.items
new file mode 100644
index 000000000000..af6da3191a83
--- /dev/null
+++ b/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/after/Test.items
@@ -0,0 +1,9 @@
+Types:
+PsiMethod:toVoidMethod : void
+PsiMethodCallExpression:toVoidMethod() : void
+
+Conversions:
+
+New expression type changes:
+Fails:
+"" + String.valueOf(999)->void
diff --git a/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/after/test.java b/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/after/test.java
new file mode 100644
index 000000000000..9a41034f67a0
--- /dev/null
+++ b/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/after/test.java
@@ -0,0 +1,11 @@
+class Test {
+
+ public void toVoidMethod() {
+ int j = 0;
+ return "" + String.valueOf(999);
+ }
+
+ public void main(String[] args) {
+ toVoidMethod();
+ }
+}
diff --git a/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/before/test.java b/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/before/test.java
new file mode 100644
index 000000000000..dc030e222267
--- /dev/null
+++ b/java/typeMigration/testData/refactoring/typeMigration/methodMigrationToVoidWithUnusedReturns/before/test.java
@@ -0,0 +1,11 @@
+class Test {
+
+ public String toVoidMethod() {
+ int j = 0;
+ return "" + String.valueOf(999);
+ }
+
+ public void main(String[] args) {
+ toVoidMethod();
+ }
+}
diff --git a/jps/jps-builders/jps-builders.iml b/jps/jps-builders/jps-builders.iml
index be7df797f0bb..f876b2a7e3cc 100644
--- a/jps/jps-builders/jps-builders.iml
+++ b/jps/jps-builders/jps-builders.iml
@@ -12,7 +12,7 @@
-
+
diff --git a/lib/asm-all.jar b/lib/asm-all.jar
index b2f2849bae45..12f25c2c4220 100644
Binary files a/lib/asm-all.jar and b/lib/asm-all.jar differ
diff --git a/lib/src/asm5-src.zip b/lib/src/asm-src.zip
similarity index 57%
rename from lib/src/asm5-src.zip
rename to lib/src/asm-src.zip
index ad405c1ca3e2..26dd8efc7fef 100644
Binary files a/lib/src/asm5-src.zip and b/lib/src/asm-src.zip differ
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java
index 6c3216b019d8..4d5357597bee 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java
@@ -722,7 +722,6 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren
final HighlightDisplayKey key = HighlightDisplayKey.find(defaultToolWrapper.getShortName());
for (ScopeToolState state : myProvider.getTools(currentTools)) {
InspectionToolWrapper toolWrapper = state.getTool();
- LOG.assertTrue(!ApplicationManager.getApplication().isReadAccessAllowed());
ReadAction.run(() -> {
if (myProvider.checkReportedProblems(myGlobalInspectionContext, toolWrapper)) {
addTool(toolWrapper,
diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java
index 394c710de8eb..1735f08961d6 100644
--- a/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java
+++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/RefElementNode.java
@@ -29,13 +29,14 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.MutableTreeNode;
+import javax.swing.tree.TreeNode;
/**
* @author max
*/
public class RefElementNode extends SuppressableInspectionTreeNode {
- private boolean myHasDescriptorsUnder = false;
- private CommonProblemDescriptor mySingleDescriptor = null;
+ private volatile boolean myHasDescriptorsUnder;
+ private volatile CommonProblemDescriptor mySingleDescriptor;
private final Icon myIcon;
public RefElementNode(@Nullable RefEntity userObject, @NotNull InspectionToolPresentation presentation) {
super(userObject, presentation);
@@ -76,7 +77,6 @@ public class RefElementNode extends SuppressableInspectionTreeNode {
@Override
public void excludeElement(ExcludedInspectionTreeNodesManager excludedManager) {
- myPresentation.ignoreCurrentElement(getElement());
super.excludeElement(excludedManager);
}
@@ -92,10 +92,14 @@ public class RefElementNode extends SuppressableInspectionTreeNode {
@Override
public void add(MutableTreeNode newChild) {
+ checkHasDescriptorUnder(newChild);
super.add(newChild);
- if (newChild instanceof ProblemDescriptionNode) {
- myHasDescriptorsUnder = true;
- }
+ }
+
+ @Override
+ public InspectionTreeNode insertByOrder(InspectionTreeNode child, boolean allowDuplication) {
+ checkHasDescriptorUnder(child);
+ return super.insertByOrder(child, allowDuplication);
}
public void setProblem(@NotNull CommonProblemDescriptor descriptor) {
@@ -142,4 +146,17 @@ public class RefElementNode extends SuppressableInspectionTreeNode {
}
return isLeaf() ? "" : null;
}
+
+ private void checkHasDescriptorUnder(MutableTreeNode newChild) {
+ if (myHasDescriptorsUnder) return;
+ if (newChild instanceof ProblemDescriptionNode ||
+ newChild instanceof RefElementNode && ((RefElementNode)newChild).hasDescriptorsUnder()) {
+ myHasDescriptorsUnder = true;
+ TreeNode parent = getParent();
+ while (parent instanceof RefElementNode) {
+ ((RefElementNode)parent).myHasDescriptorsUnder = true;
+ parent = parent.getParent();
+ }
+ }
+ }
}
diff --git a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java
index 85deb8994189..68be8769956d 100644
--- a/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/profile/codeInspection/ui/header/InspectionToolsConfigurable.java
@@ -70,6 +70,8 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public abstract class InspectionToolsConfigurable extends BaseConfigurable
implements ErrorsConfigurable, SearchableConfigurable, Configurable.NoScroll {
@@ -78,7 +80,8 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable
private static final String HEADER_TITLE = "Profile:";
private static final Logger LOG = Logger.getInstance(InspectionToolsConfigurable.class);
- private static final String COPY_SUFFIX = "copy";
+ private static final Pattern COPIED_PROFILE_SUFFIX_PATTERN = Pattern.compile("(.*\\s*copy)\\s*(\\d*)");
+
protected final InspectionProfileManager myApplicationProfileManager;
protected final InspectionProjectProfileManager myProjectProfileManager;
private final CardLayout myLayout = new CardLayout();
@@ -115,15 +118,21 @@ public abstract class InspectionToolsConfigurable extends BaseConfigurable
LOG.assertTrue(modifyLevel || modifyName);
String profileDefaultName = selectedProfile.getName();
if (modifyName) {
- if (!profileDefaultName.endsWith(COPY_SUFFIX)) {
- profileDefaultName += " " + COPY_SUFFIX;
+ final Matcher matcher = COPIED_PROFILE_SUFFIX_PATTERN.matcher(profileDefaultName);
+ int nextIdx;
+ if (matcher.matches()) {
+ profileDefaultName = matcher.group(1);
+ nextIdx = matcher.group(2).isEmpty() ? 1 : Integer.valueOf(matcher.group(2));
+ }
+ else {
+ profileDefaultName += " copy";
+ nextIdx = 1;
}
if (hasName(profileDefaultName, modifyLevel != myPanels.get(selectedProfile).isProjectLevel())) {
- int idx = 0;
String currentProfileDefaultName;
do {
- idx++;
- currentProfileDefaultName = profileDefaultName + " " + String.valueOf(idx);
+ currentProfileDefaultName = profileDefaultName + " " + String.valueOf(nextIdx);
+ nextIdx++;
}
while (hasName(currentProfileDefaultName, modifyLevel != myPanels.get(selectedProfile).isProjectLevel()));
profileDefaultName = currentProfileDefaultName;
diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenamePsiFileProcessor.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenamePsiFileProcessor.java
index 678f3903b29d..527e33289838 100644
--- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenamePsiFileProcessor.java
+++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenamePsiFileProcessor.java
@@ -56,7 +56,7 @@ public class RenamePsiFileProcessor extends RenamePsiElementProcessor {
return super.findReferences(element);
}
- protected static class PsiFileRenameDialog extends RenameWithOptionalReferencesDialog {
+ public static class PsiFileRenameDialog extends RenameWithOptionalReferencesDialog {
public PsiFileRenameDialog(Project project, PsiElement element, PsiElement nameSuggestionContext, Editor editor) {
super(project, element, nameSuggestionContext, editor);
}
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index 1d3a8a7bc364..0be25906c1b2 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -2003,6 +2003,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
private UnindexedFilesFinder(@Nullable ProgressIndicator indicator) {
myProgressIndicator = indicator;
+ if (!myInitialized) waitUntilIndicesAreInitialized();
}
@NotNull
diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java
index 02f43bc8ba3b..d669a2b870f9 100644
--- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java
+++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/ProjectFileIndexImpl.java
@@ -163,7 +163,7 @@ public class ProjectFileIndexImpl extends FileIndexBase implements ProjectFileIn
@Override
public String getPackageNameByDirectory(@NotNull VirtualFile dir) {
- LOG.assertTrue(dir.isDirectory(), dir.getPresentableUrl());
+ if (!dir.isDirectory()) LOG.error(dir.getPresentableUrl());
return myDirectoryIndex.getPackageName(dir);
}
diff --git a/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java b/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java
index 3402920719ea..ea09f7f8bc66 100644
--- a/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java
+++ b/platform/remote-servers/api/src/com/intellij/remoteServer/ServerType.java
@@ -34,6 +34,11 @@ public abstract class ServerType {
@NotNull
public abstract String getPresentableName();
+ @NotNull
+ public String getHelpTopic() {
+ return "reference.settings.clouds";
+ }
+
@NotNull
public abstract Icon getIcon();
diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/SingleRemoteServerConfigurable.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/SingleRemoteServerConfigurable.java
index 6031309cafd9..120db55c7726 100644
--- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/SingleRemoteServerConfigurable.java
+++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/configuration/SingleRemoteServerConfigurable.java
@@ -166,7 +166,7 @@ public class SingleRemoteServerConfigurable extends NamedConfigurable commands) {
Collections.addAll(commands, String.valueOf(pid), String.valueOf(beforeRestart.length));
Collections.addAll(commands, beforeRestart);
- Collections.addAll(commands, String.valueOf(argc.getValue()));
+ Collections.addAll(commands, String.valueOf(argv.length));
Collections.addAll(commands, argv);
}
});
@@ -147,11 +147,34 @@ public class Restarter {
});
}
+ private static String[] getRestartArgv(String[] argv) {
+ int countArgs = argv.length;
+ for (int i = argv.length-1; i >=0; i--) {
+ if (argv[i].endsWith("com.intellij.idea.Main") ||
+ argv[i].endsWith(".exe")) {
+ countArgs = i + 1;
+ if ("0".equals(argv[2])) {
+ // update number of args in according with removed cmd line args
+ argv[3] = String.valueOf(Integer.valueOf(argv[3]) - (argv.length - (i+1)));
+ }
+ if (argv[i].endsWith(".exe") && argv[i].indexOf(File.separator) < 0) {
+ //absolute path
+ argv[i] = new File(PathManager.getBinPath(), argv[i]).getPath();
+ }
+ break;
+ }
+ }
+ String[] restartArg = new String[countArgs];
+ System.arraycopy(argv, 0, restartArg, 0, countArgs);
+ return restartArg;
+ }
+
private static void doScheduleRestart(File restarterFile, Consumer> argumentsBuilder) throws IOException {
List commands = new ArrayList();
commands.add(createTempExecutable(restarterFile).getPath());
argumentsBuilder.consume(commands);
- Runtime.getRuntime().exec(ArrayUtil.toStringArray(commands));
+ String[] argv = getRestartArgv(ArrayUtil.toStringArray(commands));
+ Runtime.getRuntime().exec(argv);
}
public static String getRestarterDir() {
diff --git a/plugins/ByteCodeViewer/ByteCodeViewer.iml b/plugins/ByteCodeViewer/ByteCodeViewer.iml
index 022e24d30dc9..ecf022c8422d 100644
--- a/plugins/ByteCodeViewer/ByteCodeViewer.iml
+++ b/plugins/ByteCodeViewer/ByteCodeViewer.iml
@@ -7,7 +7,7 @@
-
+
@@ -19,5 +19,4 @@
-
-
+
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
index 5a91e861441a..193be4ee448f 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
@@ -16,6 +16,7 @@
package com.siyeh.ig.controlflow;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
+import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
import com.intellij.psi.util.FileTypeUtils;
import com.intellij.psi.util.PsiTreeUtil;
@@ -26,6 +27,7 @@ import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteUnnecessaryStatementFix;
import com.siyeh.ig.psiutils.ControlFlowUtils;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -85,48 +87,59 @@ public class UnnecessaryReturnInspection extends BaseInspection {
@Override
public void visitReturnStatement(@NotNull PsiReturnStatement statement) {
super.visitReturnStatement(statement);
- if (statement.getReturnValue() != null) {
- return;
+ final Ref constructorRef = Ref.create();
+ if (isReturnRedundant(statement, ignoreInThenBranch, constructorRef)) {
+ registerStatementError(statement, constructorRef.get());
}
- final PsiElement methodParent = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, PsiLambdaExpression.class);
- PsiCodeBlock codeBlock = null;
- final boolean constructor;
- if (methodParent instanceof PsiMethod) {
- final PsiMethod method = (PsiMethod)methodParent;
- codeBlock = method.getBody();
- constructor = method.isConstructor();
- }
- else if (methodParent instanceof PsiLambdaExpression) {
- constructor = false;
- final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)methodParent;
- final PsiElement lambdaBody = lambdaExpression.getBody();
- if (lambdaBody instanceof PsiCodeBlock) {
- codeBlock = (PsiCodeBlock)lambdaBody;
- }
- }
- else {
- return;
- }
- if (codeBlock == null) {
- return;
- }
- if (!ControlFlowUtils.blockCompletesWithStatement(codeBlock, statement)) {
- return;
- }
- if (ignoreInThenBranch && isInThenBranch(statement)) {
- return;
- }
- registerStatementError(statement, Boolean.valueOf(constructor));
}
- private boolean isInThenBranch(PsiStatement statement) {
- final PsiIfStatement ifStatement =
- PsiTreeUtil.getParentOfType(statement, PsiIfStatement.class, true, PsiMethod.class, PsiLambdaExpression.class);
- if (ifStatement == null) {
- return false;
- }
- final PsiStatement elseBranch = ifStatement.getElseBranch();
- return elseBranch != null && !PsiTreeUtil.isAncestor(elseBranch, statement, true);
+ }
+
+ public static boolean isReturnRedundant(@NotNull PsiReturnStatement statement,
+ boolean ignoreInThenBranch,
+ @Nullable Ref isInConstructorRef) {
+ if (statement.getReturnValue() != null) {
+ return false;
}
+ final PsiElement methodParent = PsiTreeUtil.getParentOfType(statement, PsiMethod.class, PsiLambdaExpression.class);
+ PsiCodeBlock codeBlock = null;
+ if (methodParent instanceof PsiMethod) {
+ final PsiMethod method = (PsiMethod)methodParent;
+ codeBlock = method.getBody();
+ if (isInConstructorRef != null) {
+ isInConstructorRef.set(method.isConstructor());
+ }
+ }
+ else if (methodParent instanceof PsiLambdaExpression) {
+ isInConstructorRef.set(false);
+ final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)methodParent;
+ final PsiElement lambdaBody = lambdaExpression.getBody();
+ if (lambdaBody instanceof PsiCodeBlock) {
+ codeBlock = (PsiCodeBlock)lambdaBody;
+ }
+ }
+ else {
+ return false;
+ }
+ if (codeBlock == null) {
+ return false;
+ }
+ if (!ControlFlowUtils.blockCompletesWithStatement(codeBlock, statement)) {
+ return false;
+ }
+ if (ignoreInThenBranch && isInThenBranch(statement)) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean isInThenBranch(PsiStatement statement) {
+ final PsiIfStatement ifStatement =
+ PsiTreeUtil.getParentOfType(statement, PsiIfStatement.class, true, PsiMethod.class, PsiLambdaExpression.class);
+ if (ifStatement == null) {
+ return false;
+ }
+ final PsiStatement elseBranch = ifStatement.getElseBranch();
+ return elseBranch != null && !PsiTreeUtil.isAncestor(elseBranch, statement, true);
}
}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
index 960460d28c93..abaa5582e5ed 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
@@ -20,6 +20,8 @@ import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.FileTypeUtils;
+import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Query;
@@ -27,7 +29,6 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.*;
-import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -81,6 +82,15 @@ public class TooBroadScopeInspectionBase extends BaseInspection {
if (PsiUtil.isConstantExpression(expression) || ExpressionUtils.isNullLiteral(expression)) {
return true;
}
+ if (expression instanceof PsiArrayInitializerExpression) {
+ final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)expression;
+ for (PsiExpression initializer : arrayInitializerExpression.getInitializers()) {
+ if (!isMoveable(initializer)) {
+ return false;
+ }
+ }
+ return true;
+ }
if (expression instanceof PsiNewExpression) {
final PsiNewExpression newExpression = (PsiNewExpression)expression;
final PsiExpression[] arrayDimensions = newExpression.getArrayDimensions();
@@ -93,32 +103,35 @@ public class TooBroadScopeInspectionBase extends BaseInspection {
return true;
}
final PsiArrayInitializerExpression arrayInitializer = newExpression.getArrayInitializer();
- boolean result = true;
if (arrayInitializer != null) {
final PsiExpression[] initializers = arrayInitializer.getInitializers();
for (final PsiExpression initializerExpression : initializers) {
- result &= isMoveable(initializerExpression);
+ if (!isMoveable(initializerExpression)) {
+ return false;
+ }
}
+ return true;
}
final PsiType type = newExpression.getType();
if (type == null) {
return false;
}
else if (!m_allowConstructorAsInitializer) {
- // constructors located in library packages probably have no non-local side effects
- if (!ClassUtils.isImmutable(type) && !LibraryUtil.isTypeInLibrary(type)) {
+ if (!isAllowedType(type)) {
return false;
}
}
final PsiExpressionList argumentList = newExpression.getArgumentList();
if (argumentList == null) {
- return result;
+ return false;
}
final PsiExpression[] expressions = argumentList.getExpressions();
for (final PsiExpression argumentExpression : expressions) {
- result &= isMoveable(argumentExpression);
+ if (!isMoveable(argumentExpression)) {
+ return false;
+ }
}
- return result;
+ return true;
}
if (expression instanceof PsiReferenceExpression) {
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)expression;
@@ -147,10 +160,12 @@ public class TooBroadScopeInspectionBase extends BaseInspection {
return true;
}
if (expression instanceof PsiMethodCallExpression) {
- // methods located in library packages probably have no non-local side effects
+ if (!isAllowedType(expression.getType())) {
+ return false;
+ }
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
final PsiMethod method = methodCallExpression.resolveMethod();
- if (!(method instanceof PsiCompiledElement)) {
+ if (!isAllowedMethod(method)) {
return false;
}
final PsiExpressionList argumentList = methodCallExpression.getArgumentList();
@@ -164,6 +179,43 @@ public class TooBroadScopeInspectionBase extends BaseInspection {
return false;
}
+ private static boolean isAllowedMethod(PsiMethod method) {
+ if (method == null) {
+ return false;
+ }
+ final PsiClass aClass = method.getContainingClass();
+ if (aClass == null) {
+ return false;
+ }
+ final String qualifiedName = aClass.getQualifiedName();
+ if (qualifiedName == null || !qualifiedName.startsWith("java.")) {
+ return false;
+ }
+ final String methodName = method.getName();
+ return !"now".equals(methodName) && !"currentTimeMillis".equals(methodName) && !"nanoTime".equals(methodName);
+ }
+
+ private static boolean isAllowedType(PsiType type) {
+ if (ClassUtils.isImmutable(type)) {
+ return true;
+ }
+ if (!(type instanceof PsiClassType)) {
+ return false;
+ }
+ final PsiClassType classType = (PsiClassType)type;
+ final PsiClass aClass = classType.resolve();
+ return isAllowedClass(aClass);
+ }
+
+ private static boolean isAllowedClass(@Nullable PsiClass aClass) {
+ // allow some "safe" jdk types
+ if (InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_UTIL_COLLECTION) ||
+ InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_UTIL_MAP)) {
+ return true;
+ }
+ return aClass != null && aClass.isEnum();
+ }
+
@Override
public BaseInspectionVisitor buildVisitor() {
return new TooBroadScopeVisitor();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java
index 0ded3aae25b1..a361fd33eb93 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/ClassUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2016 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
*/
package com.siyeh.ig.psiutils;
+import com.intellij.codeInspection.concurrencyAnnotations.JCiPUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -68,14 +69,22 @@ public class ClassUtils {
immutableTypes.add(CommonClassNames.JAVA_LANG_BYTE);
immutableTypes.add(CommonClassNames.JAVA_LANG_STRING);
immutableTypes.add("java.awt.Font");
+ immutableTypes.add("java.awt.BasicStroke");
immutableTypes.add("java.awt.Color");
+ immutableTypes.add("java.awt.Cursor");
immutableTypes.add("java.math.BigDecimal");
immutableTypes.add("java.math.BigInteger");
immutableTypes.add("java.math.MathContext");
immutableTypes.add("java.nio.channels.FileLock");
immutableTypes.add("java.nio.charset.Charset");
immutableTypes.add("java.io.File");
+ immutableTypes.add("java.net.Inet4Address");
+ immutableTypes.add("java.net.Inet6Address");
+ immutableTypes.add("java.net.InetSocketAddress");
immutableTypes.add("java.net.URI");
+ immutableTypes.add("java.net.URL");
+ immutableTypes.add("java.util.Locale");
+ immutableTypes.add("java.util.UUID");
immutableTypes.add("java.util.regex.Pattern");
}
@@ -107,8 +116,14 @@ public class ClassUtils {
return false;
}
final PsiClassType classType = (PsiClassType)type;
- final String className = classType.getCanonicalText();
- return immutableTypes.contains(className);
+ final PsiClass aClass = classType.resolve();
+ if (aClass == null) {
+ return false;
+ }
+ if (immutableTypes.contains(aClass.getQualifiedName())) {
+ return true;
+ }
+ return JCiPUtil.isImmutable(aClass);
}
public static boolean inSamePackage(@Nullable PsiElement element1,
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
index 44ffdf41a6e5..6b45d6f66368 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/dataflow/scope/TooBroadScope.java
@@ -150,6 +150,7 @@ public class TooBroadScope
}
private final String[] EMPTY = {};
+ private final String[] ONE = {"one"};
void abc() {
String[] strings = EMPTY;
System.out.println();
@@ -160,5 +161,41 @@ public class TooBroadScope
System.out.println();
System.out.println();
System.out.println(list);
+
+ String[] ss = new String[10];
+ System.out.println();
+ System.out.println();
+ System.out.println(ss);
+
+ String[] ss2 = new String[] {""};
+ System.out.println();
+ System.out.println();
+ System.out.println(ss2);
+
+ String[] ss3 = {};
+ System.out.println();
+ System.out.println();
+ System.out.println(ss3);
+
+ String[] ss3a = {ONE[0]};
+ backgroundAction();
+ System.out.println();
+ System.out.println(ss3a);
+
+ List ss4 = Arrays.asList(ONE);
+ backgroundAction();
+ System.out.println();
+ System.out.println(ss4);
+ }
+
+ void backgroundAction() {
+ ONE[0] = "two";
+ }
+
+ void time() {
+ long start = System.currentTimeMillis();
+ System.out.println();
+ long end = System.currentTimeMillis();
+ System.out.println("elapsed: " + (end - start));
}
}
\ No newline at end of file
diff --git a/plugins/IntelliLang/IntelliLang-java.iml b/plugins/IntelliLang/IntelliLang-java.iml
index 585a1f6d5a17..66a00fa603db 100644
--- a/plugins/IntelliLang/IntelliLang-java.iml
+++ b/plugins/IntelliLang/IntelliLang-java.iml
@@ -11,7 +11,7 @@
-
+
@@ -22,5 +22,4 @@
-
-
+
\ No newline at end of file
diff --git a/plugins/IntelliLang/IntelliLang-xml.iml b/plugins/IntelliLang/IntelliLang-xml.iml
index 20db7d65ff08..1659417efc9d 100644
--- a/plugins/IntelliLang/IntelliLang-xml.iml
+++ b/plugins/IntelliLang/IntelliLang-xml.iml
@@ -10,7 +10,7 @@
-
+
@@ -22,5 +22,4 @@
-
-
+
\ No newline at end of file
diff --git a/plugins/coverage-common/coverage-common.iml b/plugins/coverage-common/coverage-common.iml
index 0ce232bc7b7f..08567374ed2d 100644
--- a/plugins/coverage-common/coverage-common.iml
+++ b/plugins/coverage-common/coverage-common.iml
@@ -12,7 +12,7 @@
-
+
diff --git a/plugins/ui-designer/ui-designer.iml b/plugins/ui-designer/ui-designer.iml
index e6a868e99465..eca27c766b69 100644
--- a/plugins/ui-designer/ui-designer.iml
+++ b/plugins/ui-designer/ui-designer.iml
@@ -19,7 +19,7 @@
-
+
@@ -35,5 +35,4 @@
-
-
+
\ No newline at end of file
diff --git a/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py b/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py
index c9078e14457d..bbc37965ec58 100644
--- a/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py
+++ b/python/helpers/pydev/_pydev_bundle/pydev_console_utils.py
@@ -189,10 +189,13 @@ class BaseInterpreterInterface:
return self.need_more_for_code(self.buffer.text)
- def create_std_in(self):
- return StdIn(self, self.host, self.client_port)
+ def create_std_in(self, debugger=None, original_std_in=None):
+ if debugger is None:
+ return StdIn(self, self.host, self.client_port)
+ else:
+ return DebugConsoleStdIn(dbg=debugger, original_stdin=original_std_in)
- def add_exec(self, code_fragment):
+ def add_exec(self, code_fragment, debugger=None):
original_in = sys.stdin
try:
help = None
@@ -210,7 +213,7 @@ class BaseInterpreterInterface:
more = False
try:
- sys.stdin = self.create_std_in()
+ sys.stdin = self.create_std_in(debugger, original_in)
try:
if help is not None:
#This will enable the help() function to work.
diff --git a/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py b/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py
index ec0c13d692b5..85d3267e9c73 100644
--- a/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py
+++ b/python/helpers/pydev/_pydevd_bundle/pydevd_comm.py
@@ -1331,7 +1331,7 @@ class InternalConsoleExec(InternalThreadCommand):
#don't trace new threads created by console command
disable_trace_thread_modules()
- result = pydevconsole.console_exec(self.thread_id, self.frame_id, self.expression)
+ result = pydevconsole.console_exec(self.thread_id, self.frame_id, self.expression, dbg)
xml = ""
xml += pydevd_vars.var_to_xml(result, "")
xml += ""
diff --git a/python/helpers/pydev/pydevconsole.py b/python/helpers/pydev/pydevconsole.py
index 2ef4df593fb6..5beab3126b80 100644
--- a/python/helpers/pydev/pydevconsole.py
+++ b/python/helpers/pydev/pydevconsole.py
@@ -374,7 +374,7 @@ def get_completions(text, token, globals, locals):
# Debugger integration
#===============================================================================
-def exec_code(code, globals, locals):
+def exec_code(code, globals, locals, debugger):
interpreterInterface = get_interpreter()
interpreterInterface.interpreter.update(globals, locals)
@@ -383,7 +383,7 @@ def exec_code(code, globals, locals):
if res:
return True
- interpreterInterface.add_exec(code)
+ interpreterInterface.add_exec(code, debugger)
return False
@@ -443,7 +443,7 @@ class ConsoleWriter(InteractiveInterpreter):
tblist = tb = None
sys.stderr.write(''.join(lines))
-def console_exec(thread_id, frame_id, expression):
+def console_exec(thread_id, frame_id, expression, dbg):
"""returns 'False' in case expression is partially correct
"""
frame = pydevd_vars.find_frame(thread_id, frame_id)
@@ -458,7 +458,7 @@ def console_exec(thread_id, frame_id, expression):
updated_globals.update(frame.f_locals) #locals later because it has precedence over the actual globals
if IPYTHON:
- need_more = exec_code(CodeFragment(expression), updated_globals, frame.f_locals)
+ need_more = exec_code(CodeFragment(expression), updated_globals, frame.f_locals, dbg)
if not need_more:
pydevd_save_locals.save_locals(frame)
return need_more
diff --git a/python/helpers/tools/versions.xml b/python/helpers/tools/versions.xml
index a89ba6e8d570..4c6bc1e9306d 100644
--- a/python/helpers/tools/versions.xml
+++ b/python/helpers/tools/versions.xml
@@ -112,7 +112,6 @@
bsddb.test.test_sequence
build_class
builtins
- bz2
cProfile
collections
collections.__main__
@@ -859,7 +858,6 @@
bsddb.test.test_sequence
build_class
builtins
- bz2
cProfile
collections.__main__
collections.abc
@@ -1548,7 +1546,6 @@
bsddb.test.test_replication
build_class
builtins
- bz2
collections.__main__
collections.abc
concurrent
@@ -2128,7 +2125,6 @@
bsddb.test.test_fileid
build_class
builtins
- bz2
collections.__main__
collections.abc
concurrent
@@ -2541,7 +2537,6 @@
bsddb.test.test_env_close
build_class
builtins
- bz2
collections.__main__
collections.abc
concurrent
@@ -2941,7 +2936,6 @@
bsddb.test.test_replication
bsddb.test.test_sequence
bsddb.test.test_thread
- bz2
cPickle
cStringIO
collections.__main__
@@ -3480,7 +3474,6 @@
bsddb.test.test_sequence
bsddb.test.test_thread
build_class
- bz2
cPickle
cStringIO
collections.__main__
@@ -3926,7 +3919,6 @@
bsddb.test.test_sequence
bsddb.test.test_thread
build_class
- bz2
cPickle
cStringIO
collections.__main__
@@ -4232,7 +4224,6 @@
_abcoll
_bootlocale
_bytesio
- _bz2
_collections_abc
_compression
_fileio
@@ -4597,7 +4588,6 @@
__main__
_abcoll
_bytesio
- _bz2
_compression
_fileio
_hotshot
diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java
index 4b55f49acdb0..174db221d0c5 100644
--- a/python/psi-api/src/com/jetbrains/python/PyNames.java
+++ b/python/psi-api/src/com/jetbrains/python/PyNames.java
@@ -165,6 +165,7 @@ public class PyNames {
public static final String DIV = "__div__";
public static final String TRUEDIV = "__truediv__";
public static final String AITER = "__aiter__";
+ public static final String SIZEOF = "__sizeof__";
public static final String NAME = "__name__";
public static final String ENTER = "__enter__";
diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java b/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java
index 8dba1d02da9b..46f07970447a 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/impl/PyPsiUtils.java
@@ -19,7 +19,6 @@ import com.google.common.base.Preconditions;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -604,6 +603,14 @@ public class PyPsiUtils {
Preconditions.checkArgument(!module.isDisposed(), String.format("Module %s is disposed", module));
}
+ @NotNull
+ public static PsiFileSystemItem getFileSystemItem(@NotNull PsiElement element) {
+ if (element instanceof PsiFileSystemItem) {
+ return (PsiFileSystemItem)element;
+ }
+ return element.getContainingFile();
+ }
+
private static abstract class TopLevelVisitor extends PyRecursiveElementVisitor {
public void visitPyElement(final PyElement node) {
super.visitPyElement(node);
diff --git a/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java b/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java
index e998ab07678a..02b95124f3dd 100644
--- a/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java
+++ b/python/src/com/jetbrains/python/codeInsight/imports/ImportFromExistingAction.java
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.hint.QuestionAction;
import com.intellij.ide.DataManager;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -28,7 +29,10 @@ import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.util.QualifiedName;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
@@ -98,10 +102,12 @@ public class ImportFromExistingAction implements QuestionAction {
return false;
}
// act
- if (mySources.size() > 1) {
+ if (mySources.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) {
+ doWriteAction(mySources.get(0));
+ }
+ else {
selectSourceAndDo();
}
- else doWriteAction(mySources.get(0));
return true;
}
diff --git a/python/src/com/jetbrains/python/packaging/PyPackageUtil.java b/python/src/com/jetbrains/python/packaging/PyPackageUtil.java
index b1e2ffe071d5..0fc1b2017a35 100644
--- a/python/src/com/jetbrains/python/packaging/PyPackageUtil.java
+++ b/python/src/com/jetbrains/python/packaging/PyPackageUtil.java
@@ -15,11 +15,11 @@
*/
package com.jetbrains.python.packaging;
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.execution.ExecutionException;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
@@ -50,9 +50,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author vlan
@@ -314,8 +314,7 @@ public class PyPackageUtil {
}
manager.refreshAndGetPackages(true);
}
- catch (ExecutionException e) {
- LOG.warn(e);
+ catch (ExecutionException ignored) {
}
finally {
isUpdating.set(false);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
index 7a69028df556..e408dae3ba34 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -371,6 +371,11 @@ public class PyBuiltinCache {
return getObjectType("staticmethod");
}
+ @Nullable
+ public PyClassType getTypeType() {
+ return getObjectType("type");
+ }
+
/**
* @param target an element to check.
* @return true iff target is inside the __builtins__.py
diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
index c28e78734eae..ecdaa5164f10 100644
--- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
@@ -240,6 +240,27 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
}
}
+ // resolve implicit __class__ inside class function
+ if (myElement instanceof PyReferenceExpression &&
+ PyNames.__CLASS__.equals(referencedName) &&
+ LanguageLevel.forElement(myElement).isAtLeast(LanguageLevel.PYTHON30)) {
+ final PyFunction containingFunction = PsiTreeUtil.getParentOfType(myElement, PyFunction.class);
+
+ if (containingFunction != null) {
+ final PyClass containingClass = containingFunction.getContainingClass();
+
+ if (containingClass != null) {
+ final PyResolveProcessor processor = new PyResolveProcessor(referencedName);
+ PyResolveUtil.scopeCrawlUp(processor, myElement, referencedName, containingFunction);
+
+ if (processor.getElements().isEmpty()) {
+ ret.add(new RatedResolveResult(RatedResolveResult.RATE_NORMAL, containingClass));
+ return ret;
+ }
+ }
+ }
+ }
+
// here we have an unqualified expr. it may be defined:
// ...in current file
final PyResolveProcessor processor = new PyResolveProcessor(referencedName);
@@ -247,9 +268,24 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
// Use real context here to enable correct completion and resolve in case of PyExpressionCodeFragment
final PsiElement realContext = PyPsiUtils.getRealContext(myElement);
- PsiElement roof = findResolveRoof(referencedName, realContext);
+ final PsiElement roof = findResolveRoof(referencedName, realContext);
PyResolveUtil.scopeCrawlUp(processor, myElement, referencedName, roof);
- return getResultsFromProcessor(referencedName, processor, realContext, roof);
+
+ final List resultsFromProcessor = getResultsFromProcessor(referencedName, processor, realContext, roof);
+
+ // resolve to module __doc__
+ if (resultsFromProcessor.isEmpty() && referencedName.equals(PyNames.DOC)) {
+ ret.addAll(
+ Optional
+ .ofNullable(PyBuiltinCache.getInstance(myElement).getObjectType())
+ .map(type -> type.resolveMember(referencedName, myElement, AccessDirection.of(myElement), myContext))
+ .orElse(Collections.emptyList())
+ );
+
+ return ret;
+ }
+
+ return resultsFromProcessor;
}
protected List getResultsFromProcessor(@NotNull String referencedName,
diff --git a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java
index e87c189f361f..04029133f240 100644
--- a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java
+++ b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
+import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
@@ -30,7 +31,6 @@ import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
-import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -85,13 +85,7 @@ public class QualifiedNameFinder {
@Nullable
private static QualifiedName shortestQName(@NotNull List qNames) {
- QualifiedName result = null;
- for (QualifiedName name : qNames) {
- if (result == null || name.getComponentCount() < result.getComponentCount()) {
- result = name;
- }
- }
- return result;
+ return qNames.stream().min((o1, o2) -> o1.getComponentCount() - o2.getComponentCount()).orElse(null);
}
@Nullable
@@ -142,8 +136,13 @@ public class QualifiedNameFinder {
if (initPy == null) {
break;
}
- if (initPy instanceof PyFile && toplevel.equals(((PyFile)initPy).getElementNamed(((PsiNamedElement)toplevel).getName()))) {
- virtualFile = dir.getVirtualFile();
+ if (initPy instanceof PyFile) {
+ //noinspection ConstantConditions
+ final List resolved = ((PyFile)initPy).multiResolveName(((PsiNamedElement)toplevel).getName());
+ final PsiElement finalTopLevel = toplevel;
+ if (resolved.stream().anyMatch(r -> r.getElement() == finalTopLevel)) {
+ virtualFile = dir.getVirtualFile();
+ }
}
dir = dir.getParentDirectory();
}
diff --git a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java
index 5592b58c61c5..58b594e264a1 100644
--- a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java
+++ b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java
@@ -28,15 +28,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
-import com.intellij.psi.PsiNamedElement;
+import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsUtil;
import com.jetbrains.python.console.PydevConsoleRunner;
import com.jetbrains.python.facet.PythonPathContributingFacet;
+import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyUtil;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
@@ -44,6 +42,7 @@ import com.jetbrains.python.psi.impl.PyImportResolver;
import com.jetbrains.python.psi.impl.PyPsiUtils;
import com.jetbrains.python.sdk.PySdkUtil;
import com.jetbrains.python.sdk.PythonSdkType;
+import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -52,6 +51,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
+import static com.jetbrains.python.psi.PyUtil.as;
+
/**
* Resolves the specified qualified name in the specified context (module, all modules or a file) to a file or directory.
*
@@ -235,6 +236,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
final PsiFile footholdFile = myContext.getFootholdFile();
checkValidForTests(footholdFile);
+ boolean foundRelativeImport = false;
if (myRelativeLevel >= 0 && footholdFile != null && !PyUserSkeletonsUtil.isUnderUserSkeletonsDirectory(footholdFile)) {
PsiDirectory dir = footholdFile.getContainingDirectory();
checkValidForTests(dir);
@@ -246,12 +248,13 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
PsiElement module = resolveModuleAt(dir);
checkValidForTests(module);
if (module != null) {
+ foundRelativeImport = isRelativeImportResult(dir, module);
addRoot(module, true);
}
}
final PythonPathCache cache = findMyCache();
- final boolean mayCache = cache != null && !myWithoutRoots && !myWithoutForeign;
+ final boolean mayCache = cache != null && !myWithoutRoots && !myWithoutForeign && !foundRelativeImport;
if (mayCache) {
final List cachedResults = cache.get(myQualifiedName);
if (cachedResults != null) {
@@ -293,6 +296,22 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
return results;
}
+
+ private boolean isRelativeImportResult(@NotNull PsiDirectory rootDirectory, @NotNull PsiElement result) {
+ if (myRelativeLevel > 0) {
+ return true;
+ }
+ final boolean isPython2 = LanguageLevel.forElement(rootDirectory).isOlderThan(LanguageLevel.PYTHON30);
+ if (myRelativeLevel == 0 && isPython2 && PyUtil.isPackage(rootDirectory, false, null)) {
+ // Candidate for implicit relative import doesn't necessarily means that the same module cannot be imported absolutely
+ final PsiFileSystemItem moduleOrPackage = as(result, PsiFileSystemItem.class);
+ if (moduleOrPackage != null && !myQualifiedName.equals(QualifiedNameFinder.findShortestImportableQName(moduleOrPackage))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Resolve relative imports from sdk root to the skeleton dir
*/
@@ -421,6 +440,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
*
* @param directory where to start from; top qualifier will be searched for here.
*/
+ @Contract("null -> null")
@Nullable
public PsiElement resolveModuleAt(@Nullable PsiDirectory directory) {
// prerequisites
diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
index 3660c809f15f..2c1c75042b59 100644
--- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
+++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
@@ -195,10 +195,22 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
}
classMember = resolveClassMember(myClass, myIsDefinition, name, location);
+
+ if (PyNames.__CLASS__.equals(name)) {
+ return resolveDunderClass(context, classMember);
+ }
+
if (classMember != null) {
return ResolveResultList.to(classMember);
}
+ if (PyNames.DOC.equals(name)) {
+ return Optional
+ .ofNullable(PyBuiltinCache.getInstance(myClass).getObjectType())
+ .map(type -> type.resolveMember(name, location, direction, resolveContext))
+ .orElse(Collections.emptyList());
+ }
+
classMember = resolveByOverridingAncestorsMembersProviders(this, name, location);
if (classMember != null) {
final ResolveResultList list = new ResolveResultList();
@@ -293,6 +305,36 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
return resultRef;
}
+ @Nullable
+ private List extends RatedResolveResult> resolveDunderClass(@NotNull TypeEvalContext context, @Nullable PsiElement classMember) {
+ final boolean newStyleClass = myClass.isNewStyleClass(context);
+
+ if (!myIsDefinition) {
+ if (newStyleClass && classMember != null) {
+ return ResolveResultList.to(classMember);
+ }
+
+ return ResolveResultList.to(
+ myClass.getAncestorClasses(context)
+ .stream()
+ .filter(cls -> !PyUtil.isObjectClass(cls))
+ .map(cls -> cls.findClassAttribute(PyNames.__CLASS__, true, context))
+ .filter(target -> target != null)
+ .findFirst()
+ .orElse(myClass)
+ );
+ }
+
+ if (LanguageLevel.forElement(myClass).isOlderThan(LanguageLevel.PYTHON30) && !newStyleClass) {
+ return ResolveResultList.to(classMember);
+ }
+
+ return Optional
+ .ofNullable(PyBuiltinCache.getInstance(myClass).getTypeType())
+ .map(typeType -> ResolveResultList.to(typeType.getPyClass()))
+ .orElse(null);
+ }
+
@Nullable
@Override
public PyClassLikeType getMetaClassType(@NotNull final TypeEvalContext context, boolean inherited) {
diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java b/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
index e593af40baa9..edca9e70620f 100644
--- a/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
+++ b/python/src/com/jetbrains/python/sdk/PythonSdkUpdater.java
@@ -133,6 +133,7 @@ public class PythonSdkUpdater implements StartupActivity {
return true;
}
+ @SuppressWarnings("ThrowableInstanceNeverThrown") final Throwable methodCallStacktrace = new Throwable();
application.invokeLater(() -> {
synchronized (ourLock) {
if (!ourScheduledToRefresh.contains(homePath)) {
@@ -165,6 +166,7 @@ public class PythonSdkUpdater implements StartupActivity {
PyPackageManager.getInstance(sdk12).refreshAndGetPackages(true);
}
catch (ExecutionException e) {
+ e.initCause(methodCallStacktrace);
LOG.warn(e);
}
}
diff --git a/python/testData/inspections/PyCompatibilityInspection/bz2Module.py b/python/testData/inspections/PyCompatibilityInspection/bz2Module.py
new file mode 100644
index 000000000000..b4e4ac25b00a
--- /dev/null
+++ b/python/testData/inspections/PyCompatibilityInspection/bz2Module.py
@@ -0,0 +1 @@
+from bz2 import BZ2File
\ No newline at end of file
diff --git a/python/testData/inspections/PyCompatibilityInspection/underscoreBz2Module.py b/python/testData/inspections/PyCompatibilityInspection/underscoreBz2Module.py
new file mode 100644
index 000000000000..8ae8a0c2ad87
--- /dev/null
+++ b/python/testData/inspections/PyCompatibilityInspection/underscoreBz2Module.py
@@ -0,0 +1 @@
+import _bz2
\ No newline at end of file
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/dunderClass.py b/python/testData/inspections/PyUnresolvedReferencesInspection/dunderClass.py
new file mode 100644
index 000000000000..293405bd59bd
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection/dunderClass.py
@@ -0,0 +1,3 @@
+class A:
+ def foo(self):
+ return __class__
\ No newline at end of file
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection3K/dunderClass.py b/python/testData/inspections/PyUnresolvedReferencesInspection3K/dunderClass.py
new file mode 100644
index 000000000000..82edcc21ab81
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection3K/dunderClass.py
@@ -0,0 +1,3 @@
+class A:
+ def foo(self):
+ return __class__
\ No newline at end of file
diff --git a/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/bar/__init__.py b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/bar/__init__.py
new file mode 100644
index 000000000000..3fdf6be7ca9b
--- /dev/null
+++ b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/bar/__init__.py
@@ -0,0 +1 @@
+from mod import MyClass
\ No newline at end of file
diff --git a/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/bar/mod.py b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/bar/mod.py
new file mode 100644
index 000000000000..6f75e663c7a6
--- /dev/null
+++ b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/bar/mod.py
@@ -0,0 +1,2 @@
+class MyClass(object):
+ pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/foo/__init__.py b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/foo/__init__.py
new file mode 100644
index 000000000000..3fdf6be7ca9b
--- /dev/null
+++ b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/foo/__init__.py
@@ -0,0 +1 @@
+from mod import MyClass
\ No newline at end of file
diff --git a/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/foo/mod.py b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/foo/mod.py
new file mode 100644
index 000000000000..6f75e663c7a6
--- /dev/null
+++ b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/foo/mod.py
@@ -0,0 +1,2 @@
+class MyClass(object):
+ pass
\ No newline at end of file
diff --git a/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/main.py b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/main.py
new file mode 100644
index 000000000000..3d0c10c7fceb
--- /dev/null
+++ b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/main.py
@@ -0,0 +1 @@
+MyClass()
\ No newline at end of file
diff --git a/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/main_after.py b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/main_after.py
new file mode 100644
index 000000000000..8683c5a7c50e
--- /dev/null
+++ b/python/testData/quickFixes/AddImportQuickFixTest/canonicalNamesFromHigherLevelPackage/main_after.py
@@ -0,0 +1,3 @@
+from foo import MyClass
+
+MyClass()
\ No newline at end of file
diff --git a/python/testData/resolve/ClassAttrInDeclaration.py b/python/testData/resolve/ClassAttrInDeclaration.py
new file mode 100644
index 000000000000..bf5499858801
--- /dev/null
+++ b/python/testData/resolve/ClassAttrInDeclaration.py
@@ -0,0 +1,4 @@
+class A:
+ my_attr = 17
+ print(my_attr)
+# [
\ No newline at end of file
diff --git a/python/testData/resolve/ClassAttrInDeclarationNewStyleClass.py b/python/testData/resolve/ClassAttrInDeclarationNewStyleClass.py
new file mode 100644
index 000000000000..fb3c9705a2bd
--- /dev/null
+++ b/python/testData/resolve/ClassAttrInDeclarationNewStyleClass.py
@@ -0,0 +1,4 @@
+class A(object):
+ my_attr = 17
+ print(my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderClassInDeclaration.py b/python/testData/resolve/DunderClassInDeclaration.py
new file mode 100644
index 000000000000..d5bcc9eb2794
--- /dev/null
+++ b/python/testData/resolve/DunderClassInDeclaration.py
@@ -0,0 +1,3 @@
+class A:
+ print(__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderClassInDeclarationInsideFunction.py b/python/testData/resolve/DunderClassInDeclarationInsideFunction.py
new file mode 100644
index 000000000000..5a67313028ea
--- /dev/null
+++ b/python/testData/resolve/DunderClassInDeclarationInsideFunction.py
@@ -0,0 +1,6 @@
+def foo():
+ class A:
+ print(__class__)
+ # ][
+
+ return A()
\ No newline at end of file
diff --git a/python/testData/resolve/DunderClassInDeclarationNewStyleClass.py b/python/testData/resolve/DunderClassInDeclarationNewStyleClass.py
new file mode 100644
index 000000000000..317370258e67
--- /dev/null
+++ b/python/testData/resolve/DunderClassInDeclarationNewStyleClass.py
@@ -0,0 +1,3 @@
+class A(object):
+ print(__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderClassInDeclarationWithClassAttr.py b/python/testData/resolve/DunderClassInDeclarationWithClassAttr.py
new file mode 100644
index 000000000000..9e790d60290f
--- /dev/null
+++ b/python/testData/resolve/DunderClassInDeclarationWithClassAttr.py
@@ -0,0 +1,4 @@
+class A:
+ __class__ = 17
+ print(__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderClassInDeclarationWithClassAttrNewStyleClass.py b/python/testData/resolve/DunderClassInDeclarationWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..1921ecd845da
--- /dev/null
+++ b/python/testData/resolve/DunderClassInDeclarationWithClassAttrNewStyleClass.py
@@ -0,0 +1,4 @@
+class A(object):
+ __class__ = 17
+ print(__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderClassInDeclarationWithInheritedClassAttr.py b/python/testData/resolve/DunderClassInDeclarationWithInheritedClassAttr.py
new file mode 100644
index 000000000000..cb3986d46517
--- /dev/null
+++ b/python/testData/resolve/DunderClassInDeclarationWithInheritedClassAttr.py
@@ -0,0 +1,6 @@
+class A(object):
+ __class__ = 17
+
+class B(A):
+ print(__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderDocInDeclaration.py b/python/testData/resolve/DunderDocInDeclaration.py
new file mode 100644
index 000000000000..f542971e0ce5
--- /dev/null
+++ b/python/testData/resolve/DunderDocInDeclaration.py
@@ -0,0 +1,3 @@
+class A:
+ print(__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderDocInDeclarationNewStyleClass.py b/python/testData/resolve/DunderDocInDeclarationNewStyleClass.py
new file mode 100644
index 000000000000..8deaa6098586
--- /dev/null
+++ b/python/testData/resolve/DunderDocInDeclarationNewStyleClass.py
@@ -0,0 +1,3 @@
+class A(object):
+ print(__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderDocInDeclarationWithClassAttr.py b/python/testData/resolve/DunderDocInDeclarationWithClassAttr.py
new file mode 100644
index 000000000000..3e195cbb44ad
--- /dev/null
+++ b/python/testData/resolve/DunderDocInDeclarationWithClassAttr.py
@@ -0,0 +1,4 @@
+class A:
+ __doc__ = 17
+ print(__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderDocInDeclarationWithClassAttrNewStyleClass.py b/python/testData/resolve/DunderDocInDeclarationWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..6a0dc30bd74f
--- /dev/null
+++ b/python/testData/resolve/DunderDocInDeclarationWithClassAttrNewStyleClass.py
@@ -0,0 +1,4 @@
+class A(object):
+ __doc__ = 17
+ print(__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderDocInDeclarationWithInheritedClassAttr.py b/python/testData/resolve/DunderDocInDeclarationWithInheritedClassAttr.py
new file mode 100644
index 000000000000..82af27afa69b
--- /dev/null
+++ b/python/testData/resolve/DunderDocInDeclarationWithInheritedClassAttr.py
@@ -0,0 +1,6 @@
+class A(object):
+ __doc__ = 17
+
+class B(A):
+ print(__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderSizeOfInDeclaration.py b/python/testData/resolve/DunderSizeOfInDeclaration.py
new file mode 100644
index 000000000000..f15a8686048d
--- /dev/null
+++ b/python/testData/resolve/DunderSizeOfInDeclaration.py
@@ -0,0 +1,3 @@
+class A:
+ print(__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderSizeOfInDeclarationNewStyleClass.py b/python/testData/resolve/DunderSizeOfInDeclarationNewStyleClass.py
new file mode 100644
index 000000000000..52caeda412ac
--- /dev/null
+++ b/python/testData/resolve/DunderSizeOfInDeclarationNewStyleClass.py
@@ -0,0 +1,3 @@
+class A(object):
+ print(__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderSizeOfInDeclarationWithClassAttr.py b/python/testData/resolve/DunderSizeOfInDeclarationWithClassAttr.py
new file mode 100644
index 000000000000..9aa973e5cd79
--- /dev/null
+++ b/python/testData/resolve/DunderSizeOfInDeclarationWithClassAttr.py
@@ -0,0 +1,4 @@
+class A:
+ __sizeof__ = 17
+ print(__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderSizeOfInDeclarationWithClassAttrNewStyleClass.py b/python/testData/resolve/DunderSizeOfInDeclarationWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..5daf08022681
--- /dev/null
+++ b/python/testData/resolve/DunderSizeOfInDeclarationWithClassAttrNewStyleClass.py
@@ -0,0 +1,4 @@
+class A(object):
+ __sizeof__ = 17
+ print(__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/DunderSizeOfInDeclarationWithInheritedClassAttr.py b/python/testData/resolve/DunderSizeOfInDeclarationWithInheritedClassAttr.py
new file mode 100644
index 000000000000..4d8a27e1cb0a
--- /dev/null
+++ b/python/testData/resolve/DunderSizeOfInDeclarationWithInheritedClassAttr.py
@@ -0,0 +1,6 @@
+class A(object):
+ __sizeof__ = 17
+
+class B(A):
+ print(__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitClassAttr.py b/python/testData/resolve/ImplicitClassAttr.py
new file mode 100644
index 000000000000..2d8a3eff40c1
--- /dev/null
+++ b/python/testData/resolve/ImplicitClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ my_attr = 15
+
+ def foo(self):
+ return my_attr
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitClassAttrNewStyleClass.py b/python/testData/resolve/ImplicitClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..070be0694552
--- /dev/null
+++ b/python/testData/resolve/ImplicitClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ my_attr = 15
+
+ def foo(self):
+ return my_attr
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderClass.py b/python/testData/resolve/ImplicitDunderClass.py
new file mode 100644
index 000000000000..2e68ba7b1f22
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderClass.py
@@ -0,0 +1,4 @@
+class A:
+ def foo(self):
+ return __class__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderClassNewStyleClass.py b/python/testData/resolve/ImplicitDunderClassNewStyleClass.py
new file mode 100644
index 000000000000..99a8a16771b7
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderClassNewStyleClass.py
@@ -0,0 +1,4 @@
+class A(object):
+ def foo(self):
+ return __class__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderClassWithClassAttr.py b/python/testData/resolve/ImplicitDunderClassWithClassAttr.py
new file mode 100644
index 000000000000..81a09107ec71
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderClassWithClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ __class__ = 15
+
+ def foo(self):
+ return __class__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderClassWithClassAttrNewStyleClass.py b/python/testData/resolve/ImplicitDunderClassWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..4e685fd46b6b
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderClassWithClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ __class__ = 15
+
+ def foo(self):
+ return __class__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderClassWithInheritedClassAttr.py b/python/testData/resolve/ImplicitDunderClassWithInheritedClassAttr.py
new file mode 100644
index 000000000000..57cb96bf7405
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderClassWithInheritedClassAttr.py
@@ -0,0 +1,7 @@
+class A(object):
+ __class__ = int
+
+class B(A):
+ def foo(self):
+ return __class__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderDoc.py b/python/testData/resolve/ImplicitDunderDoc.py
new file mode 100644
index 000000000000..30d09c82fc71
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderDoc.py
@@ -0,0 +1,4 @@
+class A:
+ def foo(self):
+ return __doc__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderDocNewStyleClass.py b/python/testData/resolve/ImplicitDunderDocNewStyleClass.py
new file mode 100644
index 000000000000..1a93f8ff38b7
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderDocNewStyleClass.py
@@ -0,0 +1,4 @@
+class A(object):
+ def foo(self):
+ return __doc__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderDocWithClassAttr.py b/python/testData/resolve/ImplicitDunderDocWithClassAttr.py
new file mode 100644
index 000000000000..821ed805f054
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderDocWithClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ __doc__ = 15
+
+ def foo(self):
+ return __doc__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderDocWithClassAttrNewStyleClass.py b/python/testData/resolve/ImplicitDunderDocWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..545b55d94a2e
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderDocWithClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ __doc__ = 15
+
+ def foo(self):
+ return __doc__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderDocWithInheritedClassAttr.py b/python/testData/resolve/ImplicitDunderDocWithInheritedClassAttr.py
new file mode 100644
index 000000000000..71701270e7fe
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderDocWithInheritedClassAttr.py
@@ -0,0 +1,7 @@
+class A(object):
+ __doc__ = "abc"
+
+class B(A):
+ def foo(self):
+ return __doc__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderSizeOf.py b/python/testData/resolve/ImplicitDunderSizeOf.py
new file mode 100644
index 000000000000..e53d68134d68
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderSizeOf.py
@@ -0,0 +1,4 @@
+class A:
+ def foo(self):
+ return __sizeof__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderSizeOfNewStyleClass.py b/python/testData/resolve/ImplicitDunderSizeOfNewStyleClass.py
new file mode 100644
index 000000000000..c0400c03bf45
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderSizeOfNewStyleClass.py
@@ -0,0 +1,4 @@
+class A(object):
+ def foo(self):
+ return __sizeof__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderSizeOfWithClassAttr.py b/python/testData/resolve/ImplicitDunderSizeOfWithClassAttr.py
new file mode 100644
index 000000000000..46fe0e7ccd6e
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderSizeOfWithClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ __sizeof__ = 15
+
+ def foo(self):
+ return __sizeof__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderSizeOfWithClassAttrNewStyleClass.py b/python/testData/resolve/ImplicitDunderSizeOfWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..3ed21284e59a
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderSizeOfWithClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ __sizeof__ = 15
+
+ def foo(self):
+ return __sizeof__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitDunderSizeOfWithInheritedClassAttr.py b/python/testData/resolve/ImplicitDunderSizeOfWithInheritedClassAttr.py
new file mode 100644
index 000000000000..34e70e535cf8
--- /dev/null
+++ b/python/testData/resolve/ImplicitDunderSizeOfWithInheritedClassAttr.py
@@ -0,0 +1,7 @@
+class A(object):
+ __sizeof__ = 4
+
+class B(A):
+ def foo(self):
+ return __sizeof__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitInheritedClassAttr.py b/python/testData/resolve/ImplicitInheritedClassAttr.py
new file mode 100644
index 000000000000..2c72252ac833
--- /dev/null
+++ b/python/testData/resolve/ImplicitInheritedClassAttr.py
@@ -0,0 +1,7 @@
+class A(object):
+ my_attr = 4
+
+class B(A):
+ def foo(self):
+ return my_attr
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitUndeclaredClassAttr.py b/python/testData/resolve/ImplicitUndeclaredClassAttr.py
new file mode 100644
index 000000000000..d1c52ff2b51d
--- /dev/null
+++ b/python/testData/resolve/ImplicitUndeclaredClassAttr.py
@@ -0,0 +1,4 @@
+class A:
+ def foo(self):
+ return my_attr
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/ImplicitUndeclaredClassAttrNewStyleClass.py b/python/testData/resolve/ImplicitUndeclaredClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..557ef92b6202
--- /dev/null
+++ b/python/testData/resolve/ImplicitUndeclaredClassAttrNewStyleClass.py
@@ -0,0 +1,4 @@
+class A(object):
+ def foo(self):
+ return my_attr
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InheritedClassAttrInDeclaration.py b/python/testData/resolve/InheritedClassAttrInDeclaration.py
new file mode 100644
index 000000000000..2b40795270fd
--- /dev/null
+++ b/python/testData/resolve/InheritedClassAttrInDeclaration.py
@@ -0,0 +1,6 @@
+class A(object):
+ my_attr = 17
+
+class B(A):
+ print(my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceClassAttr.py b/python/testData/resolve/InstanceClassAttr.py
new file mode 100644
index 000000000000..6cd541bb959f
--- /dev/null
+++ b/python/testData/resolve/InstanceClassAttr.py
@@ -0,0 +1,7 @@
+class A:
+ my_attr = 15
+
+
+a = A()
+print(a.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceClassAttrNewStyleClass.py b/python/testData/resolve/InstanceClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..4dd67f501a87
--- /dev/null
+++ b/python/testData/resolve/InstanceClassAttrNewStyleClass.py
@@ -0,0 +1,7 @@
+class A(object):
+ my_attr = 15
+
+
+a = A()
+print(a.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderClass.py b/python/testData/resolve/InstanceDunderClass.py
new file mode 100644
index 000000000000..3f671b0c854d
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderClass.py
@@ -0,0 +1,7 @@
+class A:
+ pass
+
+
+a = A()
+print(a.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderClassNewStyleClass.py b/python/testData/resolve/InstanceDunderClassNewStyleClass.py
new file mode 100644
index 000000000000..d64ab5e20ec1
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderClassNewStyleClass.py
@@ -0,0 +1,7 @@
+class A(object):
+ pass
+
+
+a = A()
+print(a.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderClassWithClassAttr.py b/python/testData/resolve/InstanceDunderClassWithClassAttr.py
new file mode 100644
index 000000000000..819e206ffab6
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderClassWithClassAttr.py
@@ -0,0 +1,7 @@
+class A:
+ __class__ = 15
+
+
+a = A()
+print(a.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderClassWithClassAttrNewStyleClass.py b/python/testData/resolve/InstanceDunderClassWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..a51fafbcb2a0
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderClassWithClassAttrNewStyleClass.py
@@ -0,0 +1,7 @@
+class A(object):
+ __class__ = 15
+
+
+a = A()
+print(a.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderClassWithInheritedClassAttr.py b/python/testData/resolve/InstanceDunderClassWithInheritedClassAttr.py
new file mode 100644
index 000000000000..c685bbd9ce87
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderClassWithInheritedClassAttr.py
@@ -0,0 +1,10 @@
+class A(object):
+ __class__ = 15
+
+class B(A):
+ pass
+
+
+b = B()
+print(b.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderDoc.py b/python/testData/resolve/InstanceDunderDoc.py
new file mode 100644
index 000000000000..04da49b0da7e
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderDoc.py
@@ -0,0 +1,7 @@
+class A:
+ pass
+
+
+a = A()
+print(a.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderDocNewStyleClass.py b/python/testData/resolve/InstanceDunderDocNewStyleClass.py
new file mode 100644
index 000000000000..7639c9ecb3a4
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderDocNewStyleClass.py
@@ -0,0 +1,7 @@
+class A(object):
+ pass
+
+
+a = A()
+print(a.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderDocWithClassAttr.py b/python/testData/resolve/InstanceDunderDocWithClassAttr.py
new file mode 100644
index 000000000000..b83622ea787d
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderDocWithClassAttr.py
@@ -0,0 +1,7 @@
+class A:
+ __doc__ = 15
+
+
+a = A()
+print(a.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderDocWithClassAttrNewStyleClass.py b/python/testData/resolve/InstanceDunderDocWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..8e71d90f7687
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderDocWithClassAttrNewStyleClass.py
@@ -0,0 +1,7 @@
+class A(object):
+ __doc__ = 15
+
+
+a = A()
+print(a.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderDocWithInheritedClassAttr.py b/python/testData/resolve/InstanceDunderDocWithInheritedClassAttr.py
new file mode 100644
index 000000000000..3fef6e9429dc
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderDocWithInheritedClassAttr.py
@@ -0,0 +1,10 @@
+class A(object):
+ __doc__ = 16
+
+class B(A):
+ pass
+
+
+b = B()
+print(b.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderSizeOf.py b/python/testData/resolve/InstanceDunderSizeOf.py
new file mode 100644
index 000000000000..9a34e386d031
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderSizeOf.py
@@ -0,0 +1,7 @@
+class A:
+ pass
+
+
+a = A()
+print(a.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderSizeOfNewStyleClass.py b/python/testData/resolve/InstanceDunderSizeOfNewStyleClass.py
new file mode 100644
index 000000000000..58611a25ba1f
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderSizeOfNewStyleClass.py
@@ -0,0 +1,7 @@
+class A(object):
+ pass
+
+
+a = A()
+print(a.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderSizeOfWithClassAttr.py b/python/testData/resolve/InstanceDunderSizeOfWithClassAttr.py
new file mode 100644
index 000000000000..7352e5b9b00d
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderSizeOfWithClassAttr.py
@@ -0,0 +1,7 @@
+class A:
+ __sizeof__ = 15
+
+
+a = A()
+print(a.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderSizeOfWithClassAttrNewStyleClass.py b/python/testData/resolve/InstanceDunderSizeOfWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..3f89b2b1c9ba
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderSizeOfWithClassAttrNewStyleClass.py
@@ -0,0 +1,7 @@
+class A(object):
+ __sizeof__ = 15
+
+
+a = A()
+print(a.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceDunderSizeOfWithInheritedClassAttr.py b/python/testData/resolve/InstanceDunderSizeOfWithInheritedClassAttr.py
new file mode 100644
index 000000000000..2e79cdfbf9ea
--- /dev/null
+++ b/python/testData/resolve/InstanceDunderSizeOfWithInheritedClassAttr.py
@@ -0,0 +1,10 @@
+class A(object):
+ __sizeof__ = 17
+
+class B(A):
+ pass
+
+
+b = B()
+print(b.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceInheritedClassAttr.py b/python/testData/resolve/InstanceInheritedClassAttr.py
new file mode 100644
index 000000000000..5620fe5d471d
--- /dev/null
+++ b/python/testData/resolve/InstanceInheritedClassAttr.py
@@ -0,0 +1,10 @@
+class A(object):
+ my_attr = 17
+
+class B(A):
+ pass
+
+
+b = B()
+print(b.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceUndeclaredClassAttr.py b/python/testData/resolve/InstanceUndeclaredClassAttr.py
new file mode 100644
index 000000000000..a2d386057902
--- /dev/null
+++ b/python/testData/resolve/InstanceUndeclaredClassAttr.py
@@ -0,0 +1,7 @@
+class A:
+ pass
+
+
+a = A()
+print(a.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/InstanceUndeclaredClassAttrNewStyleClass.py b/python/testData/resolve/InstanceUndeclaredClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..72dc3f781122
--- /dev/null
+++ b/python/testData/resolve/InstanceUndeclaredClassAttrNewStyleClass.py
@@ -0,0 +1,7 @@
+class A(object):
+ pass
+
+
+a = A()
+print(a.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/LocalDunderClass.py b/python/testData/resolve/LocalDunderClass.py
new file mode 100644
index 000000000000..01f4adf4e65c
--- /dev/null
+++ b/python/testData/resolve/LocalDunderClass.py
@@ -0,0 +1,5 @@
+class A:
+ def foo(self):
+ __class__ = 16
+ return __class__
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeClassAttr.py b/python/testData/resolve/TypeClassAttr.py
new file mode 100644
index 000000000000..b24b8608b08a
--- /dev/null
+++ b/python/testData/resolve/TypeClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ my_attr = 15
+
+
+print(A.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeClassAttrNewStyleClass.py b/python/testData/resolve/TypeClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..5fef732aff6d
--- /dev/null
+++ b/python/testData/resolve/TypeClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ my_attr = 15
+
+
+print(A.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderClass.py b/python/testData/resolve/TypeDunderClass.py
new file mode 100644
index 000000000000..9dc04760f400
--- /dev/null
+++ b/python/testData/resolve/TypeDunderClass.py
@@ -0,0 +1,6 @@
+class A:
+ pass
+
+
+print(A.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderClassNewStyleClass.py b/python/testData/resolve/TypeDunderClassNewStyleClass.py
new file mode 100644
index 000000000000..2793517a5778
--- /dev/null
+++ b/python/testData/resolve/TypeDunderClassNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ pass
+
+
+print(A.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderClassWithClassAttr.py b/python/testData/resolve/TypeDunderClassWithClassAttr.py
new file mode 100644
index 000000000000..3696e7afca7d
--- /dev/null
+++ b/python/testData/resolve/TypeDunderClassWithClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ __class__ = 15
+
+
+print(A.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderClassWithClassAttrNewStyleClass.py b/python/testData/resolve/TypeDunderClassWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..402f7f3ee014
--- /dev/null
+++ b/python/testData/resolve/TypeDunderClassWithClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ __class__ = 15
+
+
+print(A.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderClassWithInheritedClassAttr.py b/python/testData/resolve/TypeDunderClassWithInheritedClassAttr.py
new file mode 100644
index 000000000000..907d30dddf17
--- /dev/null
+++ b/python/testData/resolve/TypeDunderClassWithInheritedClassAttr.py
@@ -0,0 +1,9 @@
+class A(object):
+ __class__ = 17
+
+class B(A):
+ pass
+
+
+print(B.__class__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderDoc.py b/python/testData/resolve/TypeDunderDoc.py
new file mode 100644
index 000000000000..64c531c8b0ed
--- /dev/null
+++ b/python/testData/resolve/TypeDunderDoc.py
@@ -0,0 +1,6 @@
+class A:
+ pass
+
+
+print(A.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderDocNewStyleClass.py b/python/testData/resolve/TypeDunderDocNewStyleClass.py
new file mode 100644
index 000000000000..2c71c76dbc5c
--- /dev/null
+++ b/python/testData/resolve/TypeDunderDocNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ pass
+
+
+print(A.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderDocWithClassAttr.py b/python/testData/resolve/TypeDunderDocWithClassAttr.py
new file mode 100644
index 000000000000..8440e5ded58e
--- /dev/null
+++ b/python/testData/resolve/TypeDunderDocWithClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ __doc__ = 16
+
+
+print(A.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderDocWithClassAttrNewStyleClass.py b/python/testData/resolve/TypeDunderDocWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..a06a2e5e863a
--- /dev/null
+++ b/python/testData/resolve/TypeDunderDocWithClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ __doc__ = 16
+
+
+print(A.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderDocWithInheritedClassAttr.py b/python/testData/resolve/TypeDunderDocWithInheritedClassAttr.py
new file mode 100644
index 000000000000..77211eb54174
--- /dev/null
+++ b/python/testData/resolve/TypeDunderDocWithInheritedClassAttr.py
@@ -0,0 +1,9 @@
+class A(object):
+ __doc__ = 17
+
+class B(A):
+ pass
+
+
+print(B.__doc__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderSizeOf.py b/python/testData/resolve/TypeDunderSizeOf.py
new file mode 100644
index 000000000000..a301afe2804c
--- /dev/null
+++ b/python/testData/resolve/TypeDunderSizeOf.py
@@ -0,0 +1,6 @@
+class A:
+ pass
+
+
+print(A.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderSizeOfNewStyleClass.py b/python/testData/resolve/TypeDunderSizeOfNewStyleClass.py
new file mode 100644
index 000000000000..711370afac64
--- /dev/null
+++ b/python/testData/resolve/TypeDunderSizeOfNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ pass
+
+
+print(A.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderSizeOfWithClassAttr.py b/python/testData/resolve/TypeDunderSizeOfWithClassAttr.py
new file mode 100644
index 000000000000..8c6ef22596fe
--- /dev/null
+++ b/python/testData/resolve/TypeDunderSizeOfWithClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ __sizeof__ = 16
+
+
+print(A.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderSizeOfWithClassAttrNewStyleClass.py b/python/testData/resolve/TypeDunderSizeOfWithClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..564f57a45a67
--- /dev/null
+++ b/python/testData/resolve/TypeDunderSizeOfWithClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ __sizeof__ = 16
+
+
+print(A.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeDunderSizeOfWithInheritedClassAttr.py b/python/testData/resolve/TypeDunderSizeOfWithInheritedClassAttr.py
new file mode 100644
index 000000000000..4d70493199b3
--- /dev/null
+++ b/python/testData/resolve/TypeDunderSizeOfWithInheritedClassAttr.py
@@ -0,0 +1,9 @@
+class A(object):
+ __sizeof__ = 17
+
+class B(A):
+ pass
+
+
+print(B.__sizeof__)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeInheritedClassAttr.py b/python/testData/resolve/TypeInheritedClassAttr.py
new file mode 100644
index 000000000000..28b4092ceb6e
--- /dev/null
+++ b/python/testData/resolve/TypeInheritedClassAttr.py
@@ -0,0 +1,9 @@
+class A(object):
+ my_attr = 17
+
+class B(A):
+ pass
+
+
+print(B.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeUndeclaredClassAttr.py b/python/testData/resolve/TypeUndeclaredClassAttr.py
new file mode 100644
index 000000000000..91cfa64f5eae
--- /dev/null
+++ b/python/testData/resolve/TypeUndeclaredClassAttr.py
@@ -0,0 +1,6 @@
+class A:
+ pass
+
+
+print(A.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/TypeUndeclaredClassAttrNewStyleClass.py b/python/testData/resolve/TypeUndeclaredClassAttrNewStyleClass.py
new file mode 100644
index 000000000000..3f2e26f1df93
--- /dev/null
+++ b/python/testData/resolve/TypeUndeclaredClassAttrNewStyleClass.py
@@ -0,0 +1,6 @@
+class A(object):
+ pass
+
+
+print(A.my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/UndeclaredClassAttrInDeclaration.py b/python/testData/resolve/UndeclaredClassAttrInDeclaration.py
new file mode 100644
index 000000000000..df3a528fd108
--- /dev/null
+++ b/python/testData/resolve/UndeclaredClassAttrInDeclaration.py
@@ -0,0 +1,3 @@
+class A:
+ print(my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/UndeclaredClassAttrInDeclarationNewStyleClass.py b/python/testData/resolve/UndeclaredClassAttrInDeclarationNewStyleClass.py
new file mode 100644
index 000000000000..cf1bce79bcf8
--- /dev/null
+++ b/python/testData/resolve/UndeclaredClassAttrInDeclarationNewStyleClass.py
@@ -0,0 +1,3 @@
+class A(object):
+ print(my_attr)
+# ][
\ No newline at end of file
diff --git a/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg/__init__.py b/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg/__init__.py
new file mode 100644
index 000000000000..3074a5c357d1
--- /dev/null
+++ b/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg/__init__.py
@@ -0,0 +1,2 @@
+import mod
+ ][
\ No newline at end of file
diff --git a/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg/mod.py b/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg/mod.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg2/__init__.py b/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg2/__init__.py
new file mode 100644
index 000000000000..3074a5c357d1
--- /dev/null
+++ b/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg2/__init__.py
@@ -0,0 +1,2 @@
+import mod
+ ][
\ No newline at end of file
diff --git a/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg2/mod.py b/python/testData/resolve/multiFile/ambiguousImplicitRelativeImport/pkg2/mod.py
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/python/testSrc/com/jetbrains/python/Py3ResolveTest.java b/python/testSrc/com/jetbrains/python/Py3ResolveTest.java
index 9edc7db4230c..4a7458f2ecad 100644
--- a/python/testSrc/com/jetbrains/python/Py3ResolveTest.java
+++ b/python/testSrc/com/jetbrains/python/Py3ResolveTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -17,11 +17,15 @@ package com.jetbrains.python;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.LightProjectDescriptor;
import com.jetbrains.python.fixtures.PyResolveTestCase;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.LanguageLevel;
+import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
+import com.jetbrains.python.psi.PyTargetExpression;
+import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
/**
@@ -60,4 +64,297 @@ public class Py3ResolveTest extends PyResolveTestCase {
public void testTrueDiv() {
assertResolvesTo(PyFunction.class, "__truediv__");
}
+
+ // PY-13734
+ public void testImplicitDunderClass() {
+ assertResolvesTo(PyClass.class, "A");
+ }
+
+ public void testImplicitDunderDoc() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testImplicitDunderSizeOf() {
+ assertUnresolved();
+ }
+
+ public void testImplicitUndeclaredClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testImplicitDunderClassWithClassAttr() {
+ assertResolvesTo(PyClass.class, "A");
+ }
+
+ public void testImplicitDunderDocWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testImplicitDunderSizeOfWithClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testImplicitClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testImplicitDunderClassWithInheritedClassAttr() {
+ assertResolvesTo(PyClass.class, "B");
+ }
+
+ public void testImplicitDunderDocWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testImplicitDunderSizeOfWithInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testImplicitInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testInstanceDunderClass() {
+ assertResolvesTo(PyClass.class, "A");
+ }
+
+ public void testInstanceDunderDoc() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testInstanceDunderSizeOf() {
+ final PyFunction expression = assertResolvesTo(PyFunction.class, PyNames.SIZEOF);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testInstanceUndeclaredClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testInstanceDunderClassWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceDunderDocWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceDunderSizeOfWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testInstanceDunderClassWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceDunderDocWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testInstanceDunderSizeOfWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testLocalDunderClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyFunction function = PsiTreeUtil.getParentOfType(expression, PyFunction.class);
+ assertNotNull(function);
+ assertEquals("foo", function.getName());
+ }
+
+ // PY-13734
+ public void testTypeDunderClass() {
+ assertResolvesTo(PyClass.class, "type");
+ }
+
+ public void testTypeDunderDoc() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testTypeDunderSizeOf() {
+ final PyFunction expression = assertResolvesTo(PyFunction.class, PyNames.SIZEOF);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testTypeUndeclaredClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testTypeDunderClassWithClassAttr() {
+ assertResolvesTo(PyClass.class, "type");
+ }
+
+ public void testTypeDunderDocWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeDunderSizeOfWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testTypeDunderClassWithInheritedClassAttr() {
+ assertResolvesTo(PyClass.class, "type");
+ }
+
+ public void testTypeDunderDocWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testTypeDunderSizeOfWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclaration() {
+ assertUnresolved();
+ }
+
+ public void testDunderDocInDeclaration() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testDunderSizeOfInDeclaration() {
+ assertUnresolved();
+ }
+
+ public void testUndeclaredClassAttrInDeclaration() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclarationWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testDunderDocInDeclarationWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testDunderSizeOfInDeclarationWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testClassAttrInDeclaration() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclarationWithInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testDunderDocInDeclarationWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE_3K, expression.getContainingFile().getName());
+ }
+
+ public void testDunderSizeOfInDeclarationWithInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testInheritedClassAttrInDeclaration() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclarationInsideFunction() {
+ assertUnresolved();
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java
index c0294660b7ff..6d61dfaed139 100644
--- a/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java
+++ b/python/testSrc/com/jetbrains/python/PyMultiFileResolveTest.java
@@ -18,6 +18,8 @@ package com.jetbrains.python;
import com.google.common.collect.Lists;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiFileImpl;
@@ -26,10 +28,14 @@ import com.jetbrains.python.fixtures.PyMultiFileResolveTestCase;
import com.jetbrains.python.fixtures.PyResolveTestCase;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.PyPsiUtils;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
+import java.util.Arrays;
import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
* @author yole
@@ -459,4 +465,29 @@ public class PyMultiFileResolveTest extends PyMultiFileResolveTestCase {
}
}
}
+
+ // PY-19989
+ public void testAmbiguousImplicitRelativeImport() {
+ prepareTestDirectory();
+ assertSameElements(doMultiResolveAndGetFileUrls("pkg2/__init__.py"), "pkg2/mod.py");
+ assertSameElements(doMultiResolveAndGetFileUrls("pkg/__init__.py"), "pkg/mod.py");
+ }
+
+ @NotNull
+ private List doMultiResolveAndGetFileUrls(@NotNull String currentFilePath) {
+ myFixture.configureByFile(currentFilePath);
+ final PsiReference reference = PyResolveTestCase.findReferenceByMarker(myFixture.getFile());
+ final VirtualFile root = ModuleRootManager.getInstance(myFixture.getModule()).getSourceRoots()[0];
+
+ final Stream fileSystemItems;
+ if (reference instanceof PsiPolyVariantReference) {
+ final ResolveResult[] results = ((PsiPolyVariantReference)reference).multiResolve(false);
+ fileSystemItems = Arrays.stream(results).map(r -> PyPsiUtils.getFileSystemItem(r.getElement()));
+ }
+ else {
+ fileSystemItems = Stream.of(PyPsiUtils.getFileSystemItem(reference.resolve()));
+ }
+ return fileSystemItems.map(f -> VfsUtilCore.getRelativeLocation(f.getVirtualFile(), root)).collect(Collectors.toList());
+
+ }
}
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/PyResolveTest.java b/python/testSrc/com/jetbrains/python/PyResolveTest.java
index 0ba634018415..ea002c2e840b 100644
--- a/python/testSrc/com/jetbrains/python/PyResolveTest.java
+++ b/python/testSrc/com/jetbrains/python/PyResolveTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -26,6 +26,7 @@ import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.documentation.docstrings.DocStringFormat;
import com.jetbrains.python.fixtures.PyResolveTestCase;
import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyPsiUtils;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
import com.jetbrains.python.psi.resolve.ImportedResolveResult;
@@ -406,7 +407,7 @@ public class PyResolveTest extends PyResolveTestCase {
public void testBuiltinVsClassMember() { // PY-1654
final PyFunction pyFunction = assertResolvesTo(PyFunction.class, "eval");
- assertEquals("__builtin__.py", pyFunction.getContainingFile().getName());
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, pyFunction.getContainingFile().getName());
}
public void testLambdaToClass() { // PY-2182
@@ -740,4 +741,481 @@ public class PyResolveTest extends PyResolveTestCase {
assertResolvesTo(PyTargetExpression.class, "foo");
}
+ // PY-13734
+ public void testImplicitDunderClass() {
+ assertUnresolved();
+ }
+
+ public void testImplicitDunderDoc() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testImplicitDunderSizeOf() {
+ assertUnresolved();
+ }
+
+ public void testImplicitUndeclaredClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testImplicitDunderClassNewStyleClass() {
+ assertUnresolved();
+ }
+
+ public void testImplicitDunderDocNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testImplicitDunderSizeOfNewStyleClass() {
+ assertUnresolved();
+ }
+
+ public void testImplicitUndeclaredClassAttrNewStyleClass() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testImplicitDunderClassWithClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testImplicitDunderDocWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testImplicitDunderSizeOfWithClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testImplicitClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testImplicitDunderClassWithClassAttrNewStyleClass() {
+ assertUnresolved();
+ }
+
+ public void testImplicitDunderDocWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testImplicitDunderSizeOfWithClassAttrNewStyleClass() {
+ assertUnresolved();
+ }
+
+ public void testImplicitClassAttrNewStyleClass() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testImplicitDunderClassWithInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testImplicitDunderDocWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testImplicitDunderSizeOfWithInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testImplicitInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testInstanceDunderClass() {
+ assertResolvesTo(PyClass.class, "A");
+ }
+
+ public void testInstanceDunderDoc() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testInstanceDunderSizeOf() {
+ assertUnresolved();
+ }
+
+ public void testInstanceUndeclaredClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testInstanceDunderClassNewStyleClass() {
+ assertResolvesTo(PyClass.class, "A");
+ }
+
+ public void testInstanceDunderDocNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testInstanceDunderSizeOfNewStyleClass() {
+ final PyFunction expression = assertResolvesTo(PyFunction.class, PyNames.SIZEOF);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testInstanceUndeclaredClassAttrNewStyleClass() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testInstanceDunderClassWithClassAttr() {
+ assertResolvesTo(PyClass.class, "A");
+ }
+
+ public void testInstanceDunderDocWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceDunderSizeOfWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testInstanceDunderClassWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceDunderDocWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceDunderSizeOfWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testInstanceDunderClassWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceDunderDocWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testInstanceDunderSizeOfWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testInstanceInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testLocalDunderClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyFunction function = PsiTreeUtil.getParentOfType(expression, PyFunction.class);
+ assertNotNull(function);
+ assertEquals("foo", function.getName());
+ }
+
+ // PY-13734
+ public void testTypeDunderClass() {
+ assertUnresolved();
+ }
+
+ public void testTypeDunderDoc() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testTypeDunderSizeOf() {
+ assertUnresolved();
+ }
+
+ public void testTypeUndeclaredClassAttr() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testTypeDunderClassNewStyleClass() {
+ assertResolvesTo(PyClass.class, "type");
+ }
+
+ public void testTypeDunderDocNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testTypeDunderSizeOfNewStyleClass() {
+ final PyFunction expression = assertResolvesTo(PyFunction.class, PyNames.SIZEOF);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testTypeUndeclaredClassAttrNewStyleClass() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testTypeDunderClassWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeDunderDocWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeDunderSizeOfWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testTypeDunderClassWithClassAttrNewStyleClass() {
+ assertResolvesTo(PyClass.class, "type");
+ }
+
+ public void testTypeDunderDocWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeDunderSizeOfWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testTypeDunderClassWithInheritedClassAttr() {
+ assertResolvesTo(PyClass.class, "type");
+ }
+
+ public void testTypeDunderDocWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testTypeDunderSizeOfWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testTypeInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclaration() {
+ assertUnresolved();
+ }
+
+ public void testDunderDocInDeclaration() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testDunderSizeOfInDeclaration() {
+ assertUnresolved();
+ }
+
+ public void testUndeclaredClassAttrInDeclaration() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclarationNewStyleClass() {
+ assertUnresolved();
+ }
+
+ public void testDunderDocInDeclarationNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testDunderSizeOfInDeclarationNewStyleClass() {
+ assertUnresolved();
+ }
+
+ public void testUndeclaredClassAttrInDeclarationNewStyleClass() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclarationWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testDunderDocInDeclarationWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testDunderSizeOfInDeclarationWithClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testClassAttrInDeclaration() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclarationWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.__CLASS__);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testDunderDocInDeclarationWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testDunderSizeOfInDeclarationWithClassAttrNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.SIZEOF);
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ public void testClassAttrInDeclarationNewStyleClass() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, "my_attr");
+
+ final PyClass cls = expression.getContainingClass();
+ assertNotNull(cls);
+ assertEquals("A", cls.getName());
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclarationWithInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testDunderDocInDeclarationWithInheritedClassAttr() {
+ final PyTargetExpression expression = assertResolvesTo(PyTargetExpression.class, PyNames.DOC);
+ assertEquals(PyBuiltinCache.BUILTIN_FILE, expression.getContainingFile().getName());
+ }
+
+ public void testDunderSizeOfInDeclarationWithInheritedClassAttr() {
+ assertUnresolved();
+ }
+
+ public void testInheritedClassAttrInDeclaration() {
+ assertUnresolved();
+ }
+
+ // PY-13734
+ public void testDunderClassInDeclarationInsideFunction() {
+ assertUnresolved();
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/fixtures/PyResolveTestCase.java b/python/testSrc/com/jetbrains/python/fixtures/PyResolveTestCase.java
index 99d5a35a43d5..953a21ee1313 100644
--- a/python/testSrc/com/jetbrains/python/fixtures/PyResolveTestCase.java
+++ b/python/testSrc/com/jetbrains/python/fixtures/PyResolveTestCase.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -89,6 +89,17 @@ public abstract class PyResolveTestCase extends PyTestCase {
return assertResolveResult(element, aClass, name, containingFilePath);
}
+ protected void assertUnresolved() {
+ final PsiElement element;
+ try {
+ element = doResolve();
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ assertNull(element);
+ }
+
public static T assertResolveResult(PsiElement element,
Class aClass,
String name) {
diff --git a/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java
index dc43bc8b5f3a..0814f810f743 100644
--- a/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java
@@ -136,4 +136,9 @@ public class Py3UnresolvedReferencesInspectionTest extends PyTestCase {
public void testDecodeBytesAfterSlicing() {
doTest();
}
+
+ // PY-13734
+ public void testDunderClass() {
+ doTest();
+ }
}
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
index e869d715e5fe..0f0065f449ad 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyCompatibilityInspectionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -167,8 +167,17 @@ public class PyCompatibilityInspectionTest extends PyTestCase {
doTest(LanguageLevel.PYTHON35);
}
+ // PY-19523
+ public void testBz2Module() {
+ doTest();
+ }
+
+ public void testUnderscoreBz2Module() {
+ doTest();
+ }
+
private void doTest(@NotNull LanguageLevel level) {
- runWithLanguageLevel(level, () -> doTest());
+ runWithLanguageLevel(level, this::doTest);
}
private void doTest() {
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
index 471e48ecac7a..3b2548bddaeb 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2016 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.
@@ -234,17 +234,17 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
// PY-6745
public void testQualNameAttribute() {
- runWithLanguageLevel(LanguageLevel.PYTHON33, () -> doTest());
+ runWithLanguageLevel(LanguageLevel.PYTHON33, this::doTest);
}
// PY-7389
public void testComprehensionScope27() {
- runWithLanguageLevel(LanguageLevel.PYTHON27, () -> doTest());
+ runWithLanguageLevel(LanguageLevel.PYTHON27, this::doTest);
}
// PY-7389
public void testComprehensionScope33() {
- runWithLanguageLevel(LanguageLevel.PYTHON33, () -> doTest());
+ runWithLanguageLevel(LanguageLevel.PYTHON33, this::doTest);
}
// PY-7516
@@ -724,6 +724,11 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
doTest();
}
+ // PY-13734
+ public void testDunderClass() {
+ doTest();
+ }
+
@NotNull
@Override
protected Class extends PyInspection> getInspectionClass() {
diff --git a/python/testSrc/com/jetbrains/python/quickFixes/AddImportQuickFixTest.java b/python/testSrc/com/jetbrains/python/quickFixes/AddImportQuickFixTest.java
index 969b7cee4028..7eef13fc19a5 100644
--- a/python/testSrc/com/jetbrains/python/quickFixes/AddImportQuickFixTest.java
+++ b/python/testSrc/com/jetbrains/python/quickFixes/AddImportQuickFixTest.java
@@ -17,6 +17,7 @@ package com.jetbrains.python.quickFixes;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.ex.QuickFixWrapper;
+import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyQuickFixTestCase;
import com.jetbrains.python.codeInsight.imports.AutoImportQuickFix;
@@ -26,7 +27,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
-import java.util.function.Consumer;
/**
* @author Mikhail Golubev
@@ -43,6 +43,17 @@ public class AddImportQuickFixTest extends PyQuickFixTestCase {
final List candidates = fix.getCandidates();
final List names = ContainerUtil.map(candidates, c -> c.getPresentableText("join"));
assertSameElements(names, "os.path.join(path, *paths)");
+ return true;
+ });
+ }
+
+ // PY-19975
+ public void testCanonicalNamesFromHigherLevelPackage() {
+ doMultiFileAutoImportTest("Import", fix -> {
+ final List candidates = fix.getCandidates();
+ final List names = ContainerUtil.map(candidates, c -> c.getPresentableText("MyClass"));
+ assertSameElements(names, "foo.MyClass", "bar.MyClass");
+ return true;
});
}
@@ -50,7 +61,7 @@ public class AddImportQuickFixTest extends PyQuickFixTestCase {
doMultiFileAutoImportTest(hintPrefix, null);
}
- private void doMultiFileAutoImportTest(@NotNull String hintPrefix, @Nullable Consumer checkQuickfix) {
+ private void doMultiFileAutoImportTest(@NotNull String hintPrefix, @Nullable Processor checkQuickfix) {
myFixture.copyDirectoryToProject(getTestName(true), "");
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
final String entryPoint = "main";
@@ -62,10 +73,13 @@ public class AddImportQuickFixTest extends PyQuickFixTestCase {
});
assertNotNull("Auto import quick fix starting with '" + hintPrefix + "' wasn't found", intention);
final AutoImportQuickFix quickfix = (AutoImportQuickFix)((QuickFixWrapper)intention).getFix();
+ boolean applyFix = true;
if (checkQuickfix != null) {
- checkQuickfix.accept(quickfix);
+ applyFix = checkQuickfix.process(quickfix);
+ }
+ if (applyFix) {
+ myFixture.launchAction(intention);
+ myFixture.checkResultByFile(getTestName(true) + "/" + entryPoint + "_after.py", true);
}
- myFixture.launchAction(intention);
- myFixture.checkResultByFile(getTestName(true) + "/" + entryPoint + "_after.py", true);
}
}
]