├── pictures ├── Settings.png ├── Training.gif ├── Inspection.gif ├── Refactoring.gif └── JB_IRen_plugin_logo.png ├── experiments ├── README.md ├── tables │ ├── kotlin │ │ ├── str.png │ │ ├── Top 100.png │ │ ├── str 10.png │ │ └── top40 sting literals intellij-community.png │ └── python │ │ ├── All str.png │ │ ├── top100.png │ │ └── All text.png ├── src │ └── main │ │ ├── resources │ │ ├── intentionDescriptions │ │ │ ├── SuggestionIntentionAction │ │ │ │ ├── after.suggest.variable.names.template │ │ │ │ ├── before.suggest.variable.names.template │ │ │ │ └── description.html │ │ │ └── SuggestVariableNamesIntention │ │ │ │ ├── after.suggestion.intention.template │ │ │ │ ├── before.ssuggestion.intention.template │ │ │ │ └── description.html │ │ ├── inspectionDescriptions │ │ │ ├── VariableNamesInspection.html │ │ │ ├── MethodNamesInspection.html │ │ │ └── IfStatementInspection.html │ │ ├── META-INF │ │ │ ├── java.xml │ │ │ ├── python.xml │ │ │ └── kotlin.xml │ │ ├── MessageBundle.properties │ │ └── messages │ │ │ └── IdNamesSuggestingBundle.properties │ │ ├── kotlin │ │ └── experiments │ │ │ ├── predictions.kt │ │ │ ├── compareWithRAM │ │ │ ├── RamPluginRunner.kt │ │ │ └── RamVarNamer.kt │ │ │ ├── compareWithDefault │ │ │ ├── DefaultPluginRunner.kt │ │ │ └── DefaultVarNamer.kt │ │ │ ├── dobfEvaluator │ │ │ ├── DOBFPluginRunner.kt │ │ │ └── DOBFVarNamer.kt │ │ │ ├── gnnEvaluator │ │ │ ├── GNNPluginRunner.kt │ │ │ └── GNNVarNamer.kt │ │ │ ├── onnxEvaluator │ │ │ ├── ONNXPluginRunner.kt │ │ │ └── ONNXVarNamer.kt │ │ │ ├── transformerEvaluator │ │ │ ├── TransformerPluginRunner.kt │ │ │ └── TransformerVarNamer.kt │ │ │ └── cacheSize │ │ │ └── CacheSizePluginRunner.kt │ │ └── java │ │ ├── tools │ │ ├── graphVarMiner │ │ │ └── AstGraphCreator.java │ │ └── varMiner │ │ │ └── VariableFeatures.java │ │ └── utils │ │ └── ChunkWriter.java ├── CHANGELOG.md ├── build.gradle.kts └── .run │ └── modelsEvaluator.run.xml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── languages ├── common │ ├── build.gradle.kts │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── messages │ │ │ │ └── Rename.properties │ │ │ ├── kotlin │ │ │ └── org │ │ │ │ └── jetbrains │ │ │ │ └── iren │ │ │ │ ├── DOBFModelRunner.kt │ │ │ │ ├── services │ │ │ │ └── DOBFModelManager.kt │ │ │ │ ├── inspections │ │ │ │ └── variable │ │ │ │ │ ├── VariableNamesInspection.kt │ │ │ │ │ └── RenameVariableQuickFix.kt │ │ │ │ ├── IRenVariableNameSuggestionProvider.kt │ │ │ │ └── DOBFTokenizer.kt │ │ │ └── java │ │ │ └── org │ │ │ └── jetbrains │ │ │ └── iren │ │ │ ├── config │ │ │ ├── ModelType.java │ │ │ └── InferenceStrategies.java │ │ │ ├── utils │ │ │ ├── DOBFModelUtils.java │ │ │ ├── RenameBundle.java │ │ │ ├── LimitedTimeRunner.java │ │ │ ├── IdeaUtil.java │ │ │ └── StringUtils.java │ │ │ ├── services │ │ │ ├── NGramModelsUsabilityService.java │ │ │ ├── RenameHistory.java │ │ │ ├── NGramModelManager.java │ │ │ └── IRenSuggestingService.java │ │ │ ├── rename │ │ │ ├── IRenMemberInplaceRenameHandler.java │ │ │ ├── IRenVariableInplaceRenameHandler.java │ │ │ ├── IRenLookups.java │ │ │ └── IRenLookupExpression.java │ │ │ ├── VariableNamesContributor.java │ │ │ ├── ModelRunner.java │ │ │ └── storages │ │ │ └── VarNamePrediction.java │ └── test │ │ └── org │ │ └── jetbrains │ │ └── iren │ │ ├── CollisionTest.java │ │ ├── GetDOBFContextTest.java │ │ ├── ParsingTest.java │ │ ├── LexFileTest.java │ │ ├── VariableTest.java │ │ ├── GetContextTest.java │ │ └── LanguageSupporterTest.java ├── kotlin │ ├── testData │ │ ├── parsing │ │ │ ├── code │ │ │ │ ├── localVariable.kt │ │ │ │ ├── parameter.kt │ │ │ │ └── property.kt │ │ │ ├── lexed │ │ │ │ ├── localVariable.json │ │ │ │ ├── parameter.json │ │ │ │ └── property.json │ │ │ ├── context │ │ │ │ ├── localVariable.json │ │ │ │ ├── parameter.json │ │ │ │ └── property.json │ │ │ └── dobfContext │ │ │ │ ├── localVariable.json │ │ │ │ ├── parameter.json │ │ │ │ └── property.json │ │ ├── collision │ │ │ ├── localVariable.kt │ │ │ ├── parameter.kt │ │ │ └── field.kt │ │ ├── variable │ │ │ ├── notVariable.kt │ │ │ ├── notVariableDeclaration.kt │ │ │ └── variableDeclaration.kt │ │ └── inspection.kt │ ├── build.gradle.kts │ ├── test │ │ └── org │ │ │ └── jetbrains │ │ │ └── iren │ │ │ ├── KotlinInspectionHeuristicsTest.java │ │ │ ├── KotlinLexFiletTest.java │ │ │ ├── KotlinGetContextTest.java │ │ │ ├── KotlinGetDOBFContextTest.java │ │ │ ├── KotlinVariableTest.java │ │ │ └── KotlinCollisionTest.java │ └── src │ │ └── org │ │ └── jetbrains │ │ └── iren │ │ ├── KotlinVariableVisitor.kt │ │ └── rename │ │ ├── IRenKotlinVariableInplaceRenameHandler.kt │ │ ├── IRenKotlinVariableInplaceRenamer.kt │ │ ├── IRenKotlinMemeberInplaceRenamer.kt │ │ └── IRenKotlinMemberInplaceRenameHandler.kt ├── python │ ├── testData │ │ ├── parsing │ │ │ ├── code │ │ │ │ ├── localVariable.py │ │ │ │ ├── parameter.py │ │ │ │ └── field.py │ │ │ ├── lexed │ │ │ │ ├── localVariable.json │ │ │ │ ├── parameter.json │ │ │ │ └── field.json │ │ │ ├── context │ │ │ │ ├── localVariable.json │ │ │ │ ├── parameter.json │ │ │ │ └── field.json │ │ │ └── dobfContext │ │ │ │ ├── localVariable.json │ │ │ │ ├── parameter.json │ │ │ │ └── field.json │ │ ├── variable │ │ │ ├── notVariable.py │ │ │ ├── variableDeclaration.py │ │ │ └── notVariableDeclaration.py │ │ ├── collision │ │ │ └── parameter.py │ │ └── inspection.py │ ├── build.gradle.kts │ ├── test │ │ └── org │ │ │ └── jetbrains │ │ │ └── iren │ │ │ ├── PyIRenInspectionTest.java │ │ │ ├── PyLexFileTest.java │ │ │ ├── PyGetContextTest.java │ │ │ ├── PyGetDOBFContextTest.java │ │ │ ├── PyCollisionTest.java │ │ │ └── PyVariableTest.java │ └── src │ │ └── org │ │ └── jetbrains │ │ └── iren │ │ ├── PyDOBFTokenizer.kt │ │ └── PyVariableVisitor.kt └── java │ ├── testData │ ├── parsing │ │ ├── code │ │ │ ├── localVariable.java │ │ │ ├── parameter.java │ │ │ └── field.java │ │ ├── context │ │ │ ├── localVariable.json │ │ │ ├── parameter.json │ │ │ └── field.json │ │ ├── lexed │ │ │ ├── localVariable.json │ │ │ ├── parameter.json │ │ │ └── field.json │ │ └── dobfContext │ │ │ ├── localVariable.json │ │ │ ├── parameter.json │ │ │ └── field.json │ ├── collision │ │ ├── localVariable.java │ │ ├── parameter.java │ │ └── field.java │ ├── variable │ │ ├── notVariable.java │ │ ├── variableDeclaration.java │ │ └── notVariableDeclaration.java │ └── inspection.java │ ├── build.gradle.kts │ ├── test │ └── org │ │ └── jetbrains │ │ └── iren │ │ ├── JavaIRenInspectionTest.java │ │ ├── JavaLexFileTest.java │ │ ├── JavaGetContextTest.java │ │ ├── JavaGetDOBFContextTest.java │ │ ├── JavaVariableTest.java │ │ └── JavaCollisionTest.java │ └── src │ └── org │ └── jetbrains │ └── iren │ └── JavaVariableVisitor.kt ├── plugin ├── src │ └── main │ │ ├── resources │ │ ├── intentionDescriptions │ │ │ └── SuggestionIntentionAction │ │ │ │ ├── after.suggest.variable.names.template │ │ │ │ ├── before.suggest.variable.names.template │ │ │ │ └── description.html │ │ ├── inspectionDescriptions │ │ │ ├── VariableNamesInspection.html │ │ │ ├── MethodNamesInspection.html │ │ │ └── IfStatementInspection.html │ │ ├── META-INF │ │ │ ├── java.xml │ │ │ ├── python.xml │ │ │ ├── kotlin.xml │ │ │ └── pluginIcon.svg │ │ └── messages │ │ │ └── IRen.properties │ │ ├── java │ │ ├── org │ │ │ └── jetbrains │ │ │ │ └── iren │ │ │ │ ├── application │ │ │ │ ├── AskPermissionsPreloadingActivity.java │ │ │ │ ├── ProjectOpenCloseListener.java │ │ │ │ └── PluginLoadedListener.java │ │ │ │ ├── api │ │ │ │ └── AbstractTrainModelAction.java │ │ │ │ ├── training │ │ │ │ ├── MemoryListener.java │ │ │ │ └── ProgressBar.java │ │ │ │ ├── services │ │ │ │ ├── NGramModelsUsabilityServiceImpl.java │ │ │ │ └── NGramModelManagerImpl.java │ │ │ │ ├── IRenBundle.java │ │ │ │ ├── contributors │ │ │ │ └── ProjectVariableNamesContributor.java │ │ │ │ ├── impl │ │ │ │ └── TrainProjectNGramModelAction.java │ │ │ │ ├── storages │ │ │ │ └── StringCounter.java │ │ │ │ └── statistics │ │ │ │ ├── IRenCollectorExtension.java │ │ │ │ └── IRenLookupUsageDescriptor.java │ │ └── com │ │ │ └── intellij │ │ │ └── completion │ │ │ └── ngram │ │ │ └── slp │ │ │ └── counting │ │ │ └── trie │ │ │ └── my │ │ │ ├── persistent │ │ │ └── PersistentCounter.java │ │ │ └── ArrayStorage.java │ │ └── kotlin │ │ └── org │ │ └── jetbrains │ │ └── iren │ │ ├── application │ │ └── ProjectOpenActivity.kt │ │ ├── utils │ │ ├── CommonUtils.kt │ │ └── OrtUtils.kt │ │ ├── services │ │ └── DOBFModelManagerImpl.kt │ │ ├── search │ │ └── BeamHypothesis.kt │ │ ├── settings │ │ └── AppSettingsState.kt │ │ ├── contributors │ │ ├── DOBFContributor.kt │ │ └── DOBFContributorKInference.kt │ │ └── models │ │ └── OrtModel.kt └── README.md ├── qodana.yml ├── astrid ├── src │ └── org │ │ └── jetbrains │ │ └── astrid │ │ ├── enums │ │ └── OSType.kt │ │ ├── extractors │ │ ├── common │ │ │ ├── MethodContent.kt │ │ │ └── Common.kt │ │ ├── features │ │ │ ├── ProgramRelation.kt │ │ │ ├── ProgramFeatures.kt │ │ │ └── Extractor.kt │ │ └── visitors │ │ │ ├── LeavesVisitor.kt │ │ │ └── FunctionVisitor.kt │ │ ├── inspections │ │ ├── ifstatement │ │ │ └── IfStatementProvider.kt │ │ ├── method │ │ │ └── MethodNamesProvider.kt │ │ └── Suggestion.kt │ │ ├── model │ │ └── PredictionModel.kt │ │ ├── utils │ │ ├── PathUtils.kt │ │ └── FileUtils.kt │ │ ├── stats │ │ └── RenameMethodStatistics.kt │ │ ├── helpers │ │ └── TensorConverter.java │ │ └── actions │ │ └── SuggestionListPopupStep.kt ├── build.gradle.kts └── plugin.xml ├── settings.gradle.kts ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── gradle.properties └── .gitignore /pictures/Settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/pictures/Settings.png -------------------------------------------------------------------------------- /pictures/Training.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/pictures/Training.gif -------------------------------------------------------------------------------- /pictures/Inspection.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/pictures/Inspection.gif -------------------------------------------------------------------------------- /pictures/Refactoring.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/pictures/Refactoring.gif -------------------------------------------------------------------------------- /experiments/README.md: -------------------------------------------------------------------------------- 1 | 2 | Run experiments in headless mode. 3 | -------------------------------------------------------------------------------- /pictures/JB_IRen_plugin_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/pictures/JB_IRen_plugin_logo.png -------------------------------------------------------------------------------- /experiments/tables/kotlin/str.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/experiments/tables/kotlin/str.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /experiments/tables/kotlin/Top 100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/experiments/tables/kotlin/Top 100.png -------------------------------------------------------------------------------- /experiments/tables/kotlin/str 10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/experiments/tables/kotlin/str 10.png -------------------------------------------------------------------------------- /experiments/tables/python/All str.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/experiments/tables/python/All str.png -------------------------------------------------------------------------------- /experiments/tables/python/top100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/experiments/tables/python/top100.png -------------------------------------------------------------------------------- /experiments/tables/python/All text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/experiments/tables/python/All text.png -------------------------------------------------------------------------------- /languages/common/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation("org.jetbrains.intellij.deps.completion:ngram-slp:0.0.3") 3 | } -------------------------------------------------------------------------------- /plugin/src/main/resources/intentionDescriptions/SuggestionIntentionAction/after.suggest.variable.names.template: -------------------------------------------------------------------------------- 1 | String firstName = obj.getFirstName() 2 | -------------------------------------------------------------------------------- /plugin/src/main/resources/intentionDescriptions/SuggestionIntentionAction/before.suggest.variable.names.template: -------------------------------------------------------------------------------- 1 | String lastName = obj.getFirstName() 2 | -------------------------------------------------------------------------------- /experiments/src/main/resources/intentionDescriptions/SuggestionIntentionAction/after.suggest.variable.names.template: -------------------------------------------------------------------------------- 1 | String firstName = obj.getFirstName() 2 | -------------------------------------------------------------------------------- /experiments/src/main/resources/intentionDescriptions/SuggestionIntentionAction/before.suggest.variable.names.template: -------------------------------------------------------------------------------- 1 | String lastName = obj.getFirstName() 2 | -------------------------------------------------------------------------------- /experiments/src/main/resources/intentionDescriptions/SuggestVariableNamesIntention/after.suggestion.intention.template: -------------------------------------------------------------------------------- 1 | String firstName = obj.getFirstName() 2 | -------------------------------------------------------------------------------- /experiments/src/main/resources/intentionDescriptions/SuggestVariableNamesIntention/before.ssuggestion.intention.template: -------------------------------------------------------------------------------- 1 | String fistName = obj.getLastName() 2 | -------------------------------------------------------------------------------- /qodana.yml: -------------------------------------------------------------------------------- 1 | # Qodana configuration: 2 | # https://www.jetbrains.com/help/qodana/qodana-yaml.html 3 | 4 | version: 1.0 5 | profile: 6 | name: qodana.recommended 7 | -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/code/localVariable.kt: -------------------------------------------------------------------------------- 1 | package parsing.code 2 | 3 | fun main(args: Array) { 4 | var i = 239 5 | i = i + 42 6 | } 7 | -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/enums/OSType.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.enums 2 | 3 | enum class OSType { 4 | WINDOWS, 5 | MACOS, 6 | LINUX, 7 | OTHER 8 | } -------------------------------------------------------------------------------- /plugin/src/main/resources/inspectionDescriptions/VariableNamesInspection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Detects inconsistent variable names in the current file.

4 | 5 | -------------------------------------------------------------------------------- /plugin/src/main/resources/intentionDescriptions/SuggestionIntentionAction/description.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | This intention generates method name suggestions 4 | 5 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "IRen" 2 | 3 | include("plugin", "experiments", "astrid", 4 | "languages:common", "languages:java", "languages:kotlin", "languages:python") 5 | -------------------------------------------------------------------------------- /experiments/src/main/resources/inspectionDescriptions/VariableNamesInspection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Detects inconsistent variable names in the current file.

4 | 5 | -------------------------------------------------------------------------------- /experiments/src/main/resources/intentionDescriptions/SuggestionIntentionAction/description.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | This intention generates method name suggestions 4 | 5 | -------------------------------------------------------------------------------- /experiments/src/main/resources/intentionDescriptions/SuggestVariableNamesIntention/description.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Suggests a list of consistent variable names.

4 | 5 | -------------------------------------------------------------------------------- /experiments/tables/kotlin/top40 sting literals intellij-community.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JetBrains-Research/IRen/HEAD/experiments/tables/kotlin/top40 sting literals intellij-community.png -------------------------------------------------------------------------------- /languages/python/testData/parsing/code/localVariable.py: -------------------------------------------------------------------------------- 1 | def sum41(): 2 | a = 0 3 | for i in range(41): 4 | a += i 5 | if a == 820: 6 | print("""Rock! 7 | Yeah!""") -------------------------------------------------------------------------------- /plugin/src/main/resources/inspectionDescriptions/MethodNamesInspection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Inspection is intended for suggesting better method names for methods in the project. 4 | 5 | -------------------------------------------------------------------------------- /experiments/src/main/resources/inspectionDescriptions/MethodNamesInspection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Inspection is intended for suggesting better method names for methods in the project. 4 | 5 | -------------------------------------------------------------------------------- /languages/common/src/main/resources/messages/Rename.properties: -------------------------------------------------------------------------------- 1 | # Inspection 2 | inspection.group.key=IRen plugin 3 | inspection.family.name=Suggest variable names 4 | inspection.description.template=Inconsistent variable name -------------------------------------------------------------------------------- /languages/java/testData/parsing/code/localVariable.java: -------------------------------------------------------------------------------- 1 | package testData.parsing.code; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | int i = 239; 6 | i = i + 42; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/extractors/common/MethodContent.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.extractors.common 2 | 3 | import com.github.javaparser.ast.Node 4 | 5 | class MethodContent(val leaves: ArrayList, val name: String, val length: Long) -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/code/parameter.kt: -------------------------------------------------------------------------------- 1 | package parsing.code 2 | 3 | class Parameter { 4 | fun foo(args: Array) { 5 | if (args.isNotEmpty()) { 6 | val s = args[0] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /languages/kotlin/testData/collision/localVariable.kt: -------------------------------------------------------------------------------- 1 | package collision 2 | 3 | const val boi = 0 4 | 5 | fun main(collision1: Array) { 6 | var i = 239 7 | val collision2 = 42 8 | i += + collision2 9 | println(boi == i) 10 | } 11 | -------------------------------------------------------------------------------- /languages/java/build.gradle.kts: -------------------------------------------------------------------------------- 1 | intellij { 2 | this.plugins.set(listOf(Plugins.java)) 3 | } 4 | 5 | dependencies { 6 | implementation(project(":languages:common")) 7 | 8 | testImplementation(project(":languages:common").dependencyProject.sourceSets["test"].output) 9 | } -------------------------------------------------------------------------------- /plugin/src/main/resources/META-INF/java.xml: -------------------------------------------------------------------------------- 1 | 2 | com.intellij.java 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /experiments/src/main/resources/META-INF/java.xml: -------------------------------------------------------------------------------- 1 | 2 | com.intellij.java 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /languages/kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | intellij { 2 | this.plugins.set(listOf(Plugins.java, Plugins.kotlin)) 3 | } 4 | 5 | dependencies { 6 | implementation(project(":languages:common")) 7 | 8 | testImplementation(project(":languages:common").dependencyProject.sourceSets["test"].output) 9 | } -------------------------------------------------------------------------------- /languages/python/build.gradle.kts: -------------------------------------------------------------------------------- 1 | intellij { 2 | this.plugins.set(listOf(Plugins.java, Plugins.python)) 3 | } 4 | 5 | dependencies { 6 | implementation(project(":languages:common")) 7 | 8 | testImplementation(project(":languages:common").dependencyProject.sourceSets["test"].output) 9 | } -------------------------------------------------------------------------------- /experiments/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # experiments-plugin Changelog 4 | 5 | ## [Unreleased] 6 | ### Added 7 | - Initial scaffold created from [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template) 8 | -------------------------------------------------------------------------------- /plugin/src/main/resources/META-INF/python.xml: -------------------------------------------------------------------------------- 1 | 2 | com.intellij.modules.python 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /experiments/src/main/resources/META-INF/python.xml: -------------------------------------------------------------------------------- 1 | 2 | com.intellij.modules.python 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /languages/java/testData/collision/localVariable.java: -------------------------------------------------------------------------------- 1 | package testData.collision; 2 | 3 | public class Main { 4 | int boi = 0; 5 | public static void main(String[] collision1) { 6 | int i = 239; 7 | int collision2 = 42; 8 | boi = i + collision2; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /languages/kotlin/testData/collision/parameter.kt: -------------------------------------------------------------------------------- 1 | package collision 2 | 3 | class Foo { 4 | var boi: Int = 0 5 | fun main(args: Array, collision: Int) { 6 | boi = args.size 7 | if (args.isNotEmpty()) { 8 | val i = args[0] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /languages/common/src/main/kotlin/org/jetbrains/iren/DOBFModelRunner.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren 2 | 3 | import com.intellij.psi.PsiNameIdentifierOwner 4 | import org.jetbrains.iren.storages.VarNamePrediction 5 | 6 | interface DOBFModelRunner { 7 | fun predict(variable: PsiNameIdentifierOwner): List 8 | } -------------------------------------------------------------------------------- /languages/java/testData/collision/parameter.java: -------------------------------------------------------------------------------- 1 | package testData.collision; 2 | 3 | public class Main { 4 | int boi = 0; 5 | public static void main(String[] args, int collision1) { 6 | boi = args.length; 7 | if (args.length > 0) 8 | String collision2 = args[0] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /languages/java/testData/parsing/code/parameter.java: -------------------------------------------------------------------------------- 1 | package testData.parsing.code; 2 | 3 | public class Main { 4 | String myText = """Parsing test!!! 5 | ¯\\_(ツ)_/¯"""; 6 | 7 | public static void main(String[] args) { 8 | if (args.length > 0) 9 | String s = args[0] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /plugin/src/main/resources/inspectionDescriptions/IfStatementInspection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Inspection is intended for detecting long if-statement conditions. Inspection extracts condition's body, creates new method in the current class, put the condition's body into new method, generates name for the it and adds method call to the if-statement condition. 4 | 5 | -------------------------------------------------------------------------------- /experiments/src/main/resources/inspectionDescriptions/IfStatementInspection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Inspection is intended for detecting long if-statement conditions. Inspection extracts condition's body, creates new method in the current class, put the condition's body into new method, generates name for the it and adds method call to the if-statement condition. 4 | 5 | -------------------------------------------------------------------------------- /languages/python/testData/variable/notVariable.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Generator: 5 | def generate_int(self, seed: int): 6 | print(f"Initialize seed with {seed}") 7 | random.seed(seed) 8 | return random.randint(0, 42) 9 | 10 | 11 | if __name__ == "__main__": 12 | g = Generator() 13 | print(g.generate_int(42)) 14 | -------------------------------------------------------------------------------- /languages/python/testData/variable/variableDeclaration.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Generator: 5 | def generate_int(self, seed: int): 6 | print(f"Initialize seed with {seed}") 7 | random.seed(seed) 8 | return random.randint(0, 42) 9 | 10 | 11 | if __name__ == "__main__": 12 | g = Generator() 13 | print(g.generate_int(42)) 14 | -------------------------------------------------------------------------------- /languages/python/testData/variable/notVariableDeclaration.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Generator: 5 | def generate_int(self, seed: int): 6 | print(f"Initialize seed with {seed}") 7 | random.seed(seed) 8 | return random.randint(0, 42) 9 | 10 | 11 | if __name__ == "__main__": 12 | g = Generator() 13 | print(g.generate_int(42)) 14 | -------------------------------------------------------------------------------- /languages/java/testData/parsing/code/field.java: -------------------------------------------------------------------------------- 1 | package testData.parsing.code; 2 | 3 | public class MyClass { 4 | public int myField = 0; 5 | 6 | public void setField(int field) { 7 | this.myField = field; 8 | } 9 | 10 | public static void main(String[] args) { 11 | MyClass instance = new MyClass(); 12 | instance.myField = 1; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /languages/python/testData/parsing/code/parameter.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Generator: 5 | def generate_int(self, seed: int): 6 | print(f"Initialize seed with {seed}", 7 | "Bugaga") 8 | random.seed(seed) 9 | return random.randint(0, 42) 10 | 11 | 12 | if __name__ == "__main__": 13 | g = Generator() 14 | print(g.generate_int(42)) 15 | -------------------------------------------------------------------------------- /astrid/build.gradle.kts: -------------------------------------------------------------------------------- 1 | intellij { 2 | this.plugins.set(listOf(Plugins.java)) 3 | } 4 | 5 | dependencies { 6 | // implementation("org.tensorflow", "tensorflow", "1.13.1") 7 | implementation("com.github.javaparser:javaparser-core:3.0.0-alpha.4") 8 | implementation("net.razorvine", "pyrolite", "4.19") 9 | implementation("org.eclipse.mylyn.github", "org.eclipse.egit.github.core", "2.1.5") 10 | } -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/inspections/ifstatement/IfStatementProvider.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.inspections.ifstatement 2 | 3 | import com.intellij.codeInspection.InspectionToolProvider 4 | 5 | class IfStatementProvider : InspectionToolProvider { 6 | override fun getInspectionClasses(): Array> { 7 | return arrayOf(IfStatementInspection::class.java) 8 | } 9 | } -------------------------------------------------------------------------------- /languages/python/testData/parsing/code/field.py: -------------------------------------------------------------------------------- 1 | class Foo: 2 | def __init__(self, v: int): 3 | self.my_field = v 4 | ustr = u"\u2156" 5 | rstr = r"\u2156" 6 | s = "\x34\x63\u2435" 7 | 8 | def print_field(self): 9 | print(self.my_field) 10 | 11 | 12 | if __name__ == "__main__": 13 | foo = Foo(42) 14 | foo.my_field = 239 15 | foo.print_field() -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/extractors/features/ProgramRelation.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.extractors.features 2 | 3 | class ProgramRelation(private val source: Property, private val target: Property, private val path: String) { 4 | 5 | override fun toString(): String { 6 | return String.format("%s,%s,%s", source.getName(), path, 7 | target.getName()) 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /languages/python/testData/collision/parameter.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Generator: 5 | def generate_int(self, seed: int, collision=42): 6 | print(f"Initialize seed with {seed}") 7 | random.seed(seed) 8 | boi = "Hello :)" 9 | return random.randint(0, collision) 10 | 11 | 12 | if __name__ == "__main__": 13 | g = Generator() 14 | print(g.generate_int(42)) 15 | -------------------------------------------------------------------------------- /languages/java/testData/collision/field.java: -------------------------------------------------------------------------------- 1 | package testData.collision; 2 | 3 | public class MyClass { 4 | public int myField = 0; 5 | public static int collision = 1; 6 | 7 | public void setField(int boi) { 8 | myField = boi; 9 | } 10 | 11 | public static void main(String[] args) { 12 | MyClass instance = new MyClass(); 13 | instance.myField = 1; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /languages/java/testData/variable/notVariable.java: -------------------------------------------------------------------------------- 1 | package testData.variable; 2 | 3 | public class MyClass { 4 | public int myField = 0; 5 | public static int collision = 1; 6 | 7 | public void setField(int boi) { 8 | myField = boi; 9 | } 10 | 11 | public static void main(String[] args) { 12 | MyClass instance = new MyClass(); 13 | instance.myField = 1; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/lexed/localVariable.json: -------------------------------------------------------------------------------- 1 | [ 2 | "package", 3 | "parsing", 4 | ".", 5 | "code", 6 | "fun", 7 | "main", 8 | "(", 9 | "args", 10 | ":", 11 | "Array", 12 | "\u003c", 13 | "String", 14 | "\u003e", 15 | ")", 16 | "{", 17 | "var", 18 | "i", 19 | "\u003d", 20 | "\u003cnum\u003e", 21 | "i", 22 | "\u003d", 23 | "i", 24 | "+", 25 | "\u003cnum\u003e", 26 | "}" 27 | ] -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/predictions.kt: -------------------------------------------------------------------------------- 1 | package experiments 2 | 3 | class VarNamePredictions( 4 | val groundTruth: String, 5 | val nGramPrediction: ModelPredictions, 6 | val nnPrediction: Any, 7 | val psiInterface: String, 8 | val inplaceRenameAvailable: Boolean 9 | ) 10 | 11 | class ModelPrediction(val name: Any, val p: Double) 12 | 13 | open class ModelPredictions(val predictions: Any, val time: Double) -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/config/ModelType.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.config; 2 | 3 | public enum ModelType { 4 | DEFAULT("default"), NGRAM("ngram"), DOBF("dobf"), BOTH("both"); 5 | 6 | private final String text; 7 | 8 | ModelType(final String text) { 9 | this.text = text; 10 | } 11 | 12 | @Override 13 | public String toString() { 14 | return text; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/compareWithRAM/RamPluginRunner.kt: -------------------------------------------------------------------------------- 1 | package experiments.compareWithRAM 2 | 3 | import experiments.modelsEvaluatorApi.PluginRunner 4 | import experiments.modelsEvaluatorApi.VarNamer 5 | 6 | class RamPluginRunner : PluginRunner() { 7 | override val projectList: List? = listOf("libgdx") 8 | 9 | override val varNamer: VarNamer 10 | get() = RamVarNamer(saveDir, supporter, ngramType) 11 | } 12 | -------------------------------------------------------------------------------- /languages/java/testData/variable/variableDeclaration.java: -------------------------------------------------------------------------------- 1 | package testData.variable; 2 | 3 | public class MyClass { 4 | public int myField = 0; 5 | public static int collision = 1; 6 | 7 | public void setField(int boi) { 8 | myField = boi; 9 | } 10 | 11 | public static void main(String[] args) { 12 | MyClass instance = new MyClass(); 13 | instance.myField = 1; 14 | } 15 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/config/InferenceStrategies.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.config; 2 | 3 | import java.util.Set; 4 | 5 | public class InferenceStrategies { 6 | public static final Set ALL = Set.of(ModelType.DEFAULT, ModelType.NGRAM, ModelType.DOBF); 7 | public static final Set NGRAM_ONLY = Set.of(ModelType.NGRAM); 8 | public static final Set DOBF_ONLY = Set.of(ModelType.DOBF); 9 | } 10 | -------------------------------------------------------------------------------- /languages/python/testData/parsing/lexed/localVariable.json: -------------------------------------------------------------------------------- 1 | [ 2 | "def", 3 | "sum41", 4 | "(", 5 | ")", 6 | ":", 7 | "a", 8 | "\u003d", 9 | "0", 10 | "for", 11 | "i", 12 | "in", 13 | "range", 14 | "(", 15 | "\u003cnum\u003e", 16 | ")", 17 | ":", 18 | "a", 19 | "+\u003d", 20 | "i", 21 | "if", 22 | "a", 23 | "\u003d\u003d", 24 | "\u003cnum\u003e", 25 | ":", 26 | "print", 27 | "(", 28 | "\u003cstr\u003e", 29 | ")" 30 | ] -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/model/PredictionModel.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.model 2 | 3 | //import Downloader.getPathToBeamModule 4 | 5 | class PredictionModel { 6 | companion object{ 7 | fun buildModel(): ByteArray? { 8 | // val beamSearchPath = getPathToBeamModule() 9 | // return if (beamSearchPath != null) org.tensorflow.TensorFlow.loadLibrary(beamSearchPath) else null 10 | return null 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /languages/java/testData/variable/notVariableDeclaration.java: -------------------------------------------------------------------------------- 1 | package testData.variable; 2 | 3 | public class MyClass { 4 | public int myField = 0; 5 | public static int collision = 1; 6 | 7 | public void setField(int boi) { 8 | myField = boi; 9 | } 10 | 11 | public static void main(String[] args) { 12 | MyClass instance = new MyClass(); 13 | instance.myField = 1; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /languages/kotlin/testData/collision/field.kt: -------------------------------------------------------------------------------- 1 | package collision 2 | 3 | class MyClass(not_collision: Boolean, val collision1: Int = 0) { 4 | var myField = 0 5 | private val collision2 = 1 6 | fun setField(boi: Int) { 7 | myField = boi 8 | } 9 | 10 | companion object { 11 | @JvmStatic 12 | fun main(args: Array) { 13 | val instance = MyClass(true) 14 | instance.myField = 1 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /languages/kotlin/testData/variable/notVariable.kt: -------------------------------------------------------------------------------- 1 | package variable 2 | 3 | class MyClass2(not_collision: Boolean, val collision1: Int = 0) { 4 | var myField = 0 5 | private val collision2 = 1 6 | fun setField(boi: Int) { 7 | myField = boi 8 | } 9 | 10 | companion object { 11 | @JvmStatic 12 | fun main(args: Array) { 13 | val instance = MyClass2(true) 14 | instance.myField = 1 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/application/AskPermissionsPreloadingActivity.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.application; 2 | 3 | import com.intellij.openapi.application.PreloadingActivity; 4 | 5 | import static org.jetbrains.iren.utils.NotificationsUtil.askPermissions; 6 | 7 | @SuppressWarnings("UnstableApiUsage") 8 | public class AskPermissionsPreloadingActivity extends PreloadingActivity { 9 | @Override 10 | public void preload() { 11 | askPermissions(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/compareWithDefault/DefaultPluginRunner.kt: -------------------------------------------------------------------------------- 1 | package experiments.compareWithDefault 2 | 3 | import experiments.modelsEvaluatorApi.PluginRunner 4 | import experiments.modelsEvaluatorApi.VarNamer 5 | 6 | class DefaultPluginRunner : PluginRunner() { 7 | override val projectList: List? = null // listOf("libgdx")// listOf("intellij-community") 8 | 9 | override val varNamer: VarNamer 10 | get() = DefaultVarNamer(saveDir, supporter, ngramType) 11 | } 12 | -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/context/localVariable.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "fun", 4 | "main", 5 | "(", 6 | "args", 7 | ":", 8 | "Array", 9 | "\u003c", 10 | "String", 11 | "\u003e", 12 | ")", 13 | "{", 14 | "var", 15 | "i", 16 | "\u003d", 17 | "\u003cnum\u003e", 18 | "i", 19 | "\u003d", 20 | "i", 21 | "+", 22 | "\u003cnum\u003e", 23 | "}" 24 | ], 25 | "varIdxs": [ 26 | 12, 27 | 15, 28 | 17 29 | ] 30 | } -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/code/property.kt: -------------------------------------------------------------------------------- 1 | package parsing.code 2 | 3 | class MyClass { 4 | var myField = 0 5 | val myText = """Parsing test!!! Number: $myField 6 | ¯\_(ツ)_/¯""" 7 | 8 | fun setField(field: Int) { 9 | this.myField = field 10 | } 11 | 12 | companion object { 13 | @JvmStatic 14 | fun main(args: Array) { 15 | val instance = MyClass() 16 | instance.myField = 1 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /languages/kotlin/testData/variable/notVariableDeclaration.kt: -------------------------------------------------------------------------------- 1 | package variable 2 | 3 | class MyClass3(not_collision: Boolean, val collision1: Int = 0) { 4 | var myField = 0 5 | private val collision2 = 1 6 | fun setField(boi: Int) { 7 | myField = boi 8 | } 9 | 10 | companion object { 11 | @JvmStatic 12 | fun main(args: Array) { 13 | val instance = MyClass3(true) 14 | instance.myField = 1 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /languages/java/testData/parsing/context/localVariable.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "public", 4 | "static", 5 | "void", 6 | "main", 7 | "(", 8 | "String", 9 | "[", 10 | "]", 11 | "args", 12 | ")", 13 | "{", 14 | "int", 15 | "i", 16 | "\u003d", 17 | "\u003cnum\u003e", 18 | ";", 19 | "i", 20 | "\u003d", 21 | "i", 22 | "+", 23 | "\u003cnum\u003e", 24 | ";", 25 | "}" 26 | ], 27 | "varIdxs": [ 28 | 12, 29 | 16, 30 | 18 31 | ] 32 | } -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/inspections/method/MethodNamesProvider.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.inspections.method 2 | 3 | import com.intellij.codeInspection.InspectionToolProvider 4 | import org.jetbrains.astrid.downloader.Downloader.checkArchive 5 | 6 | class MethodNamesProvider : InspectionToolProvider { 7 | init { 8 | checkArchive() 9 | } 10 | 11 | override fun getInspectionClasses(): Array> { 12 | return arrayOf(MethodNamesInspection::class.java) 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /languages/kotlin/testData/variable/variableDeclaration.kt: -------------------------------------------------------------------------------- 1 | package variable 2 | 3 | class MyClass4(not_collision: Boolean, val collision1: Int = 0) { 4 | var myField = 0 5 | private val collision2 = 1 6 | fun setField(boi: Int) { 7 | myField = boi 8 | } 9 | 10 | companion object { 11 | @JvmStatic 12 | fun main(args: Array) { 13 | val instance = MyClass4(true) 14 | instance.myField = 1 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/dobfContext/localVariable.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "package", 4 | "parsing", 5 | ".", 6 | "code", 7 | "fun", 8 | "main", 9 | "(", 10 | "args", 11 | ":", 12 | "Array", 13 | "\u003c", 14 | "String", 15 | "\u003e", 16 | ")", 17 | "{", 18 | "var", 19 | "i", 20 | "\u003d", 21 | "239", 22 | "i", 23 | "\u003d", 24 | "i", 25 | "+", 26 | "42", 27 | "}" 28 | ], 29 | "varIdxs": [ 30 | 16, 31 | 19, 32 | 21 33 | ] 34 | } -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/application/ProjectOpenActivity.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.application 2 | 3 | import com.intellij.openapi.project.Project 4 | import com.intellij.openapi.startup.StartupActivity 5 | import org.jetbrains.iren.LanguageSupporter 6 | import org.jetbrains.iren.training.ModelBuilder 7 | 8 | class ProjectOpenActivity : StartupActivity.Background { 9 | override fun runActivity(project: Project) { 10 | LanguageSupporter.removeRenameHandlers() 11 | ModelBuilder.prepareIRenModels(project) 12 | } 13 | } -------------------------------------------------------------------------------- /languages/java/testData/parsing/lexed/localVariable.json: -------------------------------------------------------------------------------- 1 | [ 2 | "package", 3 | "testData", 4 | ".", 5 | "parsing", 6 | ".", 7 | "code", 8 | ";", 9 | "public", 10 | "class", 11 | "Main", 12 | "{", 13 | "public", 14 | "static", 15 | "void", 16 | "main", 17 | "(", 18 | "String", 19 | "[", 20 | "]", 21 | "args", 22 | ")", 23 | "{", 24 | "int", 25 | "i", 26 | "\u003d", 27 | "\u003cnum\u003e", 28 | ";", 29 | "i", 30 | "\u003d", 31 | "i", 32 | "+", 33 | "\u003cnum\u003e", 34 | ";", 35 | "}", 36 | "}" 37 | ] -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/lexed/parameter.json: -------------------------------------------------------------------------------- 1 | [ 2 | "package", 3 | "parsing", 4 | ".", 5 | "code", 6 | "class", 7 | "Parameter", 8 | "{", 9 | "fun", 10 | "foo", 11 | "(", 12 | "args", 13 | ":", 14 | "Array", 15 | "\u003c", 16 | "String", 17 | "\u003e", 18 | ")", 19 | "{", 20 | "if", 21 | "(", 22 | "args", 23 | ".", 24 | "isNotEmpty", 25 | "(", 26 | ")", 27 | ")", 28 | "{", 29 | "val", 30 | "s", 31 | "\u003d", 32 | "args", 33 | "[", 34 | "0", 35 | "]", 36 | "}", 37 | "}", 38 | "}" 39 | ] -------------------------------------------------------------------------------- /languages/java/testData/parsing/context/parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "public", 4 | "static", 5 | "void", 6 | "main", 7 | "(", 8 | "String", 9 | "[", 10 | "]", 11 | "args", 12 | ")", 13 | "{", 14 | "if", 15 | "(", 16 | "args", 17 | ".", 18 | "length", 19 | "\u003e", 20 | "0", 21 | ")", 22 | "String", 23 | "s", 24 | "\u003d", 25 | "args", 26 | "[", 27 | "0", 28 | "]", 29 | "}" 30 | ], 31 | "varIdxs": [ 32 | 8, 33 | 13, 34 | 22 35 | ] 36 | } -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/utils/CommonUtils.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.utils 2 | 3 | import com.intellij.openapi.progress.ProcessCanceledException 4 | import com.intellij.openapi.progress.ProgressManager 5 | 6 | 7 | /** 8 | * Returns new list with appended [item] 9 | */ 10 | fun List.append(item: T) = listOf(this, listOf(item)).flatten() 11 | 12 | fun isCancelled(): Boolean { 13 | return try { 14 | ProgressManager.checkCanceled() 15 | false 16 | } catch (_: ProcessCanceledException) { 17 | true 18 | } 19 | } -------------------------------------------------------------------------------- /plugin/src/main/resources/META-INF/kotlin.xml: -------------------------------------------------------------------------------- 1 | 2 | org.jetbrains.kotlin 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /experiments/src/main/resources/META-INF/kotlin.xml: -------------------------------------------------------------------------------- 1 | 2 | org.jetbrains.kotlin 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/context/parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "fun", 4 | "foo", 5 | "(", 6 | "args", 7 | ":", 8 | "Array", 9 | "\u003c", 10 | "String", 11 | "\u003e", 12 | ")", 13 | "{", 14 | "if", 15 | "(", 16 | "args", 17 | ".", 18 | "isNotEmpty", 19 | "(", 20 | ")", 21 | ")", 22 | "{", 23 | "val", 24 | "s", 25 | "\u003d", 26 | "args", 27 | "[", 28 | "0", 29 | "]", 30 | "}", 31 | "}" 32 | ], 33 | "varIdxs": [ 34 | 3, 35 | 13, 36 | 23 37 | ] 38 | } -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/application/ProjectOpenCloseListener.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.application; 2 | 3 | import com.intellij.openapi.project.Project; 4 | import com.intellij.openapi.project.ProjectManagerListener; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.iren.services.NGramModelManager; 7 | 8 | public class ProjectOpenCloseListener implements ProjectManagerListener { 9 | @Override 10 | public void projectClosed(@NotNull Project project) { 11 | NGramModelManager.getInstance(project).removeProjectModelRunners(project); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /languages/python/testData/parsing/context/localVariable.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "def", 4 | "sum41", 5 | "(", 6 | ")", 7 | ":", 8 | "a", 9 | "\u003d", 10 | "0", 11 | "for", 12 | "i", 13 | "in", 14 | "range", 15 | "(", 16 | "\u003cnum\u003e", 17 | ")", 18 | ":", 19 | "a", 20 | "+\u003d", 21 | "i", 22 | "if", 23 | "a", 24 | "\u003d\u003d", 25 | "\u003cnum\u003e", 26 | ":", 27 | "print", 28 | "(", 29 | "\u003cstr\u003e", 30 | ")" 31 | ], 32 | "varIdxs": [ 33 | 5, 34 | 16, 35 | 20 36 | ] 37 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/utils/DOBFModelUtils.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.utils; 2 | 3 | import com.intellij.lang.Language; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class DOBFModelUtils extends ModelUtils { 7 | @Override 8 | public @NotNull String getModelsDirectoryName() { 9 | return "DOBF_models"; 10 | } 11 | 12 | @Override 13 | public @NotNull String getVersion() { 14 | return "1"; 15 | } 16 | 17 | public @NotNull String getName(@NotNull Language language) { 18 | return language.getDisplayName() + "_" + getVersion(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /languages/java/test/org/jetbrains/iren/JavaIRenInspectionTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.ide.highlighter.JavaFileType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class JavaIRenInspectionTest extends IRenInspectionTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return JavaFileType.DOT_DEFAULT_EXTENSION; 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new JavaLanguageSupporter(); 15 | } 16 | 17 | public void testInspection() { 18 | doTestInspection(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/dobfEvaluator/DOBFPluginRunner.kt: -------------------------------------------------------------------------------- 1 | package experiments.dobfEvaluator 2 | 3 | import com.intellij.completion.ngram.slp.counting.trie.my.persistent.CountersCache 4 | import experiments.modelsEvaluatorApi.PluginRunner 5 | import experiments.modelsEvaluatorApi.VarNamer 6 | 7 | class DOBFPluginRunner : PluginRunner() { 8 | 9 | override val projectList = null 10 | override val resumeEvaluation = true 11 | 12 | override val varNamer: VarNamer 13 | get() { 14 | CountersCache.MAXIMUM_CACHE_SIZE = 10_000 15 | return DOBFVarNamer(saveDir, supporter, ngramType) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /languages/java/src/org/jetbrains/iren/JavaVariableVisitor.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren 2 | 3 | import com.intellij.codeInspection.ProblemsHolder 4 | import com.intellij.psi.JavaElementVisitor 5 | import com.intellij.psi.PsiVariable 6 | import org.jetbrains.iren.utils.RenameUtils 7 | 8 | class JavaVariableVisitor(private val holder: ProblemsHolder, private val isOnTheFly: Boolean) : JavaElementVisitor() { 9 | override fun visitVariable(variable: PsiVariable) { 10 | try { 11 | RenameUtils.visitVariable(variable, holder, isOnTheFly) 12 | } finally { 13 | super.visitVariable(variable) 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /languages/python/test/org/jetbrains/iren/PyIRenInspectionTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.jetbrains.python.PythonFileType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class PyIRenInspectionTest extends IRenInspectionTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return "." + PythonFileType.INSTANCE.getDefaultExtension(); 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new PyLanguageSupporter(); 15 | } 16 | 17 | public void testInspection() { 18 | doTestInspection(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /experiments/src/main/resources/MessageBundle.properties: -------------------------------------------------------------------------------- 1 | report.error.to.plugin.vendor=Report error to plugin vendor 2 | report.error.progress.dialog.text=Submitting error report... 3 | report.error.connection.failure=Could not communicate with GitHub.\n\ 4 | Please create issue. 5 | git.issue.text=Created issue {1}. Thank you for your feedback! \n\ 6 | Make sure you have the latest plugin version. 7 | git.issue.duplicate.text=A similar issues was already reported (#{1}). \n\ 8 | Thank you for your feedback! Make sure you have the latest plugin version. -------------------------------------------------------------------------------- /languages/kotlin/test/org/jetbrains/iren/KotlinInspectionHeuristicsTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.kotlin.idea.KotlinFileType; 5 | 6 | public class KotlinInspectionHeuristicsTest extends IRenInspectionTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return "." + KotlinFileType.EXTENSION; 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new KotlinLanguageSupporter(); 15 | } 16 | 17 | public void testInspection() { 18 | doTestInspection(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /languages/java/testData/parsing/lexed/parameter.json: -------------------------------------------------------------------------------- 1 | [ 2 | "package", 3 | "testData", 4 | ".", 5 | "parsing", 6 | ".", 7 | "code", 8 | ";", 9 | "public", 10 | "class", 11 | "Main", 12 | "{", 13 | "String", 14 | "myText", 15 | "\u003d", 16 | "\u003cstr\u003e", 17 | ";", 18 | "public", 19 | "static", 20 | "void", 21 | "main", 22 | "(", 23 | "String", 24 | "[", 25 | "]", 26 | "args", 27 | ")", 28 | "{", 29 | "if", 30 | "(", 31 | "args", 32 | ".", 33 | "length", 34 | "\u003e", 35 | "0", 36 | ")", 37 | "String", 38 | "s", 39 | "\u003d", 40 | "args", 41 | "[", 42 | "0", 43 | "]", 44 | "}", 45 | "}" 46 | ] -------------------------------------------------------------------------------- /experiments/src/main/resources/messages/IdNamesSuggestingBundle.properties: -------------------------------------------------------------------------------- 1 | name=Id Names Suggesting Plugin 2 | intention.text=Suggest variable name 3 | training.task.title=Building project id suggesting model 4 | training.progress.indicator.text=Training model for {0}... 5 | global.training.task.title=Building global id suggesting model 6 | global.training.progress.indicator.text=Training global model for {0}... 7 | loading.global.model=Loading global model 8 | saving.global.model=Saving global model 9 | loading.file=Loading: {0} 10 | building.dataset.title=Building dataset... 11 | building.dataset.for.project=Building dataset for project {0}... 12 | saving.dataset=Saving dataset... 13 | -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/api/AbstractTrainModelAction.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.api; 2 | 3 | import com.intellij.openapi.actionSystem.AnAction; 4 | import com.intellij.openapi.actionSystem.AnActionEvent; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public abstract class AbstractTrainModelAction extends AnAction { 8 | @Override 9 | public void actionPerformed(@NotNull AnActionEvent e) { 10 | if (canBePerformed(e)) { 11 | doActionPerformed(e); 12 | } 13 | } 14 | 15 | protected abstract void doActionPerformed(@NotNull AnActionEvent e); 16 | 17 | protected abstract boolean canBePerformed(@NotNull AnActionEvent e); 18 | } 19 | -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/gnnEvaluator/GNNPluginRunner.kt: -------------------------------------------------------------------------------- 1 | package experiments.gnnEvaluator 2 | 3 | import experiments.modelsEvaluatorApi.PluginRunner 4 | import experiments.modelsEvaluatorApi.VarNamer 5 | 6 | class GNNPluginRunner : PluginRunner() { 7 | override val javaSmallTrain = listOf( 8 | "cassandra", "elasticsearch", "gradle", "hibernate-orm", "intellij-community", 9 | "liferay-portal", "presto", "spring-framework", "wildfly" 10 | ) 11 | override val javaSmallTest = 12 | listOf("libgdx", "hadoop") 13 | // listOf("TestProject") 14 | 15 | override val varNamer: VarNamer 16 | get() = GNNVarNamer(saveDir, supporter, ngramType) 17 | } 18 | -------------------------------------------------------------------------------- /languages/common/src/main/kotlin/org/jetbrains/iren/services/DOBFModelManager.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.services 2 | 3 | import com.intellij.lang.Language 4 | import com.intellij.openapi.Disposable 5 | import com.intellij.openapi.application.ApplicationManager 6 | import org.jetbrains.iren.DOBFModelRunner 7 | 8 | interface DOBFModelManager : Disposable { 9 | fun get(language: Language): DOBFModelRunner? 10 | fun put(language: Language, modelRunner: DOBFModelRunner) 11 | fun remove(language: Language) 12 | 13 | companion object { 14 | val instance: DOBFModelManager 15 | get() = ApplicationManager.getApplication().getService(DOBFModelManager::class.java) 16 | } 17 | } -------------------------------------------------------------------------------- /languages/java/testData/parsing/dobfContext/localVariable.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "package", 4 | "testData", 5 | ".", 6 | "parsing", 7 | ".", 8 | "code", 9 | ";", 10 | "public", 11 | "class", 12 | "Main", 13 | "{", 14 | "public", 15 | "static", 16 | "void", 17 | "main", 18 | "(", 19 | "String", 20 | "[", 21 | "]", 22 | "args", 23 | ")", 24 | "{", 25 | "int", 26 | "i", 27 | "\u003d", 28 | "239", 29 | ";", 30 | "i", 31 | "\u003d", 32 | "i", 33 | "+", 34 | "42", 35 | ";", 36 | "}", 37 | "}" 38 | ], 39 | "varIdxs": [ 40 | 23, 41 | 27, 42 | 29 43 | ] 44 | } -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/onnxEvaluator/ONNXPluginRunner.kt: -------------------------------------------------------------------------------- 1 | package experiments.onnxEvaluator 2 | 3 | import experiments.modelsEvaluatorApi.PluginRunner 4 | import experiments.modelsEvaluatorApi.VarNamer 5 | 6 | class ONNXPluginRunner : PluginRunner() { 7 | override val numProjects = 10 8 | override val projectList: List? = null 9 | // get() = saveDir.parent.resolve("java-med-onnx-2048").listDirectoryEntries("*_BiDirectional.jsonl") 10 | // .map { it.name.replace("_BiDirectional.jsonl", "") } 11 | override val resumeEvaluation: Boolean = true 12 | 13 | override val varNamer: VarNamer 14 | get() = ONNXVarNamer(saveDir, supporter, ngramType) 15 | } 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/services/NGramModelsUsabilityService.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.services; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.project.Project; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public interface NGramModelsUsabilityService { 8 | static @NotNull NGramModelsUsabilityService getInstance(@NotNull Project project) { 9 | return project.getService(NGramModelsUsabilityService.class); 10 | } 11 | 12 | boolean isTraining(); 13 | 14 | void setTraining(boolean training); 15 | 16 | void setUsable(@NotNull String name, boolean b); 17 | 18 | boolean isUsable(@NotNull String name); 19 | } 20 | -------------------------------------------------------------------------------- /astrid/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | org.jetbrains.astrid.actions.SuggestionIntentionAction 5 | Suggestions list 6 | SuggestionIntentionAction 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/dobfContext/parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "package", 4 | "parsing", 5 | ".", 6 | "code", 7 | "class", 8 | "Parameter", 9 | "{", 10 | "fun", 11 | "foo", 12 | "(", 13 | "args", 14 | ":", 15 | "Array", 16 | "\u003c", 17 | "String", 18 | "\u003e", 19 | ")", 20 | "{", 21 | "if", 22 | "(", 23 | "args", 24 | ".", 25 | "isNotEmpty", 26 | "(", 27 | ")", 28 | ")", 29 | "{", 30 | "val", 31 | "s", 32 | "\u003d", 33 | "args", 34 | "[", 35 | "0", 36 | "]", 37 | "}", 38 | "}", 39 | "}" 40 | ], 41 | "varIdxs": [ 42 | 10, 43 | 20, 44 | 30 45 | ] 46 | } -------------------------------------------------------------------------------- /languages/python/testData/parsing/context/parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "def", 4 | "generate_int", 5 | "(", 6 | "self", 7 | ",", 8 | "seed", 9 | ":", 10 | "int", 11 | ")", 12 | ":", 13 | "print", 14 | "(", 15 | "f\"", 16 | "\u003cstr\u003e", 17 | "{", 18 | "seed", 19 | "}", 20 | "\"", 21 | ",", 22 | "\u003cstr\u003e", 23 | ")", 24 | "random", 25 | ".", 26 | "seed", 27 | "(", 28 | "seed", 29 | ")", 30 | "return", 31 | "random", 32 | ".", 33 | "randint", 34 | "(", 35 | "0", 36 | ",", 37 | "\u003cnum\u003e", 38 | ")" 39 | ], 40 | "varIdxs": [ 41 | 5, 42 | 15, 43 | 25 44 | ] 45 | } -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/transformerEvaluator/TransformerPluginRunner.kt: -------------------------------------------------------------------------------- 1 | package experiments.transformerEvaluator 2 | 3 | import experiments.modelsEvaluatorApi.PluginRunner 4 | import experiments.modelsEvaluatorApi.VarNamer 5 | 6 | class TransformerPluginRunner : PluginRunner() { 7 | override val javaSmallTrain = listOf( 8 | "cassandra", "elasticsearch", "gradle", "hibernate-orm", "intellij-community", 9 | "liferay-portal", "presto", "spring-framework", "wildfly" 10 | ) 11 | override val javaSmallTest = 12 | listOf("libgdx", "hadoop") 13 | // listOf("TestProject") 14 | 15 | override val varNamer: VarNamer 16 | get() = TransformerVarNamer(saveDir, supporter, ngramType) 17 | } 18 | -------------------------------------------------------------------------------- /languages/python/testData/inspection.py: -------------------------------------------------------------------------------- 1 | # carets define highlighted elements 2 | import numpy as np 3 | 4 | MODEL_PATH = 239 5 | 6 | 7 | def some_func(param, n=5): 8 | return n * 42 9 | 10 | 11 | class Foo: 12 | def __init__(self, arg): 13 | self.arg = arg 14 | 15 | def print(self, smth): 16 | print(f"Foo: {self.arg}, also {smth}") 17 | 18 | def getCount(self): 19 | return 7 20 | 21 | 22 | class Boo(Foo): 23 | def print(self, a): 24 | x = 0 25 | for i in range(0, 239): 26 | x += i 27 | print(a) 28 | 29 | 30 | if __name__ == "__main__": 31 | foo = Foo(14) 32 | try: 33 | count = foo.getCount() 34 | except Exception as _: 35 | pass 36 | -------------------------------------------------------------------------------- /plugin/src/main/resources/META-INF/pluginIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /languages/kotlin/test/org/jetbrains/iren/KotlinLexFiletTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.kotlin.idea.KotlinFileType; 5 | 6 | public class KotlinLexFiletTest extends LexFileTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return "." + KotlinFileType.EXTENSION; 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new KotlinLanguageSupporter(); 15 | } 16 | 17 | public void testProperty() { doTestSupporterFunction(); } 18 | 19 | public void testParameter() { doTestSupporterFunction(); } 20 | 21 | public void testLocalVariable() { doTestSupporterFunction(); } 22 | } 23 | -------------------------------------------------------------------------------- /languages/python/src/org/jetbrains/iren/PyDOBFTokenizer.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren 2 | 3 | class PyDOBFTokenizer : DOBFTokenizer() { 4 | override val token2char = mapOf( 5 | "STOKEN00" to "#", 6 | "STOKEN1" to "\\n", 7 | "STOKEN2" to "\"\"\"", 8 | "STOKEN3" to "'''", 9 | ) 10 | 11 | override fun String.processWithSTokens(): String { 12 | val res = this.replace("^[ru]".toRegex(), "") 13 | return if (res.contains("\'")) res 14 | else res.replace("^\"".toRegex(), "\' ") 15 | .replace("\"$".toRegex(), " \'") 16 | .replace("^STOKEN2".toRegex(), "STOKEN3 ") 17 | .replace("STOKEN2$".toRegex(), " STOKEN3") 18 | .replace("^f\"".toRegex(), "f\'") 19 | } 20 | } -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/cacheSize/CacheSizePluginRunner.kt: -------------------------------------------------------------------------------- 1 | package experiments.cacheSize 2 | 3 | import com.intellij.openapi.project.Project 4 | import experiments.modelsEvaluatorApi.PluginRunner 5 | import experiments.modelsEvaluatorApi.VarNamer 6 | import org.jetbrains.iren.ngram.NGramModelRunner 7 | import org.jetbrains.iren.ngram.PersistentNGramModelRunner 8 | 9 | open class CacheSizePluginRunner : PluginRunner() { 10 | override val projectList = listOf("intellij-community") 11 | override val varNamer: VarNamer 12 | get() = CacheSizeVarNamer(saveDir, supporter, ngramType) 13 | 14 | override fun trainModelRunner( 15 | project: Project, 16 | ): NGramModelRunner { 17 | return PersistentNGramModelRunner() 18 | } 19 | } -------------------------------------------------------------------------------- /languages/kotlin/test/org/jetbrains/iren/KotlinGetContextTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.kotlin.idea.KotlinFileType; 5 | 6 | public class KotlinGetContextTest extends GetContextTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return "." + KotlinFileType.EXTENSION; 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new KotlinLanguageSupporter(); 15 | } 16 | 17 | public void testProperty() { doTestSupporterFunction(); } 18 | 19 | public void testParameter() { doTestSupporterFunction(); } 20 | 21 | public void testLocalVariable() { doTestSupporterFunction(); } 22 | } 23 | -------------------------------------------------------------------------------- /languages/kotlin/test/org/jetbrains/iren/KotlinGetDOBFContextTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.kotlin.idea.KotlinFileType; 5 | 6 | public class KotlinGetDOBFContextTest extends GetDOBFContextTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return "." + KotlinFileType.EXTENSION; 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new KotlinLanguageSupporter(); 15 | } 16 | 17 | public void testProperty() { doTestSupporterFunction(); } 18 | 19 | public void testParameter() { doTestSupporterFunction(); } 20 | 21 | public void testLocalVariable() { doTestSupporterFunction(); } 22 | } 23 | -------------------------------------------------------------------------------- /languages/common/test/org/jetbrains/iren/CollisionTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.psi.PsiElement; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public abstract class CollisionTest extends LanguageSupporterTest { 7 | @Override 8 | protected @NotNull String getTestDataBasePath() { 9 | return "collision/"; 10 | } 11 | 12 | protected void testCollision(boolean isColliding, String name) { 13 | configureByFile(getTestFileName()); 14 | final LanguageSupporter supporter = getLanguageSupporter(); 15 | final PsiElement variable = getTargetElementAtCaret(); 16 | assertTrue(supporter.isVariableDeclarationOrReference(variable)); 17 | assertEquals(isColliding, supporter.isColliding(variable, name)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /languages/python/testData/parsing/dobfContext/localVariable.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "def", 4 | "sum41", 5 | "(", 6 | ")", 7 | ":", 8 | "NEW_LINE", 9 | "INDENT", 10 | "a", 11 | "\u003d", 12 | "0", 13 | "NEW_LINE", 14 | "for", 15 | "i", 16 | "in", 17 | "range", 18 | "(", 19 | "41", 20 | ")", 21 | ":", 22 | "NEW_LINE", 23 | "INDENT", 24 | "a", 25 | "+\u003d", 26 | "i", 27 | "NEW_LINE", 28 | "DEDENT", 29 | "if", 30 | "a", 31 | "\u003d\u003d", 32 | "820", 33 | ":", 34 | "NEW_LINE", 35 | "INDENT", 36 | "print", 37 | "(", 38 | "\"\"\" Rock ! STRNEWLINE ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ Yeah ! \"\"\"", 39 | ")" 40 | ], 41 | "varIdxs": [ 42 | 7, 43 | 21, 44 | 27 45 | ] 46 | } -------------------------------------------------------------------------------- /languages/java/test/org/jetbrains/iren/JavaLexFileTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.ide.highlighter.JavaFileType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class JavaLexFileTest extends LexFileTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return JavaFileType.DOT_DEFAULT_EXTENSION; 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new JavaLanguageSupporter(); 15 | } 16 | 17 | public void testLocalVariable() { 18 | doTestSupporterFunction(); 19 | } 20 | 21 | public void testParameter() { 22 | doTestSupporterFunction(); 23 | } 24 | 25 | public void testField() { 26 | doTestSupporterFunction(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /languages/python/test/org/jetbrains/iren/PyLexFileTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.jetbrains.python.PythonFileType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class PyLexFileTest extends LexFileTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return "." + PythonFileType.INSTANCE.getDefaultExtension(); 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new PyLanguageSupporter(); 15 | } 16 | 17 | public void testLocalVariable() { 18 | doTestSupporterFunction(); 19 | } 20 | 21 | public void testParameter() { 22 | doTestSupporterFunction(); 23 | } 24 | 25 | public void testField() { 26 | doTestSupporterFunction(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/services/RenameHistory.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.services; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.project.Project; 5 | import com.intellij.psi.PsiNameIdentifierOwner; 6 | import com.intellij.psi.PsiNamedElement; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | public interface RenameHistory { 10 | static @NotNull RenameHistory getInstance(@NotNull Project project) { 11 | return project.getService(RenameHistory.class); 12 | } 13 | 14 | void rememberVariableName(@NotNull String variableHash, @NotNull String insertedName); 15 | 16 | boolean isRenamedVariable(@NotNull PsiNameIdentifierOwner variable); 17 | 18 | String getVariableHash(PsiNamedElement variable, boolean insertName); 19 | } 20 | -------------------------------------------------------------------------------- /languages/java/test/org/jetbrains/iren/JavaGetContextTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.ide.highlighter.JavaFileType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class JavaGetContextTest extends GetContextTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return JavaFileType.DOT_DEFAULT_EXTENSION; 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new JavaLanguageSupporter(); 15 | } 16 | 17 | public void testLocalVariable() { 18 | doTestSupporterFunction(); 19 | } 20 | 21 | public void testParameter() { 22 | doTestSupporterFunction(); 23 | } 24 | 25 | public void testField() { 26 | doTestSupporterFunction(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/rename/IRenMemberInplaceRenameHandler.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.rename; 2 | 3 | import com.intellij.openapi.editor.Editor; 4 | import com.intellij.psi.PsiElement; 5 | import com.intellij.psi.PsiNameIdentifierOwner; 6 | import com.intellij.refactoring.rename.inplace.MemberInplaceRenameHandler; 7 | import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public class IRenMemberInplaceRenameHandler extends MemberInplaceRenameHandler { 11 | @Override 12 | protected @NotNull MemberInplaceRenamer createMemberRenamer(@NotNull PsiElement element, @NotNull PsiNameIdentifierOwner elementToRename, @NotNull Editor editor) { 13 | return new IRenMemberInplaceRenamer(elementToRename, element, editor); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /languages/python/test/org/jetbrains/iren/PyGetContextTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.jetbrains.python.PythonFileType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class PyGetContextTest extends GetContextTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return "." + PythonFileType.INSTANCE.getDefaultExtension(); 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new PyLanguageSupporter(); 15 | } 16 | 17 | public void testLocalVariable() { 18 | doTestSupporterFunction(); 19 | } 20 | 21 | public void testParameter() { 22 | doTestSupporterFunction(); 23 | } 24 | 25 | public void testField() { 26 | doTestSupporterFunction(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - Language: [e.g. Kotlin] 28 | - IDE: [e.g. IntelliJ IDEA] 29 | - Version: [e.g. 2021.3] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /languages/java/test/org/jetbrains/iren/JavaGetDOBFContextTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.ide.highlighter.JavaFileType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class JavaGetDOBFContextTest extends GetDOBFContextTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return JavaFileType.DOT_DEFAULT_EXTENSION; 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new JavaLanguageSupporter(); 15 | } 16 | 17 | public void testLocalVariable() { 18 | doTestSupporterFunction(); 19 | } 20 | 21 | public void testParameter() { 22 | doTestSupporterFunction(); 23 | } 24 | 25 | public void testField() { 26 | doTestSupporterFunction(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /languages/common/test/org/jetbrains/iren/GetDOBFContextTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.psi.PsiElement; 4 | import com.intellij.psi.PsiNameIdentifierOwner; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public abstract class GetDOBFContextTest extends GetContextTest { 8 | @Override 9 | protected @NotNull String getTestFileNameResult() { 10 | return "/dobfContext/" + getTestName(true) + ".json"; 11 | } 12 | 13 | @Override 14 | public Object invokeSupporterFunction() { 15 | @NotNull LanguageSupporter supporter = getLanguageSupporter(); 16 | final PsiElement variable = getTargetElementAtCaret(); 17 | assertTrue(supporter.isVariableDeclarationOrReference(variable)); 18 | return supporter.getDOBFContext((PsiNameIdentifierOwner) variable); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /languages/python/test/org/jetbrains/iren/PyGetDOBFContextTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.jetbrains.python.PythonFileType; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class PyGetDOBFContextTest extends GetDOBFContextTest { 7 | @Override 8 | public @NotNull String getFileExtension() { 9 | return "." + PythonFileType.INSTANCE.getDefaultExtension(); 10 | } 11 | 12 | @Override 13 | public @NotNull LanguageSupporter getLanguageSupporter() { 14 | return new PyLanguageSupporter(); 15 | } 16 | 17 | public void testLocalVariable() { 18 | doTestSupporterFunction(); 19 | } 20 | 21 | public void testParameter() { 22 | doTestSupporterFunction(); 23 | } 24 | 25 | public void testField() { 26 | doTestSupporterFunction(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/rename/IRenVariableInplaceRenameHandler.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.rename; 2 | 3 | import com.intellij.openapi.editor.Editor; 4 | import com.intellij.psi.PsiElement; 5 | import com.intellij.psi.PsiNamedElement; 6 | import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler; 7 | import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.Nullable; 10 | 11 | public class IRenVariableInplaceRenameHandler extends VariableInplaceRenameHandler { 12 | @Override 13 | protected @Nullable VariableInplaceRenamer createRenamer(@NotNull PsiElement elementToRename, @NotNull Editor editor) { 14 | return new IRenVariableInplaceRenamer((PsiNamedElement) elementToRename, editor); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/extractors/features/ProgramFeatures.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.extractors.features 2 | 3 | import java.util.* 4 | 5 | class ProgramFeatures(name: String) { 6 | val features = ArrayList() 7 | val name: String 8 | 9 | init { 10 | this.name = name 11 | } 12 | 13 | override fun toString(): String { 14 | val joiner = StringJoiner(" ") 15 | for (feature in features) { 16 | val toString = feature.toString() 17 | joiner.add(toString) 18 | } 19 | return name + " " + 20 | joiner.toString() 21 | } 22 | 23 | internal fun addFeature(source: Property, path: String, target: Property) { 24 | val newRelation = ProgramRelation(source, target, path) 25 | features.add(newRelation) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /languages/java/testData/parsing/lexed/field.json: -------------------------------------------------------------------------------- 1 | [ 2 | "package", 3 | "testData", 4 | ".", 5 | "parsing", 6 | ".", 7 | "code", 8 | ";", 9 | "public", 10 | "class", 11 | "MyClass", 12 | "{", 13 | "public", 14 | "int", 15 | "myField", 16 | "\u003d", 17 | "0", 18 | ";", 19 | "public", 20 | "void", 21 | "setField", 22 | "(", 23 | "int", 24 | "field", 25 | ")", 26 | "{", 27 | "this", 28 | ".", 29 | "myField", 30 | "\u003d", 31 | "field", 32 | ";", 33 | "}", 34 | "public", 35 | "static", 36 | "void", 37 | "main", 38 | "(", 39 | "String", 40 | "[", 41 | "]", 42 | "args", 43 | ")", 44 | "{", 45 | "MyClass", 46 | "instance", 47 | "\u003d", 48 | "new", 49 | "MyClass", 50 | "(", 51 | ")", 52 | ";", 53 | "instance", 54 | ".", 55 | "myField", 56 | "\u003d", 57 | "1", 58 | ";", 59 | "}", 60 | "}" 61 | ] -------------------------------------------------------------------------------- /languages/common/test/org/jetbrains/iren/ParsingTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | public abstract class ParsingTest extends LanguageSupporterTest { 6 | protected void doTestSupporterFunction() { 7 | configureByFile(getTestFileNameCode()); 8 | Object actual = invokeSupporterFunction(); 9 | Object expected = parseResult(getTestDataPath() + getTestFileNameResult()); 10 | assertEquals(expected, actual); 11 | } 12 | 13 | protected @NotNull String getTestFileNameCode() { 14 | return "/code/" + getTestFileName(); 15 | } 16 | 17 | protected @NotNull String getTestFileNameResult() { 18 | return "/result/" + getTestName(true) + ".txt"; 19 | } 20 | 21 | public abstract Object invokeSupporterFunction(); 22 | 23 | public abstract Object parseResult(String resultFileName); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /languages/python/testData/parsing/lexed/parameter.json: -------------------------------------------------------------------------------- 1 | [ 2 | "import", 3 | "random", 4 | "class", 5 | "Generator", 6 | ":", 7 | "def", 8 | "generate_int", 9 | "(", 10 | "self", 11 | ",", 12 | "seed", 13 | ":", 14 | "int", 15 | ")", 16 | ":", 17 | "print", 18 | "(", 19 | "f\"", 20 | "\u003cstr\u003e", 21 | "{", 22 | "seed", 23 | "}", 24 | "\"", 25 | ",", 26 | "\u003cstr\u003e", 27 | ")", 28 | "random", 29 | ".", 30 | "seed", 31 | "(", 32 | "seed", 33 | ")", 34 | "return", 35 | "random", 36 | ".", 37 | "randint", 38 | "(", 39 | "0", 40 | ",", 41 | "\u003cnum\u003e", 42 | ")", 43 | "if", 44 | "__name__", 45 | "\u003d\u003d", 46 | "\u003cstr\u003e", 47 | ":", 48 | "g", 49 | "\u003d", 50 | "Generator", 51 | "(", 52 | ")", 53 | "print", 54 | "(", 55 | "g", 56 | ".", 57 | "generate_int", 58 | "(", 59 | "\u003cnum\u003e", 60 | ")", 61 | ")" 62 | ] -------------------------------------------------------------------------------- /languages/java/testData/parsing/dobfContext/parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "package", 4 | "testData", 5 | ".", 6 | "parsing", 7 | ".", 8 | "code", 9 | ";", 10 | "public", 11 | "class", 12 | "Main", 13 | "{", 14 | "String", 15 | "myText", 16 | "\u003d", 17 | "\"\"\" Parsing ▁ test ! ! ! STRNEWLINE ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ¯ \\\\ _ ( ツ ) _ / ¯ \"\"\"", 18 | ";", 19 | "public", 20 | "static", 21 | "void", 22 | "main", 23 | "(", 24 | "String", 25 | "[", 26 | "]", 27 | "args", 28 | ")", 29 | "{", 30 | "if", 31 | "(", 32 | "args", 33 | ".", 34 | "length", 35 | "\u003e", 36 | "0", 37 | ")", 38 | "String", 39 | "s", 40 | "\u003d", 41 | "args", 42 | "[", 43 | "0", 44 | "]", 45 | "}", 46 | "}" 47 | ], 48 | "varIdxs": [ 49 | 24, 50 | 29, 51 | 38 52 | ] 53 | } -------------------------------------------------------------------------------- /languages/kotlin/src/org/jetbrains/iren/KotlinVariableVisitor.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren 2 | 3 | import com.intellij.codeInspection.ProblemsHolder 4 | import org.jetbrains.iren.utils.RenameUtils 5 | import org.jetbrains.kotlin.psi.KtParameter 6 | import org.jetbrains.kotlin.psi.KtProperty 7 | import org.jetbrains.kotlin.psi.KtVisitorVoid 8 | 9 | class KotlinVariableVisitor(private val holder: ProblemsHolder, private val isOnTheFly: Boolean) : KtVisitorVoid() { 10 | override fun visitProperty(property: KtProperty) { 11 | try { 12 | RenameUtils.visitVariable(property, holder, isOnTheFly) 13 | } finally { 14 | super.visitProperty(property) 15 | } 16 | } 17 | 18 | override fun visitParameter(parameter: KtParameter) { 19 | try { 20 | RenameUtils.visitVariable(parameter, holder, isOnTheFly) 21 | } finally { 22 | super.visitParameter(parameter) 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /languages/python/testData/parsing/lexed/field.json: -------------------------------------------------------------------------------- 1 | [ 2 | "class", 3 | "Foo", 4 | ":", 5 | "def", 6 | "__init__", 7 | "(", 8 | "self", 9 | ",", 10 | "v", 11 | ":", 12 | "int", 13 | ")", 14 | ":", 15 | "self", 16 | ".", 17 | "my_field", 18 | "\u003d", 19 | "v", 20 | "ustr", 21 | "\u003d", 22 | "\u003cstr\u003e", 23 | "rstr", 24 | "\u003d", 25 | "\u003cstr\u003e", 26 | "s", 27 | "\u003d", 28 | "\u003cstr\u003e", 29 | "def", 30 | "print_field", 31 | "(", 32 | "self", 33 | ")", 34 | ":", 35 | "print", 36 | "(", 37 | "self", 38 | ".", 39 | "my_field", 40 | ")", 41 | "if", 42 | "__name__", 43 | "\u003d\u003d", 44 | "\u003cstr\u003e", 45 | ":", 46 | "foo", 47 | "\u003d", 48 | "Foo", 49 | "(", 50 | "\u003cnum\u003e", 51 | ")", 52 | "foo", 53 | ".", 54 | "my_field", 55 | "\u003d", 56 | "\u003cnum\u003e", 57 | "foo", 58 | ".", 59 | "print_field", 60 | "(", 61 | ")" 62 | ] -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/services/DOBFModelManagerImpl.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.services 2 | 3 | import com.intellij.lang.Language 4 | import org.jetbrains.iren.DOBFModelRunner 5 | 6 | val DOBF_CURRENT_VERSION = 1 7 | 8 | fun getModelName(language: Language) = "${language.displayName}_$DOBF_CURRENT_VERSION" 9 | 10 | class DOBFModelManagerImpl : DOBFModelManager { 11 | private val myModelRunners: MutableMap = HashMap() 12 | 13 | override fun get(language: Language): DOBFModelRunner? { 14 | return myModelRunners[getModelName(language)] 15 | } 16 | 17 | override fun put(language: Language, modelRunner: DOBFModelRunner) { 18 | myModelRunners[getModelName(language)] = modelRunner 19 | } 20 | 21 | override fun remove(language: Language) { 22 | myModelRunners.remove(getModelName(language)) 23 | } 24 | 25 | override fun dispose() { 26 | myModelRunners.clear() 27 | } 28 | } -------------------------------------------------------------------------------- /languages/python/test/org/jetbrains/iren/PyCollisionTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.jetbrains.python.PythonFileType; 4 | import junitparams.JUnitParamsRunner; 5 | import junitparams.Parameters; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith(JUnitParamsRunner.class) 11 | public class PyCollisionTest extends CollisionTest { 12 | @Override 13 | public @NotNull String getFileExtension() { 14 | return "." + PythonFileType.INSTANCE.getDefaultExtension(); 15 | } 16 | 17 | @Override 18 | public @NotNull LanguageSupporter getLanguageSupporter() { 19 | return new PyLanguageSupporter(); 20 | } 21 | 22 | @Test 23 | @Parameters({ 24 | "true, collision", 25 | "false, boi" 26 | }) 27 | public void testParameter(boolean isColliding, String name) { 28 | testCollision(isColliding, name); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /languages/java/testData/parsing/context/field.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "public", 4 | "class", 5 | "MyClass", 6 | "{", 7 | "public", 8 | "int", 9 | "myField", 10 | "\u003d", 11 | "0", 12 | ";", 13 | "public", 14 | "void", 15 | "setField", 16 | "(", 17 | "int", 18 | "field", 19 | ")", 20 | "{", 21 | "this", 22 | ".", 23 | "myField", 24 | "\u003d", 25 | "field", 26 | ";", 27 | "}", 28 | "public", 29 | "static", 30 | "void", 31 | "main", 32 | "(", 33 | "String", 34 | "[", 35 | "]", 36 | "args", 37 | ")", 38 | "{", 39 | "MyClass", 40 | "instance", 41 | "\u003d", 42 | "new", 43 | "MyClass", 44 | "(", 45 | ")", 46 | ";", 47 | "instance", 48 | ".", 49 | "myField", 50 | "\u003d", 51 | "1", 52 | ";", 53 | "}", 54 | "}" 55 | ], 56 | "varIdxs": [ 57 | 6, 58 | 20, 59 | 46 60 | ] 61 | } -------------------------------------------------------------------------------- /languages/python/src/org/jetbrains/iren/PyVariableVisitor.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren 2 | 3 | import com.intellij.codeInspection.ProblemsHolder 4 | import com.jetbrains.python.psi.PyElementVisitor 5 | import com.jetbrains.python.psi.PyNamedParameter 6 | import com.jetbrains.python.psi.PyTargetExpression 7 | import org.jetbrains.iren.utils.RenameUtils 8 | 9 | class PyVariableVisitor(private val holder: ProblemsHolder, private val isOnTheFly: Boolean) : PyElementVisitor() { 10 | override fun visitPyTargetExpression(node: PyTargetExpression) { 11 | try { 12 | RenameUtils.visitVariable(node, holder, isOnTheFly) 13 | } finally { 14 | super.visitPyTargetExpression(node) 15 | } 16 | } 17 | 18 | override fun visitPyNamedParameter(node: PyNamedParameter) { 19 | try { 20 | RenameUtils.visitVariable(node, holder, isOnTheFly) 21 | } finally { 22 | super.visitPyNamedParameter(node) 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/services/NGramModelManager.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.services; 2 | 3 | import com.intellij.openapi.Disposable; 4 | import com.intellij.openapi.project.Project; 5 | import com.intellij.psi.PsiFile; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | import org.jetbrains.iren.ModelRunner; 9 | 10 | public interface NGramModelManager extends Disposable { 11 | static @NotNull NGramModelManager getInstance(@NotNull Project project) { 12 | return project.getService(NGramModelManager.class); 13 | } 14 | 15 | @Nullable ModelRunner get(@NotNull String name); 16 | 17 | void put(@NotNull String name, @NotNull ModelRunner modelRunner); 18 | 19 | void remove(@NotNull String name); 20 | 21 | void removeProjectModelRunners(@NotNull Project project); 22 | 23 | boolean containsIntellijModel(); 24 | 25 | void forgetFileIfNeeded(@NotNull ModelRunner modelRunner, @NotNull PsiFile newFile); 26 | } 27 | -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/lexed/property.json: -------------------------------------------------------------------------------- 1 | [ 2 | "package", 3 | "parsing", 4 | ".", 5 | "code", 6 | "class", 7 | "MyClass", 8 | "{", 9 | "var", 10 | "myField", 11 | "\u003d", 12 | "0", 13 | "val", 14 | "myText", 15 | "\u003d", 16 | "\"\"\"", 17 | "\u003cstr\u003e", 18 | "$", 19 | "myField", 20 | "\u003cstr\u003e", 21 | "\u003cstr\u003e", 22 | "\u003cstr\u003e", 23 | "\"\"\"", 24 | "fun", 25 | "setField", 26 | "(", 27 | "field", 28 | ":", 29 | "Int", 30 | ")", 31 | "{", 32 | "this", 33 | ".", 34 | "myField", 35 | "\u003d", 36 | "field", 37 | "}", 38 | "companion", 39 | "object", 40 | "{", 41 | "@", 42 | "JvmStatic", 43 | "fun", 44 | "main", 45 | "(", 46 | "args", 47 | ":", 48 | "Array", 49 | "\u003c", 50 | "String", 51 | "\u003e", 52 | ")", 53 | "{", 54 | "val", 55 | "instance", 56 | "\u003d", 57 | "MyClass", 58 | "(", 59 | ")", 60 | "instance", 61 | ".", 62 | "myField", 63 | "\u003d", 64 | "1", 65 | "}", 66 | "}", 67 | "}" 68 | ] -------------------------------------------------------------------------------- /languages/kotlin/src/org/jetbrains/iren/rename/IRenKotlinVariableInplaceRenameHandler.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | 3 | package org.jetbrains.iren.rename 4 | 5 | import com.intellij.openapi.editor.Editor 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.psi.PsiNameIdentifierOwner 8 | import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer 9 | import org.jetbrains.kotlin.idea.refactoring.rename.KotlinVariableInplaceRenameHandler 10 | 11 | open class IRenKotlinVariableInplaceRenameHandler : KotlinVariableInplaceRenameHandler() { 12 | override fun createRenamer(elementToRename: PsiElement, editor: Editor): VariableInplaceRenamer? { 13 | val currentElementToRename = elementToRename as PsiNameIdentifierOwner 14 | val currentName = currentElementToRename.nameIdentifier?.text ?: "" 15 | return IRenKotlinVariableInplaceRenamer(currentElementToRename, editor, currentName, currentName) 16 | } 17 | } -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/training/MemoryListener.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.training; 2 | 3 | import com.intellij.openapi.Disposable; 4 | import com.intellij.openapi.util.LowMemoryWatcher; 5 | import org.jetbrains.iren.utils.NotificationsUtil; 6 | 7 | import java.util.concurrent.atomic.AtomicBoolean; 8 | 9 | public class MemoryListener implements Disposable { 10 | private final LowMemoryWatcher memoryWatcher; 11 | final AtomicBoolean canceled = new AtomicBoolean(); 12 | 13 | public MemoryListener() { 14 | memoryWatcher = LowMemoryWatcher.register(this::showNotification, 15 | LowMemoryWatcher.LowMemoryWatcherType.ONLY_AFTER_GC); 16 | } 17 | 18 | private void showNotification() { 19 | if (canceled.compareAndSet(false, true)) { 20 | NotificationsUtil.notEnoughMemoryForTraining(); 21 | } 22 | } 23 | 24 | public boolean shouldCancel() { 25 | return canceled.get(); 26 | } 27 | 28 | @Override 29 | public void dispose() { 30 | memoryWatcher.stop(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /plugin/README.md: -------------------------------------------------------------------------------- 1 | 2 | Provides assistance in variable refactoring. 3 | 4 | This tool replaces default IDE refactoring with the new one 5 | that will recommend you better variable names with the help of Machine Learning methods. 6 | 7 | To suggest consistent names, the IRen model has to train on a project in which you are currently working. 8 | By default, the IRen plugin automatically trains/loads model on a startup of the opened project. 9 | If you want to manually control it, you can switch off the corresponding option in the settings 10 | **Tools | IRen** and launch training by yourself clicking **Refactor | Train IRen Model**. 11 | Also, in the settings, you can tune some hyperparameters of the model. 12 | 13 | IRen inspection helps with maintenance of the code and marks all variables which names are not good enough. 14 | 15 | ### Supported languages: 16 | - Java 17 | - Kotlin 18 | - Python 19 | 20 | ### Issue Tracker 21 | You can file a bug in the [GitHub issue tracker](https://github.com/JetBrains-Research/IRen/issues). 22 | 23 | -------------------------------------------------------------------------------- /languages/java/testData/parsing/dobfContext/field.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "package", 4 | "testData", 5 | ".", 6 | "parsing", 7 | ".", 8 | "code", 9 | ";", 10 | "public", 11 | "class", 12 | "MyClass", 13 | "{", 14 | "public", 15 | "int", 16 | "myField", 17 | "\u003d", 18 | "0", 19 | ";", 20 | "public", 21 | "void", 22 | "setField", 23 | "(", 24 | "int", 25 | "field", 26 | ")", 27 | "{", 28 | "this", 29 | ".", 30 | "myField", 31 | "\u003d", 32 | "field", 33 | ";", 34 | "}", 35 | "public", 36 | "static", 37 | "void", 38 | "main", 39 | "(", 40 | "String", 41 | "[", 42 | "]", 43 | "args", 44 | ")", 45 | "{", 46 | "MyClass", 47 | "instance", 48 | "\u003d", 49 | "new", 50 | "MyClass", 51 | "(", 52 | ")", 53 | ";", 54 | "instance", 55 | ".", 56 | "myField", 57 | "\u003d", 58 | "1", 59 | ";", 60 | "}", 61 | "}" 62 | ], 63 | "varIdxs": [ 64 | 13, 65 | 27, 66 | 53 67 | ] 68 | } -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/services/NGramModelsUsabilityServiceImpl.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.services; 2 | 3 | import com.intellij.util.xmlb.annotations.Transient; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | public class NGramModelsUsabilityServiceImpl implements NGramModelsUsabilityService { 10 | private @Transient final Set myUsable = new HashSet<>(); 11 | private @Transient boolean training = false; 12 | 13 | @Override 14 | public boolean isTraining() { 15 | return training; 16 | } 17 | 18 | @Override 19 | public void setTraining(boolean training) { 20 | this.training = training; 21 | } 22 | 23 | @Override 24 | public void setUsable(@NotNull String name, boolean b) { 25 | if (b) { 26 | myUsable.add(name); 27 | } else { 28 | myUsable.remove(name); 29 | } 30 | } 31 | 32 | @Override 33 | public boolean isUsable(@NotNull String name) { 34 | return myUsable.contains(name); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/compareWithDefault/DefaultVarNamer.kt: -------------------------------------------------------------------------------- 1 | package experiments.compareWithDefault 2 | 3 | import com.intellij.openapi.application.ReadAction 4 | import com.intellij.psi.PsiNameIdentifierOwner 5 | import experiments.ModelPrediction 6 | import experiments.modelsEvaluatorApi.VarNamer 7 | import org.jetbrains.iren.LanguageSupporter 8 | import org.jetbrains.iren.MyJavaNameSuggestionProvider 9 | import java.nio.file.Path 10 | 11 | open class DefaultVarNamer( 12 | saveDir: Path, 13 | supporter: LanguageSupporter, 14 | ngramType: String, 15 | ) : VarNamer(saveDir, supporter, ngramType) { 16 | override var runParallel = true 17 | 18 | override fun predictWithNN(variable: PsiNameIdentifierOwner, thread: Int): Any { 19 | val names = LinkedHashSet() 20 | try { 21 | ReadAction.run { MyJavaNameSuggestionProvider().getSuggestedNames(variable, variable, names) } 22 | } catch (e: Exception) { 23 | e.printStackTrace() 24 | } 25 | return names.map { x: String -> ModelPrediction(x, 0.0) } 26 | } 27 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/services/IRenSuggestingService.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.services; 2 | 3 | import com.intellij.openapi.project.Project; 4 | import com.intellij.psi.PsiNameIdentifierOwner; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.iren.config.ModelType; 7 | import org.jetbrains.iren.storages.Context; 8 | import org.jetbrains.iren.storages.VarNamePrediction; 9 | 10 | import java.util.Collection; 11 | import java.util.List; 12 | 13 | public interface IRenSuggestingService { 14 | int PREDICTION_CUTOFF = 10; 15 | 16 | static IRenSuggestingService getInstance(@NotNull Project project) { 17 | return project.getService(IRenSuggestingService.class); 18 | } 19 | 20 | @NotNull List suggestVariableName(Project project, @NotNull PsiNameIdentifierOwner variable, Collection modelTypes); 21 | 22 | @NotNull Double getVariableNameProbability(@NotNull PsiNameIdentifierOwner variable); 23 | 24 | @NotNull Context.Statistics getVariableContextStatistics(@NotNull PsiNameIdentifierOwner variable); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /experiments/build.gradle.kts: -------------------------------------------------------------------------------- 1 | intellij { 2 | this.plugins.set(listOf(Plugins.java, Plugins.kotlin, Plugins.python)) 3 | } 4 | 5 | dependencies { 6 | implementation(project(":plugin")) 7 | implementation(project(":languages:common")) 8 | implementation(project(":languages:java")) 9 | implementation(project(":languages:kotlin")) 10 | implementation(project(":languages:python")) 11 | implementation("me.tongfei:progressbar:0.9.2") 12 | } 13 | 14 | tasks { 15 | // (graph)ModelsEvaluator part 16 | runIde { 17 | val evaluatorToUse: String? by project 18 | val dataset: String? by project 19 | val saveDir: String? by project 20 | val language: String? by project 21 | val ngramType: String? by project 22 | args = listOfNotNull(evaluatorToUse, dataset, saveDir, language, ngramType) 23 | jvmArgs = listOf( 24 | "-Djava.awt.headless=true", 25 | // "-verbose:gc", 26 | // "-XX:+PrintGCDetails", 27 | // "-Xlog:gc*:/home/igor/IdeaProjects/IRen/gc.log" 28 | ) 29 | maxHeapSize = "32g" 30 | } 31 | } -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/IRenBundle.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.DynamicBundle; 4 | import org.jetbrains.annotations.NonNls; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.PropertyKey; 7 | 8 | import java.util.function.Supplier; 9 | 10 | public class IRenBundle extends DynamicBundle { 11 | @NonNls 12 | private static final String BUNDLE = "messages.IRen"; 13 | private static final IRenBundle INSTANCE = new IRenBundle(); 14 | 15 | private IRenBundle() { 16 | super(BUNDLE); 17 | } 18 | 19 | public static @NotNull String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, 20 | Object @NotNull ... params) { 21 | return INSTANCE.getMessage(key, params); 22 | } 23 | 24 | public static @NotNull Supplier messagePointer(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, 25 | Object @NotNull ... params) { 26 | return INSTANCE.getLazyMessage(key, params); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /experiments/src/main/java/tools/graphVarMiner/AstGraphCreator.java: -------------------------------------------------------------------------------- 1 | package tools.graphVarMiner; 2 | 3 | import com.intellij.psi.JavaRecursiveElementVisitor; 4 | import com.intellij.psi.PsiComment; 5 | import com.intellij.psi.PsiElement; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import static org.jetbrains.iren.utils.DeprecatedPsiUtils.isBlank; 9 | import static org.jetbrains.iren.utils.DeprecatedPsiUtils.isLeaf; 10 | 11 | public class AstGraphCreator extends JavaRecursiveElementVisitor { 12 | 13 | public static final String CHILD_EDGE = "Child"; 14 | 15 | private final Graph graph; 16 | 17 | public AstGraphCreator(Graph graph) { 18 | this.graph = graph; 19 | } 20 | 21 | @Override 22 | public void visitElement(@NotNull PsiElement element) { 23 | if (!isLeaf(element) || !isBlank(element)) { 24 | graph.addEdge(element.getParent(), element, CHILD_EDGE, true); 25 | } 26 | super.visitElement(element); 27 | } 28 | 29 | @Override 30 | public void visitComment(@NotNull PsiComment comment) { 31 | // ignore comments 32 | } 33 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/utils/RenameBundle.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.utils; 2 | 3 | import com.intellij.DynamicBundle; 4 | import org.jetbrains.annotations.NonNls; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.PropertyKey; 7 | 8 | import java.util.function.Supplier; 9 | 10 | public class RenameBundle extends DynamicBundle { 11 | @NonNls 12 | private static final String BUNDLE = "messages.Rename"; 13 | private static final RenameBundle INSTANCE = new RenameBundle(); 14 | 15 | private RenameBundle() { 16 | super(BUNDLE); 17 | } 18 | 19 | public static @NotNull String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, 20 | Object @NotNull ... params) { 21 | return INSTANCE.getMessage(key, params); 22 | } 23 | 24 | public static @NotNull Supplier messagePointer(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, 25 | Object @NotNull ... params) { 26 | return INSTANCE.getLazyMessage(key, params); 27 | } 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/contributors/ProjectVariableNamesContributor.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.contributors; 2 | 3 | import com.intellij.openapi.project.Project; 4 | import com.intellij.psi.PsiNameIdentifierOwner; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | import org.jetbrains.iren.ModelRunner; 8 | import org.jetbrains.iren.services.NGramModelManager; 9 | import org.jetbrains.iren.services.NGramModelsUsabilityService; 10 | import org.jetbrains.iren.utils.ModelUtils; 11 | 12 | public class ProjectVariableNamesContributor extends NGramVariableNamesContributor { 13 | @Override 14 | protected boolean forgetFile() { 15 | return true; 16 | } 17 | 18 | @Override 19 | public @Nullable ModelRunner getModelRunnerToContribute(Project project, @NotNull PsiNameIdentifierOwner variable) { 20 | String name = new ModelUtils().getName(project, variable.getLanguage()); 21 | if (NGramModelsUsabilityService.getInstance(project).isUsable(name)) { 22 | return NGramModelManager.getInstance(project).get(name); 23 | } 24 | return null; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Pick one of: 2 | # - java 3 | # - kotlin 4 | # - python 5 | # - all 6 | language=all 7 | 8 | # IntelliJ Platform Artifacts Repositories 9 | # -> https://www.jetbrains.org/intellij/sdk/docs/reference_guide/intellij_artifacts.html 10 | 11 | pluginGroup = com.intellij.iren 12 | pluginName = IRen 13 | pluginVersion = 0.2.1 14 | pluginSinceBuild = 223 15 | pluginUntilBuild = 234 16 | 17 | # Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl 18 | # See https://jb.gg/intellij-platform-builds-list for available build versions. 19 | pluginVerifierIdeVersions = 2022.3 20 | 21 | platformType = IC 22 | platformVersion = 2022.3 23 | platformDownloadSources = true 24 | 25 | # Java language level used to compile sources and to generate the files for - Java 17 is required since 2022.2 26 | javaVersion = 17 27 | junit = 5.8.2 28 | kinference = 0.1.14 29 | gradleVersion = 7.6 30 | 31 | # Opt-out flag for bundling Kotlin standard library. 32 | # See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details. 33 | # suppress inspection "UnusedProperty" 34 | kotlin.stdlib.default.dependency = false 35 | -------------------------------------------------------------------------------- /languages/python/testData/parsing/context/field.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "class", 4 | "Foo", 5 | ":", 6 | "def", 7 | "__init__", 8 | "(", 9 | "self", 10 | ",", 11 | "v", 12 | ":", 13 | "int", 14 | ")", 15 | ":", 16 | "self", 17 | ".", 18 | "my_field", 19 | "\u003d", 20 | "v", 21 | "ustr", 22 | "\u003d", 23 | "\u003cstr\u003e", 24 | "rstr", 25 | "\u003d", 26 | "\u003cstr\u003e", 27 | "s", 28 | "\u003d", 29 | "\u003cstr\u003e", 30 | "def", 31 | "print_field", 32 | "(", 33 | "self", 34 | ")", 35 | ":", 36 | "print", 37 | "(", 38 | "self", 39 | ".", 40 | "my_field", 41 | ")", 42 | "if", 43 | "__name__", 44 | "\u003d\u003d", 45 | "\u003cstr\u003e", 46 | ":", 47 | "foo", 48 | "\u003d", 49 | "Foo", 50 | "(", 51 | "\u003cnum\u003e", 52 | ")", 53 | "foo", 54 | ".", 55 | "my_field", 56 | "\u003d", 57 | "\u003cnum\u003e", 58 | "foo", 59 | ".", 60 | "print_field", 61 | "(", 62 | ")" 63 | ], 64 | "varIdxs": [ 65 | 15, 66 | 37, 67 | 52 68 | ] 69 | } -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/impl/TrainProjectNGramModelAction.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.impl; 2 | 3 | import com.intellij.openapi.actionSystem.AnActionEvent; 4 | import com.intellij.openapi.project.Project; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.iren.api.AbstractTrainModelAction; 7 | import org.jetbrains.iren.LanguageSupporter; 8 | import org.jetbrains.iren.services.NGramModelsUsabilityService; 9 | import org.jetbrains.iren.training.ModelBuilder; 10 | 11 | public class TrainProjectNGramModelAction extends AbstractTrainModelAction { 12 | @Override 13 | protected void doActionPerformed(@NotNull AnActionEvent e) { 14 | Project project = e.getProject(); 15 | assert project != null; 16 | ModelBuilder.trainInBackground(project); 17 | } 18 | 19 | @Override 20 | protected boolean canBePerformed(@NotNull AnActionEvent e) { 21 | Project project = e.getProject(); 22 | return project != null && !project.isDisposed() 23 | && !NGramModelsUsabilityService.getInstance(project).isTraining() 24 | && LanguageSupporter.hasSupportedFiles(project); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/context/property.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "class", 4 | "MyClass", 5 | "{", 6 | "var", 7 | "myField", 8 | "\u003d", 9 | "0", 10 | "val", 11 | "myText", 12 | "\u003d", 13 | "\"\"\"", 14 | "\u003cstr\u003e", 15 | "$", 16 | "myField", 17 | "\u003cstr\u003e", 18 | "\u003cstr\u003e", 19 | "\u003cstr\u003e", 20 | "\"\"\"", 21 | "fun", 22 | "setField", 23 | "(", 24 | "field", 25 | ":", 26 | "Int", 27 | ")", 28 | "{", 29 | "this", 30 | ".", 31 | "myField", 32 | "\u003d", 33 | "field", 34 | "}", 35 | "companion", 36 | "object", 37 | "{", 38 | "@", 39 | "JvmStatic", 40 | "fun", 41 | "main", 42 | "(", 43 | "args", 44 | ":", 45 | "Array", 46 | "\u003c", 47 | "String", 48 | "\u003e", 49 | ")", 50 | "{", 51 | "val", 52 | "instance", 53 | "\u003d", 54 | "MyClass", 55 | "(", 56 | ")", 57 | "instance", 58 | ".", 59 | "myField", 60 | "\u003d", 61 | "1", 62 | "}", 63 | "}", 64 | "}" 65 | ], 66 | "varIdxs": [ 67 | 4, 68 | 13, 69 | 28, 70 | 56 71 | ] 72 | } -------------------------------------------------------------------------------- /languages/python/test/org/jetbrains/iren/PyVariableTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.jetbrains.python.PythonFileType; 4 | import junitparams.JUnitParamsRunner; 5 | import junitparams.Parameters; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith(JUnitParamsRunner.class) 11 | public class PyVariableTest extends VariableTest { 12 | @Override 13 | public @NotNull String getFileExtension() { 14 | return "." + PythonFileType.INSTANCE.getDefaultExtension(); 15 | } 16 | 17 | @Override 18 | public @NotNull LanguageSupporter getLanguageSupporter() { 19 | return new PyLanguageSupporter(); 20 | } 21 | 22 | @Test 23 | @Parameters({"0", "1"}) 24 | public void testNotVariable(int index) { 25 | doTestNotVariable(index); 26 | } 27 | 28 | @Test 29 | @Parameters({"0", "1"}) 30 | public void testVariableDeclaration(int index) { 31 | doTestVariableDeclaration(index, true); 32 | } 33 | 34 | @Test 35 | @Parameters({"0", "1", "2"}) 36 | public void testNotVariableDeclaration(int index) { 37 | doTestVariableDeclaration(index,false); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /languages/common/test/org/jetbrains/iren/LexFileTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.google.gson.Gson; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.FileReader; 8 | import java.io.IOException; 9 | import java.util.List; 10 | 11 | public abstract class LexFileTest extends ParsingTest { 12 | @Override 13 | protected @NotNull String getTestDataBasePath() { 14 | return "parsing"; 15 | } 16 | 17 | @Override 18 | protected @NotNull String getTestFileNameResult() { 19 | return "/lexed/" + getTestName(true) + ".json"; 20 | } 21 | 22 | @Override 23 | public Object invokeSupporterFunction() { 24 | @NotNull LanguageSupporter supporter = getLanguageSupporter(); 25 | return supporter.lexPsiFile(getFile()); 26 | } 27 | 28 | @Override 29 | public Object parseResult(String resultFileName) { 30 | try (BufferedReader br = new BufferedReader(new FileReader(resultFileName))) { 31 | Gson gson = new Gson(); 32 | return List.of(gson.fromJson(br, String[].class)); 33 | } catch (IOException e) { 34 | e.printStackTrace(); 35 | } 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /languages/java/test/org/jetbrains/iren/JavaVariableTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.ide.highlighter.JavaFileType; 4 | import junitparams.JUnitParamsRunner; 5 | import junitparams.Parameters; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith(JUnitParamsRunner.class) 11 | public class JavaVariableTest extends VariableTest { 12 | @Override 13 | public @NotNull String getFileExtension() { 14 | return JavaFileType.DOT_DEFAULT_EXTENSION; 15 | } 16 | 17 | @Override 18 | public @NotNull LanguageSupporter getLanguageSupporter() { 19 | return new JavaLanguageSupporter(); 20 | } 21 | 22 | @Test 23 | @Parameters({"0", "1"}) 24 | public void testNotVariable(int index) { 25 | doTestNotVariable(index); 26 | } 27 | 28 | @Test 29 | @Parameters({"0", "1", "2", "3", "4"}) 30 | public void testVariableDeclaration(int index) { 31 | doTestVariableDeclaration(index, true); 32 | } 33 | 34 | @Test 35 | @Parameters({"0", "1", "2", "3", "4", "5", "6"}) 36 | public void testNotVariableDeclaration(int index) { 37 | doTestVariableDeclaration(index,false); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /languages/kotlin/test/org/jetbrains/iren/KotlinVariableTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import junitparams.JUnitParamsRunner; 4 | import junitparams.Parameters; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.kotlin.idea.KotlinFileType; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith(JUnitParamsRunner.class) 11 | public class KotlinVariableTest extends VariableTest { 12 | @Override 13 | public @NotNull String getFileExtension() { 14 | return "." + KotlinFileType.EXTENSION; 15 | } 16 | 17 | @Override 18 | public @NotNull LanguageSupporter getLanguageSupporter() { 19 | return new KotlinLanguageSupporter(); 20 | } 21 | 22 | @Test 23 | @Parameters({"0", "1"}) 24 | public void testNotVariable(int index) { 25 | doTestNotVariable(index); 26 | } 27 | 28 | @Test 29 | @Parameters({"0", "1", "2", "3", "4", "5", "6"}) 30 | public void testVariableDeclaration(int index) { 31 | doTestVariableDeclaration(index, true); 32 | } 33 | 34 | @Test 35 | @Parameters({"0", "1", "2", "3"}) 36 | public void testNotVariableDeclaration(int index) { 37 | doTestVariableDeclaration(index,false); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/storages/StringCounter.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.storages; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | import java.util.Collection; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | 9 | public class StringCounter extends ConcurrentHashMap { 10 | @Override 11 | public Integer get(Object key) { 12 | if (super.get(key) == null) { 13 | return 0; 14 | } 15 | return super.get(key); 16 | } 17 | 18 | @Override 19 | public Integer put(@NotNull String key, @NotNull Integer value) { 20 | return super.put(key, this.get(key) + value); 21 | } 22 | 23 | public Integer put(String key) { 24 | return put(key, 1); 25 | } 26 | 27 | public void putAll(@Nullable Collection collection) { 28 | if (collection == null) return; 29 | collection.forEach(this::put); 30 | } 31 | 32 | public void toVocabulary(@NotNull Vocabulary vocabulary, int cutOff) { 33 | this.forEach((k, v) -> { 34 | if (v >= cutOff) { 35 | vocabulary.store(k, v); 36 | } 37 | }); 38 | vocabulary.close(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /languages/common/test/org/jetbrains/iren/VariableTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.openapi.editor.Caret; 4 | import com.intellij.psi.PsiElement; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public abstract class VariableTest extends LanguageSupporterTest { 8 | @Override 9 | protected @NotNull String getTestDataBasePath() { 10 | return "variable/"; 11 | } 12 | 13 | protected void doTestNotVariable(int index) { 14 | configureByFile(getTestFileName()); 15 | final LanguageSupporter supporter = getLanguageSupporter(); 16 | Caret caret = getEditor().getCaretModel().getAllCarets().get(index); 17 | final PsiElement element = getTargetElementAtCaret(caret); 18 | assertFalse(supporter.isVariableDeclarationOrReference(element)); 19 | } 20 | 21 | protected void doTestVariableDeclaration(int index, boolean b) { 22 | configureByFile(getTestFileName()); 23 | final LanguageSupporter supporter = getLanguageSupporter(); 24 | Caret caret = getEditor().getCaretModel().getAllCarets().get(index); 25 | final PsiElement element = getFile().findElementAt(caret.getOffset()); 26 | assertEquals(b, supporter.identifierIsVariableDeclaration(element)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /experiments/.run/modelsEvaluator.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | true 20 | false 21 | 22 | 23 | -------------------------------------------------------------------------------- /languages/common/src/main/kotlin/org/jetbrains/iren/inspections/variable/VariableNamesInspection.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.inspections.variable 2 | 3 | import com.intellij.codeInspection.LocalInspectionTool 4 | import com.intellij.codeInspection.ProblemsHolder 5 | import com.intellij.openapi.application.ApplicationManager 6 | import com.intellij.psi.PsiElementVisitor 7 | import org.jetbrains.iren.LanguageSupporter 8 | import org.jetbrains.iren.services.NGramModelsUsabilityService 9 | import org.jetbrains.iren.utils.ModelUtils 10 | 11 | class VariableNamesInspection : LocalInspectionTool() { 12 | override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { 13 | val language = holder.file.language 14 | val project = holder.project 15 | return if (ApplicationManager.getApplication().isUnitTestMode || 16 | NGramModelsUsabilityService.getInstance(project).isUsable(ModelUtils().getName(project, language)) 17 | ) LanguageSupporter.getVariableVisitor(language, holder, isOnTheFly) else PsiElementVisitor.EMPTY_VISITOR 18 | } 19 | 20 | override fun showDefaultConfigurationOptions(): Boolean { 21 | return false 22 | } 23 | 24 | override fun runForWholeFile(): Boolean { 25 | return true 26 | } 27 | } -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/search/BeamHypothesis.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.search 2 | 3 | import kotlin.math.min 4 | import kotlin.math.pow 5 | 6 | 7 | class BeamHypothesis( 8 | val beamSize: Int, 9 | val maxLength: Int, 10 | val lengthPenalty: Float, 11 | val earlyStopping: Boolean 12 | ) { 13 | val hyps = mutableListOf() 14 | var worstScore = 1e9f 15 | 16 | fun add(hyp: List, sumLogProbs: Float) { 17 | val score = sumLogProbs / hyp.size.toFloat().pow(lengthPenalty) 18 | if (hyps.size < beamSize || score > worstScore) { 19 | hyps.add(Hypothesis(hyp, score)) 20 | if (hyps.size > beamSize) { 21 | val sortedScores = hyps.withIndex().sortedBy { it.value.score } 22 | hyps.removeAt(sortedScores[0].index) 23 | worstScore = sortedScores[1].value.score 24 | } else { 25 | worstScore = min(score, worstScore) 26 | } 27 | } 28 | } 29 | 30 | fun isDone(bestSumLogProbs: Float): Boolean { 31 | return hyps.size >= beamSize && (earlyStopping || worstScore >= bestSumLogProbs / maxLength.toFloat() 32 | .pow(lengthPenalty)) 33 | } 34 | } 35 | 36 | class Hypothesis(val hyp: List, val score: Float) -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/onnxEvaluator/ONNXVarNamer.kt: -------------------------------------------------------------------------------- 1 | package experiments.onnxEvaluator 2 | 3 | import com.intellij.psi.PsiNameIdentifierOwner 4 | import experiments.ModelPrediction 5 | import experiments.ModelPredictions 6 | import experiments.modelsEvaluatorApi.VarNamer 7 | import org.jetbrains.iren.LanguageSupporter 8 | import org.jetbrains.iren.models.OrtModelRunner 9 | import org.jetbrains.iren.utils.DOBFModelUtils 10 | import java.nio.file.Path 11 | 12 | class ONNXVarNamer(saveDir: Path, supporter: LanguageSupporter, ngramType: String) : 13 | VarNamer(saveDir, supporter, ngramType) { 14 | val modelDir = Path.of("/home/igor/IdeaProjects/IRen/plugin/build/idea-sandbox/system/DOBF_models", DOBFModelUtils().getName(supporter.language)) 15 | private val runner = OrtModelRunner(modelDir, maxSequenceLength = 512, cacheSize = 0L) 16 | override var runParallel = false 17 | 18 | override fun predictWithNN(variable: PsiNameIdentifierOwner, thread: Int): Any { 19 | val start = System.nanoTime() 20 | val predictions = runner.predict(variable) 21 | return ModelPredictions( 22 | predictions.sortedBy { -it.probability }.take(10).map { ModelPrediction(it.name, it.probability) }, 23 | (System.nanoTime() - start) / 1e9 24 | ) 25 | } 26 | } -------------------------------------------------------------------------------- /languages/kotlin/testData/parsing/dobfContext/property.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "package", 4 | "parsing", 5 | ".", 6 | "code", 7 | "class", 8 | "MyClass", 9 | "{", 10 | "var", 11 | "myField", 12 | "\u003d", 13 | "0", 14 | "val", 15 | "myText", 16 | "\u003d", 17 | "\"\"\"", 18 | "Parsing ▁ test ! ! ! ▁ Number : ▁", 19 | "$", 20 | "myField", 21 | "▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ▁ ¯", 22 | "\\", 23 | "_ ( ツ ) _ / ¯", 24 | "\"\"\"", 25 | "fun", 26 | "setField", 27 | "(", 28 | "field", 29 | ":", 30 | "Int", 31 | ")", 32 | "{", 33 | "this", 34 | ".", 35 | "myField", 36 | "\u003d", 37 | "field", 38 | "}", 39 | "companion", 40 | "object", 41 | "{", 42 | "@", 43 | "JvmStatic", 44 | "fun", 45 | "main", 46 | "(", 47 | "args", 48 | ":", 49 | "Array", 50 | "\u003c", 51 | "String", 52 | "\u003e", 53 | ")", 54 | "{", 55 | "val", 56 | "instance", 57 | "\u003d", 58 | "MyClass", 59 | "(", 60 | ")", 61 | "instance", 62 | ".", 63 | "myField", 64 | "\u003d", 65 | "1", 66 | "}", 67 | "}", 68 | "}" 69 | ], 70 | "varIdxs": [ 71 | 8, 72 | 17, 73 | 32, 74 | 60 75 | ] 76 | } -------------------------------------------------------------------------------- /languages/kotlin/testData/inspection.kt: -------------------------------------------------------------------------------- 1 | // carets define highlighted elements 2 | package org.jetbrains.iren; 3 | 4 | open class Foo { 5 | open var xy = 0 6 | open fun boo(boi: Int) { 7 | val state = computeSmth() 8 | val component = returnMy() 9 | val answerForTheUltimateQuestionOfLife = computeAnswerForTheUltimateQuestionOfLife() 10 | val school = getSomeSchoolNumber() 11 | val sch = getSomeSchoolNumber() 12 | try { 13 | println("Oh My!") 14 | } catch (ignore: Exception) { 15 | } catch (ignored: Exception) { 16 | } catch (_: Exception) { 17 | } catch (e: Exception) { 18 | println("Exception is not ignored") 19 | } 20 | } 21 | 22 | private fun computeSmth(): State { 23 | return State() 24 | } 25 | 26 | private fun returnMy(): MyComponent { 27 | return MyComponent() 28 | } 29 | 30 | private fun computeAnswerForTheUltimateQuestionOfLife(): Int { 31 | return 42 32 | } 33 | 34 | private fun getSomeSchoolNumber(): Int { 35 | return 239 36 | } 37 | 38 | class State 39 | class MyComponent 40 | } 41 | 42 | internal class Foo2 : Foo() { 43 | override var xy = 1 44 | override fun boo(boi: Int) = println("Hello World!") 45 | } 46 | -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/settings/AppSettingsState.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.settings 2 | 3 | import com.intellij.openapi.components.PersistentStateComponent 4 | import com.intellij.openapi.components.State 5 | import com.intellij.openapi.components.Storage 6 | import com.intellij.openapi.components.service 7 | import com.intellij.util.xmlb.XmlSerializerUtil 8 | import java.time.temporal.ChronoUnit 9 | 10 | /** 11 | * Supports storing the application settings in a persistent way. 12 | * The {@link State} and {@link Storage} annotations define the name of the data and the file name where 13 | * these persistent application settings are stored. 14 | */ 15 | @State(name = "AppSettingsState", storages = [Storage("IRenPluginSettings.xml")]) 16 | class AppSettingsState : PersistentStateComponent { 17 | var firstOpen: Boolean = true 18 | var automaticTraining: Boolean = true 19 | var maxTrainingTime: Int = 300 20 | var vocabularyCutOff: Int = 3 21 | var modelsLifetime: Int = 1 22 | var modelsLifetimeUnit: ChronoUnit = ChronoUnit.DAYS 23 | 24 | companion object { 25 | @JvmStatic 26 | fun getInstance(): AppSettingsState = service() 27 | } 28 | 29 | override fun getState() = this 30 | 31 | override fun loadState(state: AppSettingsState) = XmlSerializerUtil.copyBean(state, this) 32 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 2 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 3 | 4 | # User-specific stuff 5 | .idea/**/workspace.xml 6 | .idea/**/tasks.xml 7 | .idea/**/usage.statistics.xml 8 | .idea/**/dictionaries 9 | .idea/**/shelf 10 | 11 | # Generated files 12 | .idea/**/contentModel.xml 13 | 14 | # Sensitive or high-churn files 15 | .idea/**/dataSources/ 16 | .idea/**/dataSources.ids 17 | .idea/**/dataSources.local.xml 18 | .idea/**/sqlDataSources.xml 19 | .idea/**/dynamic.xml 20 | .idea/**/uiDesigner.xml 21 | .idea/**/dbnavigator.xml 22 | 23 | # Gradle 24 | .idea/**/gradle.xml 25 | .idea/**/libraries 26 | 27 | # Gradle and Maven with auto-import 28 | # When using Gradle or Maven with auto-import, you should exclude module files, 29 | # since they will be recreated, and may cause churn. Uncomment if using 30 | # auto-import. 31 | .idea/artifacts 32 | .idea/compiler.xml 33 | .idea/jarRepositories.xml 34 | .idea/modules.xml 35 | .idea/*.iml 36 | .idea/modules 37 | *.iml 38 | *.ipr 39 | 40 | # IntelliJ 41 | out/ 42 | 43 | # Editor-based Rest Client 44 | .idea/httpRequests 45 | 46 | # Gradle 47 | /.gradle/ 48 | 49 | # Don't want to add models right now 50 | /model* 51 | 52 | updatePlugins.xml 53 | /**/build/* 54 | /buildSrc/.gradle/ -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/contributors/DOBFContributor.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.contributors 2 | 3 | import com.intellij.lang.java.JavaLanguage 4 | import com.intellij.psi.PsiNameIdentifierOwner 5 | import org.jetbrains.iren.VariableNamesContributor 6 | import org.jetbrains.iren.config.ModelType 7 | import org.jetbrains.iren.services.DOBFModelManager 8 | import org.jetbrains.iren.storages.VarNamePrediction 9 | 10 | 11 | class DOBFContributor : VariableNamesContributor { 12 | companion object { 13 | @JvmField 14 | val MODEL_PRIORITY = 1.0 15 | } 16 | 17 | override fun contribute( 18 | variable: PsiNameIdentifierOwner, 19 | predictionList: MutableList 20 | ): Double { 21 | var language = variable.language 22 | // Kludge 23 | if (language.displayName == "Kotlin") language = JavaLanguage.INSTANCE 24 | val runner = DOBFModelManager.instance.get(language) 25 | predictionList.addAll(runner?.predict(variable) ?: return .0) 26 | return MODEL_PRIORITY 27 | } 28 | 29 | override fun getProbability(variable: PsiNameIdentifierOwner): Pair { 30 | // get prob of the existing name. For now, it's used for debugging, so forget it. 31 | return Pair(.0, .0) 32 | } 33 | 34 | override fun getModelType() = ModelType.DOBF 35 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/VariableNamesContributor.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.openapi.extensions.ExtensionPointName; 4 | import com.intellij.psi.PsiNameIdentifierOwner; 5 | import kotlin.Pair; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.iren.config.ModelType; 8 | import org.jetbrains.iren.storages.VarNamePrediction; 9 | 10 | import java.util.List; 11 | 12 | public interface VariableNamesContributor { 13 | ExtensionPointName EP_NAME = 14 | ExtensionPointName.create("org.jetbrains.iren.variableNamesContributor"); 15 | 16 | /** 17 | * Contribute some variable names. 18 | * 19 | * @param variable variable which name we want to predict. 20 | * @param predictionList container which contains all predictions. 21 | * @return priority of contribution 22 | */ 23 | double contribute(@NotNull PsiNameIdentifierOwner variable, @NotNull List predictionList); 24 | 25 | /** 26 | * Get conditional probability of variable name. 27 | * 28 | * @param variable some variable. 29 | * @return pair of probability and model priority. 30 | */ 31 | @NotNull Pair getProbability(@NotNull PsiNameIdentifierOwner variable); 32 | 33 | @NotNull ModelType getModelType(); 34 | } 35 | -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/inspections/Suggestion.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.inspections 2 | 3 | /** 4 | * This class contains information about suggestion for method. 5 | * Suggestion is a list of pairs of the type (name, score), 6 | * where score is a probability of the corresponding name 7 | */ 8 | class Suggestion(val names: ArrayList>) { 9 | var needRecalculate: Boolean = false 10 | 11 | var ignore: Boolean = false 12 | 13 | fun setRecalculate() { 14 | this.needRecalculate = true 15 | } 16 | 17 | fun setIgnore() { 18 | this.ignore = true 19 | } 20 | 21 | fun containsName(name: String): Boolean { 22 | for (pair in names) { 23 | if (pair.first.equals(name)) return true 24 | } 25 | return false 26 | } 27 | 28 | fun addName(value: String) { 29 | this.names.add(Pair(value, -1.0)) 30 | } 31 | 32 | fun removeName(value: String) { 33 | for (pair in names) { 34 | if (pair.first.equals(value)) names.remove(pair) 35 | } 36 | } 37 | 38 | fun getScores(except: String): ArrayList { 39 | val scores: ArrayList = ArrayList() 40 | for (pair in names) { 41 | if (!except.equals(pair.first)) { 42 | scores.add(pair.second) 43 | } 44 | } 45 | return scores 46 | } 47 | } -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/models/OrtModel.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.models 2 | 3 | import ai.onnxruntime.OnnxTensor 4 | import ai.onnxruntime.OrtEnvironment 5 | import ai.onnxruntime.OrtSession 6 | import org.jetbrains.iren.utils.prepareInput 7 | import java.nio.file.Path 8 | 9 | class OrtModel(encoderPath: Path, decoderPath: Path) { 10 | val env = OrtEnvironment.getEnvironment() 11 | val encoderSession = env.createSession(encoderPath.toFile().readBytes(), OrtSession.SessionOptions()) 12 | val decoderSession = env.createSession(decoderPath.toFile().readBytes(), OrtSession.SessionOptions()) 13 | 14 | fun encode(idxs: List>): EncoderOutput { 15 | val (x, lengths) = prepareInput(idxs, env) 16 | 17 | val input = mapOf("x" to x, "lengths" to lengths) 18 | 19 | val res = encoderSession.run(input)["output"].get() as OnnxTensor 20 | return EncoderOutput(res, lengths) 21 | } 22 | 23 | fun decode(idxs: List>, encoderOutput: EncoderOutput): OnnxTensor { 24 | val (x, lengths) = prepareInput(idxs, env) 25 | val decInput2 = mutableMapOf( 26 | "x" to x, "lengths" to lengths, "src_enc" to encoderOutput.logProbs, "src_len" to encoderOutput.lengths 27 | ) 28 | return decoderSession.run(decInput2)["output"].get() as OnnxTensor 29 | } 30 | } 31 | 32 | data class EncoderOutput(val logProbs: OnnxTensor, val lengths: OnnxTensor) -------------------------------------------------------------------------------- /plugin/src/main/java/com/intellij/completion/ngram/slp/counting/trie/my/persistent/PersistentCounter.java: -------------------------------------------------------------------------------- 1 | package com.intellij.completion.ngram.slp.counting.trie.my.persistent; 2 | 3 | import com.intellij.completion.ngram.slp.counting.Counter; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Counter which is dumped on disk. Its n-gram counts can't be changed. 10 | */ 11 | public abstract class PersistentCounter implements Counter { 12 | @Override 13 | public void countBatch(List> indices) { 14 | } 15 | 16 | @Override 17 | public void unCountBatch(List> indices) { 18 | } 19 | 20 | @Override 21 | public void count(List indices) { 22 | } 23 | 24 | @Override 25 | public void unCount(List indices) { 26 | } 27 | 28 | @Override 29 | public final int[] getDistinctCounts(int range, List indices) { 30 | return new int[0]; 31 | } 32 | 33 | @Override 34 | public final int getCountOfCount(int n, int count) { 35 | return 0; 36 | } 37 | 38 | @Override 39 | public final int getSuccessorCount(List indices) { 40 | return 0; 41 | } 42 | 43 | @Override 44 | public final int getSuccessorCount() { 45 | return 0; 46 | } 47 | 48 | public abstract void prepareCache(); 49 | 50 | public abstract @NotNull CountersCache getCache(); 51 | } 52 | -------------------------------------------------------------------------------- /languages/python/testData/parsing/dobfContext/parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "import", 4 | "random", 5 | "NEW_LINE", 6 | "class", 7 | "Generator", 8 | ":", 9 | "NEW_LINE", 10 | "INDENT", 11 | "def", 12 | "generate_int", 13 | "(", 14 | "self", 15 | ",", 16 | "seed", 17 | ":", 18 | "int", 19 | ")", 20 | ":", 21 | "NEW_LINE", 22 | "INDENT", 23 | "print", 24 | "(", 25 | "f\"", 26 | "Initialize ▁ seed ▁ with ▁", 27 | "{", 28 | "seed", 29 | "}", 30 | "\"", 31 | ",", 32 | "\u0027 Bugaga \u0027", 33 | ")", 34 | "NEW_LINE", 35 | "random", 36 | ".", 37 | "seed", 38 | "(", 39 | "seed", 40 | ")", 41 | "NEW_LINE", 42 | "return", 43 | "random", 44 | ".", 45 | "randint", 46 | "(", 47 | "0", 48 | ",", 49 | "42", 50 | ")", 51 | "NEW_LINE", 52 | "DEDENT", 53 | "DEDENT", 54 | "if", 55 | "__name__", 56 | "\u003d\u003d", 57 | "\u0027 _ _ main _ _ \u0027", 58 | ":", 59 | "NEW_LINE", 60 | "INDENT", 61 | "g", 62 | "\u003d", 63 | "Generator", 64 | "(", 65 | ")", 66 | "NEW_LINE", 67 | "print", 68 | "(", 69 | "g", 70 | ".", 71 | "generate_int", 72 | "(", 73 | "42", 74 | ")", 75 | ")", 76 | "NEW_LINE", 77 | "DEDENT" 78 | ], 79 | "varIdxs": [ 80 | 13, 81 | 25, 82 | 36 83 | ] 84 | } -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/transformerEvaluator/TransformerVarNamer.kt: -------------------------------------------------------------------------------- 1 | package experiments.transformerEvaluator 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.intellij.openapi.diagnostic.logger 5 | import com.intellij.psi.PsiNameIdentifierOwner 6 | import com.intellij.psi.PsiVariable 7 | import com.intellij.util.io.HttpRequests 8 | import experiments.modelsEvaluatorApi.VarNamer 9 | import org.jetbrains.iren.LanguageSupporter 10 | import tools.varMiner.DatasetExtractor 11 | import java.nio.file.Path 12 | 13 | class TransformerVarNamer(saveDir: Path, supporter: LanguageSupporter, ngramType: String) : VarNamer(saveDir, supporter, 14 | ngramType 15 | ) { 16 | private val LOG = logger() 17 | private val TRANSFORMER_SERVER_URL = "http://127.0.0.1:5000/" 18 | 19 | override fun predictWithNN(variable: PsiNameIdentifierOwner, thread: Int): Any { 20 | // works only with java 21 | val variableFeatures = DatasetExtractor.getVariableFeatures(variable as PsiVariable, variable.containingFile) 22 | return HttpRequests.post(TRANSFORMER_SERVER_URL, HttpRequests.JSON_CONTENT_TYPE) 23 | .connect( { 24 | val objectMapper = ObjectMapper() 25 | it.write(objectMapper.writeValueAsBytes(variableFeatures)) 26 | val str = it.readString() 27 | objectMapper.readValue(str, Any::class.java) 28 | }, null, LOG) 29 | } 30 | } -------------------------------------------------------------------------------- /languages/common/src/main/kotlin/org/jetbrains/iren/IRenVariableNameSuggestionProvider.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren 2 | 3 | import com.intellij.psi.PsiElement 4 | import com.intellij.psi.PsiNameIdentifierOwner 5 | import com.intellij.psi.codeStyle.SuggestedNameInfo 6 | import com.intellij.refactoring.rename.NameSuggestionProvider 7 | import org.jetbrains.iren.config.InferenceStrategies 8 | import org.jetbrains.iren.services.IRenSuggestingService 9 | import org.jetbrains.iren.storages.VarNamePrediction 10 | 11 | class IRenVariableNameSuggestionProvider : NameSuggestionProvider { 12 | override fun getSuggestedNames( 13 | element: PsiElement, 14 | nameSuggestionContext: PsiElement?, 15 | result: MutableSet 16 | ): SuggestedNameInfo? { 17 | val project = element.project 18 | if (!(LanguageSupporter.getInstance(element.language)?.isVariableDeclaration(element) ?: return null)) return null 19 | val predictions = IRenSuggestingService.getInstance(project) 20 | .suggestVariableName( 21 | project, 22 | element as? PsiNameIdentifierOwner ?: return null, 23 | InferenceStrategies.ALL 24 | ) 25 | result.addAll(predictions.map { it.name }) 26 | return IRenSuggestedNameInfo(result.toTypedArray(), predictions) 27 | } 28 | 29 | class IRenSuggestedNameInfo(names: Array, val predictions: List) : 30 | SuggestedNameInfo(names) 31 | } -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/utils/PathUtils.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.utils 2 | 3 | import org.jetbrains.astrid.extractors.features.Extractor 4 | 5 | object PathUtils { 6 | private fun getContextsFromMethodBody(methodBody: String): String { 7 | val extractor = Extractor(methodBody) 8 | return extractor.processCodeBlock() 9 | } 10 | 11 | fun getCombinedPaths(methodBody: String): String { 12 | val pathContexts: String = getContextsFromMethodBody(methodBody) 13 | if (pathContexts.isEmpty()) return "" 14 | val parts = pathContexts.split(' ') 15 | val methodName = parts[0] 16 | val currentResultLineParts = arrayListOf(methodName) 17 | val contexts = parts.subList(1, parts.size) 18 | val maxContextsCount = 1000 19 | var contextParts: List 20 | var resultLine = "" 21 | val list = if (contexts.size < maxContextsCount) contexts else contexts.subList(0, maxContextsCount - 1) 22 | for (context: String in list) { 23 | contextParts = context.split(',') 24 | currentResultLineParts.add("${contextParts[0]},${contextParts[1]},${contextParts[2]}") 25 | } 26 | currentResultLineParts.forEach { part -> 27 | resultLine += " $part" 28 | } 29 | val spaceCount = maxContextsCount - contexts.size 30 | for (i in 0..spaceCount - 2) { 31 | resultLine += " " 32 | } 33 | return resultLine 34 | } 35 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/ModelRunner.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.completion.ngram.slp.modeling.Model; 4 | import com.intellij.openapi.progress.ProgressIndicator; 5 | import com.intellij.psi.PsiFile; 6 | import com.intellij.psi.PsiNameIdentifierOwner; 7 | import kotlin.Pair; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.Nullable; 10 | import org.jetbrains.iren.storages.Context; 11 | import org.jetbrains.iren.storages.VarNamePrediction; 12 | import org.jetbrains.iren.storages.Vocabulary; 13 | 14 | import java.nio.file.Path; 15 | import java.util.List; 16 | 17 | public interface ModelRunner { 18 | Model getModel(); 19 | 20 | Vocabulary getVocabulary(); 21 | 22 | void train(); 23 | 24 | void eval(); 25 | 26 | @NotNull List suggestNames(@NotNull PsiNameIdentifierOwner variable); 27 | 28 | @NotNull Context.Statistics getContextStatistics(@NotNull PsiNameIdentifierOwner variable); 29 | 30 | @NotNull Pair getProbability(PsiNameIdentifierOwner variable); 31 | 32 | int getOrder(); 33 | 34 | double getModelPriority(); 35 | 36 | void learnPsiFile(@NotNull PsiFile file); 37 | 38 | void forgetPsiFile(@NotNull PsiFile file); 39 | 40 | double save(@NotNull Path model_directory, @Nullable ProgressIndicator progressIndicator); 41 | 42 | boolean load(@NotNull Path model_directory, @Nullable ProgressIndicator progressIndicator); 43 | } 44 | -------------------------------------------------------------------------------- /languages/java/testData/inspection.java: -------------------------------------------------------------------------------- 1 | // carets define highlighted elements 2 | package org.jetbrains.iren; 3 | 4 | import java.io.IOError; 5 | 6 | public class Foo { 7 | public void boo(int boi) { 8 | var sch = getSomeSchoolNumber(); 9 | var state = Foo.computeSmthg(); 10 | var component = returnMy(); 11 | var answerForTheUltimateQuestionOfLife = computeAnswerForTheUltimateQuestionOfLife(); 12 | var school = getSomeSchoolNumber(); 13 | try { 14 | System.out.println("Oh My!"); 15 | } catch (RuntimeException ignore) { 16 | } catch (IOError ignored) { 17 | } catch (Exception x) { 18 | } 19 | } 20 | 21 | private static State computeSmthg() { 22 | return new State(); 23 | } 24 | 25 | private int computeAnswerForTheUltimateQuestionOfLife() { 26 | return 42; 27 | } 28 | 29 | public int getSomeSchoolNumber(int number) { 30 | return 239; 31 | } 32 | 33 | public MyComponent returnMy() { 34 | return new MyComponent(); 35 | } 36 | 37 | static class State { 38 | } 39 | 40 | static class MyComponent { 41 | } 42 | } 43 | 44 | class Foo2 extends Foo { 45 | @java.lang.Override 46 | public void boo(int boi) { 47 | System.out.println("Hello World!"); 48 | } 49 | 50 | @java.lang.Override 51 | public int getSomeSchoolNumber(int smth) { 52 | return 777; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/application/PluginLoadedListener.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.application; 2 | 3 | import com.intellij.ide.plugins.DynamicPluginListener; 4 | import com.intellij.ide.plugins.IdeaPluginDescriptor; 5 | import com.intellij.openapi.project.Project; 6 | import com.intellij.openapi.project.ProjectManager; 7 | import com.intellij.openapi.util.Disposer; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.iren.LanguageSupporter; 10 | import org.jetbrains.iren.services.ConsistencyChecker; 11 | import org.jetbrains.iren.services.NGramModelManager; 12 | 13 | import static org.jetbrains.iren.utils.NotificationsUtil.askPermissions; 14 | 15 | public class PluginLoadedListener implements DynamicPluginListener { 16 | @Override 17 | public void beforePluginUnload(@NotNull IdeaPluginDescriptor pluginDescriptor, boolean isUpdate) { 18 | DynamicPluginListener.super.beforePluginUnload(pluginDescriptor, isUpdate); 19 | for (Project project : ProjectManager.getInstance().getOpenProjects()) { 20 | Disposer.dispose(NGramModelManager.getInstance(project)); 21 | Disposer.dispose(ConsistencyChecker.getInstance(project)); 22 | } 23 | } 24 | 25 | @Override 26 | public void pluginLoaded(@NotNull IdeaPluginDescriptor pluginDescriptor) { 27 | DynamicPluginListener.super.pluginLoaded(pluginDescriptor); 28 | LanguageSupporter.removeRenameHandlers(); 29 | askPermissions(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /languages/common/test/org/jetbrains/iren/GetContextTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.psi.PsiElement; 4 | import com.intellij.psi.PsiNameIdentifierOwner; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.iren.storages.Context; 7 | 8 | import java.io.BufferedReader; 9 | import java.io.FileReader; 10 | import java.io.IOException; 11 | import java.nio.charset.StandardCharsets; 12 | 13 | public abstract class GetContextTest extends ParsingTest { 14 | @Override 15 | protected @NotNull String getTestDataBasePath() { 16 | return "parsing"; 17 | } 18 | 19 | @Override 20 | protected @NotNull String getTestFileNameResult() { 21 | return "/context/" + getTestName(true) + ".json"; 22 | } 23 | 24 | @Override 25 | public Object invokeSupporterFunction() { 26 | @NotNull LanguageSupporter supporter = getLanguageSupporter(); 27 | final PsiElement variable = getTargetElementAtCaret(); 28 | assertTrue(supporter.isVariableDeclarationOrReference(variable)); 29 | return supporter.getContext((PsiNameIdentifierOwner) variable,false); 30 | } 31 | 32 | @Override 33 | public Object parseResult(String resultFileName) { 34 | try (BufferedReader br = new BufferedReader(new FileReader(resultFileName, StandardCharsets.UTF_8))) { 35 | return Context.deserialize(br); 36 | } catch (IOException e) { 37 | e.printStackTrace(); 38 | } 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /languages/python/testData/parsing/dobfContext/field.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokens": [ 3 | "class", 4 | "Foo", 5 | ":", 6 | "NEW_LINE", 7 | "INDENT", 8 | "def", 9 | "__init__", 10 | "(", 11 | "self", 12 | ",", 13 | "v", 14 | ":", 15 | "int", 16 | ")", 17 | ":", 18 | "NEW_LINE", 19 | "INDENT", 20 | "self", 21 | ".", 22 | "my_field", 23 | "\u003d", 24 | "v", 25 | "NEW_LINE", 26 | "ustr", 27 | "\u003d", 28 | "\u0027 \\u2156 \u0027", 29 | "NEW_LINE", 30 | "rstr", 31 | "\u003d", 32 | "\u0027 \\u2156 \u0027", 33 | "NEW_LINE", 34 | "s", 35 | "\u003d", 36 | "\u0027 \\x34\\x63\\u2435 \u0027", 37 | "NEW_LINE", 38 | "DEDENT", 39 | "def", 40 | "print_field", 41 | "(", 42 | "self", 43 | ")", 44 | ":", 45 | "NEW_LINE", 46 | "INDENT", 47 | "print", 48 | "(", 49 | "self", 50 | ".", 51 | "my_field", 52 | ")", 53 | "NEW_LINE", 54 | "DEDENT", 55 | "DEDENT", 56 | "if", 57 | "__name__", 58 | "\u003d\u003d", 59 | "\u0027 _ _ main _ _ \u0027", 60 | ":", 61 | "NEW_LINE", 62 | "INDENT", 63 | "foo", 64 | "\u003d", 65 | "Foo", 66 | "(", 67 | "42", 68 | ")", 69 | "NEW_LINE", 70 | "foo", 71 | ".", 72 | "my_field", 73 | "\u003d", 74 | "239", 75 | "NEW_LINE", 76 | "foo", 77 | ".", 78 | "print_field", 79 | "(", 80 | ")" 81 | ], 82 | "varIdxs": [ 83 | 19, 84 | 48, 85 | 69 86 | ] 87 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/utils/LimitedTimeRunner.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.utils; 2 | 3 | import com.intellij.openapi.progress.ProcessCanceledException; 4 | import com.intellij.openapi.progress.ProgressManager; 5 | import com.intellij.openapi.progress.StandardProgressIndicator; 6 | import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase; 7 | import com.intellij.openapi.util.Computable; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.Nullable; 10 | 11 | public class LimitedTimeRunner { 12 | public static @Nullable T runForSomeTime(long runningTimeMs, @NotNull Computable process) { 13 | try { 14 | return ProgressManager.getInstance().runProcess(process, new LimitedRunningTimeIndicator(runningTimeMs)); 15 | } catch (ProcessCanceledException e) { 16 | // System.out.println("Canceled"); 17 | return null; 18 | } 19 | } 20 | } 21 | 22 | class LimitedRunningTimeIndicator extends AbstractProgressIndicatorBase implements StandardProgressIndicator { 23 | final long startTime = System.currentTimeMillis(); 24 | private final long runningTimeMs; 25 | 26 | public LimitedRunningTimeIndicator(long runningTimeMs) { 27 | this.runningTimeMs = runningTimeMs; 28 | } 29 | 30 | @Override 31 | public boolean isCanceled() { 32 | if (super.isCanceled()) { 33 | return true; 34 | } 35 | return (System.currentTimeMillis() - startTime) > runningTimeMs; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /languages/kotlin/test/org/jetbrains/iren/KotlinCollisionTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import junitparams.JUnitParamsRunner; 4 | import junitparams.Parameters; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.kotlin.idea.KotlinFileType; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith(JUnitParamsRunner.class) 11 | public class KotlinCollisionTest extends CollisionTest { 12 | @Override 13 | public @NotNull String getFileExtension() { 14 | return "." + KotlinFileType.EXTENSION; 15 | } 16 | 17 | @Override 18 | public @NotNull LanguageSupporter getLanguageSupporter() { 19 | return new KotlinLanguageSupporter(); 20 | } 21 | 22 | @Test 23 | @Parameters({ 24 | "true, collision1", 25 | "true, collision2", 26 | "false, boi" 27 | }) 28 | public void testLocalVariable(boolean isColliding, String name) { 29 | testCollision(isColliding, name); 30 | } 31 | 32 | @Test 33 | @Parameters({ 34 | "true, collision1", 35 | "true, collision2", 36 | "false, not_collision", 37 | "false, boi" 38 | }) 39 | public void testField(boolean isColliding, String name) { 40 | testCollision(isColliding, name); 41 | } 42 | 43 | @Test 44 | @Parameters({ 45 | "true, collision", 46 | "false, boi" 47 | }) 48 | public void testParameter(boolean isColliding, String name) { 49 | testCollision(isColliding, name); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /experiments/src/main/java/tools/varMiner/VariableFeatures.java: -------------------------------------------------------------------------------- 1 | package tools.varMiner; 2 | 3 | import com.intellij.psi.PsiVariable; 4 | 5 | import java.io.Serializable; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.LinkedHashMap; 9 | import java.util.List; 10 | 11 | public class VariableFeatures implements Serializable { 12 | public final String variable; 13 | public final List ngrams = new ArrayList<>(); 14 | public final List otherFeatures = new ArrayList<>(); 15 | public String psiInterface = null; 16 | 17 | public VariableFeatures(String variable){ 18 | this.variable = variable; 19 | } 20 | 21 | public VariableFeatures(PsiVariable variable, List collect) { 22 | this(variable.getName(), collect); 23 | this.psiInterface = variable.getClass().getInterfaces()[0].getSimpleName(); 24 | } 25 | 26 | public VariableFeatures(String variable, List usages) { 27 | this(variable); 28 | for (UsageFeatures usage: usages){ 29 | this.ngrams.add(usage.ngram); 30 | this.otherFeatures.add(usage.otherFeatures.values()); 31 | } 32 | } 33 | } 34 | 35 | class UsageFeatures implements Serializable{ 36 | public final Object ngram; 37 | public final HashMap otherFeatures = new LinkedHashMap<>(); 38 | 39 | public UsageFeatures(Object ngram, int distanceToDeclaration) { 40 | this.ngram = ngram; 41 | this.otherFeatures.put("distanceToDeclaration", distanceToDeclaration); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /languages/java/test/org/jetbrains/iren/JavaCollisionTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.ide.highlighter.JavaFileType; 4 | import junitparams.JUnitParamsRunner; 5 | import junitparams.Parameters; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | @RunWith(JUnitParamsRunner.class) 11 | public class JavaCollisionTest extends CollisionTest { 12 | @Override 13 | public @NotNull String getFileExtension() { 14 | return JavaFileType.DOT_DEFAULT_EXTENSION; 15 | } 16 | 17 | @Override 18 | public @NotNull LanguageSupporter getLanguageSupporter() { 19 | return new JavaLanguageSupporter(); 20 | } 21 | 22 | @Test 23 | @Parameters({ 24 | "true, collision1", 25 | "true, collision2", 26 | "false, boi" 27 | }) 28 | public void testLocalVariable(boolean isColliding, String name) { 29 | testCollision(isColliding, name); 30 | } 31 | 32 | @Test 33 | @Parameters({ 34 | // "true, collision", conflict dialog is showing in ide, but it doesn't work in test 35 | "false, boi" 36 | }) 37 | public void testField(boolean isColliding, String name) { 38 | testCollision(isColliding, name); 39 | } 40 | 41 | @Test 42 | @Parameters({ 43 | "true, collision1", 44 | "true, collision2", 45 | "false, boi" 46 | }) 47 | public void testParameter(boolean isColliding, String name) { 48 | testCollision(isColliding, name); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /languages/kotlin/src/org/jetbrains/iren/rename/IRenKotlinVariableInplaceRenamer.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.rename 2 | 3 | import com.intellij.openapi.editor.Editor 4 | import com.intellij.psi.PsiElement 5 | import com.intellij.psi.PsiNamedElement 6 | import com.intellij.psi.PsiReference 7 | import com.intellij.refactoring.RefactoringActionHandler 8 | import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer 9 | import org.jetbrains.kotlin.idea.base.psi.unquoteKotlinIdentifier 10 | 11 | class IRenKotlinVariableInplaceRenamer( 12 | elementToRename: PsiNamedElement, 13 | editor: Editor, 14 | currentName: String, 15 | oldName: String 16 | ) : IRenVariableInplaceRenamer(elementToRename, editor, editor.project!!, currentName, oldName) { 17 | 18 | override fun acceptReference(reference: PsiReference): Boolean { 19 | val refElement = reference.element 20 | val textRange = reference.rangeInElement 21 | val referenceText = refElement.text.substring(textRange.startOffset, textRange.endOffset).unquoteKotlinIdentifier() 22 | return referenceText == myElementToRename.name 23 | } 24 | 25 | override fun startsOnTheSameElement(handler: RefactoringActionHandler?, element: PsiElement?): Boolean { 26 | return variable == element && (handler is IRenVariableInplaceRenameHandler) 27 | } 28 | 29 | override fun createInplaceRenamerToRestart(variable: PsiNamedElement, editor: Editor, initialName: String): VariableInplaceRenamer { 30 | return IRenKotlinVariableInplaceRenamer(variable, editor, initialName, myOldName) 31 | } 32 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/storages/VarNamePrediction.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.storages; 2 | 3 | import org.jetbrains.iren.config.ModelType; 4 | 5 | public class VarNamePrediction { 6 | private final String myName; 7 | private final double myProbability; 8 | private final double myPriority; 9 | private final ModelType myModelType; 10 | 11 | public VarNamePrediction(String name, double probability, ModelType modelType, double priority) { 12 | myName = name; 13 | myProbability = probability; 14 | myModelType = modelType; 15 | myPriority = priority; 16 | } 17 | 18 | public VarNamePrediction(String name, double probability, ModelType modelType) { 19 | myName = name; 20 | myProbability = probability; 21 | myModelType = modelType; 22 | myPriority = 1; 23 | } 24 | 25 | public String getName() { 26 | return myName; 27 | } 28 | 29 | public double getProbability() { 30 | return myProbability; 31 | } 32 | 33 | public double getPriority() { 34 | return myPriority; 35 | } 36 | 37 | public ModelType getModelType() { 38 | return myModelType; 39 | } 40 | 41 | @Override 42 | public boolean equals(Object obj) { 43 | if (obj instanceof VarNamePrediction){ 44 | return myName.equals(((VarNamePrediction) obj).getName()); 45 | } 46 | return super.equals(obj); 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return myName + ':' + myProbability; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/statistics/IRenCollectorExtension.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.statistics; 2 | 3 | import com.intellij.codeInsight.lookup.impl.LookupUsageTracker; 4 | import com.intellij.internal.statistic.eventLog.events.DoubleEventField; 5 | import com.intellij.internal.statistic.eventLog.events.EventField; 6 | import com.intellij.internal.statistic.eventLog.events.EventFields; 7 | import com.intellij.internal.statistic.eventLog.events.StringEventField; 8 | import com.intellij.internal.statistic.service.fus.collectors.FeatureUsageCollectorExtension; 9 | import org.jetbrains.annotations.NonNls; 10 | import org.jetbrains.iren.config.ModelType; 11 | 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | @SuppressWarnings("UnstableApiUsage") 16 | public class IRenCollectorExtension implements FeatureUsageCollectorExtension { 17 | public final static StringEventField irenModelType = EventFields.String("iren_model_type", 18 | Arrays.asList(ModelType.DEFAULT.toString(), "both", ModelType.NGRAM.toString(), ModelType.DOBF.toString())); 19 | public final static DoubleEventField irenProbability = EventFields.Double("iren_probability"); 20 | 21 | @Override 22 | public @NonNls String getGroupId() { 23 | return LookupUsageTracker.GROUP_ID; 24 | } 25 | 26 | @Override 27 | public String getEventId() { 28 | return LookupUsageTracker.FINISHED_EVENT_ID; 29 | } 30 | 31 | @Override 32 | public List getExtensionFields() { 33 | return Arrays.asList(irenModelType, irenProbability); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/contributors/DOBFContributorKInference.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.contributors 2 | // 3 | //import io.kinference.ndarray.Strides 4 | //import io.kinference.ndarray.arrays.LongNDArray 5 | //import io.kinference.ndarray.arrays.MutableFloatNDArray 6 | //import io.kinference.ndarray.arrays.tiled.LongTiledArray 7 | //import io.kinference.ndarray.toIntArray 8 | //import io.kinference.ndarray.toLongArray 9 | //import org.jetbrains.iren.models.KInferenceModel 10 | //import org.jetbrains.iren.search.logSoftmax 11 | // 12 | //class DOBFContributorKInference : DOBFContributor() { 13 | // val model = KInferenceModel(encoderPath, decoderPath) 14 | // 15 | // override fun predictGreedy(idxs: List): Pair, Double> { 16 | // val (src_enc, src_len) = model.encode(idxs) 17 | // 18 | // val eosIdx = vocab.toIndex("") 19 | // val toDecList = mutableListOf(eosIdx) 20 | // 21 | //// Problem: it keeps generating VAR_i token 22 | // var logProb = .0 23 | // for (i in 0..5) { 24 | // val toDec = LongTiledArray(arrayOf(toDecList.toIntArray().toLongArray())) 25 | // val decIds = LongNDArray(toDec, Strides(intArrayOf(1, toDec.size))) // Shape: [B, T] 26 | // val out = model.decode(decIds, src_enc, src_len) 27 | // val idx: Int = out.argmax(1).array[0] 28 | // if (idx == eosIdx) break 29 | // logProb += logSoftmax(arrayOf((out.row(0) as MutableFloatNDArray).array.toArray()))[0][idx] 30 | // toDecList.add(idx) 31 | // } 32 | // return toDecList to logProb 33 | // } 34 | //} -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/extractors/features/Extractor.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.extractors.features 2 | 3 | import com.intellij.openapi.diagnostic.Logger 4 | import org.apache.commons.lang3.StringUtils 5 | import org.jetbrains.astrid.extractors.common.Common 6 | 7 | class Extractor(private val code: String) { 8 | 9 | private val log: Logger = Logger.getInstance(FeatureExtractor::class.java) 10 | 11 | private fun extractFromCodeBlock(): ArrayList { 12 | val featureExtractor = FeatureExtractor(this.code) 13 | return featureExtractor.extractFeatures() 14 | } 15 | 16 | fun processCodeBlock(): String { 17 | val features: ArrayList? 18 | try { 19 | features = extractFromCodeBlock() 20 | } catch (e: Exception) { 21 | log.info("Error was occurred while parsing method body.") 22 | return "" 23 | } 24 | val toPrint = featuresToString(features) 25 | return if (toPrint.isNotEmpty()) toPrint else "" 26 | } 27 | 28 | private fun featuresToString(features: ArrayList?): String { 29 | if (features == null || features.isEmpty()) { 30 | return Common.EMPTY_STRING 31 | } 32 | 33 | val methodsOutputs = ArrayList() 34 | 35 | for (singleMethodFeatures in features) { 36 | val builder = StringBuilder() 37 | val feature = singleMethodFeatures.toString() 38 | builder.append(feature) 39 | methodsOutputs.add(builder.toString()) 40 | } 41 | return StringUtils.join(methodsOutputs, "\n") 42 | } 43 | } -------------------------------------------------------------------------------- /plugin/src/main/java/com/intellij/completion/ngram/slp/counting/trie/my/ArrayStorage.java: -------------------------------------------------------------------------------- 1 | /* MIT License 2 | 3 | Copyright (c) 2018 SLP-team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | */ 15 | 16 | package com.intellij.completion.ngram.slp.counting.trie.my; 17 | 18 | import java.util.List; 19 | 20 | /* 21 | * Array storage 22 | */ 23 | public class ArrayStorage { 24 | public static boolean checkExactSequence(List indices, int index, int[] successor) { 25 | boolean valid = successor.length == indices.size() - index; 26 | if (valid) { 27 | for (int i = 1; i < successor.length; i++) { 28 | if (indices.get(index + i) != successor[i]) { 29 | valid = false; 30 | break; 31 | } 32 | } 33 | } 34 | return valid; 35 | } 36 | 37 | public static boolean checkPartialSequence(List indices, int index, int[] successor) { 38 | boolean valid = successor.length >= indices.size() - index; 39 | if (valid) { 40 | for (int i = 1; i < indices.size() - index; i++) { 41 | if (indices.get(index + i) != successor[i]) { 42 | valid = false; 43 | break; 44 | } 45 | } 46 | } 47 | return valid; 48 | } 49 | } -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/stats/RenameMethodStatistics.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.stats 2 | 3 | import com.intellij.openapi.components.PersistentStateComponent 4 | import com.intellij.openapi.components.ServiceManager; 5 | import com.intellij.openapi.components.State 6 | import com.intellij.openapi.components.Storage 7 | 8 | @State(name = "RenameMethodStatistics", storages = [(Storage("astrid_stats.xml"))]) 9 | class RenameMethodStatistics : PersistentStateComponent { 10 | private var statsState: RenameMethodState = RenameMethodState() 11 | 12 | override fun loadState(state: RenameMethodState) { 13 | statsState = state 14 | } 15 | 16 | override fun getState(): RenameMethodState { 17 | return statsState 18 | } 19 | 20 | companion object { 21 | fun applyCount(score: Double) { 22 | val stats = getInstance().statsState 23 | stats.applyRenameMethod(score) 24 | } 25 | 26 | fun ignoreCount(scores: List) { 27 | val stats = getInstance().statsState 28 | stats.ignoreRenameMethod(scores) 29 | } 30 | 31 | fun getInstance(): RenameMethodStatistics = ServiceManager.getService(RenameMethodStatistics::class.java) 32 | } 33 | } 34 | 35 | class RenameMethodState { 36 | 37 | var applied: Int = 0 38 | var ignored: Int = 0 39 | var appliedScores: ArrayList = ArrayList() 40 | var ignoredScores: ArrayList = ArrayList() 41 | 42 | fun applyRenameMethod(score: Double) { 43 | applied += 1 44 | appliedScores.add(score) 45 | } 46 | 47 | fun ignoreRenameMethod(scores: List) { 48 | ignored += 1 49 | ignoredScores.addAll(scores) 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/dobfEvaluator/DOBFVarNamer.kt: -------------------------------------------------------------------------------- 1 | package experiments.dobfEvaluator 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.intellij.openapi.application.ReadAction 5 | import com.intellij.openapi.diagnostic.logger 6 | import com.intellij.psi.PsiNameIdentifierOwner 7 | import com.intellij.util.io.HttpRequests 8 | import experiments.modelsEvaluatorApi.VarNamer 9 | import org.jetbrains.iren.LanguageSupporter 10 | import tools.DOBFPreprocessor 11 | import tools.VariableContext 12 | import java.nio.file.Path 13 | 14 | class DOBFVarNamer(saveDir: Path, supporter: LanguageSupporter, ngramType: String) : VarNamer( 15 | saveDir, supporter, 16 | ngramType 17 | ) { 18 | private val LOG = logger() 19 | private val DOBF_SERVER_URL = "http://127.0.0.1:5000/" 20 | override val maxNumberOfThreads = 7 21 | override fun predictWithNN(variable: PsiNameIdentifierOwner, thread: Int): Any { 22 | val variableContext = ReadAction.compute { 23 | DOBFPreprocessor.process( 24 | variable, 25 | variable.containingFile 26 | ) 27 | } 28 | synchronized(this) { 29 | return HttpRequests.post(DOBF_SERVER_URL, HttpRequests.JSON_CONTENT_TYPE) 30 | .connect({ 31 | val objectMapper = ObjectMapper() 32 | it.write(objectMapper.writeValueAsBytes(variableContext)) 33 | val str = it.readString() 34 | objectMapper.readValue(str, Any::class.java) 35 | }, null, LOG) 36 | } 37 | } 38 | 39 | override fun ignoreVarWithName(name: String): Boolean { 40 | return name == "self" 41 | } 42 | } -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/compareWithRAM/RamVarNamer.kt: -------------------------------------------------------------------------------- 1 | package experiments.compareWithRAM 2 | 3 | import com.intellij.openapi.application.ReadAction 4 | import com.intellij.psi.PsiNameIdentifierOwner 5 | import experiments.ModelPrediction 6 | import experiments.modelsEvaluatorApi.VarNamer 7 | import org.jetbrains.iren.LanguageSupporter 8 | import org.jetbrains.iren.ngram.NGramModelRunner 9 | import org.jetbrains.iren.services.NGramModelManager 10 | import org.jetbrains.iren.storages.VarNamePrediction 11 | import java.nio.file.Path 12 | 13 | open class RamVarNamer( 14 | saveDir: Path, 15 | supporter: LanguageSupporter, 16 | ngramType: String 17 | ) : VarNamer(saveDir, supporter, ngramType) { 18 | private val ramModelRunners: List by lazy { prepareRunners() } 19 | private fun prepareRunners(): List { 20 | val modelDir = saveDir.resolve("tmp_model") 21 | myModelRunner.save(modelDir, null) 22 | return (0 until maxNumberOfThreads).map { 23 | println("Preparing ${it + 1}-th runner") 24 | val runner = NGramModelRunner() 25 | runner.load(modelDir, null) 26 | runner 27 | } 28 | } 29 | 30 | override fun predictWithNN(variable: PsiNameIdentifierOwner, thread: Int): Any { 31 | val runner = ramModelRunners[thread] 32 | ReadAction.run { NGramModelManager.getInstance(variable.project).forgetFileIfNeeded(runner, variable.containingFile) } 33 | val nameSuggestions: List = 34 | ReadAction.compute, Exception> { runner.suggestNames(variable) } 35 | return nameSuggestions.map { x: VarNamePrediction -> ModelPrediction(x.name, x.probability) } 36 | } 37 | } -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/utils/FileUtils.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.utils 2 | 3 | import java.io.BufferedOutputStream 4 | import java.io.File 5 | import java.io.FileInputStream 6 | import java.io.FileOutputStream 7 | import java.util.zip.ZipEntry 8 | import java.util.zip.ZipInputStream 9 | 10 | object FileUtils { 11 | 12 | private const val BUFFER_SIZE = 4096 13 | 14 | /** 15 | * Extracts a zip file specified by the zipFilePath to a directory specified by 16 | * destDirectory (will be created if does not exists) 17 | */ 18 | fun unzip(zipFilePath: String, destDirectory: String) { 19 | val destDir = File(destDirectory) 20 | if (!destDir.exists()) { 21 | destDir.mkdir() 22 | } 23 | val zipIn = ZipInputStream(FileInputStream(zipFilePath)) 24 | var entry: ZipEntry? = zipIn.nextEntry 25 | while (entry != null) { 26 | val filePath = destDirectory + File.separator + entry.name 27 | if (!entry.isDirectory) { 28 | extractFile(zipIn, filePath) 29 | } else { 30 | val dir = File(filePath) 31 | dir.mkdir() 32 | } 33 | zipIn.closeEntry() 34 | entry = zipIn.nextEntry 35 | } 36 | zipIn.close() 37 | } 38 | 39 | /** 40 | * Extracts a zip entry (file entry) 41 | */ 42 | private fun extractFile(zipIn: ZipInputStream, filePath: String) { 43 | val bos = BufferedOutputStream(FileOutputStream(filePath)) 44 | val bytesIn = ByteArray(BUFFER_SIZE) 45 | var read = 0 46 | while (read != -1) { 47 | bos.write(bytesIn, 0, read) 48 | read = zipIn.read(bytesIn) 49 | } 50 | bos.close() 51 | } 52 | } -------------------------------------------------------------------------------- /experiments/src/main/kotlin/experiments/gnnEvaluator/GNNVarNamer.kt: -------------------------------------------------------------------------------- 1 | package experiments.gnnEvaluator 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper 4 | import com.google.gson.GsonBuilder 5 | import com.intellij.openapi.diagnostic.logger 6 | import com.intellij.psi.PsiFile 7 | import com.intellij.psi.PsiNameIdentifierOwner 8 | import com.intellij.psi.PsiVariable 9 | import com.intellij.util.io.HttpRequests 10 | import experiments.VarNamePredictions 11 | import experiments.modelsEvaluatorApi.VarNamer 12 | import org.jetbrains.iren.LanguageSupporter 13 | import tools.graphVarMiner.GraphDatasetExtractor 14 | import tools.graphVarMiner.JavaGraphExtractor 15 | import java.nio.file.Path 16 | 17 | class GNNVarNamer(saveDir: Path, supporter: LanguageSupporter, ngramType: String) : VarNamer(saveDir, supporter, 18 | ngramType 19 | ) { 20 | private lateinit var graphExtractor: JavaGraphExtractor 21 | private val LOG = logger() 22 | private val GNN_SERVER_URL = "http://127.0.0.1:5000/" 23 | 24 | override fun predictPsiFile(file: PsiFile, thread: Int): Collection? { 25 | graphExtractor = JavaGraphExtractor(file) 26 | return super.predictPsiFile(file, thread) 27 | } 28 | 29 | override fun predictWithNN(variable: PsiNameIdentifierOwner, thread: Int): Any { 30 | // works only with java 31 | val varData = GraphDatasetExtractor.getVarData(variable as PsiVariable, graphExtractor.file, graphExtractor) 32 | return HttpRequests.post(GNN_SERVER_URL, HttpRequests.JSON_CONTENT_TYPE) 33 | .connect( { 34 | it.write(GsonBuilder().create().toJson(varData)) 35 | val str = it.readString() 36 | ObjectMapper().readValue(str, Any::class.java) 37 | }, null, LOG) 38 | } 39 | } -------------------------------------------------------------------------------- /languages/common/test/org/jetbrains/iren/LanguageSupporterTest.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren; 2 | 3 | import com.intellij.codeInsight.TargetElementUtil; 4 | import com.intellij.openapi.editor.Caret; 5 | import com.intellij.psi.PsiElement; 6 | import com.intellij.testFramework.LightPlatformCodeInsightTestCase; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public abstract class LanguageSupporterTest extends LightPlatformCodeInsightTestCase { 11 | public @NotNull PsiElement getTargetElementAtCaret() { 12 | @Nullable PsiElement element = TargetElementUtil.findTargetElement( 13 | getEditor(), 14 | TargetElementUtil.ELEMENT_NAME_ACCEPTED | TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED 15 | ); 16 | assertNotNull(element); 17 | return element; 18 | } 19 | 20 | @NotNull 21 | public PsiElement getTargetElementAtCaret(Caret caret) { 22 | final PsiElement element = new TargetElementUtil().findTargetElement( 23 | getEditor(), 24 | TargetElementUtil.ELEMENT_NAME_ACCEPTED | TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED, 25 | caret.getOffset() 26 | ); 27 | assertNotNull(element); 28 | return element; 29 | } 30 | 31 | @Override 32 | protected @NotNull String getTestDataPath() { 33 | return "testData/" + getTestDataBasePath(); 34 | } 35 | 36 | protected @NotNull String getTestFileName() { 37 | return getTestName(true)/* for parametrized tests */.split("\\(")[0] + getFileExtension(); 38 | } 39 | 40 | protected abstract @NotNull String getTestDataBasePath(); 41 | 42 | public abstract @NotNull String getFileExtension(); 43 | 44 | public abstract @NotNull LanguageSupporter getLanguageSupporter(); 45 | } 46 | -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/training/ProgressBar.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.training; 2 | 3 | import com.intellij.history.core.Paths; 4 | import com.intellij.openapi.progress.ProgressIndicator; 5 | import com.intellij.openapi.vfs.VirtualFile; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | import java.util.function.DoubleFunction; 9 | 10 | public class ProgressBar { 11 | private final ProgressIndicator progressIndicator; 12 | private final String projectPath; 13 | int progress = 0; 14 | int total; 15 | boolean wasVocabTrained = false; 16 | 17 | public ProgressBar(int total, @Nullable ProgressIndicator progressIndicator, @Nullable String projectPath) { 18 | this.total = total; 19 | this.progressIndicator = progressIndicator; 20 | this.projectPath = projectPath; 21 | } 22 | 23 | public void clear(int newTotal) { 24 | progress = 0; 25 | total = newTotal; 26 | } 27 | 28 | public synchronized void vocabularyTrainingStep(VirtualFile file) { 29 | wasVocabTrained = true; 30 | step(file, fraction -> fraction / 2); 31 | } 32 | 33 | public synchronized void step(VirtualFile file, DoubleFunction modifyFraction) { 34 | double fraction = ++progress / (double) total; 35 | if (total < 10 || progress % (total / 10) == 0) { 36 | System.out.printf("Status:\t%.0f%%\r", fraction * 100.); 37 | } 38 | if (progressIndicator != null) { 39 | progressIndicator.setText2(projectPath != null ? Paths.relativeIfUnder(file.getPath(), projectPath) : file.getPath()); 40 | progressIndicator.setFraction(modifyFraction.apply(fraction)); 41 | } 42 | } 43 | 44 | public synchronized void trainingStep(VirtualFile file) { 45 | step(file, fraction -> wasVocabTrained ? 0.5 + fraction / 2 : fraction); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/rename/IRenLookups.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.rename; 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement; 4 | import com.intellij.codeInsight.lookup.LookupElementDecorator; 5 | import com.intellij.codeInsight.lookup.LookupElementPresentation; 6 | import com.intellij.openapi.util.Key; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.iren.config.ModelType; 9 | 10 | import java.util.LinkedHashMap; 11 | import java.util.Map; 12 | 13 | public class IRenLookups { 14 | public static Key modelTypeKey = new Key<>("model_type"); 15 | 16 | public static class LookupWithProbability extends LookupElementDecorator { 17 | public static Key probabilityKey = new Key<>("probability"); 18 | 19 | protected LookupWithProbability(@NotNull LookupElement delegate, Map namesProbs, LinkedHashMap modelTypes) { 20 | super(delegate); 21 | String name = getLookupString(); 22 | putUserData(modelTypeKey, modelTypes.get(name).toString()); 23 | putUserData(probabilityKey, namesProbs.get(name)); 24 | } 25 | 26 | @Override 27 | public void renderElement(LookupElementPresentation presentation) { 28 | super.renderElement(presentation); 29 | Double probability = getUserData(LookupWithProbability.probabilityKey); 30 | if (probability == null) return; 31 | String modelType = getUserData(modelTypeKey); 32 | presentation.setTypeText(String.format("%s%3.0f%%", modelType, probability * 100)); 33 | } 34 | } 35 | 36 | public static class Default extends LookupElementDecorator { 37 | protected Default(@NotNull LookupElement delegate) { 38 | super(delegate); 39 | putUserData(modelTypeKey, ModelType.DEFAULT.toString()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/statistics/IRenLookupUsageDescriptor.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.statistics; 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement; 4 | import com.intellij.codeInsight.lookup.impl.LookupResultDescriptor; 5 | import com.intellij.codeInsight.lookup.impl.LookupUsageDescriptor; 6 | import com.intellij.internal.statistic.eventLog.events.*; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | import org.jetbrains.iren.config.ModelType; 10 | import org.jetbrains.iren.rename.IRenLookups; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | import static org.jetbrains.iren.statistics.IRenCollectorExtension.irenModelType; 16 | import static org.jetbrains.iren.statistics.IRenCollectorExtension.irenProbability; 17 | 18 | @SuppressWarnings("UnstableApiUsage") 19 | public class IRenLookupUsageDescriptor implements LookupUsageDescriptor { 20 | @Override 21 | public @NotNull String getExtensionKey() { 22 | return "iren"; 23 | } 24 | 25 | @Override 26 | public List> getAdditionalUsageData(@NotNull LookupResultDescriptor lookupResultDescriptor) { 27 | LookupElement lookupElement = lookupResultDescriptor.getSelectedItem(); 28 | List> eventPairs = new ArrayList<>(); 29 | if (lookupElement == null) return eventPairs; 30 | @Nullable String model_type = lookupElement.getUserData(IRenLookups.modelTypeKey); 31 | if (model_type == null) return eventPairs; 32 | eventPairs.add(irenModelType.with(model_type)); 33 | if (!model_type.equals(ModelType.DEFAULT.toString())) { 34 | @Nullable Double probability = lookupElement.getUserData(IRenLookups.LookupWithProbability.probabilityKey); 35 | if (probability == null) return eventPairs; 36 | eventPairs.add(irenProbability.with(probability)); 37 | } 38 | return eventPairs; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /plugin/src/main/kotlin/org/jetbrains/iren/utils/OrtUtils.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.utils 2 | 3 | import ai.onnxruntime.OnnxTensor 4 | import ai.onnxruntime.OrtEnvironment 5 | import io.kinference.ndarray.toLongArray 6 | import java.nio.FloatBuffer 7 | import java.nio.LongBuffer 8 | 9 | const val PAD_IDX = 2 10 | 11 | fun prepareInput(idxs: List>, env: OrtEnvironment): Pair { 12 | val maxLength = idxs.maxOf { it.size } 13 | val array = 14 | Array(maxLength * idxs.size) { idxs[it.floorDiv(maxLength)].getOrElse(it.floorMod(maxLength)) { PAD_IDX } } 15 | val x = OnnxTensor.createTensor( 16 | env, LongBuffer.wrap(array.toIntArray().toLongArray()), longArrayOf(idxs.size.toLong(), maxLength.toLong()) 17 | ) 18 | val lengths = OnnxTensor.createTensor(env, LongArray(idxs.size) { idxs[it].size.toLong() }) 19 | return Pair(x, lengths) 20 | } 21 | 22 | 23 | 24 | fun tensorToArrays2D(logProbs: OnnxTensor): Array { 25 | val logProbArray = logProbs.floatBuffer.array() 26 | val shape = logProbs.info.shape 27 | return Array(shape[0].toInt()) { 28 | logProbArray.sliceArray(it * shape[1].toInt() until (it + 1) * shape[1].toInt()) 29 | } 30 | } 31 | 32 | /** 33 | * Repeat tensor on first dimension [n] times. Works with long and float values. 34 | **/ 35 | fun OnnxTensor.repeat(n: Int, env: OrtEnvironment): OnnxTensor { 36 | val shape = this.info.shape 37 | val newShape = shape.copyOf() 38 | newShape[0] = newShape[0] * n 39 | this.floatBuffer?.let { buffer -> 40 | val data = buffer.array() 41 | buffer.limit() 42 | return OnnxTensor.createTensor( 43 | env, 44 | FloatBuffer.wrap(FloatArray(data.size * n) { data[it.floorMod(data.size)] }), newShape 45 | ) 46 | } 47 | val data = this.longBuffer.array() 48 | return OnnxTensor.createTensor( 49 | env, 50 | LongBuffer.wrap(LongArray(data.size * n) { data[it.floorMod(data.size)] }), 51 | newShape 52 | ) 53 | } 54 | -------------------------------------------------------------------------------- /languages/common/src/main/kotlin/org/jetbrains/iren/DOBFTokenizer.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren 2 | 3 | import org.jetbrains.iren.utils.StringUtils 4 | 5 | open class DOBFTokenizer { 6 | open val token2char = mapOf( 7 | "STOKEN00" to "//", 8 | "STOKEN01" to "/*", 9 | "STOKEN02" to "*/", 10 | "STOKEN03" to "/**", 11 | "STOKEN04" to "**/", 12 | "STOKEN05" to "\"\"\"", 13 | "STOKEN06" to "\\n", 14 | "STOKEN07" to "\\r", 15 | "STOKEN08" to ";", 16 | "STOKEN09" to "{", 17 | "STOKEN10" to "}", 18 | "STOKEN11" to "\\\'", 19 | "STOKEN12" to "\\\"", 20 | "STOKEN13" to "\\\\", 21 | ) 22 | private val char2token: Map by lazy { token2char.map { (k, v) -> v to " $k " }.toMap() } 23 | 24 | val UTOKEN = "UTOKEN" 25 | val XTOKEN = "XTOKEN" 26 | 27 | open fun process(text: String): String { 28 | return text.replace("\\u", UTOKEN) 29 | .replace("\\x", XTOKEN) 30 | .replace("\r", "") 31 | .replace("\\r", "") 32 | .replace(" ", " ${StringUtils.SPACE_TOKEN} ") 33 | .replace("\n", " ${StringUtils.STR_NEW_LINE_TOKEN} ") 34 | .replace("\t", " ${StringUtils.STR_TAB_TOKEN} ") 35 | .replaceTokens(char2token) 36 | .processWithSTokens() 37 | .replace(" +".toRegex(), " ") 38 | .replace("(\\D)(\\p{Punct})".toRegex(), "$1 $2 ") 39 | .replace("(\\p{Punct})(\\D)".toRegex(), " $1 $2") 40 | .replace("(\\p{S})".toRegex(), " $1 ") 41 | .replace(" +".toRegex(), " ") 42 | .replaceTokens(token2char) 43 | .replace(UTOKEN, "\\u") 44 | .replace(XTOKEN, "\\x") 45 | .trim() 46 | } 47 | 48 | open fun String.processWithSTokens(): String { 49 | return this 50 | } 51 | } 52 | 53 | fun String.replaceTokens(map: Map): String { 54 | var result = this 55 | for ((k, v) in map) { 56 | result = result.replace(k, v) 57 | } 58 | return result 59 | } -------------------------------------------------------------------------------- /experiments/src/main/java/utils/ChunkWriter.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import com.intellij.openapi.diagnostic.Logger; 6 | 7 | import java.io.FileOutputStream; 8 | import java.io.IOException; 9 | import java.io.OutputStreamWriter; 10 | import java.io.Writer; 11 | import java.nio.charset.StandardCharsets; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.zip.GZIPOutputStream; 15 | 16 | public class ChunkWriter { 17 | private final String pathPrefix; 18 | private int currentChunkIdx = 0; 19 | private final int maxChunkSize; 20 | private final List unwrittenElements = new ArrayList<>(); 21 | private final Logger log = Logger.getInstance(ChunkWriter.class); 22 | 23 | public ChunkWriter(String pathPrefix, int maxChunkSize) { 24 | this.pathPrefix = pathPrefix; 25 | this.maxChunkSize = maxChunkSize; 26 | } 27 | 28 | public void add(T element) { 29 | unwrittenElements.add(element); 30 | if (unwrittenElements.size() >= maxChunkSize) { 31 | try { 32 | writeChunk(); 33 | } catch (IOException e) { 34 | throw new Error("Cannot write to output chunk file: " + e); 35 | } 36 | } 37 | } 38 | 39 | private void writeChunk() throws IOException { 40 | log.info(String.format("Writing chunk number %d...", currentChunkIdx)); 41 | try (FileOutputStream output = new FileOutputStream(pathPrefix + '.' + currentChunkIdx + ".json.gz"); 42 | Writer writer = new OutputStreamWriter(new GZIPOutputStream(output), StandardCharsets.UTF_8)) { 43 | Gson gson = new GsonBuilder().create(); 44 | writer.write(gson.toJson(unwrittenElements)); 45 | } 46 | 47 | currentChunkIdx++; 48 | unwrittenElements.clear(); 49 | } 50 | 51 | public void close() { 52 | try { 53 | writeChunk(); 54 | } catch (IOException e) { 55 | throw new Error("Cannot write to output chunk file: " + e); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /plugin/src/main/java/org/jetbrains/iren/services/NGramModelManagerImpl.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.services; 2 | 3 | import com.intellij.openapi.project.Project; 4 | import com.intellij.psi.PsiFile; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | import org.jetbrains.iren.ModelRunner; 8 | import org.jetbrains.iren.utils.ModelUtils; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | public class NGramModelManagerImpl implements NGramModelManager { 14 | private final Map myModelRunners = new HashMap<>(); 15 | 16 | @Override 17 | public @Nullable ModelRunner get(@NotNull String name) { 18 | return myModelRunners.get(name); 19 | } 20 | 21 | @Override 22 | public void put(@NotNull String name, @NotNull ModelRunner modelRunner) { 23 | myModelRunners.put(name, modelRunner); 24 | } 25 | 26 | @Override 27 | public void remove(@NotNull String name) { 28 | myModelRunners.remove(name); 29 | } 30 | 31 | @Override 32 | public void removeProjectModelRunners(@NotNull Project project) { 33 | String name = project.getName() + "_" + project.getLocationHash(); 34 | myModelRunners.entrySet().removeIf(entry -> entry.getKey().contains(name)); 35 | } 36 | 37 | @Override 38 | public void dispose() { 39 | myModelRunners.clear(); 40 | } 41 | 42 | private final Map fileMap = new HashMap<>(); 43 | 44 | public synchronized void forgetFileIfNeeded(@NotNull ModelRunner modelRunner, @NotNull PsiFile newFile) { 45 | String modelKey = modelRunner.toString(); 46 | PsiFile oldFile = fileMap.get(modelKey); 47 | if (newFile != oldFile) { 48 | if (oldFile != null) modelRunner.learnPsiFile(oldFile); 49 | modelRunner.forgetPsiFile(newFile); 50 | fileMap.put(modelKey, newFile); 51 | } 52 | } 53 | 54 | @Override 55 | public boolean containsIntellijModel() { 56 | return myModelRunners.keySet().stream().anyMatch(name -> 57 | name.startsWith(ModelUtils.INTELLIJ_NAME) 58 | ); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /languages/kotlin/src/org/jetbrains/iren/rename/IRenKotlinMemeberInplaceRenamer.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.rename 2 | 3 | import com.intellij.lang.Language 4 | import com.intellij.openapi.editor.Editor 5 | import com.intellij.psi.PsiElement 6 | import com.intellij.psi.PsiNamedElement 7 | import com.intellij.psi.PsiReference 8 | import com.intellij.refactoring.RefactoringActionHandler 9 | import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer 10 | import org.jetbrains.kotlin.idea.base.psi.unquoteKotlinIdentifier 11 | import org.jetbrains.kotlin.psi.KtObjectDeclaration 12 | 13 | class IRenKotlinMemeberInplaceRenamer : IRenMemberInplaceRenamer { 14 | constructor( 15 | elementToRename: PsiNamedElement, 16 | substitutedElement: PsiElement?, 17 | editor: Editor, 18 | currentName: String, 19 | oldName: String, 20 | ) : super(elementToRename, substitutedElement, editor, currentName, oldName) 21 | 22 | constructor( 23 | elementToRename: PsiNamedElement, 24 | editor: Editor, 25 | ) : super(elementToRename, editor) 26 | 27 | override fun isIdentifier(newName: String?, language: Language?): Boolean { 28 | if (newName == "" && (variable as? KtObjectDeclaration)?.isCompanion() == true) return true 29 | return super.isIdentifier(newName, language) 30 | } 31 | 32 | override fun acceptReference(reference: PsiReference): Boolean { 33 | val refElement = reference.element 34 | val textRange = reference.rangeInElement 35 | val referenceText = refElement.text.substring(textRange.startOffset, textRange.endOffset).unquoteKotlinIdentifier() 36 | return referenceText == myElementToRename.name 37 | } 38 | 39 | override fun startsOnTheSameElement(handler: RefactoringActionHandler?, element: PsiElement?): Boolean { 40 | return variable == element && (handler is IRenMemberInplaceRenameHandler) 41 | } 42 | 43 | override fun createInplaceRenamerToRestart( 44 | variable: PsiNamedElement, 45 | editor: Editor, 46 | initialName: String, 47 | ): VariableInplaceRenamer { 48 | return IRenKotlinMemeberInplaceRenamer(variable, substituted, editor, initialName, myOldName) 49 | } 50 | } -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/extractors/visitors/LeavesVisitor.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.extractors.visitors 2 | 3 | import com.github.javaparser.ast.Node 4 | import com.github.javaparser.ast.comments.Comment 5 | import com.github.javaparser.ast.expr.NullLiteralExpr 6 | import com.github.javaparser.ast.stmt.Statement 7 | import com.github.javaparser.ast.type.ClassOrInterfaceType 8 | import com.github.javaparser.ast.visitor.TreeVisitor 9 | import org.jetbrains.astrid.extractors.common.Common 10 | import org.jetbrains.astrid.extractors.features.Property 11 | 12 | class LeavesVisitor : TreeVisitor() { 13 | val leaves = ArrayList() 14 | 15 | override fun process(node: Node) { 16 | if (node is Comment) { 17 | return 18 | } 19 | var isLeaf = false 20 | val isGenericParent = isGenericParent(node) 21 | if (hasNoChildren(node) && isNotComment(node)) { 22 | if (!node.toString().isEmpty() && ("null" != node.toString() || node is NullLiteralExpr)) { 23 | leaves.add(node) 24 | isLeaf = true 25 | } 26 | } 27 | val childId = getChildId(node) 28 | node.setUserData(Common.CHILD_ID, childId) 29 | val property = Property(node, isLeaf, isGenericParent) 30 | node.setUserData(Common.PROPERTY_KEY, property) 31 | } 32 | 33 | private fun isGenericParent(node: Node): Boolean { 34 | return (node is ClassOrInterfaceType 35 | && node.typeArguments != null 36 | && node.typeArguments.size > 0) 37 | } 38 | 39 | private fun hasNoChildren(node: Node): Boolean { 40 | return node.childrenNodes.size == 0 41 | } 42 | 43 | private fun isNotComment(node: Node): Boolean { 44 | return node !is Comment && node !is Statement 45 | } 46 | 47 | private fun getChildId(node: Node): Int { 48 | val parent = node.parentNode 49 | val parentsChildren = parent.childrenNodes 50 | var childId = 0 51 | for (child in parentsChildren) { 52 | if (child.range == node.range) { 53 | return childId 54 | } 55 | childId++ 56 | } 57 | return childId 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /plugin/src/main/resources/messages/IRen.properties: -------------------------------------------------------------------------------- 1 | name=IRen Plugin 2 | prepare.models.title=Preparing IRen models 3 | # Training 4 | training.task.title=Building IRen models 5 | training.progress.indicator.text=Training models for {0}; Language: {1} 6 | training.progress.indexing=Waiting for indexes to be updated 7 | # Saving 8 | saving.text=Saving IRen model for {0}; Language: {1} 9 | saving.file=Saving: {0} 10 | # Loading 11 | loading.text=Loading IRen model for {0}; Language: {1} 12 | loading.file=Loading: {0} 13 | # Deletion 14 | delete.old.models.process=Deleting old IRen models 15 | delete.old.models.notification=Old IRen models were deleted 16 | # Model statistics 17 | model.training.completed=IRen model's training is completed 18 | model.training.statistics=Project: {0};\nLanguage: {1};\nTime of training: {2} s;\nVocabulary size: {3}; 19 | model.training.early.stopped=IRen model's training is early stopped 20 | model.training.early.stopped.explanation=The quality of suggestions might be poor. 21 | model.loading.statistics=Project: {0};\nLanguage: {1};\nTime of loading: {2} s;\nVocabulary size: {3}; 22 | model.loaded=IRen model is loaded 23 | model.size=Model size: {0} MB 24 | # Settings 25 | settings.automatic.training=Automatic training of the models. 26 | settings.title.model.parameters=Model Parameters 27 | settings.max.training.time=Maximal models' training time: 28 | settings.vocabulary.cutoff=Vocabulary cutoff: 29 | settings.vocabulary.cutoff.comment=Remove words with the frequencies smaller than this. 30 | settings.title.retraining=Retraining Settings 31 | settings.models.lifetime=Models' lifetime: 32 | settings.models.lifetime.comment=The time after which the model will be retrained. 33 | # Loading models 34 | downloading.model=Downloading model for {} 35 | extracting.model=Extracting model for {} 36 | downloading.model.done=Model for {} was successfully downloaded 37 | # Loading DOBF models 38 | dobf.model.loading=Loading DOBF model for {0} 39 | dobf.model.loaded=DOBF model is loaded 40 | dobf.model.loading.statistics=Language: {0};\nTime of loading: {1} s 41 | # Out of memory 42 | out.memory.title=IRen model's training is canceled 43 | out.memory.text=There is not enough memory to train IRen models. Please consider increasing available heap. 44 | -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/helpers/TensorConverter.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.helpers; 2 | 3 | //import org.tensorflow.Tensor; 4 | 5 | public class TensorConverter { 6 | 7 | // public static List parsePredictions(Tensor tensor) { 8 | // int predictionsCount = 10; 9 | // int maxSubtokenCount = (int) tensor.shape()[1]; 10 | // int[][][] predictionsMatrix = new int[(int) tensor.shape()[0]][maxSubtokenCount][(int) tensor.shape()[2]]; 11 | // tensor.copyTo(predictionsMatrix); 12 | // 13 | // List predictions = new ArrayList<>(maxSubtokenCount); 14 | // for (int i = 0; i < maxSubtokenCount; i++) { 15 | // predictions.add(Collections.singletonList(predictionsMatrix[0][i])); 16 | // } 17 | // 18 | // List listsOfIndexes = new ArrayList<>(); 19 | // for (int i = 0; i < predictionsCount; i++) { 20 | // List subtokenIndexes = new ArrayList(); 21 | // for (int z = 0; z < maxSubtokenCount; z++) { 22 | // subtokenIndexes.add(((int[]) predictions.get(z).get(0))[i]); 23 | // } 24 | // listsOfIndexes.add(subtokenIndexes); 25 | // } 26 | // return listsOfIndexes; 27 | // } 28 | // 29 | // public static List parseScores(Tensor tensor) { 30 | // int scoresCount = 10; 31 | // int maxSubtokenCount = (int) tensor.shape()[1]; 32 | // float[][][] predictionsMatrix = new float[(int) tensor.shape()[0]][maxSubtokenCount][(int) tensor.shape()[2]]; 33 | // tensor.copyTo(predictionsMatrix); 34 | // 35 | // List listOfSubtokenScores = new ArrayList<>(maxSubtokenCount); 36 | // for (int i = 0; i < maxSubtokenCount; i++) { 37 | // listOfSubtokenScores.add(Collections.singletonList(predictionsMatrix[0][i])); 38 | // } 39 | // 40 | // List listsOfScores = new ArrayList<>(); 41 | // for (int i = 0; i < scoresCount; i++) { 42 | // double score = 0.0; 43 | // for (int z = 0; z < maxSubtokenCount; z++) { 44 | // score += ((float[]) listOfSubtokenScores.get(z).get(0))[i]; 45 | // } 46 | // listsOfScores.add(Math.exp(score)); 47 | // } 48 | // return listsOfScores; 49 | // } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/extractors/visitors/FunctionVisitor.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.extractors.visitors 2 | 3 | import com.github.javaparser.ast.body.MethodDeclaration 4 | import com.github.javaparser.ast.visitor.VoidVisitorAdapter 5 | import org.jetbrains.astrid.extractors.common.Common 6 | import org.jetbrains.astrid.extractors.common.MethodContent 7 | import java.util.* 8 | 9 | class FunctionVisitor : VoidVisitorAdapter() { 10 | val methodContents = ArrayList() 11 | 12 | override fun visit(node: MethodDeclaration, arg: Any) { 13 | visitMethod(node, arg) 14 | super.visit(node, arg) 15 | } 16 | 17 | private fun visitMethod(node: MethodDeclaration, arg: Any) { 18 | val leavesCollectorVisitor = LeavesVisitor() 19 | leavesCollectorVisitor.visitDepthFirst(node) 20 | val leaves = leavesCollectorVisitor.leaves 21 | val normalizedMethodName = Common.normalizeName(node.name, Common.BLANK) 22 | val splitNameParts = Common.splitToSubtokens(node.name) 23 | var splitName = normalizedMethodName 24 | if (splitNameParts.size > 0) { 25 | splitName = splitNameParts.joinToString(Common.INTERNAL_SEPARATOR) 26 | } 27 | 28 | if (node.body != null) { 29 | methodContents.add(MethodContent(leaves, splitName, getMethodLength(node.body.toString()))) 30 | } 31 | } 32 | 33 | private fun getMethodLength(code: String): Long { 34 | var cleanCode = code.replace("\r\n".toRegex(), "\n").replace("\t".toRegex(), " ") 35 | if (cleanCode.startsWith("{\n")) 36 | cleanCode = cleanCode.substring(3).trim { it <= ' ' } 37 | if (cleanCode.endsWith("\n}")) 38 | cleanCode = cleanCode.substring(0, cleanCode.length - 2).trim { it <= ' ' } 39 | return if (cleanCode.isEmpty()) { 40 | 0 41 | } else Arrays.stream(cleanCode.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) 42 | .filter { line -> 43 | line.trim { it <= ' ' } != "{" && line.trim { it <= ' ' } != "}" 44 | && line.trim { it <= ' ' } != "" 45 | }.filter { line -> 46 | !line.trim { it <= ' ' } 47 | .startsWith("/") && !line.trim { it <= ' ' }.startsWith("*") 48 | }.count() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/rename/IRenLookupExpression.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.rename; 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement; 4 | import com.intellij.codeInsight.template.ExpressionContext; 5 | import com.intellij.psi.PsiElement; 6 | import com.intellij.psi.PsiNamedElement; 7 | import com.intellij.refactoring.rename.inplace.MyLookupExpression; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.Nullable; 10 | import org.jetbrains.iren.config.ModelType; 11 | 12 | import java.util.ArrayList; 13 | import java.util.LinkedHashMap; 14 | import java.util.LinkedHashSet; 15 | import java.util.List; 16 | 17 | public class IRenLookupExpression extends MyLookupExpression { 18 | private final LinkedHashMap myNameProbabilities; 19 | private final LinkedHashMap myModelTypes; 20 | 21 | public IRenLookupExpression(String name, 22 | @Nullable LinkedHashSet names, 23 | @NotNull PsiNamedElement elementToRename, 24 | @Nullable PsiElement nameSuggestionContext, 25 | boolean shouldSelectAll, 26 | String advertisement, 27 | @NotNull LinkedHashMap nameProbabilities, 28 | LinkedHashMap modelTypes) { 29 | super(name, names, elementToRename, nameSuggestionContext, shouldSelectAll, advertisement); 30 | myNameProbabilities = nameProbabilities; 31 | myModelTypes = modelTypes; 32 | } 33 | 34 | @Override 35 | public LookupElement[] calculateLookupItems(ExpressionContext context) { 36 | LookupElement[] lookupElements = super.calculateLookupItems(context); 37 | List newLookupElements = new ArrayList<>(); 38 | for (LookupElement lookupElement : lookupElements) { 39 | newLookupElements.add( 40 | myModelTypes.getOrDefault(lookupElement.getLookupString(), ModelType.DEFAULT) != ModelType.DEFAULT ? 41 | new IRenLookups.LookupWithProbability(lookupElement, myNameProbabilities, myModelTypes) : 42 | new IRenLookups.Default(lookupElement)); 43 | } 44 | return newLookupElements.toArray(lookupElements); 45 | } 46 | } -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/utils/IdeaUtil.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.utils; 2 | 3 | import com.intellij.openapi.application.ReadAction; 4 | import com.intellij.openapi.module.ModuleManager; 5 | import com.intellij.openapi.project.DumbService; 6 | import com.intellij.openapi.project.Project; 7 | import com.intellij.openapi.util.Key; 8 | import com.intellij.psi.JavaPsiFacade; 9 | import com.intellij.psi.search.GlobalSearchScope; 10 | import com.intellij.psi.search.GlobalSearchScopesCore; 11 | import com.intellij.ui.components.JBList; 12 | import com.intellij.util.containers.ContainerUtil; 13 | import org.jetbrains.annotations.NonNls; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | import java.util.List; 17 | 18 | /** 19 | * Copied necessary from org.jetbrains.idea.devkit.util.PsiUtil 20 | */ 21 | public class IdeaUtil { 22 | private static final Key IDEA_PROJECT = Key.create("idea.internal.inspections.enabled"); 23 | private static final List IDEA_PROJECT_MARKER_MODULE_NAMES = 24 | ContainerUtil.immutableList("intellij.idea.community.main", "intellij.platform.commercial"); 25 | private static final @NonNls String IDE_PROJECT_MARKER_CLASS = JBList.class.getName(); 26 | 27 | public static boolean isIdeaProject(@NotNull Project project) { 28 | Boolean flag = project.getUserData(IDEA_PROJECT); 29 | if (flag == null) { 30 | flag = checkIdeaProject(project); 31 | project.putUserData(IDEA_PROJECT, flag); 32 | } 33 | return flag; 34 | } 35 | 36 | private static boolean checkIdeaProject(@NotNull Project project) { 37 | boolean foundMarkerModule = false; 38 | for (String moduleName : IDEA_PROJECT_MARKER_MODULE_NAMES) { 39 | if (ModuleManager.getInstance(project).findModuleByName(moduleName) != null) { 40 | foundMarkerModule = true; 41 | break; 42 | } 43 | } 44 | if (!foundMarkerModule) return false; 45 | 46 | return ReadAction.nonBlocking(() -> 47 | DumbService.getInstance(project).computeWithAlternativeResolveEnabled(() -> { 48 | GlobalSearchScope scope = GlobalSearchScopesCore.projectProductionScope(project); 49 | return JavaPsiFacade.getInstance(project).findClass(IDE_PROJECT_MARKER_CLASS, scope) != null; 50 | }) 51 | ).executeSynchronously(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /languages/common/src/main/java/org/jetbrains/iren/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.utils; 2 | 3 | import com.intellij.util.text.NameUtilCore; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.util.*; 8 | import java.util.stream.Collectors; 9 | 10 | public class StringUtils { 11 | public static final String STRING_TOKEN = ""; 12 | public static final String NUMBER_TOKEN = ""; 13 | public static final String VARIABLE_TOKEN = ""; 14 | public static final String END_SUBTOKEN = ""; 15 | public static final List INTEGERS_TO_LEAVE = Arrays.asList("0", "1", "32", "64"); 16 | public static final String NEW_LINE_TOKEN = "NEW_LINE"; 17 | public static final String INDENT_TOKEN = "INDENT"; 18 | public static final String DEDENT_TOKEN = "DEDENT"; 19 | public static final String SPACE_TOKEN = "▁"; 20 | public static final String STR_NEW_LINE_TOKEN = "STRNEWLINE"; 21 | public static final String STR_TAB_TOKEN = "TABSYMBOL"; 22 | 23 | public static final Set INDENT_TOKENS = Set.of(NEW_LINE_TOKEN, INDENT_TOKEN, DEDENT_TOKEN); 24 | 25 | @NotNull 26 | public static List toLowerCasedTokens(String name) { 27 | return Arrays.stream(NameUtilCore.splitNameIntoWords(name)).map(String::toLowerCase).collect(Collectors.toList()); 28 | } 29 | 30 | public static boolean areSubtokensMatch(@Nullable String name, @NotNull Collection suggestions) { 31 | return name != null && suggestions.stream().anyMatch(suggestion -> name.length() < 2 ? 32 | suggestion.equals(name) : 33 | checkAnySubtokensMatch(suggestion, name)); 34 | } 35 | 36 | private static boolean checkAnySubtokensMatch(String first, String second) { 37 | @NotNull List firstTokens = toLowerCasedTokens(first); 38 | @NotNull List secondTokens = toLowerCasedTokens(second); 39 | Set intersection = new HashSet<>(firstTokens); // use the copy constructor 40 | intersection.retainAll(new HashSet<>(secondTokens)); 41 | return !intersection.isEmpty(); 42 | } 43 | 44 | public static boolean areSubtokensMatch(@Nullable String name, @Nullable String suggestion) { 45 | return name != null && suggestion != null && 46 | (name.length() < 2 ? suggestion.equals(name) : checkAnySubtokensMatch(suggestion, name)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /languages/common/src/main/kotlin/org/jetbrains/iren/inspections/variable/RenameVariableQuickFix.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.iren.inspections.variable 2 | 3 | import com.intellij.codeInsight.FileModificationService 4 | import com.intellij.codeInspection.LocalQuickFix 5 | import com.intellij.codeInspection.ProblemDescriptor 6 | import com.intellij.ide.DataManager 7 | import com.intellij.openapi.fileEditor.FileEditorManager 8 | import com.intellij.openapi.project.Project 9 | import com.intellij.psi.PsiElement 10 | import com.intellij.refactoring.RefactoringFactory 11 | import com.intellij.refactoring.rename.RenameHandlerRegistry 12 | import org.jetbrains.iren.utils.RenameBundle 13 | 14 | // Copied from org.jetbrains.kotlin.idea.quickfix.RenameIdentifierFix 15 | class RenameVariableQuickFix : LocalQuickFix { 16 | override fun getName() = RenameBundle.message("inspection.family.name") 17 | override fun getFamilyName() = name 18 | 19 | override fun startInWriteAction(): Boolean = false 20 | 21 | override fun applyFix(project: Project, descriptor: ProblemDescriptor) { 22 | val element = descriptor.psiElement ?: return 23 | val file = element.containingFile ?: return 24 | if (!FileModificationService.getInstance().prepareFileForWrite(file)) return 25 | val editorManager = FileEditorManager.getInstance(project) 26 | val fileEditor = editorManager.getSelectedEditor(file.virtualFile) ?: return renameWithoutEditor(element) 27 | val dataContext = DataManager.getInstance().getDataContext(fileEditor.component) 28 | val renameHandler = RenameHandlerRegistry.getInstance().getRenameHandler(dataContext) 29 | 30 | val editor = editorManager.selectedTextEditor 31 | if (editor != null) { 32 | renameHandler?.invoke(project, editor, file, dataContext) 33 | } else { 34 | val elementToRename = getElementToRename(element) ?: return 35 | renameHandler?.invoke(project, arrayOf(elementToRename), dataContext) 36 | } 37 | } 38 | 39 | private fun getElementToRename(element: PsiElement): PsiElement? = element.parent 40 | 41 | private fun renameWithoutEditor(element: PsiElement) { 42 | val elementToRename = getElementToRename(element) ?: return 43 | val factory = RefactoringFactory.getInstance(element.project) 44 | val renameRefactoring = factory.createRename(elementToRename, null, true, true) 45 | renameRefactoring.run() 46 | } 47 | } -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/actions/SuggestionListPopupStep.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.actions 2 | 3 | import com.intellij.openapi.editor.Editor 4 | import com.intellij.openapi.ui.popup.PopupStep 5 | import com.intellij.openapi.ui.popup.util.BaseListPopupStep 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.psi.PsiFile 8 | import com.intellij.psi.PsiNamedElement 9 | import com.intellij.refactoring.RefactoringFactory 10 | import org.jetbrains.astrid.inspections.Suggestion 11 | import org.jetbrains.astrid.stats.RenameMethodStatistics 12 | 13 | class SuggestionListPopupStep( 14 | aTitle: String, private val aValues: Suggestion, private var editor: Editor, private val psiFile: PsiFile 15 | ) : BaseListPopupStep>(aTitle, aValues.names.toMutableList()) { 16 | 17 | private var selectedMethodName: Pair = Pair("", 0.0) 18 | 19 | override fun onChosen(selectedValue: Pair, finalChoice: Boolean): PopupStep<*>? { 20 | selectedMethodName = selectedValue 21 | return super.onChosen(selectedValue, finalChoice) 22 | } 23 | 24 | private fun doRenameMethodRefactoring(selectedValue: Pair) { 25 | val elementAt = psiFile.findElementAt(editor.caretModel.offset) ?: return 26 | if (selectedMethodName.first == "Suppress on this method") { 27 | RenameMethodStatistics.ignoreCount(aValues.getScores(selectedValue.first)) 28 | return 29 | } 30 | val refactoringFactory = RefactoringFactory.getInstance(editor.project) 31 | val rename = refactoringFactory.createRename(findNamedElement(elementAt), selectedValue.first) 32 | val usages = rename.findUsages() 33 | RenameMethodStatistics.applyCount(selectedValue.second) 34 | rename.doRefactoring(usages) 35 | /* StatsSender(FilePathProvider(), 36 | RequestService()).sendStatsData(LogEvent(RenameMethodStatistics.getInstance().state).toString())*/ 37 | } 38 | 39 | private fun findNamedElement(element: PsiElement): PsiElement { 40 | when (element) { 41 | is PsiNamedElement -> return element 42 | else -> return findNamedElement(element.parent) 43 | } 44 | } 45 | 46 | override fun getFinalRunnable(): Runnable? { 47 | return Runnable { doRenameMethodRefactoring(selectedMethodName) } 48 | } 49 | 50 | override fun getTextFor(value: Pair): String { 51 | return value.first 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /astrid/src/org/jetbrains/astrid/extractors/common/Common.kt: -------------------------------------------------------------------------------- 1 | package org.jetbrains.astrid.extractors.common 2 | 3 | import com.github.javaparser.ast.Node 4 | import com.github.javaparser.ast.UserDataKey 5 | import org.jetbrains.astrid.extractors.features.Property 6 | 7 | object Common { 8 | val PROPERTY_KEY: UserDataKey = object : UserDataKey() { 9 | } 10 | 11 | val CHILD_ID: UserDataKey = object : UserDataKey() { 12 | } 13 | const val EMPTY_STRING = "" 14 | private const val METHOD_DECLARATION = "MethodDeclaration" 15 | private const val NAME_EXPR = "NameExpr" 16 | const val BLANK = "BLANK" 17 | const val MAX_LABEL_LENGTH = 50 18 | const val METHOD_NAME = "METHOD_NAME" 19 | const val INTERNAL_SEPARATOR = "|" 20 | 21 | fun normalizeName(original: String, defaultString: String): String { 22 | val normalizedString = original.toLowerCase().replace("\\\\n".toRegex(), "") 23 | .replace("//s+".toRegex(), "") 24 | .replace("[\"',]".toRegex(), "") 25 | .replace("\\P{Print}".toRegex(), "") 26 | val stripped = normalizedString.replace("[^A-Za-z]".toRegex(), "") 27 | return when { 28 | stripped.isEmpty() -> { 29 | val carefulStripped = normalizedString.replace(" ".toRegex(), "_") 30 | if (carefulStripped.isEmpty()) { 31 | defaultString 32 | } else { 33 | carefulStripped 34 | } 35 | } 36 | else -> stripped 37 | } 38 | } 39 | 40 | fun isMethod(node: Node, type: String?): Boolean { 41 | val parentProperty = node.parentNode.getUserData(PROPERTY_KEY) ?: return false 42 | val parentType = parentProperty.type 43 | return NAME_EXPR.equals(type) && METHOD_DECLARATION.equals(parentType) 44 | } 45 | 46 | fun splitToSubtokens(str: String): ArrayList { 47 | val s = str.trim { it <= ' ' } 48 | val strings = ArrayList() 49 | s.split("(?<=[a-z])(?=[A-Z])|_|[0-9]|(?<=[A-Z])(?=[A-Z][a-z])|\\s+".toRegex()).dropLastWhile { it.isEmpty() } 50 | .toTypedArray().forEach { 51 | if (it.isNotEmpty()) { 52 | val normalizedName = normalizeName(it, EMPTY_STRING) 53 | if (normalizedName.isNotEmpty()) { 54 | strings.add(normalizedName) 55 | } 56 | } 57 | } 58 | return strings 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /languages/kotlin/src/org/jetbrains/iren/rename/IRenKotlinMemberInplaceRenameHandler.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | 3 | package org.jetbrains.iren.rename 4 | 5 | import com.intellij.openapi.editor.Editor 6 | import com.intellij.psi.PsiDocumentManager 7 | import com.intellij.psi.PsiElement 8 | import com.intellij.psi.PsiFile 9 | import com.intellij.psi.PsiNameIdentifierOwner 10 | import com.intellij.refactoring.rename.inplace.MemberInplaceRenameHandler 11 | import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer 12 | import org.jetbrains.kotlin.idea.refactoring.rename.KotlinVariableInplaceRenameHandler 13 | import org.jetbrains.kotlin.psi.KtPrimaryConstructor 14 | 15 | class IRenKotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() { 16 | private fun PsiElement.substitute(): PsiElement { 17 | if (this is KtPrimaryConstructor) return getContainingClassOrObject() 18 | return this 19 | } 20 | 21 | override fun createMemberRenamer( 22 | element: PsiElement, 23 | elementToRename: PsiNameIdentifierOwner, 24 | editor: Editor, 25 | ): MemberInplaceRenamer { 26 | val currentElementToRename = elementToRename.substitute() as PsiNameIdentifierOwner 27 | val nameIdentifier = currentElementToRename.nameIdentifier 28 | 29 | // Move caret if constructor range doesn't intersect with the one of the containing class 30 | val offset = editor.caretModel.offset 31 | val editorPsiFile = PsiDocumentManager.getInstance(element.project).getPsiFile(editor.document) 32 | if (nameIdentifier != null && editorPsiFile == elementToRename.containingFile && elementToRename is KtPrimaryConstructor && offset !in nameIdentifier.textRange && offset in elementToRename.textRange) { 33 | editor.caretModel.moveToOffset(nameIdentifier.textOffset) 34 | } 35 | 36 | val currentName = nameIdentifier?.text ?: "" 37 | return IRenKotlinMemeberInplaceRenamer(currentElementToRename, element, editor, currentName, currentName) 38 | } 39 | 40 | override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean { 41 | if (!editor.settings.isVariableInplaceRenameEnabled) return false 42 | val currentElement = element?.substitute() as? PsiNameIdentifierOwner ?: return false 43 | return currentElement.nameIdentifier != null && !KotlinVariableInplaceRenameHandler.isInplaceRenameAvailable( 44 | currentElement) 45 | } 46 | } 47 | --------------------------------------------------------------------------------