[java-inspections] IDEA-324141 Use var for the inspection "Bulk 'Files.readAttributes()' call can be used"

PR#2508
Reviewed-by: Tagir Valeev <tagir.valeev@jetbrains.com>

GitOrigin-RevId: c3914e71028831bcd72121e0f3070d4ed1fc01db
This commit is contained in:
Fabrice Tiercelin
2023-07-10 12:08:19 +02:00
committed by intellij-monorepo-bot
parent b5322dba9c
commit 7ce127b0f9
10 changed files with 180 additions and 31 deletions

View File

@@ -14,6 +14,7 @@ import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.util.ArrayUtil;
import com.intellij.util.CommonJavaRefactoringUtil;
import com.intellij.util.ObjectUtils;
@@ -249,7 +250,19 @@ public class BulkFileAttributesReadInspection extends AbstractBaseJavaLocalInspe
@NotNull PsiType type,
@Nullable PsiExpression initializer) {
PsiElementFactory elementFactory = PsiElementFactory.getInstance(parent.getProject());
PsiDeclarationStatement declaration = elementFactory.createVariableDeclarationStatement(varName, type, initializer);
PsiType displayType;
if (
initializer != null
&& parent.getContext() != null
&& PsiUtil.isLanguageLevel10OrHigher(parent.getContainingFile())
&& JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_VAR_TYPE
) {
displayType = TypeUtils.getType(PsiKeyword.VAR, parent.getContext());
} else {
displayType = type;
}
PsiDeclarationStatement declaration = elementFactory
.createVariableDeclarationStatement(varName, displayType, initializer);
declaration = (PsiDeclarationStatement)parent.addBefore(declaration, anchor);
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(parent.getProject());
return (PsiDeclarationStatement)codeStyleManager.shortenClassReferences(declaration);

View File

@@ -8,7 +8,7 @@ Reports multiple sequential <code>java.io.File</code> attribute checks, such as:
<li><code>length()</code></li>
</ul>
Such calls can be replaced with a bulk <code>Files.readAttributes()</code> call.
This is usually more performant then multiple separate attribute checks.
This is usually more performant than multiple separate attribute checks.
<p>Example:</p>
<pre><code>
boolean isNewFile(File file, long lastModified) throws IOException {
@@ -18,14 +18,14 @@ This is usually more performant then multiple separate attribute checks.
<p>After the quick-fix is applied:</p>
<pre><code>
boolean isNewFile(File file, long lastModified) throws IOException {
BasicFileAttributes fileAttributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
var fileAttributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
return fileAttributes.isRegularFile() && fileAttributes.lastModifiedTime().toMillis() > lastModified;
}
</code></pre>
<!-- tooltip end -->
<p>This inspection does not show a warning if <code>IOException</code> is not handled in the current context, but the quick-fix is still available.</p>
<p>Note that the replacements are usually not completely equivalent and should be applied with care. In particular, the behavior could differ if
the file does not exist at all.</p>
the file does not exist at all.</p>
<p>This inspection only reports if the language level of the project or module is 7 or higher.</p>
<p><small>New in 2022.1</small></p>
</body>

View File

@@ -0,0 +1,18 @@
// "Replace with bulk 'Files.readAttributes()' call" "true-preview"
import java.io.*;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
class Foo {
private File file;
boolean printDirectory() {
try {
var basicFileAttributes = Files.readAttributes(file.toPath(), BasicFileAttributes.class);
return basicFileAttributes.isDirectory() && basicFileAttributes.isRegularFile();
} catch (Exception e) {
}
return false;
}
}

View File

@@ -0,0 +1,15 @@
// "Replace with bulk 'Files.readAttributes()' call" "true-preview"
import java.io.*;
class Foo {
private File file;
boolean printDirectory() {
try {
return file.isDirec<caret>tory() && file.isFile();
} catch (Exception e) {
}
return false;
}
}

View File

@@ -0,0 +1,18 @@
import java.io.*;
public class Simple {
public long modificationTime(File file) {
if (<info descr="Multiple file attribute calls can be replaced with single 'Files.readAttributes()' call">file.isDirectory()</info>) {
System.out.println(<info descr="Multiple file attribute calls can be replaced with single 'Files.readAttributes()' call">file.isFile()</info>);
}
return <info descr="Multiple file attribute calls can be replaced with single 'Files.readAttributes()' call">file.lastModified()</info>;
}
public long isAlwaysDirectory(File file) {
System.out.println(<info descr="Multiple file attribute calls can be replaced with single 'Files.readAttributes()' call">file.isFile()</info>);
while (file.isDirectory()) {
System.out.println(<info descr="Multiple file attribute calls can be replaced with single 'Files.readAttributes()' call">file.isFile()</info>);
System.out.println(<info descr="Multiple file attribute calls can be replaced with single 'Files.readAttributes()' call">file.length()</info>);
}
return <info descr="Multiple file attribute calls can be replaced with single 'Files.readAttributes()' call">file.lastModified()</info>;
}
}

View File

@@ -0,0 +1,17 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInspection;
import com.intellij.refactoring.JavaRefactoringSettings;
public class BulkFileAttributesReadFixExplicitTypeTest extends BulkFileAttributesReadFixJava11Test {
@Override
protected void setUp() throws Exception {
super.setUp();
JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_VAR_TYPE = false;
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/bulkFileAttributesRead";
}
}

View File

@@ -0,0 +1,48 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInspection;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.codeInspection.BulkFileAttributesReadInspection;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NotNull;
public class BulkFileAttributesReadFixJava11Test extends LightQuickFixParameterizedTestCase {
private Boolean introduceLocalCreateVarType;
@Override
protected void setUp() throws Exception {
super.setUp();
introduceLocalCreateVarType = JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_VAR_TYPE;
JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_VAR_TYPE = true;
}
@Override
protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() {
return new LocalInspectionTool[]{new BulkFileAttributesReadInspection()};
}
@Override
protected Sdk getProjectJDK() {
return IdeaTestUtil.getMockJdk11();
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/bulkFileAttributesReadVar";
}
@Override
protected void tearDown() throws Exception {
try {
JavaRefactoringSettings.getInstance().INTRODUCE_LOCAL_CREATE_VAR_TYPE = introduceLocalCreateVarType;
}
catch (Throwable e) {
addSuppressedException(e);
}
finally {
super.tearDown();
}
}
}

View File

@@ -0,0 +1,19 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInspection;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class BulkFileAttributesReadFixJava9Test extends BulkFileAttributesReadFixJava11Test {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_9;
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/bulkFileAttributesRead";
}
}

View File

@@ -0,0 +1,28 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.codeInspection.BulkFileAttributesReadInspection;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public class BulkFileAttributesReadInspectionTest extends LightJavaCodeInsightFixtureTestCase {
public void testSimple() { doTest(); }
private void doTest() {
myFixture.enableInspections(new BulkFileAttributesReadInspection());
myFixture.testHighlighting(true, true, true, getTestName(false) + ".java");
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_20;
}
@Override
protected String getTestDataPath() {
return JavaTestUtil.getJavaTestDataPath() + "/inspection/bulkFileAttributesRead";
}
}

View File

@@ -1,27 +0,0 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInspection;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.codeInspection.BulkFileAttributesReadInspection;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NotNull;
public class BulkFileAttributesReadTest extends LightQuickFixParameterizedTestCase {
@Override
protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() {
return new LocalInspectionTool[]{new BulkFileAttributesReadInspection()};
}
@Override
protected Sdk getProjectJDK() {
return IdeaTestUtil.getMockJdk11();
}
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/bulkFileAttributesRead";
}
}