Revert "IJPL-846 refactor (cannot get rid of awaitWithCheckCanceled yet)"

This reverts commit 2815ddb2bd068aeb765f12d6791fce22a6c1b4c5.

GitOrigin-RevId: 8c0e45657a7bdc99988c8761a3d000d253d051d7
This commit is contained in:
Vladimir Krivosheev
2024-03-21 21:25:14 +00:00
committed by intellij-monorepo-bot
parent d0b79f4252
commit e02c4cd3e6
6 changed files with 81 additions and 86 deletions
@@ -13,7 +13,7 @@ import java.io.IOException;
* @deprecated use `TextMateService#readBundle` or `TextMateBundleReader`
*/
@Deprecated
public final class BundleFactory {
public class BundleFactory {
private final PlistReader myPlistReader;
public BundleFactory(PlistReader plistReader) {
@@ -21,16 +21,17 @@ public final class BundleFactory {
}
/**
* Create a bundle object from directory.
* Return {code}null{code} if a bundle type can't be defined or
* if IO exception occurred while reading the directory.
* Create bundle object from directory.
* Return {code}null{code} if bundle type can't be defined or
* if IO exception occurred while reading directory.
*
* @return Bundle object or null
* @deprecated use `TextMateService#readBundle#readGrammars` or `TextMateBundleReader`
*/
@Deprecated
public @Nullable Bundle fromDirectory(@NotNull File directory) throws IOException {
final BundleType type = BundleType.Companion.detectBundleType(directory.toPath());
@Nullable
public Bundle fromDirectory(@NotNull File directory) throws IOException {
final BundleType type = BundleType.detectBundleType(directory.toPath());
return switch (type) {
case TEXTMATE -> fromTextMateBundle(directory);
case SUBLIME -> new Bundle(directory.getName(), directory.getPath(), type);
@@ -4,6 +4,9 @@ import org.jetbrains.plugins.textmate.Constants
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.extension
import kotlin.io.path.isDirectory
import kotlin.io.path.isRegularFile
import kotlin.io.path.name
import kotlin.streams.asSequence
enum class BundleType {
@@ -14,7 +17,7 @@ enum class BundleType {
companion object {
/**
* Detect a bundle type by directory.
* Detect bundle type by directory.
*
* @param directory Bundle directory.
* @return bundle type.
@@ -23,34 +26,34 @@ enum class BundleType {
*/
@JvmStatic
fun detectBundleType(directory: Path?): BundleType {
if (directory == null || !Files.isDirectory(directory)) {
return UNDEFINED
}
if (directory != null && directory.isDirectory()) {
if ("tmBundle".equals(directory.extension, ignoreCase = true)) {
return TEXTMATE
}
val packageJson = directory.resolve(Constants.PACKAGE_JSON_NAME)
if (packageJson.isRegularFile()) {
return VSCODE
}
if (directory.extension.endsWith(".tmBundle", ignoreCase = true)) {
return TEXTMATE
}
val packageJson = directory.resolve(Constants.PACKAGE_JSON_NAME)
if (Files.isRegularFile(packageJson)) {
return VSCODE
}
val hasTmFiles = runCatching {
Files.list(directory).use { children ->
children.asSequence().any { child ->
val name = child.fileName.toString()
name.endsWith(".tmLanguage", ignoreCase = true) || name.endsWith(".tmPreferences", ignoreCase = true)
val hasTmFiles = runCatching {
Files.list(directory).use { children ->
children.asSequence().any { child ->
child.name.endsWith(".tmLanguage", ignoreCase = true) ||
child.name.endsWith(".tmPreferences", ignoreCase = true)
}
}
}
}
if (hasTmFiles.getOrNull() == true) {
return SUBLIME
}
if (hasTmFiles.getOrNull() == true) {
return SUBLIME
}
val infoPlist = directory.resolve(Constants.BUNDLE_INFO_PLIST_NAME)
val hasInfoPlistFile = Files.isRegularFile(infoPlist)
return if (hasInfoPlistFile) TEXTMATE else UNDEFINED
val infoPlist = directory.resolve(Constants.BUNDLE_INFO_PLIST_NAME)
val hasInfoPlistFile = infoPlist.isRegularFile()
if (hasInfoPlistFile) {
return TEXTMATE
}
}
return UNDEFINED
}
}
}
@@ -60,7 +60,7 @@ public final class TestUtil {
public static TextMateBundleReader readBundle(String bundleName) {
Path bundleDirectory = getBundleDirectory(bundleName);
BundleType bundleType = BundleType.Companion.detectBundleType(bundleDirectory);
BundleType bundleType = BundleType.detectBundleType(bundleDirectory);
return switch (bundleType) {
case TEXTMATE -> readTextMateBundle(bundleDirectory);
case SUBLIME -> readSublimeBundle(bundleDirectory);
@@ -25,7 +25,7 @@ public abstract class TextMateService {
}
/**
* Create a bundle object from a given directory.
* Create bundle object from given directory.
*
* @return bundle object or {@code null} if directory doesn't exist or bundle type can't be defined
*/
@@ -38,7 +38,7 @@ public abstract class TextMateService {
* Unregister all and register all enabled bundles in IDE {@link TextMateUserBundlesSettings#getBundles()}, {@link TextMateBuiltinBundlesSettings#builtinBundles}
* 1. read all enabled bundles
* 2. prepare syntax table of supported languages
* 3. prepare preference table of enabled bundles
* 3. prepare preferences table of enabled bundles
* 4. fill the extensions mapping for {@link TextMateFileType}
*/
public abstract void reloadEnabledBundles();
@@ -63,7 +63,7 @@ public abstract class TextMateService {
/**
* @return custom highlighting colors defined inside bundles (not in themes).
* Note that background color in text attributes is stored in raw format and isn't merged with a default background.
* Note that background color in text attributes is stored in raw format and isn't merged with default background.
*/
@NotNull
public abstract Map<CharSequence, TextMateTextAttributesAdapter> getCustomHighlightingColors();
@@ -18,8 +18,6 @@ import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.util.text.Strings
import com.intellij.util.containers.Interner
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.TestOnly
import org.jetbrains.plugins.textmate.TextMateService.LOG
@@ -40,7 +38,7 @@ import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.Volatile
class TextMateServiceImpl(private val scope: CoroutineScope) : TextMateService() {
class TextMateServiceImpl(private val myScope: CoroutineScope) : TextMateService() {
private var builtinBundlesDisabled = false
@Volatile
@@ -87,7 +85,7 @@ class TextMateServiceImpl(private val scope: CoroutineScope) : TextMateService()
builtInBundles.filter { !turnedOffBundleNames.contains(it.name) }
}
registerBundlesInParallel(
scope = scope,
scope = myScope,
bundlesToLoad = bundlesToEnable,
registrar = { registerBundle(Path.of(it.path), newExtensionsMapping) },
)
@@ -103,9 +101,9 @@ class TextMateServiceImpl(private val scope: CoroutineScope) : TextMateService()
}
if (!bundlesToLoad.isEmpty()) {
registerBundlesInParallel(
scope = scope,
scope = myScope,
bundlesToLoad = bundlesToLoad,
registrar = { registerBundle(Path.of(it.path), newExtensionsMapping) },
registrar = { bundleToLoad -> registerBundle(Path.of(bundleToLoad.path), newExtensionsMapping) },
registrationFailed = { bundleToLoad ->
val bundleName = bundleToLoad.name
val errorMessage = TextMateBundle.message("textmate.cant.register.bundle", bundleName)
@@ -200,29 +198,28 @@ class TextMateServiceImpl(private val scope: CoroutineScope) : TextMateService()
}
override fun readBundle(directory: Path?): TextMateBundleReader? {
if (directory == null) {
return null
}
val bundleType = detectBundleType(directory)
return when (bundleType) {
BundleType.TEXTMATE -> readTextMateBundle(directory)
BundleType.SUBLIME -> readSublimeBundle(directory)
BundleType.VSCODE -> readVSCBundle { relativePath ->
try {
return@readVSCBundle Files.newInputStream(directory.resolve(relativePath))
}
catch (e: NoSuchFileException) {
LOG.warn("Cannot find referenced file `$relativePath` in bundle `$directory`")
return@readVSCBundle null
}
catch (e: Throwable) {
LOG.warn("Cannot read referenced file `$relativePath` in bundle `$directory`", e)
return@readVSCBundle null
if (directory != null) {
val bundleType = detectBundleType(directory)
return when (bundleType) {
BundleType.TEXTMATE -> readTextMateBundle(directory)
BundleType.SUBLIME -> readSublimeBundle(directory)
BundleType.VSCODE -> readVSCBundle { relativePath: String ->
try {
return@readVSCBundle Files.newInputStream(directory.resolve(relativePath))
}
catch (e: NoSuchFileException) {
LOG.warn("Cannot find referenced file `$relativePath` in bundle `$directory`")
return@readVSCBundle null
}
catch (e: Throwable) {
LOG.warn("Cannot read referenced file `$relativePath` in bundle `$directory`", e)
return@readVSCBundle null
}
}
BundleType.UNDEFINED -> null
}
BundleType.UNDEFINED -> null
}
return null
}
private fun ensureInitialized() {
@@ -239,14 +236,15 @@ class TextMateServiceImpl(private val scope: CoroutineScope) : TextMateService()
}
}
private suspend fun registerBundle(directory: Path?, extensionMapping: MutableMap<TextMateFileNameMatcher, CharSequence>): Boolean {
val reader = withContext(Dispatchers.IO) {
readBundle(directory)
} ?: return false
registerLanguageSupport(reader, extensionMapping)
registerPreferences(reader)
registerSnippets(reader)
return true
private fun registerBundle(directory: Path?, extensionMapping: MutableMap<TextMateFileNameMatcher, CharSequence>): Boolean {
val reader = readBundle(directory)
if (reader != null) {
registerLanguageSupport(reader, extensionMapping)
registerPreferences(reader)
registerSnippets(reader)
return true
}
return false
}
private fun registerSnippets(reader: TextMateBundleReader) {
@@ -10,14 +10,13 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.future.asCompletableFuture
import kotlinx.coroutines.launch
import java.util.concurrent.CancellationException
import java.util.function.Consumer
@IntellijInternalApi
@JvmOverloads
internal fun registerBundlesInParallel(scope: CoroutineScope,
bundlesToLoad: List<TextMateBundleToLoad>,
registrar: suspend (TextMateBundleToLoad) -> Boolean,
registrar: (TextMateBundleToLoad) -> Boolean,
registrationFailed: Consumer<TextMateBundleToLoad>? = null) {
fun handleError(bundleToLoad: TextMateBundleToLoad, t: Throwable? = null) {
if (registrationFailed == null || ApplicationManager.getApplication().isHeadlessEnvironment) {
@@ -30,27 +29,21 @@ internal fun registerBundlesInParallel(scope: CoroutineScope,
}
}
val initializationJob = scope.launch {
for (bundleToLoad in bundlesToLoad) {
val initializationJob = scope.launch(Dispatchers.IO) {
bundlesToLoad.map { bundleToLoad ->
launch {
val registered = try {
runCatching {
registrar(bundleToLoad)
}
catch (e: CancellationException) {
throw e
}
catch (e: Throwable) {
handleError(bundleToLoad, e)
null
}
if (registered != null && !registered) {
handleError(bundleToLoad)
}.onFailure { t ->
handleError(bundleToLoad, t)
}.onSuccess { registered ->
if (!registered) {
handleError(bundleToLoad)
}
}
}
}
}
ProgressIndicatorUtils.awaitWithCheckCanceled(initializationJob.asCompletableFuture())
}