├── .gitignore
├── CHANGELOG.md
├── DeveloperGuide.md
├── LICENSE
├── README.md
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── images
├── authenticate.png
├── code_context.png
├── confirm.png
├── install_plugin.png
├── settings.png
├── statusbar.png
├── tool_window.png
└── view_total.png
├── settings.gradle
└── src
├── main
├── java
│ └── ai
│ │ └── deepcode
│ │ └── jbplugin
│ │ ├── DeepCodeConsoleToolWindowFactory.java
│ │ ├── DeepCodeIcons.java
│ │ ├── DeepCodeNotifications.java
│ │ ├── DeepCodeStartupActivity.java
│ │ ├── DeepCodeStatusBarWidgetProvider.java
│ │ ├── DeepCodeToolWindowFactory.java
│ │ ├── actions
│ │ ├── AnalyseCurrentFileAction.java
│ │ ├── AnalyseProjectAction.java
│ │ ├── DeepCodeIntentionAction.java
│ │ ├── InvalidateCachesAction.java
│ │ ├── SeeResultsInBrowserAction.java
│ │ └── ShowSettingsAction.java
│ │ ├── annotators
│ │ └── DeepCodeExternalAnnotator.java
│ │ ├── core
│ │ ├── AnalysisData.java
│ │ ├── BulkMode.java
│ │ ├── DCLogger.java
│ │ ├── DeepCodeIgnoreInfoHolder.java
│ │ ├── DeepCodeParams.java
│ │ ├── DeepCodeUtils.java
│ │ ├── HashContentUtils.java
│ │ ├── LoginUtils.java
│ │ ├── MyBulkFileListener.java
│ │ ├── MyProjectManagerListener.java
│ │ ├── PDU.java
│ │ └── RunUtils.java
│ │ └── ui
│ │ ├── AllTodosTreeBuilder.java
│ │ ├── AllTodosTreeStructure.java
│ │ ├── ChangeListTodosPanel.java
│ │ ├── ChangeListTodosTreeBuilder.java
│ │ ├── ChangeListTodosTreeStructure.java
│ │ ├── CurrentFileTodosPanel.java
│ │ ├── CurrentFileTodosTreeBuilder.java
│ │ ├── CurrentFileTodosTreeStructure.java
│ │ ├── CustomChangelistTodoTreeStructure.java
│ │ ├── DeepCodeDirAndModuleComparator.java
│ │ ├── FileTree.java
│ │ ├── HighlightedRegionProvider.java
│ │ ├── MultiLineTodoLocalityDetector.java
│ │ ├── MultiLineTodoRenderer.java
│ │ ├── ScopeBasedTodosPanel.java
│ │ ├── ScopeBasedTodosTreeBuilder.java
│ │ ├── ScopeBasedTodosTreeStructure.java
│ │ ├── SetTodoFilterAction.java
│ │ ├── SmartTodoItemPointer.java
│ │ ├── SmartTodoItemPointerComparator.java
│ │ ├── ToDoSettings.java
│ │ ├── ToDoSummary.java
│ │ ├── TodoCompositeRenderer.java
│ │ ├── TodoNodeVisitor.java
│ │ ├── TodoPanel.java
│ │ ├── TodoPanelSettings.java
│ │ ├── TodoTreeBuilder.java
│ │ ├── TodoTreeBuilderFactory.java
│ │ ├── TodoTreeStructure.java
│ │ ├── config
│ │ ├── DeepCodeConfigEntry.java
│ │ ├── DeepCodeConfigForm.form
│ │ └── DeepCodeConfigForm.java
│ │ ├── configurable
│ │ ├── FilterDialog.java
│ │ ├── FiltersTableModel.java
│ │ ├── PatternDialog.java
│ │ ├── PatternsTableModel.java
│ │ ├── TodoConfigurable.java
│ │ └── TodoPatternTableCellRenderer.java
│ │ ├── myTodoView.java
│ │ ├── nodes
│ │ ├── BaseToDoNode.java
│ │ ├── MarkerItemImpl.java
│ │ ├── ModuleToDoNode.java
│ │ ├── SingleFileToDoNode.java
│ │ ├── SuggestionNode.java
│ │ ├── SummaryNode.java
│ │ ├── ToDoRootNode.java
│ │ ├── TodoDirNode.java
│ │ ├── TodoFileNode.java
│ │ ├── TodoItemNode.java
│ │ └── TodoTreeHelper.java
│ │ └── utils
│ │ └── DeepCodeUIUtils.java
└── resources
│ ├── META-INF
│ ├── plugin.xml
│ ├── pluginIcon.svg
│ └── pluginIcon_dark.svg
│ └── icons
│ ├── DeepCodeLogo.svg
│ └── DeepCodeLogo_dark.svg
└── test
├── .dcignore
├── java
└── ai
│ └── deepcode
│ └── jbplugin
│ ├── MyBasePlatformTestCase.java
│ ├── MyPlatformTestCase.java
│ ├── TestAnnotatorForCPP.java
│ ├── TestAnnotatorForJava.java
│ ├── TestAnnotatorForJavaScript.java
│ ├── TestLoginProcess.java
│ └── core
│ └── TestInnerCaches.java
├── resources
└── log4j.properties
└── testData
├── AnnotatorTest.cpp
├── AnnotatorTest.java
├── AnnotatorTest.js
└── AnnotatorTest_ValidCPP.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
25 | # Gradle related
26 | .gradle
27 | /build
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Latest update 🗞️ (start here first 👇)
2 |
3 | - Dear developers 👋, thank you for your support and feedback!
4 | - With the DeepCode acquisition by [Snyk](https://snyk.io) we will be starting a new journey, a better one, towards helping you write robust and secure application code. The DeepCode plugin will be replaced by [Snyk's JetBrains plugin](https://plugins.jetbrains.com/plugin/10972-snyk-vulnerability-scanner) with includes DeepCode's functionality and more.
5 | - If you want to read more about it, here is the [official announcement](https://www.deepcode.ai/). We will start sunsetting the official DeepCode API in August, 2021. In the mean time we will do one last update of the JetBrains plugin with this message to ensure you are up to date.
6 | - We invite you to join us and start using the new Snyk plugin! We are excited and looking forward to helping you build stable and secure applications 🚀
7 |
8 | ## [1.2.14] - 2021-06
9 | 1.2.14 - fix deprecation deadline and links at plugin replacement announcement;
10 |
11 | ## [1.2.13] - 2021-05
12 | 1.2.13 - 2021.1 compatibility and plugin replacement announcement;
13 |
14 | ## [1.2.12] - 2019-10-05
15 | 1.2.12 - Upcoming 2020.3 compatibility and bug fixes;
16 |
17 | ## [1.2.11] - 2019-09-16
18 | 1.2.11 - Fix bug with IndexOutOfBound Exception for wrongly positioned suggestion/marker;
19 | - Fix bug with multiple analyses processes on project opening.
20 |
21 | ## [1.2.10] - 2019-09-14
22 | - Update modes added:
23 | * Interactive (on any source file change);
24 | * On Save (when source file saved on disk);
25 | * On Demand (only if explicitly invoked).
26 |
27 | ## [1.2.9] - 2019-09-08
28 | - Status Bar widget with summary info added;
29 | - .dcignore parsing fixed.
30 |
31 | ## [1.2.8] - 2019-09-03
32 | - Improvements:
33 | * markers for each suggestion are shown in the List and highlighted in Preview
34 | * more informative Progress indicator messages
35 |
36 | - Bug fixes:
37 | * fix missing re-analyse in some corner cases
38 | * fix missing/"too many" login/consent requests
39 | * fix ignoring action (quick fix) been broken in some cases
40 | * fix logger to not pollute IntelliJ general log (see readme.md how to collect log information)
41 |
42 | ## [1.2.0] - 2019-06-20
43 | - Moving common logic into java-client
44 |
45 | ## [1.1.2] - 2019-06-19
46 | - Fix bug parsing of trailing "**" in .dcignore
47 |
48 | ## [1.1.1] - 2019-06-16
49 | - Speedup of large projects analysis and suggestions highlighting; various internal fixes and refactoring
50 |
51 | ## [1.1.0] - 2019-06-01
52 | - Speedup of large projects analysis and suggestions highlighting
53 | - Various internal fixes and refactoring
54 |
55 | ## [1.0.3] - 2019-05-28
56 | - Fix multiple rescan requests and add ignoring events while rescan running
57 | - Fix cache invalidation in Bulk mode for files update
58 | - CheckBundle after uploadFiles to ensure no missingFiles left
59 |
60 | ## [1.0.2] - 2019-05-25
61 | - Bugfixing and better support for refactoring
62 |
63 | ## [1.0.1] - 2019-05-22
64 | - Updated Java-client and added support for Java 8, required for Android Studio
65 |
66 | ## [1.0.0] - 2019-05-21
67 | ### Added
68 | - First public beta release
69 |
--------------------------------------------------------------------------------
/DeveloperGuide.md:
--------------------------------------------------------------------------------
1 | # Latest update 🗞️ (start here first 👇)
2 |
3 | - Dear developers 👋, thank you for your support and feedback!
4 | - With the DeepCode acquisition by [Snyk](https://snyk.io) we will be starting a new journey, a better one, towards helping you write robust and secure application code. The DeepCode plugin will be replaced by [Snyk's JetBrains plugin](https://plugins.jetbrains.com/plugin/10972-snyk-vulnerability-scanner) with includes DeepCode's functionality and more.
5 | - If you want to read more about it, here is the [official announcement](https://www.deepcode.ai/). We will start sunsetting the official DeepCode API in August, 2021. In the mean time we will do one last update of the JetBrains plugin with this message to ensure you are up to date.
6 | - We invite you to join us and start using the new Snyk plugin! We are excited and looking forward to helping you build stable and secure applications 🚀
7 |
8 | ### Build
9 |
10 | - Clone this repository: `git clone https://github.com/DeepCodeAI/jetbrains-plugin.git`
11 | - Switch to the dev branch: `git checkout origin/dev`
12 | - Install Java 11 or higher (https://adoptopenjdk.net/) and/or make sure JAVA_HOME is pointing to Java 11 installation path of the JDK;
13 | - Check if java is correctly installed (and your java version) with `java -version` command;
14 | - Place `java-client-{X.X.X}-all.jar` into `..\libs` dir (see [java-client](https://github.com/DeepCodeAI/java-client) repository for instruction how to build it);
15 |
16 | **Important note: Starting version 1.2.0 use of java-client version 2.0 or above required!**
17 |
18 | See below correspondent `java-client` version requirements:
19 |
20 | | jetbrains-plugin | java-client |
21 | |------------------|-------------|
22 | | 1.2.0 | 2.0.0 |
23 | | 1.2.2 | 2.0.4 |
24 | | 1.2.3 | 2.0.5 |
25 | | 1.2.4 | 2.0.6 |
26 | | 1.2.5 | 2.0.8 |
27 | | 1.2.7 | 2.0.12 |
28 | | 1.2.8 | 2.0.14 |
29 | | 1.2.10 | 2.0.16 |
30 | | 1.2.11 | 2.0.17 |
31 | | 1.2.12 | 2.0.18 |
32 | | 1.2.13 | 2.0.18 |
33 | | 1.2.14 | 2.0.18 |
34 |
35 | **Important note: For backward compatibility build MUST be run against Intellij Idea 2019.2 instance!**
36 | - Run `source gradlew buildPlugin`
37 | - Look for resulting ZIP file at `..\build\distributions`
38 |
39 | ### Run tests
40 |
41 | - environment variable with __already logged__ Token need to be declared:
42 |
43 | `DEEPCODE_API_KEY` - logged at https://www.deepcode.ai Token
44 |
45 | - Run gradle test task: `source gradlew test --stacktrace --scan`
46 |
47 | ### See log output
48 |
49 | To see plugin's log output in idea.log (related to testing Idea instance), please enable Debug level logging
50 | (in testing Idea instance) by open `Help -> Diagnostic Tools -> Debug Log Settings...` and type there `DeepCode` (case-sensitive!).
51 |
52 | ### Useful links
53 | - IntelliJ Platform SDK [documentation](https://www.jetbrains.org/intellij/sdk/docs/intro/welcome.html)
54 | - JetBrains Marketplace [documentation](https://plugins.jetbrains.com/docs/marketplace/about-marketplace.html)
55 | - [Community SDK Forum](https://intellij-support.jetbrains.com/hc/en-us/community/topics/200366979-IntelliJ-IDEA-Open-API-and-Plugin-Development)
56 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 DeepCodeAI
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 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | import org.jetbrains.intellij.tasks.RunIdeTask
2 |
3 | plugins {
4 | id 'java'
5 | id 'org.jetbrains.intellij' version '0.4.19'
6 | }
7 |
8 | //group 'org.example'
9 |
10 | version '1.2.14'
11 | sourceCompatibility = 1.8
12 |
13 | repositories {
14 | mavenCentral()
15 | }
16 |
17 | dependencies {
18 | compile fileTree("$rootProject.projectDir/libs")
19 |
20 | testCompile group: 'junit', name: 'junit', version: '4.12'
21 | }
22 |
23 | // See https://github.com/JetBrains/gradle-intellij-plugin/
24 | intellij {
25 | pluginName "DeepCode-$project.name"
26 | version '2019.2'
27 | // plugins += 'java'
28 | // plugins += 'PsiViewer:192-SNAPSHOT'
29 |
30 | }
31 | patchPluginXml {
32 | sinceBuild 192
33 | untilBuild 212
34 |
35 | changeNotes """
36 | Dear developers, thank you for your support and feedback!
37 | With the DeepCode acquisition by Snyk we will be starting a new journey, a better one, towards helping you write robust and secure application code. The DeepCode plugin will be replaced by Snyk's JetBrains plugin with includes DeepCode's functionality and more.
38 | If you want to read more about it, here is the official announcement. We will start sunsetting the official DeepCode API in August, 2021. In the mean time we will do one last update of the JetBrains plugin with this message to ensure you are up to date.
39 | We invite you to join us and start using the new Snyk plugin! We are excited and looking forward to helping you build stable and secure applications 🚀
40 |
41 | 1.2.14 - fix deprecation deadline and links at plugin replacement announcement
42 | 1.2.13 - 2021.1 compatibility and plugin replacement announcement
43 | 1.2.12 - Upcoming 2020.3 compatibility and bug fixes
44 | 1.2.11 - Fix bugs and performance optimisation
45 | 1.2.10 - Update modes added:
46 | * Interactive (on any source file change);
47 | * On Save (when source file saved on disk);
48 | * On Demand (only if explicitly invoked).
49 | 1.2.9 - Status Bar widget with summary info added; .dcignore parsing fixed.
50 | 1.2.8 - Improvements:
51 | * markers for each suggestion are shown in the List and highlighted in Preview
52 | * more informative Progress indicator messages
53 | - Bug fixes:
54 | * fix missing re-analyse in some corner cases
55 | * fix missing/"too many" login/consent requests
56 | * fix ignoring action (quick fix) been broken in some cases
57 | * fix logger to not pollute IntelliJ general log (see readme.md)
58 | 1.1.2 - Fix bug parsing of trailing "**" in .dcignore
59 | 1.1.1 - Fix errors symbolic presentation; fix exception when analysis results not available.
60 | 1.1.0 - Speedup of large projects analysis and suggestions highlighting; various internal fixes and refactoring
61 | 1.0.4 - Bugfixing internals
62 | 1.0.3 - Bugfixing and optimization of bulk file changes
63 | 1.0.2 - Bugfixing and better support for refactoring
64 | 1.0.1 - Updated Java-client and added support for Java 8, required for Android Studio
65 | 1.0.0 - First public beta release.
66 | """
67 | }
68 |
69 | runIde {
70 | jvmArgs '-Xmx2G'
71 | }
72 |
73 | task runIC_201(type: RunIdeTask){
74 | jvmArgs '-Xmx2G'
75 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-C\\ch-1\\201.7846.76'
76 | }
77 |
78 | task runIC_202(type: RunIdeTask){
79 | jvmArgs '-Xmx2G'
80 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-C\\ch-0\\202.7319.50'
81 | }
82 |
83 | task runIC_203(type: RunIdeTask){
84 | jvmArgs '-Xmx2G'
85 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-C\\ch-3\\203.5600.34'
86 | }
87 |
88 | task runIC_211(type: RunIdeTask){
89 | jvmArgs '-Xmx2G'
90 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-C\\ch-3\\211.6693.111'
91 | }
92 |
93 | task runIC_193(type: RunIdeTask){
94 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-C\\ch-0\\193.6911.18'
95 | }
96 |
97 | task runIU_192(type: RunIdeTask){
98 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\IDEA-U\\ch-1\\192.7142.36'
99 | }
100 |
101 | task runPC_193(type: RunIdeTask){
102 | jvmArgs '-Xmx2G'
103 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-C\\ch-0\\193.5233.109'
104 | }
105 |
106 | task runCLion_193(type: RunIdeTask){
107 | jvmArgs '-Xmx2G'
108 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\CLion\\ch-0\\193.6494.38'
109 | }
110 |
111 | task runCLion_192(type: RunIdeTask){
112 | jvmArgs '-Xmx2G'
113 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\CLion\\ch-2\\192.7142.39'
114 | }
115 |
116 | task run_WS_201(type: RunIdeTask){
117 | jvmArgs '-Xmx2G'
118 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\WebStorm\\ch-0\\201.6668.106'
119 | }
120 |
121 | task run_WS_192(type: RunIdeTask){
122 | jvmArgs '-Xmx2G'
123 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\WebStorm\\ch-1\\192.7142.35'
124 | }
125 |
126 | task run_PC_201(type: RunIdeTask){
127 | jvmArgs '-Xmx2G'
128 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-C\\ch-0\\201.7223.92'
129 | }
130 |
131 | task run_AS_40(type: RunIdeTask){
132 | jvmArgs '-Xmx2G'
133 | jbrVersion '8u202b1483.24'
134 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\AndroidStudio\\ch-0\\193.6453388'
135 | }
136 |
137 | task run_AS_36(type: RunIdeTask){
138 | jvmArgs '-Xmx2G'
139 | jbrVersion '8u202b1483.24'
140 | ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\AndroidStudio\\ch-1\\192.6392135'
141 | }
142 |
143 | tasks.withType(RunIdeTask).forEach {task -> task.dependsOn(prepareSandbox)}
144 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Mar 20 09:57:06 MSK 2020
2 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
3 | distributionBase=GRADLE_USER_HOME
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS='"-Xmx64m"'
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS="-Xmx64m"
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/images/authenticate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/images/authenticate.png
--------------------------------------------------------------------------------
/images/code_context.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/images/code_context.png
--------------------------------------------------------------------------------
/images/confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/images/confirm.png
--------------------------------------------------------------------------------
/images/install_plugin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/images/install_plugin.png
--------------------------------------------------------------------------------
/images/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/images/settings.png
--------------------------------------------------------------------------------
/images/statusbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/images/statusbar.png
--------------------------------------------------------------------------------
/images/tool_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/images/tool_window.png
--------------------------------------------------------------------------------
/images/view_total.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeepCodeAI/jetbrains-plugin/e228308541c5d0bfb13156f219095859af33f683/images/view_total.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'jetbrains-plugin'
2 |
3 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/DeepCodeConsoleToolWindowFactory.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin;
2 |
3 | import ai.deepcode.javaclient.core.MyTextRange;
4 | import ai.deepcode.jbplugin.core.AnalysisData;
5 | import ai.deepcode.jbplugin.core.DeepCodeUtils;
6 | import ai.deepcode.javaclient.core.SuggestionForFile;
7 | import com.intellij.execution.impl.ConsoleViewUtil;
8 | import com.intellij.openapi.Disposable;
9 | import com.intellij.openapi.editor.Document;
10 | import com.intellij.openapi.editor.EditorFactory;
11 | import com.intellij.openapi.editor.ex.EditorEx;
12 | import com.intellij.openapi.project.Project;
13 | import com.intellij.openapi.ui.SimpleToolWindowPanel;
14 | import com.intellij.openapi.util.Disposer;
15 | import com.intellij.openapi.util.TextRange;
16 | import com.intellij.openapi.wm.ToolWindow;
17 | import com.intellij.openapi.wm.ToolWindowFactory;
18 | import com.intellij.psi.PsiFile;
19 | import com.intellij.ui.content.Content;
20 | import com.intellij.ui.content.ContentFactory;
21 | import com.intellij.ui.content.ContentManager;
22 | import com.intellij.ui.scale.JBUIScale;
23 | import com.intellij.util.ui.AbstractLayoutManager;
24 | import org.jetbrains.annotations.NotNull;
25 | import org.slf4j.Logger;
26 | import org.slf4j.LoggerFactory;
27 |
28 | import javax.swing.*;
29 | import java.awt.*;
30 | import java.util.List;
31 |
32 | public class DeepCodeConsoleToolWindowFactory implements ToolWindowFactory, Disposable {
33 | private static final Logger LOG = LoggerFactory.getLogger("DeepCodeToolWindowFactory");
34 | private static PsiFile myCurrentFile;
35 |
36 | @Override
37 | public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
38 | final ContentManager contentManager = toolWindow.getContentManager();
39 | final ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
40 |
41 | // Current File panel
42 | JPanel editorPanel =
43 | new JPanel(
44 | new AbstractLayoutManager() {
45 | private int getOffset() {
46 | return JBUIScale.scale(4);
47 | }
48 |
49 | @Override
50 | public Dimension preferredLayoutSize(Container parent) {
51 | Dimension size = parent.getComponent(0).getPreferredSize();
52 | return new Dimension(size.width + getOffset(), size.height);
53 | }
54 |
55 | @Override
56 | public void layoutContainer(Container parent) {
57 | int offset = getOffset();
58 | parent
59 | .getComponent(0)
60 | .setBounds(offset, 0, parent.getWidth() - offset, parent.getHeight());
61 | }
62 | }) {
63 | };
64 |
65 | editorPanel.add(CurrentFileEditor.get(project).getComponent());
66 |
67 | // todo CurrentFilePanel
68 | final SimpleToolWindowPanel currentFilePanel = new SimpleToolWindowPanel(true);
69 | currentFilePanel.setContent(editorPanel);
70 | Content currentFileContent =
71 | contentFactory.createContent(currentFilePanel, "Current File", false);
72 | contentManager.addContent(currentFileContent);
73 |
74 | // Update CurrentFile Panel if file was edited
75 | /*
76 | PsiManager.getInstance(project)
77 | .addPsiTreeChangeListener(
78 | new PsiTreeChangeAdapter() {
79 | @Override
80 | public void childrenChanged(@NotNull PsiTreeChangeEvent event) {
81 | PsiFile file = event.getFile();
82 | if (file != null && file.equals(myCurrentFile)) {
83 | DeepCodeUtils.getInstance().asyncUpdateCurrentFilePanel(file);
84 | }
85 | }
86 | });
87 | */
88 |
89 | }
90 |
91 | /**
92 | * Perform additional initialization routine here.
93 | *
94 | * @param toolWindow
95 | */
96 | @Override
97 | public void init(@NotNull ToolWindow toolWindow) {}
98 |
99 | /** Usually not invoked directly, see class javadoc. */
100 | @Override
101 | public void dispose() {}
102 |
103 | // ------------------------------------------------------------------------------
104 |
105 | private static class CurrentFileEditor {
106 |
107 | private static EditorEx myEditor;
108 |
109 | public static EditorEx get(@NotNull Project project) {
110 | if (myEditor == null) {
111 | myEditor = ConsoleViewUtil.setupConsoleEditor(project, false, false);
112 | Disposer.register(
113 | project,
114 | () -> {
115 | EditorFactory.getInstance().releaseEditor(myEditor);
116 | });
117 | }
118 | return myEditor;
119 | }
120 | }
121 |
122 | public static void updateCurrentFilePanel(@NotNull PsiFile psiFile) {
123 | myCurrentFile = psiFile;
124 | Project project = psiFile.getProject();
125 | cleanMessages(project);
126 | if (!DeepCodeUtils.getInstance().isSupportedFileFormat(psiFile)) return;
127 | List suggestions = AnalysisData.getInstance().getAnalysis(psiFile);
128 | for (SuggestionForFile suggestion : suggestions) {
129 | printMessage(project, suggestion.getMessage());
130 | for (MyTextRange range : suggestion.getRanges()) {
131 | printMessage(project, " " + range);
132 | }
133 | }
134 | }
135 |
136 | private static void printMessage(Project project, String message) {
137 | EditorEx editor = CurrentFileEditor.get(project);
138 | if (editor.isDisposed()) {
139 | return;
140 | }
141 | Document document = editor.getDocument();
142 | if (document.getTextLength() >= 0) {
143 | document.insertString(document.getTextLength(), message + "\n");
144 | }
145 | }
146 |
147 | private static void cleanMessages(Project project) {
148 | EditorEx editor = CurrentFileEditor.get(project);
149 | if (editor.isDisposed()) {
150 | return;
151 | }
152 | Document document = editor.getDocument();
153 | if (document.getTextLength() >= 0) {
154 | document.setText("");
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/DeepCodeIcons.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin;
2 |
3 | import com.intellij.openapi.util.IconLoader;
4 |
5 | import javax.swing.*;
6 |
7 | public class DeepCodeIcons {
8 | public static final Icon LOGO = IconLoader.getIcon("/icons/DeepCodeLogo.svg");
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/DeepCodeStartupActivity.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin;
2 |
3 | import ai.deepcode.jbplugin.core.*;
4 | import com.intellij.openapi.application.ApplicationManager;
5 | import com.intellij.openapi.project.Project;
6 | import com.intellij.openapi.project.ProjectManager;
7 | import com.intellij.openapi.startup.StartupActivity;
8 | import com.intellij.openapi.vfs.VirtualFileManager;
9 | import com.intellij.util.messages.MessageBusConnection;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | public class DeepCodeStartupActivity implements StartupActivity {
13 |
14 | private static boolean listenersActivated = false;
15 |
16 | @Override
17 | public void runActivity(@NotNull Project project) {
18 | if (DeepCodeParams.getInstance().isPluginDeprecated()) {
19 | DeepCodeNotifications.showPluginDeprecationAnnouncement(project);
20 | // Unfortunately, we can't disable plugin here programmatically: https://intellij-support.jetbrains.com/hc/en-us/community/posts/360009820960/comments/360002292200
21 | // as workaround will return `isLogged() = false` to stop requesting disabled API
22 | }
23 |
24 | if (!listenersActivated) {
25 | final MessageBusConnection messageBusConnection =
26 | ApplicationManager.getApplication().getMessageBus().connect();
27 | messageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, new MyBulkFileListener());
28 | messageBusConnection.subscribe(ProjectManager.TOPIC, new MyProjectManagerListener(project));
29 | listenersActivated = true;
30 | }
31 | if (DeepCodeParams.getInstance().isFirstStart()) {
32 | DeepCodeNotifications.showTutorialRequest(project);
33 | }
34 | if (DeepCodeParams.getInstance().needToShowReplacementMessage()) {
35 | DeepCodeNotifications.showPluginReplacementAnnouncement(project);
36 | }
37 | // Keep commented - for DEBUG ONLY !!!!!!!!!!!!!!!!!
38 | //PropertiesComponent.getInstance(project).setValue("consentGiven", false);
39 |
40 | AnalysisData.getInstance().resetCachesAndTasks(project);
41 | // Initial logging if needed.
42 | if (LoginUtils.getInstance().isLogged(project, true)) {
43 | RunUtils.getInstance().asyncAnalyseProjectAndUpdatePanel(project);
44 | }
45 | // Keep commented - for DEBUG ONLY !!!!!!!!!!!!!!!!!
46 | //throw new NullPointerException();
47 |
48 | /*
49 | // Update CurrentFile Panel if file Tab was changed in Editor
50 | MessageBusConnection connection = project.getMessageBus().connect();
51 | connection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, new MyEditorManagerListener());
52 | */
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/DeepCodeStatusBarWidgetProvider.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin;
2 |
3 | import ai.deepcode.jbplugin.ui.utils.DeepCodeUIUtils;
4 | import com.intellij.openapi.project.Project;
5 | import com.intellij.openapi.wm.*;
6 | import com.intellij.util.Consumer;
7 | import org.jetbrains.annotations.NotNull;
8 | import org.jetbrains.annotations.Nullable;
9 |
10 | import javax.swing.*;
11 | import java.awt.event.MouseEvent;
12 |
13 | public class DeepCodeStatusBarWidgetProvider implements StatusBarWidgetProvider {
14 |
15 | public static void updateWidget(@NotNull Project project) {
16 | StatusBar statusBar = WindowManager.getInstance().getStatusBar(project);
17 | if (statusBar != null) {
18 | StatusBarWidget widget = statusBar.getWidget("DeepCodeAnalysisStatus");
19 | if (widget instanceof DeepCodeStatusBarWidget)
20 | ((DeepCodeStatusBarWidget) widget).update();
21 | }
22 | }
23 |
24 | @Nullable
25 | @Override
26 | public StatusBarWidget getWidget(@NotNull Project project) {
27 | return new DeepCodeStatusBarWidget(project);
28 | }
29 |
30 | @NotNull
31 | @Override
32 | public String getAnchor() {
33 | return StatusBar.Anchors.before(StatusBar.StandardWidgets.POSITION_PANEL);
34 | }
35 |
36 | public static class DeepCodeStatusBarWidget
37 | implements StatusBarWidget, StatusBarWidget.IconPresentation {
38 | private final Project project;
39 | private StatusBar myStatusBar;
40 | private Icon myCurrentIcon = DeepCodeUIUtils.EMPTY_EWI_ICON;
41 | private String myToolTipText = "DeepCode";
42 |
43 | public DeepCodeStatusBarWidget(@NotNull Project project) {
44 | this.project = project;
45 | update();
46 | }
47 |
48 | private void update() {
49 | myCurrentIcon = DeepCodeUIUtils.getSummaryIcon(project);
50 | myToolTipText = DeepCodeUIUtils.addErrWarnInfoCounts(project, "DeepCode", true, null);
51 | if (myStatusBar != null) myStatusBar.updateWidget(ID());
52 | }
53 |
54 | @NotNull
55 | @Override
56 | public String ID() {
57 | return "DeepCodeAnalysisStatus";
58 | }
59 |
60 | @Nullable
61 | @Override
62 | public WidgetPresentation getPresentation(@NotNull StatusBarWidget.PlatformType type) {
63 | return this;
64 | }
65 |
66 | @Override
67 | public void install(@NotNull StatusBar statusBar) {
68 | myStatusBar = statusBar;
69 | }
70 |
71 | @Override
72 | public void dispose() {}
73 |
74 | @Nullable
75 | @Override
76 | public Icon getIcon() {
77 | return myCurrentIcon;
78 | }
79 |
80 | @Nullable
81 | @Override
82 | public String getTooltipText() {
83 | return myToolTipText;
84 | }
85 |
86 | @Nullable
87 | @Override
88 | public Consumer getClickConsumer() {
89 | return mouseEvent -> {
90 | ToolWindow myToolWindow = ToolWindowManager.getInstance(project).getToolWindow("DeepCode");
91 | myToolWindow.show(null);
92 | };
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/DeepCodeToolWindowFactory.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin;
2 |
3 | import ai.deepcode.jbplugin.ui.myTodoView;
4 | import ai.deepcode.jbplugin.ui.utils.DeepCodeUIUtils;
5 | import com.intellij.openapi.components.ServiceManager;
6 | import com.intellij.openapi.project.DumbService;
7 | import com.intellij.openapi.project.Project;
8 | import com.intellij.openapi.wm.ToolWindow;
9 | import com.intellij.openapi.wm.ToolWindowFactory;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | public class DeepCodeToolWindowFactory implements ToolWindowFactory {
13 | @Override
14 | public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
15 | DumbService.getInstance(project)
16 | .runWhenSmart(
17 | () -> ServiceManager.getService(project, myTodoView.class).initToolWindow(toolWindow));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/actions/AnalyseCurrentFileAction.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin.actions;
2 |
3 | import ai.deepcode.jbplugin.DeepCodeNotifications;
4 | import ai.deepcode.jbplugin.core.LoginUtils;
5 | import ai.deepcode.jbplugin.core.RunUtils;
6 | import ai.deepcode.jbplugin.ui.myTodoView;
7 | import ai.deepcode.jbplugin.core.DeepCodeUtils;
8 | import com.intellij.openapi.actionSystem.AnAction;
9 | import com.intellij.openapi.actionSystem.AnActionEvent;
10 | import com.intellij.openapi.actionSystem.CommonDataKeys;
11 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
12 | import com.intellij.openapi.components.ServiceManager;
13 | import com.intellij.openapi.project.Project;
14 | import com.intellij.psi.PsiFile;
15 | import org.jetbrains.annotations.NotNull;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | // TODO Remove it?
20 | public class AnalyseCurrentFileAction extends AnAction {
21 | private static final Logger LOG = LoggerFactory.getLogger("DeepCode.AnalyseCurrentFileAction");
22 |
23 | @Override
24 | public void update(AnActionEvent e) {
25 | // perform action if and only if EDITOR != null
26 | boolean enabled = e.getData(CommonDataKeys.EDITOR) != null;
27 | e.getPresentation().setEnabled(enabled);
28 | }
29 |
30 | @Override
31 | public void actionPerformed(@NotNull AnActionEvent event) {
32 | final PsiFile psiFile = event.getRequiredData(PlatformDataKeys.PSI_FILE);
33 | Project project = psiFile.getProject();
34 |
35 | if (!LoginUtils.getInstance().isLogged(project, true)) {
36 | // DeepCodeNotifications.reShowLastNotification();
37 | return;
38 | }
39 |
40 | if (!DeepCodeUtils.getInstance().isSupportedFileFormat(psiFile)) {
41 | DeepCodeNotifications.showInfo(
42 | String.format(
43 | "Files with `%1$s` extension are not supported yet.",
44 | psiFile.getVirtualFile().getExtension()),
45 | project);
46 | return;
47 | }
48 | //RunUtils.asyncUpdateCurrentFilePanel(psiFile);
49 | ServiceManager.getService(project, myTodoView.class).refresh();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/actions/AnalyseProjectAction.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin.actions;
2 |
3 | import ai.deepcode.jbplugin.core.*;
4 | import com.intellij.openapi.actionSystem.AnAction;
5 | import com.intellij.openapi.actionSystem.AnActionEvent;
6 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
7 | import com.intellij.openapi.project.Project;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | public class AnalyseProjectAction extends AnAction {
11 |
12 | @Override
13 | public void actionPerformed(@NotNull AnActionEvent e) {
14 | final Project project = e.getRequiredData(PlatformDataKeys.PROJECT);
15 | DCLogger.getInstance().logInfo("Re-Analyse Project requested for: " + project);
16 | // fixme: ?? background task here to avoid potential freeze due to MUTEX lock
17 | AnalysisData.getInstance().resetCachesAndTasks(project);
18 | if (LoginUtils.getInstance().isLogged(project, true)) {
19 | RunUtils.getInstance().asyncAnalyseProjectAndUpdatePanel(project);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/actions/InvalidateCachesAction.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin.actions;
2 |
3 | import ai.deepcode.jbplugin.ui.myTodoView;
4 | import ai.deepcode.jbplugin.core.AnalysisData;
5 | import com.intellij.openapi.actionSystem.AnAction;
6 | import com.intellij.openapi.actionSystem.AnActionEvent;
7 | import com.intellij.openapi.actionSystem.PlatformDataKeys;
8 | import com.intellij.openapi.components.ServiceManager;
9 | import com.intellij.openapi.project.Project;
10 | import org.jetbrains.annotations.NotNull;
11 |
12 | public class InvalidateCachesAction extends AnAction {
13 |
14 | @Override
15 | public void actionPerformed(@NotNull AnActionEvent e) {
16 | final Project project = e.getRequiredData(PlatformDataKeys.PROJECT);
17 | AnalysisData.getInstance().resetCachesAndTasks(project);
18 | ServiceManager.getService(project, myTodoView.class).refresh();
19 | /*
20 | ActionManager.getInstance()
21 | .getAction("ai.deepcode.jbplugin.ToolsMenu.AnalyseProjectAction")
22 | .actionPerformed(e);
23 | */
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/actions/SeeResultsInBrowserAction.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin.actions;
2 |
3 | import ai.deepcode.jbplugin.core.AnalysisData;
4 | import com.intellij.ide.BrowserUtil;
5 | import com.intellij.openapi.actionSystem.AnAction;
6 | import com.intellij.openapi.actionSystem.AnActionEvent;
7 | import com.intellij.openapi.project.Project;
8 | import org.jetbrains.annotations.NotNull;
9 |
10 | public class SeeResultsInBrowserAction extends AnAction {
11 |
12 | @Override
13 | public void update(@NotNull AnActionEvent e) {
14 | final Project project = e.getProject();
15 | if (project==null) return;
16 | final boolean urlExist = !AnalysisData.getInstance().getAnalysisUrl(project).isEmpty();
17 | e.getPresentation().setEnabled(urlExist);
18 | }
19 |
20 | @Override
21 | public void actionPerformed(@NotNull AnActionEvent e) {
22 | final Project project = e.getProject();
23 | if (project==null) return;
24 | final String analysisUrl = AnalysisData.getInstance().getAnalysisUrl(project);
25 | if (!analysisUrl.isEmpty()) BrowserUtil.open(analysisUrl);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/actions/ShowSettingsAction.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin.actions;
2 |
3 | import ai.deepcode.jbplugin.ui.config.DeepCodeConfigEntry;
4 | import com.intellij.openapi.actionSystem.AnAction;
5 | import com.intellij.openapi.actionSystem.AnActionEvent;
6 | import com.intellij.openapi.options.ShowSettingsUtil;
7 | import org.jetbrains.annotations.NotNull;
8 |
9 | public class ShowSettingsAction extends AnAction {
10 |
11 | @Override
12 | public void actionPerformed(@NotNull AnActionEvent e) {
13 | ShowSettingsUtil.getInstance().showSettingsDialog(e.getProject(), DeepCodeConfigEntry.class);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/annotators/DeepCodeExternalAnnotator.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin.annotators;
2 |
3 | import ai.deepcode.javaclient.core.MyTextRange;
4 | import ai.deepcode.jbplugin.actions.DeepCodeIntentionAction;
5 | import ai.deepcode.jbplugin.core.DCLogger;
6 | import ai.deepcode.jbplugin.core.PDU;
7 | import ai.deepcode.jbplugin.core.AnalysisData;
8 | import ai.deepcode.jbplugin.core.DeepCodeUtils;
9 | import ai.deepcode.javaclient.core.SuggestionForFile;
10 | import com.intellij.lang.annotation.Annotation;
11 | import com.intellij.lang.annotation.AnnotationHolder;
12 | import com.intellij.lang.annotation.ExternalAnnotator;
13 | import com.intellij.openapi.editor.Editor;
14 | import com.intellij.openapi.progress.ProgressManager;
15 | import com.intellij.openapi.util.TextRange;
16 | import com.intellij.psi.PsiFile;
17 | import org.jetbrains.annotations.NotNull;
18 | import org.jetbrains.annotations.Nullable;
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 |
22 | import java.util.Collections;
23 | import java.util.List;
24 |
25 | /**
26 | * We should use ExternalAnnotator to work on files level while ordinary Annotators works on
27 | * elements level.
28 | */
29 | public class DeepCodeExternalAnnotator extends ExternalAnnotator> {
30 |
31 | private static final Logger LOG = LoggerFactory.getLogger("DeepCode.Annotator");
32 |
33 | /*
34 | @Nullable
35 | @Override
36 | public PsiFile collectInformation(@NotNull PsiFile psiFile) {
37 | DCLogger.getInstance().info("collectInformation(@NotNull PsiFile psiFile) for " + psiFile);
38 | return psiFile;
39 | }
40 |
41 | */
42 | @Override
43 | @Nullable
44 | public PsiFile collectInformation(
45 | @NotNull PsiFile psiFile, @NotNull Editor editor, boolean hasErrors) {
46 | // DCLogger.getInstance().info("collectInformation(@NotNull PsiFile psiFile, @NotNull Editor
47 | // editor, boolean hasErrors) for " + psiFile);
48 | return psiFile;
49 | // return collectInformation(psiFile);
50 | }
51 |
52 | @Nullable
53 | @Override
54 | public List doAnnotate(PsiFile psiFile) {
55 | if (!DeepCodeUtils.getInstance().isSupportedFileFormat(psiFile)) return Collections.emptyList();
56 | final long annotatorId = System.currentTimeMillis();
57 | DCLogger.getInstance()
58 | .logInfo("Annotator (" + annotatorId + ") requested for file: " + psiFile.getName());
59 | AnalysisData.getInstance()
60 | .waitForUpdateAnalysisFinish(psiFile.getProject(), ProgressManager.getInstance().getProgressIndicator());
61 | ProgressManager.checkCanceled();
62 | List suggestions = AnalysisData.getInstance().getAnalysis(psiFile);
63 | DCLogger.getInstance()
64 | .logInfo(
65 | "Annotator (" + annotatorId + ") suggestions gotten for file: " + psiFile.getName());
66 | ProgressManager.checkCanceled();
67 |
68 | return suggestions;
69 | /*
70 | // https://youtrack.jetbrains.com/issue/IDEA-239960
71 | return ProgressManager.getInstance()
72 | .runProcess(
73 | () -> AnalysisData.getAnalysis(psiFile),
74 | new BackgroundableProcessIndicator(
75 | psiFile.getProject(),
76 | "DeepCode: Analysing " + psiFile.getName() + " file... ",
77 | () -> true,
78 | "Stop",
79 | "Stop file analysis",
80 | true));
81 | */
82 | }
83 |
84 | @SuppressWarnings("deprecation") // later move to .newAnnotation introduced in 2020.1
85 | @Override
86 | public void apply(
87 | @NotNull PsiFile psiFile,
88 | List suggestions,
89 | @NotNull AnnotationHolder holder) {
90 | if (suggestions == null) return;
91 | for (SuggestionForFile suggestion : suggestions) {
92 | final String message = "DeepCode: " + suggestion.getMessage();
93 | Annotation annotation;
94 | for (MyTextRange myTextRange : suggestion.getRanges()) {
95 | final TextRange range = PDU.toTextRange(myTextRange);
96 | switch (suggestion.getSeverity()) {
97 | case 1:
98 | annotation = holder.createWeakWarningAnnotation(range, message);
99 | break;
100 | case 2:
101 | annotation = holder.createWarningAnnotation(range, message);
102 | break;
103 | case 3:
104 | annotation = holder.createErrorAnnotation(range, message);
105 | break;
106 | default:
107 | annotation = holder.createInfoAnnotation(range, message);
108 | break;
109 | }
110 | annotation.registerFix(
111 | new DeepCodeIntentionAction(psiFile, range, suggestion.getRule(), false));
112 | annotation.registerFix(
113 | new DeepCodeIntentionAction(psiFile, range, suggestion.getRule(), true));
114 | /*
115 | holder
116 | .newAnnotation(severity, "DeepCode: " + suggestion.getMessage())
117 | .range(range)
118 | .create();
119 | */
120 | }
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/ai/deepcode/jbplugin/core/AnalysisData.java:
--------------------------------------------------------------------------------
1 | package ai.deepcode.jbplugin.core;
2 |
3 | import ai.deepcode.javaclient.core.*;
4 | import ai.deepcode.jbplugin.DeepCodeStatusBarWidgetProvider;
5 | import com.intellij.psi.PsiFile;
6 | import org.jetbrains.annotations.NotNull;
7 |
8 | import java.util.Collection;
9 |
10 | public final class AnalysisData extends AnalysisDataBase {
11 |
12 | private static final AnalysisData INSTANCE = new AnalysisData();
13 |
14 | public static AnalysisData getInstance() {
15 | return INSTANCE;
16 | }
17 |
18 | private AnalysisData() {
19 | super(
20 | PDU.getInstance(),
21 | HashContentUtils.getInstance(),
22 | DeepCodeParams.getInstance(),
23 | DCLogger.getInstance());
24 | }
25 |
26 | @Override
27 | protected void updateUIonFilesRemovalFromCache(@NotNull Collection