[java] IDEA-297687 DefaultFileTemplateUsageInspection triggers loading of all file templates

GitOrigin-RevId: b3e473fd4897bb9ba82d807763a94c876c56abe2
This commit is contained in:
Yuriy Artamonov
2022-07-10 13:58:53 +02:00
committed by intellij-monorepo-bot
parent c6c98e6b5b
commit e79882b250
11 changed files with 1 additions and 391 deletions

View File

@@ -1696,9 +1696,6 @@
enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection"
key="inspection.unchecked.warning.display.name" bundle="messages.JavaBundle"/>
<localInspection shortName="DefaultFileTemplate" bundle="messages.JavaBundle" key="default.file.template.display.name"
groupKey="inspection.general.tools.group.name" groupBundle="messages.InspectionsBundle" enabledByDefault="true" level="WARNING"
implementationClass="com.intellij.codeInspection.defaultFileTemplateUsage.DefaultFileTemplateUsageInspection"/>
<localInspection groupPath="Java" language="JAVA" shortName="AccessStaticViaInstance" bundle="messages.JavaBundle" key="access.static.via.instance"
groupKey="group.names.declaration.redundancy" groupBundle="messages.InspectionsBundle"
enabledByDefault="true" level="WARNING" cleanupTool="true" alternativeId="static-access"

View File

@@ -1,101 +0,0 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInspection.defaultFileTemplateUsage;
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class DefaultFileTemplateUsageInspection extends AbstractBaseJavaLocalInspectionTool {
/**
* @deprecated unused, left to avoid modifications in config files
*/
@Deprecated
public boolean CHECK_FILE_HEADER = true;
/**
* @deprecated unused, left to avoid modifications in config files
*/
@Deprecated
public boolean CHECK_TRY_CATCH_SECTION = true;
/**
* @deprecated unused, left to avoid modifications in config files
*/
@Deprecated
public boolean CHECK_METHOD_BODY = true;
@Override
@NotNull
public String getGroupDisplayName() {
return getGeneralGroupName();
}
@Override
@NotNull
@NonNls
public String getShortName() {
return "DefaultFileTemplate";
}
@Override
public ProblemDescriptor @Nullable [] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
ProblemDescriptor descriptor = FileHeaderChecker.checkFileHeader(file, manager, isOnTheFly);
return descriptor == null ? null : new ProblemDescriptor[]{descriptor};
}
@Override
public boolean isEnabledByDefault() {
return true;
}
public static LocalQuickFix createEditFileTemplateFix(FileTemplate templateToEdit, ReplaceWithFileTemplateFix replaceTemplateFix) {
return new EditFileTemplateFix(templateToEdit, replaceTemplateFix);
}
private static class EditFileTemplateFix implements LocalQuickFix {
private final FileTemplate myTemplateToEdit;
private final ReplaceWithFileTemplateFix myReplaceTemplateFix;
EditFileTemplateFix(FileTemplate templateToEdit, ReplaceWithFileTemplateFix replaceTemplateFix) {
myTemplateToEdit = templateToEdit;
myReplaceTemplateFix = replaceTemplateFix;
}
@Override
@NotNull
public String getFamilyName() {
return JavaBundle.message("default.file.template.edit.template");
}
@Override
public boolean startInWriteAction() {
return false;
}
@Override
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
final FileTemplateConfigurable configurable = new FileTemplateConfigurable(project);
configurable.setTemplate(myTemplateToEdit, null);
boolean ok = ShowSettingsUtil.getInstance().editConfigurable(project, configurable);
if (ok) {
WriteCommandAction.runWriteCommandAction(project, () -> {
FileTemplateManager.getInstance(project).saveAllTemplates();
myReplaceTemplateFix.applyFix(project, descriptor);
});
}
}
}
}

View File

@@ -1,111 +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.codeInspection.defaultFileTemplateUsage;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiComment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.util.PsiTreeUtil;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.Arrays;
import java.util.Properties;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final class FileHeaderChecker {
private static final Logger LOG = Logger.getInstance(FileHeaderChecker.class);
static ProblemDescriptor checkFileHeader(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean onTheFly) {
Int2ObjectMap<String> offsetToProperty = new Int2ObjectOpenHashMap<>();
FileTemplate defaultTemplate = FileTemplateManager.getInstance(file.getProject()).getDefaultTemplate(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME);
Pattern pattern = FileTemplateUtil.getTemplatePattern(defaultTemplate, file.getProject(), offsetToProperty);
Matcher matcher = pattern.matcher(file.getViewProvider().getContents());
if (!matcher.matches()) {
return null;
}
PsiComment element = PsiTreeUtil.findElementOfClassAtRange(file, matcher.start(1), matcher.end(1), PsiComment.class);
if (element == null) {
return null;
}
LocalQuickFix[] fixes = createQuickFix(matcher, offsetToProperty, file.getProject(), onTheFly);
String description = JavaBundle.message("default.file.template.description");
return manager.createProblemDescriptor(element, description, onTheFly, fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
}
private static Properties computeProperties(final MatchResult matcher, final Int2ObjectMap<String> offsetToProperty, Project project) {
Properties properties = new Properties(FileTemplateManager.getInstance(project).getDefaultProperties());
int[] offsets = offsetToProperty.keySet().toIntArray();
Arrays.sort(offsets);
for (int i = 0; i < offsets.length; i++) {
final int offset = offsets[i];
String propName = offsetToProperty.get(offset);
int groupNum = i + 2; // first group is whole doc comment
String propValue = matcher.group(groupNum);
properties.setProperty(propName, propValue);
}
return properties;
}
private static LocalQuickFix[] createQuickFix(final MatchResult matcher,
final Int2ObjectMap<String> offsetToProperty,
Project project,
boolean onTheFly) {
final FileTemplate template = FileTemplateManager.getInstance(project).getPattern(FileTemplateManager.FILE_HEADER_TEMPLATE_NAME);
ReplaceWithFileTemplateFix replaceTemplateFix = new ReplaceWithFileTemplateFix() {
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
if (element == null) return;
String newText;
try {
newText = template.getText(computeProperties(matcher, offsetToProperty, project)).trim();
}
catch (IOException e) {
LOG.error(e);
return;
}
if (!newText.isEmpty()) {
PsiElement parent = element.getParent();
PsiFile tempFile = PsiFileFactory.getInstance(project).createFileFromText("template.java", JavaFileType.INSTANCE, newText);
for (PsiElement child : tempFile.getChildren()) {
if (child.getTextLength() > 0) {
parent.addBefore(child, element);
}
}
}
element.delete();
}
};
if (onTheFly) {
LocalQuickFix editFileTemplateFix = DefaultFileTemplateUsageInspection.createEditFileTemplateFix(template, replaceTemplateFix);
return template.isDefault() ? new LocalQuickFix[]{editFileTemplateFix} : new LocalQuickFix[]{replaceTemplateFix, editFileTemplateFix};
}
return template.isDefault() ? null : new LocalQuickFix[] {replaceTemplateFix};
}
}

View File

@@ -1,28 +0,0 @@
/*
* Copyright 2000-2009 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.codeInspection.defaultFileTemplateUsage;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.java.JavaBundle;
import org.jetbrains.annotations.NotNull;
public abstract class ReplaceWithFileTemplateFix implements LocalQuickFix {
@Override
@NotNull
public String getFamilyName() {
return JavaBundle.message("default.file.template.replace.with.actual.file.template");
}
}

View File

@@ -1,10 +0,0 @@
package mylibs.aspectjlibs.lib2;
<warning descr="Default File template">/**
* Created by irina on 11/6/2014.
*/</warning>
class Range {
/**
* for all public methods with name == foo* and String type
*/
}

View File

@@ -1,62 +0,0 @@
package x;
import java.io.*;
<warning descr="Default File template">/**
* Created by Alexey on 02.12.2005.
*/</warning>
public class X implements Runnable{
File f; //kkj lkkl jjkuufdffffjkkjjh kjh kjhj kkjh kjh i k kj kj klj lkj lkj lkjl kj klkl kl
{
try {
f=null;
} catch (Exception e) {
e.printStackTrace();
}
try {
g();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void g() throws EOFException, FileNotFoundException {
}
public int hashCode() {
return super.hashCode();
}
public String toString() {
return super.toString();
}
public void run() {
}
private void method() {
// hello
}
private int geti() {
return 0;
}
private void cat() {
try {
}
catch (Exception e) {
e.printStackTrace(); // hey
}
}
protected void finalize() throws Throwable {
super.finalize();
}
private void multi() {
try {
g();
} catch (EOFException | FileNotFoundException ex) {
ex.printStackTrace();
}
}
}

View File

@@ -1,8 +0,0 @@
package x;
import java.io.*;
<warning descr="Default File template">/**
* Created by Alexey on 02.12.2005.
*/</warning>
public class X2 {
}

View File

@@ -1,9 +0,0 @@
package x;
import java.io.*;
/**
* Created by Alexey on 02.12.2005.
* This class represents something important.
*/
public class X3 {
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright 2000-2017 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.java.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.codeInspection.defaultFileTemplateUsage.DefaultFileTemplateUsageInspection;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
public class DefaultFileTemplateUsageInspectionTest extends LightJavaCodeInsightFixtureTestCase {
@Override
protected String getTestDataPath() {
return JavaTestUtil.getJavaTestDataPath() + "/inspection/defaultFileTemplateUsage";
}
public void testX() { doTest(); }
public void testX2() { doTest(); }
public void testX3() { doTest(); }
public void testRange() { doTest(); }
private void doTest() {
myFixture.enableInspections(new DefaultFileTemplateUsageInspection());
myFixture.testHighlighting(true, false, true, getTestName(false) + ".java");
}
@Override
protected void setUp() throws Exception {
super.setUp();
PlatformTestUtil.setLongMeaninglessFileIncludeTemplateTemporarilyFor(getProject(), getTestRootDisposable());
}
}

View File

@@ -1,7 +1,6 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.java.psi
import com.intellij.codeInspection.defaultFileTemplateUsage.DefaultFileTemplateUsageInspection
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.psi.*
import com.intellij.psi.impl.source.PsiClassReferenceType
@@ -14,6 +13,7 @@ import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
import com.intellij.util.ref.GCWatcher
import java.util.function.Predicate
/**
* @author peter
*/
@@ -64,19 +64,6 @@ class AstLeaksTest extends LightJavaCodeInsightFixtureTestCase {
LeakHunter.checkLeak(sup, MethodElement, { it.psi.containingFile == sup })
}
void "test no hard refs to Default File Template inspection internal AST"() {
myFixture.addFileToProject('sup.java', 'class Super { void bar() {} }')
def file = myFixture.addFileToProject('a.java', 'class Foo { void bar() { bar(); } }')
myFixture.configureFromExistingVirtualFile(file.virtualFile)
myFixture.enableInspections(new DefaultFileTemplateUsageInspection())
myFixture.doHighlighting()
def mainClass = ((PsiJavaFile)file).classes[0]
LeakHunter.checkLeak(mainClass, MethodElement, { MethodElement node ->
!node.psi.physical
})
}
void "test no hard refs to AST via class reference type"() {
def cls = myFixture.addClass("class Foo { Object bar() {} }")
def file = cls.containingFile as PsiFileImpl

View File

@@ -1,7 +1,6 @@
com.intellij.codeInspection.canBeFinal.CanBeFinalInspection
com.intellij.codeInspection.dataFlow.DataFlowInspection
com.intellij.codeInspection.deadCode.UnusedDeclarationInspection
com.intellij.codeInspection.defaultFileTemplateUsage.DefaultFileTemplateUsageInspection
com.intellij.codeInspection.defUse.DefUseInspection
com.intellij.codeInspection.duplicatePropertyInspection.DuplicatePropertyInspection
com.intellij.codeInspection.duplicateStringLiteral.DuplicateStringLiteralInspection