Use JvmMetadataVersion where appropriate instead of bytecode version

This commit is contained in:
Alexander Udalov
2016-01-13 21:24:20 +03:00
parent bd47e9d47b
commit b587d3a78d
19 changed files with 65 additions and 56 deletions
@@ -29,7 +29,7 @@ import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
import org.jetbrains.kotlin.load.kotlin.PackageParts;
import org.jetbrains.kotlin.name.FqName;
@@ -123,7 +123,7 @@ public class ClassFileFactory implements OutputFileCollection {
try {
ByteArrayOutputStream moduleMapping = new ByteArrayOutputStream(4096);
DataOutputStream dataOutStream = new DataOutputStream(moduleMapping);
int[] version = JvmBytecodeBinaryVersion.INSTANCE.toArray();
int[] version = JvmMetadataVersion.INSTANCE.toArray();
dataOutStream.writeInt(version.length);
for (int number : version) {
dataOutStream.writeInt(number);
@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import kotlin.collections.CollectionsKt;
import kotlin.text.StringsKt;
import kotlin.jvm.functions.Function1;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
import org.jetbrains.kotlin.load.kotlin.ModuleMapping;
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityUtilsKt;
import org.jetbrains.kotlin.psi.KtFile;
@@ -224,7 +224,7 @@ public class JvmCodegenUtil {
}
public static void writeAbiVersion(@NotNull AnnotationVisitor av) {
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmBytecodeBinaryVersion.INSTANCE.toArray());
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmMetadataVersion.INSTANCE.toArray());
}
public static void writeModuleName(@NotNull AnnotationVisitor av, @NotNull GenerationState state) {
@@ -31,9 +31,9 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.diagnostics.*;
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages;
import org.jetbrains.kotlin.load.java.JavaBindingContext;
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
import org.jetbrains.kotlin.load.java.components.TraceBasedErrorReporter;
import org.jetbrains.kotlin.load.java.components.TraceBasedErrorReporter.AbiVersionErrorData;
import org.jetbrains.kotlin.load.java.components.TraceBasedErrorReporter.MetadataVersionErrorData;
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.AnalyzingUtils;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -146,26 +146,27 @@ public final class AnalyzerWithCompilerReport {
}
@NotNull
private List<AbiVersionErrorData> getAbiVersionErrors() {
private List<MetadataVersionErrorData> getAbiVersionErrors() {
assert analysisResult != null;
BindingContext bindingContext = analysisResult.getBindingContext();
Collection<String> errorClasses = bindingContext.getKeys(TraceBasedErrorReporter.ABI_VERSION_ERRORS);
List<AbiVersionErrorData> result = new ArrayList<AbiVersionErrorData>(errorClasses.size());
Collection<String> errorClasses = bindingContext.getKeys(TraceBasedErrorReporter.METADATA_VERSION_ERRORS);
List<MetadataVersionErrorData> result = new ArrayList<MetadataVersionErrorData>(errorClasses.size());
for (String kotlinClass : errorClasses) {
result.add(bindingContext.get(TraceBasedErrorReporter.ABI_VERSION_ERRORS, kotlinClass));
result.add(bindingContext.get(TraceBasedErrorReporter.METADATA_VERSION_ERRORS, kotlinClass));
}
return result;
}
private void reportAbiVersionErrors(@NotNull List<AbiVersionErrorData> errors) {
for (AbiVersionErrorData data : errors) {
private void reportMetadataVersionErrors(@NotNull List<MetadataVersionErrorData> errors) {
for (MetadataVersionErrorData data : errors) {
String path = toSystemDependentName(data.getFilePath());
messageCollector.report(
CompilerMessageSeverity.ERROR,
"Class '" + JvmClassName.byClassId(data.getClassId()) + "' was compiled with an incompatible version of Kotlin. " +
"Its ABI version is " + data.getActualVersion() + ", expected ABI version is " + JvmBytecodeBinaryVersion.INSTANCE,
"The binary version of its metadata is " + data.getActualVersion() +
", expected version is " + JvmMetadataVersion.INSTANCE,
CompilerMessageLocation.create(path, -1, -1, null)
);
}
@@ -265,10 +266,10 @@ public final class AnalyzerWithCompilerReport {
public void analyzeAndReport(@NotNull Collection<KtFile> files, @NotNull Function0<AnalysisResult> analyzer) {
analysisResult = analyzer.invoke();
reportSyntaxErrors(files);
List<AbiVersionErrorData> abiVersionErrors = getAbiVersionErrors();
List<MetadataVersionErrorData> abiVersionErrors = getAbiVersionErrors();
reportDiagnostics(analysisResult.getBindingContext().getDiagnostics(), messageCollector, !abiVersionErrors.isEmpty());
if (hasErrors()) {
reportAbiVersionErrors(abiVersionErrors);
reportMetadataVersionErrors(abiVersionErrors);
}
reportIncompleteHierarchies();
reportAlternativeSignatureErrors();
@@ -32,20 +32,22 @@ class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorReporter {
companion object {
private val LOG = Logger.getInstance(TraceBasedErrorReporter::class.java)
@JvmField val ABI_VERSION_ERRORS: WritableSlice<String, AbiVersionErrorData> = Slices.createCollectiveSlice()
@JvmField
val METADATA_VERSION_ERRORS: WritableSlice<String, MetadataVersionErrorData> = Slices.createCollectiveSlice()
// TODO: MutableList is a workaround for KT-5792 Covariant types in Kotlin translated to wildcard types in Java
@JvmField val INCOMPLETE_HIERARCHY: WritableSlice<ClassDescriptor, MutableList<String>> = Slices.createCollectiveSlice()
@JvmField
val INCOMPLETE_HIERARCHY: WritableSlice<ClassDescriptor, MutableList<String>> = Slices.createCollectiveSlice()
}
data class AbiVersionErrorData(
data class MetadataVersionErrorData(
val actualVersion: BinaryVersion,
val filePath: String,
val classId: ClassId
)
override fun reportIncompatibleAbiVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
trace.record(ABI_VERSION_ERRORS, filePath, AbiVersionErrorData(actualVersion, filePath, classId))
override fun reportIncompatibleMetadataVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
trace.record(METADATA_VERSION_ERRORS, filePath, MetadataVersionErrorData(actualVersion, filePath, classId))
}
override fun reportIncompleteHierarchy(descriptor: ClassDescriptor, unresolvedSuperClasses: List<String>) {
+1 -1
View File
@@ -9,5 +9,5 @@ public fun kotlin.Throwable.printStackTrace(writer: java.io.PrintWriter): kotlin
(note: this may be caused by the fact that some classes compiled with an incompatible version of Kotlin were found in the classpath. Such classes cannot be loaded properly by this version of Kotlin compiler. See below for more information)
1.printStackTrace(2, 3)
^
compiler/testData/cli/jvm/wrongAbiVersionLib/bin/ClassWithWrongAbiVersion.class: error: class 'ClassWithWrongAbiVersion' was compiled with an incompatible version of Kotlin. Its ABI version is 0.30.0, expected ABI version is $ABI_VERSION$
compiler/testData/cli/jvm/wrongAbiVersionLib/bin/ClassWithWrongAbiVersion.class: error: class 'ClassWithWrongAbiVersion' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 0.30.0, expected version is $ABI_VERSION$
COMPILATION_ERROR
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.cli.common.ExitCode;
import org.jetbrains.kotlin.cli.common.KotlinVersion;
import org.jetbrains.kotlin.cli.js.K2JSCompiler;
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler;
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.Tmpdir;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
@@ -72,7 +72,7 @@ public class CliBaseTest {
public static String getNormalizedCompilerOutput(@NotNull String pureOutput, @NotNull ExitCode exitCode, @NotNull String testDataDir) {
String normalizedOutputWithoutExitCode = pureOutput
.replace(new File(testDataDir).getAbsolutePath(), "$TESTDATA_DIR$")
.replace("expected ABI version is " + JvmBytecodeBinaryVersion.INSTANCE, "expected ABI version is $ABI_VERSION$")
.replace("expected version is " + JvmMetadataVersion.INSTANCE, "expected version is $ABI_VERSION$")
.replace("\\", "/")
.replace(KotlinVersion.VERSION, "$VERSION$");
@@ -21,7 +21,7 @@ import com.google.common.collect.Collections2;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion;
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.test.ConfigurationKind;
@@ -146,6 +146,6 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
int[] version = (int[]) CodegenTestUtil.getAnnotationAttribute(annotation, VERSION_FIELD_NAME);
assertNotNull(version);
assertTrue("Annotation " + annotationFqName + " is written with an unsupported format",
JvmBytecodeBinaryVersion.create(version).isCompatible());
JvmMetadataVersion.create(version).isCompatible());
}
}
@@ -71,7 +71,7 @@ fun LazyJavaResolverContext.resolveKotlinBinaryClass(kotlinClass: KotlinJvmBinar
val header = kotlinClass.classHeader
return when {
!header.metadataVersion.isCompatible() -> {
components.errorReporter.reportIncompatibleAbiVersion(kotlinClass.classId, kotlinClass.location, header.metadataVersion)
components.errorReporter.reportIncompatibleMetadataVersion(kotlinClass.classId, kotlinClass.location, header.metadataVersion)
KotlinClassLookupResult.NotFound
}
header.kind == KotlinClassHeader.Kind.CLASS -> {
@@ -116,7 +116,7 @@ public final class DeserializedDescriptorResolver {
public String[] readData(@NotNull KotlinJvmBinaryClass kotlinClass, @NotNull Set<KotlinClassHeader.Kind> expectedKinds) {
KotlinClassHeader header = kotlinClass.getClassHeader();
if (!header.getMetadataVersion().isCompatible()) {
errorReporter.reportIncompatibleAbiVersion(kotlinClass.getClassId(), kotlinClass.getLocation(), header.getMetadataVersion());
errorReporter.reportIncompatibleMetadataVersion(kotlinClass.getClassId(), kotlinClass.getLocation(), header.getMetadataVersion());
}
else if (expectedKinds.contains(header.getKind())) {
return header.getAnnotationData();
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.serialization.jvm.JvmPackageTable
import java.io.ByteArrayInputStream
import java.io.DataInputStream
@@ -28,22 +27,22 @@ class ModuleMapping private constructor(val packageFqName2Parts: Map<String, Pac
}
companion object {
@JvmField val MAPPING_FILE_EXT: String = "kotlin_module"
@JvmField
val MAPPING_FILE_EXT: String = "kotlin_module"
@JvmField val EMPTY: ModuleMapping = ModuleMapping(emptyMap())
@JvmField
val EMPTY: ModuleMapping = ModuleMapping(emptyMap())
fun create(proto: ByteArray? = null): ModuleMapping {
if (proto == null) {
return EMPTY
}
val inputStream = DataInputStream(ByteArrayInputStream(proto))
val size = inputStream.readInt()
val version = JvmBytecodeBinaryVersion.create((0..size - 1).map { inputStream.readInt() }.toIntArray())
val stream = DataInputStream(ByteArrayInputStream(proto))
val version = JvmMetadataVersion.create(IntArray(stream.readInt()) { stream.readInt() })
if (version.isCompatible()) {
val parseFrom = JvmPackageTable.PackageTable.parseFrom(inputStream)
val parseFrom = JvmPackageTable.PackageTable.parseFrom(stream)
if (parseFrom != null) {
val packageFqNameParts = hashMapOf<String, PackageParts>()
parseFrom.packagePartsList.forEach {
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.load.java.components
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
@@ -29,14 +29,14 @@ object RuntimeErrorReporter : ErrorReporter {
throw IllegalStateException("Incomplete hierarchy for class ${descriptor.name}, unresolved classes $unresolvedSuperClasses")
}
override fun reportIncompatibleAbiVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
throw IllegalStateException("Incompatible ABI version of $classId: $actualVersion " +
"(expected version is ${JvmBytecodeBinaryVersion.INSTANCE})")
override fun reportIncompatibleMetadataVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
throw IllegalStateException("Incompatible binary version of $classId: $actualVersion " +
"(expected version is ${JvmMetadataVersion.INSTANCE})")
}
override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) {
// TODO: use DescriptorRenderer
throw IllegalStateException("Cannot infer visibility for class ${descriptor.name}")
throw IllegalStateException("Cannot infer visibility for $descriptor")
}
override fun reportLoadingError(message: String, exception: Exception?) {
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.name.ClassId;
import java.util.List;
public interface ErrorReporter {
void reportIncompatibleAbiVersion(@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion);
void reportIncompatibleMetadataVersion(@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion);
void reportIncompleteHierarchy(@NotNull ClassDescriptor descriptor, @NotNull List<String> unresolvedSuperClasses);
@@ -35,7 +35,7 @@ public interface ErrorReporter {
ErrorReporter DO_NOTHING = new ErrorReporter() {
@Override
public void reportIncompatibleAbiVersion(
public void reportIncompatibleMetadataVersion(
@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion
) {
}
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
import org.jetbrains.kotlin.idea.decompiler.textBuilder.ResolverForDecompiler
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
import org.jetbrains.kotlin.idea.decompiler.textBuilder.defaultDecompilerRendererOptions
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.types.flexibility
@@ -83,7 +83,7 @@ fun buildDecompiledTextForClassFile(
if (!classHeader.metadataVersion.isCompatible()) {
return DecompiledText(
INCOMPATIBLE_ABI_VERSION_COMMENT
.replace(CURRENT_ABI_VERSION_MARKER, JvmBytecodeBinaryVersion.INSTANCE.toString())
.replace(CURRENT_ABI_VERSION_MARKER, JvmMetadataVersion.INSTANCE.toString())
.replace(FILE_ABI_VERSION_MARKER, classHeader.metadataVersion.toString()),
mapOf()
)
@@ -36,7 +36,7 @@ class LoggingErrorReporter(private val log: Logger) : ErrorReporter {
log.error("Could not infer visibility for $descriptor")
}
override fun reportIncompatibleAbiVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
override fun reportIncompatibleMetadataVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
log.error("Incompatible ABI version for class $classId, actual version: $actualVersion")
}
}
+1 -1
View File
@@ -567,7 +567,7 @@
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.js.KotlinJavaScriptMetaFileDecompiler"/>
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInDecompiler"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinAbiVersionIndex"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinMetadataVersionIndex"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinJavaScriptAbiVersionIndex"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinClassFileIndex"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinJavaScriptMetaFileIndex"/>
@@ -22,15 +22,15 @@ import com.intellij.util.indexing.FileBasedIndex
import com.intellij.util.indexing.FileContent
import org.jetbrains.kotlin.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.*
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersionIndex>(
KotlinAbiVersionIndex::class.java, { JvmBytecodeBinaryVersion.create(it) }
object KotlinMetadataVersionIndex : KotlinAbiVersionIndexBase<KotlinMetadataVersionIndex>(
KotlinMetadataVersionIndex::class.java, { JvmMetadataVersion.create(it) }
) {
override fun getIndexer() = INDEXER
@@ -38,7 +38,7 @@ object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersionIndex>(
override fun getVersion() = VERSION
private val VERSION = 2
private val VERSION = 3
private val kotlinAnnotationsDesc = setOf(
KOTLIN_CLASS,
@@ -61,7 +61,7 @@ object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersionIndex>(
return object : AnnotationVisitor(Opcodes.ASM5) {
override fun visit(name: String, value: Any) {
if (name == VERSION_FIELD_NAME && value is IntArray) {
version = JvmBytecodeBinaryVersion.create(value)
version = JvmMetadataVersion.create(value)
}
}
}
@@ -71,7 +71,7 @@ object KotlinAbiVersionIndex : KotlinAbiVersionIndexBase<KotlinAbiVersionIndex>(
if (annotationPresent && version == null) {
// No version at all because the class is too old, or version is set to something weird
version = JvmBytecodeBinaryVersion.INVALID_VERSION
version = JvmMetadataVersion.INVALID_VERSION
}
if (version != null) mapOf(version!! to null) else mapOf()
@@ -69,7 +69,7 @@ public class KotlinRuntimeLibraryUtil {
@NotNull
public static Collection<VirtualFile> getLibraryRootsWithAbiIncompatibleKotlinClasses(@NotNull Project project) {
return getLibraryRootsWithAbiIncompatibleVersion(
project, KotlinAbiVersionIndex.INSTANCE,
project, KotlinMetadataVersionIndex.INSTANCE,
new Function1<Module, Boolean>() {
@Override
public Boolean invoke(@Nullable Module module) {
@@ -62,7 +62,7 @@ class KotlinUpdatePluginComponent : ApplicationComponent {
// Force update indices for files under config directory
val fileBasedIndex = FileBasedIndex.getInstance()
fileBasedIndex.requestRebuild(KotlinAbiVersionIndex.name)
fileBasedIndex.requestRebuild(KotlinMetadataVersionIndex.name)
fileBasedIndex.requestRebuild(KotlinJavaScriptAbiVersionIndex.name)
fileBasedIndex.requestRebuild(KotlinClassFileIndex.KEY)
fileBasedIndex.requestRebuild(KotlinJavaScriptMetaFileIndex.KEY)
@@ -23,6 +23,7 @@ import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.jps.incremental.CacheVersion.Action
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import java.io.File
private val NORMAL_VERSION = 8
@@ -47,7 +48,13 @@ class CacheVersion(
get() = versionFile.readText().toInt()
private val expectedVersion: Int
get() = ownVersion * 1000000 + JvmBytecodeBinaryVersion.INSTANCE.major * 1000 + JvmBytecodeBinaryVersion.INSTANCE.minor
get() {
val metadata = JvmMetadataVersion.INSTANCE
val bytecode = JvmBytecodeBinaryVersion.INSTANCE
return ownVersion * 1000000 +
bytecode.major * 10000 + bytecode.minor * 100 +
metadata.major * 1000 + metadata.minor
}
fun checkVersion(): Action =
when (versionFile.exists() to isEnabled) {