test for FileType constructor to be non-public to avoid duplicates and double instantiation because file types must be singletons

GitOrigin-RevId: d448ee007d87edbaf095f8fbe7e1b51ce8c7d9bc
This commit is contained in:
Alexey Kudravtsev
2020-09-25 15:10:42 +02:00
committed by intellij-monorepo-bot
parent 56d3af36bf
commit a4e9a0121a
32 changed files with 103 additions and 31 deletions

View File

@@ -31,9 +31,11 @@ public class RegExpFileType extends LanguageFileType {
super(RegExpLanguage.INSTANCE);
}
public RegExpFileType(@NotNull Language language) {
private RegExpFileType(@NotNull Language language) {
super(language);
if (!(language.getBaseLanguage() instanceof RegExpLanguage)) throw new AssertionError();
if (!(language.getBaseLanguage() instanceof RegExpLanguage)) {
throw new IllegalArgumentException(String.valueOf(language.getBaseLanguage()));
}
}
@Override
@@ -61,4 +63,9 @@ public class RegExpFileType extends LanguageFileType {
public Icon getIcon() {
return getLanguage() == RegExpLanguage.INSTANCE ? AllIcons.FileTypes.Regexp : null;
}
@NotNull
public static LanguageFileType forLanguage(@NotNull Language language) {
return new RegExpFileType(language);
}
}

View File

@@ -84,7 +84,7 @@ public final class CheckRegExpForm {
}
else {
// for correct syntax highlighting
fileType = new RegExpFileType(language);
fileType = RegExpFileType.forLanguage(language);
}
final EditorTextField myRegExp = new EditorTextField(document, project, fileType, false, false) {
@Override

View File

@@ -1,9 +1,11 @@
// 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 org.intellij.lang.regexp.inspection;
package org.intellij.lang.regexp;
import com.intellij.codeInspection.LocalInspectionTool;
import org.intellij.lang.regexp.RegExpFileType;
import org.intellij.lang.regexp.ecmascript.EcmaScriptRegexpLanguage;
import org.intellij.lang.regexp.inspection.RedundantEscapeInspection;
import org.intellij.lang.regexp.inspection.RegExpInspectionTestCase;
import org.jetbrains.annotations.NotNull;
/**
@@ -26,7 +28,7 @@ public class RedundantEscapeInspectionTest extends RegExpInspectionTestCase {
public void testEscapedU() {
quickfixTest("<warning descr=\"Redundant character escape '\\u' in RegExp\">\\u</warning>", "u", "Remove redundant escape",
new RegExpFileType(EcmaScriptRegexpLanguage.INSTANCE));
RegExpFileType.forLanguage(EcmaScriptRegexpLanguage.INSTANCE));
}
public void testPoundSign() {

View File

@@ -1,9 +1,10 @@
// 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 org.intellij.lang.regexp.inspection;
package org.intellij.lang.regexp;
import com.intellij.codeInspection.LocalInspectionTool;
import org.intellij.lang.regexp.RegExpFileType;
import org.intellij.lang.regexp.ecmascript.EcmaScriptRegexpLanguage;
import org.intellij.lang.regexp.inspection.RegExpInspectionTestCase;
import org.intellij.lang.regexp.inspection.RepeatedSpaceInspection;
import org.jetbrains.annotations.NotNull;
/**
@@ -38,7 +39,7 @@ public class RepeatedSpaceInspectionTest extends RegExpInspectionTestCase {
public void testEscapedWhitespace() {
quickfixTest("<warning descr=\"3 consecutive spaces in RegExp\"><caret>\\ </warning>", " {3}", "Replace with ' {3}",
new RegExpFileType(EcmaScriptRegexpLanguage.INSTANCE));
RegExpFileType.forLanguage(EcmaScriptRegexpLanguage.INSTANCE));
}
public void testNoStringIndexOutOfBoundsException() {

View File

@@ -7,6 +7,7 @@ import com.intellij.codeInspection.InspectionProfileEntry;
import com.intellij.codeInspection.InspectionsBundle;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ex.InspectionProfileImpl;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager;
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
@@ -26,7 +27,7 @@ public abstract class RegExpInspectionTestCase extends BasePlatformTestCase {
highlightTest(code, RegExpFileType.INSTANCE);
}
protected void highlightTest(@Language("RegExp") String code, RegExpFileType fileType) {
protected void highlightTest(@Language("RegExp") String code, FileType fileType) {
final LocalInspectionTool inspection = getInspection();
myFixture.enableInspections(inspection);
final HighlightDisplayKey displayKey = HighlightDisplayKey.find(inspection.getShortName());
@@ -46,7 +47,7 @@ public abstract class RegExpInspectionTestCase extends BasePlatformTestCase {
quickfixTest(before, after, hint, RegExpFileType.INSTANCE);
}
protected void quickfixTest(@Language("RegExp") String before, @Language("RegExp") String after, String hint, RegExpFileType fileType) {
protected void quickfixTest(@Language("RegExp") String before, @Language("RegExp") String after, String hint, FileType fileType) {
highlightTest(before, fileType);
myFixture.launchAction(myFixture.findSingleIntention(hint));
myFixture.checkResult(after);
@@ -54,7 +55,6 @@ public abstract class RegExpInspectionTestCase extends BasePlatformTestCase {
protected final void quickfixAllTest(@Language("RegExp") String before, @Language("RegExp") String after) {
InspectionProfileEntry inspection = getInspection();
assert inspection != null : "getInspection() needs to return a non-null value for quickFixAllTest() to work";
quickfixTest(before, after, InspectionsBundle.message("fix.all.inspection.problems.in.file", inspection.getDisplayName()));
}
}

View File

@@ -11,6 +11,9 @@ import javax.swing.*;
public final class ImageFileType extends UserBinaryFileType {
public static final ImageFileType INSTANCE = new ImageFileType();
private ImageFileType() {
}
@NotNull
@Override
public String getName() {

View File

@@ -23,7 +23,7 @@ public class JsonFileType extends LanguageFileType{
super(language, secondary);
}
public JsonFileType() {
protected JsonFileType() {
super(JsonLanguage.INSTANCE);
}

View File

@@ -26,6 +26,9 @@ import javax.swing.*;
public class ArchiveFileType implements FileType {
public static final ArchiveFileType INSTANCE = new ArchiveFileType();
protected ArchiveFileType() {
}
@Override
@NotNull
public String getName() {

View File

@@ -23,7 +23,7 @@ public class ScratchFileType extends LanguageFileType implements FileTypeIdentif
public static final LanguageFileType INSTANCE = new ScratchFileType();
ScratchFileType() {
private ScratchFileType() {
super(PlainTextLanguage.INSTANCE, true);
}

View File

@@ -18,6 +18,10 @@ package com.intellij.openapi.fileTypes;
import com.intellij.openapi.options.SettingsEditor;
public class UserBinaryFileType extends UserFileType<UserBinaryFileType> {
public static final UserBinaryFileType INSTANCE = new UserBinaryFileType();
protected UserBinaryFileType() {
}
@Override
public SettingsEditor<UserBinaryFileType> getEditor() {
return null;

View File

@@ -17,6 +17,9 @@ public abstract class UserFileType<T extends UserFileType<T>> implements FileTyp
private Icon myIcon;
private String myIconPath;
protected UserFileType() {
}
public abstract SettingsEditor<T> getEditor();
@Override

View File

@@ -8,6 +8,8 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public abstract class FakeFileType implements FileTypeIdentifiableByVirtualFile {
protected FakeFileType() {
}
@Override
@NotNull

View File

@@ -354,4 +354,9 @@ public class AbstractFileType extends UserFileType<AbstractFileType> implements
public void setCommenter(@NotNull Commenter commenter) {
myCommenter = commenter;
}
@Override
public String toString() {
return "AbstractFileType "+mySyntaxTable;
}
}

View File

@@ -39,7 +39,6 @@ import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.GuiUtils;
import com.intellij.util.*;
import com.intellij.util.containers.CollectionFactory;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.io.URLUtil;
import com.intellij.util.messages.MessageBusConnection;
import org.jdom.Element;
@@ -361,11 +360,10 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
}
private static void initializeMatchers(@NotNull FileTypeBean bean) {
bean.addMatchers(ContainerUtil.concat(
parse(StringUtil.notNullize(bean.extensions)),
parse(StringUtil.notNullize(bean.fileNames), token -> new ExactFileNameMatcher(token)),
parse(StringUtil.notNullize(bean.fileNamesCaseInsensitive), token -> new ExactFileNameMatcher(token, true)),
parse(StringUtil.notNullize(bean.patterns), token -> FileNameMatcherFactory.getInstance().createMatcher(token))));
bean.addMatchers(parse(StringUtil.notNullize(bean.extensions)));
bean.addMatchers(parse(StringUtil.notNullize(bean.fileNames), token -> new ExactFileNameMatcher(token)));
bean.addMatchers(parse(StringUtil.notNullize(bean.fileNamesCaseInsensitive), token -> new ExactFileNameMatcher(token, true)));
bean.addMatchers(parse(StringUtil.notNullize(bean.patterns), token -> FileNameMatcherFactory.getInstance().createMatcher(token)));
}
private void instantiatePendingFileTypes() {
@@ -1175,7 +1173,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements Persistent
Element element = typeElement.getChild(AbstractFileType.ELEMENT_HIGHLIGHTING);
if (element == null) {
type = new UserBinaryFileType();
type = UserBinaryFileType.INSTANCE;
}
else {
SyntaxTable table = AbstractFileType.readSyntaxTable(element);

View File

@@ -53,6 +53,8 @@ import org.junit.Assume;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@@ -653,7 +655,7 @@ public class FileTypesTest extends HeavyPlatformTestCase {
}
public void testIfDetectorRanThenIdeaReopenedTheDetectorShouldBeReRun() throws IOException {
final UserBinaryFileType stuffType = new UserBinaryFileType();
final UserBinaryFileType stuffType = new UserBinaryFileType(){};
stuffType.setName("stuffType");
final Set<VirtualFile> detectorCalled = ContainerUtil.newConcurrentSet();
@@ -1037,6 +1039,9 @@ public class FileTypesTest extends HeavyPlatformTestCase {
}
private static class MyReplaceableByContentDetectionFileType implements FileType, PlainTextLikeFileType {
private MyReplaceableByContentDetectionFileType() {
}
@NotNull
@Override
public String getName() {
@@ -1094,6 +1099,9 @@ public class FileTypesTest extends HeavyPlatformTestCase {
private static class MyTestFileType implements FileType {
public static final String NAME = "Foo files";
private MyTestFileType() {
}
@NotNull
@Override
public String getName() {
@@ -1138,6 +1146,9 @@ public class FileTypesTest extends HeavyPlatformTestCase {
private static class MyHaskellFileType implements FileType {
public static final String NAME = "Haskell";
private MyHaskellFileType() {
}
@NotNull
@Override
public String getName() {
@@ -1178,4 +1189,16 @@ public class FileTypesTest extends HeavyPlatformTestCase {
return null;
}
}
public void testFileTypeConstructorsMustBeNonPublic() {
FileType[] fileTypes = myFileTypeManager.getRegisteredFileTypes();
LOG.debug("Registered file types: "+fileTypes.length);
for (FileType fileType : fileTypes) {
if (fileType.getClass() == AbstractFileType.class) continue;
Constructor<?>[] constructors = fileType.getClass().getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
assertFalse("FileType constructor must be non-public to avoid duplicates but got: " + constructor, Modifier.isPublic(constructor.getModifiers()));
}
}
}
}

View File

@@ -980,7 +980,7 @@ public class FileEncodingTest extends HeavyPlatformTestCase implements TestDialo
public void testEncodingDetectionRequestsRunInOneThreadForEachDocument() {
Set<Thread> detectThreads = ContainerUtil.newConcurrentSet();
class MyFT extends LanguageFileType implements FileTypeIdentifiableByVirtualFile {
MyFT() {
private MyFT() {
super(new Language("my") {
});
}

View File

@@ -38,7 +38,7 @@ public class IgnoreFileType extends LanguageFileType {
@NotNull
public static final IgnoreFileType INSTANCE = new IgnoreFileType();
protected IgnoreFileType() {
private IgnoreFileType() {
this(IgnoreLanguage.INSTANCE);
}

View File

@@ -20,6 +20,9 @@ public class PatchFileType implements FileType {
public static final String NAME = "PATCH"; //NON-NLS
private PatchFileType() {
}
@Override
@NotNull
@NonNls

View File

@@ -21,7 +21,7 @@ import javax.swing.Icon
import javax.swing.JComponent
import javax.swing.JPanel
class VcsLogFileType : FileType {
class VcsLogFileType private constructor() : FileType {
override fun getName(): String = "VcsLog"
override fun getDescription(): String = VcsLogBundle.message("vcs.log.file.type.description")
override fun getDefaultExtension(): String = ""

View File

@@ -16,6 +16,9 @@ import javax.swing.*;
public class EclipseFileType implements FileType {
public static final FileType INSTANCE = new EclipseFileType();
private EclipseFileType() {
}
@Override
@NotNull
@NonNls

View File

@@ -8,7 +8,7 @@ import org.jetbrains.idea.maven.dom.MavenDomBundle
import org.jetbrains.idea.maven.project.MavenProjectBundle
import javax.swing.Icon
class MavenConfigFileType : LanguageFileType(PlainTextLanguage.INSTANCE, true) {
class MavenConfigFileType private constructor(): LanguageFileType(PlainTextLanguage.INSTANCE, true) {
override fun getName(): String {
return "MavenConfig"

View File

@@ -23,6 +23,9 @@ import org.jetbrains.annotations.NotNull;
public class ResourceBundleFileType extends FakeFileType {
public static final ResourceBundleFileType INSTANCE = new ResourceBundleFileType();
private ResourceBundleFileType() {
}
@Override
@NotNull
public String getName() {

View File

@@ -46,7 +46,7 @@ internal class SpaceChatIconProvider : FileIconProvider {
}
}
private class SpaceChatFileType : FileType {
private class SpaceChatFileType private constructor(): FileType {
override fun getName(): String = "SpaceChat"

View File

@@ -12,6 +12,9 @@ public class TerminalSessionFileType extends FakeFileType {
public final static TerminalSessionFileType INSTANCE = new TerminalSessionFileType();
private TerminalSessionFileType() {
}
@Override
@NotNull
public String getName() {

View File

@@ -32,6 +32,9 @@ public class GuiFormFileType implements /*UIBased*/FileType {
@NonNls public static final String DEFAULT_EXTENSION = "form";
@NonNls public static final String DOT_DEFAULT_EXTENSION = "." + DEFAULT_EXTENSION;
private GuiFormFileType() {
}
@Override
@NotNull
public String getName() {

View File

@@ -26,7 +26,7 @@ import org.jetbrains.annotations.NotNull;
public class PyFunctionTypeAnnotationFileType extends PythonFileType {
public static final PyFunctionTypeAnnotationFileType INSTANCE = new PyFunctionTypeAnnotationFileType();
public PyFunctionTypeAnnotationFileType() {
private PyFunctionTypeAnnotationFileType() {
super(PyFunctionTypeAnnotationDialect.INSTANCE);
}

View File

@@ -27,7 +27,7 @@ import org.jetbrains.annotations.NotNull;
public class PyDocstringFileType extends PythonFileType {
public static final PythonFileType INSTANCE = new PyDocstringFileType();
protected PyDocstringFileType() {
private PyDocstringFileType() {
super(new PyDocstringLanguageDialect());
}

View File

@@ -26,7 +26,7 @@ public class PyiFileType extends PythonFileType {
@NotNull
public static final PythonFileType INSTANCE = new PyiFileType();
protected PyiFileType() {
private PyiFileType() {
super(new PyiLanguageDialect());
}

View File

@@ -32,7 +32,7 @@ public final class CommandLineFileType extends LanguageFileType {
*/
static final String EXTENSION = "cmdline";
CommandLineFileType() {
private CommandLineFileType() {
super(CommandLineLanguage.INSTANCE);
}

View File

@@ -13,7 +13,7 @@ import javax.swing.*;
public class QtUIFileType extends QtFileType implements FileType {
public static final QtUIFileType INSTANCE = new QtUIFileType();
protected QtUIFileType() {
private QtUIFileType() {
super("Qt UI file", PyBundle.message("qt.ui.designer.form.filetype.description"), "ui");
}

View File

@@ -11,6 +11,9 @@ import javax.swing.*;
public class PyRemoteDebugFileType implements FileType {
public static final PyRemoteDebugFileType INSTANCE = new PyRemoteDebugFileType();
private PyRemoteDebugFileType() {
}
@NotNull
@Override
public String getName() {

View File

@@ -15,6 +15,9 @@ import javax.swing.*;
public class DictionaryFileType implements FileType {
public static final DictionaryFileType INSTANCE = new DictionaryFileType();
private DictionaryFileType() {
}
@NotNull
@Override
public String getName() {