diff --git a/libraries/examples/annotation-processor-example/src/main/kotlin/example/ExampleAnnotationProcessor.kt b/libraries/examples/annotation-processor-example/src/main/kotlin/example/ExampleAnnotationProcessor.kt index 34227456f0b..5f4d9fc56f2 100644 --- a/libraries/examples/annotation-processor-example/src/main/kotlin/example/ExampleAnnotationProcessor.kt +++ b/libraries/examples/annotation-processor-example/src/main/kotlin/example/ExampleAnnotationProcessor.kt @@ -28,6 +28,10 @@ class ExampleAnnotationProcessor : AbstractProcessor() { processAnnotation(roundEnv, annotation, prefix) } + for (errorElement in roundEnv.getElementsAnnotatedWith(GenError::class.java)) { + processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, "GenError element", errorElement) + } + return true } @@ -67,7 +71,9 @@ class ExampleAnnotationProcessor : AbstractProcessor() { override fun getSupportedSourceVersion() = SourceVersion.RELEASE_6 - override fun getSupportedAnnotationTypes() = ANNOTATION_TO_PREFIX.keys.map { it.java.canonicalName }.toSet() + override fun getSupportedAnnotationTypes(): Set { + return ANNOTATION_TO_PREFIX.keys.map { it.java.canonicalName }.toSet() + GenError::class.java.canonicalName + } override fun getSupportedOptions() = setOf(SUFFIX_OPTION, GENERATE_KOTLIN_CODE_OPTION, GENERATE_ERROR) } \ No newline at end of file diff --git a/libraries/examples/annotation-processor-example/src/main/kotlin/example/annotations.kt b/libraries/examples/annotation-processor-example/src/main/kotlin/example/annotations.kt index a5833ac1918..25222c6fc04 100644 --- a/libraries/examples/annotation-processor-example/src/main/kotlin/example/annotations.kt +++ b/libraries/examples/annotation-processor-example/src/main/kotlin/example/annotations.kt @@ -15,4 +15,6 @@ annotation class ExampleBinaryAnnotation @Inherited @Retention(AnnotationRetention.RUNTIME) -annotation class ExampleRuntimeAnnotation \ No newline at end of file +annotation class ExampleRuntimeAnnotation + +annotation class GenError \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt index 626e462b5ce..44686007068 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kapt3IT.kt @@ -301,6 +301,32 @@ open class Kapt3IT : Kapt3BaseIT() { } } + @Test + fun testLocationMapping() { + val project = Project("locationMapping", GRADLE_VERSION, directoryPrefix = "kapt2") + + project.build("build") { + assertFailed() + + assertContains("Test.java:9: error: GenError element") + assertContains("Test.java:17: error: GenError element") + } + + project.projectDir.getFileByName("build.gradle").modify { + it.replace("mapDiagnosticLocations = false", "mapDiagnosticLocations = true") + } + + project.build("build") { + assertFailed() + + assertNotContains("Test.java:9: error: GenError element") + assertNotContains("Test.java:17: error: GenError element") + + assertContains("test.kt:3: error: GenError element") + assertContains("test.kt:7: error: GenError element") + } + } + @Test fun testChangesInLocalAnnotationProcessor() { val project = Project("localAnnotationProcessor", GRADLE_VERSION, directoryPrefix = "kapt2") diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/locationMapping/build.gradle b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/locationMapping/build.gradle new file mode 100644 index 00000000000..9e07222662c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/locationMapping/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + mavenLocal() + mavenCentral() + } + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +apply plugin: "java" +apply plugin: "kotlin" +apply plugin: "kotlin-kapt" + +repositories { + mavenLocal() + mavenCentral() +} + +dependencies { + compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + compile "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version" + kapt "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version" + testCompile 'junit:junit:4.12' +} + +kapt { + mapDiagnosticLocations = false +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/locationMapping/src/main/java/test.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/locationMapping/src/main/java/test.kt new file mode 100644 index 00000000000..48b8f12a6f7 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kapt2/locationMapping/src/main/java/test.kt @@ -0,0 +1,8 @@ +package example + +class Test { + @field:example.GenError + val a: String + + fun b(@example.GenError a: Boolean) {} +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt index 3c4df43c4a2..46b58d33d06 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/Kapt3KotlinGradleSubplugin.kt @@ -278,6 +278,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin { pluginOptions += SubpluginOption("useLightAnalysis", "${kaptExtension.useLightAnalysis}") pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}") + pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}") pluginOptions += FilesSubpluginOption("stubs", listOf(getKaptStubsDir())) if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") { diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KaptExtension.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KaptExtension.kt index 3e52bde5a30..77fbeea3159 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KaptExtension.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KaptExtension.kt @@ -30,6 +30,8 @@ open class KaptExtension { open var correctErrorTypes: Boolean = false + open var mapDiagnosticLocations: Boolean = false + open var processors: String = "" /** Explicit opt-in switch for Kapt caching. Should be used when annotation processors used by this project are diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java index 4af6b7ac787..f0a1eb46eee 100644 --- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java @@ -55,6 +55,9 @@ public class KaptJVMCompilerMojo extends K2JVMCompileMojo { @Parameter private boolean correctErrorTypes = false; + @Parameter + private boolean mapDiagnosticLocations = false; + @Parameter private List annotationProcessorArgs; @@ -94,6 +97,7 @@ public class KaptJVMCompilerMojo extends K2JVMCompileMojo { options.add(new KaptOption("aptOnly", true)); options.add(new KaptOption("useLightAnalysis", useLightAnalysis)); options.add(new KaptOption("correctErrorTypes", correctErrorTypes)); + options.add(new KaptOption("mapDiagnosticLocations", mapDiagnosticLocations)); options.add(new KaptOption("processors", annotationProcessors)); if (arguments.getVerbose()) { diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt index 4a832989c9e..979f8d7203e 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Extension.kt @@ -71,12 +71,13 @@ class ClasspathBasedKapt3Extension( aptMode: AptMode, val useLightAnalysis: Boolean, correctErrorTypes: Boolean, + mapDiagnosticLocations: Boolean, pluginInitializedTime: Long, logger: KaptLogger, compilerConfiguration: CompilerConfiguration ) : AbstractKapt3Extension(compileClasspath, annotationProcessingClasspath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir, stubsOutputDir, incrementalDataOutputDir, options, javacOptions, annotationProcessors, - aptMode, pluginInitializedTime, logger, correctErrorTypes, compilerConfiguration) { + aptMode, pluginInitializedTime, logger, correctErrorTypes, mapDiagnosticLocations, compilerConfiguration) { override val analyzePartially: Boolean get() = useLightAnalysis @@ -129,6 +130,7 @@ abstract class AbstractKapt3Extension( val pluginInitializedTime: Long, val logger: KaptLogger, val correctErrorTypes: Boolean, + val mapDiagnosticLocations: Boolean, val compilerConfiguration: CompilerConfiguration ) : PartialAnalysisHandlerExtension() { val compileClasspath = compileClasspath.distinct() @@ -204,7 +206,8 @@ abstract class AbstractKapt3Extension( private fun generateStubs(project: Project, module: ModuleDescriptor, context: BindingContext, files: Collection): KaptContext<*> { if (!aptMode.generateStubs) { - return KaptContext(logger, project, BindingContext.EMPTY, emptyList(), emptyMap(), null, options, javacOptions) + return KaptContext(logger, project, BindingContext.EMPTY, emptyList(), emptyMap(), null, + mapDiagnosticLocations, options, javacOptions) } logger.info { "Kotlin files to compile: " + files.map { it.virtualFile?.name ?: "" } } @@ -259,7 +262,8 @@ abstract class AbstractKapt3Extension( logger.info { "Stubs compilation took $classFilesCompilationTime ms" } logger.info { "Compiled classes: " + compiledClasses.joinToString { it.name } } - return KaptContext(logger, project, bindingContext, compiledClasses, origins, generationState, options, javacOptions) + return KaptContext(logger, project, bindingContext, compiledClasses, origins, generationState, + mapDiagnosticLocations, options, javacOptions) } private fun generateKotlinSourceStubs(kaptContext: KaptContext) { diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt index c911b955c56..a889241ef4c 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt @@ -88,6 +88,9 @@ object Kapt3ConfigurationKeys { val CORRECT_ERROR_TYPES: CompilerConfigurationKey = CompilerConfigurationKey.create("replace error types with ones from the declaration sources") + + val MAP_DIAGNOSTIC_LOCATIONS: CompilerConfigurationKey = + CompilerConfigurationKey.create("map diagnostic reported on kapt stubs to original locations in Kotlin sources") } class Kapt3CommandLineProcessor : CommandLineProcessor { @@ -141,6 +144,9 @@ class Kapt3CommandLineProcessor : CommandLineProcessor { val CORRECT_ERROR_TYPES_OPTION: CliOption = CliOption("correctErrorTypes", "true | false", "Replace generated or error types with ones from the generated sources", required = false) + + val MAP_DIAGNOSTIC_LOCATIONS_OPTION: CliOption = + CliOption("mapDiagnosticLocations", "true | false", "Map diagnostic reported on kapt stubs to original locations in Kotlin sources", required = false) } override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID @@ -149,7 +155,7 @@ class Kapt3CommandLineProcessor : CommandLineProcessor { listOf(SOURCE_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION, JAVAC_CLI_OPTIONS_OPTION, CLASS_OUTPUT_DIR_OPTION, VERBOSE_MODE_OPTION, STUBS_OUTPUT_DIR_OPTION, APT_ONLY_OPTION, APT_MODE_OPTION, USE_LIGHT_ANALYSIS_OPTION, CORRECT_ERROR_TYPES_OPTION, ANNOTATION_PROCESSORS_OPTION, INCREMENTAL_DATA_OUTPUT_DIR_OPTION, - CONFIGURATION) + CONFIGURATION, MAP_DIAGNOSTIC_LOCATIONS_OPTION) override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) { when (option) { @@ -166,6 +172,7 @@ class Kapt3CommandLineProcessor : CommandLineProcessor { APT_MODE_OPTION -> configuration.put(Kapt3ConfigurationKeys.APT_MODE, value) USE_LIGHT_ANALYSIS_OPTION -> configuration.put(Kapt3ConfigurationKeys.USE_LIGHT_ANALYSIS, value) CORRECT_ERROR_TYPES_OPTION -> configuration.put(Kapt3ConfigurationKeys.CORRECT_ERROR_TYPES, value) + MAP_DIAGNOSTIC_LOCATIONS_OPTION -> configuration.put(Kapt3ConfigurationKeys.MAP_DIAGNOSTIC_LOCATIONS, value) CONFIGURATION -> configuration.applyOptionsFrom(decodePluginOptions(value), pluginOptions) else -> throw CliOptionProcessingException("Unknown option: ${option.name}") } @@ -254,12 +261,14 @@ class Kapt3ComponentRegistrar : ComponentRegistrar { val useLightAnalysis = configuration.get(Kapt3ConfigurationKeys.USE_LIGHT_ANALYSIS) == "true" val correctErrorTypes = configuration.get(Kapt3ConfigurationKeys.CORRECT_ERROR_TYPES) == "true" + val mapDiagnosticLocations = configuration.get(Kapt3ConfigurationKeys.MAP_DIAGNOSTIC_LOCATIONS) == "true" if (isVerbose) { logger.info("Kapt3 is enabled.") logger.info("Annotation processing mode: $aptMode") logger.info("Use light analysis: $useLightAnalysis") logger.info("Correct error types: $correctErrorTypes") + logger.info("Map diagnostic locations: $mapDiagnosticLocations") logger.info("Source output directory: $sourcesOutputDir") logger.info("Classes output directory: $classFilesOutputDir") logger.info("Stubs output directory: $stubsOutputDir") @@ -274,7 +283,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar { val kapt3AnalysisCompletedHandlerExtension = ClasspathBasedKapt3Extension( compileClasspath, apClasspath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir, stubsOutputDir, incrementalDataOutputDir, apOptions, javacCliOptions, annotationProcessors, - aptMode, useLightAnalysis, correctErrorTypes, System.currentTimeMillis(), logger, configuration) + aptMode, useLightAnalysis, correctErrorTypes, mapDiagnosticLocations, System.currentTimeMillis(), logger, configuration) AnalysisHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension) } diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptContext.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptContext.kt index a36c63353d5..64ecb86b868 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptContext.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptContext.kt @@ -40,6 +40,7 @@ class KaptContext( val compiledClasses: List, val origins: Map, val generationState: GState, + mapDiagnosticLocations: Boolean, processorOptions: Map, javacOptions: Map = emptyMap() ) : AutoCloseable { @@ -50,7 +51,7 @@ class KaptContext( val javaLog: KaptJavaLog init { - KaptJavaLog.preRegister(this, logger.messageCollector) + KaptJavaLog.preRegister(this, logger.messageCollector, mapDiagnosticLocations) JavacFileManager.preRegister(context) KaptTreeMaker.preRegister(context, this) KaptJavaCompiler.preRegister(context) diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaLog.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaLog.kt index a49732ebc87..7e6130afcce 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaLog.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaLog.kt @@ -41,7 +41,8 @@ class KaptJavaLog( errWriter: PrintWriter, warnWriter: PrintWriter, noticeWriter: PrintWriter, - val interceptorData: DiagnosticInterceptorData + val interceptorData: DiagnosticInterceptorData, + val mapDiagnosticLocations: Boolean ) : Log(context, errWriter, warnWriter, noticeWriter) { private val stubLineInfo = KaptStubLineInformation() private val javacMessages = JavacMessages.instance(context) @@ -97,7 +98,7 @@ class KaptJavaLog( } } - if (sourceFile != null && targetElement.tree != null) { + if (mapDiagnosticLocations && sourceFile != null && targetElement.tree != null) { val kotlinPosition = stubLineInfo.getPositionInKotlinFile(sourceFile, targetElement.tree) val kotlinFile = kotlinPosition?.let { getKotlinSourceFile(it) } if (kotlinPosition != null && kotlinFile != null) { @@ -229,14 +230,18 @@ class KaptJavaLog( "compiler.err.annotation.type.not.applicable", "compiler.err.doesnt.exist") - internal fun preRegister(kaptContext: KaptContext<*>, messageCollector: MessageCollector) { + internal fun preRegister(kaptContext: KaptContext<*>, messageCollector: MessageCollector, mapDiagnosticLocations: Boolean) { val interceptorData = DiagnosticInterceptorData() kaptContext.context.put(Log.logKey, Context.Factory { newContext -> fun makeWriter(severity: CompilerMessageSeverity) = PrintWriter(MessageCollectorBackedWriter(messageCollector, severity)) + val errWriter = makeWriter(ERROR) val warnWriter = makeWriter(STRONG_WARNING) val noticeWriter = makeWriter(WARNING) - KaptJavaLog(kaptContext.project, newContext, errWriter, warnWriter, noticeWriter, interceptorData) + + KaptJavaLog( + kaptContext.project, newContext, errWriter, warnWriter, noticeWriter, + interceptorData, mapDiagnosticLocations) }) } } diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3IntegrationTest.kt b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3IntegrationTest.kt index 0497693a9c9..aa89ec198aa 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3IntegrationTest.kt +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3IntegrationTest.kt @@ -165,7 +165,8 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() { ) : AbstractKapt3Extension(PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath, emptyList(), javaSourceRoots, outputDir, outputDir, stubsOutputDir, incrementalDataOutputDir, options, emptyMap(), "", STUBS_AND_APT, System.currentTimeMillis(), - KaptLogger(true), correctErrorTypes = true, compilerConfiguration = CompilerConfiguration.EMPTY + KaptLogger(true), correctErrorTypes = true, mapDiagnosticLocations = true, + compilerConfiguration = CompilerConfiguration.EMPTY ) { internal var savedStubs: String? = null internal var savedBindings: Map? = null diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt index 2efd04769df..dec007ded39 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt @@ -114,7 +114,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() { }.toMap() val kaptContext = KaptContext(logger, generationState.project, generationState.bindingContext, classBuilderFactory.compiledClasses, - classBuilderFactory.origins, generationState, + classBuilderFactory.origins, generationState, mapDiagnosticLocations = true, processorOptions = emptyMap(), javacOptions = javacOptions) val javaFiles = files diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/JavaKaptContextTest.kt b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/JavaKaptContextTest.kt index 36358f0d49d..102d39cb1a2 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/JavaKaptContextTest.kt +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/JavaKaptContextTest.kt @@ -86,6 +86,7 @@ class JavaKaptContextTest { compiledClasses = emptyList(), origins = emptyMap(), generationState = null, + mapDiagnosticLocations = true, processorOptions = emptyMap() ).doAnnotationProcessing( listOf(javaSourceFile),