Repository: JetBrains/kotlin-eclipse
Branch: master
Commit: 202197775219
Files: 1604
Total size: 2.2 MB
Directory structure:
gitextract_ciuqhpnh/
├── .gitattributes
├── .github/
│ └── workflows/
│ └── main.yml
├── .gitignore
├── LICENSE
├── README.md
├── common-settings/
│ └── kotlin-formatting.xml
├── docs/
│ └── dev-documentation.md
├── kotlin-bundled-compiler/
│ ├── Get Bundled Kotlin.launch
│ ├── META-INF/
│ │ └── MANIFEST.MF
│ ├── build.gradle.kts
│ ├── build.properties
│ ├── buildSrc/
│ │ ├── build.gradle
│ │ └── src/
│ │ ├── main/
│ │ │ └── groovy/
│ │ │ └── com/
│ │ │ └── intellij/
│ │ │ └── buildsupport/
│ │ │ ├── dependencies/
│ │ │ │ ├── PackageList.groovy
│ │ │ │ ├── PackageListFromManifest.groovy
│ │ │ │ └── PackageListFromSimpleFile.groovy
│ │ │ ├── resolve/
│ │ │ │ ├── http/
│ │ │ │ │ ├── HttpArtifact.groovy
│ │ │ │ │ ├── HttpArtifactsResolver.groovy
│ │ │ │ │ └── idea/
│ │ │ │ │ └── IntellijIdeaArtifactsResolver.groovy
│ │ │ │ └── tc/
│ │ │ │ ├── TCArtifact.groovy
│ │ │ │ ├── TCArtifactsResolver.groovy
│ │ │ │ └── kotlin/
│ │ │ │ ├── CommonIDEArtifactsResolver.groovy
│ │ │ │ └── KotlinCompilerTCArtifactsResolver.groovy
│ │ │ └── utils/
│ │ │ └── FileUtils.groovy
│ │ └── test/
│ │ └── groovy/
│ │ └── com/
│ │ └── intellij/
│ │ └── buildsupport/
│ │ └── tc/
│ │ └── kotlin/
│ │ └── KotlinCompilerTCArtifactsResolverSpecification.groovy
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── pom.xml
│ ├── referencedPackages.txt
│ └── src/
│ ├── com/
│ │ └── intellij/
│ │ ├── codeInsight/
│ │ │ ├── CodeInsightBundle.java
│ │ │ ├── KotlinNullableNotNullManager.kt
│ │ │ ├── actions/
│ │ │ │ └── ReformatCodeProcessor.java
│ │ │ └── generation/
│ │ │ └── GenerateEqualsHelper.java
│ │ ├── formatting/
│ │ │ ├── KotlinLanguageCodeStyleSettingsProvider.kt
│ │ │ └── KotlinSettingsProvider.kt
│ │ ├── openapi/
│ │ │ ├── editor/
│ │ │ │ └── Editor.java
│ │ │ ├── extensions/
│ │ │ │ └── ExtensionException.kt
│ │ │ ├── fileTypes/
│ │ │ │ └── StdFileTypes.java
│ │ │ └── util/
│ │ │ └── text/
│ │ │ └── StringUtil.java
│ │ └── util/
│ │ ├── SequentialModalProgressTask.java
│ │ ├── SequentialTask.java
│ │ ├── SingletonSet.java
│ │ └── containers/
│ │ ├── LinkedMultiMap.java
│ │ ├── MultiMap.java
│ │ └── ObjectIntHashMap.java
│ ├── it/
│ │ └── unimi/
│ │ └── dsi/
│ │ └── fastutil/
│ │ └── ints/
│ │ └── IntOpenHashSet.java
│ └── org/
│ └── jetbrains/
│ └── kotlin/
│ └── idea/
│ └── core/
│ └── formatter/
│ └── KotlinPackageEntry.kt
├── kotlin-eclipse-aspects/
│ ├── META-INF/
│ │ ├── MANIFEST.MF
│ │ └── aop.xml
│ ├── build.properties
│ ├── pom.xml
│ └── src/
│ └── org/
│ └── jetbrains/
│ └── kotlin/
│ └── aspects/
│ ├── Activator.java
│ ├── debug/
│ │ ├── core/
│ │ │ ├── KotlinSourceLookupAspect.aj
│ │ │ └── KotlinStackFrameFilterAspect.aj
│ │ └── ui/
│ │ └── SuppressBreakpointMarkerUpdaterAspect.aj
│ ├── navigation/
│ │ ├── KotlinFindSourceAspect.aj
│ │ ├── KotlinOpenEditorAspect.aj
│ │ └── KotlinSearchEditorOpenerAspect.aj
│ ├── refactoring/
│ │ ├── KotlinBinaryReferencesAspect.aj
│ │ ├── KotlinBreakpointRenamingParticipantAspect.aj
│ │ ├── KotlinJavaDescriptorAspect.aj
│ │ ├── KotlinRefactoringChecksAspect.aj
│ │ ├── KotlinRefactoringTypeAspect.aj
│ │ ├── KotlinRemoveDeclarationUpdateAspect.aj
│ │ ├── KotlinRenameFromJavaAspect.aj
│ │ └── KotlinRippleMethodFinderAspect.aj
│ └── ui/
│ └── PackageExplorerLabelProviderAspect.aj
├── kotlin-eclipse-core/
│ ├── META-INF/
│ │ └── MANIFEST.MF
│ ├── build.properties
│ ├── plugin.xml
│ ├── pom.xml
│ ├── preferences.ini
│ ├── schema/
│ │ ├── org.jetbrains.kotlin.core.predefinedKotlinCodeStyle.exsd
│ │ └── org.jetbrains.kotlin.core.scriptTemplateContribution.exsd
│ └── src/
│ └── org/
│ └── jetbrains/
│ └── kotlin/
│ └── core/
│ ├── Activator.java
│ ├── KotlinClasspathContainer.kt
│ ├── KotlinClasspathContainerInitializer.kt
│ ├── KotlinClasspathProvider.kt
│ ├── asJava/
│ │ ├── BinaryClassWriter.java
│ │ ├── KotlinLightClassGeneration.kt
│ │ ├── LightClassBuilderFactory.java
│ │ ├── LightClassFile.java
│ │ └── elementUtils.kt
│ ├── builder/
│ │ └── KotlinPsiManager.kt
│ ├── compiler/
│ │ ├── KotlinCompiler.kt
│ │ ├── KotlinCompiler2.java
│ │ └── KotlinCompilerUtils.kt
│ ├── debug/
│ │ └── KotlinSourceLookupNavigator.java
│ ├── filesystem/
│ │ ├── EnvironmentRemnantNature.kt
│ │ ├── KotlinFileStore.kt
│ │ ├── KotlinFileSystem.java
│ │ ├── KotlinLightClassManager.kt
│ │ └── KotlinScriptFIleSystem.kt
│ ├── formatting/
│ │ └── KotlinCodeStyleManager.kt
│ ├── imports/
│ │ ├── FunctionImportFinder.kt
│ │ ├── importCandidates.kt
│ │ └── importServices.kt
│ ├── launch/
│ │ ├── CompilerOutputData.java
│ │ ├── CompilerOutputElement.java
│ │ ├── CompilerOutputParser.java
│ │ └── KotlinCLICompiler.kt
│ ├── log/
│ │ └── kotlinLogger.kt
│ ├── model/
│ │ ├── CachedEnvironment.kt
│ │ ├── DummyCodeStyleManager.kt
│ │ ├── EclipseKotlinModuleResolver.kt
│ │ ├── EclipseScriptDefinitionProvider.kt
│ │ ├── KotlinAnalysisFileCache.kt
│ │ ├── KotlinAnalysisProjectCache.kt
│ │ ├── KotlinCommonEnvironment.kt
│ │ ├── KotlinEnvironment.kt
│ │ ├── KotlinJavaManager.kt
│ │ ├── KotlinLightVirtualFile.kt
│ │ ├── KotlinNature.kt
│ │ ├── KotlinRefreshProjectListener.kt
│ │ ├── executableEP.kt
│ │ └── kotlinModelUtils.kt
│ ├── preferences/
│ │ ├── KotlinBuildingProperties.kt
│ │ ├── KotlinCodeStyleProperties.kt
│ │ ├── KotlinProperties.kt
│ │ ├── KotlinPropertiesExtensions.kt
│ │ └── Preferences.kt
│ ├── references/
│ │ ├── KotlinReference.kt
│ │ └── referenceUtils.kt
│ ├── resolve/
│ │ ├── BuiltInsReferenceResolver.java
│ │ ├── DeserializedDescriptorUtils.kt
│ │ ├── EclipseAnalyzerFacadeForJVM.kt
│ │ ├── EclipseDescriptorUtils.java
│ │ ├── KotlinAnalyzer.kt
│ │ ├── KotlinCacheServiceImpl.kt
│ │ ├── KotlinPackagePartProvider.kt
│ │ ├── KotlinResolutionFacade.kt
│ │ ├── KotlinSourceIndex.java
│ │ ├── injection.kt
│ │ ├── lang/
│ │ │ ├── java/
│ │ │ │ ├── EclipseJavaClassFinder.java
│ │ │ │ ├── resolver/
│ │ │ │ │ ├── EclipseJavaSourceElement.java
│ │ │ │ │ ├── EclipseJavaSourceElementFactory.java
│ │ │ │ │ └── EclipseTraceBasedJavaResolverCache.kt
│ │ │ │ └── structure/
│ │ │ │ ├── EclipseJavaAnnotation.kt
│ │ │ │ ├── EclipseJavaAnnotationArgument.kt
│ │ │ │ ├── EclipseJavaAnnotationAsAnnotationArgument.kt
│ │ │ │ ├── EclipseJavaArrayAnnotationArgument.kt
│ │ │ │ ├── EclipseJavaArrayType.java
│ │ │ │ ├── EclipseJavaClass.kt
│ │ │ │ ├── EclipseJavaClassObjectAnnotationArgument.java
│ │ │ │ ├── EclipseJavaClassifier.kt
│ │ │ │ ├── EclipseJavaClassifierType.java
│ │ │ │ ├── EclipseJavaConstructor.java
│ │ │ │ ├── EclipseJavaElement.kt
│ │ │ │ ├── EclipseJavaElementFactory.java
│ │ │ │ ├── EclipseJavaElementUtil.java
│ │ │ │ ├── EclipseJavaField.kt
│ │ │ │ ├── EclipseJavaLiteralAnnotationArgument.java
│ │ │ │ ├── EclipseJavaMember.java
│ │ │ │ ├── EclipseJavaMethod.kt
│ │ │ │ ├── EclipseJavaPackage.java
│ │ │ │ ├── EclipseJavaPrimitiveType.java
│ │ │ │ ├── EclipseJavaPropertyInitializerEvaluator.java
│ │ │ │ ├── EclipseJavaReferenceAnnotationArgument.java
│ │ │ │ ├── EclipseJavaType.java
│ │ │ │ ├── EclipseJavaTypeAsAnnotationArgument.kt
│ │ │ │ ├── EclipseJavaTypeParameter.kt
│ │ │ │ ├── EclipseJavaValueParameter.java
│ │ │ │ ├── EclipseJavaWildcardType.java
│ │ │ │ └── EclipseOptimizedJavaClass.kt
│ │ │ └── kotlin/
│ │ │ └── EclipseVirtualFileFinder.kt
│ │ └── sources/
│ │ └── LibrarySourcesIndex.kt
│ ├── script/
│ │ ├── EnvironmentProjectsManager.kt
│ │ ├── ScriptTemplateContribution.kt
│ │ └── template/
│ │ ├── ProjectFilesResolver.kt
│ │ ├── ProjectScriptTemplate.kt
│ │ └── ProjectScriptTemplateContribution.kt
│ └── utils/
│ ├── DebugUtils.java
│ ├── DependencyResolverException.kt
│ ├── ProjectUtils.kt
│ ├── analyzeUtils.kt
│ ├── genericUtils.kt
│ ├── importsUtils.kt
│ ├── jobUtils.kt
│ ├── kotlinFilesCollectorUtils.kt
│ └── projectFilesUtils.kt
├── kotlin-eclipse-feature/
│ ├── build.properties
│ ├── feature.xml
│ └── pom.xml
├── kotlin-eclipse-gradle/
│ ├── META-INF/
│ │ └── MANIFEST.MF
│ ├── build.properties
│ ├── plugin.xml
│ ├── pom.xml
│ ├── scripts/
│ │ └── init.gradle.kts
│ └── src/
│ └── org/
│ └── jetbrains/
│ └── kotlin/
│ └── gradle/
│ ├── Activator.kt
│ ├── configurator/
│ │ └── KotlinProjectConfigurator.kt
│ └── initialization/
│ └── ModelInjector.kt
├── kotlin-eclipse-gradle-feature/
│ ├── build.properties
│ ├── feature.xml
│ └── pom.xml
├── kotlin-eclipse-gradle-model/
│ ├── META-INF/
│ │ └── MANIFEST.MF
│ ├── build.gradle
│ ├── build.properties
│ ├── gradle/
│ │ └── wrapper/
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── pom.xml
│ ├── settings.gradle
│ └── src/
│ └── org/
│ └── jetbrains/
│ └── kotlin/
│ └── gradle/
│ └── model/
│ ├── GradleMultiProjectForEclipse.kt
│ ├── GradleProjectForEclipse.kt
│ └── plugins.kt
├── kotlin-eclipse-maven/
│ ├── META-INF/
│ │ └── MANIFEST.MF
│ ├── build.properties
│ ├── lifecycle-mapping-metadata.xml
│ ├── plugin.xml
│ ├── pom.xml
│ └── src/
│ └── org/
│ └── jetbrains/
│ └── kotlin/
│ └── maven/
│ ├── Activator.java
│ └── configuration/
│ ├── KotlinMavenProjectConfigurator.kt
│ └── MavenAttributeAccessor.kt
├── kotlin-eclipse-p2updatesite/
│ ├── category.xml
│ └── pom.xml
├── kotlin-eclipse-policy/
│ ├── build.properties
│ ├── feature.xml
│ └── pom.xml
├── kotlin-eclipse-test-framework/
│ ├── META-INF/
│ │ └── MANIFEST.MF
│ ├── build.properties
│ ├── pom.xml
│ └── src/
│ └── org/
│ └── jetbrains/
│ └── kotlin/
│ └── testframework/
│ ├── Activator.java
│ ├── editor/
│ │ ├── KotlinEditorAutoTestCase.java
│ │ ├── KotlinEditorSequentialAutoTestCase.java
│ │ ├── KotlinEditorTestCase.java
│ │ ├── KotlinEditorWithAfterFileTestCase.java
│ │ ├── KotlinProjectTestCase.java
│ │ └── TextEditorTest.java
│ └── utils/
│ ├── CodeStyleConfigurator.kt
│ ├── EditorTestUtils.java
│ ├── ExpectedCompletionUtils.java
│ ├── InTextDirectivesUtils.java
│ ├── KotlinTestUtils.java
│ ├── SourceFileData.java
│ ├── TestJavaProject.java
│ ├── TypingUtils.java
│ └── WorkspaceUtil.java
├── kotlin-eclipse-ui/
│ ├── META-INF/
│ │ └── MANIFEST.MF
│ ├── Run Kotlin Plugin with Equinox Weaving.launch
│ ├── Run with open port.launch
│ ├── build.properties
│ ├── plugin.xml
│ ├── pom.xml
│ ├── schema/
│ │ └── org.jetbrains.kotlin.ui.editor.textHover.exsd
│ ├── src/
│ │ └── org/
│ │ └── jetbrains/
│ │ └── kotlin/
│ │ ├── eclipse/
│ │ │ └── ui/
│ │ │ └── utils/
│ │ │ ├── EditorUtil.java
│ │ │ ├── IndenterUtil.java
│ │ │ ├── KotlinEclipseScope.kt
│ │ │ ├── KotlinImageProvider.kt
│ │ │ ├── LineEndUtil.java
│ │ │ ├── ProjectScopedPreferenceUtils.java
│ │ │ ├── analyzeUtils.kt
│ │ │ └── offsetUtils.kt
│ │ ├── perspective/
│ │ │ └── KotlinPerspectiveFactory.java
│ │ ├── preferences/
│ │ │ ├── BasePropertyPage.kt
│ │ │ ├── EditorPreferencePage.java
│ │ │ ├── KotlinPreferenceInitializer.kt
│ │ │ ├── KotlinPreferencePage.java
│ │ │ ├── KotlinTemplatePreferencePage.java
│ │ │ ├── building/
│ │ │ │ ├── ProjectBuildingPropertyPage.kt
│ │ │ │ └── WorkspaceBuildingPropertyPage.kt
│ │ │ ├── compiler/
│ │ │ │ ├── CompilerPluginDialog.kt
│ │ │ │ ├── ProjectCompilerPropertyPage.kt
│ │ │ │ ├── RebuildJob.kt
│ │ │ │ └── WorkspaceCompilerPropertyPage.kt
│ │ │ ├── style/
│ │ │ │ ├── ProjectCodeStylePropertyPage.kt
│ │ │ │ └── WorkspaceCodeStylePropertyPage.kt
│ │ │ └── views/
│ │ │ ├── BuildingPropertiesView.kt
│ │ │ ├── CompilerPropertiesView.kt
│ │ │ ├── ProjectCompilerPropertiesView.kt
│ │ │ ├── Validable.kt
│ │ │ └── codeStylePropertiesView.kt
│ │ ├── swt/
│ │ │ └── builders/
│ │ │ ├── ChecklistView.kt
│ │ │ └── controls.kt
│ │ ├── ui/
│ │ │ ├── Activator.kt
│ │ │ ├── KotlinAwarePackageExplorerLabelProvider.kt
│ │ │ ├── KotlinPluginUpdater.kt
│ │ │ ├── KotlinUiStartupClass.java
│ │ │ ├── RemoveRemnantProjectsJob.kt
│ │ │ ├── ScriptClasspathUpdater.kt
│ │ │ ├── ScriptEnvironmentsFilter.kt
│ │ │ ├── builder/
│ │ │ │ ├── AspectsUtils.java
│ │ │ │ ├── BaseKotlinBuilderElement.kt
│ │ │ │ ├── CompileKotlinClassesAction.kt
│ │ │ │ ├── IncrementalKotlinBuilderElement.kt
│ │ │ │ ├── KotlinAnalysisJob.kt
│ │ │ │ ├── KotlinBuilder.kt
│ │ │ │ ├── KotlinBuilderElement.kt
│ │ │ │ ├── ResourceChangeListener.kt
│ │ │ │ └── kotlinJavaElementsListeners.kt
│ │ │ ├── commands/
│ │ │ │ ├── AddCoroutinesActionHandler.kt
│ │ │ │ ├── ConfigureKotlinActionHandler.kt
│ │ │ │ ├── DeconfigureKotlinActionHandler.kt
│ │ │ │ ├── commandsUtils.kt
│ │ │ │ ├── findReferences/
│ │ │ │ │ ├── KotlinFindReferencesAction.kt
│ │ │ │ │ └── querySpecifications.kt
│ │ │ │ ├── j2k/
│ │ │ │ │ ├── CompositeUndoableOperation.java
│ │ │ │ │ ├── JavaToKotlinActionHandler.java
│ │ │ │ │ ├── SetFileCharsetOperation.java
│ │ │ │ │ └── converterUtils.kt
│ │ │ │ └── psiVisualization/
│ │ │ │ ├── PsiContentProvider.java
│ │ │ │ ├── PsiVisualization.java
│ │ │ │ └── VisualizationPage.java
│ │ │ ├── debug/
│ │ │ │ ├── KotlinRunToLineAdapter.kt
│ │ │ │ ├── KotlinToggleBreakpointAdapter.kt
│ │ │ │ └── commands/
│ │ │ │ └── KotlinStepIntoSelectionHandler.kt
│ │ │ ├── editors/
│ │ │ │ ├── Configuration.java
│ │ │ │ ├── FileEditorConfiguration.kt
│ │ │ │ ├── KotlinActionGroup.kt
│ │ │ │ ├── KotlinAutoIndentStrategy.java
│ │ │ │ ├── KotlinBracketInserter.java
│ │ │ │ ├── KotlinClassFileEditor.kt
│ │ │ │ ├── KotlinClassFileEditorInput.kt
│ │ │ │ ├── KotlinCommonEditor.kt
│ │ │ │ ├── KotlinCorrectionProcessor.kt
│ │ │ │ ├── KotlinEditor.kt
│ │ │ │ ├── KotlinElementHyperlink.kt
│ │ │ │ ├── KotlinElementHyperlinkDetector.kt
│ │ │ │ ├── KotlinFileEditor.kt
│ │ │ │ ├── KotlinFormatAction.kt
│ │ │ │ ├── KotlinReconcilingStrategy.kt
│ │ │ │ ├── KotlinScriptEditor.kt
│ │ │ │ ├── annotations/
│ │ │ │ │ ├── AnnotationManager.kt
│ │ │ │ │ ├── DiagnosticAnnotation.kt
│ │ │ │ │ ├── DiagnosticAnnotationUtil.java
│ │ │ │ │ └── KotlinAnnotationImageProvider.java
│ │ │ │ ├── codeassist/
│ │ │ │ │ ├── CompletionElementType.kt
│ │ │ │ │ ├── FilterPositionUtil.java
│ │ │ │ │ ├── KeywordCompletion.kt
│ │ │ │ │ ├── KotlinCompletionProcessor.kt
│ │ │ │ │ ├── KotlinCompletionProposal.kt
│ │ │ │ │ ├── KotlinContextInfoContentAssistProcessor.kt
│ │ │ │ │ ├── KotlinFunctionCompletionProposal.kt
│ │ │ │ │ ├── KotlinFunctionParameterInfoAssist.kt
│ │ │ │ │ ├── KotlinParameterListValidator.kt
│ │ │ │ │ ├── VisibilityUtils.kt
│ │ │ │ │ ├── nonImportedCompletionHandler.kt
│ │ │ │ │ ├── positionFilters.kt
│ │ │ │ │ └── relevanceSorting.kt
│ │ │ │ ├── completion/
│ │ │ │ │ ├── KotlinCompletionUtils.kt
│ │ │ │ │ └── KotlinReferenceVariantsHelper.kt
│ │ │ │ ├── highlighting/
│ │ │ │ │ ├── KotlinHighlightingColors.kt
│ │ │ │ │ ├── KotlinPositionUpdater.kt
│ │ │ │ │ ├── KotlinSemanticHighlighting.kt
│ │ │ │ │ ├── KotlinSemanticHighlightingVisitor.kt
│ │ │ │ │ ├── KotlinTokenScanner.java
│ │ │ │ │ ├── KotlinTokens.kt
│ │ │ │ │ └── KotlinViewerCreator.kt
│ │ │ │ ├── hover/
│ │ │ │ │ ├── KotlinInformationProvider.kt
│ │ │ │ │ ├── KotlinJavadocTextHover.kt
│ │ │ │ │ ├── KotlinProblemTextHover.kt
│ │ │ │ │ └── KotlinTextHover.kt
│ │ │ │ ├── navigation/
│ │ │ │ │ ├── JarNavigationUtils.kt
│ │ │ │ │ ├── KotlinOpenDeclarationAction.kt
│ │ │ │ │ ├── KotlinOpenEditorFromConsole.kt
│ │ │ │ │ ├── KotlinOpenSuperImplementationAction.kt
│ │ │ │ │ ├── StringInput.kt
│ │ │ │ │ ├── StringStorage.kt
│ │ │ │ │ ├── navigationUtils.kt
│ │ │ │ │ └── psiDeclarationFinder.kt
│ │ │ │ ├── occurrences/
│ │ │ │ │ └── KotlinMarkOccurrences.kt
│ │ │ │ ├── organizeImports/
│ │ │ │ │ ├── KotlinOrganizeImportsAction.kt
│ │ │ │ │ └── importsCollector.kt
│ │ │ │ ├── outline/
│ │ │ │ │ ├── KotlinOutlinePage.kt
│ │ │ │ │ ├── KotlinOutlinePopup.java
│ │ │ │ │ ├── PsiContentProvider.kt
│ │ │ │ │ └── PsiLabelProvider.java
│ │ │ │ ├── quickassist/
│ │ │ │ │ ├── KotlinChangeReturnTypeProposal.kt
│ │ │ │ │ ├── KotlinConvertToBlockBodyAssistProposal.kt
│ │ │ │ │ ├── KotlinConvertToExpressionBodyAssistProposal.kt
│ │ │ │ │ ├── KotlinImplementMethodsProposal.kt
│ │ │ │ │ ├── KotlinIntentionUtils.kt
│ │ │ │ │ ├── KotlinQuickAssist.kt
│ │ │ │ │ ├── KotlinQuickAssistProcessor.kt
│ │ │ │ │ ├── KotlinQuickAssistProposal.kt
│ │ │ │ │ ├── KotlinQuickAssistProposalsGenerator.kt
│ │ │ │ │ ├── KotlinRemoveExplicitTypeAssistProposal.kt
│ │ │ │ │ ├── KotlinReplaceGetAssistProposal.java
│ │ │ │ │ └── KotlinSpecifyTypeAssistProposal.kt
│ │ │ │ ├── quickfix/
│ │ │ │ │ ├── KotlinAddModifierResolution.kt
│ │ │ │ │ ├── KotlinAutoImportQuickFix.kt
│ │ │ │ │ ├── KotlinMakeOverridenMemberOpenResolution.kt
│ │ │ │ │ ├── KotlinMarkerResolutionGenerator.kt
│ │ │ │ │ ├── KotlinQuickFix.kt
│ │ │ │ │ ├── KotlinRemoveModifierResolution.kt
│ │ │ │ │ └── MarkerExtensions.kt
│ │ │ │ ├── selection/
│ │ │ │ │ ├── KotlinSelectEnclosingAction.java
│ │ │ │ │ ├── KotlinSelectNextAction.java
│ │ │ │ │ ├── KotlinSelectPreviousAction.java
│ │ │ │ │ ├── KotlinSemanticSelectionAction.java
│ │ │ │ │ ├── PsiElementChildrenIterable.java
│ │ │ │ │ └── handlers/
│ │ │ │ │ ├── KotlinBlockSelectionHandler.kt
│ │ │ │ │ ├── KotlinDeclarationSelectionHandler.kt
│ │ │ │ │ ├── KotlinDefaultSelectionHandler.kt
│ │ │ │ │ ├── KotlinDocSectionSelectionHandler.kt
│ │ │ │ │ ├── KotlinElementSelectionHandler.java
│ │ │ │ │ ├── KotlinElementSelectioner.kt
│ │ │ │ │ ├── KotlinListSelectionHandler.kt
│ │ │ │ │ ├── KotlinNonTraversableSelectionHanlder.kt
│ │ │ │ │ ├── KotlinStringTemplateSelectionHandler.kt
│ │ │ │ │ ├── KotlinWhiteSpaceSelectionHandler.kt
│ │ │ │ │ └── PsiUtils.kt
│ │ │ │ └── templates/
│ │ │ │ ├── KotlinApplicableTemplateContext.java
│ │ │ │ ├── KotlinDocumentTemplateContext.java
│ │ │ │ ├── KotlinTemplateContextType.java
│ │ │ │ ├── KotlinTemplateFormatter.java
│ │ │ │ └── KotlinTemplateManager.java
│ │ │ ├── formatter/
│ │ │ │ ├── AbstractBlock.kt
│ │ │ │ ├── AlignmentStrategy.java
│ │ │ │ ├── AlignmentStrategy.kt
│ │ │ │ ├── EclipseDocumentFormattingModel.java
│ │ │ │ ├── EclipseFormattingModel.java
│ │ │ │ ├── KotlinBlock.kt
│ │ │ │ ├── NodeAlignmentStrategy.kt
│ │ │ │ └── kotlinFormatter.kt
│ │ │ ├── launch/
│ │ │ │ ├── CompilerStatusHandler.kt
│ │ │ │ ├── KotlinLaunchShortcut.kt
│ │ │ │ ├── KotlinLaunchableTester.kt
│ │ │ │ ├── KotlinRuntimeConfigurator.kt
│ │ │ │ ├── KotlinScriptLaunchConfigurationDelegate.kt
│ │ │ │ ├── KotlinScriptLaunchConfigurationTabGroup.kt
│ │ │ │ ├── KotlinScriptLaunchShortcut.kt
│ │ │ │ ├── KotlinScriptLaunchableTester.kt
│ │ │ │ ├── junit/
│ │ │ │ │ ├── KotlinJUnitLaunchShortcut.java
│ │ │ │ │ ├── KotlinJUnitLaunchUtils.java
│ │ │ │ │ └── KotlinJUnitLaunchableTester.java
│ │ │ │ └── kotlinConsole.kt
│ │ │ ├── navigation/
│ │ │ │ ├── KotlinOpenEditor.java
│ │ │ │ └── KotlinOpenEditorUtils.kt
│ │ │ ├── overrideImplement/
│ │ │ │ ├── KotlinCallableLabelProvider.kt
│ │ │ │ └── KotlinOverrideMembersAction.kt
│ │ │ ├── refactorings/
│ │ │ │ ├── extract/
│ │ │ │ │ ├── KotlinExtractVariableAction.kt
│ │ │ │ │ ├── KotlinExtractVariableRefactoring.kt
│ │ │ │ │ └── KotlinExtractVariableWizard.kt
│ │ │ │ └── rename/
│ │ │ │ ├── KotlinLightElementsFactory.java
│ │ │ │ ├── KotlinRenameAction.kt
│ │ │ │ ├── KotlinRenameParticipant.kt
│ │ │ │ ├── KotlinRenameProcessor.kt
│ │ │ │ ├── lightEclipseElements.kt
│ │ │ │ ├── refactoringUtils.kt
│ │ │ │ └── renameParticipants.kt
│ │ │ └── search/
│ │ │ ├── KotlinElementMatchCreator.kt
│ │ │ ├── KotlinQueryParticipant.kt
│ │ │ ├── KotlinReferenceMatchPresentation.kt
│ │ │ ├── SearchParentObjectMapper.kt
│ │ │ └── searchFilters.kt
│ │ ├── utils/
│ │ │ ├── DescriptorUtils.kt
│ │ │ ├── LazyObservable.kt
│ │ │ └── ThrowableExtensions.kt
│ │ └── wizards/
│ │ ├── AbstractWizard.java
│ │ ├── AbstractWizardPage.java
│ │ ├── FileCreationOp.java
│ │ ├── NewProjectWizard.java
│ │ ├── NewProjectWizardPage.java
│ │ ├── NewUnitWizard.java
│ │ ├── NewUnitWizardPage.java
│ │ ├── ProjectCreationOp.java
│ │ ├── SWTWizardUtils.java
│ │ ├── WizardType.kt
│ │ ├── unitWizards.kt
│ │ └── wizardUtils.kt
│ └── templates/
│ └── default-templates.xml
├── kotlin-eclipse-ui-test/
│ ├── META-INF/
│ │ └── MANIFEST.MF
│ ├── build.properties
│ ├── plugin.xml
│ ├── pom.xml
│ ├── src/
│ │ └── org/
│ │ └── jetbrains/
│ │ └── kotlin/
│ │ ├── checkers/
│ │ │ └── KotlinDiagnosticsTestCase.java
│ │ ├── core/
│ │ │ └── tests/
│ │ │ ├── diagnostics/
│ │ │ │ ├── AdditionalConditions.java
│ │ │ │ ├── AllDiagnosticsTests.java
│ │ │ │ ├── FileComparisonFailure.java
│ │ │ │ ├── JavaAnnotationArgumentsInKotlinTest.java
│ │ │ │ ├── JetLightFixture.java
│ │ │ │ ├── JetTestUtils.java
│ │ │ │ ├── KotlinDiagnosticsJavaPlusKotlinTest.java
│ │ │ │ └── KotlinDiagnosticsTest.java
│ │ │ └── launch/
│ │ │ ├── AllTests.java
│ │ │ ├── KotlinJUnitLaunchTest.java
│ │ │ ├── KotlinJUnitLaunchTestCase.java
│ │ │ ├── KotlinLaunchTest.java
│ │ │ └── KotlinLaunchTestCase.kt
│ │ └── ui/
│ │ ├── AllTests.java
│ │ └── tests/
│ │ ├── editors/
│ │ │ ├── AllTests.java
│ │ │ ├── CommandTestCase.java
│ │ │ ├── KotlinAnalyzerInIDETest.java
│ │ │ ├── KotlinAnalyzerInIDETestCase.kt
│ │ │ ├── KotlinAutoIndentTest.java
│ │ │ ├── KotlinAutoIndentTestCase.kt
│ │ │ ├── KotlinAutoIndenterTestCase.java
│ │ │ ├── KotlinBasicAutoIndentTest.java
│ │ │ ├── KotlinBracketInserterTest.java
│ │ │ ├── KotlinBracketInserterTestCase.java
│ │ │ ├── KotlinCustomLocationBugTest.java
│ │ │ ├── KotlinEditorBaseTest.java
│ │ │ ├── KotlinEditorClosedProjectInfluenceTest.java
│ │ │ ├── PsiVisualizationCommandTest.java
│ │ │ ├── completion/
│ │ │ │ ├── AllTests.java
│ │ │ │ ├── KotlinBasicCompletionTest.java
│ │ │ │ ├── KotlinBasicCompletionTestCase.kt
│ │ │ │ ├── KotlinCompletionRelevanceTest.java
│ │ │ │ ├── KotlinCompletionRelevanceTestCase.kt
│ │ │ │ ├── KotlinFunctionParameterInfoTest.java
│ │ │ │ ├── KotlinFunctionParameterInfoTestCase.kt
│ │ │ │ ├── KotlinKeywordCompletionTest.java
│ │ │ │ ├── KotlinKeywordCompletionTestCase.kt
│ │ │ │ ├── completionTestUtils.kt
│ │ │ │ ├── handlers/
│ │ │ │ │ ├── KotlinCompletionHandlerInsertTest.java
│ │ │ │ │ └── KotlinCompletionHandlerInsertTestCase.java
│ │ │ │ └── templates/
│ │ │ │ ├── AllTests.java
│ │ │ │ ├── KotlinTemplatesTest.java
│ │ │ │ └── KotlinTemplatesTestCase.java
│ │ │ ├── formatter/
│ │ │ │ ├── AllFormatTests.java
│ │ │ │ ├── KotlinFileAnnotationsFormatTest.java
│ │ │ │ ├── KotlinFormatActionTest.java
│ │ │ │ ├── KotlinFormatActionTestCase.java
│ │ │ │ ├── KotlinIdeaFormatActionTest.java
│ │ │ │ ├── KotlinModifierListFormatTest.java
│ │ │ │ └── KotlinParameterListFormatTest.java
│ │ │ ├── highlighting/
│ │ │ │ ├── KotlinHighlightingPositionUpdaterTest.java
│ │ │ │ ├── KotlinHighlightingPositionUpdaterTestCase.kt
│ │ │ │ ├── KotlinHighlightingTest.java
│ │ │ │ └── KotlinHighlightingTestCase.java
│ │ │ ├── markers/
│ │ │ │ ├── AllTests.java
│ │ │ │ ├── KotlinParsingMarkersTest.java
│ │ │ │ ├── KotlinParsingMarkersTestCase.java
│ │ │ │ └── MarkerAttributesTest.java
│ │ │ ├── navigation/
│ │ │ │ ├── AllTests.java
│ │ │ │ ├── JavaToKotlinNavigationTest.java
│ │ │ │ ├── JavaToKotlinNavigationTestCase.java
│ │ │ │ ├── KotlinBuiltInsReferenceResolverTest.java
│ │ │ │ ├── KotlinBuiltInsReferenceResolverTestCase.java
│ │ │ │ ├── KotlinNavigationFromLibraryTest.java
│ │ │ │ ├── KotlinNavigationFromLibraryTestCase.kt
│ │ │ │ ├── KotlinNavigationTest.java
│ │ │ │ ├── KotlinNavigationTestCase.java
│ │ │ │ ├── KotlinNavigationToLibraryTest.java
│ │ │ │ ├── KotlinNavigationToLibraryTestCase.kt
│ │ │ │ ├── KotlinNavigationToSuperTest.java
│ │ │ │ ├── KotlinNavigationToSuperTestCase.kt
│ │ │ │ ├── KotlinSourcesNavigationTestCase.kt
│ │ │ │ └── library/
│ │ │ │ └── NavigationTestLibrary.kt
│ │ │ ├── organizeImports/
│ │ │ │ ├── KotlinCommonOptimizeImportsTest.java
│ │ │ │ ├── KotlinJvmOptimizeImportsTest.java
│ │ │ │ ├── KotlinOrganizeImportsTest.java
│ │ │ │ └── KotlinOrganizeImportsTestCase.kt
│ │ │ ├── quickfix/
│ │ │ │ ├── autoimport/
│ │ │ │ │ ├── AllTests.java
│ │ │ │ │ ├── KotlinAbstractModifierQuickFixTest.java
│ │ │ │ │ ├── KotlinAutoImportTest.java
│ │ │ │ │ ├── KotlinAutoImportTestCase.java
│ │ │ │ │ ├── KotlinChangeModifiersQuickFixTest.java
│ │ │ │ │ ├── KotlinMakeClassOpenQuickFixTest.java
│ │ │ │ │ ├── KotlinMakeOverridenMemberOpenQuickFixTest.java
│ │ │ │ │ └── KotlinQuickFixTestCase.kt
│ │ │ │ └── intentions/
│ │ │ │ ├── AbstractKotlinQuickAssistTestCase.java
│ │ │ │ ├── KotlinChangeReturnTypeTest.java
│ │ │ │ ├── KotlinChangeReturnTypeTestCase.kt
│ │ │ │ ├── KotlinConvertToBlockBodyTest.java
│ │ │ │ ├── KotlinConvertToBlockBodyTestCase.java
│ │ │ │ ├── KotlinConvertToExpressionBodyTest.java
│ │ │ │ ├── KotlinConvertToExpressionBodyTestCase.java
│ │ │ │ ├── KotlinImplementMethodsTest.java
│ │ │ │ ├── KotlinImplementMethodsTestCase.java
│ │ │ │ ├── KotlinOverrideMembersTestCase.kt
│ │ │ │ ├── KotlinOverrideMethodsTest.java
│ │ │ │ ├── KotlinRemoveExplicitTypeTest.java
│ │ │ │ ├── KotlinRemoveExplicitTypeTestCase.kt
│ │ │ │ ├── KotlinReplaceGetIntentionTest.java
│ │ │ │ ├── KotlinReplaceGetIntentionTestCase.java
│ │ │ │ ├── KotlinSpacesForTabsQuickAssistTestCase.java
│ │ │ │ ├── KotlinSpecifyTypeTest.java
│ │ │ │ └── KotlinSpecifyTypeTestCase.java
│ │ │ └── selection/
│ │ │ ├── KotlinCommonSelectionTestCase.kt
│ │ │ ├── KotlinSelectEnclosingTest.java
│ │ │ ├── KotlinSelectEnclosingTestCase.kt
│ │ │ ├── KotlinSelectNextTest.java
│ │ │ ├── KotlinSelectNextTestCase.kt
│ │ │ ├── KotlinSelectPreviousTest.java
│ │ │ └── KotlinSelectPreviousTestCase.kt
│ │ ├── refactoring/
│ │ │ ├── convert/
│ │ │ │ └── JavaToKotlinEncodingBugTest.java
│ │ │ ├── extract/
│ │ │ │ ├── KotlinExtractVariableTest.java
│ │ │ │ └── KotlinExtractVariableTestCase.kt
│ │ │ └── rename/
│ │ │ ├── KotlinLocalRenameTest.java
│ │ │ ├── KotlinLocalRenameTestCase.kt
│ │ │ ├── KotlinRenameTest.java
│ │ │ └── KotlinRenameTestCase.kt
│ │ ├── scripts/
│ │ │ ├── completion/
│ │ │ │ └── CompletionInScriptsTest.java
│ │ │ ├── navigation/
│ │ │ │ └── BasicNavigationInScripts.java
│ │ │ └── templates/
│ │ │ ├── KotlinScriptWithTemplateResolveTest.java
│ │ │ ├── KotlinScriptWithTemplateResolveTestCase.kt
│ │ │ ├── TestKtScriptTemplateProvider.kt
│ │ │ ├── TestKtScriptTemplateProviderEx.kt
│ │ │ ├── TestScriptTemplateDefinition.kt
│ │ │ └── testCustomEPResolver.kt
│ │ └── search/
│ │ ├── KotlinFindReferencesTest.java
│ │ └── KotlinFindReferencesTestCase.kt
│ └── testData/
│ ├── compiler/
│ │ └── diagnostics/
│ │ └── tests/
│ │ ├── ResolveOfJavaGenerics.kt
│ │ ├── ResolveOfJavaGenerics.txt
│ │ ├── ResolveToJava.kt
│ │ ├── ResolveToJava.txt
│ │ ├── StarsInFunctionCalls.kt
│ │ ├── StarsInFunctionCalls.txt
│ │ ├── TypeInference.kt
│ │ └── TypeInference.txt
│ ├── completion/
│ │ ├── autoimport/
│ │ │ ├── classNestedInClassImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── classNestedInObjectImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── extensionFunctionImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── other.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── extensionFunctionReferenceImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── other.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── extensionInfixFunctionImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── other1.kt
│ │ │ │ ├── other2.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── extensionMethodInLambdaWithReceiverAmbigousImport/
│ │ │ │ ├── dependency1.kt
│ │ │ │ ├── dependency2.kt
│ │ │ │ ├── other.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── extensionMethodInLambdaWithReceiverImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── extensionOperatorImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── other1.kt
│ │ │ │ ├── other2.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── extensionValImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── other.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── extensionValReferenceImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── other.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── functionExtensionValImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── other.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── functionReferenceImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── importClassWithExistingPackageKeyword.kt
│ │ │ ├── importClassWithExistingPackageKeyword.kt.after
│ │ │ ├── importOnlyUnresolvedReferenceExpressions.kt
│ │ │ ├── importOnlyUnresolvedReferenceExpressions.kt.after
│ │ │ ├── importWithExtraBreakline.kt
│ │ │ ├── importWithExtraBreakline.kt.after
│ │ │ ├── importWithExtraBreaklineWithoutPackage.kt
│ │ │ ├── importWithExtraBreaklineWithoutPackage.kt.after
│ │ │ ├── invokableExtensionValImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── other.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── localJavaClassAutoImport/
│ │ │ │ ├── Bar.kt
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java
│ │ │ ├── localJavaEnumAutoImport/
│ │ │ │ ├── Bar.kt
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── FooEnum.java
│ │ │ ├── localJavaInterfaceAutoImport/
│ │ │ │ ├── Bar.kt
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── FooInterface.java
│ │ │ ├── oneStandardVectorAutoImport.kt
│ │ │ ├── oneStandardVectorAutoImport.kt.after
│ │ │ ├── packageArrayListAutoImport.kt
│ │ │ ├── packageArrayListAutoImport.kt.after
│ │ │ ├── packageLevelFunctionImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── packageLevelFunctionValImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── packageLevelInvokableValImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── packageLevelValImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── propertyReferenceImport/
│ │ │ │ ├── dependency.kt
│ │ │ │ ├── test.kt
│ │ │ │ └── test.kt.after
│ │ │ ├── sameProjectJavaClassAutoImport/
│ │ │ │ ├── Bar.kt
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java
│ │ │ ├── standardEnumMapAutoImport.kt
│ │ │ ├── standardEnumMapAutoImport.kt.after
│ │ │ └── unaryExtensionOperatorImport/
│ │ │ ├── dependency.kt
│ │ │ ├── other1.kt
│ │ │ ├── other2.kt
│ │ │ ├── other3.kt
│ │ │ ├── test.kt
│ │ │ └── test.kt.after
│ │ ├── basic/
│ │ │ ├── common/
│ │ │ │ ├── AfterFloatOnNewLine.kt
│ │ │ │ ├── AfterIntSeparatedWithComments.kt
│ │ │ │ ├── AutoCastAfterIf.kt
│ │ │ │ ├── AutoCastAfterIfMethod.kt
│ │ │ │ ├── AutoCastForThis.kt
│ │ │ │ ├── AutoCastInWhen.kt
│ │ │ │ ├── BasicAny.kt
│ │ │ │ ├── BasicInt.kt
│ │ │ │ ├── BeforeDotInCall.kt
│ │ │ │ ├── CallLocalLambda.kt
│ │ │ │ ├── ClassObjectElementsInClass.kt
│ │ │ │ ├── ClassRedeclaration1.kt
│ │ │ │ ├── ClassRedeclaration2.kt
│ │ │ │ ├── ExtendClassName.kt
│ │ │ │ ├── ExtendQualifiedClassName.kt
│ │ │ │ ├── ExtensionForProperty.kt
│ │ │ │ ├── ExtensionFunReceiver.kt
│ │ │ │ ├── ExtensionFunReceiverForce.kt
│ │ │ │ ├── ExtensionInsideFunction.kt
│ │ │ │ ├── ExtensionToIntInFloatStyle.kt
│ │ │ │ ├── FromImports.kt
│ │ │ │ ├── FunctionCompletionFormatting.kt
│ │ │ │ ├── InCallExpression.kt
│ │ │ │ ├── InClassInitializer.kt
│ │ │ │ ├── InClassPropertyAccessor.kt
│ │ │ │ ├── InEmptyImport.kt
│ │ │ │ ├── InExpressionNoPrefix.kt
│ │ │ │ ├── InExtendTypeAnnotation.kt
│ │ │ │ ├── InFileWithMultiDeclaration.kt
│ │ │ │ ├── InFileWithTypedef.kt
│ │ │ │ ├── InFunInClassInitializer.kt
│ │ │ │ ├── InGlobalPropertyInitializer.kt
│ │ │ │ ├── InImport.kt
│ │ │ │ ├── InInitializerInPropertyAccessor.kt
│ │ │ │ ├── InLocalObjectDeclaration.kt
│ │ │ │ ├── InLongDotQualifiedExpression.kt
│ │ │ │ ├── InMiddleOfPackage.kt
│ │ │ │ ├── InMiddleOfPackageDirective.kt
│ │ │ │ ├── InObjectInDelegationSpecifier.kt
│ │ │ │ ├── InPackageBegin.kt
│ │ │ │ ├── InParametersTypes.kt
│ │ │ │ ├── InParametersTypesForce.kt
│ │ │ │ ├── InTypeAnnotation.kt
│ │ │ │ ├── JavaPackage.kt
│ │ │ │ ├── LocalMultideclarationValues.kt
│ │ │ │ ├── NamedObject.kt
│ │ │ │ ├── NoClassNameDuplication.kt
│ │ │ │ ├── NoCompletionAfterBigFloat.kt
│ │ │ │ ├── NoCompletionAfterFloat.kt
│ │ │ │ ├── NoCompletionAfterInt.kt
│ │ │ │ ├── NoCompletionAfterLong.kt
│ │ │ │ ├── NoEmptyPackage.kt
│ │ │ │ ├── NoObjectInTypePosition.kt
│ │ │ │ ├── NoTopLevelCompletionInQualifiedUserTypes.kt
│ │ │ │ ├── ObjectRedeclaration1.kt
│ │ │ │ ├── ObjectRedeclaration2.kt
│ │ │ │ ├── OneProposalWithExplicitImport.kt
│ │ │ │ ├── OneWithStarImport.kt
│ │ │ │ ├── OnlyScopedClassesWithoutExplicit.kt
│ │ │ │ ├── OverloadFunctions.kt
│ │ │ │ ├── ShortClassNamesInTypePosition.kt
│ │ │ │ ├── StandardJetArrayFirst.kt
│ │ │ │ ├── StandardJetDoubleFirst.kt
│ │ │ │ ├── SubpackageInFun.kt
│ │ │ │ ├── TopLevelClassCompletionInQualifiedCall.kt
│ │ │ │ ├── VariableClassName.kt
│ │ │ │ ├── VariableWithLowerCase.kt
│ │ │ │ ├── VisibilityClassMembersFromExternal.kt
│ │ │ │ ├── WithCompletedExpression.kt
│ │ │ │ ├── functionWithLowerCase.kt
│ │ │ │ ├── notImportedAnnotation.kt
│ │ │ │ └── visibility/
│ │ │ │ └── VisibilityPrivateToThisWithWrongThis.kt
│ │ │ ├── java/
│ │ │ │ ├── AutoForceCompletion.kt
│ │ │ │ ├── ExtensionFromStandardLibrary.kt
│ │ │ │ ├── InPackage.kt
│ │ │ │ ├── JavaClassNames.kt
│ │ │ │ ├── JavaConstructorsCompletion.kt
│ │ │ │ ├── NoClassNameDuplicationForRuntimeClass.kt
│ │ │ │ ├── NoImportedJavaClassDuplication.kt
│ │ │ │ ├── PropertyMetadata.kt
│ │ │ │ ├── TopLevelFromStandardLibrary.kt
│ │ │ │ └── TopLevelFromStandardLibraryWithoutParam.kt
│ │ │ └── scripts/
│ │ │ ├── absentMainTemplate.kts
│ │ │ ├── argsCompletion.kts
│ │ │ ├── classFromJRE.kts
│ │ │ ├── functionFromStdlib.kts
│ │ │ ├── keywordsCompletion.kts
│ │ │ ├── localDeclarations.kts
│ │ │ └── typeFromRuntime.kts
│ │ ├── handlers/
│ │ │ ├── ExistingSingleBrackets.kt
│ │ │ ├── ExistingSingleBrackets.kt.after
│ │ │ ├── FunctionWithParamOnBracket.kt
│ │ │ ├── FunctionWithParamOnBracket.kt.after
│ │ │ ├── completeNonImported.kt
│ │ │ ├── completeNonImported.kt.after
│ │ │ ├── completeWithExistingBraces.kt
│ │ │ ├── completeWithExistingBraces.kt.after
│ │ │ ├── completeWithExistingBracesOnBrace.kt
│ │ │ ├── completeWithExistingBracesOnBrace.kt.after
│ │ │ ├── completeWithExistingBracesOnDot.kt
│ │ │ ├── completeWithExistingBracesOnDot.kt.after
│ │ │ ├── filterTypesFromSamePackage.dependency.kt
│ │ │ ├── filterTypesFromSamePackage.kt
│ │ │ ├── filterTypesFromSamePackage.kt.after
│ │ │ ├── functionLiteralInsertOnSpace.kt
│ │ │ ├── functionLiteralInsertOnSpace.kt.after
│ │ │ ├── functionWithParamOnDot.kt
│ │ │ ├── functionWithParamOnDot.kt.after
│ │ │ ├── higherOrderFunction.kt
│ │ │ ├── higherOrderFunction.kt.after
│ │ │ ├── higherOrderFunctionWithArgs1.kt
│ │ │ ├── higherOrderFunctionWithArgs1.kt.after
│ │ │ ├── insertFunctionWithBothParentheses.kt
│ │ │ ├── insertFunctionWithBothParentheses.kt.after
│ │ │ ├── insertFunctionWithSingleParameterWithBrace.kt
│ │ │ ├── insertFunctionWithSingleParameterWithBrace.kt.after
│ │ │ ├── insertJavaMethodWithParam.kt
│ │ │ ├── insertJavaMethodWithParam.kt.after
│ │ │ ├── insertVoidJavaMethod.kt
│ │ │ ├── insertVoidJavaMethod.kt.after
│ │ │ ├── noParamsFunction.kt
│ │ │ ├── noParamsFunction.kt.after
│ │ │ ├── nonImportedByCamelCase.kt
│ │ │ ├── nonImportedByCamelCase.kt.after
│ │ │ ├── paramFunctionOnBracket.kt
│ │ │ ├── paramFunctionOnBracket.kt.after
│ │ │ ├── paramFunctionOnDot.kt
│ │ │ ├── paramFunctionOnDot.kt.after
│ │ │ ├── paramsFunction.kt
│ │ │ ├── paramsFunction.kt.after
│ │ │ ├── paramsFunctionOnDot.kt
│ │ │ ├── paramsFunctionOnDot.kt.after
│ │ │ ├── singleBrackets.kt
│ │ │ ├── singleBrackets.kt.after
│ │ │ ├── unitFunctionOnBracket.kt
│ │ │ ├── unitFunctionOnBracket.kt.after
│ │ │ ├── unitFunctionOnDot.kt
│ │ │ ├── unitFunctionOnDot.kt.after
│ │ │ ├── withLambdaAndBraces.kt
│ │ │ ├── withLambdaAndBraces.kt.after
│ │ │ ├── withLambdaAndBracesOnDot.kt
│ │ │ ├── withLambdaAndBracesOnDot.kt.after
│ │ │ ├── withParamsAndBraces.kt
│ │ │ ├── withParamsAndBraces.kt.after
│ │ │ ├── withParamsAndBracesOnBrace.kt
│ │ │ ├── withParamsAndBracesOnBrace.kt.after
│ │ │ ├── withParamsAndBracesOnDot.kt
│ │ │ └── withParamsAndBracesOnDot.kt.after
│ │ ├── keywords/
│ │ │ └── InFunctionTypePosition.kt
│ │ └── relevance/
│ │ ├── byCamelCaseLocal.kt
│ │ ├── byPrefixMatchLocal.kt
│ │ ├── byPrefixWithImported.kt
│ │ ├── localBeforeNonImported.kt
│ │ ├── sortingForLocal.kt
│ │ └── sortingForNonImported.kt
│ ├── diagnostics/
│ │ ├── FunctionCalleeExpressions.kt
│ │ ├── FunctionCalleeExpressions.txt
│ │ ├── annotationAsJavaAnnotationArgument.kt
│ │ ├── constAsJavaAnnotationArgument.kt
│ │ └── resolveConstructor.kt
│ ├── findUsages/
│ │ ├── java/
│ │ │ ├── JKClassAllUsages.0.java
│ │ │ ├── JKClassAllUsages.1.kt
│ │ │ ├── JKClassAllUsages.results.txt
│ │ │ ├── JKClassDerivedAnonymousObjects.0.java
│ │ │ ├── JKClassDerivedAnonymousObjects.1.kt
│ │ │ ├── JKClassDerivedAnonymousObjects.results.txt
│ │ │ ├── JKClassDerivedClasses.0.java
│ │ │ ├── JKClassDerivedClasses.1.kt
│ │ │ ├── JKClassDerivedClasses.results.txt
│ │ │ ├── JKClassDerivedInnerClasses.0.java
│ │ │ ├── JKClassDerivedInnerClasses.1.kt
│ │ │ ├── JKClassDerivedInnerClasses.results.txt
│ │ │ ├── JKClassDerivedInnerObjects.0.java
│ │ │ ├── JKClassDerivedInnerObjects.1.kt
│ │ │ ├── JKClassDerivedInnerObjects.results.txt
│ │ │ ├── JKClassDerivedLocalClasses.0.java
│ │ │ ├── JKClassDerivedLocalClasses.1.kt
│ │ │ ├── JKClassDerivedLocalClasses.results.txt
│ │ │ ├── JKClassDerivedLocalObjects.0.java
│ │ │ ├── JKClassDerivedLocalObjects.1.kt
│ │ │ ├── JKClassDerivedLocalObjects.results.txt
│ │ │ ├── JKClassDerivedObjects.0.java
│ │ │ ├── JKClassDerivedObjects.1.kt
│ │ │ ├── JKClassDerivedObjects.results.txt
│ │ │ ├── JKClassWithImplicitConstructorAllUsages.0.java
│ │ │ ├── JKClassWithImplicitConstructorAllUsages.1.kt
│ │ │ ├── JKClassWithImplicitConstructorAllUsages.results.txt
│ │ │ ├── JKDerivedInterfaces.0.java
│ │ │ ├── JKDerivedInterfaces.1.kt
│ │ │ ├── JKDerivedInterfaces.results.txt
│ │ │ ├── JKNestedClassAllUsages.0.java
│ │ │ ├── JKNestedClassAllUsages.1.kt
│ │ │ └── JKNestedClassAllUsages.results.txt
│ │ └── kotlin/
│ │ ├── findFunctionUsages/
│ │ │ ├── javaMethodUsages.0.kt
│ │ │ ├── javaMethodUsages.1.java
│ │ │ ├── javaMethodUsages.results.txt
│ │ │ ├── kotlinMethodUsages.0.kt
│ │ │ ├── kotlinMethodUsages.1.kt
│ │ │ ├── kotlinMethodUsages.results.txt
│ │ │ ├── kotlinMultiRefInImport.0.kt
│ │ │ ├── kotlinMultiRefInImport.1.kt
│ │ │ └── kotlinMultiRefInImport.results.txt
│ │ ├── findObjectUsages/
│ │ │ ├── javaObjectUsages.0.kt
│ │ │ ├── javaObjectUsages.1.java
│ │ │ ├── javaObjectUsages.results.txt
│ │ │ ├── kotlinNestedObjectUsages.0.kt
│ │ │ ├── kotlinNestedObjectUsages.1.kt
│ │ │ ├── kotlinNestedObjectUsages.results.txt
│ │ │ ├── kotlinObjectUsages.0.kt
│ │ │ ├── kotlinObjectUsages.1.kt
│ │ │ └── kotlinObjectUsages.results.txt
│ │ ├── findPrimaryConstructorUsages/
│ │ │ ├── primaryConstructorByRef.0.kt
│ │ │ ├── primaryConstructorByRef.results.txt
│ │ │ ├── primaryConstructorWithKeyword.0.kt
│ │ │ └── primaryConstructorWithKeyword.results.txt
│ │ └── findPropertyUsages/
│ │ ├── kotlinTopLevelPropertyUsages.0.kt
│ │ ├── kotlinTopLevelPropertyUsages.1.kt
│ │ ├── kotlinTopLevelPropertyUsages.2.java
│ │ └── kotlinTopLevelPropertyUsages.results.txt
│ ├── format/
│ │ ├── autoIndent/
│ │ │ ├── afterFunCallInScript.after.kts
│ │ │ ├── afterFunCallInScript.kts
│ │ │ ├── afterOneOpenBrace.after.kt
│ │ │ ├── afterOneOpenBrace.kt
│ │ │ ├── afterOpenBraceWithShift.after.kt
│ │ │ ├── afterOpenBraceWithShift.kt
│ │ │ ├── afterOperatorIfWithoutBraces.after.kt
│ │ │ ├── afterOperatorIfWithoutBraces.kt
│ │ │ ├── afterOperatorWhileWithoutBraces.after.kt
│ │ │ ├── afterOperatorWhileWithoutBraces.kt
│ │ │ ├── beforeCloseBrace.after.kt
│ │ │ ├── beforeCloseBrace.kt
│ │ │ ├── beforeFunctionStart.after.kt
│ │ │ ├── beforeFunctionStart.kt
│ │ │ ├── betweenBracesOnDifferentLine.after.kt
│ │ │ ├── betweenBracesOnDifferentLine.kt
│ │ │ ├── betweenBracesOnOneLine.after.kt
│ │ │ ├── betweenBracesOnOneLine.kt
│ │ │ ├── betweenBracesWithSpacesAtStart.after.kt
│ │ │ ├── betweenBracesWithSpacesAtStart.kt
│ │ │ ├── betweenBracesWithSpacesEnd1.after.kt
│ │ │ ├── betweenBracesWithSpacesEnd1.kt
│ │ │ ├── betweenBracesWithSpacesEnd2.after.kt
│ │ │ ├── betweenBracesWithSpacesEnd2.kt
│ │ │ ├── betweenBracesWithSpacesMiddle.after.kt
│ │ │ ├── betweenBracesWithSpacesMiddle.kt
│ │ │ ├── breakLineAfterIfWithoutBraces.after.kt
│ │ │ ├── breakLineAfterIfWithoutBraces.kt
│ │ │ ├── continuationAfterDotCall.after.kt
│ │ │ ├── continuationAfterDotCall.kt
│ │ │ ├── continuationBeforeFunName.after.kt
│ │ │ ├── continuationBeforeFunName.kt
│ │ │ ├── indentBeforeWhile.after.kt
│ │ │ ├── indentBeforeWhile.kt
│ │ │ ├── lineBreakSaveIndent.after.kt
│ │ │ ├── lineBreakSaveIndent.kt
│ │ │ ├── nestedOperatorsWithBraces.after.kt
│ │ │ ├── nestedOperatorsWithBraces.kt
│ │ │ ├── nestedOperatorsWithoutBraces.after.kt
│ │ │ ├── nestedOperatorsWithoutBraces.kt
│ │ │ ├── newLineInParameters1.after.kt
│ │ │ ├── newLineInParameters1.kt
│ │ │ ├── newLineInParameters2.after.kt
│ │ │ ├── newLineInParameters2.kt
│ │ │ ├── sampleTest.after.kt
│ │ │ └── sampleTest.kt
│ │ ├── blockCommentBeforeDeclaration.kt
│ │ ├── blockCommentBeforeDeclaration.kt.after
│ │ ├── classesAndPropertiesFormatTest.kt
│ │ ├── classesAndPropertiesFormatTest.kt.after
│ │ ├── commentOnTheLastLineOfLambda.kt
│ │ ├── commentOnTheLastLineOfLambda.kt.after
│ │ ├── formatScriptFile.kts
│ │ ├── formatScriptFile.kts.after
│ │ ├── formatSelection.kt
│ │ ├── formatSelection.kt.after
│ │ ├── indentInDoWhile.kt
│ │ ├── indentInDoWhile.kt.after
│ │ ├── indentInIfExpressionBlock.kt
│ │ ├── indentInIfExpressionBlock.kt.after
│ │ ├── indentInPropertyAccessor.kt
│ │ ├── indentInPropertyAccessor.kt.after
│ │ ├── indentInWhenEntry.kt
│ │ ├── indentInWhenEntry.kt.after
│ │ ├── initIndent.kt
│ │ ├── initIndent.kt.after
│ │ ├── lambdaInBlock.kt
│ │ ├── lambdaInBlock.kt.after
│ │ ├── newLineAfterImportsAndPackage.kt
│ │ ├── newLineAfterImportsAndPackage.kt.after
│ │ ├── objectsAndLocalFunctionsFormatTest.kt
│ │ ├── objectsAndLocalFunctionsFormatTest.kt.after
│ │ ├── packageFunctionsFormatTest.kt
│ │ ├── packageFunctionsFormatTest.kt.after
│ │ ├── respectCaretAfterFormatting.kt
│ │ ├── respectCaretAfterFormatting.kt.after
│ │ ├── withBlockComments.kt
│ │ ├── withBlockComments.kt.after
│ │ ├── withJavaDoc.kt
│ │ ├── withJavaDoc.kt.after
│ │ ├── withLineComments.kt
│ │ ├── withLineComments.kt.after
│ │ ├── withMutableVariable.kt
│ │ ├── withMutableVariable.kt.after
│ │ ├── withWhitespaceBeforeBrace.kt
│ │ ├── withWhitespaceBeforeBrace.kt.after
│ │ ├── withoutComments.kt
│ │ └── withoutComments.kt.after
│ ├── highlighting/
│ │ ├── basic/
│ │ │ ├── blockComment.kt
│ │ │ ├── forKeyword.kt
│ │ │ ├── function.kt
│ │ │ ├── getterSetter.kt
│ │ │ ├── highlightCompanionObject.kt
│ │ │ ├── importKeyword.kt
│ │ │ ├── inKeyword.kt
│ │ │ ├── interfaceKeyword.kt
│ │ │ ├── kdocBasic.kt
│ │ │ ├── kdocWithEmptyLines.kt
│ │ │ ├── kdocWithMyTag.kt
│ │ │ ├── kdocWithParam.kt
│ │ │ ├── kdocWithProperty.kt
│ │ │ ├── kdocWithSee.kt
│ │ │ ├── kdocWithThrows.kt
│ │ │ ├── kdocWithoutLeadingAsterisk.kt
│ │ │ ├── keywordWithText.kt
│ │ │ ├── openKeyword.kt
│ │ │ ├── singleLineComment.kt
│ │ │ ├── softImportKeyword.kt
│ │ │ ├── softKeywords.kt
│ │ │ ├── stringInterpolation.kt
│ │ │ ├── stringToken.kt
│ │ │ ├── textWithTokenBetween.kt
│ │ │ ├── textWithTokenInPrefix.kt
│ │ │ └── textWithTokenInSuffix.kt
│ │ └── positionUpdater/
│ │ ├── afterFunctionName.kt
│ │ ├── afterFunctionName.kt.after
│ │ ├── afterHighlightedPosition.kt
│ │ ├── afterHighlightedPosition.kt.after
│ │ ├── beforeFunctionName.kt
│ │ ├── beforeFunctionName.kt.after
│ │ ├── beforeHighlightedPosition.kt
│ │ ├── beforeHighlightedPosition.kt.after
│ │ ├── illegalCharactersAfter.kt
│ │ ├── illegalCharactersAfter.kt.after
│ │ ├── illegalCharactersBefore.kt
│ │ ├── illegalCharactersBefore.kt.after
│ │ ├── illegalCharactersBeforeHighlightedPosition.kt
│ │ ├── illegalCharactersBeforeHighlightedPosition.kt.after
│ │ ├── insideHighlightedPosition.kt
│ │ └── insideHighlightedPosition.kt.after
│ ├── ide_analyzer/
│ │ ├── analyzerHasKotlinAnnotations.kt
│ │ ├── analyzerHasKotlinRuntime.kt
│ │ ├── checkAnalyzerFoundError.kt
│ │ ├── checkExistancePackageLevelFunctions/
│ │ │ ├── Bar.kt
│ │ │ ├── Baz.kt
│ │ │ └── Foo.java
│ │ ├── checkTestsFoundJavaError/
│ │ │ └── J1.java
│ │ ├── companionObjectFromJava/
│ │ │ ├── Bar.kt
│ │ │ └── Foo.java
│ │ ├── javaFromKotlin/
│ │ │ ├── Bar.kt
│ │ │ └── Foo.java
│ │ ├── kotlinFromJava/
│ │ │ ├── Bar.kt
│ │ │ └── Foo.java
│ │ ├── kotlinInPackageFromJava/
│ │ │ ├── J1.java
│ │ │ └── K1.kt
│ │ ├── kotlinJavaKotlin/
│ │ │ ├── J1.java
│ │ │ ├── K1.kt
│ │ │ └── K2.kt
│ │ ├── kotlinWithErrorsFromJava/
│ │ │ ├── J1.java
│ │ │ └── K1.kt
│ │ ├── packageLevelFunctionsFromJava/
│ │ │ ├── Bar.kt
│ │ │ └── Foo.java
│ │ ├── packageLevelPropertiesFromJava/
│ │ │ ├── Bar.kt
│ │ │ └── Foo.java
│ │ └── unresolvedPackageType/
│ │ ├── Bar.kt
│ │ └── Baz.kt
│ ├── intentions/
│ │ ├── changeReturnType/
│ │ │ ├── changeReturnTypeInScript.kts
│ │ │ ├── changeReturnTypeInScript.kts.after
│ │ │ ├── typeMismatchInReturnLambda.kt
│ │ │ ├── typeMismatchInReturnLambda.kt.after
│ │ │ ├── typeMismatchInReturnLambdaWithLabel.kt
│ │ │ └── typeMismatchInReturnLambdaWithLabel.kt.after
│ │ ├── convertToBlockBody/
│ │ │ ├── implicitlyNonUnitFun.kt
│ │ │ └── implicitlyNonUnitFun.kt.after
│ │ ├── convertToExpressionBody/
│ │ │ ├── anonymousObjectExpression.kt
│ │ │ ├── anonymousObjectExpression.kt.after
│ │ │ ├── funWithImplicitUnitTypeWithThrow.kt
│ │ │ ├── funWithImplicitUnitTypeWithThrow.kt.after
│ │ │ ├── funWithNothingType.kt
│ │ │ ├── funWithNothingType.kt.after
│ │ │ ├── funWithReturn.kt
│ │ │ ├── funWithReturn.kt.after
│ │ │ ├── funWithUnitTypeWithThrow.kt
│ │ │ └── funWithUnitTypeWithThrow.kt.after
│ │ ├── implementMethods/
│ │ │ ├── implementMethodInScript.kts
│ │ │ └── implementMethodInScript.kts.after
│ │ ├── replaceGetOrSet/
│ │ │ ├── replaceGetInScript.kts
│ │ │ └── replaceGetInScript.kts.after
│ │ └── specifyType/
│ │ ├── ClassNameClashing.kt
│ │ ├── ClassNameClashing.kt.after
│ │ ├── StringRedefined.kt
│ │ └── StringRedefined.kt.after
│ ├── launch/
│ │ └── junit/
│ │ ├── RunTestExtendingTestCase.kt
│ │ └── SimpleJUnitTests.kt
│ ├── markers/
│ │ └── parsing/
│ │ ├── classDefinitionTypoErrorTest.kt
│ │ ├── classDefinitionTypoErrorTest.kt.after
│ │ ├── excessBraceTypingErrorTest.kt
│ │ ├── excessBraceTypingErrorTest.kt.after
│ │ ├── missingClosingBraceErrorTest.kt
│ │ ├── missingClosingBraceErrorTest.kt.after
│ │ ├── missingFunctionBodyErrorTest.kt
│ │ └── missingFunctionBodyErrorTest.kt.after
│ ├── navigation/
│ │ ├── fromGetterSyntheticProperty/
│ │ │ ├── Bar.kt.before
│ │ │ └── Foo.java.after
│ │ ├── fromSetterSyntheticProperty/
│ │ │ ├── Bar.kt.before
│ │ │ └── Foo.java.after
│ │ ├── fromSyntheticPropertyOnlyWithGetter/
│ │ │ ├── Bar.kt.before
│ │ │ └── Foo.java.after
│ │ ├── javaToKotlin/
│ │ │ ├── specifiedPackageLevelFunction/
│ │ │ │ ├── Bar.kt
│ │ │ │ ├── Baz.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toBasicProperty/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toBasicTopLevelProperty/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toCompanionObject/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFilePart/
│ │ │ │ ├── Baz.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunInBaseClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionInEnumClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionInFilePart/
│ │ │ │ ├── Baz.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionInInnerClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionInObject/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionWithExistingConstructorEqualSignature/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionWithExistingEqualSignature/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionWithNameDuplicate/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionWithNameDuplicateInClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toFunctionWithPlatformName/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toInnerKotlinClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toInnerKotlinEnumClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toInnerKotlinEnumEntry/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinClassInPackage/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinEnumClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinEnumEntry/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinFunction/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinFunctionInCompanion/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinObject/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinSuperClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toKotlinTopLevelFunction/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toMethodWithDefaultArg/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toMutablePropertyFromGetter/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toMutablePropertyFromSetter/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toMutablePropertyInCompanion/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toNamedCompanionObject/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toNestedCompanionObject/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toObjectInstance/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toOverloadMethod1/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toOverloadMethod2/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toOverridenProperty/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toParametrizedClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toParametrizedFunction/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toParametrizedFunctionWithOverload/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toPrimaryConstructor/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toPropertyInBaseClass/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toPropertyInCompanion/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toPropertyWithGetter/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toPropertyWithSetter/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toSecondaryConstructor1/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toSecondaryConstructor2/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ ├── toTopLevelPropertyWithGetter/
│ │ │ │ ├── Bar.kt.after
│ │ │ │ └── Foo.java.before
│ │ │ └── toTopLevelPropertyWithSetter/
│ │ │ ├── Bar.kt.after
│ │ │ └── Foo.java.before
│ │ ├── scripts/
│ │ │ └── basic/
│ │ │ ├── toFunction.kts
│ │ │ ├── toFunction.kts.after
│ │ │ ├── toVariable.kts
│ │ │ └── toVariable.kts.after
│ │ ├── toJavaClassNavigation/
│ │ │ ├── Bar.kt.before
│ │ │ └── Foo.java.after
│ │ ├── toJavaGetterMethod/
│ │ │ ├── Bar.kt.before
│ │ │ └── Foo.java.after
│ │ ├── toJavaMethodNavigation/
│ │ │ ├── Bar.kt.before
│ │ │ └── Foo.java.after
│ │ ├── toKotlinClassNavigation/
│ │ │ ├── Bar.kt
│ │ │ ├── Baz.kt.before
│ │ │ └── Foo.kt.after
│ │ ├── toKotlinMethodNavigation/
│ │ │ ├── Bar.kt
│ │ │ ├── Baz.kt.before
│ │ │ └── Foo.kt.after
│ │ ├── withinFileFromConstructorToClassNavigation.kt
│ │ ├── withinFileFromConstructorToClassNavigation.kt.after
│ │ ├── withinFileToClassNavigation.kt
│ │ ├── withinFileToClassNavigation.kt.after
│ │ ├── withinFileToMethodNavigation.kt
│ │ └── withinFileToMethodNavigation.kt.after
│ ├── organizeImports/
│ │ ├── doNotInsertLinesForNoErrors.kt
│ │ ├── doNotInsertLinesForNoErrors.kt.after
│ │ ├── importOneClass.kt
│ │ ├── importOneClass.kt.after
│ │ ├── importSeveralClasses.kt
│ │ ├── importSeveralClasses.kt.after
│ │ ├── importSeveralClassesWithExistingPackage.kt
│ │ ├── importSeveralClassesWithExistingPackage.kt.after
│ │ └── includeImportsOnlyFromActiveFile/
│ │ ├── Bar.kt
│ │ ├── Bar.kt.after
│ │ └── Baz.kt
│ ├── refactoring/
│ │ └── rename/
│ │ ├── automaticRenamer/
│ │ │ ├── after/
│ │ │ │ ├── JavaFoo.java
│ │ │ │ ├── lib.kt
│ │ │ │ └── main.kt
│ │ │ ├── before/
│ │ │ │ ├── JavaFoo.java
│ │ │ │ ├── lib.kt
│ │ │ │ └── main.kt
│ │ │ └── simple.test
│ │ ├── renameJavaClass/
│ │ │ ├── after/
│ │ │ │ ├── RenameJavaClass.kt
│ │ │ │ └── testing/
│ │ │ │ └── NewName.java
│ │ │ ├── before/
│ │ │ │ ├── RenameJavaClass.kt
│ │ │ │ └── testing/
│ │ │ │ └── SomeClass.java
│ │ │ └── renameJavaClass.test
│ │ ├── renameJavaClassSamePackage/
│ │ │ ├── after/
│ │ │ │ ├── RenameJavaClassSamePackage.kt
│ │ │ │ └── testing/
│ │ │ │ └── NewName.java
│ │ │ ├── before/
│ │ │ │ ├── RenameJavaClassSamePackage.kt
│ │ │ │ └── testing/
│ │ │ │ └── SomeClass.java
│ │ │ └── renameJavaClassSamePackage.test
│ │ ├── renameJavaInterface/
│ │ │ ├── after/
│ │ │ │ ├── RenameJavaClass.kt
│ │ │ │ └── testing/
│ │ │ │ └── NewInterface.java
│ │ │ ├── before/
│ │ │ │ ├── RenameJavaClass.kt
│ │ │ │ └── testing/
│ │ │ │ └── SomeInterface.java
│ │ │ └── renameJavaInterface.test
│ │ ├── renameJavaMethod/
│ │ │ ├── after/
│ │ │ │ ├── MethodUsages.kt
│ │ │ │ └── testing/
│ │ │ │ └── JavaClass.java
│ │ │ ├── before/
│ │ │ │ ├── MethodUsages.kt
│ │ │ │ └── testing/
│ │ │ │ └── JavaClass.java
│ │ │ ├── javaBaseMethod.test
│ │ │ └── kotlinOverridenMethod.test
│ │ ├── renameJavaStaticMethod/
│ │ │ ├── after/
│ │ │ │ ├── Some.kt
│ │ │ │ └── SomeJava.java
│ │ │ ├── before/
│ │ │ │ ├── Some.kt
│ │ │ │ └── SomeJava.java
│ │ │ └── renameJavaStaticMethod.test
│ │ ├── renameKotlinBaseMethod/
│ │ │ ├── after/
│ │ │ │ ├── RenameKotlinBaseMethod.kt
│ │ │ │ └── testing/
│ │ │ │ └── JavaClient.java
│ │ │ ├── before/
│ │ │ │ ├── RenameKotlinBaseMethod.kt
│ │ │ │ └── testing/
│ │ │ │ └── JavaClient.java
│ │ │ ├── javaWrapperForBaseFunction.test
│ │ │ ├── javaWrapperForOverridenFunctionWithKotlinBase.test
│ │ │ └── kotlinBaseFunction.test
│ │ ├── renameKotlinClass/
│ │ │ ├── after/
│ │ │ │ ├── RenameKotlinClass.kt
│ │ │ │ ├── Second.kt
│ │ │ │ └── testing/
│ │ │ │ └── JavaClient.java
│ │ │ ├── before/
│ │ │ │ ├── RenameKotlinClass.kt
│ │ │ │ ├── Second.kt
│ │ │ │ └── testing/
│ │ │ │ └── JavaClient.java
│ │ │ ├── javaWrapperForKotlinClass.test
│ │ │ └── kotlinClass.test
│ │ ├── renameKotlinClassByConstructorRef/
│ │ │ ├── after/
│ │ │ │ └── main.kt
│ │ │ ├── before/
│ │ │ │ └── main.kt
│ │ │ └── renameKotlinClassByConstructorRef.test
│ │ ├── renameKotlinClassFromJava/
│ │ │ ├── after/
│ │ │ │ ├── JavaUsage.java
│ │ │ │ └── KotlinCls.kt
│ │ │ ├── before/
│ │ │ │ ├── JavaUsage.java
│ │ │ │ └── KotlinCls.kt
│ │ │ └── renameKotlinClassFromJava.test
│ │ ├── renameKotlinMethod/
│ │ │ ├── after/
│ │ │ │ ├── RenameKotlinMethod.kt
│ │ │ │ └── testing/
│ │ │ │ └── JavaClient.java
│ │ │ ├── before/
│ │ │ │ ├── RenameKotlinMethod.kt
│ │ │ │ └── testing/
│ │ │ │ └── JavaClient.java
│ │ │ ├── javaWrapperForKotlinMethod.test
│ │ │ └── renameKotlinMethod.test
│ │ ├── renameKotlinMethodFromJava/
│ │ │ ├── after/
│ │ │ │ ├── JavaUsage.java
│ │ │ │ └── KotlinCls.kt
│ │ │ ├── before/
│ │ │ │ ├── JavaUsage.java
│ │ │ │ └── KotlinCls.kt
│ │ │ └── renameKotlinMethodFromJava.test
│ │ ├── renameKotlinTopLevelFun/
│ │ │ ├── after/
│ │ │ │ ├── Some.kt
│ │ │ │ └── SomeJava.java
│ │ │ ├── before/
│ │ │ │ ├── Some.kt
│ │ │ │ └── SomeJava.java
│ │ │ └── renameKotlinTopLevelFun.test
│ │ ├── renameKotlinTopLevelFunFromJava/
│ │ │ ├── after/
│ │ │ │ ├── JavaUsage.java
│ │ │ │ └── KotlinCls.kt
│ │ │ ├── before/
│ │ │ │ ├── JavaUsage.java
│ │ │ │ └── KotlinCls.kt
│ │ │ └── renameKotlinTopLevelFunFromJava.test
│ │ ├── scripts/
│ │ │ ├── renameClassInScript/
│ │ │ │ ├── after/
│ │ │ │ │ └── main.kts
│ │ │ │ ├── before/
│ │ │ │ │ └── main.kts
│ │ │ │ └── info.test
│ │ │ ├── renameFunctionInScript/
│ │ │ │ ├── after/
│ │ │ │ │ └── main.kts
│ │ │ │ ├── before/
│ │ │ │ │ └── main.kts
│ │ │ │ └── info.test
│ │ │ ├── renameInScriptLocally/
│ │ │ │ ├── after/
│ │ │ │ │ ├── main.kts
│ │ │ │ │ └── other.kts
│ │ │ │ ├── before/
│ │ │ │ │ ├── main.kts
│ │ │ │ │ └── other.kts
│ │ │ │ └── info.test
│ │ │ └── renamePropertyInScript/
│ │ │ ├── after/
│ │ │ │ └── main.kts
│ │ │ ├── before/
│ │ │ │ └── main.kts
│ │ │ └── info.test
│ │ └── simple/
│ │ ├── after/
│ │ │ └── main.kt
│ │ ├── before/
│ │ │ └── main.kt
│ │ └── info.test
│ ├── scripts/
│ │ └── templates/
│ │ ├── customEPResolver.kts
│ │ ├── sample.testDef.kts
│ │ ├── sampleEx.testDef.kts
│ │ └── standard.kts
│ └── wordSelection/
│ ├── selectEnclosing/
│ │ ├── DocComment/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ └── 3.kt
│ │ ├── ForRange/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ └── 3.kt
│ │ ├── FunctionWithLineCommentAfter/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ └── 3.kt
│ │ ├── FunctionWithLineCommentBefore/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ └── 3.kt
│ │ ├── IfBody/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ ├── 4.kt
│ │ │ └── 5.kt
│ │ ├── IfCondition/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ └── 3.kt
│ │ ├── LineComment/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── ShiftOnWhitespace/
│ │ │ ├── 0.kt
│ │ │ └── 1.kt
│ │ ├── SimpleComment/
│ │ │ ├── 0.kt
│ │ │ └── 1.kt
│ │ ├── SimpleStringLiteral/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── SimpleStringLiteral2/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── Statements/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ ├── 4.kt
│ │ │ ├── 5.kt
│ │ │ ├── 6.kt
│ │ │ ├── 7.kt
│ │ │ ├── 8.kt
│ │ │ └── 9.kt
│ │ ├── StatementsWithWindowsDelimiter/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ ├── 4.kt
│ │ │ ├── 5.kt
│ │ │ ├── 6.kt
│ │ │ ├── 7.kt
│ │ │ ├── 8.kt
│ │ │ └── 9.kt
│ │ ├── TemplateStringLiteral1/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ └── 3.kt
│ │ ├── TemplateStringLiteral2/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ └── 4.kt
│ │ ├── TemplateStringLiteral3/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ ├── 4.kt
│ │ │ └── 5.kt
│ │ ├── TypeArguments/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── TypeParameters/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── ValueArguments/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── ValueParameters/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── WhenEntries/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ └── 4.kt
│ │ ├── WholeFileSelection/
│ │ │ ├── 0.kt
│ │ │ └── 1.kt
│ │ └── selectEnclosingFunctionNameWithoutSelection/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ ├── 3.kt
│ │ ├── 4.kt
│ │ ├── 5.kt
│ │ └── 6.kt
│ ├── selectNext/
│ │ ├── BlockStatements/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ ├── 4.kt
│ │ │ ├── 5.kt
│ │ │ ├── 6.kt
│ │ │ ├── 7.kt
│ │ │ ├── 8.kt
│ │ │ └── 9.kt
│ │ ├── BlockStatementsWithWindowsDelimiter/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ ├── 4.kt
│ │ │ ├── 5.kt
│ │ │ ├── 6.kt
│ │ │ ├── 7.kt
│ │ │ ├── 8.kt
│ │ │ └── 9.kt
│ │ ├── Classes/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ └── 4.kt
│ │ ├── DocComment/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ └── 4.kt
│ │ ├── FunctionWithLineComments/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ └── 4.kt
│ │ ├── Functions/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── Imports/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ ├── 4.kt
│ │ │ ├── 5.kt
│ │ │ ├── 6.kt
│ │ │ └── 7.kt
│ │ ├── NonTraversableElement/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── ShiftOnWhitespace/
│ │ │ ├── 0.kt
│ │ │ └── 1.kt
│ │ ├── TemplateStringLiteral/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ ├── 3.kt
│ │ │ ├── 4.kt
│ │ │ └── 5.kt
│ │ ├── TypeArguments/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── TypeParameters/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ └── 2.kt
│ │ ├── ValueArguments/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ └── 3.kt
│ │ ├── ValueParameters/
│ │ │ ├── 0.kt
│ │ │ ├── 1.kt
│ │ │ ├── 2.kt
│ │ │ └── 3.kt
│ │ └── WholeFile/
│ │ ├── 0.kt
│ │ └── 1.kt
│ └── selectPrevious/
│ ├── BlockStatements/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ ├── 3.kt
│ │ ├── 4.kt
│ │ ├── 5.kt
│ │ ├── 6.kt
│ │ ├── 7.kt
│ │ ├── 8.kt
│ │ └── 9.kt
│ ├── BlockStatementsWithWindowsDelimiter/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ ├── 3.kt
│ │ ├── 4.kt
│ │ ├── 5.kt
│ │ ├── 6.kt
│ │ ├── 7.kt
│ │ ├── 8.kt
│ │ └── 9.kt
│ ├── Classes/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ ├── 3.kt
│ │ └── 4.kt
│ ├── DocComment/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ ├── 3.kt
│ │ └── 4.kt
│ ├── FunctionWithLineComments/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ ├── 3.kt
│ │ └── 4.kt
│ ├── Functions/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ └── 2.kt
│ ├── Imports/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ ├── 3.kt
│ │ ├── 4.kt
│ │ ├── 5.kt
│ │ ├── 6.kt
│ │ └── 7.kt
│ ├── NonTraversableElement/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ └── 2.kt
│ ├── ShiftOnWhitespace/
│ │ ├── 0.kt
│ │ └── 1.kt
│ ├── TemplateStringLiteral/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ ├── 3.kt
│ │ ├── 4.kt
│ │ └── 5.kt
│ ├── TypeArguments/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ └── 3.kt
│ ├── TypeParameters/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ └── 3.kt
│ ├── ValueArguments/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ └── 3.kt
│ ├── ValueParameters/
│ │ ├── 0.kt
│ │ ├── 1.kt
│ │ ├── 2.kt
│ │ └── 3.kt
│ └── WholeFile/
│ ├── 0.kt
│ └── 1.kt
├── kotlin-weaving-feature/
│ ├── build.properties
│ ├── feature.xml
│ └── pom.xml
├── maven-build/
│ ├── maven-build-install-offline.launch
│ ├── maven-build-install.launch
│ └── maven-update-version.launch
├── pom.xml
└── publish-new-version.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
**/testData/** linguist-vendored
================================================
FILE: .github/workflows/main.yml
================================================
name: kotlin-eclipse
on:
push:
branches: [ "master" ]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
- name: Build with Maven
run: mvn --batch-mode --nsu clean && mvn --batch-mode --update-snapshots clean validate -Pwith-gradle -pl kotlin-bundled-compiler && mvn --batch-mode --update-snapshots package
- name: Publish eclipse repository
uses: actions/upload-artifact@v3
with:
name: kotlin-eclipse-plugin
path: kotlin-eclipse-p2updatesite/target/kotlin-eclipse-plugin.zip
================================================
FILE: .gitignore
================================================
.DS_Store
.gradle
.idea
.metadata
.recommenders
.gradletasknamecache
bin
build
common_testData
kotlin-eclipse-ui-test/lib
kotlin-eclipse-gradle-model/lib
target
*.iml
*.orig
target/
.settings
.classpath
.project
lib
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2013-2019 JetBrains s.r.o. and Kotlin for Eclipse project contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
Kotlin for Eclipse
==============
[](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
Welcome to Kotlin for Eclipse project! Some handy links:
* [Kotlin Site](http://kotlinlang.org/)
* [Getting Started Guide](http://kotlinlang.org/docs/tutorials/getting-started-eclipse.html)
* [Kotlin on Eclipse Marketplace](https://marketplace.eclipse.org/content/kotlin-plugin-eclipse)
* Issue Tracker: [File New Issue](https://youtrack.jetbrains.com/newIssue?project=KE&clearDraft=true), [All Open Issues](https://youtrack.jetbrains.com/issues/KE?q=%23Unresolved)
* [Kotlin Blog](http://blog.jetbrains.com/kotlin/)
* [Forum](https://discuss.kotlinlang.org/)
* [TeamCity CI build](https://teamcity.jetbrains.com/viewType.html?buildTypeId=Kotlin_EclipsePlugin)
* [Follow Kotlin on Twitter](https://twitter.com/kotlin)
### Installation
To give it a try you will need a clean installation of Eclipse Neon or newer. The Kotlin plugin is available from the Eclipse Marketplace. The easiest way to install the Kotlin plugin is to **drag-and-drop this button into a running Eclipse window**:
Alternatively, you can use *Help -> Eclipse Marketplace�* menu, or the following update site:
https://files.pkg.jetbrains.space/kotlin/p/kotlin-eclipse/main/last/
### Building and Development
*Eclipse IDE for Eclipse Committers* is the recommended way to build and develop the `kotlin-eclipse` project. Eclipse [Oxygen 4.7](https://www.eclipse.org/downloads/packages/eclipse-ide-eclipse-committers/oxygenr) is used so far.
In order to start development in Eclipse:
- Install the [AspectJ Eclipse plug-in for Eclipse 4.7](http://www.eclipse.org/ajdt/downloads/index.php). To install AJDT 2.2.4 use the following update site:
http://download.eclipse.org/tools/ajdt/47/dev/update
- Since Kotlin plugin contains code written in Kotlin itself, you will also need a Kotlin plugin to build the project in Eclipse. To install the Kotlin Eclipse plugin use the following update site:
https://teamcity.jetbrains.com/guestAuth/repository/download/Kotlin_EclipsePlugin/bootstrap.tcbuildtag/
- Since Kotlin plugin uses weaving, you need to launch the project with weaving enabled. Installation of Equinox Weaving Launcher will add two additional launch configurations types for running plugin and for testing. To install the Equinox Weaving Launcher you can use the following update site:
http://download.scala-ide.org/plugins/equinox-weaving-launcher/releases/site/
- Import plugin projects from the cloned repository into your workspace
File -> Import -> Existing Projects into Workspace
- Using the command line, run gradle build to download the Kotlin compiler. It will be used as a bundled compiler in built plugin and as a library during development.
cd {repository}/kotlin-bundled-compiler
./gradlew clean getBundled
or in Windows environment:
cd {repository}\kotlin-bundled-compiler
gradlew.bat clean getBundled
- Run another instance of Eclipse with the Kotlin plugin inside
kotlin-eclipse-ui -> Run As -> Eclipse Weaving enabled Eclipse Application
Building from the command line is also available (Note that Maven **3.0.5** is required):
cd {repository}
mvn install
### Eclipse update sites
Latest stable release:
https://files.pkg.jetbrains.space/kotlin/p/kotlin-eclipse/main/last/
Any previously released version (replace *:version* with the version number):
https://files.pkg.jetbrains.space/kotlin/p/kotlin-eclipse/main/:version/
Nightly build:
https://teamcity.jetbrains.com/guestAuth/repository/download/Kotlin_EclipsePlugin/.lastSuccessful/
### Kotlin Eclipse Plugin Developer Documentation
See basic developer documentation [here](https://github.com/JetBrains/kotlin-eclipse/blob/master/docs/dev-documentation.md)
================================================
FILE: common-settings/kotlin-formatting.xml
================================================
================================================
FILE: docs/dev-documentation.md
================================================
# Kotlin Eclipse Plugin Developer Documentation
## Kotlin Eclipse plugins overview
Kotlin plugin consists of several plugins, here is a short description for each of them:
- `kotlin-bundled-compiler`: This plugin is used as a dependency for all other plugins, it exports main jars to work with Kotlin (`kotlin-compiler.jar`, `kotlin-ide-common.jar`...).
Kotlin compiler will be used as the bundled compiler in the built plugin and as a library during development.
Also, `kotlin-bundled-compiler` plugin contains several helper classes for IDE-features (such as formatter) that are coming from IntelliJ IDEA.
- `kotlin-eclipse-aspects`: This plugin provides several aspects to weave into Eclipse and JDT internals.
- `kotlin-eclipse-core`: This plugin is used to interact with the Kotlin compiler to configure it and provide such features as analysis, compilation and interoperability with Java.
- `kotlin-eclipse-maven`: This plugin depends on `m2e` plugin and provides functionality to configure maven project with Kotlin.
- `kotlin-eclipse-ui`: This plugin provides IDE features through the standard Eclipse and JDT extension points.
- `kotlin-eclipse-test-framework`: This plugin contains useful utils and mock classes to write tests
- `kotlin-eclipse-ui-test`: This plugin contains functional tests for IDE features
#### Interoperability with JDT
Existing Java code can be called from Kotlin in a natural way, and Kotlin code can be used from Java.
Java code in Eclipse should understand Kotlin. Features such as navigation, refactorings, find usages, and others should work together with Kotlin and Java.
##### Light classes
Note that Kotlin does not have a presentation compiler, like Java or Scala. Instead of this, the
Kotlin plugin generates so called "light class files": Kotlin source code translated to bytecode declarations without bodies.
Each project with Kotlin in Eclipse depends on `KOTLIN_CONTAINER` (see [`KotlinClasspathContainer`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/KotlinClasspathContainer.kt))
which contains `kotlin-stdlib.jar`, `kotlin-reflect.jar` and a folder with light classfiles (`kotlin_bin`).
Light classes are stored only in virtual memory and are managed by a special file system (see [`KotlinFileSystem`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/filesystem/KotlinFileSystem.java)
, [`KotlinFileStore`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/filesystem/KotlinFileStore.kt)),
so they do not affect the runtime.
Let us describe what is happening on each file save.
On each file save Eclipse triggers Kotlin builder, then the method [`KotlinLightClassGeneration.updateLightClasses()`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/asJava/KotlinLightClassGeneration.kt)
is called which takes affected files and computes names of class files that can be created from the affected source files.
If we don't find a light class in our cache, we create a new empty class file in our file system. If file exists, we touch that file.
After this, Eclipse determines that some class files on the classpath were added or changed which triggers reindex for those files
by calling method [`KotlinFileStore.openInputStream`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/filesystem/KotlinFileStore.kt#L46).
This method generates bytecode for the light class by calling the Kotlin compiler in special mode ([`KotlinLightClassGeneration.buildLightClasses`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/asJava/KotlinLightClassGeneration.kt#L43)).
Basically, this allows Java to see Kotlin sources as special binary dependency.
##### Light classes to Kotlin source code
Existence of light classes allows to call Kotlin code from Java in Eclipse, but to navigate from Java to Kotlin source code we have to map light classes to the source code.
Otherwise we would navigate to the binary code. Unfortunately, Eclipse JDT does not provide any extension point to handle such case, and to do so, we use aspects to weave
into Java navigation mechanism. We provide a simple aspect ([`KotlinOpenEditorAspect.aj`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/navigation/KotlinOpenEditorAspect.aj)),
which weaves into `org.eclipse.jdt.internal.ui.javaeditor.EditorUtility.openInEditor` method and checks input element.
If this element belongs to our special file system, then we are trying to find corresponding source element in Kotlin and navigate to it.
### Editor Actions
Kotlin plugin provides editors for usual Kotlin files (`.kt`), Kotlin script files (`.kts`) and Kotlin binary files (`.class` files).
Each editor implements common interface [`KotlinEditor`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/KotlinEditor.kt).
Editors for Kotlin files and script files also implement [`KotlinCommonEditor`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/KotlinCommonEditor.kt).
[`KotlinCommonEditor`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/KotlinCommonEditor.kt)
extends Java editor (`CompilationUnitEditor`) and provides own editor actions (see [`createActions`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/KotlinCommonEditor.kt#L108))
#### Organize imports action example
As an example of editor action let's consider how organize imports works. Organize imports action is registered in [`createActions`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/KotlinCommonEditor.kt#L145)
method with the corresponding action ID. As we reuse the Java editor, we don't have to set up shortcuts, they will be the same as for Java editor.
The main method for this action is [`KotlinOrganizeImportsAction.run`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/organizeImports/KotlinOrganizeImportsAction.kt#L59).
First of all, it collects missing imports, adds them to the existing imports and then runs [`KotlinOrganizeImportsAction.optimizeImports`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/organizeImports/KotlinOrganizeImportsAction.kt#L86).
This method removes duplicates and unused imports, reorganizes imports and replaces some explicit imports with the star import. The important part here is that we
reuse the code to optimize imports from the Kotlin plugin for IntelliJ IDEA. The original method that is called from the Eclipse plugin is [`buildOptimizedImports`](https://github.com/JetBrains/kotlin/blob/master/idea/ide-common/src/org/jetbrains/kotlin/idea/util/OptimizedImportsBuilder.kt#L87),
which is also used in the plugin for IDEA.
#### Code reuse from the IDEA plugin
Eclipse plugin depends on `kotlin-ide-common.jar` artifact, which provides common functionality for IDEA and Eclipse plugin.
Basically, this is a module ([`ide-common`](https://github.com/JetBrains/kotlin/tree/master/idea/ide-common)) in Kotlin project with minimum dependencies,
so it can be used in Eclipse or Netbeans plugin. This module provides several features that are used across the Eclipse plugin.
For example, completion in the Eclipse plugin mostly reuses parts of completion from the IDEA plugin
([`KotlinCompletionUtils.getReferenceVariants`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/completion/KotlinCompletionUtils.kt#L84)
uses [`ReferenceVarianceHelper`](https://github.com/JetBrains/kotlin/blob/master/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt)).
Generally, it's a preferable way to implement features in the Eclipse plugin, i.e. to reuse parts from the IDEA plugin. Unfortunately, there is no
common way to do this because of different models of IDEs.
### Kotlin compilation and launch
Kotlin Eclipse plugin does not support incremental compilation or presentation compiler. Kotlin files are compiled using the
Kotlin compiler in [`KotlinCompiler.compileKotlinFiles`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/compiler/KotlinCompiler.java#L48).
#### Kotlin Builder
Kotlin plugin uses the Eclipse builder concept to track changes and compile Kotlin files if needed. For a usual change in project,
Kotlin builder only updates light classes. Then, if project is being built to launch the application ([`KotlinBuilder.isBuildingForLaunch`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/builder/KotlinBuilder.kt#L180)),
Kotlin builder compiles Kotlin files (in [`KotlinBuilder.build`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/builder/KotlinBuilder.kt#L63)).
Therefore, Kotlin builder should always precede Java builder.
#### Kotlin Nature
There is a Kotlin [nature](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/model/KotlinNature.kt)
to mark Kotlin projects.
#### Kotlin Debugger
Kotlin Eclipse plugin is using the standard debugger for Java in Eclipse.
For example, there are [`KotlinToggleBreakpointAdapter`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/debug/KotlinToggleBreakpointAdapter.kt)
and [`KotlinRunToLineAdapter`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/debug/KotlinRunToLineAdapter.kt)
adapters to add breakpoint to a specific line and to support action "run to cursor".
### Kotlin environment and project analysis
In order to analyse files and use compiler API, [`KotlinEnvironment`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/model/KotlinEnvironment.kt#L207)
have to be configured. Basically, `KotlinEnvironment` is created for each project in Eclipse and maps external (from Eclipse) project model to the internal one.
Also, it registers various services and configures dependencies, see [`KotlinEnvironment.configureClasspath`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/model/KotlinEnvironment.kt#L231).
Important note: if classpath was changed, corresponding Kotlin environment should be recreated.
#### Kotlin parsing
There are PSI and Kt elements that are basically represent concrete syntax tree of Kotlin program. (The term "PSI" is used in IntelliJ IDEA to refer to the syntax tree, and stands for "Program Structure Interface".) To get the parsed version of a source file
[`KotlinPsiManager`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/builder/KotlinPsiManager.kt)
should be used. Note that it caches last version of `KtFile`, so to get actual `KtFile`, source code of file can be
explicitly passed to the [`getKotlinFileIfExist`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/builder/KotlinPsiManager.kt#L368)
method, or you can use [`commitFile`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/builder/KotlinPsiManager.kt#L389)
to reparse and cache changed file.
#### "Remove explicit type" quick assist example
Let's consider how "Remove explicit type" quick assist works. This quick assist removes explicitly written type reference for property,
function and loop parameter, i.e. it converts `val s: String = "value"` to `val s = "value"`.
First of all, when user invokes quick assist on some element (`ctrl+1`), method
[`KotlinQuickAssist.isApplicable`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/quickassist/KotlinQuickAssist.kt#L32)
is called. `isApplicable` method obtains current PSI element ([`getActiveElement`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/quickassist/KotlinQuickAssist.kt#L37)),
it gets PSI file and then calls `findElementAt` to get concrete element at specific offset.
Once we get active PSI element, we pass it to our quick assists and check for theirs applicability.
[`KotlinRemoveExplicitTypeAssistProposal.isApplicable`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/quickassist/KotlinRemoveExplicitTypeAssistProposal.kt#L35)
checks that active PSI element is actually a property, function or loop parameter with a type reference.
In method [`KotlinRemoveExplicitTypeAssistProposal.apply`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/quickassist/KotlinRemoveExplicitTypeAssistProposal.kt#L62)
quick assist is executed and removes corresponding type reference.
This and other quick assists and actions rely completely on the knowledge of CST for Kotlin. In order to make it easier, there is an action
"View Psi Structure for Current File" in the context menu for Kotlin file, which can be used to examine structure of the Kotlin CST.
#### Kotlin analyzer
Many features in IDE requires more deep knowledge of the Kotlin compiler implementation. For example, [`KotlinLineAnnotationsReconciler`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/annotations/AnnotationManager.kt#L146)
is used to show diagnostics from the compiler. It uses concept of `ReconcilingStrategy` and runs after each change in active file,
when analysis results for the file will be ready and cached. The main line there is `KotlinAnalyzer.analyzeFile(file)...`, which returns
analysis results and can be used to get diagnostics from the compiler.
Kotlin compiler uses map called `BindingContext` to contain all types and internal representations (descriptors) for expressions in program.
To get binding context one can use [`KotlinAnalyzer.analyzeFile(file).bindingContext`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-core/src/org/jetbrains/kotlin/core/resolve/KotlinAnalyzer.kt#L26).
See [`KotlinSemanticHighlighter`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/highlighting/KotlinSemanticHighlighting.kt)
for an example of the compiler analysis use. There are several methods in [`KotlinSemanticHighlightingVisitor`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/highlighting/KotlinSemanticHighlightingVisitor.kt),
which uses binding context to obtain information either from a declaration ([`visitProperty`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/highlighting/KotlinSemanticHighlightingVisitor.kt#L123)),
or from a reference ([`visitSimpleNameExpression`](https://github.com/JetBrains/kotlin-eclipse/blob/master/kotlin-eclipse-ui/src/org/jetbrains/kotlin/ui/editors/highlighting/KotlinSemanticHighlightingVisitor.kt#L82)).
================================================
FILE: kotlin-bundled-compiler/Get Bundled Kotlin.launch
================================================
================================================
FILE: kotlin-bundled-compiler/META-INF/MANIFEST.MF
================================================
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Bundled Kotlin Compiler
Bundle-SymbolicName: org.jetbrains.kotlin.bundled-compiler;singleton:=true
Bundle-Version: 0.8.24.qualifier
Bundle-Vendor: JetBrains
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ClassPath: .,
lib/ide-common.jar,
lib/kotlin-compiler.jar,
lib/ide-dependencies.jar,
lib/kotlin-stdlib.jar,
lib/kotlin-plugin-parts.jar,
lib/kotlin-script-runtime.jar,
lib/kotlin-scripting-compiler.jar,
lib/kotlin-formatter.jar,
lib/kotlin-common.jar,
lib/kotlin-core.jar,
lib/kotlin-idea.jar,
lib/kotlin-j2k-old.jar,
lib/kotlin-j2k-new.jar,
lib/kotlin-j2k-idea.jar,
lib/kotlin-j2k-services.jar,
lib/kotlin-frontend-independent.jar,
lib/kotlin-reflect.jar,
../kotlin-eclipse-ui-test/lib/gson-2.3.1.jar,
lib/annotations-13.0.jar,
lib/kotlin-scripting-compiler-impl.jar,
lib/kotlin-scripting-common.jar,
lib/kotlin-scripting-jvm.jar,
lib/kotlinx-coroutines-core.jar
Export-Package: com.google.common.collect,
com.intellij,
org.jetbrains.kotlin.idea.util.application,
org.jetbrains.kotlin.idea.caches.resolve,
org.jetbrains.kotlin.idea.core.util,
org.jetbrains.kotlin.nj2k,
org.jetbrains.kotlin.idea.j2k,
org.jetbrains.kotlin.nj2k.postProcessing,
com.intellij.codeInsight,
com.intellij.codeInsight.completion.scope,
com.intellij.codeInsight.folding,
com.intellij.codeInsight.folding.impl,
com.intellij.codeInsight.javadoc,
com.intellij.codeInsight.runner,
com.intellij.core,
com.intellij.diagnostic,
com.intellij.extapi.psi,
com.intellij.formatting,
com.intellij.icons,
com.intellij.ide,
com.intellij.ide.highlighter,
com.intellij.ide.plugins,
com.intellij.ide.util,
com.intellij.injected.editor,
com.intellij.lang,
com.intellij.lang.folding,
com.intellij.lang.impl,
com.intellij.lang.injection,
com.intellij.lang.java,
com.intellij.lang.java.lexer,
com.intellij.lang.java.parser,
com.intellij.lang.jvm,
com.intellij.lang.jvm.facade,
com.intellij.lexer,
com.intellij.mock,
com.intellij.navigation,
com.intellij.openapi,
com.intellij.openapi.application,
com.intellij.openapi.application.ex,
com.intellij.openapi.application.impl,
com.intellij.openapi.command,
com.intellij.openapi.command.impl,
com.intellij.openapi.command.undo,
com.intellij.openapi.components,
com.intellij.openapi.diagnostic,
com.intellij.openapi.editor,
com.intellij.openapi.editor.actionSystem,
com.intellij.openapi.editor.colors,
com.intellij.openapi.editor.event,
com.intellij.openapi.editor.ex,
com.intellij.openapi.editor.impl,
com.intellij.openapi.editor.impl.event,
com.intellij.openapi.editor.markup,
com.intellij.openapi.extensions,
com.intellij.openapi.extensions.impl,
com.intellij.openapi.fileEditor,
com.intellij.openapi.fileEditor.impl,
com.intellij.openapi.fileTypes,
com.intellij.openapi.module,
com.intellij.openapi.progress,
com.intellij.openapi.project,
com.intellij.openapi.projectRoots,
com.intellij.openapi.roots,
com.intellij.openapi.ui,
com.intellij.openapi.util,
com.intellij.openapi.util.io,
com.intellij.openapi.util.objectTree,
com.intellij.openapi.util.registry,
com.intellij.openapi.util.text,
com.intellij.openapi.vfs,
com.intellij.openapi.vfs.encoding,
com.intellij.openapi.vfs.ex,
com.intellij.openapi.vfs.impl,
com.intellij.openapi.vfs.impl.jar,
com.intellij.openapi.vfs.local,
com.intellij.openapi.vfs.newvfs,
com.intellij.openapi.vfs.newvfs.events,
com.intellij.openapi.vfs.pointers,
com.intellij.patterns,
com.intellij.patterns.compiler,
com.intellij.pom,
com.intellij.pom.event,
com.intellij.pom.impl,
com.intellij.pom.java,
com.intellij.pom.tree,
com.intellij.pom.tree.events,
com.intellij.pom.tree.events.impl,
com.intellij.psi,
com.intellij.psi.augment,
com.intellij.psi.codeStyle,
com.intellij.psi.compiled,
com.intellij.psi.controlFlow,
com.intellij.psi.css,
com.intellij.psi.filters,
com.intellij.psi.filters.classes,
com.intellij.psi.filters.element,
com.intellij.psi.filters.position,
com.intellij.psi.formatter,
com.intellij.psi.impl,
com.intellij.psi.impl.cache,
com.intellij.psi.impl.compiled,
com.intellij.psi.impl.file,
com.intellij.psi.impl.file.impl,
com.intellij.psi.impl.java.stubs,
com.intellij.psi.impl.java.stubs.impl,
com.intellij.psi.impl.java.stubs.index,
com.intellij.psi.impl.light,
com.intellij.psi.impl.meta,
com.intellij.psi.impl.smartPointers,
com.intellij.psi.impl.source,
com.intellij.psi.impl.source.codeStyle,
com.intellij.psi.impl.source.javadoc,
com.intellij.psi.impl.source.resolve,
com.intellij.psi.impl.source.resolve.graphInference,
com.intellij.psi.impl.source.resolve.graphInference.constraints,
com.intellij.psi.impl.source.resolve.reference,
com.intellij.psi.impl.source.resolve.reference.impl,
com.intellij.psi.impl.source.resolve.reference.impl.manipulators,
com.intellij.psi.impl.source.resolve.reference.impl.providers,
com.intellij.psi.impl.source.tree,
com.intellij.psi.impl.source.tree.injected,
com.intellij.psi.impl.source.tree.java,
com.intellij.psi.infos,
com.intellij.psi.javadoc,
com.intellij.psi.meta,
com.intellij.psi.presentation.java,
com.intellij.psi.scope,
com.intellij.psi.scope.conflictResolvers,
com.intellij.psi.scope.processor,
com.intellij.psi.scope.util,
com.intellij.psi.search,
com.intellij.psi.search.searches,
com.intellij.psi.stubs,
com.intellij.psi.targets,
com.intellij.psi.templateLanguages,
com.intellij.psi.text,
com.intellij.psi.tree,
com.intellij.psi.tree.java,
com.intellij.psi.util,
com.intellij.reference,
com.intellij.testFramework,
com.intellij.ui,
com.intellij.util,
com.intellij.util.cls,
com.intellij.util.codeInsight,
com.intellij.util.concurrency,
com.intellij.util.containers,
com.intellij.util.containers.hash,
com.intellij.util.diff,
com.intellij.util.execution,
com.intellij.util.graph,
com.intellij.util.indexing,
com.intellij.util.io,
com.intellij.util.keyFMap,
com.intellij.util.lang,
com.intellij.util.messages,
com.intellij.util.messages.impl,
com.intellij.util.pico,
com.intellij.util.text,
com.intellij.util.xmlb,
com.intellij.util.xmlb.annotations,
gnu.trove,
kotlin,
kotlin.collections,
kotlin.comparisons,
kotlin.concurrent,
kotlin.coroutines,
kotlin.coroutines.intrinsics,
kotlin.coroutines.jvm.internal,
kotlin.internal;x-internal:=true,
kotlin.io,
kotlin.jvm,
kotlin.jvm.functions,
kotlin.jvm.internal;x-internal:=true,
kotlin.jvm.internal.unsafe;x-internal:=true,
kotlin.properties,
kotlin.ranges,
kotlin.reflect,
kotlin.reflect.full,
kotlin.reflect.jvm.internal.impl.load.kotlin,
kotlin.script.dependencies,
kotlin.script.experimental.annotations,
kotlin.script.experimental.api,
kotlin.script.experimental.dependencies,
kotlin.script.experimental.host,
kotlin.script.experimental.jvm,
kotlin.script.experimental.util,
kotlin.script.extensions,
kotlin.script.templates,
kotlin.script.templates.standard,
kotlin.sequences,
kotlin.text,
kotlinx.coroutines,
org.jetbrains.annotations,
org.jetbrains.kotlin,
org.jetbrains.kotlin.analyzer,
org.jetbrains.kotlin.analyzer.common,
org.jetbrains.kotlin.asJava,
org.jetbrains.kotlin.asJava.classes,
org.jetbrains.kotlin.asJava.finder,
org.jetbrains.kotlin.backend.common,
org.jetbrains.kotlin.backend.common.bridges,
org.jetbrains.kotlin.backend.common.output,
org.jetbrains.kotlin.builtins,
org.jetbrains.kotlin.builtins.jvm,
org.jetbrains.kotlin.caches.resolve,
org.jetbrains.kotlin.cfg,
org.jetbrains.kotlin.cfg.pseudocode,
org.jetbrains.kotlin.cfg.pseudocode.instructions,
org.jetbrains.kotlin.cfg.pseudocode.instructions.eval,
org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps,
org.jetbrains.kotlin.cfg.pseudocode.instructions.special,
org.jetbrains.kotlin.cfg.pseudocodeTraverser,
org.jetbrains.kotlin.checkers,
org.jetbrains.kotlin.checkers.diagnostics,
org.jetbrains.kotlin.checkers.diagnostics.factories,
org.jetbrains.kotlin.checkers.utils,
org.jetbrains.kotlin.cli.common,
org.jetbrains.kotlin.cli.common.arguments,
org.jetbrains.kotlin.cli.common.messages,
org.jetbrains.kotlin.cli.common.modules,
org.jetbrains.kotlin.cli.js,
org.jetbrains.kotlin.cli.jvm,
org.jetbrains.kotlin.cli.jvm.compiler,
org.jetbrains.kotlin.cli.jvm.index,
org.jetbrains.kotlin.codegen,
org.jetbrains.kotlin.codegen.binding,
org.jetbrains.kotlin.codegen.context,
org.jetbrains.kotlin.codegen.extensions,
org.jetbrains.kotlin.codegen.inline,
org.jetbrains.kotlin.codegen.intrinsics,
org.jetbrains.kotlin.codegen.optimization,
org.jetbrains.kotlin.codegen.optimization.boxing,
org.jetbrains.kotlin.codegen.optimization.common,
org.jetbrains.kotlin.codegen.optimization.transformer,
org.jetbrains.kotlin.codegen.signature,
org.jetbrains.kotlin.codegen.state,
org.jetbrains.kotlin.codegen.when,
org.jetbrains.kotlin.compiler.plugin,
org.jetbrains.kotlin.config,
org.jetbrains.kotlin.container,
org.jetbrains.kotlin.context,
org.jetbrains.kotlin.contracts,
org.jetbrains.kotlin.descriptors,
org.jetbrains.kotlin.descriptors.annotations,
org.jetbrains.kotlin.descriptors.impl,
org.jetbrains.kotlin.descriptors.java,
org.jetbrains.kotlin.diagnostics,
org.jetbrains.kotlin.diagnostics.rendering,
org.jetbrains.kotlin.extensions,
org.jetbrains.kotlin.fileClasses,
org.jetbrains.kotlin.frontend.di,
org.jetbrains.kotlin.frontend.java.di,
org.jetbrains.kotlin.idea,
org.jetbrains.kotlin.idea.codeInsight,
org.jetbrains.kotlin.idea.core.formatter,
org.jetbrains.kotlin.idea.formatter,
org.jetbrains.kotlin.idea.imports,
org.jetbrains.kotlin.idea.kdoc,
org.jetbrains.kotlin.idea.resolve,
org.jetbrains.kotlin.idea.util,
org.jetbrains.kotlin.incremental,
org.jetbrains.kotlin.incremental.components,
org.jetbrains.kotlin.j2k,
org.jetbrains.kotlin.js.resolve.diagnostics,
org.jetbrains.kotlin.kdoc.lexer,
org.jetbrains.kotlin.kdoc.parser,
org.jetbrains.kotlin.kdoc.psi.api,
org.jetbrains.kotlin.kdoc.psi.impl,
org.jetbrains.kotlin.lexer,
org.jetbrains.kotlin.load.java,
org.jetbrains.kotlin.load.java.components,
org.jetbrains.kotlin.load.java.descriptors,
org.jetbrains.kotlin.load.java.lazy,
org.jetbrains.kotlin.load.java.lazy.descriptors,
org.jetbrains.kotlin.load.java.lazy.types,
org.jetbrains.kotlin.load.java.sam,
org.jetbrains.kotlin.load.java.sources,
org.jetbrains.kotlin.load.java.structure,
org.jetbrains.kotlin.load.java.structure.impl,
org.jetbrains.kotlin.load.java.typeEnhancement,
org.jetbrains.kotlin.load.kotlin,
org.jetbrains.kotlin.load.kotlin.header,
org.jetbrains.kotlin.load.kotlin.incremental,
org.jetbrains.kotlin.metadata.jvm.deserialization,
org.jetbrains.kotlin.name,
org.jetbrains.kotlin.parsing,
org.jetbrains.kotlin.platform,
org.jetbrains.kotlin.platform.jvm,
org.jetbrains.kotlin.progress,
org.jetbrains.kotlin.psi,
org.jetbrains.kotlin.psi.addRemoveModifier,
org.jetbrains.kotlin.psi.codeFragmentUtil,
org.jetbrains.kotlin.psi.debugText,
org.jetbrains.kotlin.psi.findDocComment,
org.jetbrains.kotlin.psi.psiUtil,
org.jetbrains.kotlin.psi.stubs,
org.jetbrains.kotlin.psi.stubs.elements,
org.jetbrains.kotlin.psi.stubs.impl,
org.jetbrains.kotlin.psi.typeRefHelpers,
org.jetbrains.kotlin.renderer,
org.jetbrains.kotlin.resolve,
org.jetbrains.kotlin.resolve.annotations,
org.jetbrains.kotlin.resolve.bindingContextUtil,
org.jetbrains.kotlin.resolve.calls,
org.jetbrains.kotlin.resolve.calls.callUtil,
org.jetbrains.kotlin.resolve.calls.checkers,
org.jetbrains.kotlin.resolve.calls.context,
org.jetbrains.kotlin.resolve.calls.inference,
org.jetbrains.kotlin.resolve.calls.inference.constraintPosition,
org.jetbrains.kotlin.resolve.calls.model,
org.jetbrains.kotlin.resolve.calls.results,
org.jetbrains.kotlin.resolve.calls.smartcasts,
org.jetbrains.kotlin.resolve.calls.tasks,
org.jetbrains.kotlin.resolve.calls.util,
org.jetbrains.kotlin.resolve.checkers,
org.jetbrains.kotlin.resolve.constants,
org.jetbrains.kotlin.resolve.constants.evaluate,
org.jetbrains.kotlin.resolve.deprecation,
org.jetbrains.kotlin.resolve.descriptorUtil,
org.jetbrains.kotlin.resolve.diagnostics,
org.jetbrains.kotlin.resolve.extensions,
org.jetbrains.kotlin.resolve.jvm,
org.jetbrains.kotlin.resolve.jvm.diagnostics,
org.jetbrains.kotlin.resolve.jvm.extensions,
org.jetbrains.kotlin.resolve.jvm.jvmSignature,
org.jetbrains.kotlin.resolve.jvm.kotlinSignature,
org.jetbrains.kotlin.resolve.jvm.modules,
org.jetbrains.kotlin.resolve.jvm.platform,
org.jetbrains.kotlin.resolve.lazy,
org.jetbrains.kotlin.resolve.lazy.data,
org.jetbrains.kotlin.resolve.lazy.declarations,
org.jetbrains.kotlin.resolve.lazy.descriptors,
org.jetbrains.kotlin.resolve.sam,
org.jetbrains.kotlin.resolve.scopes,
org.jetbrains.kotlin.resolve.scopes.receivers,
org.jetbrains.kotlin.resolve.scopes.utils,
org.jetbrains.kotlin.resolve.source,
org.jetbrains.kotlin.resolve.typeBinding,
org.jetbrains.kotlin.scripting.configuration,
org.jetbrains.kotlin.scripting.definitions,
org.jetbrains.kotlin.scripting.extensions,
org.jetbrains.kotlin.scripting.resolve,
org.jetbrains.kotlin.serialization,
org.jetbrains.kotlin.serialization.builtins,
org.jetbrains.kotlin.serialization.deserialization,
org.jetbrains.kotlin.serialization.deserialization.builtins,
org.jetbrains.kotlin.serialization.deserialization.descriptors,
org.jetbrains.kotlin.storage,
org.jetbrains.kotlin.synthetic,
org.jetbrains.kotlin.types,
org.jetbrains.kotlin.types.checker,
org.jetbrains.kotlin.types.error,
org.jetbrains.kotlin.types.expressions,
org.jetbrains.kotlin.types.typeUtil,
org.jetbrains.kotlin.types.typesApproximation,
org.jetbrains.kotlin.util,
org.jetbrains.kotlin.util.collectionUtils,
org.jetbrains.kotlin.util.slicedMap,
org.jetbrains.kotlin.utils,
org.jetbrains.kotlin.utils.addToStdlib,
org.jetbrains.kotlin.utils.concurrent.block,
org.jetbrains.kotlin.utils.fileUtils,
org.jetbrains.kotlin.utils.intellij,
org.jetbrains.kotlin.utils.strings,
org.jetbrains.org.objectweb.asm,
org.jetbrains.org.objectweb.asm.commons,
org.jetbrains.org.objectweb.asm.signature,
org.jetbrains.org.objectweb.asm.tree,
org.jetbrains.org.objectweb.asm.tree.analysis,
org.jetbrains.org.objectweb.asm.util
================================================
FILE: kotlin-bundled-compiler/build.gradle.kts
================================================
import com.intellij.buildsupport.dependencies.PackageListFromSimpleFile
import com.intellij.buildsupport.resolve.http.HttpArtifact
import com.intellij.buildsupport.resolve.http.HttpArtifactsResolver
import com.intellij.buildsupport.resolve.http.idea.IntellijIdeaArtifactsResolver
import com.intellij.buildsupport.utils.FileUtils
apply(plugin = "base")
// constants
val teamcityBaseUrl ="https://teamcity.jetbrains.com"
val ideaSdkUrl = "https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea"
// properties that might/should be modifiable
//val kotlinCompilerTcBuildId: String = project.findProperty("kotlinCompilerTcBuildId") as String? ?: "3546752"
val kotlinPluginUpdateId = project.findProperty("kotlinPluginUpdateId") as String? ?: "169248" // Kotlin Plugin 1.6.21 for Idea 2021.3
val kotlinCompilerVersion: String = project.findProperty("kotlinCompilerVersion") as String? ?: "1.6.21"
val kotlinxVersion: String = project.findProperty("kolinxVersion") as String? ?: "1.5.2"
val tcArtifactsPath: String = project.findProperty("tcArtifactsPath") as String? ?: ""
val ideaVersion: String = project.findProperty("ideaVersion") as String? ?: "213.5744.223" //Idea 2021.3
val kotlinIdeaCompatibleVersionMinor: String = project.findProperty("kotlinIdeaCompatibleVersionMinor") as String? ?: "2021.3"
val ignoreSources: Boolean = true//project.hasProperty("ignoreSources")
//directories
val testDataDir = file("${projectDir.parentFile}/kotlin-eclipse-ui-test/common_testData")
//TODO later refactor to the proper project dir
val testModuleLibDir = file("${projectDir.parentFile}/kotlin-eclipse-ui-test/lib")
//TODO later refactor to the proper project dir
val downloadDirName = "downloads$ideaVersion-$kotlinCompilerVersion"
val teamCityWorkingDir = project.findProperty("teamcity.buildsupport.workingDir")
val libDir = if (teamCityWorkingDir != null) file("$teamCityWorkingDir/lib") else file("lib")
val localTCArtifacts: Boolean = tcArtifactsPath.isNotBlank()
val downloadDir = if(localTCArtifacts) file(tcArtifactsPath) else file("$libDir/$downloadDirName")
/*val tcArtifactsResolver = KotlinCompilerTCArtifactsResolver(teamcityBaseUrl,
project.hasProperty("lastSuccessfulBuild"),
kotlinCompilerTcBuildId,
kotlinCompilerVersion,
kotlinIdeaCompatibleVersionMinor)*/
HttpArtifactsResolver.getProxyProps()["https.proxyHost"] = project.findProperty("https.proxyHost") ?: System.getProperty("https.proxyHost")
HttpArtifactsResolver.getProxyProps()["https.proxyPort"] = project.findProperty("https.proxyPort") ?: System.getProperty("https.proxyPort")
HttpArtifactsResolver.getProxyProps()["https.proxyUser"] = project.findProperty("https.proxyUser") ?: System.getProperty("https.proxyUser")
HttpArtifactsResolver.getProxyProps()["https.proxyPassword"] = project.findProperty("https.proxyPassword") ?: System.getProperty("https.proxyPassword")
val ideaArtifactsResolver = IntellijIdeaArtifactsResolver(ideaSdkUrl, ideaVersion)
val kotlinPluginArtifactsResolver = HttpArtifactsResolver("https://plugins.jetbrains.com")
val tempKotlinHttpArtifact = HttpArtifact("plugin/download?rel=true&updateId=$kotlinPluginUpdateId")
tasks.withType {
gradleVersion = "5.5.1"
}
val testFrameworkDependencies by configurations.creating
val kotlinxLibraries by configurations.creating
dependencies {
testFrameworkDependencies("com.google.code.gson:gson:2.3.1")
kotlinxLibraries("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinxVersion") { isTransitive = false }
kotlinxLibraries("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$kotlinxVersion") { isTransitive = false }
}
repositories {
mavenCentral()
}
tasks.named("clean") {
doLast {
FileUtils.cleanDir(testDataDir)
FileUtils.cleanDir(testModuleLibDir)
FileUtils.cleanDirExceptSubDirName(libDir, downloadDirName)
}
}
val deleteLibrariesFromLibFolder by tasks.registering {
doFirst {
libDir.listFiles()?.filter { it.isFile }?.forEach { it.deleteRecursively() }
}
}
val downloadTestData by tasks.registering {
val locallyDownloadedTestDataFile by extra {
if(localTCArtifacts){
file("$tcArtifactsPath/kotlin-test-data.zip")
} else {
file("$testDataDir/kotlin-test-data.zip")
}
}
doLast {
//TODO can we get the test data from somewhere?
if (!localTCArtifacts && !locallyDownloadedTestDataFile.exists()) {
//tcArtifactsResolver.downloadTo(tcArtifactsResolver.KOTLIN_TEST_DATA_ZIP, locallyDownloadedTestDataFile)
}
/*copy {
from(zipTree(locallyDownloadedTestDataFile))
into(testDataDir)
}*/
}
}
val downloadTestFrameworkDependencies by tasks.registering(Copy::class) {
from(testFrameworkDependencies)
into(testModuleLibDir)
}
val downloadKotlinCompilerPluginAndExtractSelectedJars by tasks.registering {
dependsOn(deleteLibrariesFromLibFolder)
val kotlinDownloadDir = file("$downloadDir/kotlin-$kotlinCompilerVersion/$kotlinIdeaCompatibleVersionMinor")
val locallyDownloadedCompilerFile by extra {
file(kotlinDownloadDir).listFiles()?.firstOrNull { it.name.startsWith("kotlin-plugin-") }
?: file("$kotlinDownloadDir/kotlin-plugin.zip")
}
doLast {
if (!localTCArtifacts && !locallyDownloadedCompilerFile.exists()) {
kotlinPluginArtifactsResolver.downloadTo(tempKotlinHttpArtifact, locallyDownloadedCompilerFile)
//tcArtifactsResolver.downloadTo(tcArtifactsResolver.KOTLIN_PLUGIN_ZIP, locallyDownloadedCompilerFile)
}
copy {
from(zipTree(locallyDownloadedCompilerFile))
setIncludes(setOf("Kotlin/lib/kotlin-plugin.jar",
"Kotlin/lib/ide-common.jar",
"Kotlin/lib/kotlin-core.jar",
"Kotlin/lib/kotlin-idea.jar",
"Kotlin/lib/kotlin-common.jar",
"Kotlin/lib/kotlin-j2k-old.jar",
"Kotlin/lib/kotlin-j2k-new.jar",
"Kotlin/lib/kotlin-j2k-idea.jar",
"Kotlin/lib/kotlin-j2k-services.jar",
"Kotlin/lib/kotlin-frontend-independent.jar",
"Kotlin/lib/kotlin-formatter.jar",
"Kotlin/kotlinc/lib/kotlin-compiler.jar",
"Kotlin/kotlinc/lib/kotlin-stdlib.jar",
"Kotlin/kotlinc/lib/kotlin-reflect.jar",
"Kotlin/kotlinc/lib/kotlin-script-runtime.jar",
"Kotlin/kotlinc/lib/kotlin-scripting-compiler.jar",
"Kotlin/kotlinc/lib/kotlin-scripting-common.jar",
"Kotlin/kotlinc/lib/kotlin-scripting-jvm.jar",
"Kotlin/kotlinc/lib/kotlin-scripting-compiler-impl.jar",
"Kotlin/kotlinc/lib/kotlin-jdk-annotations.jar",
"Kotlin/kotlinc/lib/kotlin-stdlib-sources.jar",
"Kotlin/kotlinc/lib/allopen-compiler-plugin.jar",
"Kotlin/kotlinc/lib/noarg-compiler-plugin.jar",
"Kotlin/kotlinc/lib/sam-with-receiver-compiler-plugin.jar",
"Kotlin/kotlinc/lib/annotations-13.0.jar"))
includeEmptyDirs = false
into(libDir)
// flatten + rename
eachFile {
this.relativePath = RelativePath(true, this.name)
}
}
}
}
val extractPackagesFromPlugin by tasks.registering(Jar::class) {
dependsOn(downloadKotlinCompilerPluginAndExtractSelectedJars)
from(zipTree("$libDir/kotlin-plugin.jar"))
destinationDirectory.set(libDir)
archiveFileName.set("kotlin-plugin-parts.jar")
include("**")
exclude("com/intellij/util/**")
doLast {
file("$libDir/kotlin-plugin.jar").delete()
}
}
val extractPackagesFromKTCompiler by tasks.registering(Jar::class) {
dependsOn(downloadKotlinCompilerPluginAndExtractSelectedJars)
from(zipTree("$libDir/kotlin-compiler.jar"))
destinationDirectory.set(libDir)
archiveFileName.set("kotlin-compiler-tmp.jar")
include("**")
exclude("com/intellij/openapi/util/text/**")
exclude("com/intellij/util/containers/MultiMap*")
doLast {
file("$libDir/kotlin-compiler.jar").delete()
file("$libDir/kotlin-compiler-tmp.jar").renameTo(file("$libDir/kotlin-compiler.jar"))
}
}
val downloadIntellijCoreAndExtractSelectedJars by tasks.registering {
dependsOn(deleteLibrariesFromLibFolder)
val ideaDownloadDir = file("$downloadDir/idea-$ideaVersion")
val locallyDownloadedIntellijCoreFile by extra { file("$ideaDownloadDir/intellij-core.zip") }
doLast {
if(!locallyDownloadedIntellijCoreFile.exists()) {
ideaArtifactsResolver.downloadTo(ideaArtifactsResolver.INTELLIJ_CORE_ZIP, locallyDownloadedIntellijCoreFile)
}
copy {
from(zipTree(locallyDownloadedIntellijCoreFile))
setIncludes(setOf("intellij-core.jar"))
includeEmptyDirs = false
into(libDir)
}
}
}
val downloadIdeaDistributionZipAndExtractSelectedJars by tasks.registering {
dependsOn(deleteLibrariesFromLibFolder)
val ideaDownloadDir = file("$downloadDir/idea-$ideaVersion")
val locallyDownloadedIdeaZipFile by extra { file("$ideaDownloadDir/ideaIC.zip") }
val chosenJars by extra { setOf(//"openapi",
//"platform-util-ui",
"util",
"idea",
//"trove4j",
"platform-api",
"platform-impl") }
doLast {
if(!locallyDownloadedIdeaZipFile.exists()) {
ideaArtifactsResolver.downloadTo(ideaArtifactsResolver.IDEA_IC_ZIP, locallyDownloadedIdeaZipFile)
}
copy {
from(zipTree(locallyDownloadedIdeaZipFile))
setIncludes(chosenJars.map { "lib/$it.jar" }.toSet())
includeEmptyDirs = false
into(libDir)
// flatten the files
eachFile {
this.relativePath = RelativePath(true, this.name)
}
}
}
}
val extractSelectedFilesFromIdeaJars by tasks.registering {
dependsOn(downloadIdeaDistributionZipAndExtractSelectedJars)
val packages by extra {
/*new PackageListFromManifest("META-INF/MANIFEST.MF"),*/
PackageListFromSimpleFile(file("referencedPackages.txt").path).pathsToInclude
}
val extractDir by extra { file("$downloadDir/dependencies") }
doLast {
val chosenJars: Set by downloadIdeaDistributionZipAndExtractSelectedJars.get().extra
for (library in chosenJars) {
copy {
from(zipTree("$libDir/$library.jar"))
setIncludes(packages)
includeEmptyDirs = false
into(extractDir)
}
file("$libDir/$library.jar").delete()
}
}
}
val createIdeDependenciesJar by tasks.registering(Jar::class) {
dependsOn(extractSelectedFilesFromIdeaJars)
val extractDir: File by extractSelectedFilesFromIdeaJars.get().extra
from(extractDir)
destinationDirectory.set(libDir)
archiveFileName.set("ide-dependencies.jar")
manifest {
attributes(mapOf("Built-By" to "JetBrains",
"Implementation-Vendor" to "JetBrains",
"Implementation-Version" to "1.0",
"Implementation-Title" to "ide-dependencies"))
}
doLast {
extractDir.deleteRecursively()
}
}
val downloadKotlinxLibraries by tasks.registering(Copy::class) {
from(kotlinxLibraries)
into(libDir)
rename("(kotlinx-coroutines-\\w+)-.*", "$1.jar")
}
val downloadIdeaAndKotlinCompilerSources by tasks.registering {
val locallyDownloadedKotlinCompilerSourcesFile by extra { file("$downloadDir/kotlin-compiler-sources.jar") }
val locallyDownloadedIdeaSourcesFile by extra { file("$downloadDir/idea-sdk-sources.jar") }
doLast {
if(!locallyDownloadedKotlinCompilerSourcesFile.exists()) {
//TODO can we get the sources from somewhere?
//tcArtifactsResolver.downloadTo(tcArtifactsResolver.KOTLIN_COMPILER_SOURCES_JAR, locallyDownloadedKotlinCompilerSourcesFile)
}
if(!locallyDownloadedIdeaSourcesFile.exists()) {
ideaArtifactsResolver.downloadTo(ideaArtifactsResolver.IDEA_IC_SOURCES_JAR, locallyDownloadedIdeaSourcesFile)
}
}
}
val repackageIdeaAndKotlinCompilerSources by tasks.registering(Zip::class) {
dependsOn(downloadIdeaAndKotlinCompilerSources)
val locallyDownloadedKotlinCompilerSourcesFile: File by downloadIdeaAndKotlinCompilerSources.get().extra
val locallyDownloadedIdeaSourcesFile: File by downloadIdeaAndKotlinCompilerSources.get().extra
from(zipTree(locallyDownloadedKotlinCompilerSourcesFile))
from(zipTree(locallyDownloadedIdeaSourcesFile))
destinationDirectory.set(libDir)
archiveFileName.set("kotlin-compiler-sources.jar")
}
val downloadBundled by tasks.registering {
libDir.listFiles()?.filter { it.isFile }?.forEach { it.deleteRecursively() }
if (localTCArtifacts) {
dependsOn(extractPackagesFromPlugin,
extractPackagesFromKTCompiler,
downloadIntellijCoreAndExtractSelectedJars,
createIdeDependenciesJar,
downloadKotlinxLibraries)
} else {
dependsOn(extractPackagesFromPlugin,
extractPackagesFromKTCompiler,
downloadIntellijCoreAndExtractSelectedJars,
createIdeDependenciesJar,
downloadKotlinxLibraries)
}
if (!ignoreSources) {
dependsOn(repackageIdeaAndKotlinCompilerSources)
}
}
val getBundled by tasks.registering {
dependsOn(downloadTestData, downloadTestFrameworkDependencies, downloadBundled)
}
================================================
FILE: kotlin-bundled-compiler/build.properties
================================================
###############################################################################
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
###############################################################################
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
lib/kotlin-compiler.jar,\
lib/kotlin-stdlib.jar,\
lib/kotlin-reflect.jar,\
lib/kotlin-stdlib-sources.jar,\
lib/kotlin-script-runtime.jar,\
lib/allopen-compiler-plugin.jar,\
lib/kotlin-scripting-compiler.jar,\
lib/sam-with-receiver-compiler-plugin.jar,\
lib/noarg-compiler-plugin.jar,\
lib/annotations-13.0.jar,\
lib/kotlinx-coroutines-core.jar,\
lib/kotlinx-coroutines-jdk8.jar,\
lib/ide-dependencies.jar,\
lib/kotlin-scripting-common.jar,\
lib/kotlin-scripting-jvm.jar,\
lib/kotlin-scripting-compiler-impl.jar,\
lib/kotlin-plugin-parts.jar,\
lib/kotlin-formatter.jar,\
lib/kotlin-common.jar,\
lib/kotlin-idea.jar,\
lib/kotlin-core.jar,\
lib/kotlin-j2k-old.jar,\
lib/kotlin-j2k-new.jar,\
lib/kotlin-j2k-idea.jar,\
lib/kotlin-j2k-services.jar,\
lib/kotlin-frontend-independent.jar,\
lib/ide-common.jar
src.includes = lib/
bin.excludes = lib/kotlin-compiler-sources.jar,\
lib/downloads/
src.excludes = lib/downloads/,\
lib/intellij-core.jar
================================================
FILE: kotlin-bundled-compiler/buildSrc/build.gradle
================================================
apply plugin: 'groovy'
repositories {
jcenter()
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'org.jetbrains.teamcity:teamcity-rest-client:1.5.0'
testImplementation('org.spockframework:spock-core:2.2-groovy-3.0') {
exclude module : 'groovy-all'
}
testImplementation 'com.github.stefanbirkner:system-rules:1.19.0'
testImplementation 'org.apache.commons:commons-lang3:3.8.1'
}
test.enabled = false // otherwise integration tests will run always before the actual build
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/dependencies/PackageList.groovy
================================================
package com.intellij.buildsupport.dependencies
abstract class PackageList {
List getPathsToInclude() {
List tempList = []
packageNames.forEach {
if(it.startsWith("custom:")) {
tempList.add(it.replace("custom:", ""))
} else {
tempList.add(it.replace('.', '/') + '/*.class')
}
}
return tempList
}
protected abstract List getPackageNames()
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/dependencies/PackageListFromManifest.groovy
================================================
package com.intellij.buildsupport.dependencies
import groovy.transform.TupleConstructor
import java.util.jar.Manifest
@TupleConstructor
class PackageListFromManifest extends PackageList {
String path
@Override
protected List getPackageNames() {
new Manifest(new FileInputStream(path)).mainAttributes
.getValue("Export-Package")
.split(',')
*.takeWhile { it != ';' } as List
}
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/dependencies/PackageListFromSimpleFile.groovy
================================================
package com.intellij.buildsupport.dependencies
import groovy.transform.TupleConstructor
import java.util.jar.Manifest
@TupleConstructor
class PackageListFromSimpleFile extends PackageList {
String path
@Override
protected List getPackageNames() {
new FileInputStream(path).readLines()
*.trim()
.findAll { !it.empty }
.findAll { it.take(1) != '#' }
}
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/resolve/http/HttpArtifact.groovy
================================================
package com.intellij.buildsupport.resolve.http
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import groovy.transform.TupleConstructor
@TupleConstructor(includeFields = true)
@EqualsAndHashCode
@ToString
class HttpArtifact {
// relative to HTTP base URL
final String filePath // cannot contain any regex patterns
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/resolve/http/HttpArtifactsResolver.groovy
================================================
package com.intellij.buildsupport.resolve.http
import groovy.transform.TupleConstructor
@TupleConstructor(includeFields = true)
class HttpArtifactsResolver {
// FIELDS =========================================================================================================
protected final String httpBaseUrl
static Map proxyProps = new HashMap<>()
// PUBLIC API =====================================================================================================
final void downloadTo(HttpArtifact httpArtifact, File outputFile) {
println "Downloading artifact: $httpArtifact.filePath"
downloadFileFromUrlInto "$httpBaseUrl/$httpArtifact.filePath", outputFile
}
// PRIVATE API ====================================================================================================
private void downloadFileFromUrlInto(String fileURL, File destinationFile) {
destinationFile.parentFile.mkdirs()
def ant = new AntBuilder()
if (!proxyProps.isEmpty() && proxyProps['https.proxyHost'] != null) {
if (proxyProps.get("https.proxyUser") == null) {
ant.setproxy(proxyHost: proxyProps['https.proxyHost'], proxyPort: proxyProps['https.proxyPort'])
} else {
ant.setproxy(proxyHost: proxyProps['https.proxyHost'], proxyPort: proxyProps['https.proxyPort'], proxyUser: proxyProps['https.proxyUser'], proxyPassword: proxyProps['https.proxyPassword'])
}
}
ant.get(src: fileURL,
dest: destinationFile,
usetimestamp: true)
}
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/resolve/http/idea/IntellijIdeaArtifactsResolver.groovy
================================================
package com.intellij.buildsupport.resolve.http.idea
import com.intellij.buildsupport.resolve.http.HttpArtifact
import com.intellij.buildsupport.resolve.http.HttpArtifactsResolver
import groovy.transform.CompileStatic
@CompileStatic
class IntellijIdeaArtifactsResolver extends HttpArtifactsResolver {
final String ideaVersion
IntellijIdeaArtifactsResolver(String httpBaseUrl, String ideaVersion) {
super(httpBaseUrl)
this.ideaVersion = ideaVersion
}
public final HttpArtifact INTELLIJ_CORE_ZIP = new HttpArtifact("intellij-core/$ideaVersion/intellij-core-${ideaVersion}.zip",)
public final HttpArtifact IDEA_IC_ZIP = new HttpArtifact("ideaIC/$ideaVersion/ideaIC-${ideaVersion}.zip",)
public final HttpArtifact IDEA_IC_SOURCES_JAR = new HttpArtifact("ideaIC/$ideaVersion/ideaIC-$ideaVersion-sources.jar",)
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/resolve/tc/TCArtifact.groovy
================================================
package com.intellij.buildsupport.resolve.tc
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
import groovy.transform.TupleConstructor
@TupleConstructor(includeFields = true)
@EqualsAndHashCode
@ToString
class TCArtifact {
// relative to TeamCity base URL
final String fileParentPathRegex // might contain '*' pattern
final String fileNameRegex // might contain '*' pattern
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/resolve/tc/TCArtifactsResolver.groovy
================================================
package com.intellij.buildsupport.resolve.tc
import groovy.transform.CompileStatic
import groovy.transform.TupleConstructor
import org.jetbrains.teamcity.rest.Build
import org.jetbrains.teamcity.rest.BuildArtifact
import org.jetbrains.teamcity.rest.BuildConfigurationId
import org.jetbrains.teamcity.rest.BuildId
import org.jetbrains.teamcity.rest.BuildLocator
import org.jetbrains.teamcity.rest.TeamCityConversationException
import org.jetbrains.teamcity.rest.TeamCityInstanceFactory
import org.jetbrains.teamcity.rest.TeamCityQueryException
@TupleConstructor(includeFields = true, excludes = ['resolvedArtifactMap', 'untilDate'])
@CompileStatic
abstract class TCArtifactsResolver {
// FIELDS =========================================================================================================
protected final String teamcityBaseUrl
protected final boolean lastSuccessfulBuild
protected final String tcBuildId
protected final String tcBuildBranch
// for testing purposes only
protected Date untilDate = null
private Map resolvedArtifactMap = null
// ABSTRACT METHODS TO IMPLEMENT ==================================================================================
abstract List getRequiredArtifacts()
abstract String tcBuildTypeId()
// PUBLIC API =====================================================================================================
final void downloadTo(TCArtifact tcArtifact, File outputFile) {
if (resolvedArtifactMap == null) {
resolvedArtifactMap = lastSuccessfulBuild ? resolveFromLastSuccessfulBuild()
: resolveFromBuildId()
}
BuildArtifact resolvedTCArtifact = resolvedArtifactMap.get(tcArtifact)
println "Downloading artifact: $resolvedTCArtifact.fullName"
resolvedTCArtifact.download(outputFile)
}
// PRIVATE API ====================================================================================================
private Map resolveFromBuildId() {
Build tcBuild = TeamCityInstanceFactory.guestAuth(teamcityBaseUrl)
.build(new BuildId(tcBuildId))
println "Resolving TC build: $tcBuild"
return resolveRequiredArtifacts(tcBuild)
}
private Map resolveFromLastSuccessfulBuild() {
BuildLocator builds = TeamCityInstanceFactory.guestAuth(teamcityBaseUrl)
.builds()
.fromConfiguration(new BuildConfigurationId(tcBuildTypeId()))
.includeFailed()
if (!tcBuildBranch.trim().isEmpty())
builds.withBranch(tcBuildBranch.trim())
if (untilDate != null)
builds.untilDate(untilDate)
for (Build tcBuild in iterable(builds.all())) {
println "Resolving TC build: $tcBuild"
Map resolvedArtifacts = resolveRequiredArtifacts(tcBuild)
if (resolvedArtifacts.isEmpty())
continue
else
return resolvedArtifacts
}
}
private Map resolveRequiredArtifacts(Build tcBuild) {
Map resolvedArtifactMap = [:] as HashMap
for (TCArtifact requiredTcArtifact in getRequiredArtifacts()) {
BuildArtifact resolvedTcArtifact
// search the build and dependencies of the build for the artifact (in case of an aggregate build)
for (build in [tcBuild] + tcBuild.snapshotDependencies) {
try {
resolvedTcArtifact = build.findArtifact(requiredTcArtifact.fileNameRegex,
requiredTcArtifact.fileParentPathRegex,true)
break
}
catch (TeamCityConversationException ignored) {}
catch (TeamCityQueryException ignored) {}
}
// in the case the latest build does not contain any artifacts, we continue searching the previous build
if(resolvedTcArtifact == null)
return Collections.EMPTY_MAP
resolvedArtifactMap.put requiredTcArtifact, resolvedTcArtifact
}
return resolvedArtifactMap
}
private static Iterable iterable(kotlin.sequences.Sequence sequence) {
return sequence.iterator() as Iterable
}
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/resolve/tc/kotlin/CommonIDEArtifactsResolver.groovy
================================================
package com.intellij.buildsupport.resolve.tc.kotlin
import com.intellij.buildsupport.resolve.tc.TCArtifact
import com.intellij.buildsupport.resolve.tc.TCArtifactsResolver
import groovy.transform.CompileStatic
@CompileStatic
class CommonIDEArtifactsResolver extends TCArtifactsResolver {
final String kotlinCompilerVersion
CommonIDEArtifactsResolver(
String teamcityBaseUrl,
boolean lastSuccessfulBuild,
String tcBuildId,
String kotlinCompilerVersion
) {
super(teamcityBaseUrl, lastSuccessfulBuild, tcBuildId, kotlinCompilerVersion)
this.kotlinCompilerVersion = kotlinCompilerVersion
}
public final TCArtifact KOTLIN_FORMATTER_JAR = new TCArtifact('internal', 'kotlin-formatter.jar')
public final TCArtifact KOTLIN_IDE_COMMON_JAR = new TCArtifact('internal', 'kotlin-ide-common.jar')
@Override
List getRequiredArtifacts() {
return [
KOTLIN_IDE_COMMON_JAR,
KOTLIN_FORMATTER_JAR
]
}
@Override
String tcBuildTypeId() {
String kotlinCompilerVersionInBuildId = kotlinCompilerVersion.replace('.', '') // '1.3.0' => '130'
.replace('-', '') // '1.3-M2' => '13M2'
return "Kotlin_${kotlinCompilerVersionInBuildId}_CompilerAllPlugins"
}
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/resolve/tc/kotlin/KotlinCompilerTCArtifactsResolver.groovy
================================================
package com.intellij.buildsupport.resolve.tc.kotlin
import com.intellij.buildsupport.resolve.tc.TCArtifact
import com.intellij.buildsupport.resolve.tc.TCArtifactsResolver
import groovy.transform.CompileStatic
@CompileStatic
class KotlinCompilerTCArtifactsResolver extends TCArtifactsResolver {
final String kotlinIdeaCompatibleVersionMinor
final String kotlinCompilerVersion
KotlinCompilerTCArtifactsResolver(String teamcityBaseUrl, boolean lastSuccessfulBuild, String tcBuildId,
String kotlinCompilerVersion, String kotlinIdeaCompatibleVersionMinor) {
super(teamcityBaseUrl,
lastSuccessfulBuild,
tcBuildId,
kotlinCompilerVersion)
this.kotlinCompilerVersion = kotlinCompilerVersion
this.kotlinIdeaCompatibleVersionMinor = kotlinIdeaCompatibleVersionMinor
}
public final TCArtifact KOTLIN_PLUGIN_ZIP = new TCArtifact('', "kotlin-plugin-*-IJ${kotlinIdeaCompatibleVersionMinor}*.zip")
public final TCArtifact KOTLIN_TEST_DATA_ZIP = new TCArtifact('internal', 'kotlin-test-data.zip')
public final TCArtifact KOTLIN_COMPILER_SOURCES_JAR = new TCArtifact('maven/org/jetbrains/kotlin/kotlin-compiler', 'kotlin-compiler-*-sources.jar')
@Override
List getRequiredArtifacts() {
return [KOTLIN_TEST_DATA_ZIP,
KOTLIN_PLUGIN_ZIP,
KOTLIN_COMPILER_SOURCES_JAR]
}
@Override
String tcBuildTypeId() {
String kotlinCompilerVersionInBuildId = kotlinCompilerVersion.replace('.', '') // '1.3.0' => '130'
.replace('-', '') // '1.3-M2' => '13M2'
return "Kotlin_${kotlinCompilerVersionInBuildId}_Aggregate"
}
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/main/groovy/com/intellij/buildsupport/utils/FileUtils.groovy
================================================
package com.intellij.buildsupport.utils
import groovy.transform.CompileStatic
@CompileStatic
class FileUtils {
private FileUtils() {}
static void cleanDir(File dir) {
dir.deleteDir()
dir.mkdirs()
}
static void cleanDirExceptSubDirName(File dir, String retainSubDirName) {
if (dir.exists()) {
dir.eachFile { File file ->
if (file.isFile())
file.delete()
else if (file.isDirectory()) {
if (file.name != retainSubDirName)
file.deleteDir()
}
}
}
dir.mkdirs()
new File("$dir/$retainSubDirName").mkdirs()
}
}
================================================
FILE: kotlin-bundled-compiler/buildSrc/src/test/groovy/com/intellij/buildsupport/tc/kotlin/KotlinCompilerTCArtifactsResolverSpecification.groovy
================================================
package com.intellij.buildsupport.tc.kotlin
import com.intellij.buildsupport.resolve.tc.TCArtifactsResolver
import com.intellij.buildsupport.resolve.tc.kotlin.KotlinCompilerTCArtifactsResolver
import java.text.SimpleDateFormat
import org.junit.Rule
import org.junit.contrib.java.lang.system.SystemOutRule
import spock.lang.Specification
import spock.lang.Unroll
import static org.apache.commons.lang3.StringUtils.countMatches
class KotlinCompilerTCArtifactsResolverSpecification extends Specification {
private static final String TC_BASE_URL = 'https://teamcity.jetbrains.com'
@Rule
public final SystemOutRule systemOut = new SystemOutRule().enableLog()
@Unroll
def "should resolve TC artifacts by buildId for version #releaseDescribeVersion"() {
setup:
def tcArtifactResolver = tcArtifactResolverWithBuildId(tcBuildId,
kotlinIdeaCompatibleVersionMinor)
def temporaryFile = File.createTempFile("kotlin-compiler-$releaseDescribeVersion", '.tmp')
expect:
tcArtifactResolver.downloadTo tcArtifactResolver.KOTLIN_PLUGIN_ZIP, temporaryFile
assert temporaryFile.exists()
where:
releaseDescribeVersion | tcBuildId | kotlinIdeaCompatibleVersionMinor
'1.2.72-release-68' | '1646860' | '2017.3'
'1.3-M2-eap-105' | '1572593' | '2017.3'
'1.3.0-rc-153' | '1664232' | '2017.3'
}
@Unroll
def "should resolve TC artifacts for latest successful build for version #kotlinCompilerVersion"() {
setup:
def tcArtifactResolver = tcArtifactResolverWithLatestBuildAndKotlinCompilerVersion(kotlinCompilerVersion,
kotlinIdeaCompatibleVersionMinor)
def temporaryFile = File.createTempFile("kotlin-compiler-latest-$kotlinCompilerVersion", '.tmp')
expect:
tcArtifactResolver.downloadTo tcArtifactResolver.KOTLIN_PLUGIN_ZIP, temporaryFile
assert temporaryFile.exists()
where:
kotlinCompilerVersion | kotlinIdeaCompatibleVersionMinor
'1.2.70' | '2017.3'
'1.3-M1' | '2017.3'
'1.3-M2' | '2017.3'
'1.3.0' | '2017.3'
}
@Unroll
def "should resolve TC artifacts for latest successful build without TC artifacts for version #kotlinCompilerVersion"() {
setup:
def tcArtifactResolver = tcArtifactResolverWithLatestBuildAndKotlinCompilerVersion(kotlinCompilerVersion,
kotlinIdeaCompatibleVersionMinor,
untilDate)
def temporaryFile = File.createTempFile("kotlin-compiler-latest-$kotlinCompilerVersion", '.tmp')
expect:
tcArtifactResolver.downloadTo tcArtifactResolver.KOTLIN_PLUGIN_ZIP, temporaryFile
assert temporaryFile.exists()
assert countMatches(systemOut.log, 'Resolving TC build') == expectednumberOfSearchedTcBuilds
where:
untilDate | kotlinCompilerVersion | kotlinIdeaCompatibleVersionMinor || expectednumberOfSearchedTcBuilds
'2018-08-16' | '1.2.60' | '2017.3' || 4
'2018-09-10' | '1.2.70' | '2017.3' || 5
'2018-08-24' | '1.3-M2' | '2017.3' || 4
'2018-10-03' | '1.3.0' | '2017.3' || 11
}
private static TCArtifactsResolver tcArtifactResolverWithBuildId(String tcBuildId,
String kotlinIdeaCompatibleVersionMinor) {
return new KotlinCompilerTCArtifactsResolver(TC_BASE_URL,
false, // not searching for last successful build
tcBuildId,
'', // Kotlin compiler version determined automatically
kotlinIdeaCompatibleVersionMinor)
}
private static TCArtifactsResolver tcArtifactResolverWithLatestBuildAndKotlinCompilerVersion(String kotlinCompilerVersion,
String kotlinIdeaCompatibleVersionMinor) {
return tcArtifactResolverWithLatestBuildAndKotlinCompilerVersion(kotlinCompilerVersion,
kotlinIdeaCompatibleVersionMinor,
null)
}
private static TCArtifactsResolver tcArtifactResolverWithLatestBuildAndKotlinCompilerVersion(String kotlinCompilerVersion,
String kotlinIdeaCompatibleVersionMinor,
String untilDate) {
TCArtifactsResolver tcArtifactsResolver = new KotlinCompilerTCArtifactsResolver(TC_BASE_URL,
true, // searching for last successful build
'', // buildId not used
kotlinCompilerVersion,
kotlinIdeaCompatibleVersionMinor)
if (untilDate != null)
tcArtifactsResolver.untilDate = new SimpleDateFormat("yyyy-MM-dd").parse(untilDate)
return tcArtifactsResolver
}
}
================================================
FILE: kotlin-bundled-compiler/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: kotlin-bundled-compiler/gradlew
================================================
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
================================================
FILE: kotlin-bundled-compiler/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: kotlin-bundled-compiler/pom.xml
================================================
4.0.0
../pom.xml
kotlin.eclipse
kotlin.eclipse.plugin
0.8.24-SNAPSHOT
org.jetbrains.kotlin.bundled-compiler
eclipse-plugin
src
org.jetbrains.kotlin
kotlin-maven-plugin
${kotlin.version}
17
compile
process-sources
compile
org.apache.maven.plugins
maven-compiler-plugin
3.10.1
17
with-gradle
org.codehaus.mojo
exec-maven-plugin
3.0.0
gradle-clean
clean
exec
${project.basedir}/gradlew
clean
gradle-getBundled
validate
exec
${project.basedir}/gradlew
getBundled
================================================
FILE: kotlin-bundled-compiler/referencedPackages.txt
================================================
# List of packages that are referenced from other dependencies and should be included in plugin to avoid classpath issues
com.intellij.psi.codeStyle
com.intellij.psi.formatter
com.intellij.openapi.components
com.intellij.openapi.options
com.intellij.application.options
com.intellij.application.options.codeStyle.properties
com.intellij.formatting
com.intellij.formatting.engine
com.intellij.util.containers
gnu.trove
com.intellij.openapi.util
com.intellij.openapi.util.text
com.intellij.psi.codeStyle.arrangement
com.intellij.configurationStore
com.intellij.openapi.progress
com.intellij.ui
com.intellij.util.text
custom:com/intellij/CodeStyleBundle.class
custom:com/intellij/DynamicBundle.class
custom:com/intellij/AbstractBundle.class
custom:messages/CodeStyleBundle.*
it.unimi.dsi.fastutil.objects
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/codeInsight/CodeInsightBundle.java
================================================
package com.intellij.codeInsight;
public class CodeInsightBundle {
public static String message(String key, Object... params) {
return key;
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/codeInsight/KotlinNullableNotNullManager.kt
================================================
/*******************************************************************************
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package com.intellij.codeInsight
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiModifierListOwner
import org.jetbrains.annotations.Nullable
// Dummy implementation. Will be changed to something more useful, when KE-277 is fixed.
class KotlinNullableNotNullManager(project: Project) : NullableNotNullManager(project) {
private val _nullables = mutableListOf()
private val _notNulls = mutableListOf()
override fun getNullables(): List = _nullables
override fun setInstrumentedNotNulls(names: MutableList) {}
override fun getInstrumentedNotNulls(): List = emptyList()
// override fun isJsr305Default(annotation: PsiAnnotation, placeTargetTypes: Array): NullabilityAnnotationInfo? = null
override fun setNullables(vararg annotations: String) {
_nullables.clear()
_nullables.addAll(annotations)
}
override fun getNotNulls(): List = _notNulls
override fun setDefaultNotNull(defaultNotNull: String) {
}
override fun getDefaultNullable(): String = "Nullable"
override fun getDefaultNotNull(): String {
return "NotNullable"
}
override fun getDefaultNullables(): MutableList {
return mutableListOf(defaultNullable)
}
override fun getDefaultNotNulls(): MutableList {
return mutableListOf(defaultNotNull)
}
override fun getAllDefaultAnnotations(): MutableList {
return (defaultNullables + defaultNotNulls).toMutableList()
}
override fun setNotNulls(vararg annotations: String) {
_notNulls.clear()
_notNulls.addAll(annotations)
}
// For now we get unresolved psi elements and as a result annotations qualified names are short
init {
setNotNulls("NotNull")
setNullables("Nullable")
}
override fun setDefaultNullable(defaultNullable: String) {
}
override fun hasHardcodedContracts(element: PsiElement): Boolean = false
override fun isNotNull(owner: PsiModifierListOwner, checkBases: Boolean): Boolean {
val notNullAnnotations = notNulls.toSet()
return owner.modifierList?.annotations?.any { annotation ->
annotation.qualifiedName in notNullAnnotations
} ?: false
}
@Nullable
override fun getNullityDefault(
container: PsiModifierListOwner,
placeTargetTypes: Array,
context: PsiElement, superPackage: Boolean
): NullabilityAnnotationInfo? {
return null
}
override fun isNullable(owner: PsiModifierListOwner, checkBases: Boolean) = !isNotNull(owner, checkBases)
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/codeInsight/actions/ReformatCodeProcessor.java
================================================
package com.intellij.codeInsight.actions;
public class ReformatCodeProcessor {
public static final String COMMAND_NAME = "dummy";
public static String getCommandName() {
return "Reformat Code";
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/codeInsight/generation/GenerateEqualsHelper.java
================================================
package com.intellij.codeInsight.generation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeParameter;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureUtil;
// Temp workaround for bad j2k classes politics
public class GenerateEqualsHelper {
public static MethodSignature getEqualsSignature(Project project, GlobalSearchScope scope) {
final PsiClassType javaLangObject = PsiType.getJavaLangObject(PsiManager.getInstance(project), scope);
return MethodSignatureUtil.createMethodSignature(
"equals", new PsiType[]{javaLangObject}, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/formatting/KotlinLanguageCodeStyleSettingsProvider.kt
================================================
package com.intellij.formatting
import org.jetbrains.kotlin.idea.KotlinLanguage
import com.intellij.application.options.IndentOptionsEditor
import com.intellij.lang.Language
import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider
import org.jetbrains.kotlin.idea.formatter.KotlinCommonCodeStyleSettings
class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvider() {
override fun getLanguage(): Language = KotlinLanguage.INSTANCE
override fun getCodeSample(settingsType: SettingsType): String = ""
override fun getLanguageName(): String = KotlinLanguage.NAME
override fun customizeSettings(consumer:CodeStyleSettingsCustomizable, settingsType:SettingsType) {
}
override fun getIndentOptionsEditor(): IndentOptionsEditor? = null
override fun getDefaultCommonSettings(): CommonCodeStyleSettings {
val commonCodeStyleSettings = KotlinCommonCodeStyleSettings()
commonCodeStyleSettings.initIndentOptions()
return commonCodeStyleSettings
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/formatting/KotlinSettingsProvider.kt
================================================
package com.intellij.formatting
import com.intellij.lang.Language
import com.intellij.openapi.options.Configurable
import com.intellij.psi.codeStyle.CodeStyleSettings
import com.intellij.psi.codeStyle.CodeStyleSettingsProvider
import com.intellij.psi.codeStyle.CustomCodeStyleSettings
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
class KotlinSettingsProvider : CodeStyleSettingsProvider() {
override fun getConfigurableDisplayName(): String = KotlinLanguage.NAME
override fun getLanguage(): Language = KotlinLanguage.INSTANCE
override fun createCustomSettings(settings: CodeStyleSettings): CustomCodeStyleSettings {
return KotlinCodeStyleSettings(settings).apply {
this.ALLOW_TRAILING_COMMA = true
this.ALLOW_TRAILING_COMMA_ON_CALL_SITE = true
}
}
override fun createSettingsPage(settings: CodeStyleSettings, originalSettings: CodeStyleSettings): Configurable {
throw UnsupportedOperationException()
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/openapi/editor/Editor.java
================================================
package com.intellij.openapi.editor;
public class Editor {
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/openapi/extensions/ExtensionException.kt
================================================
package com.intellij.openapi.extensions
class ExtensionException(val extensionClass: Class<*>) : RuntimeException(extensionClass.getCanonicalName())
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/openapi/fileTypes/StdFileTypes.java
================================================
package com.intellij.openapi.fileTypes;
public class StdFileTypes {
public static final LanguageFileType JAVA = null;
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/openapi/util/text/StringUtil.java
================================================
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.openapi.util.text;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.*;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;
import java.beans.Introspector;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.*;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//TeamCity inherits StringUtil: do not add private constructors!!!
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
public class StringUtil extends StringUtilRt {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.text.StringUtil");
@SuppressWarnings("SpellCheckingInspection") private static final String VOWELS = "aeiouy";
private static final Pattern EOL_SPLIT_KEEP_SEPARATORS = Pattern.compile("(?<=(\r\n|\n))|(?<=\r)(?=[^\n])");
private static final Pattern EOL_SPLIT_PATTERN = Pattern.compile(" *(\r|\n|\r\n)+ *");
private static final Pattern EOL_SPLIT_PATTERN_WITH_EMPTY = Pattern.compile(" *(\r|\n|\r\n) *");
private static final Pattern EOL_SPLIT_DONT_TRIM_PATTERN = Pattern.compile("(\r|\n|\r\n)+");
@NotNull
public static MergingCharSequence replaceSubSequence(@NotNull CharSequence charSeq, int start, int end, @NotNull CharSequence replacement) {
return new MergingCharSequence(
new MergingCharSequence(charSeq.subSequence(0, start), replacement),
charSeq.subSequence(end, charSeq.length()));
}
@Contract(value = "null -> null; !null->!null", pure = true)
public static String internEmptyString(String s) {
return s == null ? null : (s.isEmpty() ? "" : s);
}
private static class MyHtml2Text extends HTMLEditorKit.ParserCallback {
@NotNull private final StringBuilder myBuffer = new StringBuilder();
private final boolean myIsSkipStyleTag;
private boolean myIsStyleTagOpened;
private MyHtml2Text(boolean isSkipStyleTag) {
myIsSkipStyleTag = isSkipStyleTag;
}
public void parse(@NotNull Reader in) throws IOException {
myBuffer.setLength(0);
new ParserDelegator().parse(in, this, Boolean.TRUE);
}
@Override
public void handleText(@NotNull char[] text, int pos) {
if (!myIsStyleTagOpened) {
myBuffer.append(text);
}
}
@Override
public void handleStartTag(@NotNull HTML.Tag tag, MutableAttributeSet set, int i) {
if (myIsSkipStyleTag && "style".equals(tag.toString())) {
myIsStyleTagOpened = true;
}
handleTag(tag);
}
@Override
public void handleEndTag(@NotNull HTML.Tag tag, int pos) {
if (myIsSkipStyleTag && "style".equals(tag.toString())) {
myIsStyleTagOpened = false;
}
}
@Override
public void handleSimpleTag(HTML.Tag tag, MutableAttributeSet set, int i) {
handleTag(tag);
}
private void handleTag(@NotNull HTML.Tag tag) {
if (tag.breaksFlow() && myBuffer.length() > 0) {
myBuffer.append(SystemProperties.getLineSeparator());
}
}
@NotNull
public String getText() {
return myBuffer.toString();
}
}
private static final MyHtml2Text html2TextParser = new MyHtml2Text(false);
public static final NotNullFunction QUOTER = new NotNullFunction() {
@Override
@NotNull
public String fun(String s) {
return "\"" + s + "\"";
}
};
public static final NotNullFunction SINGLE_QUOTER = new NotNullFunction() {
@Override
@NotNull
public String fun(String s) {
return "'" + s + "'";
}
};
@NotNull
@Contract(pure = true)
public static List getWordsInStringLongestFirst(@NotNull String find) {
List words = getWordsIn(find);
// hope long words are rare
Collections.sort(words, new Comparator() {
@Override
public int compare(@NotNull final String o1, @NotNull final String o2) {
return o2.length() - o1.length();
}
});
return words;
}
@NotNull
@Contract(pure = true)
public static String escapePattern(@NotNull final String text) {
return replace(replace(text, "'", "''"), "{", "'{'");
}
@NotNull
@Contract(pure = true)
public static Function createToStringFunction(@SuppressWarnings("unused") @NotNull Class cls) {
return new Function() {
@Override
public String fun(@NotNull T o) {
return o.toString();
}
};
}
@NotNull
public static final Function TRIMMER = new Function() {
@Nullable
@Override
public String fun(@Nullable String s) {
return trim(s);
}
};
// Unlike String.replace(CharSequence,CharSequence) does not allocate intermediate objects on non-match
// TODO revise when JDK9 arrives - its String.replace(CharSequence, CharSequence) is more optimized
@NotNull
@Contract(pure = true)
public static String replace(@NotNull String text, @NotNull String oldS, @NotNull String newS) {
return replace(text, oldS, newS, false);
}
@NotNull
@Contract(pure = true)
public static String replaceIgnoreCase(@NotNull String text, @NotNull String oldS, @NotNull String newS) {
return replace(text, oldS, newS, true);
}
/**
* @deprecated Use {@link String#replace(char,char)} instead
*/
@NotNull
@Contract(pure = true)
@Deprecated
public static String replaceChar(@NotNull String buffer, char oldChar, char newChar) {
return buffer.replace(oldChar, newChar);
}
@Contract(pure = true)
public static String replace(@NotNull final String text, @NotNull final String oldS, @NotNull final String newS, final boolean ignoreCase) {
if (text.length() < oldS.length()) return text;
StringBuilder newText = null;
int i = 0;
while (i < text.length()) {
final int index = ignoreCase? indexOfIgnoreCase(text, oldS, i) : text.indexOf(oldS, i);
if (index < 0) {
if (i == 0) {
return text;
}
newText.append(text, i, text.length());
break;
}
else {
if (newText == null) {
if (text.length() == oldS.length()) {
return newS;
}
newText = new StringBuilder(text.length() - i);
}
newText.append(text, i, index);
newText.append(newS);
i = index + oldS.length();
}
}
return newText != null ? newText.toString() : "";
}
@Contract(pure = true)
public static int indexOfIgnoreCase(@NotNull String where, @NotNull String what, int fromIndex) {
return indexOfIgnoreCase((CharSequence)where, what, fromIndex);
}
/**
* Implementation copied from {@link String#indexOf(String, int)} except character comparisons made case insensitive
*/
@Contract(pure = true)
public static int indexOfIgnoreCase(@NotNull CharSequence where, @NotNull CharSequence what, int fromIndex) {
int targetCount = what.length();
int sourceCount = where.length();
if (fromIndex >= sourceCount) {
return targetCount == 0 ? sourceCount : -1;
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}
char first = what.charAt(0);
int max = sourceCount - targetCount;
for (int i = fromIndex; i <= max; i++) {
/* Look for first character. */
if (!charsEqualIgnoreCase(where.charAt(i), first)) {
//noinspection StatementWithEmptyBody,AssignmentToForLoopParameter
while (++i <= max && !charsEqualIgnoreCase(where.charAt(i), first)) ;
}
/* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
//noinspection StatementWithEmptyBody
for (int k = 1; j < end && charsEqualIgnoreCase(where.charAt(j), what.charAt(k)); j++, k++) ;
if (j == end) {
/* Found whole string. */
return i;
}
}
}
return -1;
}
@Contract(pure = true)
public static int indexOfIgnoreCase(@NotNull String where, char what, int fromIndex) {
int sourceCount = where.length();
for (int i = Math.max(fromIndex, 0); i < sourceCount; i++) {
if (charsEqualIgnoreCase(where.charAt(i), what)) {
return i;
}
}
return -1;
}
@Contract(pure = true)
public static int lastIndexOfIgnoreCase(@NotNull String where, char what, int fromIndex) {
for (int i = Math.min(fromIndex, where.length() - 1); i >= 0; i--) {
if (charsEqualIgnoreCase(where.charAt(i), what)) {
return i;
}
}
return -1;
}
@Contract(pure = true)
public static boolean containsIgnoreCase(@NotNull String where, @NotNull String what) {
return indexOfIgnoreCase(where, what, 0) >= 0;
}
@Contract(pure = true)
public static boolean endsWithIgnoreCase(@NotNull String str, @NotNull String suffix) {
return StringUtilRt.endsWithIgnoreCase(str, suffix);
}
@Contract(pure = true)
public static boolean startsWithIgnoreCase(@NotNull String str, @NotNull String prefix) {
return StringUtilRt.startsWithIgnoreCase(str, prefix);
}
@Contract(pure = true)
@NotNull
public static String stripHtml(@NotNull String html, boolean convertBreaks) {
if (convertBreaks) {
html = html.replaceAll("
", "\n\n");
}
return html.replaceAll("<(.|\n)*?>", "");
}
@Contract(value = "null -> null; !null -> !null", pure = true)
public static String toLowerCase(@Nullable final String str) {
return str == null ? null : str.toLowerCase();
}
@NotNull
@Contract(pure = true)
public static String getPackageName(@NotNull String fqName) {
return getPackageName(fqName, '.');
}
/**
* Given a fqName returns the package name for the type or the containing type.
*
*
* - {@code java.lang.String} -> {@code java.lang}
* - {@code java.util.Map.Entry} -> {@code java.util.Map}
*
*
* @param fqName a fully qualified type name. Not supposed to contain any type arguments
* @param separator the separator to use. Typically '.'
* @return the package name of the type or the declarator of the type. The empty string if the given fqName is unqualified
*/
@NotNull
@Contract(pure = true)
public static String getPackageName(@NotNull String fqName, char separator) {
int lastPointIdx = fqName.lastIndexOf(separator);
if (lastPointIdx >= 0) {
return fqName.substring(0, lastPointIdx);
}
return "";
}
@Contract(pure = true)
public static int getLineBreakCount(@NotNull CharSequence text) {
int count = 0;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c == '\n') {
count++;
}
else if (c == '\r') {
if (i + 1 < text.length() && text.charAt(i + 1) == '\n') {
//noinspection AssignmentToForLoopParameter
i++;
}
count++;
}
}
return count;
}
@Contract(pure = true)
public static boolean containsLineBreak(@NotNull CharSequence text) {
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (isLineBreak(c)) return true;
}
return false;
}
@Contract(pure = true)
public static boolean isLineBreak(char c) {
return c == '\n' || c == '\r';
}
@NotNull
@Contract(pure = true)
public static String escapeLineBreak(@NotNull String text) {
StringBuilder buffer = new StringBuilder(text.length());
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
switch (c) {
case '\n':
buffer.append("\\n");
break;
case '\r':
buffer.append("\\r");
break;
default:
buffer.append(c);
}
}
return buffer.toString();
}
@Contract(pure = true)
public static boolean endsWithLineBreak(@NotNull CharSequence text) {
int len = text.length();
return len > 0 && isLineBreak(text.charAt(len - 1));
}
@Contract(pure = true)
public static int lineColToOffset(@NotNull CharSequence text, int line, int col) {
int curLine = 0;
int offset = 0;
while (line != curLine) {
if (offset == text.length()) return -1;
char c = text.charAt(offset);
if (c == '\n') {
curLine++;
}
else if (c == '\r') {
curLine++;
if (offset < text.length() - 1 && text.charAt(offset + 1) == '\n') {
offset++;
}
}
offset++;
}
return offset + col;
}
@Contract(pure = true)
public static int offsetToLineNumber(@NotNull CharSequence text, int offset) {
LineColumn lineColumn = offsetToLineColumn(text, offset);
return lineColumn != null ? lineColumn.line : -1;
}
@Contract(pure = true)
public static LineColumn offsetToLineColumn(@NotNull CharSequence text, int offset) {
int curLine = 0;
int curLineStart = 0;
int curOffset = 0;
while (curOffset < offset) {
if (curOffset == text.length()) return null;
char c = text.charAt(curOffset);
if (c == '\n') {
curLine++;
curLineStart = curOffset + 1;
}
else if (c == '\r') {
curLine++;
if (curOffset < text.length() - 1 && text.charAt(curOffset + 1) == '\n') {
curOffset++;
}
curLineStart = curOffset + 1;
}
curOffset++;
}
return LineColumn.of(curLine, offset - curLineStart);
}
/**
* Classic dynamic programming algorithm for string differences.
*/
@Contract(pure = true)
public static int difference(@NotNull String s1, @NotNull String s2) {
int[][] a = new int[s1.length()][s2.length()];
for (int i = 0; i < s1.length(); i++) {
a[i][0] = i;
}
for (int j = 0; j < s2.length(); j++) {
a[0][j] = j;
}
for (int i = 1; i < s1.length(); i++) {
for (int j = 1; j < s2.length(); j++) {
a[i][j] = Math.min(Math.min(a[i - 1][j - 1] + (s1.charAt(i) == s2.charAt(j) ? 0 : 1), a[i - 1][j] + 1), a[i][j - 1] + 1);
}
}
return a[s1.length() - 1][s2.length() - 1];
}
@NotNull
@Contract(pure = true)
public static String wordsToBeginFromUpperCase(@NotNull String s) {
return fixCapitalization(s, ourPrepositions, true);
}
@NotNull
@Contract(pure = true)
public static String wordsToBeginFromLowerCase(@NotNull String s) {
return fixCapitalization(s, ourPrepositions, false);
}
@NotNull
@Contract(pure = true)
public static String toTitleCase(@NotNull String s) {
return fixCapitalization(s, ArrayUtil.EMPTY_STRING_ARRAY, true);
}
@NotNull
private static String fixCapitalization(@NotNull String s, @NotNull String[] prepositions, boolean title) {
StringBuilder buffer = null;
for (int i = 0; i < s.length(); i++) {
char prevChar = i == 0 ? ' ' : s.charAt(i - 1);
char currChar = s.charAt(i);
if (!Character.isLetterOrDigit(prevChar) && prevChar != '\'') {
if (Character.isLetterOrDigit(currChar)) {
if (title || Character.isUpperCase(currChar)) {
int j = i;
for (; j < s.length(); j++) {
if (!Character.isLetterOrDigit(s.charAt(j))) {
break;
}
}
if (!title && j > i + 1 && !Character.isLowerCase(s.charAt(i + 1))) {
// filter out abbreviations like I18n, SQL and CSS
continue;
}
if (!isPreposition(s, i, j - 1, prepositions)) {
if (buffer == null) {
buffer = new StringBuilder(s);
}
buffer.setCharAt(i, title ? toUpperCase(currChar) : toLowerCase(currChar));
}
}
}
}
}
return buffer == null ? s : buffer.toString();
}
private static final String[] ourPrepositions = {
"a", "an", "and", "as", "at", "but", "by", "down", "for", "from", "if", "in", "into", "not", "of", "on", "onto", "or", "out", "over",
"per", "nor", "the", "to", "up", "upon", "via", "with"
};
@Contract(pure = true)
public static boolean isPreposition(@NotNull String s, int firstChar, int lastChar) {
return isPreposition(s, firstChar, lastChar, ourPrepositions);
}
@Contract(pure = true)
public static boolean isPreposition(@NotNull String s, int firstChar, int lastChar, @NotNull String[] prepositions) {
for (String preposition : prepositions) {
boolean found = false;
if (lastChar - firstChar + 1 == preposition.length()) {
found = true;
for (int j = 0; j < preposition.length(); j++) {
if (toLowerCase(s.charAt(firstChar + j)) != preposition.charAt(j)) {
found = false;
}
}
}
if (found) {
return true;
}
}
return false;
}
@NotNull
@Contract(pure = true)
public static NotNullFunction escaper(final boolean escapeSlash, @Nullable final String additionalChars) {
return new NotNullFunction() {
@NotNull
@Override
public String fun(@NotNull String dom) {
final StringBuilder builder = new StringBuilder(dom.length());
escapeStringCharacters(dom.length(), dom, additionalChars, escapeSlash, builder);
return builder.toString();
}
};
}
public static void escapeStringCharacters(int length, @NotNull String str, @NotNull StringBuilder buffer) {
escapeStringCharacters(length, str, "\"", buffer);
}
@NotNull
public static StringBuilder escapeStringCharacters(int length,
@NotNull String str,
@Nullable String additionalChars,
@NotNull StringBuilder buffer) {
return escapeStringCharacters(length, str, additionalChars, true, buffer);
}
@NotNull
public static StringBuilder escapeStringCharacters(int length,
@NotNull String str,
@Nullable String additionalChars,
boolean escapeSlash,
@NotNull StringBuilder buffer) {
return escapeStringCharacters(length, str, additionalChars, escapeSlash, true, buffer);
}
@NotNull
public static StringBuilder escapeStringCharacters(int length,
@NotNull String str,
@Nullable String additionalChars,
boolean escapeSlash,
boolean escapeUnicode,
@NotNull StringBuilder buffer) {
char prev = 0;
for (int idx = 0; idx < length; idx++) {
char ch = str.charAt(idx);
switch (ch) {
case '\b':
buffer.append("\\b");
break;
case '\t':
buffer.append("\\t");
break;
case '\n':
buffer.append("\\n");
break;
case '\f':
buffer.append("\\f");
break;
case '\r':
buffer.append("\\r");
break;
default:
if (escapeSlash && ch == '\\') {
buffer.append("\\\\");
}
else if (additionalChars != null && additionalChars.indexOf(ch) > -1 && (escapeSlash || prev != '\\')) {
buffer.append("\\").append(ch);
}
else if (escapeUnicode && !isPrintableUnicode(ch)) {
CharSequence hexCode = toUpperCase(Integer.toHexString(ch));
buffer.append("\\u");
int paddingCount = 4 - hexCode.length();
while (paddingCount-- > 0) {
buffer.append(0);
}
buffer.append(hexCode);
}
else {
buffer.append(ch);
}
}
prev = ch;
}
return buffer;
}
@Contract(pure = true)
public static boolean isPrintableUnicode(char c) {
int t = Character.getType(c);
return t != Character.UNASSIGNED && t != Character.LINE_SEPARATOR && t != Character.PARAGRAPH_SEPARATOR &&
t != Character.CONTROL && t != Character.FORMAT && t != Character.PRIVATE_USE && t != Character.SURROGATE;
}
@NotNull
@Contract(pure = true)
public static String escapeStringCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder(s.length());
escapeStringCharacters(s.length(), s, "\"", buffer);
return buffer.toString();
}
@NotNull
@Contract(pure = true)
public static String escapeCharCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder(s.length());
escapeStringCharacters(s.length(), s, "\'", buffer);
return buffer.toString();
}
@NotNull
@Contract(pure = true)
public static String unescapeStringCharacters(@NotNull String s) {
StringBuilder buffer = new StringBuilder(s.length());
unescapeStringCharacters(s.length(), s, buffer);
return buffer.toString();
}
private static boolean isQuoteAt(@NotNull String s, int ind) {
char ch = s.charAt(ind);
return ch == '\'' || ch == '\"';
}
@Contract(pure = true)
public static boolean isQuotedString(@NotNull String s) {
return StringUtilRt.isQuotedString(s);
}
@NotNull
@Contract(pure = true)
public static String unquoteString(@NotNull String s) {
return StringUtilRt.unquoteString(s);
}
private static void unescapeStringCharacters(int length, @NotNull String s, @NotNull StringBuilder buffer) {
boolean escaped = false;
for (int idx = 0; idx < length; idx++) {
char ch = s.charAt(idx);
if (!escaped) {
if (ch == '\\') {
escaped = true;
}
else {
buffer.append(ch);
}
}
else {
int octalEscapeMaxLength = 2;
switch (ch) {
case 'n':
buffer.append('\n');
break;
case 'r':
buffer.append('\r');
break;
case 'b':
buffer.append('\b');
break;
case 't':
buffer.append('\t');
break;
case 'f':
buffer.append('\f');
break;
case '\'':
buffer.append('\'');
break;
case '\"':
buffer.append('\"');
break;
case '\\':
buffer.append('\\');
break;
case 'u':
if (idx + 4 < length) {
try {
int code = Integer.parseInt(s.substring(idx + 1, idx + 5), 16);
//noinspection AssignmentToForLoopParameter
idx += 4;
buffer.append((char)code);
}
catch (NumberFormatException e) {
buffer.append("\\u");
}
}
else {
buffer.append("\\u");
}
break;
case '0':
case '1':
case '2':
case '3':
octalEscapeMaxLength = 3;
//noinspection fallthrough
case '4':
case '5':
case '6':
case '7':
int escapeEnd = idx + 1;
while (escapeEnd < length && escapeEnd < idx + octalEscapeMaxLength && isOctalDigit(s.charAt(escapeEnd))) escapeEnd++;
try {
buffer.append((char)Integer.parseInt(s.substring(idx, escapeEnd), 8));
}
catch (NumberFormatException e) {
throw new RuntimeException("Couldn't parse " + s.substring(idx, escapeEnd), e); // shouldn't happen
}
//noinspection AssignmentToForLoopParameter
idx = escapeEnd - 1;
break;
default:
buffer.append(ch);
break;
}
escaped = false;
}
}
if (escaped) buffer.append('\\');
}
// @NotNull
// @Contract(pure = true)
// public static String pluralize(@NotNull String word) {
// String plural = Pluralizer.PLURALIZER.plural(word);
// if (plural != null) return plural;
// if (word.endsWith("s")) return Pluralizer.restoreCase(word, word + "es");
// return Pluralizer.restoreCase(word, word + "s");
// }
@NotNull
@Contract(pure = true)
public static String capitalizeWords(@NotNull String text,
boolean allWords) {
return capitalizeWords(text, " \t\n\r\f", allWords, false);
}
@NotNull
@Contract(pure = true)
public static String capitalizeWords(@NotNull String text,
@NotNull String tokenizerDelim,
boolean allWords,
boolean leaveOriginalDelims) {
final StringTokenizer tokenizer = new StringTokenizer(text, tokenizerDelim, leaveOriginalDelims);
final StringBuilder out = new StringBuilder(text.length());
boolean toCapitalize = true;
while (tokenizer.hasMoreTokens()) {
final String word = tokenizer.nextToken();
if (!leaveOriginalDelims && out.length() > 0) {
out.append(' ');
}
out.append(toCapitalize ? capitalize(word) : word);
if (!allWords) {
toCapitalize = false;
}
}
return out.toString();
}
@NotNull
@Contract(pure = true)
public static String decapitalize(@NotNull String s) {
return Introspector.decapitalize(s);
}
@Contract(pure = true)
public static boolean isVowel(char c) {
return VOWELS.indexOf(c) >= 0;
}
/**
* Capitalize the first letter of the sentence.
*/
@NotNull
@Contract(pure = true)
public static String capitalize(@NotNull String s) {
if (s.isEmpty()) return s;
if (s.length() == 1) return toUpperCase(s).toString();
// Optimization
if (Character.isUpperCase(s.charAt(0))) return s;
return toUpperCase(s.charAt(0)) + s.substring(1);
}
@Contract(value = "null -> false", pure = true)
public static boolean isCapitalized(@Nullable String s) {
return s != null && !s.isEmpty() && Character.isUpperCase(s.charAt(0));
}
@NotNull
@Contract(pure = true)
public static String capitalizeWithJavaBeanConvention(@NotNull String s) {
if (s.length() > 1 && Character.isUpperCase(s.charAt(1))) {
return s;
}
return capitalize(s);
}
@Contract(pure = true)
public static int stringHashCode(@NotNull CharSequence chars) {
if (chars instanceof String || chars instanceof CharSequenceWithStringHash) {
// we know for sure these classes have conformant (and maybe faster) hashCode()
return chars.hashCode();
}
return stringHashCode(chars, 0, chars.length());
}
@Contract(pure = true)
public static int stringHashCode(@NotNull CharSequence chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
h = 31 * h + chars.charAt(off);
}
return h;
}
@Contract(pure = true)
public static int stringHashCode(char[] chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
h = 31 * h + chars[off];
}
return h;
}
@Contract(pure = true)
public static int stringHashCodeInsensitive(@NotNull char[] chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
h = 31 * h + toLowerCase(chars[off]);
}
return h;
}
@Contract(pure = true)
public static int stringHashCodeInsensitive(@NotNull CharSequence chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
h = 31 * h + toLowerCase(chars.charAt(off));
}
return h;
}
@Contract(pure = true)
public static int stringHashCodeInsensitive(@NotNull CharSequence chars) {
return stringHashCodeInsensitive(chars, 0, chars.length());
}
@Contract(pure = true)
public static int stringHashCodeIgnoreWhitespaces(@NotNull char[] chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
char c = chars[off];
if (!isWhiteSpace(c)) {
h = 31 * h + c;
}
}
return h;
}
@Contract(pure = true)
public static int stringHashCodeIgnoreWhitespaces(@NotNull CharSequence chars, int from, int to) {
int h = 0;
for (int off = from; off < to; off++) {
char c = chars.charAt(off);
if (!isWhiteSpace(c)) {
h = 31 * h + c;
}
}
return h;
}
@Contract(pure = true)
public static int stringHashCodeIgnoreWhitespaces(@NotNull CharSequence chars) {
return stringHashCodeIgnoreWhitespaces(chars, 0, chars.length());
}
/**
* Equivalent to string.startsWith(prefixes[0] + prefixes[1] + ...) but avoids creating an object for concatenation.
*/
@Contract(pure = true)
public static boolean startsWithConcatenation(@NotNull String string, @NotNull String... prefixes) {
int offset = 0;
for (String prefix : prefixes) {
int prefixLen = prefix.length();
if (!string.regionMatches(offset, prefix, 0, prefixLen)) {
return false;
}
offset += prefixLen;
}
return true;
}
@Contract(value = "null -> null; !null -> !null", pure = true)
public static String trim(@Nullable String s) {
return s == null ? null : s.trim();
}
@NotNull
@Contract(pure = true)
public static String trimEnd(@NotNull String s, @NotNull String suffix) {
return trimEnd(s, suffix, false);
}
@NotNull
@Contract(pure = true)
public static String trimEnd(@NotNull String s, @NotNull String suffix, boolean ignoreCase) {
boolean endsWith = ignoreCase ? endsWithIgnoreCase(s, suffix) : s.endsWith(suffix);
if (endsWith) {
return s.substring(0, s.length() - suffix.length());
}
return s;
}
@NotNull
@Contract(pure = true)
public static String trimEnd(@NotNull String s, char suffix) {
if (endsWithChar(s, suffix)) {
return s.substring(0, s.length() - 1);
}
return s;
}
@NotNull
@Contract(pure = true)
public static String trimLog(@NotNull final String text, final int limit) {
if (limit > 5 && text.length() > limit) {
return text.substring(0, limit - 5) + " ...\n";
}
return text;
}
@NotNull
@Contract(pure = true)
public static String trimLeading(@NotNull String string) {
return trimLeading((CharSequence)string).toString();
}
@NotNull
@Contract(pure = true)
public static CharSequence trimLeading(@NotNull CharSequence string) {
int index = 0;
while (index < string.length() && Character.isWhitespace(string.charAt(index))) index++;
return string.subSequence(index, string.length());
}
@NotNull
@Contract(pure = true)
public static String trimLeading(@NotNull String string, char symbol) {
int index = 0;
while (index < string.length() && string.charAt(index) == symbol) index++;
return string.substring(index);
}
@NotNull
public static StringBuilder trimLeading(@NotNull StringBuilder builder, char symbol) {
int index = 0;
while (index < builder.length() && builder.charAt(index) == symbol) index++;
if (index > 0) builder.delete(0, index);
return builder;
}
@NotNull
@Contract(pure = true)
public static String trimTrailing(@NotNull String string) {
return trimTrailing((CharSequence)string).toString();
}
@NotNull
@Contract(pure = true)
public static CharSequence trimTrailing(@NotNull CharSequence string) {
int index = string.length() - 1;
while (index >= 0 && Character.isWhitespace(string.charAt(index))) index--;
return string.subSequence(0, index + 1);
}
@NotNull
@Contract(pure = true)
public static String trimTrailing(@NotNull String string, char symbol) {
int index = string.length() - 1;
while (index >= 0 && string.charAt(index) == symbol) index--;
return string.substring(0, index + 1);
}
@NotNull
public static StringBuilder trimTrailing(@NotNull StringBuilder builder, char symbol) {
int index = builder.length() - 1;
while (index >= 0 && builder.charAt(index) == symbol) index--;
builder.setLength(index + 1);
return builder;
}
@Contract(pure = true)
public static boolean startsWithChar(@Nullable CharSequence s, char prefix) {
return s != null && s.length() != 0 && s.charAt(0) == prefix;
}
@Contract(pure = true)
public static boolean endsWithChar(@Nullable CharSequence s, char suffix) {
return StringUtilRt.endsWithChar(s, suffix);
}
@NotNull
@Contract(pure = true)
public static String trimStart(@NotNull String s, @NotNull String prefix) {
if (s.startsWith(prefix)) {
return s.substring(prefix.length());
}
return s;
}
@NotNull
@Contract(pure = true)
public static String trimExtensions(@NotNull String name) {
int index = name.indexOf('.');
return index < 0 ? name : name.substring(0, index);
}
// @NotNull
// @Contract(pure = true)
// public static String pluralize(@NotNull String base, int count) {
// if (count == 1) return base;
// return pluralize(base);
// }
public static void repeatSymbol(@NotNull Appendable buffer, char symbol, int times) {
assert times >= 0 : times;
try {
for (int i = 0; i < times; i++) {
buffer.append(symbol);
}
}
catch (IOException e) {
LOG.error(e);
}
}
@Contract(pure = true)
public static String defaultIfEmpty(@Nullable String value, String defaultValue) {
return isEmpty(value) ? defaultValue : value;
}
@Contract(value = "null -> false", pure = true)
public static boolean isNotEmpty(@Nullable String s) {
return !isEmpty(s);
}
@Contract(value = "null -> true", pure = true)
public static boolean isEmpty(@Nullable String s) {
return s == null || s.isEmpty();
}
@Contract(value = "null -> true",pure = true)
public static boolean isEmpty(@Nullable CharSequence cs) {
return StringUtilRt.isEmpty(cs);
}
@Contract(pure = true)
public static int length(@Nullable CharSequence cs) {
return cs == null ? 0 : cs.length();
}
@NotNull
@Contract(pure = true)
public static String notNullize(@Nullable String s) {
return StringUtilRt.notNullize(s);
}
@NotNull
@Contract(pure = true)
public static String notNullize(@Nullable String s, @NotNull String defaultValue) {
return StringUtilRt.notNullize(s, defaultValue);
}
@Nullable
@Contract(pure = true)
public static String nullize(@Nullable String s) {
return nullize(s, false);
}
@Nullable
@Contract(pure = true)
public static String nullize(@Nullable String s, boolean nullizeSpaces) {
boolean empty = nullizeSpaces ? isEmptyOrSpaces(s) : isEmpty(s);
return empty ? null : s;
}
@Contract(value = "null -> true",pure = true)
// we need to keep this method to preserve backward compatibility
public static boolean isEmptyOrSpaces(@Nullable String s) {
return isEmptyOrSpaces((CharSequence)s);
}
@Contract(value = "null -> true", pure = true)
public static boolean isEmptyOrSpaces(@Nullable CharSequence s) {
return StringUtilRt.isEmptyOrSpaces(s);
}
/**
* Allows to answer if given symbol is white space, tabulation or line feed.
*
* @param c symbol to check
* @return {@code true} if given symbol is white space, tabulation or line feed; {@code false} otherwise
*/
@Contract(pure = true)
public static boolean isWhiteSpace(char c) {
return c == '\n' || c == '\t' || c == ' ';
}
@NotNull
@Contract(pure = true)
public static String getThrowableText(@NotNull Throwable aThrowable) {
return ExceptionUtil.getThrowableText(aThrowable);
}
@NotNull
@Contract(pure = true)
public static String repeatSymbol(final char aChar, final int count) {
char[] buffer = new char[count];
Arrays.fill(buffer, aChar);
return StringFactory.createShared(buffer);
}
@NotNull
@Contract(pure = true)
public static String repeat(@NotNull String s, int count) {
assert count >= 0 : count;
StringBuilder sb = new StringBuilder(s.length() * count);
for (int i = 0; i < count; i++) {
sb.append(s);
}
return sb.toString();
}
@NotNull
@Contract(pure = true)
public static List split(@NotNull String s, @NotNull String separator) {
return split(s, separator, true);
}
@NotNull
@Contract(pure = true)
public static List split(@NotNull CharSequence s, @NotNull CharSequence separator) {
return split(s, separator, true, true);
}
@NotNull
@Contract(pure = true)
public static List split(@NotNull String s, @NotNull String separator, boolean excludeSeparator) {
return split(s, separator, excludeSeparator, true);
}
@NotNull
@Contract(pure = true)
@SuppressWarnings("unchecked")
public static List split(@NotNull String s, @NotNull String separator, boolean excludeSeparator, boolean excludeEmptyStrings) {
return (List)split((CharSequence)s, separator, excludeSeparator, excludeEmptyStrings);
}
@NotNull
@Contract(pure = true)
public static List split(@NotNull CharSequence s, @NotNull CharSequence separator, boolean excludeSeparator, boolean excludeEmptyStrings) {
if (separator.length() == 0) {
return Collections.singletonList(s);
}
List result = new ArrayList();
int pos = 0;
while (true) {
int index = indexOf(s, separator, pos);
if (index == -1) break;
final int nextPos = index + separator.length();
CharSequence token = s.subSequence(pos, excludeSeparator ? index : nextPos);
if (token.length() != 0 || !excludeEmptyStrings) {
result.add(token);
}
pos = nextPos;
}
if (pos < s.length() || !excludeEmptyStrings && pos == s.length()) {
result.add(s.subSequence(pos, s.length()));
}
return result;
}
@NotNull
@Contract(pure = true)
public static Iterable tokenize(@NotNull String s, @NotNull String separators) {
final com.intellij.util.text.StringTokenizer tokenizer = new com.intellij.util.text.StringTokenizer(s, separators);
return new Iterable() {
@NotNull
@Override
public Iterator iterator() {
return new Iterator() {
@Override
public boolean hasNext() {
return tokenizer.hasMoreTokens();
}
@Override
public String next() {
return tokenizer.nextToken();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
@NotNull
@Contract(pure = true)
public static Iterable tokenize(@NotNull final StringTokenizer tokenizer) {
return new Iterable() {
@NotNull
@Override
public Iterator iterator() {
return new Iterator() {
@Override
public boolean hasNext() {
return tokenizer.hasMoreTokens();
}
@Override
public String next() {
return tokenizer.nextToken();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
/**
* @return list containing all words in {@code text}, or {@link ContainerUtil#emptyList()} if there are none.
* The word here means the maximum sub-string consisting entirely of characters which are {@code Character.isJavaIdentifierPart(c)}.
*/
@NotNull
@Contract(pure = true)
public static List getWordsIn(@NotNull String text) {
List result = null;
int start = -1;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
boolean isIdentifierPart = Character.isJavaIdentifierPart(c);
if (isIdentifierPart && start == -1) {
start = i;
}
if (isIdentifierPart && i == text.length() - 1) {
if (result == null) {
result = new SmartList();
}
result.add(text.substring(start, i + 1));
}
else if (!isIdentifierPart && start != -1) {
if (result == null) {
result = new SmartList();
}
result.add(text.substring(start, i));
start = -1;
}
}
if (result == null) {
return ContainerUtil.emptyList();
}
return result;
}
@NotNull
@Contract(pure = true)
public static List getWordIndicesIn(@NotNull String text) {
return getWordIndicesIn(text, null);
}
/**
* @param text text to get word ranges in.
* @param separatorsSet if not null, only these characters will be considered as separators (i.e. not a part of word).
* Otherwise {@link Character#isJavaIdentifierPart(char)} will be used to determine whether a symbol is part of word.
* @return ranges ranges of words in passed text.
*/
@NotNull
@Contract(pure = true)
public static List getWordIndicesIn(@NotNull String text, @Nullable Set separatorsSet) {
List result = new SmartList();
int start = -1;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
boolean isIdentifierPart = separatorsSet == null ? Character.isJavaIdentifierPart(c) : !separatorsSet.contains(c);
if (isIdentifierPart && start == -1) {
start = i;
}
if (isIdentifierPart && i == text.length() - 1) {
result.add(new TextRange(start, i + 1));
}
else if (!isIdentifierPart && start != -1) {
result.add(new TextRange(start, i));
start = -1;
}
}
return result;
}
@NotNull
@Contract(pure = true)
public static String join(@NotNull final String[] strings, @NotNull final String separator) {
return join(strings, 0, strings.length, separator);
}
@NotNull
@Contract(pure = true)
public static String join(@NotNull final String[] strings, int startIndex, int endIndex, @NotNull final String separator) {
final StringBuilder result = new StringBuilder();
for (int i = startIndex; i < endIndex; i++) {
if (i > startIndex) result.append(separator);
result.append(strings[i]);
}
return result.toString();
}
@NotNull
@Contract(pure = true)
public static String[] zip(@NotNull String[] strings1, @NotNull String[] strings2, String separator) {
if (strings1.length != strings2.length) throw new IllegalArgumentException();
String[] result = ArrayUtil.newStringArray(strings1.length);
for (int i = 0; i < result.length; i++) {
result[i] = strings1[i] + separator + strings2[i];
}
return result;
}
@NotNull
@Contract(pure = true)
public static String[] surround(@NotNull String[] strings, @NotNull String prefix, @NotNull String suffix) {
String[] result = ArrayUtil.newStringArray(strings.length);
for (int i = 0; i < result.length; i++) {
result[i] = prefix + strings[i] + suffix;
}
return result;
}
@NotNull
@Contract(pure = true)
public static String join(@NotNull T[] items, @NotNull Function super T, String> f, @NotNull String separator) {
return join(Arrays.asList(items), f, separator);
}
@NotNull
@Contract(pure = true)
public static String join(@NotNull Collection extends T> items,
@NotNull Function super T, String> f,
@NotNull String separator) {
if (items.isEmpty()) return "";
if (items.size() == 1) return notNullize(f.fun(items.iterator().next()));
return join((Iterable extends T>)items, f, separator);
}
@Contract(pure = true)
public static String join(@NotNull Iterable> items, @NotNull String separator) {
StringBuilder result = new StringBuilder();
for (Object item : items) {
result.append(item).append(separator);
}
if (result.length() > 0) {
result.setLength(result.length() - separator.length());
}
return result.toString();
}
@NotNull
@Contract(pure = true)
public static String join(@NotNull Iterable extends T> items,
@NotNull Function super T, String> f,
@NotNull String separator) {
StringBuilder result = new StringBuilder();
join(items, f, separator, result);
return result.toString();
}
public static void join(@NotNull Iterable extends T> items,
@NotNull Function super T, String> f,
@NotNull String separator,
@NotNull StringBuilder result) {
boolean isFirst = true;
for (T item : items) {
String string = f.fun(item);
if (!isEmpty(string)) {
if (isFirst) {
isFirst = false;
}
else {
result.append(separator);
}
result.append(string);
}
}
}
@NotNull
@Contract(pure = true)
public static String join(@NotNull Collection strings, @NotNull String separator) {
if (strings.size() <= 1) {
return notNullize(ContainerUtil.getFirstItem(strings));
}
StringBuilder result = new StringBuilder();
join(strings, separator, result);
return result.toString();
}
public static void join(@NotNull Collection strings, @NotNull String separator, @NotNull StringBuilder result) {
boolean isFirst = true;
for (String string : strings) {
if (string != null) {
if (isFirst) {
isFirst = false;
}
else {
result.append(separator);
}
result.append(string);
}
}
}
@NotNull
@Contract(pure = true)
public static String join(@NotNull final int[] strings, @NotNull final String separator) {
final StringBuilder result = new StringBuilder();
for (int i = 0; i < strings.length; i++) {
if (i > 0) result.append(separator);
result.append(strings[i]);
}
return result.toString();
}
@NotNull
@Contract(pure = true)
public static String join(@NotNull final String... strings) {
if (strings.length == 0) return "";
final StringBuilder builder = new StringBuilder();
for (final String string : strings) {
builder.append(string);
}
return builder.toString();
}
/**
* Consider using {@link StringUtil#unquoteString(String)} instead.
* Note: this method has an odd behavior:
* Quotes are removed even if leading and trailing quotes are different or
* if there is only one quote (leading or trailing).
*/
@NotNull
@Contract(pure = true)
public static String stripQuotesAroundValue(@NotNull String text) {
final int len = text.length();
if (len > 0) {
final int from = isQuoteAt(text, 0) ? 1 : 0;
final int to = len > 1 && isQuoteAt(text, len - 1) ? len - 1 : len;
if (from > 0 || to < len) {
return text.substring(from, to);
}
}
return text;
}
/** Formats given duration as a sum of time units (example: {@code formatDuration(123456) = "2 m 3 s 456 ms"}). */
@NotNull
@Contract(pure = true)
public static String formatDuration(long duration) {
return formatDuration(duration, " ");
}
private static final String[] TIME_UNITS = {"ms", "s", "m", "h", "d", "mo", "yr", "c", "ml", "ep"};
private static final long[] TIME_MULTIPLIERS = {1, 1000, 60, 60, 24, 30, 12, 100, 10, 10000};
/** Formats given duration as a sum of time units (example: {@code formatDuration(123456, "") = "2m 3s 456ms"}). */
@NotNull
@Contract(pure = true)
public static String formatDuration(long duration, @NotNull String unitSeparator) {
String[] units = TIME_UNITS;
StringBuilder sb = new StringBuilder();
long count = duration;
int i = 1;
for (; i < units.length && count > 0; i++) {
long multiplier = TIME_MULTIPLIERS[i];
if (count < multiplier) break;
long remainder = count % multiplier;
count /= multiplier;
if (remainder != 0 || sb.length() > 0) {
if (!units[i - 1].isEmpty()) {
sb.insert(0, units[i - 1]);
sb.insert(0, unitSeparator);
}
sb.insert(0, remainder).insert(0, " ");
}
else {
remainder = Math.round(remainder * 100 / (double)multiplier);
count += remainder / 100;
}
}
if (!units[i - 1].isEmpty()) {
sb.insert(0, units[i - 1]);
sb.insert(0, unitSeparator);
}
sb.insert(0, count);
return sb.toString();
}
@Contract(pure = true)
public static boolean containsAlphaCharacters(@NotNull String value) {
for (int i = 0; i < value.length(); i++) {
if (Character.isLetter(value.charAt(i))) return true;
}
return false;
}
@Contract(pure = true)
public static boolean containsAnyChar(@NotNull final String value, @NotNull final String chars) {
return chars.length() > value.length()
? containsAnyChar(value, chars, 0, value.length())
: containsAnyChar(chars, value, 0, chars.length());
}
@Contract(pure = true)
public static boolean containsAnyChar(@NotNull final String value,
@NotNull final String chars,
final int start, final int end) {
for (int i = start; i < end; i++) {
if (chars.indexOf(value.charAt(i)) >= 0) {
return true;
}
}
return false;
}
@Contract(pure = true)
public static boolean containsChar(@NotNull final String value, final char ch) {
return value.indexOf(ch) >= 0;
}
/**
* @deprecated use #capitalize(String)
*/
@Deprecated
@Contract(value = "null -> null; !null -> !null", pure = true)
public static String firstLetterToUpperCase(@Nullable final String displayString) {
if (displayString == null || displayString.isEmpty()) return displayString;
char firstChar = displayString.charAt(0);
char uppedFirstChar = toUpperCase(firstChar);
if (uppedFirstChar == firstChar) return displayString;
char[] buffer = displayString.toCharArray();
buffer[0] = uppedFirstChar;
return StringFactory.createShared(buffer);
}
/**
* Strip out all characters not accepted by given filter
*
* @param s e.g. "/n my string "
* @param filter e.g. {@link CharFilter#NOT_WHITESPACE_FILTER}
* @return stripped string e.g. "mystring"
*/
@NotNull
@Contract(pure = true)
public static String strip(@NotNull final String s, @NotNull final CharFilter filter) {
final StringBuilder result = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (filter.accept(ch)) {
result.append(ch);
}
}
return result.toString();
}
@NotNull
@Contract(pure = true)
public static List findMatches(@NotNull String s, @NotNull Pattern pattern) {
return findMatches(s, pattern, 1);
}
@NotNull
@Contract(pure = true)
public static List findMatches(@NotNull String s, @NotNull Pattern pattern, int groupIndex) {
List result = new SmartList();
Matcher m = pattern.matcher(s);
while (m.find()) {
String group = m.group(groupIndex);
if (group != null) {
result.add(group);
}
}
return result;
}
/**
* Find position of the first character accepted by given filter.
*
* @param s the string to search
* @param filter search filter
* @return position of the first character accepted or -1 if not found
*/
@Contract(pure = true)
public static int findFirst(@NotNull final CharSequence s, @NotNull CharFilter filter) {
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (filter.accept(ch)) {
return i;
}
}
return -1;
}
@NotNull
@Contract(pure = true)
public static String replaceSubstring(@NotNull String string, @NotNull TextRange range, @NotNull String replacement) {
return range.replace(string, replacement);
}
@Contract(pure = true)
public static boolean startsWithWhitespace(@NotNull String text) {
return !text.isEmpty() && Character.isWhitespace(text.charAt(0));
}
@Contract(pure = true)
public static boolean isChar(CharSequence seq, int index, char c) {
return index >= 0 && index < seq.length() && seq.charAt(index) == c;
}
@Contract(pure = true)
public static boolean startsWith(@NotNull CharSequence text, @NotNull CharSequence prefix) {
int l1 = text.length();
int l2 = prefix.length();
if (l1 < l2) return false;
for (int i = 0; i < l2; i++) {
if (text.charAt(i) != prefix.charAt(i)) return false;
}
return true;
}
@Contract(pure = true)
public static boolean startsWith(@NotNull CharSequence text, int startIndex, @NotNull CharSequence prefix) {
int tl = text.length();
if (startIndex < 0 || startIndex > tl) {
throw new IllegalArgumentException("Index is out of bounds: " + startIndex + ", length: " + tl);
}
int l1 = tl - startIndex;
int l2 = prefix.length();
if (l1 < l2) return false;
for (int i = 0; i < l2; i++) {
if (text.charAt(i + startIndex) != prefix.charAt(i)) return false;
}
return true;
}
@Contract(pure = true)
public static boolean endsWith(@NotNull CharSequence text, @NotNull CharSequence suffix) {
int l1 = text.length();
int l2 = suffix.length();
if (l1 < l2) return false;
for (int i = l1 - 1; i >= l1 - l2; i--) {
if (text.charAt(i) != suffix.charAt(i + l2 - l1)) return false;
}
return true;
}
@NotNull
@Contract(pure = true)
public static String commonPrefix(@NotNull String s1, @NotNull String s2) {
return s1.substring(0, commonPrefixLength(s1, s2));
}
@Contract(pure = true)
public static int commonPrefixLength(@NotNull CharSequence s1, @NotNull CharSequence s2) {
return commonPrefixLength(s1, s2, false);
}
@Contract(pure = true)
public static int commonPrefixLength(@NotNull CharSequence s1, @NotNull CharSequence s2, boolean ignoreCase) {
int i;
int minLength = Math.min(s1.length(), s2.length());
for (i = 0; i < minLength; i++) {
if (!charsMatch(s1.charAt(i), s2.charAt(i), ignoreCase)) {
break;
}
}
return i;
}
@NotNull
@Contract(pure = true)
public static String commonSuffix(@NotNull String s1, @NotNull String s2) {
return s1.substring(s1.length() - commonSuffixLength(s1, s2));
}
@Contract(pure = true)
public static int commonSuffixLength(@NotNull CharSequence s1, @NotNull CharSequence s2) {
int s1Length = s1.length();
int s2Length = s2.length();
if (s1Length == 0 || s2Length == 0) return 0;
int i;
for (i = 0; i < s1Length && i < s2Length; i++) {
if (s1.charAt(s1Length - i - 1) != s2.charAt(s2Length - i - 1)) {
break;
}
}
return i;
}
/**
* Allows to answer if target symbol is contained at given char sequence at {@code [start; end)} interval.
*
* @param s target char sequence to check
* @param start start offset to use within the given char sequence (inclusive)
* @param end end offset to use within the given char sequence (exclusive)
* @param c target symbol to check
* @return {@code true} if given symbol is contained at the target range of the given char sequence;
* {@code false} otherwise
*/
@Contract(pure = true)
public static boolean contains(@NotNull CharSequence s, int start, int end, char c) {
return indexOf(s, c, start, end) >= 0;
}
@Contract(pure = true)
public static boolean containsWhitespaces(@Nullable CharSequence s) {
if (s == null) return false;
for (int i = 0; i < s.length(); i++) {
if (Character.isWhitespace(s.charAt(i))) return true;
}
return false;
}
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence s, char c) {
return indexOf(s, c, 0, s.length());
}
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence s, char c, int start) {
return indexOf(s, c, start, s.length());
}
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence s, char c, int start, int end) {
end = Math.min(end, s.length());
for (int i = Math.max(start, 0); i < end; i++) {
if (s.charAt(i) == c) return i;
}
return -1;
}
@Contract(pure = true)
public static boolean contains(@NotNull CharSequence sequence, @NotNull CharSequence infix) {
return indexOf(sequence, infix) >= 0;
}
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence sequence, @NotNull CharSequence infix) {
return indexOf(sequence, infix, 0);
}
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence sequence, @NotNull CharSequence infix, int start) {
return indexOf(sequence, infix, start, sequence.length());
}
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence sequence, @NotNull CharSequence infix, int start, int end) {
for (int i = start; i <= end - infix.length(); i++) {
if (startsWith(sequence, i, infix)) {
return i;
}
}
return -1;
}
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence s, char c, int start, int end, boolean caseSensitive) {
end = Math.min(end, s.length());
for (int i = Math.max(start, 0); i < end; i++) {
if (charsMatch(s.charAt(i), c, !caseSensitive)) return i;
}
return -1;
}
@Contract(pure = true)
public static int indexOf(@NotNull char[] s, char c, int start, int end, boolean caseSensitive) {
end = Math.min(end, s.length);
for (int i = Math.max(start, 0); i < end; i++) {
if (charsMatch(s[i], c, !caseSensitive)) return i;
}
return -1;
}
@Contract(pure = true)
public static int indexOfSubstringEnd(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return -1;
return i + subString.length();
}
@Contract(pure = true)
public static int indexOfAny(@NotNull final String s, @NotNull final String chars) {
return indexOfAny(s, chars, 0, s.length());
}
@Contract(pure = true)
public static int indexOfAny(@NotNull final CharSequence s, @NotNull final String chars) {
return indexOfAny(s, chars, 0, s.length());
}
@Contract(pure = true)
public static int indexOfAny(@NotNull final String s, @NotNull final String chars, final int start, final int end) {
return indexOfAny((CharSequence)s, chars, start, end);
}
@Contract(pure = true)
public static int indexOfAny(@NotNull final CharSequence s, @NotNull final String chars, final int start, int end) {
end = Math.min(end, s.length());
for (int i = Math.max(start, 0); i < end; i++) {
if (containsChar(chars, s.charAt(i))) return i;
}
return -1;
}
@Contract(pure = true)
public static int lastIndexOfAny(@NotNull CharSequence s, @NotNull final String chars) {
for (int i = s.length() - 1; i >= 0; i--) {
if (containsChar(chars, s.charAt(i))) return i;
}
return -1;
}
@Nullable
@Contract(pure = true)
public static String substringBefore(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return null;
return text.substring(0, i);
}
@NotNull
@Contract(pure = true)
public static String substringBeforeLast(@NotNull String text, @NotNull String subString) {
int i = text.lastIndexOf(subString);
if (i == -1) return text;
return text.substring(0, i);
}
@Nullable
@Contract(pure = true)
public static String substringAfter(@NotNull String text, @NotNull String subString) {
int i = text.indexOf(subString);
if (i == -1) return null;
return text.substring(i + subString.length());
}
@Nullable
@Contract(pure = true)
public static String substringAfterLast(@NotNull String text, @NotNull String subString) {
int i = text.lastIndexOf(subString);
if (i == -1) return null;
return text.substring(i + subString.length());
}
/**
* Allows to retrieve index of last occurrence of the given symbols at {@code [start; end)} sub-sequence of the given text.
*
* @param s target text
* @param c target symbol which last occurrence we want to check
* @param start start offset of the target text (inclusive)
* @param end end offset of the target text (exclusive)
* @return index of the last occurrence of the given symbol at the target sub-sequence of the given text if any;
* {@code -1} otherwise
*/
@Contract(pure = true)
public static int lastIndexOf(@NotNull CharSequence s, char c, int start, int end) {
return StringUtilRt.lastIndexOf(s, c, start, end);
}
@NotNull
@Contract(pure = true)
public static String first(@NotNull String text, final int maxLength, final boolean appendEllipsis) {
return text.length() > maxLength ? text.substring(0, maxLength) + (appendEllipsis ? "..." : "") : text;
}
@NotNull
@Contract(pure = true)
public static CharSequence first(@NotNull CharSequence text, final int length, final boolean appendEllipsis) {
if (text.length() <= length) {
return text;
}
if (appendEllipsis) {
return text.subSequence(0, length) + "...";
}
return text.subSequence(0, length);
}
@NotNull
@Contract(pure = true)
public static CharSequence last(@NotNull CharSequence text, final int length, boolean prependEllipsis) {
if (text.length() <= length) {
return text;
}
if (prependEllipsis) {
return "..." + text.subSequence(text.length() - length, text.length());
}
return text.subSequence(text.length() - length, text.length());
}
@NotNull
@Contract(pure = true)
public static String firstLast(@NotNull String text, int length) {
return text.length() > length
? text.subSequence(0, length / 2) + "\u2026" + text.subSequence(text.length() - length / 2 - 1, text.length())
: text;
}
@NotNull
@Contract(pure = true)
public static String escapeChar(@NotNull final String str, final char character) {
return escapeChars(str, character);
}
@NotNull
@Contract(pure = true)
public static String escapeChars(@NotNull final String str, final char... character) {
final StringBuilder buf = new StringBuilder(str);
for (char c : character) {
escapeChar(buf, c);
}
return buf.toString();
}
public static void escapeChar(@NotNull final StringBuilder buf, final char character) {
int idx = 0;
while ((idx = indexOf(buf, character, idx)) >= 0) {
buf.insert(idx, "\\");
idx += 2;
}
}
@NotNull
@Contract(pure = true)
public static String escapeQuotes(@NotNull final String str) {
return escapeChar(str, '"');
}
public static void escapeQuotes(@NotNull final StringBuilder buf) {
escapeChar(buf, '"');
}
@NotNull
@Contract(pure = true)
public static String escapeSlashes(@NotNull final String str) {
return escapeChar(str, '/');
}
@NotNull
@Contract(pure = true)
public static String escapeBackSlashes(@NotNull final String str) {
return escapeChar(str, '\\');
}
public static void escapeSlashes(@NotNull final StringBuilder buf) {
escapeChar(buf, '/');
}
@NotNull
@Contract(pure = true)
public static String unescapeSlashes(@NotNull final String str) {
final StringBuilder buf = new StringBuilder(str.length());
unescapeChar(buf, str, '/');
return buf.toString();
}
@NotNull
@Contract(pure = true)
public static String unescapeBackSlashes(@NotNull final String str) {
final StringBuilder buf = new StringBuilder(str.length());
unescapeChar(buf, str, '\\');
return buf.toString();
}
@NotNull
@Contract(pure = true)
public static String unescapeChar(@NotNull final String str, char unescapeChar) {
final StringBuilder buf = new StringBuilder(str.length());
unescapeChar(buf, str, unescapeChar);
return buf.toString();
}
private static void unescapeChar(@NotNull StringBuilder buf, @NotNull String str, char unescapeChar) {
final int length = str.length();
final int last = length - 1;
for (int i = 0; i < length; i++) {
char ch = str.charAt(i);
if (ch == '\\' && i != last) {
//noinspection AssignmentToForLoopParameter
i++;
ch = str.charAt(i);
if (ch != unescapeChar) buf.append('\\');
}
buf.append(ch);
}
}
public static void quote(@NotNull final StringBuilder builder) {
quote(builder, '\"');
}
public static void quote(@NotNull final StringBuilder builder, final char quotingChar) {
builder.insert(0, quotingChar);
builder.append(quotingChar);
}
@NotNull
@Contract(pure = true)
public static String wrapWithDoubleQuote(@NotNull String str) {
return '\"' + str + "\"";
}
private static final List REPLACES_REFS = Arrays.asList("<", ">", "&", "'", """);
private static final List REPLACES_DISP = Arrays.asList("<", ">", "&", "'", "\"");
/**
* @deprecated Use {@link #unescapeXmlEntities(String)} instead
*/
@Contract(value = "null -> null; !null -> !null",pure = true)
@Deprecated
public static String unescapeXml(@Nullable final String text) {
return text == null ? null : unescapeXmlEntities(text);
}
/**
* @deprecated Use {@link #escapeXmlEntities(String)} instead
*/
@Contract(value = "null -> null; !null -> !null",pure = true)
@Deprecated
public static String escapeXml(@Nullable final String text) {
return text == null ? null : escapeXmlEntities(text);
}
/**
* @return {@code text} with some standard XML entities replaced with corresponding characters, e.g. '{@code <}' replaced with '<'
*/
@NotNull
@Contract(pure = true)
public static String unescapeXmlEntities(@NotNull String text) {
return replace(text, REPLACES_REFS, REPLACES_DISP);
}
/**
* @return {@code text} with some characters replaced with standard XML entities, e.g. '<' replaced with '{@code <}'
*/
@NotNull
@Contract(pure = true)
public static String escapeXmlEntities(@NotNull String text) {
return replace(text, REPLACES_DISP, REPLACES_REFS);
}
@NotNull
public static String removeHtmlTags(@NotNull String htmlString) {
return removeHtmlTags(htmlString, false);
}
@NotNull
public static String removeHtmlTags(@NotNull String htmlString, boolean isRemoveStyleTag) {
if (isEmpty(htmlString)) {
return "";
}
final MyHtml2Text parser = isRemoveStyleTag ? new MyHtml2Text(true) : html2TextParser;
try {
parser.parse(new StringReader(htmlString));
}
catch (IOException e) {
LOG.error(e);
}
return parser.getText();
}
private static final List MN_QUOTED = Arrays.asList("&&", "__");
private static final List MN_CHARS = Arrays.asList("&", "_");
@NotNull
@Contract(pure = true)
public static String escapeMnemonics(@NotNull String text) {
return replace(text, MN_CHARS, MN_QUOTED);
}
@NotNull
@Contract(pure = true)
public static String htmlEmphasize(@NotNull String text) {
return "" + escapeXmlEntities(text) + "";
}
@NotNull
@Contract(pure = true)
public static String escapeToRegexp(@NotNull String text) {
final StringBuilder result = new StringBuilder(text.length());
return escapeToRegexp(text, result).toString();
}
@NotNull
public static StringBuilder escapeToRegexp(@NotNull CharSequence text, @NotNull StringBuilder builder) {
for (int i = 0; i < text.length(); i++) {
final char c = text.charAt(i);
if (c == ' ' || Character.isLetter(c) || Character.isDigit(c) || c == '_') {
builder.append(c);
}
else if (c == '\n') {
builder.append("\\n");
}
else if (c == '\r') {
builder.append("\\r");
}
else {
builder.append('\\').append(c);
}
}
return builder;
}
@Contract(pure = true)
public static boolean isEscapedBackslash(@NotNull char[] chars, int startOffset, int backslashOffset) {
if (chars[backslashOffset] != '\\') {
return true;
}
boolean escaped = false;
for (int i = startOffset; i < backslashOffset; i++) {
if (chars[i] == '\\') {
escaped = !escaped;
}
else {
escaped = false;
}
}
return escaped;
}
@Contract(pure = true)
public static boolean isEscapedBackslash(@NotNull CharSequence text, int startOffset, int backslashOffset) {
if (text.charAt(backslashOffset) != '\\') {
return true;
}
boolean escaped = false;
for (int i = startOffset; i < backslashOffset; i++) {
if (text.charAt(i) == '\\') {
escaped = !escaped;
}
else {
escaped = false;
}
}
return escaped;
}
/**
* @deprecated Use {@link #replace(String, List, List)}
*/
@Deprecated
@NotNull
@Contract(pure = true)
public static String replace(@NotNull String text, @NotNull String[] from, @NotNull String[] to) {
return replace(text, Arrays.asList(from), Arrays.asList(to));
}
@NotNull
@Contract(pure = true)
public static String replace(@NotNull String text, @NotNull List from, @NotNull List to) {
assert from.size() == to.size();
StringBuilder result = null;
replace:
for (int i = 0; i < text.length(); i++) {
for (int j = 0; j < from.size(); j += 1) {
String toReplace = from.get(j);
String replaceWith = to.get(j);
final int len = toReplace.length();
if (text.regionMatches(i, toReplace, 0, len)) {
if (result == null) {
result = new StringBuilder(text.length());
result.append(text, 0, i);
}
result.append(replaceWith);
//noinspection AssignmentToForLoopParameter
i += len - 1;
continue replace;
}
}
if (result != null) {
result.append(text.charAt(i));
}
}
return result == null ? text : result.toString();
}
@NotNull
@Contract(pure = true)
public static String[] filterEmptyStrings(@NotNull String[] strings) {
int emptyCount = 0;
for (String string : strings) {
if (string == null || string.isEmpty()) emptyCount++;
}
if (emptyCount == 0) return strings;
String[] result = ArrayUtil.newStringArray(strings.length - emptyCount);
int count = 0;
for (String string : strings) {
if (string == null || string.isEmpty()) continue;
result[count++] = string;
}
return result;
}
@Contract(pure = true)
public static int countNewLines(@NotNull CharSequence text) {
return countChars(text, '\n');
}
@Contract(pure = true)
public static int countChars(@NotNull CharSequence text, char c) {
return countChars(text, c, 0, false);
}
@Contract(pure = true)
public static int countChars(@NotNull CharSequence text, char c, int offset, boolean stopAtOtherChar) {
return countChars(text, c, offset, text.length(), stopAtOtherChar);
}
@Contract(pure = true)
public static int countChars(@NotNull CharSequence text, char c, int start, int end, boolean stopAtOtherChar) {
boolean forward = start <= end;
start = forward ? Math.max(0, start) : Math.min(text.length(), start);
end = forward ? Math.min(text.length(), end) : Math.max(0, end);
int count = 0;
for (int i = forward ? start : start - 1; forward == i < end; i += forward ? 1 : -1) {
if (text.charAt(i) == c) {
count++;
}
else if (stopAtOtherChar) {
break;
}
}
return count;
}
@NotNull
@Contract(pure = true)
public static String capitalsOnly(@NotNull String s) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (Character.isUpperCase(s.charAt(i))) {
b.append(s.charAt(i));
}
}
return b.toString();
}
/**
* @param args Strings to join.
* @return {@code null} if any of given Strings is {@code null}.
*/
@Nullable
@Contract(pure = true)
public static String joinOrNull(@NotNull String... args) {
StringBuilder r = new StringBuilder();
for (String arg : args) {
if (arg == null) return null;
r.append(arg);
}
return r.toString();
}
@Nullable
@Contract(pure = true)
public static String getPropertyName(@NotNull String methodName) {
if (methodName.startsWith("get")) {
return Introspector.decapitalize(methodName.substring(3));
}
if (methodName.startsWith("is")) {
return Introspector.decapitalize(methodName.substring(2));
}
if (methodName.startsWith("set")) {
return Introspector.decapitalize(methodName.substring(3));
}
return null;
}
@Contract(pure = true)
public static boolean isJavaIdentifierStart(char c) {
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || Character.isJavaIdentifierStart(c);
}
@Contract(pure = true)
public static boolean isJavaIdentifierPart(char c) {
return c >= '0' && c <= '9' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || Character.isJavaIdentifierPart(c);
}
@Contract(pure = true)
public static boolean isJavaIdentifier(@NotNull String text) {
int len = text.length();
if (len == 0) return false;
if (!isJavaIdentifierStart(text.charAt(0))) return false;
for (int i = 1; i < len; i++) {
if (!isJavaIdentifierPart(text.charAt(i))) return false;
}
return true;
}
/**
* Escape property name or key in property file. Unicode characters are escaped as well.
*
* @param input an input to escape
* @param isKey if true, the rules for key escaping are applied. The leading space is escaped in that case.
* @return an escaped string
*/
@NotNull
@Contract(pure = true)
public static String escapeProperty(@NotNull String input, final boolean isKey) {
final StringBuilder escaped = new StringBuilder(input.length());
for (int i = 0; i < input.length(); i++) {
final char ch = input.charAt(i);
switch (ch) {
case ' ':
if (isKey && i == 0) {
// only the leading space has to be escaped
escaped.append('\\');
}
escaped.append(' ');
break;
case '\t':
escaped.append("\\t");
break;
case '\r':
escaped.append("\\r");
break;
case '\n':
escaped.append("\\n");
break;
case '\f':
escaped.append("\\f");
break;
case '\\':
case '#':
case '!':
case ':':
case '=':
escaped.append('\\');
escaped.append(ch);
break;
default:
if (20 < ch && ch < 0x7F) {
escaped.append(ch);
}
else {
escaped.append("\\u");
escaped.append(Character.forDigit((ch >> 12) & 0xF, 16));
escaped.append(Character.forDigit((ch >> 8) & 0xF, 16));
escaped.append(Character.forDigit((ch >> 4) & 0xF, 16));
escaped.append(Character.forDigit((ch) & 0xF, 16));
}
break;
}
}
return escaped.toString();
}
@NotNull
@Contract(pure = true)
public static String getQualifiedName(@Nullable String packageName, @NotNull String className) {
if (packageName == null || packageName.isEmpty()) {
return className;
}
return packageName + '.' + className;
}
@Contract(pure = true)
public static int compareVersionNumbers(@Nullable String v1, @Nullable String v2) {
// todo duplicates com.intellij.util.text.VersionComparatorUtil.compare
// todo please refactor next time you make changes here
if (v1 == null && v2 == null) {
return 0;
}
if (v1 == null) {
return -1;
}
if (v2 == null) {
return 1;
}
String[] part1 = v1.split("[._\\-]");
String[] part2 = v2.split("[._\\-]");
int idx = 0;
for (; idx < part1.length && idx < part2.length; idx++) {
String p1 = part1[idx];
String p2 = part2[idx];
int cmp;
if (p1.matches("\\d+") && p2.matches("\\d+")) {
cmp = new Integer(p1).compareTo(new Integer(p2));
}
else {
cmp = part1[idx].compareTo(part2[idx]);
}
if (cmp != 0) return cmp;
}
if (part1.length != part2.length) {
boolean left = part1.length > idx;
String[] parts = left ? part1 : part2;
for (; idx < parts.length; idx++) {
String p = parts[idx];
int cmp;
if (p.matches("\\d+")) {
cmp = new Integer(p).compareTo(0);
}
else {
cmp = 1;
}
if (cmp != 0) return left ? cmp : -cmp;
}
}
return 0;
}
@Contract(pure = true)
public static int getOccurrenceCount(@NotNull String text, final char c) {
int res = 0;
int i = 0;
while (i < text.length()) {
i = text.indexOf(c, i);
if (i >= 0) {
res++;
i++;
}
else {
break;
}
}
return res;
}
@Contract(pure = true)
public static int getOccurrenceCount(@NotNull String text, @NotNull String s) {
int res = 0;
int i = 0;
while (i < text.length()) {
i = text.indexOf(s, i);
if (i >= 0) {
res++;
i++;
}
else {
break;
}
}
return res;
}
@Contract(pure = true)
public static int getIgnoreCaseOccurrenceCount(@NotNull String text, @NotNull String s) {
int res = 0;
int i = 0;
while (i < text.length()) {
i = indexOfIgnoreCase(text, s, i);
if (i >= 0) {
res++;
i++;
}
else {
break;
}
}
return res;
}
@NotNull
@Contract(pure = true)
public static String fixVariableNameDerivedFromPropertyName(@NotNull String name) {
if (isEmptyOrSpaces(name)) return name;
char c = name.charAt(0);
if (isVowel(c)) {
return "an" + Character.toUpperCase(c) + name.substring(1);
}
return "a" + Character.toUpperCase(c) + name.substring(1);
}
@NotNull
@Contract(pure = true)
public static String sanitizeJavaIdentifier(@NotNull String name) {
final StringBuilder result = new StringBuilder(name.length());
for (int i = 0; i < name.length(); i++) {
final char ch = name.charAt(i);
if (Character.isJavaIdentifierPart(ch)) {
if (result.length() == 0 && !Character.isJavaIdentifierStart(ch)) {
result.append("_");
}
result.append(ch);
}
}
return result.toString();
}
public static void assertValidSeparators(@NotNull CharSequence s) {
char[] chars = CharArrayUtil.fromSequenceWithoutCopying(s);
int slashRIndex = -1;
if (chars != null) {
for (int i = 0, len = s.length(); i < len; ++i) {
if (chars[i] == '\r') {
slashRIndex = i;
break;
}
}
}
else {
for (int i = 0, len = s.length(); i < len; i++) {
if (s.charAt(i) == '\r') {
slashRIndex = i;
break;
}
}
}
if (slashRIndex != -1) {
String context =
String.valueOf(last(s.subSequence(0, slashRIndex), 10, true)) + first(s.subSequence(slashRIndex, s.length()), 10, true);
context = escapeStringCharacters(context);
throw new AssertionError("Wrong line separators: '" + context + "' at offset " + slashRIndex);
}
}
@NotNull
@Contract(pure = true)
public static String tail(@NotNull String s, final int idx) {
return idx >= s.length() ? "" : s.substring(idx);
}
/**
* Splits string by lines.
*
* @param string String to split
* @return array of strings
*/
@NotNull
@Contract(pure = true)
public static String[] splitByLines(@NotNull String string) {
return splitByLines(string, true);
}
/**
* Splits string by lines. If several line separators are in a row corresponding empty lines
* are also added to result if {@code excludeEmptyStrings} is {@code false}.
*
* @param string String to split
* @return array of strings
*/
@NotNull
@Contract(pure = true)
public static String[] splitByLines(@NotNull String string, boolean excludeEmptyStrings) {
return (excludeEmptyStrings ? EOL_SPLIT_PATTERN : EOL_SPLIT_PATTERN_WITH_EMPTY).split(string);
}
@NotNull
@Contract(pure = true)
public static String[] splitByLinesDontTrim(@NotNull String string) {
return EOL_SPLIT_DONT_TRIM_PATTERN.split(string);
}
/**
* Splits string by lines, keeping all line separators at the line ends and in the empty lines.
*
E.g. splitting text
*
* foo\r\n
* \n
* bar\n
* \r\n
* baz\r
* \r
*
* will return the following array: foo\r\n, \n, bar\n, \r\n, baz\r, \r
*
*/
@NotNull
@Contract(pure = true)
public static String[] splitByLinesKeepSeparators(@NotNull String string) {
return EOL_SPLIT_KEEP_SEPARATORS.split(string);
}
@NotNull
@Contract(pure = true)
public static List> getWordsWithOffset(@NotNull String s) {
List> res = ContainerUtil.newArrayList();
s += " ";
StringBuilder name = new StringBuilder();
int startInd = -1;
for (int i = 0; i < s.length(); i++) {
if (Character.isWhitespace(s.charAt(i))) {
if (name.length() > 0) {
res.add(Pair.create(name.toString(), startInd));
name.setLength(0);
startInd = -1;
}
}
else {
if (startInd == -1) {
startInd = i;
}
name.append(s.charAt(i));
}
}
return res;
}
@Contract(pure = true)
public static int naturalCompare(@Nullable String string1, @Nullable String string2) {
return NaturalComparator.INSTANCE.compare(string1, string2);
}
@Contract(pure = true)
public static boolean isDecimalDigit(char c) {
return c >= '0' && c <= '9';
}
@Contract("null -> false")
public static boolean isNotNegativeNumber(@Nullable CharSequence s) {
if (s == null) {
return false;
}
for (int i = 0; i < s.length(); i++) {
if (!isDecimalDigit(s.charAt(i))) {
return false;
}
}
return true;
}
@Contract(pure = true)
public static int compare(@Nullable String s1, @Nullable String s2, boolean ignoreCase) {
//noinspection StringEquality
if (s1 == s2) return 0;
if (s1 == null) return -1;
if (s2 == null) return 1;
return ignoreCase ? s1.compareToIgnoreCase(s2) : s1.compareTo(s2);
}
@Contract(pure = true)
public static int comparePairs(@Nullable String s1, @Nullable String t1, @Nullable String s2, @Nullable String t2, boolean ignoreCase) {
final int compare = compare(s1, s2, ignoreCase);
return compare != 0 ? compare : compare(t1, t2, ignoreCase);
}
@Contract(pure = true)
public static int hashCode(@NotNull CharSequence s) {
return stringHashCode(s);
}
@Contract(pure = true)
public static boolean equals(@Nullable CharSequence s1, @Nullable CharSequence s2) {
if (s1 == null ^ s2 == null) {
return false;
}
if (s1 == null) {
return true;
}
if (s1.length() != s2.length()) {
return false;
}
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) != s2.charAt(i)) {
return false;
}
}
return true;
}
@Contract(pure = true)
public static boolean equalsIgnoreCase(@Nullable CharSequence s1, @Nullable CharSequence s2) {
if (s1 == null ^ s2 == null) {
return false;
}
if (s1 == null) {
return true;
}
if (s1.length() != s2.length()) {
return false;
}
for (int i = 0; i < s1.length(); i++) {
if (!charsEqualIgnoreCase(s1.charAt(i), s2.charAt(i))) {
return false;
}
}
return true;
}
@Contract(pure = true)
public static boolean equalsIgnoreWhitespaces(@Nullable CharSequence s1, @Nullable CharSequence s2) {
if (s1 == null ^ s2 == null) {
return false;
}
if (s1 == null) {
return true;
}
int len1 = s1.length();
int len2 = s2.length();
int index1 = 0;
int index2 = 0;
while (index1 < len1 && index2 < len2) {
if (s1.charAt(index1) == s2.charAt(index2)) {
index1++;
index2++;
continue;
}
boolean skipped = false;
while (index1 != len1 && isWhiteSpace(s1.charAt(index1))) {
skipped = true;
index1++;
}
while (index2 != len2 && isWhiteSpace(s2.charAt(index2))) {
skipped = true;
index2++;
}
if (!skipped) return false;
}
for (; index1 != len1; index1++) {
if (!isWhiteSpace(s1.charAt(index1))) return false;
}
for (; index2 != len2; index2++) {
if (!isWhiteSpace(s2.charAt(index2))) return false;
}
return true;
}
@Contract(pure = true)
public static boolean equalsTrimWhitespaces(@NotNull CharSequence s1, @NotNull CharSequence s2) {
int start1 = 0;
int end1 = s1.length();
int end2 = s2.length();
while (start1 < end1) {
char c = s1.charAt(start1);
if (!isWhiteSpace(c)) break;
start1++;
}
while (start1 < end1) {
char c = s1.charAt(end1 - 1);
if (!isWhiteSpace(c)) break;
end1--;
}
int start2 = 0;
while (start2 < end2) {
char c = s2.charAt(start2);
if (!isWhiteSpace(c)) break;
start2++;
}
while (start2 < end2) {
char c = s2.charAt(end2 - 1);
if (!isWhiteSpace(c)) break;
end2--;
}
CharSequence ts1 = new CharSequenceSubSequence(s1, start1, end1);
CharSequence ts2 = new CharSequenceSubSequence(s2, start2, end2);
return equals(ts1, ts2);
}
/**
* Collapses all white-space (including new lines) between non-white-space characters to a single space character.
* Leading and trailing white space is removed.
*/
public static String collapseWhiteSpace(@NotNull CharSequence s) {
final StringBuilder result = new StringBuilder();
boolean space = false;
for (int i = 0, length = s.length(); i < length; i++) {
final char ch = s.charAt(i);
if (isWhiteSpace(ch)) {
if (!space) space = true;
}
else {
if (space && result.length() > 0) result.append(' ');
result.append(ch);
space = false;
}
}
return result.toString();
}
@Contract(pure = true)
public static boolean findIgnoreCase(@Nullable String toFind, @NotNull String... where) {
for (String string : where) {
if (equalsIgnoreCase(toFind, string)) return true;
}
return false;
}
@Contract(pure = true)
public static int compare(char c1, char c2, boolean ignoreCase) {
// duplicating String.equalsIgnoreCase logic
int d = c1 - c2;
if (d == 0 || !ignoreCase) {
return d;
}
// If characters don't match but case may be ignored,
// try converting both characters to uppercase.
// If the results match, then the comparison scan should
// continue.
char u1 = StringUtilRt.toUpperCase(c1);
char u2 = StringUtilRt.toUpperCase(c2);
d = u1 - u2;
if (d != 0) {
// Unfortunately, conversion to uppercase does not work properly
// for the Georgian alphabet, which has strange rules about case
// conversion. So we need to make one last check before
// exiting.
d = StringUtilRt.toLowerCase(u1) - StringUtilRt.toLowerCase(u2);
}
return d;
}
@Contract(pure = true)
public static boolean charsMatch(char c1, char c2, boolean ignoreCase) {
return compare(c1, c2, ignoreCase) == 0;
}
@NotNull
@Contract(pure = true)
public static String formatLinks(@NotNull String message) {
Pattern linkPattern = Pattern.compile("http://[a-zA-Z0-9./\\-+]+");
StringBuffer result = new StringBuffer();
Matcher m = linkPattern.matcher(message);
while (m.find()) {
m.appendReplacement(result, "" + m.group() + "");
}
m.appendTail(result);
return result.toString();
}
@Contract(pure = true)
public static boolean isHexDigit(char c) {
return '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F';
}
@Contract(pure = true)
public static boolean isOctalDigit(char c) {
return '0' <= c && c <= '7';
}
@NotNull
@Contract(pure = true)
public static String shortenTextWithEllipsis(@NotNull final String text, final int maxLength, final int suffixLength) {
return shortenTextWithEllipsis(text, maxLength, suffixLength, false);
}
@NotNull
@Contract(pure = true)
public static String trimMiddle(@NotNull String text, int maxLength) {
return shortenTextWithEllipsis(text, maxLength, maxLength >> 1, true);
}
@NotNull
@Contract(pure = true)
public static String shortenTextWithEllipsis(@NotNull final String text,
final int maxLength,
final int suffixLength,
@NotNull String symbol) {
final int textLength = text.length();
if (textLength > maxLength) {
final int prefixLength = maxLength - suffixLength - symbol.length();
assert prefixLength > 0;
return text.substring(0, prefixLength) + symbol + text.substring(textLength - suffixLength);
}
else {
return text;
}
}
@NotNull
@Contract(pure = true)
public static String shortenTextWithEllipsis(@NotNull final String text,
final int maxLength,
final int suffixLength,
boolean useEllipsisSymbol) {
String symbol = useEllipsisSymbol ? "\u2026" : "...";
return shortenTextWithEllipsis(text, maxLength, suffixLength, symbol);
}
@NotNull
@Contract(pure = true)
public static String shortenPathWithEllipsis(@NotNull final String path, final int maxLength, boolean useEllipsisSymbol) {
return shortenTextWithEllipsis(path, maxLength, (int)(maxLength * 0.7), useEllipsisSymbol);
}
@NotNull
@Contract(pure = true)
public static String shortenPathWithEllipsis(@NotNull final String path, final int maxLength) {
return shortenPathWithEllipsis(path, maxLength, false);
}
@Contract(pure = true)
public static boolean charsEqualIgnoreCase(char a, char b) {
return charsMatch(a, b, true);
}
@Contract(pure = true)
public static char toUpperCase(char a) {
return StringUtilRt.toUpperCase(a);
}
@Contract(value = "null -> null; !null -> !null", pure = true)
public static String toUpperCase(String a) {
if (a == null)
return null;
StringBuilder answer = null;
for (int i = 0; i < a.length(); i++) {
char c = a.charAt(i);
char upCased = toUpperCase(c);
if (answer == null && upCased != c) {
answer = new StringBuilder(a.length());
answer.append(a.subSequence(0, i));
}
if (answer != null) {
answer.append(upCased);
}
}
return answer == null ? a : answer.toString();
}
@Contract(pure = true)
public static char toLowerCase(final char a) {
return StringUtilRt.toLowerCase(a);
}
@Contract(pure = true)
public static boolean isUpperCase(@NotNull CharSequence sequence) {
for (int i = 0; i < sequence.length(); i++) {
if (!Character.isUpperCase(sequence.charAt(i))) return false;
}
return true;
}
@Nullable
public static LineSeparator detectSeparators(@NotNull CharSequence text) {
int index = indexOfAny(text, "\n\r");
if (index == -1) return null;
LineSeparator lineSeparator = getLineSeparatorAt(text, index);
if (lineSeparator == null) {
throw new AssertionError();
}
return lineSeparator;
}
@Nullable
public static LineSeparator getLineSeparatorAt(@NotNull CharSequence text, int index) {
if (index < 0 || index >= text.length()) {
return null;
}
char ch = text.charAt(index);
if (ch == '\r') {
return index + 1 < text.length() && text.charAt(index + 1) == '\n' ? LineSeparator.CRLF : LineSeparator.CR;
}
return ch == '\n' ? LineSeparator.LF : null;
}
@NotNull
@Contract(pure = true)
public static String convertLineSeparators(@NotNull String text) {
return StringUtilRt.convertLineSeparators(text);
}
@NotNull
@Contract(pure = true)
public static String convertLineSeparators(@NotNull String text, boolean keepCarriageReturn) {
return StringUtilRt.convertLineSeparators(text, keepCarriageReturn);
}
@NotNull
@Contract(pure = true)
public static String convertLineSeparators(@NotNull String text, @NotNull String newSeparator) {
return StringUtilRt.convertLineSeparators(text, newSeparator);
}
@NotNull
public static String convertLineSeparators(@NotNull String text, @NotNull String newSeparator, @Nullable int[] offsetsToKeep) {
return StringUtilRt.convertLineSeparators(text, newSeparator, offsetsToKeep);
}
@Contract(pure = true)
public static int parseInt(@Nullable String string, int defaultValue) {
return StringUtilRt.parseInt(string, defaultValue);
}
@NotNull
@Contract(pure = true)
public static String getShortName(@NotNull String fqName) {
return StringUtilRt.getShortName(fqName);
}
@NotNull
@Contract(pure = true)
public static String getShortName(@NotNull String fqName, char separator) {
return StringUtilRt.getShortName(fqName, separator);
}
/**
* Equivalent for {@code getShortName(fqName).equals(shortName)}, but could be faster.
*
* @param fqName fully-qualified name (dot-separated)
* @param shortName a short name, must not contain dots
* @return true if specified short name is a short name of fully-qualified name
*/
public static boolean isShortNameOf(@NotNull String fqName, @NotNull String shortName) {
if (fqName.length() < shortName.length()) return false;
if (fqName.length() == shortName.length()) return fqName.equals(shortName);
int diff = fqName.length() - shortName.length();
if (fqName.charAt(diff - 1) != '.') return false;
return fqName.regionMatches(diff, shortName, 0, shortName.length());
}
/**
* Strips class name from Object#toString if present.
* To be used as custom data type renderer for java.lang.Object.
* To activate just add {@code StringUtil.toShortString(this)}
* expression in Settings | Debugger | Data Views.
*/
@Contract("null->null;!null->!null")
@SuppressWarnings("UnusedDeclaration")
static String toShortString(@Nullable Object o) {
if (o == null) return null;
if (o instanceof CharSequence) return o.toString();
String className = o.getClass().getName();
String s = o.toString();
if (!s.startsWith(className)) return s;
return s.length() > className.length() && !Character.isLetter(s.charAt(className.length())) ?
trimStart(s, className) : s;
}
@NotNull
@Contract(pure = true)
public static CharSequence newBombedCharSequence(@NotNull CharSequence sequence, long delay) {
final long myTime = System.currentTimeMillis() + delay;
return new BombedCharSequence(sequence) {
@Override
protected void checkCanceled() {
long l = System.currentTimeMillis();
if (l >= myTime) {
throw new ProcessCanceledException();
}
}
};
}
public static boolean trimEnd(@NotNull StringBuilder buffer, @NotNull CharSequence end) {
if (endsWith(buffer, end)) {
buffer.delete(buffer.length() - end.length(), buffer.length());
return true;
}
return false;
}
/**
* Say smallPart = "op" and bigPart="open". Method returns true for "Ope" and false for "ops"
*/
@Contract(pure = true)
@SuppressWarnings("StringToUpperCaseOrToLowerCaseWithoutLocale")
public static boolean isBetween(@NotNull String string, @NotNull String smallPart, @NotNull String bigPart) {
final String s = string.toLowerCase();
return s.startsWith(smallPart.toLowerCase()) && bigPart.toLowerCase().startsWith(s);
}
/**
* Does the string have an uppercase character?
* @param s the string to test.
* @return true if the string has an uppercase character, false if not.
*/
public static boolean hasUpperCaseChar(String s) {
char[] chars = s.toCharArray();
for (char c : chars) {
if (Character.isUpperCase(c)) {
return true;
}
}
return false;
}
/**
* Does the string have a lowercase character?
* @param s the string to test.
* @return true if the string has a lowercase character, false if not.
*/
public static boolean hasLowerCaseChar(String s) {
char[] chars = s.toCharArray();
for (char c : chars) {
if (Character.isLowerCase(c)) {
return true;
}
}
return false;
}
private static final Pattern UNICODE_CHAR = Pattern.compile("\\\\u[0-9a-fA-F]{4}");
public static String replaceUnicodeEscapeSequences(String text) {
if (text == null) return null;
final Matcher matcher = UNICODE_CHAR.matcher(text);
if (!matcher.find()) return text; // fast path
matcher.reset();
int lastEnd = 0;
final StringBuilder sb = new StringBuilder(text.length());
while (matcher.find()) {
sb.append(text, lastEnd, matcher.start());
final char c = (char)Integer.parseInt(matcher.group().substring(2), 16);
sb.append(c);
lastEnd = matcher.end();
}
sb.append(text.substring(lastEnd));
return sb.toString();
}
/**
* Expirable CharSequence. Very useful to control external library execution time,
* i.e. when java.util.regex.Pattern match goes out of control.
*/
public abstract static class BombedCharSequence implements CharSequence {
private final CharSequence delegate;
private int i;
private boolean myDefused;
public BombedCharSequence(@NotNull CharSequence sequence) {
delegate = sequence;
}
@Override
public int length() {
check();
return delegate.length();
}
@Override
public char charAt(int i) {
check();
return delegate.charAt(i);
}
protected void check() {
if (myDefused) {
return;
}
if ((++i & 1023) == 0) {
checkCanceled();
}
}
public final void defuse() {
myDefused = true;
}
@NotNull
@Override
public String toString() {
check();
return delegate.toString();
}
protected abstract void checkCanceled();
@NotNull
@Override
public CharSequence subSequence(int i, int i1) {
check();
return delegate.subSequence(i, i1);
}
}
@Contract(pure = true)
@NotNull
public static String toHexString(@NotNull byte[] bytes) {
@SuppressWarnings("SpellCheckingInspection") String digits = "0123456789abcdef";
StringBuilder sb = new StringBuilder(2 * bytes.length);
for (byte b : bytes) sb.append(digits.charAt((b >> 4) & 0xf)).append(digits.charAt(b & 0xf));
return sb.toString();
}
@Contract(pure = true)
@NotNull
public static byte[] parseHexString(@NotNull String str) {
int len = str.length();
if (len % 2 != 0) throw new IllegalArgumentException("Non-even-length: " + str);
byte[] bytes = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
bytes[i / 2] = (byte)((Character.digit(str.charAt(i), 16) << 4) + Character.digit(str.charAt(i + 1), 16));
}
return bytes;
}
/** @deprecated use {@link #startsWithConcatenation(String, String...)} (to remove in IDEA 15) */
@Deprecated
public static boolean startsWithConcatenationOf(@NotNull String string, @NotNull String firstPrefix, @NotNull String secondPrefix) {
return startsWithConcatenation(string, firstPrefix, secondPrefix);
}
/**
* @return {@code true} if the passed string is not {@code null} and not empty
* and contains only latin upper- or lower-case characters and digits; {@code false} otherwise.
*/
@Contract(pure = true)
public static boolean isLatinAlphanumeric(@Nullable CharSequence str) {
if (isEmpty(str)) {
return false;
}
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || Character.isDigit(c)) {
continue;
}
return false;
}
return true;
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/util/SequentialModalProgressTask.java
================================================
package com.intellij.util;
import java.lang.reflect.InvocationTargetException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
public class SequentialModalProgressTask extends Task.Modal {
private static final Logger LOG = Logger.getInstance("#" + SequentialModalProgressTask.class.getName());
private static final long DEFAULT_MIN_ITERATION_MIN_TIME = 500;
/**
* We want to perform the task by big chunks at EDT. However, there is a
* possible case that particular task iteration is executed in short amount
* of time. Hence, we may want to execute more than one chunk during single
* EDT iteration. This field holds min amount of time (in milliseconds) to
* spend to performing the task.
*/
private long myMinIterationTime = DEFAULT_MIN_ITERATION_MIN_TIME;
private final String myTitle;
private ProgressIndicator myIndicator;
private SequentialTask myTask;
public SequentialModalProgressTask(@Nullable Project project, @NotNull String title) {
this(project, title, true);
}
public SequentialModalProgressTask(@Nullable Project project, @NotNull String title, boolean canBeCancelled) {
super(project, title, canBeCancelled);
myTitle = title;
}
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
doRun(indicator);
} catch (Exception e) {
LOG.info("Unexpected exception occurred during processing sequential task '" + myTitle + "'", e);
} finally {
indicator.stop();
}
}
public void doRun(@NotNull ProgressIndicator indicator) throws InvocationTargetException, InterruptedException {
final SequentialTask task = myTask;
if (task == null) {
return;
}
myIndicator = indicator;
prepare(task);
// We need to sync background thread and EDT here in order to avoid
// situation when event queue is full of processing requests.
while (!task.isDone()) {
if (indicator.isCanceled()) {
task.stop();
break;
}
long start = System.currentTimeMillis();
try {
while (!task.isDone() && System.currentTimeMillis() - start < myMinIterationTime) {
task.iteration();
}
} catch (RuntimeException e) {
task.stop();
throw e;
}
}
}
public void setMinIterationTime(long minIterationTime) {
myMinIterationTime = minIterationTime;
}
public void setTask(@Nullable SequentialTask task) {
myTask = task;
}
public ProgressIndicator getIndicator() {
return myIndicator;
}
/**
* Executes preliminary jobs prior to the target sequential task processing
* ({@link SequentialTask#prepare()} by default).
*
* @param task
* task to be executed
*/
protected void prepare(@NotNull SequentialTask task) {
task.prepare();
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/util/SequentialTask.java
================================================
package com.intellij.util;
public interface SequentialTask {
/**
* Callback method that is assumed to be called before the processing.
*/
void prepare();
/**
* @return true if the processing is complete;
* false otherwise
*/
boolean isDone();
/**
* Asks current task to perform one more processing iteration.
*
* @return true if the processing is done; false
* otherwise
*/
boolean iteration();
/**
* Asks current task to stop the processing (if any).
*/
void stop();
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/util/SingletonSet.java
================================================
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util;
import com.intellij.util.containers.SingletonIterator;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
/**
* Read-only set consisting of the only element
*/
public class SingletonSet implements Set {
private final E theElement;
public SingletonSet(E e) {
theElement = e;
}
@Override
public int size() {
return 1;
}
@Override
public boolean contains(Object elem) {
//noinspection unchecked
return getStrategy().equals(theElement, (E)elem);
}
@NotNull
@Override
public Iterator iterator() {
return new SingletonIterator<>(theElement);
}
@NotNull
@Override
public Object[] toArray() {
return new Object[]{theElement};
}
@NotNull
@Override
public T[] toArray(@NotNull T[] a) {
if (a.length == 0) {
a = ArrayUtil.newArray(ArrayUtil.getComponentType(a), 1);
}
//noinspection unchecked
a[0] = (T)theElement;
if (a.length > 1) {
a[1] = null;
}
return a;
}
@Override
public boolean add(E t) {
throw new IncorrectOperationException();
}
@Override
public boolean remove(Object o) {
throw new IncorrectOperationException();
}
@Override
public boolean containsAll(@NotNull Collection> c) {
for (Object e : c) {
if (!contains(e)) {
return false;
}
}
return true;
}
@Override
public boolean addAll(@NotNull Collection extends E> c) {
throw new IncorrectOperationException();
}
@Override
public boolean retainAll(@NotNull Collection> c) {
throw new IncorrectOperationException();
}
@Override
public boolean removeAll(@NotNull Collection> c) {
throw new IncorrectOperationException();
}
@Override
public void clear() {
throw new IncorrectOperationException();
}
@Override
public boolean isEmpty() {
return false;
}
@NotNull
protected TObjectHashingStrategy getStrategy() {
//noinspection unchecked
return TObjectHashingStrategy.CANONICAL;
}
@NotNull
public static Set withCustomStrategy(T o, @NotNull TObjectHashingStrategy strategy) {
return new CustomStrategySingletonSet<>(o, strategy);
}
private static class CustomStrategySingletonSet extends SingletonSet {
@NotNull private final TObjectHashingStrategy strategy;
private CustomStrategySingletonSet(E e, @NotNull final TObjectHashingStrategy strategy) {
super(e);
this.strategy = strategy;
}
@Override
@NotNull
protected TObjectHashingStrategy getStrategy() {
return strategy;
}
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/util/containers/LinkedMultiMap.java
================================================
package com.intellij.util.containers;
@Deprecated
public class LinkedMultiMap extends MultiMap {
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/util/containers/MultiMap.java
================================================
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.containers;
import com.intellij.util.SmartList;
import gnu.trove.THashMap;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.Serializable;
import java.util.HashMap;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Consider to use factory methods {@link #createLinked()}, {@link #createSet()}, {@link #createSmart()}, {@link #create(TObjectHashingStrategy)} instead of override.
* @see BidirectionalMultiMap
* @see ConcurrentMultiMap
* @author Dmitry Avdeev
*/
public class MultiMap implements Serializable {
public static final MultiMap EMPTY = new EmptyMap();
private static final long serialVersionUID = -2632269270151455493L;
protected final Map> myMap;
private Collection values;
public MultiMap() {
myMap = createMap();
}
public MultiMap(@NotNull Map> mapImpl) {
myMap = mapImpl;
}
public MultiMap(@NotNull MultiMap extends K, ? extends V> toCopy) {
this();
putAllValues(toCopy);
}
@NotNull
public MultiMap copy() {
return new MultiMap<>(this);
}
public MultiMap(int initialCapacity, float loadFactor) {
myMap = createMap(initialCapacity, loadFactor);
}
@NotNull
protected Map> createMap() {
return new java.util.HashMap>();
}
@NotNull
protected Map> createMap(int initialCapacity, float loadFactor) {
return new HashMap>(initialCapacity, loadFactor);
}
@NotNull
protected Collection createCollection() {
return new SmartList();
}
@NotNull
protected Collection createEmptyCollection() {
return Collections.emptyList();
}
public void putAllValues(@NotNull MultiMap extends K, ? extends V> from) {
for (Map.Entry extends K, ? extends Collection extends V>> entry : from.entrySet()) {
putValues(entry.getKey(), entry.getValue());
}
}
public void putAllValues(@NotNull Map extends K, ? extends V> from) {
for (Map.Entry extends K, ? extends V> entry : from.entrySet()) {
putValue(entry.getKey(), entry.getValue());
}
}
public void putValues(K key, @NotNull Collection extends V> values) {
Collection list = myMap.get(key);
if (list == null) {
list = createCollection();
myMap.put(key, list);
}
list.addAll(values);
}
public void putValue(@Nullable K key, V value) {
Collection list = myMap.get(key);
if (list == null) {
list = createCollection();
myMap.put(key, list);
}
list.add(value);
}
@NotNull
public Set>> entrySet() {
return myMap.entrySet();
}
public boolean isEmpty() {
if (myMap.isEmpty()) return true;
for(Collection valueList: myMap.values()) {
if (!valueList.isEmpty()) {
return false;
}
}
return true;
}
public boolean containsKey(K key) {
return myMap.containsKey(key);
}
public boolean containsScalarValue(V value) {
for(Collection valueList: myMap.values()) {
if (valueList.contains(value)) {
return true;
}
}
return false;
}
@NotNull
public Collection get(final K key) {
final Collection collection = myMap.get(key);
return collection == null ? createEmptyCollection() : collection;
}
@NotNull
public Collection getModifiable(final K key) {
Collection collection = myMap.get(key);
if (collection == null) {
myMap.put(key, collection = createCollection());
}
return collection;
}
@NotNull
public Set keySet() {
return myMap.keySet();
}
public int size() {
return myMap.size();
}
public void put(final K key, Collection values) {
myMap.put(key, values);
}
/**
* @deprecated use {@link #remove(Object, Object)} instead
*/
@Deprecated
public void removeValue(K key, V value) {
remove(key, value);
}
public boolean remove(final K key, final V value) {
final Collection values = myMap.get(key);
if (values != null) {
boolean removed = values.remove(value);
if (values.isEmpty()) {
myMap.remove(key);
}
return removed;
}
return false;
}
@NotNull
public Collection extends V> values() {
if (values == null) {
values = new AbstractCollection() {
@NotNull
@Override
public Iterator iterator() {
return new Iterator() {
private final Iterator> mapIterator = myMap.values().iterator();
private Iterator itr = EmptyIterator.getInstance();
@Override
public boolean hasNext() {
do {
if (itr.hasNext()) return true;
if (!mapIterator.hasNext()) return false;
itr = mapIterator.next().iterator();
} while (true);
}
@Override
public V next() {
do {
if (itr.hasNext()) return itr.next();
if (!mapIterator.hasNext()) throw new NoSuchElementException();
itr = mapIterator.next().iterator();
} while (true);
}
@Override
public void remove() {
itr.remove();
}
};
}
@Override
public int size() {
int res = 0;
for (Collection vs : myMap.values()) {
res += vs.size();
}
return res;
}
// Don't remove this method!!!
@Override
public boolean contains(Object o) {
for (Collection vs : myMap.values()) {
if (vs.contains(o)) return true;
}
return false;
}
};
}
return values;
}
public void clear() {
myMap.clear();
}
@Nullable
public Collection remove(K key) {
return myMap.remove(key);
}
@NotNull
public static MultiMap emptyInstance() {
@SuppressWarnings("unchecked") final MultiMap empty = EMPTY;
return empty;
}
/**
* Null keys supported.
*/
@NotNull
public static MultiMap create() {
return new MultiMap();
}
@NotNull
public static MultiMap create(@NotNull final TObjectHashingStrategy strategy) {
return new MultiMap() {
@NotNull
@Override
protected Map> createMap() {
return new THashMap>(strategy);
}
};
}
@NotNull
public static MultiMap createLinked() {
return new LinkedMultiMap();
}
@NotNull
public static MultiMap createLinkedSet() {
return new LinkedMultiMap() {
@NotNull
@Override
protected Collection createCollection() {
return new LinkedHashSet();
}
@NotNull
@Override
protected Collection createEmptyCollection() {
return Collections.emptySet();
}
};
}
@NotNull
public static MultiMap createOrderedSet() {
return new LinkedMultiMap() {
@NotNull
@Override
protected Collection createCollection() {
return new OrderedSet();
}
@NotNull
@Override
protected Collection createEmptyCollection() {
return Collections.emptySet();
}
};
}
@NotNull
public static MultiMap createSmart() {
return new MultiMap() {
@NotNull
@Override
protected Map> createMap() {
return new THashMap>();
}
};
}
@NotNull
public static MultiMap createConcurrent() {
return new MultiMap(new ConcurrentHashMap<>()) {
@NotNull
protected Collection createCollection() {
return ContainerUtil.createLockFreeCopyOnWriteList();
}
};
}
@NotNull
public static MultiMap createConcurrentSet() {
return new ConcurrentMultiMap() {
@NotNull
@Override
protected Collection createCollection() {
return Collections.newSetFromMap(new ConcurrentHashMap<>());
}
@NotNull
@Override
protected Collection createEmptyCollection() {
return Collections.emptySet();
}
};
}
@NotNull
public static MultiMap createSet() {
return createSet(ContainerUtil.canonicalStrategy());
}
@NotNull
public static MultiMap createSet(@NotNull final TObjectHashingStrategy strategy) {
return new MultiMap() {
@NotNull
@Override
protected Collection createCollection() {
return new SmartHashSet();
}
@NotNull
@Override
protected Collection createEmptyCollection() {
return Collections.emptySet();
}
@NotNull
@Override
protected Map> createMap() {
return new THashMap>(strategy);
}
};
}
@NotNull
public static MultiMap createWeakKey() {
return new MultiMap() {
@NotNull
@Override
protected Map> createMap() {
return ContainerUtil.createWeakMap();
}
};
}
public static MultiMap create(int initialCapacity, float loadFactor) {
return new MultiMap(initialCapacity, loadFactor);
}
@Override
public boolean equals(Object o) {
return this == o || o instanceof MultiMap && myMap.equals(((MultiMap)o).myMap);
}
@Override
public int hashCode() {
return myMap.hashCode();
}
@Override
public String toString() {
return new java.util.HashMap>(myMap).toString();
}
/**
* @return immutable empty multi-map
*/
public static MultiMap empty() {
//noinspection unchecked
return EMPTY;
}
private static class EmptyMap extends MultiMap {
@NotNull
@Override
protected Map createMap() {
return Collections.emptyMap();
}
@Override
public void putValues(Object key, @NotNull Collection values) {
throw new UnsupportedOperationException();
}
@Override
public void putValue(@Nullable Object key, Object value) {
throw new UnsupportedOperationException();
}
@Override
public void put(Object key, Collection values) {
throw new UnsupportedOperationException();
}
@Override
public boolean remove(Object key, Object value) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
throw new UnsupportedOperationException();
}
@Nullable
@Override
public Collection remove(Object key) {
throw new UnsupportedOperationException();
}
}
}
================================================
FILE: kotlin-bundled-compiler/src/com/intellij/util/containers/ObjectIntHashMap.java
================================================
package com.intellij.util.containers;
import gnu.trove.TObjectHashingStrategy;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
public class ObjectIntHashMap extends TObjectIntHashMap implements ObjectIntMap {
public ObjectIntHashMap(int initialCapacity) {
super(initialCapacity);
}
public ObjectIntHashMap(@NotNull TObjectHashingStrategy strategy) {
super(strategy);
}
public ObjectIntHashMap(int initialCapacity, @NotNull TObjectHashingStrategy strategy) {
super(initialCapacity, strategy);
}
public ObjectIntHashMap() {
super();
}
public final int get(@NotNull K key) {
return this.get(key, -1);
}
@Override
public @NotNull
Set keySet() {
return Collections.emptySet();
}
@NotNull
@Override
public int[] values() {
return Arrays.copyOf(_values, _values.length);
}
@Override
public @NotNull
Iterable> entries() {
return Collections.emptySet();
}
public final int get(K key, int defaultValue) {
int index = this.index(key);
return index < 0 ? defaultValue : this._values[index];
}
public int put(K key, int value, int defaultValue) {
int index = this.index(key);
int prev = super.put(key, value);
return index >= 0 ? prev : defaultValue;
}
}
================================================
FILE: kotlin-bundled-compiler/src/it/unimi/dsi/fastutil/ints/IntOpenHashSet.java
================================================
package it.unimi.dsi.fastutil.ints;
import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.HashCommon;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.NoSuchElementException;
public class IntOpenHashSet extends AbstractIntSet implements Hash, Serializable, Cloneable {
private static final long serialVersionUID = 0L;
protected transient int[] key;
protected transient int mask;
protected transient boolean containsNull;
protected transient int n;
protected transient int maxFill;
protected final transient int minN;
protected int size;
protected final float f;
public IntOpenHashSet(int expected, float f) {
if (!(f <= 0.0F) && !(f >= 1.0F)) {
if (expected < 0) {
throw new IllegalArgumentException("The expected number of elements must be nonnegative");
} else {
this.f = f;
this.minN = this.n = HashCommon.arraySize(expected, f);
this.mask = this.n - 1;
this.maxFill = HashCommon.maxFill(this.n, f);
this.key = new int[this.n + 1];
}
} else {
throw new IllegalArgumentException("Load factor must be greater than 0 and smaller than 1");
}
}
public IntOpenHashSet(int expected) {
this(expected, 0.75F);
}
public IntOpenHashSet() {
this(16, 0.75F);
}
private int realSize() {
return this.containsNull ? this.size - 1 : this.size;
}
private void ensureCapacity(int capacity) {
int needed = HashCommon.arraySize(capacity, this.f);
if (needed > this.n) {
this.rehash(needed);
}
}
private void tryCapacity(long capacity) {
int needed = (int)Math.min(1073741824L, Math.max(2L, HashCommon.nextPowerOfTwo((long)Math.ceil((double)((float)capacity / this.f)))));
if (needed > this.n) {
this.rehash(needed);
}
}
public boolean addAll(Collection extends Integer> c) {
if ((double)this.f <= 0.5D) {
this.ensureCapacity(c.size());
} else {
this.tryCapacity((long)(this.size() + c.size()));
}
return super.addAll(c);
}
public boolean add(int k) {
if (k == 0) {
if (this.containsNull) {
return false;
}
this.containsNull = true;
} else {
int[] key = this.key;
int pos;
int curr;
if ((curr = key[pos = HashCommon.mix(k) & this.mask]) != 0) {
if (curr == k) {
return false;
}
while((curr = key[pos = pos + 1 & this.mask]) != 0) {
if (curr == k) {
return false;
}
}
}
key[pos] = k;
}
if (this.size++ >= this.maxFill) {
this.rehash(HashCommon.arraySize(this.size + 1, this.f));
}
return true;
}
protected final void shiftKeys(int pos) {
int[] key = this.key;
while(true) {
int last = pos;
pos = pos + 1 & this.mask;
int curr;
while(true) {
if ((curr = key[pos]) == 0) {
key[last] = 0;
return;
}
int slot = HashCommon.mix(curr) & this.mask;
if (last <= pos) {
if (last >= slot || slot > pos) {
break;
}
} else if (last >= slot && slot > pos) {
break;
}
pos = pos + 1 & this.mask;
}
key[last] = curr;
}
}
private boolean removeEntry(int pos) {
--this.size;
this.shiftKeys(pos);
if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) {
this.rehash(this.n / 2);
}
return true;
}
private boolean removeNullEntry() {
this.containsNull = false;
this.key[this.n] = 0;
--this.size;
if (this.n > this.minN && this.size < this.maxFill / 4 && this.n > 16) {
this.rehash(this.n / 2);
}
return true;
}
public boolean remove(int k) {
if (k == 0) {
return this.containsNull ? this.removeNullEntry() : false;
} else {
int[] key = this.key;
int curr;
int pos;
if ((curr = key[pos = HashCommon.mix(k) & this.mask]) == 0) {
return false;
} else if (k == curr) {
return this.removeEntry(pos);
} else {
while((curr = key[pos = pos + 1 & this.mask]) != 0) {
if (k == curr) {
return this.removeEntry(pos);
}
}
return false;
}
}
}
public boolean contains(int k) {
if (k == 0) {
return this.containsNull;
} else {
int[] key = this.key;
int curr;
int pos;
if ((curr = key[pos = HashCommon.mix(k) & this.mask]) == 0) {
return false;
} else if (k == curr) {
return true;
} else {
while((curr = key[pos = pos + 1 & this.mask]) != 0) {
if (k == curr) {
return true;
}
}
return false;
}
}
}
public void clear() {
if (this.size != 0) {
this.size = 0;
this.containsNull = false;
Arrays.fill(this.key, 0);
}
}
public int size() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
public IntIterator iterator() {
return new IntOpenHashSet.SetIterator();
}
protected void rehash(int newN) {
int[] key = this.key;
int mask = newN - 1;
int[] newKey = new int[newN + 1];
int i = this.n;
int pos;
for(int var7 = this.realSize(); var7-- != 0; newKey[pos] = key[i]) {
do {
--i;
} while(key[i] == 0);
if (newKey[pos = HashCommon.mix(key[i]) & mask] != 0) {
while(newKey[pos = pos + 1 & mask] != 0) {
}
}
}
this.n = newN;
this.mask = mask;
this.maxFill = HashCommon.maxFill(this.n, this.f);
this.key = newKey;
}
public IntOpenHashSet clone() {
IntOpenHashSet c;
try {
c = (IntOpenHashSet)super.clone();
} catch (CloneNotSupportedException var3) {
throw new InternalError();
}
c.key = (int[])this.key.clone();
c.containsNull = this.containsNull;
return c;
}
public int hashCode() {
int h = 0;
int j = this.realSize();
for(int i = 0; j-- != 0; ++i) {
while(this.key[i] == 0) {
++i;
}
h += this.key[i];
}
return h;
}
private class SetIterator implements IntIterator {
int pos;
int last;
int c;
boolean mustReturnNull;
IntArrayList wrapped;
private SetIterator() {
this.pos = IntOpenHashSet.this.n;
this.last = -1;
this.c = IntOpenHashSet.this.size;
this.mustReturnNull = IntOpenHashSet.this.containsNull;
}
public boolean hasNext() {
return this.c != 0;
}
public int nextInt() {
if (!this.hasNext()) {
throw new NoSuchElementException();
} else {
--this.c;
if (this.mustReturnNull) {
this.mustReturnNull = false;
this.last = IntOpenHashSet.this.n;
return IntOpenHashSet.this.key[IntOpenHashSet.this.n];
} else {
int[] key = IntOpenHashSet.this.key;
while(--this.pos >= 0) {
if (key[this.pos] != 0) {
return key[this.last = this.pos];
}
}
this.last = -2147483648;
return this.wrapped.getInt(-this.pos - 1);
}
}
}
private final void shiftKeys(int pos) {
int[] key = IntOpenHashSet.this.key;
while(true) {
int last = pos;
pos = pos + 1 & IntOpenHashSet.this.mask;
int curr;
while(true) {
if ((curr = key[pos]) == 0) {
key[last] = 0;
return;
}
int slot = HashCommon.mix(curr) & IntOpenHashSet.this.mask;
if (last <= pos) {
if (last >= slot || slot > pos) {
break;
}
} else if (last >= slot && slot > pos) {
break;
}
pos = pos + 1 & IntOpenHashSet.this.mask;
}
if (pos < last) {
if (this.wrapped == null) {
this.wrapped = new IntArrayList(2);
}
this.wrapped.add(key[pos]);
}
key[last] = curr;
}
}
public void remove() {
if (this.last == -1) {
throw new IllegalStateException();
} else {
if (this.last == IntOpenHashSet.this.n) {
IntOpenHashSet.this.containsNull = false;
IntOpenHashSet.this.key[IntOpenHashSet.this.n] = 0;
} else {
if (this.pos < 0) {
IntOpenHashSet.this.remove(this.wrapped.getInt(-this.pos - 1));
this.last = -1;
return;
}
this.shiftKeys(this.last);
}
--IntOpenHashSet.this.size;
this.last = -1;
}
}
}
}
================================================
FILE: kotlin-bundled-compiler/src/org/jetbrains/kotlin/idea/core/formatter/KotlinPackageEntry.kt
================================================
package org.jetbrains.kotlin.idea.core.formatter
class KotlinPackageEntry(
packageName: String,
val withSubpackages: Boolean
) {
val packageName = packageName.removeSuffix(".*")
companion object {
@JvmField
val ALL_OTHER_IMPORTS_ENTRY =
KotlinPackageEntry("import all other imports", withSubpackages = true)
@JvmField
val ALL_OTHER_ALIAS_IMPORTS_ENTRY = KotlinPackageEntry("", withSubpackages = true)
}
fun matchesPackageName(otherPackageName: String): Boolean {
if (otherPackageName.startsWith(packageName)) {
if (otherPackageName.length == packageName.length) return true
if (withSubpackages) {
if (otherPackageName[packageName.length] == '.') return true
}
}
return false
}
val isSpecial: Boolean get() = this == ALL_OTHER_IMPORTS_ENTRY || this == ALL_OTHER_ALIAS_IMPORTS_ENTRY
override fun toString(): String {
return packageName
}
}
================================================
FILE: kotlin-eclipse-aspects/META-INF/MANIFEST.MF
================================================
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: kotlin-eclipse-aspects
Bundle-SymbolicName: org.jetbrains.kotlin.aspects
Bundle-Version: 0.8.24.qualifier
Bundle-Activator: org.jetbrains.kotlin.aspects.Activator
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.aspectj.runtime,
org.jetbrains.kotlin.core,
org.eclipse.jdt.ui,
org.eclipse.pde.launching,
org.eclipse.jdt.core,
org.eclipse.ltk.core.refactoring,
org.jetbrains.kotlin.ui,
org.eclipse.debug.core,
org.eclipse.jdt.debug,
org.eclipse.jdt.core.manipulation
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-ActivationPolicy: lazy
Bundle-Vendor: JetBrains
Import-Package: org.eclipse.core.resources,
org.eclipse.debug.core,
org.eclipse.debug.core.sourcelookup,
org.eclipse.jdt.core,
org.eclipse.jdt.debug.core,
org.eclipse.jdt.internal.core,
org.eclipse.jdt.internal.debug.core,
org.eclipse.jdt.internal.debug.core.refactoring,
org.eclipse.jdt.internal.debug.ui,
org.eclipse.jdt.internal.ui.packageview,
org.eclipse.jdt.internal.ui.viewsupport,
org.eclipse.jdt.launching,
org.eclipse.jdt.launching.sourcelookup.containers,
org.eclipse.jface.text,
org.eclipse.swt.graphics,
org.eclipse.ui.ide
Eclipse-SupplementBundle:
org.eclipse.jdt.debug.ui,
org.eclipse.jdt.debug,
org.eclipse.jdt.launching,
org.eclipse.jdt.ui,
org.eclipse.jdt.internal.debug.core,
org.eclipse.debug.core,
org.eclipse.pde.launching,
org.eclipse.jdt.core
Export-Package: org.jetbrains.kotlin.aspects.debug.ui,
org.jetbrains.kotlin.aspects.debug.core,
org.jetbrains.kotlin.aspects.navigation,
org.jetbrains.kotlin.aspects.refactoring,
org.jetbrains.kotlin.aspects.ui
================================================
FILE: kotlin-eclipse-aspects/META-INF/aop.xml
================================================
================================================
FILE: kotlin-eclipse-aspects/build.properties
================================================
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.
================================================
FILE: kotlin-eclipse-aspects/pom.xml
================================================
4.0.0
../pom.xml
kotlin.eclipse
kotlin.eclipse.plugin
0.8.24-SNAPSHOT
org.jetbrains.kotlin.aspects
eclipse-plugin
org.eclipse.tycho
tycho-compiler-plugin
**/*.aj
org.codehaus.mojo
aspectj-maven-plugin
1.14.0
process-sources
compile
16
16
src
ignore
true
compile
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/Activator.java
================================================
package org.jetbrains.kotlin.aspects;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.jetbrains.kotlin.aspects"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/debug/core/KotlinSourceLookupAspect.aj
================================================
package org.jetbrains.kotlin.aspects.debug.core;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.core.resources.IFile;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.jetbrains.kotlin.core.debug.KotlinSourceLookupNavigator;
public aspect KotlinSourceLookupAspect {
pointcut getSourceElement(Object object) :
args(object)
&& execution(Object ISourceLookupDirector.getSourceElement(Object));
@SuppressAjWarnings({"adviceDidNotMatch"})
Object around(Object object) : getSourceElement(object) {
Object result = proceed(object);
if (result instanceof IFile) {
String fileName = ((IFile) result).getName();
if (JavaCore.isJavaLikeFileName(fileName)) {
return result;
}
}
if (object instanceof IJavaStackFrame) {
IJavaStackFrame frame = (IJavaStackFrame) object;
IFile kotlinSourceFile = KotlinSourceLookupNavigator.INSTANCE.findKotlinSourceFile(frame);
return kotlinSourceFile != null ? kotlinSourceFile : result;
}
return result;
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/debug/core/KotlinStackFrameFilterAspect.aj
================================================
package org.jetbrains.kotlin.aspects.debug.core;
import java.util.stream.Stream;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IVariable;
import org.jetbrains.kotlin.core.utils.DebugUtils;
public aspect KotlinStackFrameFilterAspect {
pointcut getVariables(IStackFrame receiver) :
execution(* IStackFrame.getVariables()) &&
target(receiver);
@SuppressAjWarnings({ "adviceDidNotMatch" })
IVariable[] around(IStackFrame receiver) throws DebugException : getVariables(receiver) {
IVariable[] result = proceed(receiver);
if (DebugUtils.hasKotlinSource(receiver)) {
result = Stream.of(result)
.filter(DebugUtils::isVisible)
.toArray(IVariable[]::new);
}
return result;
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/debug/ui/SuppressBreakpointMarkerUpdaterAspect.aj
================================================
package org.jetbrains.kotlin.aspects.debug.ui;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.jdt.internal.debug.ui.BreakpointMarkerUpdater;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.jetbrains.kotlin.ui.builder.AspectsUtils;
public aspect SuppressBreakpointMarkerUpdaterAspect {
pointcut updateMarker(BreakpointMarkerUpdater markerUpdater, IMarker marker, IDocument document, Position position):
args(marker, document, position)
&& execution(boolean BreakpointMarkerUpdater.updateMarker(IMarker, IDocument, Position))
&& target(markerUpdater);
@SuppressAjWarnings({"adviceDidNotMatch"})
boolean around(BreakpointMarkerUpdater markerUpdater, IMarker marker, IDocument document, Position position):
updateMarker(markerUpdater, marker, document, position) {
IFile resource = (IFile) marker.getResource();
if (resource != null && (AspectsUtils.existsSourceFile(resource) || AspectsUtils.isScript(resource))) {
return true;
}
return proceed(markerUpdater, marker, document, position);
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/navigation/KotlinFindSourceAspect.aj
================================================
package org.jetbrains.kotlin.aspects.navigation;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.core.SourceMapper;
import org.jetbrains.kotlin.core.resolve.KotlinSourceIndex;
@SuppressWarnings("restriction")
public aspect KotlinFindSourceAspect {
pointcut findSource(SourceMapper mapper, IType type, String simpleSourceFileName) :
target(mapper) &&
args(type, simpleSourceFileName)
&& call(char[] findSource(IType, String));
char[] around(SourceMapper mapper, IType type, String simpleSourceFileName) : findSource(mapper, type, simpleSourceFileName) {
char[] result = proceed(mapper, type, simpleSourceFileName);
if (result == null && KotlinSourceIndex.isKotlinSource(simpleSourceFileName)) {
return KotlinSourceIndex.getSource(mapper, type, simpleSourceFileName);
}
return result;
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/navigation/KotlinOpenEditorAspect.aj
================================================
package org.jetbrains.kotlin.aspects.navigation;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.ui.IEditorPart;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
import org.jetbrains.kotlin.ui.navigation.KotlinOpenEditor;
public aspect KotlinOpenEditorAspect {
pointcut openInEditor(Object inputElement, boolean activate) :
args(inputElement, activate)
&& execution(IEditorPart EditorUtility.openInEditor(Object, boolean));
@SuppressAjWarnings({"adviceDidNotMatch"})
IEditorPart around(Object inputElement, boolean activate) : openInEditor(inputElement, activate) {
if (inputElement instanceof IJavaElement) {
IJavaElement javaElement = (IJavaElement) inputElement;
if (EclipseJavaElementUtil.isKotlinLightClass(javaElement)) {
return KotlinOpenEditor.openKotlinEditor(javaElement, activate);
}
if (EclipseJavaElementUtil.isKotlinBinaryElement(javaElement)) {
return KotlinOpenEditor.openKotlinClassFileEditor(javaElement, activate);
}
}
return proceed(inputElement, activate);
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/navigation/KotlinSearchEditorOpenerAspect.aj
================================================
package org.jetbrains.kotlin.aspects.navigation;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
import org.eclipse.jdt.internal.ui.search.JavaSearchEditorOpener;
import org.eclipse.ui.IEditorPart;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
import org.jetbrains.kotlin.ui.navigation.KotlinOpenEditor;
public aspect KotlinSearchEditorOpenerAspect {
pointcut openElement(Object element) :
args(element)
&& execution(IEditorPart JavaSearchEditorOpener.openElement(Object));
@SuppressAjWarnings({"adviceDidNotMatch"})
IEditorPart around(Object element) : openElement(element) {
if (element instanceof IJavaElement) {
IJavaElement javaElement = (IJavaElement) element;
if (EclipseJavaElementUtil.isKotlinLightClass(javaElement)) {
IEditorPart kotlinEditor = KotlinOpenEditor.openKotlinEditor(javaElement, true);
EditorUtility.revealInEditor(kotlinEditor, javaElement);
return null;
}
}
return proceed(element);
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/refactoring/KotlinBinaryReferencesAspect.aj
================================================
package org.jetbrains.kotlin.aspects.refactoring;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
@SuppressWarnings("restriction")
public aspect KotlinBinaryReferencesAspect {
pointcut addErrorIfNecessary(RefactoringStatus status) :
args(status)
&& execution(void ReferencesInBinaryContext.addErrorIfNecessary(RefactoringStatus));
// JDT report about error if there are binary references for rename
@SuppressAjWarnings({"adviceDidNotMatch"})
void around(RefactoringStatus status) : addErrorIfNecessary(status) {
ReferencesInBinaryContext targetObject = (ReferencesInBinaryContext) thisJoinPoint.getTarget();
boolean hasKotlinReference = false;
for (SearchMatch match : targetObject.getMatches()) {
Object element = match.getElement();
if (element instanceof IJavaElement && EclipseJavaElementUtil.isKotlinLightClass((IJavaElement) element)) {
hasKotlinReference = true;
break;
}
}
if (!hasKotlinReference) {
proceed(status);
}
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/refactoring/KotlinBreakpointRenamingParticipantAspect.aj
================================================
package org.jetbrains.kotlin.aspects.refactoring;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.internal.debug.core.refactoring.BreakpointChange;
import org.jetbrains.kotlin.ui.builder.AspectsUtils;
@SuppressWarnings("restriction")
public aspect KotlinBreakpointRenamingParticipantAspect {
pointcut findElement(IJavaElement parent, IJavaElement element):
args(parent, element)
&& execution(IJavaElement BreakpointChange.findElement(IJavaElement, IJavaElement));
// BreakpointRenameParticipant operates with compilation unit to rename breakpoint configuration
// Thus we disable it for Kotlin files
@SuppressAjWarnings({"adviceDidNotMatch"})
IJavaElement around(IJavaElement parent, IJavaElement element): findElement(parent, element) {
IResource resource = parent.getResource();
if (resource instanceof IFile && AspectsUtils.isKotlinFile((IFile) resource)) {
return null;
}
return proceed(parent, element);
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/refactoring/KotlinJavaDescriptorAspect.aj
================================================
package org.jetbrains.kotlin.aspects.refactoring;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.internal.corext.refactoring.JavaRefactoringDescriptorUtil;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
import org.jetbrains.kotlin.ui.refactorings.rename.KotlinLightElementsFactory;
public aspect KotlinJavaDescriptorAspect {
pointcut handleToElement(final WorkingCopyOwner owner, final String project, final String handle, final boolean check) :
args(owner, project, handle, check)
&& execution(IJavaElement JavaRefactoringDescriptorUtil.handleToElement(WorkingCopyOwner, String, String, boolean));
@SuppressAjWarnings({"adviceDidNotMatch"})
IJavaElement around(final WorkingCopyOwner owner, final String project, final String handle, final boolean check) :
handleToElement(owner, project, handle, check) {
IJavaElement javaElement = proceed(owner, project, handle, check);
if (EclipseJavaElementUtil.isKotlinLightClass(javaElement)) {
return KotlinLightElementsFactory.createLightElement(javaElement);
}
return javaElement;
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/refactoring/KotlinRefactoringChecksAspect.aj
================================================
package org.jetbrains.kotlin.aspects.refactoring;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.internal.corext.refactoring.Checks;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
public aspect KotlinRefactoringChecksAspect {
pointcut checkIfCuBroken(IMember member) :
args(member)
&& execution(RefactoringStatus Checks.checkIfCuBroken(IMember));
// Disable checking of compilation unit for Kotlin files
@SuppressAjWarnings({"adviceDidNotMatch"})
RefactoringStatus around(IMember member) : checkIfCuBroken(member) {
if (EclipseJavaElementUtil.isKotlinLightClass(member)) {
return new RefactoringStatus();
}
return proceed(member);
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/refactoring/KotlinRefactoringTypeAspect.aj
================================================
package org.jetbrains.kotlin.aspects.refactoring;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameTypeProcessor;
import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
@SuppressWarnings("restriction")
public aspect KotlinRefactoringTypeAspect {
pointcut addTypeDeclarationUpdate(TextChangeManager manager) :
args(manager)
&& execution(void RenameTypeProcessor.addTypeDeclarationUpdate(TextChangeManager));
// Prohibit renaming Kotlin type declaration from JDT
@SuppressAjWarnings({"adviceDidNotMatch"})
void around(TextChangeManager manager) : addTypeDeclarationUpdate(manager) {
try {
Method method = RenameTypeProcessor.class.getDeclaredMethod("getType");
IType type = (IType) method.invoke(thisJoinPoint.getTarget());
if (!EclipseJavaElementUtil.isKotlinLightClass(type)) {
proceed(manager);
}
} catch (NoSuchMethodException | SecurityException | IllegalAccessException |
IllegalArgumentException | InvocationTargetException e) {
// skip
}
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/refactoring/KotlinRemoveDeclarationUpdateAspect.aj
================================================
package org.jetbrains.kotlin.aspects.refactoring;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.jdt.internal.corext.refactoring.rename.RenameNonVirtualMethodProcessor;
import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
@SuppressWarnings("restriction")
public aspect KotlinRemoveDeclarationUpdateAspect {
pointcut addDeclarationUpdate(TextChangeManager manager) :
args(manager)
&& execution(void RenameNonVirtualMethodProcessor.addDeclarationUpdate(TextChangeManager));
// Prohibit renaming Kotlin method declaration from JDT
@SuppressAjWarnings({"adviceDidNotMatch"})
void around(TextChangeManager manager) : addDeclarationUpdate(manager) {
RenameNonVirtualMethodProcessor processor = (RenameNonVirtualMethodProcessor) thisJoinPoint.getTarget();
if (EclipseJavaElementUtil.isKotlinLightClass(processor.getMethod())) {
return;
}
proceed(manager);
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/refactoring/KotlinRenameFromJavaAspect.aj
================================================
package org.jetbrains.kotlin.aspects.refactoring;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.internal.ui.refactoring.actions.RenameJavaElementAction;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
import org.jetbrains.kotlin.ui.refactorings.rename.KotlinLightElementsFactory;
public aspect KotlinRenameFromJavaAspect {
pointcut getJavaElementFromEditor() :
args()
&& execution(IJavaElement RenameJavaElementAction.getJavaElementFromEditor());
@SuppressAjWarnings({"adviceDidNotMatch"})
IJavaElement around() : getJavaElementFromEditor() {
IJavaElement javaElement = proceed();
if (EclipseJavaElementUtil.isKotlinLightClass(javaElement)) {
return KotlinLightElementsFactory.createLightElement(javaElement);
}
return javaElement;
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/refactoring/KotlinRippleMethodFinderAspect.aj
================================================
package org.jetbrains.kotlin.aspects.refactoring;
import org.aspectj.lang.annotation.SuppressAjWarnings;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.WorkingCopyOwner;
import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext;
import org.eclipse.jdt.internal.corext.refactoring.rename.RippleMethodFinder2;
import org.jetbrains.kotlin.core.resolve.lang.java.structure.EclipseJavaElementUtil;
@SuppressWarnings("restriction")
public aspect KotlinRippleMethodFinderAspect {
pointcut getRelatedMethods(IMethod method, ReferencesInBinaryContext binaryRefs, IProgressMonitor pm, WorkingCopyOwner owner) :
args(method, binaryRefs, pm, owner)
&& execution(IMethod[] RippleMethodFinder2.getRelatedMethods(IMethod, ReferencesInBinaryContext,
IProgressMonitor, WorkingCopyOwner));
@SuppressAjWarnings({"adviceDidNotMatch"})
IMethod[] around(IMethod method, ReferencesInBinaryContext binaryRefs, IProgressMonitor pm, WorkingCopyOwner owner) :
getRelatedMethods(method, binaryRefs, pm, owner) {
if (EclipseJavaElementUtil.isKotlinLightClass(method)) {
return new IMethod[] { method };
}
return proceed(method, binaryRefs, pm, owner);
}
}
================================================
FILE: kotlin-eclipse-aspects/src/org/jetbrains/kotlin/aspects/ui/PackageExplorerLabelProviderAspect.aj
================================================
package org.jetbrains.kotlin.aspects.ui;
import org.eclipse.jdt.internal.ui.packageview.PackageExplorerContentProvider;
import org.eclipse.jdt.internal.ui.packageview.PackageExplorerLabelProvider;
import org.jetbrains.kotlin.ui.KotlinAwarePackageExplorerLabelProvider;
@SuppressWarnings("restriction")
public aspect PackageExplorerLabelProviderAspect {
/**
* Replaces all instances of {@link PackageExplorerLabelProvider}
* with instances of {@link KotlinAwarePackageExplorerLabelProvider}
*
* It affects classes {@link JavaNavigatorLabelProvider} and {@link PackageExplorerPart},
* which provides icons for Project Explorer and Package Explorer, respectively.
*/
PackageExplorerLabelProvider around(PackageExplorerContentProvider cp)
: call(PackageExplorerLabelProvider.new(PackageExplorerContentProvider)) && args(cp) {
return new KotlinAwarePackageExplorerLabelProvider(cp);
}
}
================================================
FILE: kotlin-eclipse-core/META-INF/MANIFEST.MF
================================================
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: kotlin-eclipse-core
Bundle-SymbolicName: org.jetbrains.kotlin.core;singleton:=true
Bundle-Version: 0.8.24.qualifier
Bundle-Activator: org.jetbrains.kotlin.core.Activator
Bundle-Vendor: JetBrains
Require-Bundle: org.jetbrains.kotlin.bundled-compiler,
org.eclipse.core.runtime,
org.eclipse.jdt.core,
org.eclipse.jdt.launching,
org.eclipse.debug.core,
org.eclipse.core.filesystem,
org.eclipse.core.expressions,
org.eclipse.jdt.junit
Bundle-ActivationPolicy: lazy
Import-Package: com.intellij.codeInsight,
com.intellij.openapi.components,
kotlin.script.experimental.annotations,
kotlin.script.experimental.api,
kotlin.script.experimental.dependencies,
kotlin.script.experimental.host,
kotlin.script.experimental.util,
kotlin.script.experimental.jvm,
org.eclipse.core.filesystem,
org.eclipse.core.resources,
org.eclipse.debug.internal.ui.viewers,
org.eclipse.jdt.core,
org.eclipse.jdt.debug.core,
org.eclipse.jdt.internal.core,
org.eclipse.jdt.internal.corext.dom,
org.eclipse.jdt.internal.debug.core,
org.eclipse.jdt.internal.debug.core.breakpoints,
org.eclipse.jdt.junit.launcher,
org.eclipse.jdt.ui,
org.eclipse.jface.text,
org.jetbrains.kotlin.resolve.sam
Export-Package: org.jetbrains.kotlin.core,
org.jetbrains.kotlin.core.asJava,
org.jetbrains.kotlin.core.builder,
org.jetbrains.kotlin.core.compiler,
org.jetbrains.kotlin.core.debug,
org.jetbrains.kotlin.core.filesystem,
org.jetbrains.kotlin.core.formatting,
org.jetbrains.kotlin.core.imports,
org.jetbrains.kotlin.core.launch,
org.jetbrains.kotlin.core.log,
org.jetbrains.kotlin.core.model,
org.jetbrains.kotlin.core.preferences,
org.jetbrains.kotlin.core.references,
org.jetbrains.kotlin.core.resolve,
org.jetbrains.kotlin.core.resolve.lang.java.resolver,
org.jetbrains.kotlin.core.resolve.lang.java.structure,
org.jetbrains.kotlin.core.resolve.lang.kotlin,
org.jetbrains.kotlin.core.script,
org.jetbrains.kotlin.core.utils
Bundle-RequiredExecutionEnvironment: JavaSE-17
================================================
FILE: kotlin-eclipse-core/build.properties
================================================
###############################################################################
# Copyright 2000-2014 JetBrains s.r.o.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
###############################################################################
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
schema/,\
preferences.ini
================================================
FILE: kotlin-eclipse-core/plugin.xml
================================================
================================================
FILE: kotlin-eclipse-core/pom.xml
================================================
4.0.0
../pom.xml
kotlin.eclipse
kotlin.eclipse.plugin
0.8.24-SNAPSHOT
org.jetbrains.kotlin.core
eclipse-plugin
src
org.jetbrains.kotlin
kotlin-maven-plugin
${kotlin.version}
17
compile
process-sources
compile
org.apache.maven.plugins
maven-compiler-plugin
3.10.1
17
================================================
FILE: kotlin-eclipse-core/preferences.ini
================================================
jvmTarget=JVM_1_6
compilerPlugins/all-open/active=false
compilerPlugins/all-open/jarPath=$KOTLIN_HOME/lib/allopen-compiler-plugin.jar
compilerPlugins/spring/active=false
compilerPlugins/spring/jarPath=$KOTLIN_HOME/lib/allopen-compiler-plugin.jar
compilerPlugins/spring/args=org.jetbrains.kotlin.allopen:preset=spring
compilerPlugins/no-arg/active=false
compilerPlugins/no-arg/jarPath=$KOTLIN_HOME/lib/noarg-compiler-plugin.jar
compilerPlugins/jpa/active=false
compilerPlugins/jpa/jarPath=$KOTLIN_HOME/lib/noarg-compiler-plugin.jar
compilerPlugins/jpa/args=org.jetbrains.kotlin.noarg:preset=jpa
compilerPlugins/sam-with-receiver/active=false
compilerPlugins/sam-with-receiver/jarPath=$KOTLIN_HOME/lib/sam-with-receiver-compiler-plugin.jar
codeStyle/codeStyleId=KOTLIN_OFFICIAL
================================================
FILE: kotlin-eclipse-core/schema/org.jetbrains.kotlin.core.predefinedKotlinCodeStyle.exsd
================================================
[Enter description of this extension point.]
[Enter the first release in which this extension point appears.]
[Enter extension point usage example here.]
[Enter API information here.]
[Enter information about supplied implementation of this extension point.]
================================================
FILE: kotlin-eclipse-core/schema/org.jetbrains.kotlin.core.scriptTemplateContribution.exsd
================================================
[Enter description of this extension point.]
[Enter the first release in which this extension point appears.]
[Enter extension point usage example here.]
[Enter API information here.]
[Enter information about supplied implementation of this extension point.]
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/Activator.java
================================================
/*******************************************************************************
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package org.jetbrains.kotlin.core;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.jetbrains.kotlin.core.model.KotlinAnalysisProjectCache;
import org.jetbrains.kotlin.core.model.KotlinRefreshProjectListener;
import org.jetbrains.kotlin.core.preferences.KotlinProperties;
import org.osgi.framework.BundleContext;
public class Activator extends Plugin {
private static Activator plugin;
public static final String PLUGIN_ID = "org.jetbrains.kotlin.core";
public Activator() {
plugin = this;
}
public static Activator getDefault() {
return plugin;
}
@Override
public void start(BundleContext bundleContext) throws Exception {
super.start(bundleContext);
ResourcesPlugin.getWorkspace().addResourceChangeListener(KotlinAnalysisProjectCache.INSTANCE,
IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE | IResourceChangeEvent.PRE_BUILD);
ResourcesPlugin.getWorkspace().addResourceChangeListener(KotlinRefreshProjectListener.INSTANCE,
IResourceChangeEvent.PRE_REFRESH);
KotlinProperties.init();
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
ResourcesPlugin.getWorkspace().removeResourceChangeListener(KotlinAnalysisProjectCache.INSTANCE);
ResourcesPlugin.getWorkspace().removeResourceChangeListener(KotlinRefreshProjectListener.INSTANCE);
plugin = null;
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/KotlinClasspathContainer.kt
================================================
/*******************************************************************************
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package org.jetbrains.kotlin.core
import org.eclipse.core.runtime.IPath
import org.eclipse.core.runtime.Path
import org.eclipse.jdt.core.IClasspathContainer
import org.eclipse.jdt.core.IClasspathEntry
import org.eclipse.jdt.core.IJavaProject
import org.eclipse.jdt.core.JavaCore
import org.jetbrains.kotlin.core.model.KotlinJavaManager
import org.jetbrains.kotlin.core.utils.ProjectUtils
import org.jetbrains.kotlin.core.utils.buildLibPath
import java.util.*
val runtimeContainerId: IPath = Path("org.jetbrains.kotlin.core.KOTLIN_CONTAINER")
class KotlinClasspathContainer(val javaProject: IJavaProject) : IClasspathContainer {
companion object {
val CONTAINER_ENTRY: IClasspathEntry = JavaCore.newContainerEntry(runtimeContainerId)
val LIB_RUNTIME_NAME = "kotlin-stdlib"
val LIB_RUNTIME_SRC_NAME = "kotlin-stdlib-sources"
val LIB_REFLECT_NAME = "kotlin-reflect"
val LIB_SCRIPT_RUNTIME_NAME = "kotlin-script-runtime"
val LIB_ANNOTATIONS_1_3 = "annotations-13.0"
@JvmStatic
fun getPathToLightClassesFolder(javaProject: IJavaProject): IPath {
return Path(javaProject.project.name).append(KotlinJavaManager.KOTLIN_BIN_FOLDER).makeAbsolute()
}
}
override fun getClasspathEntries(): Array {
val entries = ArrayList()
val kotlinBinFolderEntry =
ProjectUtils.newExportedLibraryEntry(getPathToLightClassesFolder(javaProject))
entries.add(kotlinBinFolderEntry)
val project = javaProject.project
if (!ProjectUtils.isMavenProject(project) && !ProjectUtils.isGradleProject(project)) {
val kotlinRuntimeEntry = JavaCore.newLibraryEntry(
LIB_RUNTIME_NAME.buildLibPath(),
LIB_RUNTIME_SRC_NAME.buildLibPath(),
null,
true)
val kotlinReflectEntry =
ProjectUtils.newExportedLibraryEntry(LIB_REFLECT_NAME.buildLibPath())
val kotlinScriptRuntime =
ProjectUtils.newExportedLibraryEntry(LIB_SCRIPT_RUNTIME_NAME.buildLibPath())
val annotations13 =
ProjectUtils.newExportedLibraryEntry(LIB_ANNOTATIONS_1_3.buildLibPath())
entries.add(kotlinRuntimeEntry)
entries.add(kotlinReflectEntry)
entries.add(kotlinScriptRuntime)
entries.add(annotations13)
}
return entries.toTypedArray()
}
override fun getDescription(): String = "Kotlin Runtime Library"
override fun getKind(): Int = IClasspathContainer.K_APPLICATION
override fun getPath(): IPath = runtimeContainerId
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/KotlinClasspathContainerInitializer.kt
================================================
package org.jetbrains.kotlin.core
import org.eclipse.core.resources.IFolder
import org.eclipse.core.resources.IResource
import org.eclipse.core.runtime.IPath
import org.eclipse.core.runtime.Path
import org.eclipse.jdt.core.ClasspathContainerInitializer
import org.eclipse.jdt.core.IJavaProject
import org.eclipse.jdt.core.JavaCore
import org.jetbrains.kotlin.core.filesystem.KotlinFileSystem
import org.jetbrains.kotlin.core.model.KotlinJavaManager
import java.net.URI
class KotlinClasspathContainerInitializer : ClasspathContainerInitializer() {
override fun initialize(containerPath: IPath, javaProject: IJavaProject) {
if (JavaCore.getClasspathContainer(runtimeContainerId, javaProject) !is KotlinClasspathContainer) {
if (!KotlinJavaManager.hasLinkedKotlinBinFolder(javaProject.project)) {
addFolderForKotlinClassFiles(javaProject)
}
JavaCore.setClasspathContainer(containerPath, arrayOf(javaProject), arrayOf(KotlinClasspathContainer(javaProject)), null)
}
}
}
private fun setKotlinFileSystemScheme(folder: IFolder) : URI {
val locationURI = folder.locationURI
val path = Path(folder.project.name).append(KotlinJavaManager.KOTLIN_BIN_FOLDER).makeAbsolute()
return URI(
KotlinFileSystem.SCHEME,
locationURI.userInfo,
locationURI.host,
locationURI.port,
path.toPortableString(),
locationURI.query,
locationURI.fragment)
}
private fun addFolderForKotlinClassFiles(javaProject: IJavaProject) {
val folder = javaProject.project.getFolder(KotlinJavaManager.KOTLIN_BIN_FOLDER)
folder.createLink(setKotlinFileSystemScheme(folder), IResource.REPLACE or IResource.ALLOW_MISSING_LOCAL, null)
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/KotlinClasspathProvider.kt
================================================
package org.jetbrains.kotlin.core
import org.eclipse.debug.core.ILaunchConfiguration
import org.eclipse.jdt.launching.IRuntimeClasspathEntry
import org.eclipse.jdt.launching.JavaRuntime
import org.eclipse.jdt.launching.StandardClasspathProvider
const val KOTLIN_CLASSPATH_PROVIDER_ID = "org.jetbrains.kotlin.core.kotlinClasspathProvider"
class KotlinClasspathProvider : StandardClasspathProvider() {
override fun computeUnresolvedClasspath(configuration: ILaunchConfiguration): Array =
super.computeUnresolvedClasspath(configuration)
.filterNot { it.location != null && it.location == configuration.lightClassPath }
.toTypedArray()
private val ILaunchConfiguration.lightClassPath: String?
get() = JavaRuntime.getJavaProject(this)
?.let { KotlinClasspathContainer.getPathToLightClassesFolder(it) }
?.toPortableString()
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/asJava/BinaryClassWriter.java
================================================
package org.jetbrains.kotlin.core.asJava;
import org.jetbrains.org.objectweb.asm.ClassWriter;
public class BinaryClassWriter extends ClassWriter {
public BinaryClassWriter() {
super(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
}
@Override
protected String getCommonSuperClass(String type1, String type2) {
try {
return super.getCommonSuperClass(type1, type2);
}
catch (Throwable t) {
// TODO: we might need at some point do more sophisticated handling
return "java/lang/Object";
}
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/asJava/KotlinLightClassGeneration.kt
================================================
/*******************************************************************************
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package org.jetbrains.kotlin.core.asJava
import org.eclipse.core.resources.IFile
import org.eclipse.core.resources.IProject
import org.eclipse.core.runtime.Path
import org.eclipse.jdt.core.JavaCore
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.core.builder.KotlinPsiManager
import org.jetbrains.kotlin.core.filesystem.KotlinLightClassManager
import org.jetbrains.kotlin.core.model.KotlinEnvironment
import org.jetbrains.kotlin.core.model.KotlinJavaManager
import org.jetbrains.kotlin.core.preferences.languageVersionSettings
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtScript
object KotlinLightClassGeneration {
fun updateLightClasses(project: IProject, affectedFiles: Set, resourcesTreeBlocked: Boolean = false) {
if (!KotlinJavaManager.hasLinkedKotlinBinFolder(project)) return
KotlinPsiManager.recreateSourcesForProject(JavaCore.create(project))
KotlinLightClassManager.getInstance(project).computeLightClassesSources()
KotlinLightClassManager.getInstance(project).updateLightClasses(affectedFiles, resourcesTreeBlocked)
}
fun buildLightClasses(
analysisResult: AnalysisResult,
eclipseProject: IProject,
jetFiles: List,
requestedClassName: String): GenerationState {
val tempProps = KotlinEnvironment.getEnvironment(eclipseProject).compilerProperties
val tempConfig = CompilerConfiguration().apply {
put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, tempProps.languageVersionSettings)
}
val state = GenerationState.Builder(
KotlinEnvironment.getEnvironment(eclipseProject).project,
LightClassBuilderFactory(),
analysisResult.moduleDescriptor,
analysisResult.bindingContext,
jetFiles,
tempConfig)
.generateDeclaredClassFilter(object : GenerationState.GenerateClassFilter() {
override fun shouldGenerateCodeFragment(script: KtCodeFragment): Boolean = false
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean = true
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean {
val internalName = KotlinLightClassManager.getInternalName(processingClassOrObject)
return checkByInternalName(internalName, requestedClassName)
}
override fun shouldGeneratePackagePart(ktFile: KtFile): Boolean {
val internalName = JvmFileClassUtil.getFileClassInternalName(ktFile)
return checkByInternalName(internalName, requestedClassName)
}
override fun shouldGenerateScript(script: KtScript): Boolean = false
override fun shouldGenerateClassMembers(processingClassOrObject: KtClassOrObject): Boolean {
return super.shouldGenerateClassMembers(processingClassOrObject) ||
processingClassOrObject.hasModifier(KtTokens.COMPANION_KEYWORD)
}
}).build()
KotlinCodegenFacade.compileCorrectFiles(state)
return state
}
private fun checkByInternalName(internalName: String?, requestedClassFileName: String): Boolean {
if (internalName == null) return false
val classFileName = Path(internalName).lastSegment()
val requestedInternalName = requestedClassFileName.dropLast(".class".length)
if (requestedInternalName.startsWith(classFileName)) {
if (requestedInternalName.length == classFileName.length) return true
if (requestedInternalName[classFileName.length] == '$') return true
}
return false
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/asJava/LightClassBuilderFactory.java
================================================
package org.jetbrains.kotlin.core.asJava;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.AbstractClassBuilder;
import org.jetbrains.kotlin.codegen.ClassBuilder;
import org.jetbrains.kotlin.codegen.ClassBuilderFactory;
import org.jetbrains.kotlin.codegen.ClassBuilderMode;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.org.objectweb.asm.ClassWriter;
import org.jetbrains.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
public class LightClassBuilderFactory implements ClassBuilderFactory {
public static final Key>> JVM_SIGNATURE = Key.create("JVM_SIGNATURE");
@Override
@NotNull
public ClassBuilderMode getClassBuilderMode() {
return ClassBuilderMode.LIGHT_CLASSES;
}
@Override
@NotNull
public ClassBuilder newClassBuilder(@NotNull JvmDeclarationOrigin origin) {
return new AbstractClassBuilder.Concrete(new BinaryClassWriter()) {
@Override
@NotNull
public MethodVisitor newMethod(@NotNull JvmDeclarationOrigin origin, int access, @NotNull String name,
@NotNull String desc, @Nullable String signature, @Nullable String[] exceptions) {
saveJvmSignature(origin, name, desc);
return super.newMethod(origin, access, name, desc, signature, exceptions);
}
@Override
@NotNull
public FieldVisitor newField(@NotNull JvmDeclarationOrigin origin, int access, @NotNull String name,
@NotNull String desc, @Nullable String signature, @Nullable Object value) {
saveJvmSignature(origin, name, desc);
return super.newField(origin, access, name, desc, signature, value);
}
private void saveJvmSignature(@NotNull JvmDeclarationOrigin origin, @NotNull String name, @NotNull String desc) {
PsiElement element = origin.getElement();
if (element != null) {
Set> userData = element.getUserData(JVM_SIGNATURE);
if (userData == null) {
userData = Collections.newSetFromMap(new ConcurrentHashMap, Boolean>());
element.putUserData(JVM_SIGNATURE, userData);
}
userData.add(new Pair(desc, name));
}
}
};
}
@Override
public String asText(ClassBuilder builder) {
throw new UnsupportedOperationException("BINARIES generator asked for text");
}
@Override
public byte[] asBytes(ClassBuilder builder) {
ClassWriter visitor = (ClassWriter) builder.getVisitor();
return visitor.toByteArray();
}
@Override
public void close() {
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/asJava/LightClassFile.java
================================================
package org.jetbrains.kotlin.core.asJava;
import java.io.ByteArrayInputStream;
import java.io.File;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.core.log.KotlinLogger;
public class LightClassFile {
private final IFile file;
public LightClassFile(@NotNull IFile file) {
this.file = file;
}
public boolean exists() {
return file.exists();
}
public boolean createIfNotExists() {
try {
if (!file.exists()) {
file.create(new ByteArrayInputStream(new byte[0]), false, null);
return true;
}
} catch (CoreException e) {
KotlinLogger.logAndThrow(e);
}
return false;
}
public void touchFile() {
try {
file.touch(null);
} catch (CoreException e) {
KotlinLogger.logAndThrow(e);
}
}
@NotNull
public File asFile() {
return file.getFullPath().toFile();
}
@NotNull
public IFile getResource() {
return file;
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/asJava/elementUtils.kt
================================================
/*******************************************************************************
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package org.jetbrains.kotlin.core.asJava
import org.jetbrains.kotlin.psi.KtElement
import org.eclipse.jdt.core.IMember
import org.eclipse.jdt.core.IField
import org.eclipse.jdt.core.IMethod
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtConstructor
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtClassOrObject
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.name.FqName
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
fun equalsJvmSignature(KtElement: KtElement, javaMember: IMember): Boolean {
val jetSignatures = KtElement.getUserData(LightClassBuilderFactory.JVM_SIGNATURE)
if (jetSignatures == null) return false
val memberSignature = when (javaMember) {
is IField -> javaMember.getTypeSignature().replace("\\.".toRegex(), "/") // Hack
is IMethod -> javaMember.getSignature()
else -> null
}
return jetSignatures.any {
if (it.first == memberSignature) {
return@any when {
javaMember is IMethod && javaMember.isConstructor() ->
KtElement is KtClass || KtElement is KtConstructor<*>
else -> it.second == javaMember.getElementName()
}
}
false
}
}
fun getDeclaringTypeFqName(KtElement: KtElement): FqName? {
val parent = PsiTreeUtil.getParentOfType(KtElement, KtClassOrObject::class.java, KtFile::class.java)
return if (parent != null) getTypeFqName(parent) else null
}
fun getTypeFqName(element: PsiElement): FqName? {
return when (element) {
is KtClassOrObject -> element.getFqName()
is KtFile -> JvmFileClassUtil.getFileClassInfoNoResolve(element).fileClassFqName
else -> null
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/builder/KotlinPsiManager.kt
================================================
/*******************************************************************************
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package org.jetbrains.kotlin.core.builder
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.util.text.StringUtilRt
import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.impl.PsiFileFactoryImpl
import org.eclipse.core.resources.IFile
import org.eclipse.core.resources.IProject
import org.eclipse.core.resources.IResource
import org.eclipse.core.resources.IResourceDelta
import org.eclipse.core.resources.ResourcesPlugin
import org.eclipse.core.runtime.CoreException
import org.eclipse.core.runtime.Path
import org.eclipse.jdt.core.IClasspathEntry
import org.eclipse.jdt.core.IJavaProject
import org.eclipse.jdt.core.JavaCore
import org.eclipse.jface.text.IDocument
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreApplicationEnvironment
import org.jetbrains.kotlin.core.log.KotlinLogger
import org.jetbrains.kotlin.core.model.*
import org.jetbrains.kotlin.core.utils.ProjectUtils
import org.jetbrains.kotlin.core.utils.asFile
import org.jetbrains.kotlin.core.utils.javaProject
import org.jetbrains.kotlin.core.utils.sourceFolders
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionProvider
import java.io.File
import java.util.Collections
import java.util.HashSet
import java.util.concurrent.ConcurrentHashMap
import kotlin.script.experimental.host.FileScriptSource
interface PsiFilesStorage {
fun getPsiFile(eclipseFile: IFile): KtFile
fun getPsiFile(file: IFile, expectedSourceCode: String): KtFile
fun isApplicable(file: IFile): Boolean
fun removeFile(file: IFile)
}
private class ScriptsFilesStorage : PsiFilesStorage {
private val cachedKtFiles = ConcurrentHashMap()
override fun getPsiFile(eclipseFile: IFile): KtFile {
assert(isApplicable(eclipseFile)) { "$eclipseFile is not applicable for Kotlin scripts storage" }
return cachedKtFiles.getOrPut(eclipseFile) { KotlinPsiManager.parseFile(eclipseFile)!! }
}
@Synchronized
override fun getPsiFile(file: IFile, expectedSourceCode: String): KtFile {
val sourceCodeWithouCR = StringUtilRt.convertLineSeparators(expectedSourceCode)
val currentParsedFile = getPsiFile(file)
if (currentParsedFile.getText() != sourceCodeWithouCR) {
val jetFile = KotlinPsiManager.parseText(sourceCodeWithouCR, file)!!
cachedKtFiles.put(file, jetFile)
}
return getPsiFile(file)
}
override fun isApplicable(file: IFile): Boolean =
EclipseScriptDefinitionProvider.isScript(FileScriptSource(file.asFile))
override fun removeFile(file: IFile) {
cachedKtFiles.remove(file)
}
}
private class ProjectSourceFiles : PsiFilesStorage {
companion object {
@JvmStatic
fun isKotlinFile(file: IFile): Boolean = KotlinFileType.INSTANCE.getDefaultExtension() == file.fileExtension
}
private val projectFiles = hashMapOf>()
private val cachedKtFiles = hashMapOf()
private val mapOperationLock = Any()
override fun getPsiFile(eclipseFile: IFile): KtFile {
synchronized (mapOperationLock) {
updateProjectPsiSourcesIfNeeded(eclipseFile.getProject())
assert(existsInProjectSources(eclipseFile), { "File(" + eclipseFile.getName() + ") does not contain in the psiFiles" })
return cachedKtFiles.getOrPut(eclipseFile) {
KotlinPsiManager.parseFile(eclipseFile) ?: throw IllegalStateException("Can't parse file $eclipseFile")
}
}
}
override fun getPsiFile(file: IFile, expectedSourceCode: String): KtFile {
synchronized (mapOperationLock) {
updatePsiFile(file, expectedSourceCode)
return getPsiFile(file)
}
}
override fun isApplicable(file: IFile): Boolean = existsInProjectSources(file)
fun existsInProjectSources(file: IFile, update: Boolean = true): Boolean {
synchronized (mapOperationLock) {
return file.project?.let {
if (update) {
updateProjectPsiSourcesIfNeeded(it)
}
projectFiles[it]?.contains(file)
} ?: false
}
}
fun containsProject(project: IProject): Boolean {
return synchronized (mapOperationLock) {
projectFiles.containsKey(project)
}
}
fun getFilesByProject(project: IProject): Set {
synchronized (mapOperationLock) {
updateProjectPsiSourcesIfNeeded(project)
if (projectFiles.containsKey(project)) {
return Collections.unmodifiableSet(projectFiles[project])
}
return emptySet()
}
}
fun addFile(file: IFile) {
synchronized (mapOperationLock) {
assert(KotlinNature.hasKotlinNature(file.getProject()),
{ "Project (" + file.getProject().getName() + ") does not have Kotlin nature" })
assert(!existsInProjectSources(file, false), { "File(" + file.getName() + ") is already added" })
projectFiles
.getOrPut(file.project) { hashSetOf() }
.add(file)
}
}
override fun removeFile(file: IFile) {
synchronized (mapOperationLock) {
assert(existsInProjectSources(file), { "File(" + file.getName() + ") does not contain in the psiFiles" })
cachedKtFiles.remove(file)
projectFiles.get(file.project)?.remove(file)
}
}
fun addProject(project: IProject) {
synchronized (mapOperationLock) {
if (ProjectUtils.isAccessibleKotlinProject(project)) {
addFilesToParse(JavaCore.create(project))
}
}
}
fun removeProject(project: IProject) {
synchronized (mapOperationLock) {
val files = getFilesByProject(project)
projectFiles.remove(project)
for (file in files) {
cachedKtFiles.remove(file)
}
}
}
fun addFilesToParse(javaProject: IJavaProject) {
try {
projectFiles.put(javaProject.getProject(), HashSet())
for (sourceFolder in javaProject.sourceFolders) {
sourceFolder.resource.accept { resource ->
if (resource is IFile && isKotlinFile(resource)) {
addFile(resource)
}
true
}
}
} catch (e: CoreException) {
KotlinLogger.logError(e)
}
}
fun updateProjectPsiSourcesIfNeeded(project: IProject) {
if (projectFiles.containsKey(project)) {
return
}
if (ProjectUtils.isAccessibleKotlinProject(project)) {
updateProjectPsiSources(project, IResourceDelta.ADDED)
}
}
fun updateProjectPsiSources(project: IProject, flag: Int) {
when (flag) {
IResourceDelta.ADDED -> addProject(project)
IResourceDelta.REMOVED -> removeProject(project)
}
}
fun invalidateProjectSourceFiles() {
cachedKtFiles.clear()
}
private fun updatePsiFile(file: IFile, sourceCode: String) {
val sourceCodeWithouCR = StringUtilRt.convertLineSeparators(sourceCode)
synchronized (mapOperationLock) {
assert(existsInProjectSources(file), { "File(" + file.getName() + ") does not contain in the psiFiles" })
val currentParsedFile = getPsiFile(file)
if (!currentParsedFile.getText().equals(sourceCodeWithouCR)) {
val jetFile = KotlinPsiManager.parseText(sourceCodeWithouCR, file)!!
cachedKtFiles.put(file, jetFile)
}
}
}
fun addFilesIfNotPresent(project: IJavaProject) {
try {
with(projectFiles.getOrPut(project.project) { hashSetOf() }) {
for (sourceFolder in project.sourceFolders) {
sourceFolder.resource.accept { resource ->
if (resource is IFile && isKotlinFile(resource) && !contains(resource)) {
add(resource)
}
true
}
}
}
} catch (e: CoreException) {
KotlinLogger.logError(e)
}
}
}
object KotlinPsiManager {
private val projectSourceFiles = ProjectSourceFiles()
private val scriptsFiles = ScriptsFilesStorage()
fun getParsedFile(file: IFile): KtFile {
return storage(file).getPsiFile(file)
}
private fun isApplicable(file: IFile): Boolean {
return applicableStorage(file)?.isApplicable(file) ?: false
}
fun updateProjectPsiSources(file: IFile, flag: Int) {
when (flag) {
IResourceDelta.ADDED -> projectSourceFiles.addFile(file)
IResourceDelta.REMOVED -> removeFile(file)
else -> throw IllegalArgumentException()
}
}
fun invalidateCachedProjectSourceFiles() {
projectSourceFiles.invalidateProjectSourceFiles()
}
fun removeFile(file: IFile) {
storage(file).removeFile(file)
}
fun removeProjectFromManager(project: IProject) {
projectSourceFiles.updateProjectPsiSources(project, IResourceDelta.REMOVED)
}
fun getFilesByProject(project: IProject): Set {
return projectSourceFiles.getFilesByProject(project)
}
fun existsSourceFile(file: IFile): Boolean {
return projectSourceFiles.existsInProjectSources(file)
}
fun getFilesByProject(projectName: String): Set {
val project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName)
updateProjectPsiSourcesIfNeeded(project)
return getFilesByProject(project)
}
private fun storage(file: IFile): PsiFilesStorage {
return applicableStorage(file) ?: throw IllegalStateException("There is not applicable storage for file: $file")
}
private fun applicableStorage(file: IFile): PsiFilesStorage? {
return when {
scriptsFiles.isApplicable(file) -> scriptsFiles
projectSourceFiles.isApplicable(file) -> projectSourceFiles
else -> null
}
}
private fun updateProjectPsiSourcesIfNeeded(project: IProject) {
projectSourceFiles.updateProjectPsiSourcesIfNeeded(project)
}
private fun getParsedFile(file: IFile, expectedSourceCode: String): KtFile {
return storage(file).getPsiFile(file, expectedSourceCode)
}
@JvmOverloads
@JvmStatic
fun isKotlinSourceFile(
resource: IResource,
javaProject: IJavaProject = JavaCore.create(resource.project)): Boolean {
if (!(resource is IFile) || !KotlinFileType.INSTANCE.getDefaultExtension().equals(resource.getFileExtension())) {
return false
}
if (!javaProject.exists()) {
return false
}
if (!KotlinNature.hasKotlinNature(javaProject.getProject())) {
return false
}
val classpathEntries = javaProject.getRawClasspath()
val resourceRoot = resource.getFullPath().segment(1)
return classpathEntries.any { classpathEntry ->
classpathEntry.entryKind == IClasspathEntry.CPE_SOURCE && resourceRoot == classpathEntry.path.segment(1)
}
}
fun parseFile(file: IFile): KtFile? {
if (!file.exists()) {
return null
}
val ioFile = File(file.getRawLocation().toOSString())
return parseText(FileUtil.loadFile(ioFile, null, true), file)
}
fun parseText(text: String, file: IFile): KtFile? {
StringUtil.assertValidSeparators(text)
val project = getEnvironment(file).project
val virtualFile = KotlinLightVirtualFile(file, text)
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET)
val psiFileFactory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl
return psiFileFactory.trySetupPsiForFile(virtualFile, KotlinLanguage.INSTANCE, true, false) as? KtFile
}
@JvmStatic
fun isKotlinFile(file: IFile): Boolean = KotlinFileType.INSTANCE.getDefaultExtension() == file.fileExtension
@JvmStatic
fun getKotlinParsedFile(file: IFile): KtFile? {
return if (isApplicable(file)) getParsedFile(file) else null
}
@JvmStatic
fun getKotlinFileIfExist(file: IFile, sourceCode: String): KtFile? {
return if (isApplicable(file)) getParsedFile(file, sourceCode) else null
}
@JvmStatic
fun getEclipseFile(jetFile: KtFile): IFile? {
val virtualFile = jetFile.getVirtualFile()
return if (virtualFile != null)
ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path(virtualFile.getPath()))
else
null
}
@JvmStatic
fun getJavaProject(jetElement: KtElement): IJavaProject? {
return getEclipseFile(jetElement.getContainingKtFile())?.let { eclipseFile ->
JavaCore.create(eclipseFile.project)
}
}
@JvmStatic
fun commitFile(file: IFile, document: IDocument) {
getKotlinFileIfExist(file, document.get())
}
@JvmStatic
fun recreateSourcesForProject(project: IJavaProject) {
if (projectSourceFiles.containsProject(project.project)) {
projectSourceFiles.addFilesIfNotPresent(project)
}
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/compiler/KotlinCompiler.kt
================================================
package org.jetbrains.kotlin.core.compiler
import com.intellij.openapi.util.Disposer
import org.eclipse.jdt.core.IJavaProject
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.EXCEPTION
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.core.filesystem.KotlinLightClassManager.Companion.KOTLIN_TOUCHED_FILES_FILE_NAME
import org.jetbrains.kotlin.core.launch.CompilerOutputData
import org.jetbrains.kotlin.core.launch.CompilerOutputParser
import org.jetbrains.kotlin.core.launch.KotlinCLICompiler
import org.jetbrains.kotlin.core.model.KOTLIN_COMPILER_PATH
import org.jetbrains.kotlin.core.model.KotlinEnvironment
import org.jetbrains.kotlin.core.preferences.CompilerPlugin
import org.jetbrains.kotlin.core.utils.DependencyResolverException
import org.jetbrains.kotlin.core.utils.ProjectUtils
import org.jetbrains.kotlin.incremental.makeIncrementally
import java.io.*
object KotlinCompiler {
private fun compileKotlinFiles(
javaProject: IJavaProject,
compilation: (IJavaProject, File, List) -> KotlinCompilerResult
): KotlinCompilerResult =
ProjectUtils.getSrcOutDirectories(javaProject)
.groupingBy { it.second }.fold(mutableListOf()) { list, key ->
list.apply { add(key.first) }
}.onEach { (out) ->
val tempFile = File(out, KOTLIN_TOUCHED_FILES_FILE_NAME).takeIf { it.exists() }
tempFile?.readLines()?.map(::File)?.flatMap { tempFileToDelete ->
val tempName = tempFileToDelete.nameWithoutExtension
val tempFiles = tempFileToDelete.parentFile?.listFiles(FileFilter { it.name == "$tempName.class" || (it.name.startsWith("$tempName$") && it.name.endsWith(".class")) })
tempFiles?.toList() ?: emptyList()
}?.distinct()?.forEach(File::delete)
tempFile?.delete()
out.walkTopDown().filter { it.extension == "kt" }.forEach { it.delete() }
}.map { (out, sources) ->
compilation(javaProject, out, sources)
}.fold(KotlinCompilerResult(true, CompilerOutputData())) { previous, current ->
KotlinCompilerResult(previous.result and current.result, CompilerOutputData().apply {
previous.compilerOutput.list.union(current.compilerOutput.list).forEach {
add(it.messageSeverity, it.message, it.messageLocation)
}
})
}
@JvmStatic
fun compileKotlinFiles(javaProject: IJavaProject): KotlinCompilerResult =
compileKotlinFiles(javaProject) { project, path, sources ->
execKotlinCompiler(configureCompilerArguments(project, path.absolutePath, sources))
}
@JvmStatic
fun compileIncrementallyFiles(
javaProject: IJavaProject
): KotlinCompilerResult =
compileKotlinFiles(javaProject) { project, path, sources ->
execIncrementalKotlinCompiler(project, path.absoluteFile, sources)
}
private fun execIncrementalKotlinCompiler(
javaProject: IJavaProject,
outputDir: File,
sourceDirs: List
): KotlinCompilerResult {
val arguments = getCompilerArguments(javaProject, outputDir)
val messageCollector = CompilerMessageCollector()
val disposable = Disposer.newDisposable("Incremental compilation")
val config = CompilerConfiguration().apply {
put(JVMConfigurationKeys.NO_JDK, true)
put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
put(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, KOTLIN_COMPILER_PATH)
}
KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForProduction(disposable, config)
val cacheDir = File("${outputDir.parentFile.absolutePath}/cache").also { it.mkdirs() }
makeIncrementally(cacheDir, sourceDirs, arguments, messageCollector)
return messageCollector.getCompilerResult()
}
private fun execKotlinCompiler(arguments: Array): KotlinCompilerResult = with(ByteArrayOutputStream()) {
KotlinCLICompiler.doMain(K2JVMCompiler(), PrintStream(this), arguments)
parseCompilerOutput(BufferedReader(StringReader(this.toString())))
}
private fun getCompilerArguments(javaProject: IJavaProject, outputDir: File) = K2JVMCompilerArguments().apply {
val kotlinProperties =
KotlinEnvironment.getEnvironment(javaProject.project).compilerProperties
kotlinHome = ProjectUtils.ktHome
destination = outputDir.absolutePath
moduleName = "kotlin-eclipse-plugin"
val jdkUndefined = kotlinProperties.isJDKHomUndefined()
kotlinProperties.jdkHome?.takeUnless { jdkUndefined }?.let { jdkHomePath ->
jdkHome = jdkHomePath
} ?: {
noJdk = true
}()
noStdlib = true
jvmTarget = kotlinProperties.jvmTarget.description
intellijPluginRoot = KOTLIN_COMPILER_PATH
languageVersion = kotlinProperties.languageVersion.versionString
apiVersion = kotlinProperties.apiVersion.versionString
val pluginClasspathsList = mutableListOf()
val pluginOptionsList = mutableListOf()
kotlinProperties.compilerPlugins.entries.forEach { plugin ->
plugin.jarPath?.takeIf { plugin.active }?.let { jarPath ->
pluginClasspathsList.add(jarPath.replace("\$KOTLIN_HOME", ProjectUtils.ktHome))
plugin.args.forEach { arg ->
pluginOptionsList.add("plugin: $arg")
}
}
}
pluginClasspaths = pluginClasspathsList.toTypedArray()
pluginOptions = pluginOptionsList.toTypedArray()
val tempFiles = try {
ProjectUtils.collectClasspathWithDependenciesForLaunch(javaProject, jdkUndefined)
} catch (e: DependencyResolverException) {
e.resolvedFiles
}
classpath = tempFiles.joinToString(separator = System.getProperty("path.separator")) { it.absolutePath }
}
private fun configureCompilerArguments(
javaProject: IJavaProject, outputDir: String, sourceDirs: List
): Array = with(mutableListOf()) {
val kotlinProperties =
KotlinEnvironment.getEnvironment(javaProject.project).compilerProperties
add("-kotlin-home")
add(ProjectUtils.ktHome)
val jdkUndefined = kotlinProperties.isJDKHomUndefined()
kotlinProperties.jdkHome?.takeUnless { jdkUndefined }?.let { jdkHomePath ->
add("-jdk-home")
add(jdkHomePath)
} ?: add("-no-jdk")
add("-no-stdlib") // Because we add runtime into the classpath
add("-jvm-target")
add(kotlinProperties.jvmTarget.description)
add("-language-version")
add(kotlinProperties.languageVersion.versionString)
add("-api-version")
add(kotlinProperties.apiVersion.versionString)
kotlinProperties.compilerPlugins.entries.forEach { plugin ->
addAll(configurePlugin(plugin))
}
kotlinProperties.compilerFlags?.takeUnless { it.isBlank() }?.split("\\s+".toRegex())?.let {
addAll(it)
}
add("-classpath")
val tempFiles = try {
ProjectUtils.collectClasspathWithDependenciesForLaunch(javaProject, jdkUndefined)
} catch (e: DependencyResolverException) {
e.resolvedFiles
}
add(tempFiles.joinToString(separator = System.getProperty("path.separator")) { it.absolutePath })
add("-d")
add(outputDir)
addAll(sourceDirs.map {
it.absolutePath
})
toTypedArray()
}
private fun configurePlugin(plugin: CompilerPlugin): Collection = mutableListOf().apply {
plugin.jarPath?.takeIf { plugin.active }?.let { jarPath ->
add("-Xplugin=${jarPath.replace("\$KOTLIN_HOME", ProjectUtils.ktHome)}")
plugin.args.forEach { arg ->
add("-P")
add("plugin: $arg")
}
}
}
private class CompilerMessageCollector : MessageCollector {
var hasErrors = false
val severities: MutableList = mutableListOf()
val compilerOutput = CompilerOutputData()
override fun report(
severity: CompilerMessageSeverity,
message: String,
location: CompilerMessageSourceLocation?
) {
hasErrors == hasErrors || severity.isError
severities.add(severity)
if (location != null) {
val messageLocation = CompilerMessageLocation.create(location.path, location.line, location.column, location.lineContent)
compilerOutput.add(severity, message, messageLocation)
} else {
compilerOutput.add(severity, message, null)
}
}
override fun hasErrors(): Boolean = hasErrors
override fun clear() {
hasErrors = false
}
fun getCompilerResult(): KotlinCompilerResult =
KotlinCompilerResult(severities.firstOrNull { it == ERROR || it == EXCEPTION } == null, compilerOutput)
}
private fun parseCompilerOutput(reader: Reader): KotlinCompilerResult {
val messageCollector = CompilerMessageCollector()
CompilerOutputParser.parseCompilerMessagesFromReader(messageCollector, reader)
return messageCollector.getCompilerResult()
}
}
class KotlinCompilerResult(val result: Boolean, val compilerOutput: CompilerOutputData) {
fun compiledCorrectly() = result
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/compiler/KotlinCompiler2.java
================================================
package org.jetbrains.kotlin.core.compiler;
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/compiler/KotlinCompilerUtils.kt
================================================
/*******************************************************************************
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.core.compiler
import org.jetbrains.kotlin.core.compiler.KotlinCompiler.compileKotlinFiles
import org.jetbrains.kotlin.core.compiler.KotlinCompiler.compileIncrementallyFiles
import org.eclipse.core.runtime.CoreException
import org.eclipse.jdt.core.IJavaProject
import org.eclipse.core.runtime.IStatus
import org.eclipse.core.runtime.Status
import org.eclipse.debug.core.IStatusHandler
import org.eclipse.debug.core.DebugPlugin
import org.jetbrains.kotlin.core.Activator
import org.jetbrains.kotlin.core.launch.CompilerOutputData
object KotlinCompilerUtils {
fun compileWholeProject(javaProject: IJavaProject): KotlinCompilerResult = compileKotlinFiles(javaProject)
fun compileProjectIncrementally(javaProject: IJavaProject): KotlinCompilerResult =
compileIncrementallyFiles(javaProject)
fun handleCompilerOutput(compilerOutput: CompilerOutputWithProject) {
val status: IStatus = Status(IStatus.ERROR, Activator.PLUGIN_ID, 1, "", null)
val handler = DebugPlugin.getDefault().getStatusHandler(status)
handler?.handleStatus(status, compilerOutput)
}
data class CompilerOutputWithProject(val data: CompilerOutputData, val project: IJavaProject)
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/debug/KotlinSourceLookupNavigator.java
================================================
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.core.debug;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.core.builder.KotlinPsiManager;
import org.jetbrains.kotlin.core.log.KotlinLogger;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtFile;
public class KotlinSourceLookupNavigator {
public static final KotlinSourceLookupNavigator INSTANCE = new KotlinSourceLookupNavigator();
private KotlinSourceLookupNavigator() {
}
// From JDI model we obtain path to file as "some/pckg/File.kt" and Java seeks file in folder some/pckg what might be wrong
@Nullable
public IFile findKotlinSourceFile(@NotNull IJavaStackFrame frame) {
ISourceLocator sourceLocator = frame.getLaunch().getSourceLocator();
if (!(sourceLocator instanceof ISourceLookupDirector)) {
return null;
}
try {
return findKotlinSourceFile(frame, (ISourceLookupDirector) sourceLocator);
} catch (CoreException e) {
KotlinLogger.logAndThrow(e);
}
return null;
}
private IFile findKotlinSourceFile(IJavaStackFrame frame, ISourceLookupDirector lookupDirector) throws CoreException {
boolean isFindDuplicates = lookupDirector.isFindDuplicates();
try {
lookupDirector.setFindDuplicates(true);
return findKotlinSourceFile(lookupDirector, frame);
} finally {
lookupDirector.setFindDuplicates(isFindDuplicates);
}
}
@Nullable
private IFile findKotlinSourceFile(@NotNull ISourceLookupDirector lookupDirector, @NotNull IJavaStackFrame frame) throws CoreException {
String sourceName = frame.getSourceName();
if (sourceName == null) return null;
FqName declaringPackage = new FqName(frame.getDeclaringTypeName()).parent();
for (ISourceContainer sourceContainer : lookupDirector.getSourceContainers()) {
Object[] elements = sourceContainer.findSourceElements(sourceName);
for (Object element : elements) {
if (!(element instanceof IFile)) {
continue;
}
IFile kotlinFile = (IFile) element;
if (fileMatches(kotlinFile, declaringPackage, sourceName)) {
return kotlinFile;
}
}
}
return null;
}
private boolean fileMatches(@NotNull IFile kotlinFile, @NotNull FqName packageName, @NotNull String sourceName) {
boolean isKotlinSourceFile = kotlinFile.getName().equals(sourceName) && KotlinPsiManager.INSTANCE.existsSourceFile(kotlinFile);
if (isKotlinSourceFile) {
KtFile jetFile = KotlinPsiManager.INSTANCE.getParsedFile(kotlinFile);
if (jetFile.getPackageFqName().equals(packageName)) {
return true;
}
}
return false;
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/filesystem/EnvironmentRemnantNature.kt
================================================
/*
* Copyright 2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.core.filesystem
import org.eclipse.core.resources.IProject
import org.eclipse.core.resources.IProjectNature
class EnvironmentRemnantNature: IProjectNature {
companion object {
const val NATURE_ID = "org.jetbrains.kotlin.core.environmentRemnant"
}
private lateinit var _project: IProject
override fun setProject(project: IProject) {
_project = project
}
override fun configure() {
// nothing to do
}
override fun deconfigure() {
// nothing to do
}
override fun getProject() = _project
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/filesystem/KotlinFileStore.kt
================================================
/*******************************************************************************
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package org.jetbrains.kotlin.core.filesystem
import org.eclipse.core.filesystem.IFileInfo
import org.eclipse.core.filesystem.IFileStore
import org.eclipse.core.filesystem.IFileSystem
import org.eclipse.core.filesystem.provider.FileInfo
import org.eclipse.core.internal.filesystem.local.LocalFile
import org.eclipse.core.resources.IContainer
import org.eclipse.core.resources.IFile
import org.eclipse.core.resources.IProject
import org.eclipse.core.resources.IResource
import org.eclipse.core.resources.ResourcesPlugin
import org.eclipse.core.runtime.CoreException
import org.eclipse.core.runtime.IPath
import org.eclipse.core.runtime.IProgressMonitor
import org.eclipse.core.runtime.Path
import org.eclipse.core.runtime.Status
import org.eclipse.jdt.internal.compiler.util.Util
import org.jetbrains.kotlin.core.asJava.KotlinLightClassGeneration
import org.jetbrains.kotlin.core.model.KotlinAnalysisProjectCache
import org.jetbrains.kotlin.core.resolve.KotlinAnalyzer
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.InputStream
import java.io.OutputStream
import java.net.URI
public class KotlinFileStore(file: File) : LocalFile(file) {
override public fun openInputStream(options: Int, monitor: IProgressMonitor?): InputStream {
val project = getProject()
if (project == null) {
throw CoreException(Status.CANCEL_STATUS)
}
val lightClass = KotlinLightClassManager.getInstance(project).getCachedLightClass(file)
if (lightClass != null) {
return ByteArrayInputStream(lightClass)
}
val jetFiles = KotlinLightClassManager.getInstance(project).getSourceFiles(file)
if (jetFiles.isNotEmpty()) {
val analysisResult = KotlinAnalyzer.analyzeFiles(jetFiles).analysisResult
val requestedClassName = Path(file.getAbsolutePath()).lastSegment()
val state = KotlinLightClassGeneration.buildLightClasses(analysisResult, project, jetFiles, requestedClassName)
val generatedClass = state.factory.asList().find {
val generatedClassName = Path(it.relativePath).lastSegment()
requestedClassName == generatedClassName
}
if (generatedClass != null) {
val byteArray = generatedClass.asByteArray()
KotlinLightClassManager.getInstance(project).cacheLightClass(file, byteArray)
return ByteArrayInputStream(byteArray)
}
}
throw CoreException(Status.CANCEL_STATUS)
}
override public fun fetchInfo(options: Int, monitor: IProgressMonitor?): IFileInfo {
val info = super.fetchInfo(options, monitor) as FileInfo
if (Util.isClassFileName(getName())) {
val workspaceFile = findFileInWorkspace()
if (workspaceFile != null) {
info.setExists(workspaceFile.exists())
}
} else {
val workspaceContainer = findFolderInWorkspace()
if (workspaceContainer != null) {
info.setExists(workspaceContainer.exists())
info.setDirectory(true)
}
}
return info
}
override public fun childNames(options: Int, monitor: IProgressMonitor?): Array {
val folder = findFolderInWorkspace()
if (folder != null && folder.exists()) {
return folder.members()
.map { it.getName() }
.toTypedArray()
}
return emptyArray()
}
override fun getFileSystem(): IFileSystem = KotlinFileSystem.getInstance()
override public fun mkdir(options: Int, monitor: IProgressMonitor?): IFileStore = this
override public fun openOutputStream(options: Int, monitor: IProgressMonitor?): OutputStream = ByteArrayOutputStream()
override public fun getChild(name: String): IFileStore = KotlinFileStore(File(file, name))
override public fun getChild(path: IPath): IFileStore = KotlinFileStore(File(file, path.toOSString()))
override public fun getFileStore(path: IPath): IFileStore = KotlinFileStore(Path(file.getPath()).append(path).toFile())
override public fun getParent(): IFileStore? = file.getParentFile()?.let { KotlinFileStore(it) }
fun getProject(): IProject? = findFileInWorkspace()?.let { it.project }
private fun findFileInWorkspace(): IFile? {
return findResourceInWorkspace { ResourcesPlugin.getWorkspace().root.findFilesForLocationURI(it) }
}
private fun findFolderInWorkspace(): IContainer? {
return findResourceInWorkspace { ResourcesPlugin.getWorkspace().root.findContainersForLocationURI(it) }
}
private inline fun findResourceInWorkspace(search: (URI) -> Array?): T? {
val absolutePath = file.toURI().path
val pathRelatedToKtFileSystem = URI(KotlinFileSystem.SCHEME, null, absolutePath, null)
val resources = search(pathRelatedToKtFileSystem)
return if (resources != null && resources.isNotEmpty()) {
assert(resources.size == 1, { "By ${pathRelatedToKtFileSystem} found more than one file" })
resources[0]
} else {
null
}
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/filesystem/KotlinFileSystem.java
================================================
package org.jetbrains.kotlin.core.filesystem;
import java.io.File;
import java.net.URI;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.IFileTree;
import org.eclipse.core.filesystem.provider.FileSystem;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
public class KotlinFileSystem extends FileSystem {
public static final String SCHEME = "org.jetbrains.kotlin.core.filesystem";
private static KotlinFileSystem instance;
public KotlinFileSystem() {
instance = this;
}
@Override
public IFileStore getStore(URI uri) {
return new KotlinFileStore(new File(uri.getSchemeSpecificPart()));
}
@Override
public boolean canDelete() {
return true;
}
@Override
public boolean canWrite() {
return true;
}
public static KotlinFileSystem getInstance() {
return instance;
}
@Override
public IFileTree fetchFileTree(IFileStore root, IProgressMonitor monitor) throws CoreException {
return super.fetchFileTree(root, monitor);
}
}
================================================
FILE: kotlin-eclipse-core/src/org/jetbrains/kotlin/core/filesystem/KotlinLightClassManager.kt
================================================
package org.jetbrains.kotlin.core.filesystem
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.eclipse.core.internal.jobs.JobStatus
import org.eclipse.core.resources.*
import org.eclipse.core.runtime.*
import org.eclipse.jdt.core.JavaCore
import org.eclipse.jdt.internal.core.util.LRUCache
import org.jetbrains.kotlin.core.asJava.LightClassFile
import org.jetbrains.kotlin.core.builder.KotlinPsiManager.getFilesByProject
import org.jetbrains.kotlin.core.builder.KotlinPsiManager.getKotlinParsedFile
import org.jetbrains.kotlin.core.builder.KotlinPsiManager.getParsedFile
import org.jetbrains.kotlin.core.log.KotlinLogger.logAndThrow
import org.jetbrains.kotlin.core.model.KotlinEnvironment.Companion.getEnvironment
import org.jetbrains.kotlin.core.model.KotlinJavaManager
import org.jetbrains.kotlin.core.model.KotlinJavaManager.getKotlinBinFolderFor
import org.jetbrains.kotlin.core.utils.ProjectUtils.cleanFolder
import org.jetbrains.kotlin.core.utils.ProjectUtils.getAllOutputFolders
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import java.io.File
import java.io.IOException
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
import kotlin.text.Charsets.UTF_8
class KotlinLightClassManager(private val project: IProject) {
private val cachedLightClasses = LRUCache(LIGHT_CLASSES_CACHE_SIZE)
private val sourceFiles: ConcurrentMap> = ConcurrentHashMap()
@Synchronized
fun getCachedLightClass(file: File): ByteArray? {
val lightClass: Any? = cachedLightClasses[file]
return if (lightClass != null) lightClass as ByteArray? else null
}
@Synchronized
fun cacheLightClass(file: File, lightClass: ByteArray) {
cachedLightClasses.put(file, lightClass)
}
@Synchronized
fun removeLightClass(file: File) {
cachedLightClasses.flush(file)
val tempFolders = getAllOutputFolders(JavaCore.create(project))
val tempSegments = file.path.split("[/\\\\]".toRegex()).toTypedArray()
val tempRealPath = tempSegments.copyOfRange(3, tempSegments.size)
for (tempFolder in tempFolders) {
val tempRootFolder = tempFolder.location.toFile()
var tempCurrentFolder = tempRootFolder
for ((tempIndex, tempSegment) in tempRealPath.withIndex()) {
if (tempIndex == tempRealPath.lastIndex) {
val tempFile = File(tempCurrentFolder, tempSegment).takeIf { it.exists() } ?: break
val tempTouchedFilesFile = File(tempRootFolder, KOTLIN_TOUCHED_FILES_FILE_NAME)
try {
if (!tempTouchedFilesFile.exists()) tempTouchedFilesFile.createNewFile()
val tempLines = tempTouchedFilesFile.readLines(UTF_8).toMutableSet()
tempLines.add(tempFile.absolutePath)
tempTouchedFilesFile.writeText(tempLines.joinToString("\n"), UTF_8)
} catch (e: IOException) {
e.printStackTrace()
}
} else {
tempCurrentFolder = File(tempCurrentFolder, tempSegment).takeIf { it.exists() } ?: break
}
}
}
}
fun computeLightClassesSources() {
val newSourceFilesMap: MutableMap> = HashMap()
for (sourceFile in getFilesByProject(project)) {
val lightClassesPaths = getLightClassesPaths(sourceFile)
for (path in lightClassesPaths) {
val lightClassFile = LightClassFile(project.getFile(path))
val newSourceFiles = newSourceFilesMap.computeIfAbsent(lightClassFile.asFile()) { HashSet() }
newSourceFiles.add(sourceFile)
}
}
sourceFiles.clear()
sourceFiles.putAll(newSourceFilesMap)
}
fun updateLightClasses(affectedFiles: Set, resourceTreeBlocked: Boolean) {
val toCreate: MutableList = ArrayList()
val toRemove: MutableList = ArrayList()
for ((key, value) in sourceFiles) {
val lightClassIFile = ResourcesPlugin.getWorkspace().root.getFile(Path(key.path))
?: continue
val lightClassFile = LightClassFile(lightClassIFile)
if (!lightClassFile.exists()) {
toCreate.add(lightClassFile)
}
for (sourceFile in value) {
if (affectedFiles.contains(sourceFile)) {
toRemove.add(lightClassFile)
break
}
}
}
if (resourceTreeBlocked) {
if (toCreate.isNotEmpty() || toRemove.isNotEmpty()) {
val job: WorkspaceJob = object : WorkspaceJob(WORKSPACE_JOB_ID) {
override fun runInWorkspace(monitor: IProgressMonitor): IStatus {
monitor.beginTask("Light class generation started", 0)
updateLightClasses(toCreate, toRemove)
monitor.done()
return JobStatus(0, this, "Light classes generation finished")
}
}
job.rule = ResourcesPlugin.getWorkspace().ruleFactory.createRule(
project.getFolder(KotlinJavaManager.KOTLIN_BIN_FOLDER))
job.schedule()
}
} else {
updateLightClasses(toCreate, toRemove)
}
}
private fun updateLightClasses(toCreate: List, toRemove: List) {
for (lightClassFile in toCreate) {
createParentDirsFor(lightClassFile)
lightClassFile.createIfNotExists()
}
for (lightClassFile in toRemove) {
removeLightClass(lightClassFile.asFile())
lightClassFile.touchFile()
}
cleanOutdatedLightClasses(project)
}
fun getSourceFiles(file: File): List {
if (sourceFiles.isEmpty()) {
computeLightClassesSources()
}
return getSourceKtFiles(file)
}
private fun getSourceKtFiles(lightClass: File): List {
val sourceIOFiles: Set? = sourceFiles[lightClass]
if (sourceIOFiles != null) {
val jetSourceFiles: MutableList = ArrayList()
for (sourceFile in sourceIOFiles) {
val jetFile = getKotlinParsedFile(sourceFile)
if (jetFile != null) {
jetSourceFiles.add(jetFile)
}
}
return jetSourceFiles
}
return emptyList()
}
private fun getLightClassesPaths(sourceFile: IFile): List {
val lightClasses: MutableList = ArrayList()
val ktFile = getParsedFile(sourceFile)
for (classOrObject in findLightClasses(ktFile)) {
val internalName = getInternalName(classOrObject)
if (internalName != null) {
lightClasses.add(computePathByInternalName(internalName))
}
}
if (ktFile.hasTopLevelCallables()) {
val newFacadeInternalName = JvmFileClassUtil.getFileClassInternalName(ktFile)
lightClasses.add(computePathByInternalName(newFacadeInternalName))
}
return lightClasses
}
private fun findLightClasses(ktFile: KtFile): List