mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+2
-2
@@ -1,11 +1,11 @@
|
||||
<component name="libraryTable">
|
||||
<library name="asm5">
|
||||
<library name="ASM">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/asm-all.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/src/asm-src.zip!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<property name="src.dir" value="${basedir}/src"/>
|
||||
<property name="out.dir" value="${basedir}/out"/>
|
||||
<property name="src.zip" value="${basedir}/asm5-src.zip"/>
|
||||
<property name="src.zip" value="${basedir}/asm-src.zip"/>
|
||||
<property name="out.jar" value="${basedir}/asm-all.jar"/>
|
||||
|
||||
<target name="check">
|
||||
@@ -41,6 +41,7 @@
|
||||
<target name="patch" depends="unpack">
|
||||
<patch dir="${src.dir}" strip="0" patchfile="1_version_check.patch" failonerror="true"/>
|
||||
<patch dir="${src.dir}" strip="0" patchfile="2_coverage_fix.patch" failonerror="true"/>
|
||||
<delete file="${src.dir}/org/objectweb/asm/optimizer/ModuleInfoBndPlugin.java" quiet="true"/>
|
||||
</target>
|
||||
|
||||
<target name="repackage" depends="patch">
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="Groovy" level="project" />
|
||||
<orderEntry type="library" exported="" name="Ant" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="asm5" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="ASM" level="project" />
|
||||
<orderEntry type="library" exported="" scope="RUNTIME" name="cli-parser" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="JDOM" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Netty" level="project" />
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="JDOM" level="project" />
|
||||
<orderEntry type="module" module-name="forms_rt" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="JUnit3" level="project" />
|
||||
<orderEntry type="library" name="jgoodies-forms" level="project" />
|
||||
<orderEntry type="module" module-name="instrumentation-util" exported="" />
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<orderEntry type="library" name="Trove4j" level="project" />
|
||||
<orderEntry type="module" module-name="java-runtime" />
|
||||
<orderEntry type="module" module-name="instrumentation-util" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="jsp-openapi" />
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="IDEA jdk" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -10,7 +10,7 @@
|
||||
<orderEntry type="library" name="Ant" level="project" />
|
||||
<orderEntry type="module" module-name="forms-compiler" />
|
||||
<orderEntry type="module" module-name="forms_rt" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="module" module-name="instrumentation-util" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
@@ -165,5 +165,4 @@
|
||||
<option name="useAlternate" value="false" />
|
||||
</LanguageOptions>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -17,7 +17,6 @@
|
||||
<orderEntry type="module" module-name="java-analysis-api" exported="" />
|
||||
<orderEntry type="module" module-name="resources-en" />
|
||||
<orderEntry type="module" module-name="xml-psi-impl" />
|
||||
<orderEntry type="library" exported="" name="asm5" level="project" />
|
||||
<orderEntry type="library" exported="" name="ASM" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
+6
-8
@@ -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<VirtualFile> 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());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -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 <code>#ref</code> in @Immutable class #loc");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool {
|
||||
List<EntryPoint> deadCodeAddIns = new ArrayList<EntryPoint>(extensions.length);
|
||||
for (EntryPoint entryPoint : extensions) {
|
||||
try {
|
||||
deadCodeAddIns.add(entryPoint);
|
||||
deadCodeAddIns.add(entryPoint.clone());
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<orderEntry type="module" module-name="jps-model-impl" />
|
||||
<orderEntry type="module" module-name="java-analysis-impl" exported="" />
|
||||
<orderEntry type="module" module-name="external-system-api" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
<orderEntry type="library" name="Xerces" level="project" />
|
||||
<orderEntry type="library" name="Velocity" level="project" />
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
<orderEntry type="module" module-name="java-psi-api" exported="" />
|
||||
<orderEntry type="module" module-name="core-impl" exported="" />
|
||||
<orderEntry type="module" module-name="resources-en" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="library" name="Guava" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -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
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
<orderEntry type="library" name="Velocity" level="project" />
|
||||
<orderEntry type="module" module-name="java-i18n" exported="" />
|
||||
<orderEntry type="module" module-name="compiler-impl" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="module" module-name="instrumentation-util" />
|
||||
<orderEntry type="library" name="Groovy" level="project" />
|
||||
<orderEntry type="module" module-name="IntelliLang-java" scope="RUNTIME" />
|
||||
|
||||
+1
-1
@@ -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"); }
|
||||
@@ -8,6 +8,7 @@
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.ElementToArrayConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.ThreadLocalConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.LongAdderConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.VoidConversionRule"/>
|
||||
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaOptionalConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaFluentIterableConversionRule"/>
|
||||
|
||||
+84
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<java.lang.String>", null));
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
Types:
|
||||
PsiMethod:toVoidMethod : void
|
||||
PsiMethodCallExpression:toVoidMethod() : void
|
||||
|
||||
Conversions:
|
||||
|
||||
New expression type changes:
|
||||
Fails:
|
||||
"" + String.valueOf(999)->void
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Test {
|
||||
|
||||
public void toVoidMethod() {
|
||||
int j = 0;
|
||||
return "" + String.valueOf(999);
|
||||
}
|
||||
|
||||
public void main(String[] args) {
|
||||
toVoidMethod();
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Test {
|
||||
|
||||
public String toVoidMethod() {
|
||||
int j = 0;
|
||||
return "" + String.valueOf(999);
|
||||
}
|
||||
|
||||
public void main(String[] args) {
|
||||
toVoidMethod();
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<orderEntry type="module" module-name="forms_rt" />
|
||||
<orderEntry type="module" module-name="forms-compiler" />
|
||||
<orderEntry type="module" module-name="instrumentation-util" />
|
||||
<orderEntry type="library" exported="" name="asm5" level="project" />
|
||||
<orderEntry type="library" exported="" name="ASM" level="project" />
|
||||
<orderEntry type="library" name="JDOM" level="project" />
|
||||
<orderEntry type="library" name="NanoXML" level="project" />
|
||||
<orderEntry type="library" name="jgoodies-forms" level="project" />
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-6
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -2003,6 +2003,7 @@ public class FileBasedIndexImpl extends FileBasedIndex {
|
||||
|
||||
private UnindexedFilesFinder(@Nullable ProgressIndicator indicator) {
|
||||
myProgressIndicator = indicator;
|
||||
if (!myInitialized) waitUntilIndicesAreInitialized();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@ public abstract class ServerType<C extends ServerConfiguration> {
|
||||
@NotNull
|
||||
public abstract String getPresentableName();
|
||||
|
||||
@NotNull
|
||||
public String getHelpTopic() {
|
||||
return "reference.settings.clouds";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract Icon getIcon();
|
||||
|
||||
|
||||
+1
-1
@@ -166,7 +166,7 @@ public class SingleRemoteServerConfigurable extends NamedConfigurable<RemoteServ
|
||||
@Nullable
|
||||
@Override
|
||||
public String getHelpTopic() {
|
||||
return HELP_TOPIC_ID;
|
||||
return myServer.getType().getHelpTopic();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -121,7 +121,7 @@ public class Restarter {
|
||||
public void consume(List<String> 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<List<String>> argumentsBuilder) throws IOException {
|
||||
List<String> commands = new ArrayList<String>();
|
||||
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() {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="module" module-name="core-api" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
@@ -19,5 +19,4 @@
|
||||
<orderEntry type="module" module-name="openapi" />
|
||||
<orderEntry type="module" module-name="compiler-impl" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
+52
-39
@@ -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<Boolean> 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<Boolean> 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);
|
||||
}
|
||||
}
|
||||
+62
-10
@@ -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();
|
||||
|
||||
+18
-3
@@ -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,
|
||||
|
||||
@@ -150,6 +150,7 @@ public class TooBroadScope
|
||||
}
|
||||
|
||||
private final String[] EMPTY = {};
|
||||
private final String[] ONE = {"one"};
|
||||
void abc() {
|
||||
String[] <warning descr="Scope of variable 'strings' is too broad">strings</warning> = EMPTY;
|
||||
System.out.println();
|
||||
@@ -160,5 +161,41 @@ public class TooBroadScope
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
System.out.println(list);
|
||||
|
||||
String[] <warning descr="Scope of variable 'ss' is too broad">ss</warning> = new String[10];
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
System.out.println(ss);
|
||||
|
||||
String[] <warning descr="Scope of variable 'ss2' is too broad">ss2</warning> = new String[] {""};
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
System.out.println(ss2);
|
||||
|
||||
String[] <warning descr="Scope of variable 'ss3' is too broad">ss3</warning> = {};
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
System.out.println(ss3);
|
||||
|
||||
String[] ss3a = {ONE[0]};
|
||||
backgroundAction();
|
||||
System.out.println();
|
||||
System.out.println(ss3a);
|
||||
|
||||
List<String> 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));
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="compiler-impl" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="module" module-name="RegExpSupport" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
<orderEntry type="module" module-name="java-impl" />
|
||||
@@ -22,5 +22,4 @@
|
||||
<setting name="state" value="1" />
|
||||
</Base>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -10,7 +10,7 @@
|
||||
<orderEntry type="module" module-name="platform-impl" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="xml" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="module" module-name="RegExpSupport" />
|
||||
<orderEntry type="module" module-name="xpath" />
|
||||
<orderEntry type="module" module-name="platform-api" />
|
||||
@@ -22,5 +22,4 @@
|
||||
<setting name="state" value="1" />
|
||||
</Base>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -12,7 +12,7 @@
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="module" module-name="extensions" />
|
||||
<orderEntry type="module" module-name="annotations" />
|
||||
<orderEntry type="library" exported="" name="asm5" level="project" />
|
||||
<orderEntry type="library" exported="" name="ASM" level="project" />
|
||||
<orderEntry type="library" exported="" name="Coverage" level="project" />
|
||||
<orderEntry type="library" exported="" name="Trove4j" level="project" />
|
||||
<orderEntry type="module" module-name="testRunner" />
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<orderEntry type="module" module-name="compiler-impl" />
|
||||
<orderEntry type="module" module-name="icons" />
|
||||
<orderEntry type="library" name="jgoodies-forms" level="project" />
|
||||
<orderEntry type="library" name="asm5" level="project" />
|
||||
<orderEntry type="library" name="ASM" level="project" />
|
||||
<orderEntry type="module" module-name="java-i18n" exported="" />
|
||||
<orderEntry type="module" module-name="idea-ui" />
|
||||
<orderEntry type="module" module-name="testFramework-java" scope="TEST" />
|
||||
@@ -35,5 +35,4 @@
|
||||
<setting name="state" value="1" />
|
||||
</Base>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
</module>
|
||||
@@ -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.
|
||||
|
||||
@@ -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>"
|
||||
xml += pydevd_vars.var_to_xml(result, "")
|
||||
xml += "</xml>"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -112,7 +112,6 @@
|
||||
<module>bsddb.test.test_sequence</module>
|
||||
<module>build_class</module>
|
||||
<module>builtins</module>
|
||||
<module>bz2</module>
|
||||
<module>cProfile</module>
|
||||
<module>collections</module>
|
||||
<module>collections.__main__</module>
|
||||
@@ -859,7 +858,6 @@
|
||||
<module>bsddb.test.test_sequence</module>
|
||||
<module>build_class</module>
|
||||
<module>builtins</module>
|
||||
<module>bz2</module>
|
||||
<module>cProfile</module>
|
||||
<module>collections.__main__</module>
|
||||
<module>collections.abc</module>
|
||||
@@ -1548,7 +1546,6 @@
|
||||
<module>bsddb.test.test_replication</module>
|
||||
<module>build_class</module>
|
||||
<module>builtins</module>
|
||||
<module>bz2</module>
|
||||
<module>collections.__main__</module>
|
||||
<module>collections.abc</module>
|
||||
<module>concurrent</module>
|
||||
@@ -2128,7 +2125,6 @@
|
||||
<module>bsddb.test.test_fileid</module>
|
||||
<module>build_class</module>
|
||||
<module>builtins</module>
|
||||
<module>bz2</module>
|
||||
<module>collections.__main__</module>
|
||||
<module>collections.abc</module>
|
||||
<module>concurrent</module>
|
||||
@@ -2541,7 +2537,6 @@
|
||||
<module>bsddb.test.test_env_close</module>
|
||||
<module>build_class</module>
|
||||
<module>builtins</module>
|
||||
<module>bz2</module>
|
||||
<module>collections.__main__</module>
|
||||
<module>collections.abc</module>
|
||||
<module>concurrent</module>
|
||||
@@ -2941,7 +2936,6 @@
|
||||
<module>bsddb.test.test_replication</module>
|
||||
<module>bsddb.test.test_sequence</module>
|
||||
<module>bsddb.test.test_thread</module>
|
||||
<module>bz2</module>
|
||||
<module>cPickle</module>
|
||||
<module>cStringIO</module>
|
||||
<module>collections.__main__</module>
|
||||
@@ -3480,7 +3474,6 @@
|
||||
<module>bsddb.test.test_sequence</module>
|
||||
<module>bsddb.test.test_thread</module>
|
||||
<module>build_class</module>
|
||||
<module>bz2</module>
|
||||
<module>cPickle</module>
|
||||
<module>cStringIO</module>
|
||||
<module>collections.__main__</module>
|
||||
@@ -3926,7 +3919,6 @@
|
||||
<module>bsddb.test.test_sequence</module>
|
||||
<module>bsddb.test.test_thread</module>
|
||||
<module>build_class</module>
|
||||
<module>bz2</module>
|
||||
<module>cPickle</module>
|
||||
<module>cStringIO</module>
|
||||
<module>collections.__main__</module>
|
||||
@@ -4232,7 +4224,6 @@
|
||||
<module>_abcoll</module>
|
||||
<module>_bootlocale</module>
|
||||
<module>_bytesio</module>
|
||||
<module>_bz2</module>
|
||||
<module>_collections_abc</module>
|
||||
<module>_compression</module>
|
||||
<module>_fileio</module>
|
||||
@@ -4597,7 +4588,6 @@
|
||||
<module>__main__</module>
|
||||
<module>_abcoll</module>
|
||||
<module>_bytesio</module>
|
||||
<module>_bz2</module>
|
||||
<module>_compression</module>
|
||||
<module>_fileio</module>
|
||||
<module>_hotshot</module>
|
||||
|
||||
@@ -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__";
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<RatedResolveResult> 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<RatedResolveResult> getResultsFromProcessor(@NotNull String referencedName,
|
||||
|
||||
@@ -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<QualifiedName> 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<RatedResolveResult> 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();
|
||||
}
|
||||
|
||||
@@ -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<PsiElement> 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
|
||||
|
||||
@@ -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))
|
||||
.<PsiElement>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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from bz2 import BZ2File
|
||||
@@ -0,0 +1 @@
|
||||
import <warning descr="Python version 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2 do not have module _bz2">_bz2</warning>
|
||||
@@ -0,0 +1,3 @@
|
||||
class A:
|
||||
def foo(self):
|
||||
return <error descr="Unresolved reference '__class__'">__class__</error>
|
||||
@@ -0,0 +1,3 @@
|
||||
class A:
|
||||
def foo(self):
|
||||
return __class__
|
||||
+1
@@ -0,0 +1 @@
|
||||
from mod import MyClass
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
class MyClass(object):
|
||||
pass
|
||||
+1
@@ -0,0 +1 @@
|
||||
from mod import MyClass
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
class MyClass(object):
|
||||
pass
|
||||
+1
@@ -0,0 +1 @@
|
||||
<error descr="Unresolved reference 'MyClass'">MyClass</error>()
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
from foo import MyClass
|
||||
|
||||
MyClass()
|
||||
@@ -0,0 +1,4 @@
|
||||
class A:
|
||||
my_attr = 17
|
||||
print(my_attr)
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A(object):
|
||||
my_attr = 17
|
||||
print(my_attr)
|
||||
# <ref>
|
||||
@@ -0,0 +1,3 @@
|
||||
class A:
|
||||
print(__class__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
def foo():
|
||||
class A:
|
||||
print(__class__)
|
||||
# <ref>
|
||||
|
||||
return A()
|
||||
@@ -0,0 +1,3 @@
|
||||
class A(object):
|
||||
print(__class__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A:
|
||||
__class__ = 17
|
||||
print(__class__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A(object):
|
||||
__class__ = 17
|
||||
print(__class__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A(object):
|
||||
__class__ = 17
|
||||
|
||||
class B(A):
|
||||
print(__class__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,3 @@
|
||||
class A:
|
||||
print(__doc__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,3 @@
|
||||
class A(object):
|
||||
print(__doc__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A:
|
||||
__doc__ = 17
|
||||
print(__doc__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A(object):
|
||||
__doc__ = 17
|
||||
print(__doc__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A(object):
|
||||
__doc__ = 17
|
||||
|
||||
class B(A):
|
||||
print(__doc__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,3 @@
|
||||
class A:
|
||||
print(__sizeof__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,3 @@
|
||||
class A(object):
|
||||
print(__sizeof__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A:
|
||||
__sizeof__ = 17
|
||||
print(__sizeof__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A(object):
|
||||
__sizeof__ = 17
|
||||
print(__sizeof__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A(object):
|
||||
__sizeof__ = 17
|
||||
|
||||
class B(A):
|
||||
print(__sizeof__)
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A:
|
||||
my_attr = 15
|
||||
|
||||
def foo(self):
|
||||
return my_attr
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A(object):
|
||||
my_attr = 15
|
||||
|
||||
def foo(self):
|
||||
return my_attr
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A:
|
||||
def foo(self):
|
||||
return __class__
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A(object):
|
||||
def foo(self):
|
||||
return __class__
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A:
|
||||
__class__ = 15
|
||||
|
||||
def foo(self):
|
||||
return __class__
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A(object):
|
||||
__class__ = 15
|
||||
|
||||
def foo(self):
|
||||
return __class__
|
||||
# <ref>
|
||||
@@ -0,0 +1,7 @@
|
||||
class A(object):
|
||||
__class__ = int
|
||||
|
||||
class B(A):
|
||||
def foo(self):
|
||||
return __class__
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A:
|
||||
def foo(self):
|
||||
return __doc__
|
||||
# <ref>
|
||||
@@ -0,0 +1,4 @@
|
||||
class A(object):
|
||||
def foo(self):
|
||||
return __doc__
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A:
|
||||
__doc__ = 15
|
||||
|
||||
def foo(self):
|
||||
return __doc__
|
||||
# <ref>
|
||||
@@ -0,0 +1,6 @@
|
||||
class A(object):
|
||||
__doc__ = 15
|
||||
|
||||
def foo(self):
|
||||
return __doc__
|
||||
# <ref>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user