mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Cleanup (warnings; formatting)
GitOrigin-RevId: fa3874b1b3a0789415fbffd52e5262c15c8f8592
This commit is contained in:
committed by
intellij-monorepo-bot
parent
13a81937cd
commit
4a6f9bd7d8
+17
-18
@@ -1,4 +1,4 @@
|
||||
// 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.
|
||||
// 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.openapi.fileEditor.impl;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -29,13 +29,13 @@ import java.util.Map;
|
||||
public abstract class FileDocumentManagerBase extends FileDocumentManager {
|
||||
public static final Key<Document> HARD_REF_TO_DOCUMENT_KEY = Key.create("HARD_REF_TO_DOCUMENT_KEY");
|
||||
public static final Key<Boolean> TRACK_NON_PHYSICAL = Key.create("TRACK_NON_PHYSICAL");
|
||||
|
||||
private static final Key<VirtualFile> FILE_KEY = Key.create("FILE_KEY");
|
||||
private static final Key<Boolean> BIG_FILE_PREVIEW = Key.create("BIG_FILE_PREVIEW");
|
||||
private static final Object lock = new Object();
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Document getDocument(@NotNull VirtualFile file) {
|
||||
public @Nullable Document getDocument(@NotNull VirtualFile file) {
|
||||
ApplicationManager.getApplication().assertReadAccessAllowed();
|
||||
DocumentEx document = (DocumentEx)getCachedDocument(file);
|
||||
if (document == null) {
|
||||
@@ -47,7 +47,7 @@ public abstract class FileDocumentManagerBase extends FileDocumentManager {
|
||||
CharSequence text = loadText(file, tooLarge);
|
||||
synchronized (lock) {
|
||||
document = (DocumentEx)getCachedDocument(file);
|
||||
if (document != null) return document; // Double checking
|
||||
if (document != null) return document; // double-checking
|
||||
|
||||
document = (DocumentEx)createDocument(text, file);
|
||||
document.setModificationStamp(file.getModificationStamp());
|
||||
@@ -78,8 +78,7 @@ public abstract class FileDocumentManagerBase extends FileDocumentManager {
|
||||
document.putUserData(BIG_FILE_PREVIEW, tooLarge ? Boolean.TRUE : null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CharSequence loadText(@NotNull VirtualFile file, boolean tooLarge) {
|
||||
private @NotNull CharSequence loadText(@NotNull VirtualFile file, boolean tooLarge) {
|
||||
if (file instanceof LightVirtualFile) {
|
||||
FileViewProvider vp = findCachedPsiInAnyProject(file);
|
||||
if (vp != null) {
|
||||
@@ -90,24 +89,26 @@ public abstract class FileDocumentManagerBase extends FileDocumentManager {
|
||||
return tooLarge ? LoadTextUtil.loadText(file, getPreviewCharCount(file)) : LoadTextUtil.loadText(file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected abstract Document createDocument(@NotNull CharSequence text, @NotNull VirtualFile file);
|
||||
protected abstract @NotNull Document createDocument(@NotNull CharSequence text, @NotNull VirtualFile file);
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Document getCachedDocument(@NotNull VirtualFile file) {
|
||||
public @Nullable Document getCachedDocument(@NotNull VirtualFile file) {
|
||||
Document hard = file.getUserData(HARD_REF_TO_DOCUMENT_KEY);
|
||||
return hard != null ? hard : getDocumentFromCache(file);
|
||||
}
|
||||
|
||||
// store file<->document association with hard references to avoid undesired gc.
|
||||
// works for non-physical ViewProviders only to avoid memleaks.
|
||||
// please do not use under the penalty of severe memory leaks and wild PSI inconsistencies.
|
||||
/**
|
||||
* Storing file<->document association with hard references to avoid undesired GCs.
|
||||
* Works for non-physical ViewProviders only, to avoid memory leaks.
|
||||
* Please do not use under the penalty of severe memory leaks and wild PSI inconsistencies.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void registerDocument(@NotNull Document document, @NotNull VirtualFile virtualFile) {
|
||||
if (!(virtualFile instanceof LightVirtualFile) &&
|
||||
!(virtualFile.getFileSystem() instanceof NonPhysicalFileSystem)) {
|
||||
throw new IllegalArgumentException("Hard-coding file<->document association is permitted for non-physical files only (see FileViewProvider.isPhysical()) to avoid memleaks. virtualFile="+virtualFile);
|
||||
throw new IllegalArgumentException(
|
||||
"Hard-coding file<->document association is permitted for non-physical files only (see FileViewProvider.isPhysical())" +
|
||||
" to avoid memory leaks. virtualFile=" + virtualFile);
|
||||
}
|
||||
synchronized (lock) {
|
||||
document.putUserData(FILE_KEY, virtualFile);
|
||||
@@ -116,10 +117,8 @@ public abstract class FileDocumentManagerBase extends FileDocumentManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public VirtualFile getFile(@NotNull Document document) {
|
||||
if (document instanceof FrozenDocument) return null;
|
||||
return document.getUserData(FILE_KEY);
|
||||
public @Nullable VirtualFile getFile(@NotNull Document document) {
|
||||
return document instanceof FrozenDocument ? null : document.getUserData(FILE_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,8 +16,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.util.text.Strings;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileEvent;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingRegistry;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.util.*;
|
||||
@@ -48,16 +46,15 @@ public final class LoadTextUtil {
|
||||
|
||||
private LoadTextUtil() { }
|
||||
|
||||
@NotNull
|
||||
private static ConvertResult convertLineSeparatorsToSlashN(@NotNull CharBuffer buffer) {
|
||||
private static @NotNull ConvertResult convertLineSeparatorsToSlashN(@NotNull CharBuffer buffer) {
|
||||
int dst = 0;
|
||||
char prev = ' ';
|
||||
int crCount = 0;
|
||||
int lfCount = 0;
|
||||
int crlfCount = 0;
|
||||
|
||||
final int length = buffer.length();
|
||||
final char[] bufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer);
|
||||
int length = buffer.length();
|
||||
char[] bufferArray = CharArrayUtil.fromSequenceWithoutCopying(buffer);
|
||||
|
||||
for (int src = 0; src < length; src++) {
|
||||
char c = bufferArray != null ? bufferArray[src]:buffer.charAt(src);
|
||||
@@ -92,8 +89,7 @@ public final class LoadTextUtil {
|
||||
|
||||
private static final char UNDEFINED_CHAR = 0xFDFF;
|
||||
|
||||
@NotNull
|
||||
private static ConvertResult convertLineSeparatorsToSlashN(byte @NotNull [] charsAsBytes, int startOffset, int endOffset) {
|
||||
private static @NotNull ConvertResult convertLineSeparatorsToSlashN(byte @NotNull [] charsAsBytes, int startOffset, int endOffset) {
|
||||
int lineBreak = findLineBreakOrWideChar(charsAsBytes, startOffset, endOffset);
|
||||
if (!BitUtil.isSet(lineBreak, CR) && !BitUtil.isSet(lineBreak, WIDE)) {
|
||||
// optimisation: if there is no CR in the file, no line separator conversion is necessary. we can re-use the passed byte buffer inplace
|
||||
@@ -141,8 +137,7 @@ public final class LoadTextUtil {
|
||||
return new ConvertResult(sequence, crCount, lfCount, crlfCount);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ConvertResult convertWideCharacters(byte @NotNull [] charsAsBytes, int startOffset, int endOffset) {
|
||||
private static @NotNull ConvertResult convertWideCharacters(byte @NotNull [] charsAsBytes, int startOffset, int endOffset) {
|
||||
// convert \r\n to \n, \r to \n, wide char to UNDEFINED_CHAR
|
||||
char prev = ' ';
|
||||
int crCount = 0;
|
||||
@@ -183,6 +178,7 @@ public final class LoadTextUtil {
|
||||
private static final int CR = 1;
|
||||
private static final int LF = 2;
|
||||
private static final int WIDE = 4;
|
||||
|
||||
@MagicConstant(flags = {CR, LF, WIDE})
|
||||
private static int findLineBreakOrWideChar(byte @NotNull [] ints, int start, int end) {
|
||||
int flags = 0;
|
||||
@@ -195,10 +191,12 @@ public final class LoadTextUtil {
|
||||
return flags;
|
||||
}
|
||||
|
||||
// private fake charsets for files which have one-byte-for-ascii-characters encoding but contain seven bits characters only. used for optimization since we don't have to encode-decode bytes here.
|
||||
// Private fake charsets for files having one-byte-for-ascii-characters encoding but containing only 7-bit characters.
|
||||
// Used for optimization since we don't have to encode-decode bytes here.
|
||||
private static final Charset INTERNAL_SEVEN_BIT_UTF8 = new SevenBitCharset(StandardCharsets.UTF_8);
|
||||
private static final Charset INTERNAL_SEVEN_BIT_ISO_8859_1 = new SevenBitCharset(StandardCharsets.ISO_8859_1);
|
||||
private static final Charset INTERNAL_SEVEN_BIT_WIN_1251 = new SevenBitCharset(CharsetToolkit.WIN_1251_CHARSET);
|
||||
|
||||
private static class SevenBitCharset extends Charset {
|
||||
private final Charset myBaseCharset;
|
||||
|
||||
@@ -238,13 +236,12 @@ public final class LoadTextUtil {
|
||||
}
|
||||
}
|
||||
|
||||
// guess from file type or content
|
||||
@NotNull
|
||||
private static DetectResult detectHardCharset(@NotNull VirtualFile virtualFile,
|
||||
// guess from a file type or a content
|
||||
private static @NotNull DetectResult detectHardCharset(@NotNull VirtualFile virtualFile,
|
||||
byte @NotNull [] internalBuffer,
|
||||
int length,
|
||||
@NotNull FileType fileType) {
|
||||
String charsetName = fileType.getCharset(virtualFile, internalBuffer); // todo aaaaah
|
||||
String charsetName = fileType.getCharset(virtualFile, internalBuffer); // todo[cdr]
|
||||
Charset charset = charsetName == null ? null : CharsetToolkit.forName(charsetName);
|
||||
DetectResult detectResult = guessFromContent(virtualFile, internalBuffer, length);
|
||||
Charset hardCodedCharset = charset == null ? detectResult.hardCodedCharset : charset;
|
||||
@@ -260,24 +257,21 @@ public final class LoadTextUtil {
|
||||
return new DetectResult(result, guessed, detectedBOM);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Charset detectCharsetAndSetBOM(@NotNull VirtualFile virtualFile, byte @NotNull [] content, @NotNull FileType fileType) {
|
||||
public static @NotNull Charset detectCharsetAndSetBOM(@NotNull VirtualFile virtualFile, byte @NotNull [] content, @NotNull FileType fileType) {
|
||||
Charset internalCharset = detectInternalCharsetAndSetBOM(virtualFile, content, content.length, true, fileType).hardCodedCharset;
|
||||
return internalCharset instanceof SevenBitCharset ? ((SevenBitCharset)internalCharset).myBaseCharset : internalCharset;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Charset getDefaultCharsetFromEncodingManager(@NotNull VirtualFile virtualFile) {
|
||||
private static @NotNull Charset getDefaultCharsetFromEncodingManager(@NotNull VirtualFile virtualFile) {
|
||||
Charset specifiedExplicitly = EncodingRegistry.getInstance().getEncoding(virtualFile, true);
|
||||
return ObjectUtils.notNull(specifiedExplicitly, EncodingRegistry.getInstance().getDefaultCharset());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DetectResult detectInternalCharsetAndSetBOM(@NotNull VirtualFile file,
|
||||
byte @NotNull [] internalBuffer,
|
||||
int length,
|
||||
boolean saveBOM,
|
||||
@NotNull FileType fileType) {
|
||||
private static @NotNull DetectResult detectInternalCharsetAndSetBOM(@NotNull VirtualFile file,
|
||||
byte @NotNull [] internalBuffer,
|
||||
int length,
|
||||
boolean saveBOM,
|
||||
@NotNull FileType fileType) {
|
||||
DetectResult info = detectHardCharset(file, internalBuffer, length, fileType);
|
||||
|
||||
Charset charset;
|
||||
@@ -314,19 +308,17 @@ public final class LoadTextUtil {
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public static DetectResult guessFromContent(@NotNull VirtualFile virtualFile, byte @NotNull [] content) {
|
||||
public static @NotNull DetectResult guessFromContent(@NotNull VirtualFile virtualFile, byte @NotNull [] content) {
|
||||
return guessFromContent(virtualFile, content, content.length);
|
||||
}
|
||||
|
||||
private static final boolean GUESS_UTF = Boolean.parseBoolean(System.getProperty("idea.guess.utf.encoding", "true"));
|
||||
@NotNull
|
||||
private static DetectResult guessFromContent(@NotNull VirtualFile virtualFile, byte @NotNull [] content, int length) {
|
||||
private static @NotNull DetectResult guessFromContent(@NotNull VirtualFile virtualFile, byte @NotNull [] content, int length) {
|
||||
AutoDetectionReason detectedFromBytes = null;
|
||||
try {
|
||||
DetectResult info;
|
||||
if (GUESS_UTF) {
|
||||
info = guessFromBytes(content, 0, length, getDefaultCharsetFromEncodingManager(virtualFile));
|
||||
info = guessFromBytes(content, length, getDefaultCharsetFromEncodingManager(virtualFile));
|
||||
if (info.BOM != null) {
|
||||
detectedFromBytes = AutoDetectionReason.FROM_BOM;
|
||||
}
|
||||
@@ -344,11 +336,8 @@ public final class LoadTextUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DetectResult guessFromBytes(byte @NotNull [] content,
|
||||
int startOffset, int endOffset,
|
||||
@NotNull Charset defaultCharset) {
|
||||
if (startOffset == endOffset) {
|
||||
private static @NotNull DetectResult guessFromBytes(byte @NotNull [] content, int endOffset, @NotNull Charset defaultCharset) {
|
||||
if (endOffset == 0) {
|
||||
return new DetectResult(null, CharsetToolkit.GuessedEncoding.SEVEN_BIT, null);
|
||||
}
|
||||
CharsetToolkit toolkit = new CharsetToolkit(content, defaultCharset, true);
|
||||
@@ -357,46 +346,14 @@ public final class LoadTextUtil {
|
||||
byte[] bom = ObjectUtils.notNull(CharsetToolkit.getMandatoryBom(charset), CharsetToolkit.UTF8_BOM);
|
||||
return new DetectResult(charset, null, bom);
|
||||
}
|
||||
CharsetToolkit.GuessedEncoding guessed = toolkit.guessFromContent(startOffset, endOffset);
|
||||
CharsetToolkit.GuessedEncoding guessed = toolkit.guessFromContent(0, endOffset);
|
||||
if (guessed == CharsetToolkit.GuessedEncoding.VALID_UTF8) {
|
||||
return new DetectResult(StandardCharsets.UTF_8, CharsetToolkit.GuessedEncoding.VALID_UTF8, null); //UTF detected, ignore all directives
|
||||
}
|
||||
return new DetectResult(null, guessed, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to detect text in the {@code bytes} and call the {@code fileTextProcessor} with the text (if detected) or with null if not
|
||||
*/
|
||||
public static String getTextFromBytesOrNull(byte @NotNull [] bytes, int startOffset, int endOffset) {
|
||||
Charset defaultCharset = EncodingManager.getInstance().getDefaultCharset();
|
||||
DetectResult info = guessFromBytes(bytes, startOffset, endOffset, defaultCharset);
|
||||
Charset charset;
|
||||
if (info.hardCodedCharset != null) {
|
||||
charset = info.hardCodedCharset;
|
||||
}
|
||||
else {
|
||||
switch (info.guessed) {
|
||||
case SEVEN_BIT:
|
||||
charset = StandardCharsets.US_ASCII;
|
||||
break;
|
||||
case VALID_UTF8:
|
||||
charset = StandardCharsets.UTF_8;
|
||||
break;
|
||||
case INVALID_UTF8:
|
||||
case BINARY:
|
||||
// the charset was not detected so the file is likely binary
|
||||
return null;
|
||||
default:
|
||||
throw new IllegalStateException(String.valueOf(info.guessed));
|
||||
}
|
||||
}
|
||||
byte[] bom = info.BOM;
|
||||
ConvertResult result = convertBytes(bytes, Math.min(startOffset + (bom == null ? 0 : bom.length), endOffset), endOffset, charset);
|
||||
return result.text.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Pair.NonNull<Charset,byte[]> getOverriddenCharsetByBOM(byte @NotNull [] content, @NotNull Charset charset) {
|
||||
private static @NotNull Pair.NonNull<Charset, byte[]> getOverriddenCharsetByBOM(byte @NotNull [] content, @NotNull Charset charset) {
|
||||
if (charset.name().contains(CharsetToolkit.UTF8) && CharsetToolkit.hasUTF8Bom(content)) {
|
||||
return Pair.createNonNull(charset, CharsetToolkit.UTF8_BOM);
|
||||
}
|
||||
@@ -420,16 +377,7 @@ public final class LoadTextUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites file with text and sets modification stamp and time stamp to the specified values.
|
||||
* <p/>
|
||||
* Normally you should not use this method.
|
||||
*
|
||||
* @param requestor any object to control who called this method. Note that
|
||||
* it is considered to be an external change if {@code requestor} is {@code null}.
|
||||
* See {@link VirtualFileEvent#getRequestor}
|
||||
* @param newModificationStamp new modification stamp or -1 if no special value should be set @return {@code Writer}
|
||||
* @throws IOException if an I/O error occurs
|
||||
* @see VirtualFile#getModificationStamp()
|
||||
* Normally, one should not use this method.
|
||||
*/
|
||||
public static void write(@Nullable Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@@ -443,24 +391,22 @@ public final class LoadTextUtil {
|
||||
if (!charset.equals(existing)) {
|
||||
virtualFile.setCharset(charset);
|
||||
}
|
||||
setDetectedFromBytesFlagBack(virtualFile, buffer);
|
||||
restoreDetectedFromContentFlag(virtualFile, buffer);
|
||||
|
||||
try (OutputStream stream = virtualFile.getOutputStream(requestor, newModificationStamp, -1)) {
|
||||
stream.write(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pair.NonNull<Charset, byte[]> charsetForWriting(@Nullable Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull String text,
|
||||
@NotNull Charset existing) {
|
||||
public static @NotNull Pair.NonNull<Charset, byte[]> charsetForWriting(@Nullable Project project,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull String text,
|
||||
@NotNull Charset existing) {
|
||||
Charset specified = extractCharsetFromFileContent(project, virtualFile, text);
|
||||
Pair.NonNull<Charset, byte[]> chosen = chooseMostlyHarmlessCharset(existing, specified, text);
|
||||
Charset charset = chosen.first;
|
||||
|
||||
// in case of "UTF-16", OutputStreamWriter sometimes adds BOM on it's own.
|
||||
// see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6800103
|
||||
// in the case of "UTF-16", OutputStreamWriter sometimes adds BOM on its own (see JDK-6800103)
|
||||
byte[] bom = virtualFile.getBOM();
|
||||
Charset fromBom = bom == null ? null : CharsetToolkit.guessFromBOM(bom);
|
||||
if (fromBom != null && !fromBom.equals(charset)) {
|
||||
@@ -469,18 +415,17 @@ public final class LoadTextUtil {
|
||||
return chosen;
|
||||
}
|
||||
|
||||
private static void setDetectedFromBytesFlagBack(@NotNull VirtualFile virtualFile, byte @NotNull [] content) {
|
||||
private static void restoreDetectedFromContentFlag(@NotNull VirtualFile virtualFile, byte @NotNull [] content) {
|
||||
if (virtualFile.getBOM() == null) {
|
||||
guessFromContent(virtualFile, content);
|
||||
}
|
||||
else {
|
||||
// prevent file to be reloaded in other encoding after save with BOM
|
||||
// prevent file to be reloaded in another encoding after save with BOM
|
||||
setCharsetAutoDetectionReason(virtualFile, AutoDetectionReason.FROM_BOM);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Pair.NonNull<Charset, byte[]> chooseMostlyHarmlessCharset(@NotNull Charset existing, @NotNull Charset specified, @NotNull String text) {
|
||||
public static @NotNull Pair.NonNull<Charset, byte[]> chooseMostlyHarmlessCharset(@NotNull Charset existing, @NotNull Charset specified, @NotNull String text) {
|
||||
try {
|
||||
if (specified.equals(existing)) {
|
||||
return Pair.createNonNull(specified, text.getBytes(existing));
|
||||
@@ -494,7 +439,7 @@ public final class LoadTextUtil {
|
||||
if (out != null) {
|
||||
return Pair.createNonNull(existing, out); //otherwise stick to the old encoding if it's ok
|
||||
}
|
||||
return Pair.createNonNull(specified, text.getBytes(specified)); //if both are bad there is no difference
|
||||
return Pair.createNonNull(specified, text.getBytes(specified)); //if both are bad, there is no difference
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
Charset defaultCharset = Charset.defaultCharset();
|
||||
@@ -517,21 +462,18 @@ public final class LoadTextUtil {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Charset extractCharsetFromFileContent(@Nullable Project project, @NotNull VirtualFile virtualFile, @NotNull CharSequence text) {
|
||||
public static @NotNull Charset extractCharsetFromFileContent(@Nullable Project project, @NotNull VirtualFile virtualFile, @NotNull CharSequence text) {
|
||||
return ObjectUtils.notNull(charsetFromContentOrNull(project, virtualFile, text), virtualFile.getCharset());
|
||||
}
|
||||
|
||||
@Nullable("returns null if cannot determine from content")
|
||||
public static Charset charsetFromContentOrNull(@Nullable Project project, @NotNull VirtualFile virtualFile, @NotNull CharSequence text) {
|
||||
public static @Nullable("returns null if cannot determine from content") Charset charsetFromContentOrNull(@Nullable Project project, @NotNull VirtualFile virtualFile, @NotNull CharSequence text) {
|
||||
return CharsetUtil.extractCharsetFromFileContent(project, virtualFile, virtualFile.getFileType(), text);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CharSequence loadText(@NotNull final VirtualFile file) {
|
||||
public static @NotNull CharSequence loadText(@NotNull VirtualFile file) {
|
||||
FileType type = file.getFileType();
|
||||
if (type.isBinary()) {
|
||||
final BinaryFileDecompiler decompiler = BinaryFileTypeDecompilers.getInstance().forFileType(type);
|
||||
BinaryFileDecompiler decompiler = BinaryFileTypeDecompilers.getInstance().forFileType(type);
|
||||
if (decompiler != null) {
|
||||
CharSequence text = decompiler.decompile(file);
|
||||
try {
|
||||
@@ -550,19 +492,13 @@ public final class LoadTextUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads content of given virtual file. If limit is {@value UNLIMITED} then full CharSequence will be returned. Else CharSequence
|
||||
* will be truncated by limit if it has bigger length.
|
||||
* @param file Virtual file for content loading
|
||||
* @param limit Maximum characters count or {@value UNLIMITED}
|
||||
* @throws IllegalArgumentException for binary files
|
||||
* @return Full or truncated CharSequence with file content
|
||||
*/
|
||||
@NotNull
|
||||
public static CharSequence loadText(@NotNull final VirtualFile file, int limit) {
|
||||
public static @NotNull CharSequence loadText(@NotNull VirtualFile file, int limit) {
|
||||
FileType type = file.getFileType();
|
||||
if (type.isBinary()) throw new IllegalArgumentException(
|
||||
"Attempt to load truncated text for binary file: " + file.getPresentableUrl() + ". File type: " + type.getName()
|
||||
);
|
||||
if (type.isBinary()) {
|
||||
throw new IllegalArgumentException("Attempt to load truncated text for binary file: " + file.getPresentableUrl() + ". File type: " + type.getName());
|
||||
}
|
||||
|
||||
if (file instanceof LightVirtualFile) {
|
||||
return limitCharSequence(((LightVirtualFile)file).getContent(), limit);
|
||||
@@ -572,38 +508,32 @@ public final class LoadTextUtil {
|
||||
throw new AssertionError("'" + file.getPresentableUrl() + "' is a directory");
|
||||
}
|
||||
try {
|
||||
byte[] bytes = limit == UNLIMITED ? file.contentsToByteArray() :
|
||||
FileUtil.loadFirstAndClose(file.getInputStream(), limit);
|
||||
byte[] bytes = limit == UNLIMITED ? file.contentsToByteArray() : FileUtil.loadFirstAndClose(file.getInputStream(), limit);
|
||||
return getTextByBinaryPresentation(bytes, file);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.debug(e);
|
||||
return Strings.EMPTY_CHAR_SEQUENCE;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CharSequence limitCharSequence(@NotNull CharSequence sequence, int limit) {
|
||||
private static @NotNull CharSequence limitCharSequence(@NotNull CharSequence sequence, int limit) {
|
||||
return limit == UNLIMITED ? sequence : sequence.subSequence(0, Math.min(limit, sequence.length()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CharSequence getTextByBinaryPresentation(final byte @NotNull [] bytes, @NotNull VirtualFile virtualFile) {
|
||||
public static @NotNull CharSequence getTextByBinaryPresentation(byte @NotNull [] bytes, @NotNull VirtualFile virtualFile) {
|
||||
return getTextByBinaryPresentation(bytes, virtualFile, true, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CharSequence getTextByBinaryPresentation(byte @NotNull [] bytes,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
boolean saveDetectedSeparators,
|
||||
boolean saveBOM) {
|
||||
public static @NotNull CharSequence getTextByBinaryPresentation(byte @NotNull [] bytes,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
boolean saveDetectedSeparators,
|
||||
boolean saveBOM) {
|
||||
DetectResult info = detectInternalCharsetAndSetBOM(virtualFile, bytes, bytes.length, saveBOM, virtualFile.getFileType());
|
||||
ConvertResult result = convertBytesAndSetSeparator(bytes, bytes.length, virtualFile, saveDetectedSeparators, info, info.hardCodedCharset);
|
||||
return result.text;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static Set<String> detectAllLineSeparators(@NotNull VirtualFile virtualFile) {
|
||||
static @NotNull Set<String> detectAllLineSeparators(@NotNull VirtualFile virtualFile) {
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = virtualFile.contentsToByteArray();
|
||||
@@ -618,8 +548,7 @@ public final class LoadTextUtil {
|
||||
}
|
||||
|
||||
// written in push way to make sure no-one stores the CharSequence because it came from thread-local byte buffers which will be overwritten soon
|
||||
@NotNull
|
||||
public static FileType processTextFromBinaryPresentationOrNull(@NotNull ByteSequence bytes,
|
||||
public static @NotNull FileType processTextFromBinaryPresentationOrNull(@NotNull ByteSequence bytes,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
boolean saveDetectedSeparators,
|
||||
boolean saveBOM,
|
||||
@@ -631,7 +560,7 @@ public final class LoadTextUtil {
|
||||
CharsetToolkit.GuessedEncoding guessed = detectResult.guessed;
|
||||
CharSequence toProcess;
|
||||
if (internalCharset == null || guessed == CharsetToolkit.GuessedEncoding.BINARY || guessed == CharsetToolkit.GuessedEncoding.INVALID_UTF8) {
|
||||
// the charset was not detected so the file is likely binary
|
||||
// the charset was not detected, so the file is likely binary
|
||||
toProcess = null;
|
||||
}
|
||||
else {
|
||||
@@ -641,13 +570,12 @@ public final class LoadTextUtil {
|
||||
return fileTextProcessor.fun(toProcess);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ConvertResult convertBytesAndSetSeparator(byte @NotNull [] bytes,
|
||||
int length,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
boolean saveDetectedSeparators,
|
||||
@NotNull DetectResult info,
|
||||
@NotNull Charset internalCharset) {
|
||||
private static @NotNull ConvertResult convertBytesAndSetSeparator(byte @NotNull [] bytes,
|
||||
int length,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
boolean saveDetectedSeparators,
|
||||
@NotNull DetectResult info,
|
||||
@NotNull Charset internalCharset) {
|
||||
byte[] bom = info.BOM;
|
||||
int BOMEndOffset = Math.min(length, bom == null ? 0 : bom.length);
|
||||
ConvertResult result = convertBytes(bytes, BOMEndOffset, length, internalCharset);
|
||||
@@ -668,34 +596,29 @@ public final class LoadTextUtil {
|
||||
* @param checkFile if the line separator was not detected before, try to detect it
|
||||
* @return the detected line separator or null
|
||||
*/
|
||||
@Nullable
|
||||
public static String detectLineSeparator(@NotNull VirtualFile file, boolean checkFile) {
|
||||
public static @Nullable String detectLineSeparator(@NotNull VirtualFile file, boolean checkFile) {
|
||||
String lineSeparator = file.getDetectedLineSeparator();
|
||||
if (lineSeparator == null && checkFile) {
|
||||
try {
|
||||
getTextByBinaryPresentation(file.contentsToByteArray(), file);
|
||||
lineSeparator = file.getDetectedLineSeparator();
|
||||
}
|
||||
catch (IOException e) {
|
||||
// null will be returned
|
||||
}
|
||||
catch (IOException ignored) { }
|
||||
}
|
||||
return lineSeparator;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static CharSequence getTextByBinaryPresentation(byte @NotNull [] bytes, @NotNull Charset charset) {
|
||||
public static @NotNull CharSequence getTextByBinaryPresentation(byte @NotNull [] bytes, @NotNull Charset charset) {
|
||||
Pair.NonNull<Charset, byte[]> pair = getOverriddenCharsetByBOM(bytes, charset);
|
||||
byte[] bom = pair.getSecond();
|
||||
|
||||
final ConvertResult result = convertBytes(bytes, Math.min(bom.length, bytes.length), bytes.length, pair.first);
|
||||
ConvertResult result = convertBytes(bytes, Math.min(bom.length, bytes.length), bytes.length, pair.first);
|
||||
return result.text;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ConvertResult convertBytes(byte @NotNull [] bytes,
|
||||
final int startOffset, int endOffset,
|
||||
@NotNull Charset internalCharset) {
|
||||
private static @NotNull ConvertResult convertBytes(byte @NotNull [] bytes,
|
||||
int startOffset, int endOffset,
|
||||
@NotNull Charset internalCharset) {
|
||||
assert startOffset >= 0 && startOffset <= endOffset && endOffset <= bytes.length: startOffset + "," + endOffset+": "+bytes.length;
|
||||
if (internalCharset instanceof SevenBitCharset || internalCharset == StandardCharsets.US_ASCII) {
|
||||
// optimisation: skip byte-to-char conversion for ascii chars
|
||||
@@ -716,7 +639,7 @@ public final class LoadTextUtil {
|
||||
}
|
||||
|
||||
private static class ConvertResult {
|
||||
@NotNull private final CharSequence text;
|
||||
private final @NotNull CharSequence text;
|
||||
private final int CR_count;
|
||||
private final int LF_count;
|
||||
private final int CRLF_count;
|
||||
@@ -753,8 +676,8 @@ public final class LoadTextUtil {
|
||||
}
|
||||
|
||||
private static final Key<AutoDetectionReason> CHARSET_WAS_DETECTED_FROM_BYTES = Key.create("CHARSET_WAS_DETECTED_FROM_BYTES");
|
||||
@Nullable("null if was not detected, otherwise the reason it was")
|
||||
public static AutoDetectionReason getCharsetAutoDetectionReason(@NotNull VirtualFile virtualFile) {
|
||||
|
||||
public static @Nullable("null if was not detected, otherwise the reason it was") AutoDetectionReason getCharsetAutoDetectionReason(@NotNull VirtualFile virtualFile) {
|
||||
return virtualFile.getUserData(CHARSET_WAS_DETECTED_FROM_BYTES);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.extensions.ExtensionPoint;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManagerListener;
|
||||
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeEvent;
|
||||
import com.intellij.openapi.fileTypes.FileTypeListener;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
@@ -73,7 +74,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
public void runActivity(@NotNull Project project) {
|
||||
MessageBusConnection connection = project.getMessageBus().connect();
|
||||
|
||||
ExtensionPoint<KeyedLazyInstance<LanguageSubstitutor>> point = LanguageSubstitutors.getInstance().getPoint();
|
||||
ExtensionPoint<@NotNull KeyedLazyInstance<LanguageSubstitutor>> point = LanguageSubstitutors.getInstance().getPoint();
|
||||
if (point != null) {
|
||||
point.addChangeListener(() -> {
|
||||
if (project.isDisposed()) {
|
||||
@@ -114,9 +115,6 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This code is implemented as static method (and not static constructor, as it was done before) to prevent installing listeners in Upsource
|
||||
*/
|
||||
private static void installGlobalListener() {
|
||||
if (!ourGlobalListenerInstalled.compareAndSet(false, true)) {
|
||||
return;
|
||||
@@ -135,10 +133,9 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
@Override
|
||||
public void after(@NotNull List<? extends @NotNull VFileEvent> events) {
|
||||
Project[] projects = ProjectUtilCore.getOpenProjects();
|
||||
// let PushedFilePropertiesUpdater process all pending vfs events and update file properties before we issue PSI events
|
||||
// let PushedFilePropertiesUpdater process all pending VFS events and update file properties before we issue PSI events
|
||||
for (Project project : projects) {
|
||||
PushedFilePropertiesUpdater updater = PushedFilePropertiesUpdater.getInstance(project);
|
||||
// false in upsource
|
||||
if (updater instanceof PushedFilePropertiesUpdaterImpl) {
|
||||
((PushedFilePropertiesUpdaterImpl)updater).processAfterVfsChanges(events);
|
||||
}
|
||||
@@ -150,8 +147,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiDirectory getCachedDirectory(VirtualFile parent) {
|
||||
private @Nullable PsiDirectory getCachedDirectory(VirtualFile parent) {
|
||||
return parent == null ? null : myFileManager.getCachedDirectory(parent);
|
||||
}
|
||||
|
||||
@@ -176,10 +172,10 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
}
|
||||
|
||||
private void beforeFileDeletion(@NotNull VFileDeleteEvent event) {
|
||||
final VirtualFile vFile = event.getFile();
|
||||
VirtualFile vFile = event.getFile();
|
||||
|
||||
VirtualFile parent = vFile.getParent();
|
||||
final PsiDirectory parentDir = getCachedDirectory(parent);
|
||||
PsiDirectory parentDir = getCachedDirectory(parent);
|
||||
if (parentDir == null) return; // do not notify listeners if parent directory was never accessed via PSI
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(
|
||||
@@ -195,7 +191,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
);
|
||||
}
|
||||
|
||||
// optimization: call myFileManager.removeInvalidFilesAndDirs() once for group of delete events, instead of once for each event
|
||||
// optimization: call myFileManager.removeInvalidFilesAndDirs() once for a group of deletion events, instead of once for each event
|
||||
private void filesDeleted(@NotNull List<? extends VFileEvent> events) {
|
||||
boolean needToRemoveInvalidFilesAndDirs = false;
|
||||
for (VFileEvent event : events) {
|
||||
@@ -203,14 +199,14 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
VirtualFile vFile = de.getFile();
|
||||
VirtualFile parent = vFile.getParent();
|
||||
|
||||
final PsiFile psiFile = myFileManager.getCachedPsiFileInner(vFile);
|
||||
PsiFile psiFile = myFileManager.getCachedPsiFileInner(vFile);
|
||||
PsiElement element;
|
||||
if (psiFile != null) {
|
||||
myFileManager.setViewProvider(vFile, null);
|
||||
element = psiFile;
|
||||
}
|
||||
else {
|
||||
final PsiDirectory psiDir = myFileManager.getCachedDirectory(vFile);
|
||||
PsiDirectory psiDir = myFileManager.getCachedDirectory(vFile);
|
||||
if (psiDir != null) {
|
||||
needToRemoveInvalidFilesAndDirs = true;
|
||||
element = psiDir;
|
||||
@@ -223,7 +219,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
element = null;
|
||||
}
|
||||
}
|
||||
final PsiDirectory parentDir = getCachedDirectory(parent);
|
||||
PsiDirectory parentDir = getCachedDirectory(parent);
|
||||
if (element != null && parentDir != null) {
|
||||
ApplicationManager.getApplication().runWriteAction((ExternalChangeAction)() -> {
|
||||
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
|
||||
@@ -242,14 +238,14 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
DebugUtil.performPsiModification(why, ()-> myFileManager.setViewProvider(vFile, null));
|
||||
}
|
||||
|
||||
private void beforePropertyChange(@NotNull final VFilePropertyChangeEvent event) {
|
||||
final VirtualFile vFile = event.getFile();
|
||||
final String propertyName = event.getPropertyName();
|
||||
private void beforePropertyChange(@NotNull VFilePropertyChangeEvent event) {
|
||||
VirtualFile vFile = event.getFile();
|
||||
String propertyName = event.getPropertyName();
|
||||
|
||||
final FileViewProvider viewProvider = myFileManager.findCachedViewProvider(vFile);
|
||||
FileViewProvider viewProvider = myFileManager.findCachedViewProvider(vFile);
|
||||
|
||||
VirtualFile parent = vFile.getParent();
|
||||
final PsiDirectory parentDir = viewProvider != null && parent != null ? myFileManager.findDirectory(parent) : getCachedDirectory(parent);
|
||||
PsiDirectory parentDir = viewProvider != null && parent != null ? myFileManager.findDirectory(parent) : getCachedDirectory(parent);
|
||||
if (parent != null && parentDir == null) return; // do not notifyListeners event if parent directory was never accessed via PSI
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(
|
||||
@@ -258,7 +254,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
treeEvent.setParent(parentDir);
|
||||
|
||||
if (VirtualFile.PROP_NAME.equals(propertyName)) {
|
||||
final String newName = (String)event.getNewValue();
|
||||
String newName = (String)event.getNewValue();
|
||||
|
||||
if (parentDir == null) return;
|
||||
|
||||
@@ -284,7 +280,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
}
|
||||
}
|
||||
else {
|
||||
final FileViewProvider viewProvider1 = myFileManager.findViewProvider(vFile);
|
||||
FileViewProvider viewProvider1 = myFileManager.findViewProvider(vFile);
|
||||
PsiFile psiFile = viewProvider1.getPsi(viewProvider1.getBaseLanguage());
|
||||
PsiFile psiFile1 = createFileCopyWithNewName(vFile, newName);
|
||||
|
||||
@@ -339,18 +335,18 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void propertyChanged(@NotNull final VFilePropertyChangeEvent event) {
|
||||
final String propertyName = event.getPropertyName();
|
||||
final VirtualFile vFile = event.getFile();
|
||||
private void propertyChanged(@NotNull VFilePropertyChangeEvent event) {
|
||||
String propertyName = event.getPropertyName();
|
||||
VirtualFile vFile = event.getFile();
|
||||
|
||||
FileViewProvider oldFileViewProvider = myFileManager.findCachedViewProvider(vFile);
|
||||
PsiFile oldPsiFile = myFileManager.getCachedPsiFile(vFile);
|
||||
|
||||
VirtualFile parent = vFile.getParent();
|
||||
final PsiDirectory parentDir = oldPsiFile != null && parent != null ? myFileManager.findDirectory(parent) : getCachedDirectory(parent);
|
||||
PsiDirectory parentDir = oldPsiFile != null && parent != null ? myFileManager.findDirectory(parent) : getCachedDirectory(parent);
|
||||
|
||||
if (oldFileViewProvider != null // there is no need to rebuild if there were no PSI in the first place
|
||||
&& FileContentUtilCore.FORCE_RELOAD_REQUESTOR.equals(event.getRequestor())) {
|
||||
if (oldFileViewProvider != null && FileContentUtilCore.FORCE_RELOAD_REQUESTOR.equals(event.getRequestor())) {
|
||||
// there is no need to rebuild if there were no PSI in the first place
|
||||
myFileManager.forceReload(vFile);
|
||||
return;
|
||||
}
|
||||
@@ -401,8 +397,8 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
}
|
||||
}
|
||||
else {
|
||||
final FileViewProvider fileViewProvider = myFileManager.createFileViewProvider(vFile, true);
|
||||
final PsiFile newPsiFile = fileViewProvider.getPsi(fileViewProvider.getBaseLanguage());
|
||||
FileViewProvider fileViewProvider = myFileManager.createFileViewProvider(vFile, true);
|
||||
PsiFile newPsiFile = fileViewProvider.getPsi(fileViewProvider.getBaseLanguage());
|
||||
if (oldPsiFile != null) {
|
||||
if (newPsiFile == null) {
|
||||
clearViewProvider(vFile, "PSI renamed");
|
||||
@@ -493,7 +489,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
});
|
||||
}
|
||||
|
||||
// optimization: call myFileManager.removeInvalidFilesAndDirs() once for group of move events, instead of once for each event
|
||||
// optimization: call myFileManager.removeInvalidFilesAndDirs() once for a group of move events, instead of once for each event
|
||||
private void filesMoved(@NotNull List<? extends VFileEvent> events) {
|
||||
List<PsiElement> oldElements = new ArrayList<>(events.size());
|
||||
List<PsiDirectory> oldParentDirs = new ArrayList<>(events.size());
|
||||
@@ -503,7 +499,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
for (VFileEvent e : events) {
|
||||
VFileMoveEvent event = (VFileMoveEvent)e;
|
||||
|
||||
final VirtualFile vFile = event.getFile();
|
||||
VirtualFile vFile = event.getFile();
|
||||
|
||||
PsiDirectory oldParentDir = myFileManager.findDirectory(event.getOldParent());
|
||||
PsiDirectory newParentDir = myFileManager.findDirectory(event.getNewParent());
|
||||
@@ -515,7 +511,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
if (oldProject != null && oldProject != myProject) {
|
||||
// file moved between projects, remove all associations to the old project
|
||||
myFileManager.removeFilesAndDirsRecursively(vFile);
|
||||
// avoid crash in filePointer.getElement()
|
||||
// avoiding crashes in filePointer.getElement()
|
||||
PsiCopyPasteManager.getInstance().fileMovedOutsideProject(vFile);
|
||||
oldElement = null;
|
||||
oldParentDir = null;
|
||||
@@ -530,15 +526,15 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
for (int i = 0; i < events.size(); i++) {
|
||||
VFileMoveEvent event = (VFileMoveEvent)events.get(i);
|
||||
|
||||
final VirtualFile vFile = event.getFile();
|
||||
VirtualFile vFile = event.getFile();
|
||||
|
||||
final PsiDirectory oldParentDir = oldParentDirs.get(i);
|
||||
final PsiDirectory newParentDir = newParentDirs.get(i);
|
||||
PsiDirectory oldParentDir = oldParentDirs.get(i);
|
||||
PsiDirectory newParentDir = newParentDirs.get(i);
|
||||
if (oldParentDir == null && newParentDir == null) continue;
|
||||
|
||||
final PsiElement oldElement = oldElements.get(i);
|
||||
final PsiElement newElement;
|
||||
final FileViewProvider newViewProvider;
|
||||
PsiElement oldElement = oldElements.get(i);
|
||||
PsiElement newElement;
|
||||
FileViewProvider newViewProvider;
|
||||
if (vFile.isDirectory()) {
|
||||
newElement = myFileManager.findDirectory(vFile);
|
||||
newViewProvider = null;
|
||||
@@ -592,14 +588,14 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiFile createFileCopyWithNewName(VirtualFile vFile, String name) {
|
||||
private @Nullable PsiFile createFileCopyWithNewName(VirtualFile vFile, String name) {
|
||||
// TODO[ik] remove this. Event handling and generation must be in view providers mechanism since we
|
||||
// need to track changes in _all_ psi views (e.g. namespace changes in XML)
|
||||
var typeManager = FileTypeManager.getInstance();
|
||||
if (typeManager.isFileIgnored(name)) return null;
|
||||
var fileType = typeManager.getFileTypeByFileName(name);
|
||||
return PsiFileFactory.getInstance(myManager.getProject()).createFileFromText(name, fileType, "", vFile.getModificationStamp(), true, false);
|
||||
FileTypeManager instance = FileTypeManager.getInstance();
|
||||
if (instance.isFileIgnored(name)) return null;
|
||||
FileType fileTypeByFileName = instance.getFileTypeByFileName(name);
|
||||
return PsiFileFactory.getInstance(myManager.getProject()).createFileFromText(
|
||||
name, fileTypeByFileName, "", vFile.getModificationStamp(), true, false);
|
||||
}
|
||||
|
||||
private static final class MyModuleRootListener implements ModuleRootListener {
|
||||
@@ -613,7 +609,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeRootsChange(@NotNull final ModuleRootEvent event) {
|
||||
public void beforeRootsChange(@NotNull ModuleRootEvent event) {
|
||||
if (event.isCausedByFileTypesChange()) return;
|
||||
ApplicationManager.getApplication().runWriteAction(
|
||||
(ExternalChangeAction)() -> {
|
||||
@@ -628,7 +624,7 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rootsChanged(@NotNull final ModuleRootEvent event) {
|
||||
public void rootsChanged(@NotNull ModuleRootEvent event) {
|
||||
fileManager.dispatchPendingEvents();
|
||||
|
||||
if (event.isCausedByFileTypesChange()) return;
|
||||
@@ -750,13 +746,12 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
myReportedUnloadedPsiChange = false;
|
||||
}
|
||||
|
||||
// group same type events together and call fireForGrouped() for each batch
|
||||
// grouping events of the same type together and calling fireForGrouped() for each batch
|
||||
private void groupAndFire(@NotNull List<? extends VFileEvent> events) {
|
||||
StreamEx.of(events)
|
||||
// group several VFileDeleteEvents together, several VFileMoveEvents together, place all other events into one-element lists
|
||||
.groupRuns((event1, event2) ->
|
||||
event1 instanceof VFileDeleteEvent && event2 instanceof VFileDeleteEvent
|
||||
|| event1 instanceof VFileMoveEvent && event2 instanceof VFileMoveEvent)
|
||||
.groupRuns((e1, e2) -> e1 instanceof VFileDeleteEvent && e2 instanceof VFileDeleteEvent ||
|
||||
e1 instanceof VFileMoveEvent && e2 instanceof VFileMoveEvent)
|
||||
.forEach(this::fireForGrouped);
|
||||
}
|
||||
|
||||
@@ -772,15 +767,15 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
assert subList.size() == 1;
|
||||
if (event instanceof VFileCopyEvent) {
|
||||
VFileCopyEvent ce = (VFileCopyEvent)event;
|
||||
final VirtualFile copy = ce.getNewParent().findChild(ce.getNewChildName());
|
||||
VirtualFile copy = ce.getNewParent().findChild(ce.getNewChildName());
|
||||
if (copy != null) {
|
||||
fileCreated(copy); // no need to group creation
|
||||
fileCreated(copy); // no need to group file creation events
|
||||
}
|
||||
}
|
||||
else if (event instanceof VFileCreateEvent) {
|
||||
VirtualFile file = event.getFile();
|
||||
if (file != null) {
|
||||
fileCreated(file); // no need to group creation
|
||||
fileCreated(file); // no need to group file creation events
|
||||
}
|
||||
}
|
||||
else if (event instanceof VFilePropertyChangeEvent) {
|
||||
@@ -789,4 +784,3 @@ public final class PsiVFSListener implements BulkFileListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user