├── .github └── ISSUE_TEMPLATE │ └── language-support.md ├── .gitignore ├── .idea └── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── LICENSE ├── README.md ├── build.gradle.kts ├── change-notes ├── 0_1_1.html ├── 0_2_0.html ├── 0_3_0.html ├── 0_3_1.html ├── 0_3_2.html ├── 0_4_0.html ├── 0_4_1.html ├── 0_4_2.html ├── 0_4_3.html ├── 0_4_4.html ├── 0_4_5.html ├── 0_4_6.html ├── 0_4_7.html ├── 0_5_0.html ├── 0_6_0.html ├── 0_6_1.html ├── 0_6_2.html ├── 0_7_0.html ├── 0_7_1.html ├── 0_8_0.html ├── 0_8_1.html ├── 0_8_2.html └── 0_8_3.html ├── fix-author.sh ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── gutter-icons.png ├── return-highlighter-logo.png ├── scope.png ├── style.png └── usage-example.png ├── plugin-description.html ├── settings.gradle.kts └── src └── main ├── java └── com │ └── github │ └── lppedd │ └── highlighter │ ├── java │ ├── JavaReturnHighlighterConfigurableGui.form │ └── JavaReturnHighlighterConfigurableGui.java │ ├── javascript │ ├── JavaScriptReturnHighlighterConfigurableGui.form │ └── JavaScriptReturnHighlighterConfigurableGui.java │ ├── php │ ├── PhpReturnHighlighterConfigurableGui.form │ └── PhpReturnHighlighterConfigurableGui.java │ ├── python │ ├── PythonReturnHighlighterConfigurableGui.form │ └── PythonReturnHighlighterConfigurableGui.java │ └── settings │ ├── ReturnHighlighterConfigurableGui.form │ └── ReturnHighlighterConfigurableGui.java ├── kotlin └── com │ └── github │ └── lppedd │ └── highlighter │ ├── AbstractReturnAnnotator.kt │ ├── AbstractReturnLineMarkerProvider.kt │ ├── Application.kt │ ├── Constants.kt │ ├── Icons.kt │ ├── ReturnHighlightStrategy.kt │ ├── ReturnHighlighterBundle.kt │ ├── TopLevelReturnHighlightStrategy.kt │ ├── java │ ├── JavaAlwaysHighlightStrategy.kt │ ├── JavaReturnAnnotator.kt │ ├── JavaReturnHighlighterConfig.kt │ ├── JavaReturnHighlighterConfigurable.kt │ ├── JavaReturnLineMarkerProvider.kt │ ├── JavaSimpleGetterHighlightStrategy.kt │ └── JavaTopLevelHighlightStrategy.kt │ ├── javascript │ ├── JavaScriptAlwaysHighlightStrategy.kt │ ├── JavaScriptReturnAnnotator.kt │ ├── JavaScriptReturnHighlighterConfig.kt │ ├── JavaScriptReturnHighlighterConfigurable.kt │ ├── JavaScriptReturnLineMarkerProvider.kt │ ├── JavaScriptSimpleGetterHighlightStrategy.kt │ └── JavaScriptTopLevelHighlightStrategy.kt │ ├── php │ ├── PhpAlwaysHighlightStrategy.kt │ ├── PhpReturnAnnotator.kt │ ├── PhpReturnHighlighterConfig.kt │ ├── PhpReturnHighlighterConfigurable.kt │ ├── PhpReturnLineMarkerProvider.kt │ └── PhpTopLevelHighlightStrategy.kt │ ├── python │ ├── PythonAlwaysHighlightStrategy.kt │ ├── PythonReturnAnnotator.kt │ ├── PythonReturnHighlighterConfig.kt │ ├── PythonReturnHighlighterConfigurable.kt │ ├── PythonReturnLineMarkerProvider.kt │ └── PythonTopLevelHighlightStrategy.kt │ └── settings │ ├── ReturnHighlighterColorSettingsPage.kt │ └── ReturnHighlighterConfigurable.kt └── resources ├── META-INF ├── java.xml ├── javascript.xml ├── php.xml ├── plugin.xml ├── pluginIcon.svg ├── pluginIcon_dark.svg └── python.xml ├── colorSchemes ├── return-highlighter-default-darcula.xml └── return-highlighter-default.xml ├── icons ├── return.svg └── return_dark.svg └── messages ├── ReturnHighlighterBundle.properties └── ReturnHighlighterBundle_it_IT.properties /.github/ISSUE_TEMPLATE/language-support.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Language support 3 | about: Suggest a new language to support 4 | title: 'Language support: [LANGUAGE]' 5 | labels: enhancement, language 6 | assignees: lppedd 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/* 3 | .idea_modules/ 4 | !.idea/codeStyles 5 | 6 | # Gradle and Maven with auto-import 7 | # When using Gradle or Maven with auto-import, you should exclude module files, 8 | # since they will be recreated, and may cause churn. Uncomment if using 9 | # auto-import. 10 | *.iml 11 | *.ipr 12 | 13 | # CMake 14 | cmake-build-*/ 15 | 16 | # File-based project format 17 | *.iws 18 | 19 | # IntelliJ 20 | out/ 21 | build/ 22 | 23 | # JIRA plugin 24 | atlassian-ide-plugin.xml 25 | 26 | # Crashlytics plugin (for Android Studio and IntelliJ) 27 | com_crashlytics_export_strings.xml 28 | crashlytics.properties 29 | crashlytics-build.properties 30 | fabric.properties 31 | 32 | # Compiled class file 33 | *.class 34 | 35 | # Log file 36 | *.log 37 | 38 | # BlueJ files 39 | *.ctxt 40 | 41 | # Mobile Tools for Java (J2ME) 42 | .mtj.tmp/ 43 | 44 | # Package Files # 45 | *.jar 46 | *.war 47 | *.nar 48 | *.ear 49 | *.zip 50 | *.tar.gz 51 | *.rar 52 | 53 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 54 | hs_err_pid* 55 | 56 | # Gradle 57 | .gradle 58 | 59 | # Ignore Gradle GUI config 60 | gradle-app.setting 61 | 62 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 63 | !gradle-wrapper.jar 64 | 65 | # Cache of project 66 | .gradletasknamecache 67 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 890 | 891 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Edoardo Luppi 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | :bell: Localization needed! PRs are welcomed (look [here][4] for bundles) :sunglasses: 2 | 3 | Plugin logo 4 | 5 | # Return Highlighter 6 | 7 | ### Available @ [JetBrains Plugins Repository][1] 8 | 9 | Looking for the latest **plugin binaries**? Get them [here][3] as `.zip` 10 | Supported IDE versions: `201.6668` to `*` 11 | 12 | #### Supported languages 13 | 14 | - Java 15 | - JavaScript and TypeScript 16 | - Python 17 | - PHP 18 | - Need another language? [Open an issue][2] 19 | 20 | ----- 21 | 22 | The aim of this plugin is to highlight `return` keywords in source code. 23 | Sometimes it happens we find difficult to read source files; take for example this piece of code 24 | 25 | ```typescript 26 | 1 private toggleRowCheck(rowId: string, doCheck: boolean): boolean { 27 | 2 if (doCheck) { 28 | 3 if (this.checkedRows.size >= (this.selectionOpt.limit || Infinity)) return false; 29 | 4 this.checkedRows.add(rowId); 30 | 5 } else { 31 | 6 this.checkedRows.delete(rowId); 32 | 7 } 33 | 8 return true; 34 | 9 } 35 | ``` 36 | 37 | It is not immediately apparent a `return` statement is present at line `3`. 38 | This is why the plugin does 39 | 40 | - Show a gutter icon next to the `return`ing lines (clicking on it will take you to the return statement!) 41 | - Highlight the `return` keyword, so that it stands out more 42 | 43 | #### Example 44 | 45 | Usage example 46 | 47 | ----- 48 | 49 | The plugin offers some degree of customization. 50 | 51 | ### Choose for which languages to show the gutter icon 52 | 53 | You can customize which languages will have the gutter icon via 54 | **Settings > Editor > General > Gutter Icons** 55 | 56 | You'll find a _Return Highlighter_ section, with all available languages listed. 57 | 58 | Gutter icons 59 | 60 | ### Disable/Customize the return keyword color highlighting 61 | 62 | You can disable or customize how the return keyword is highlighted, to stand out more, via 63 | **Settings > Editor > Color Scheme > Return Highlighter** 64 | 65 | To reset values to the default ones, check **Inherit values from**. 66 | 67 | Style 68 | 69 | ### Limit the scope of the plugin 70 | 71 | - #### Top-level returns only 72 | Certain languages offer features like _lambda expressions_ (Java) or _function expressions_ (JavaScript). 73 | This means potentially you can have nested functions, and thus nested `return` statements. 74 | 75 | To highlight only top-level `return` keywords, depending on the language, look under 76 | **Settings > Return Highlighter > *[language]*** 77 | and check **Only top-level return keywords**. 78 | 79 | - #### Skip simple getters 80 | Highlighting `return` statements in simple functions/methods can be annoying. 81 | Thus it is possible to disable it for such elements. 82 | 83 | To skip `return` keywords inside simple getters, look under 84 | **Settings > Return Highlighter > *[language]*** 85 | and check **Skip simple getters**. 86 | 87 | Scope 88 | 89 | A _tooltip_ is there to show examples of simple getters, per language, but for the sake of README completeness 90 | here is one too in TypeScript 91 | 92 | ``` 93 | isEnabled(): boolean { 94 | return true; 95 | } 96 | ``` 97 | 98 | ----- 99 | 100 | ## Author 101 | 102 | - Edoardo Luppi () 103 | 104 | [1]: https://plugins.jetbrains.com/plugin/13303-return-highlighter 105 | [2]: https://github.com/lppedd/idea-return-highlighter/issues/new?assignees=lppedd&labels=enhancement%2C+language&template=language-support.md&title=Language+support%3A+%5BLANGUAGE%5D 106 | [3]: https://github.com/lppedd/idea-return-highlighter/releases 107 | [4]: https://github.com/lppedd/idea-return-highlighter/tree/master/src/main/resources/messages 108 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("TrailingComma", "ConvertLambdaToReference") 2 | 3 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 4 | 5 | plugins { 6 | java 7 | id("org.jetbrains.intellij") version "1.13.2" 8 | kotlin("jvm") version "1.8.10" 9 | } 10 | 11 | group = "com.github.lppedd" 12 | version = "0.8.3" 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | implementation(kotlin("stdlib")) 20 | testImplementation("junit:junit:4.13.2") 21 | } 22 | 23 | intellij { 24 | version.set("IU-201.6668.113") 25 | downloadSources.set(true) 26 | pluginName.set("idea-return-highlighter") 27 | plugins.set(listOf( 28 | "java", 29 | "JavaScriptLanguage", 30 | "Pythonid:201.6668.113", 31 | "com.jetbrains.php:201.6668.113" 32 | )) 33 | } 34 | 35 | configure { 36 | sourceCompatibility = JavaVersion.VERSION_1_8 37 | targetCompatibility = JavaVersion.VERSION_1_8 38 | } 39 | 40 | tasks { 41 | wrapper { 42 | distributionType = Wrapper.DistributionType.ALL 43 | } 44 | 45 | val kotlinSettings: KotlinCompile.() -> Unit = { 46 | kotlinOptions.jvmTarget = "1.8" 47 | kotlinOptions.freeCompilerArgs += listOf( 48 | "-Xno-call-assertions", 49 | "-Xno-receiver-assertions", 50 | "-Xno-param-assertions", 51 | ) 52 | } 53 | 54 | compileKotlin(kotlinSettings) 55 | compileTestKotlin(kotlinSettings) 56 | 57 | patchPluginXml { 58 | version.set(project.version.toString()) 59 | sinceBuild.set("201.6668") 60 | untilBuild.set("") 61 | 62 | val projectPath = projectDir.path 63 | pluginDescription.set((File("$projectPath/plugin-description.html").readText(Charsets.UTF_8))) 64 | changeNotes.set((File("$projectPath/change-notes/${version.get().replace('.', '_')}.html").readText(Charsets.UTF_8))) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /change-notes/0_1_1.html: -------------------------------------------------------------------------------- 1 |

0.1.1 (09/11/2019)

2 |

3 | Initial alpha release.
4 | Supports 5 |

6 | 10 |
11 |

Each comes with different colors for light and dark editor schemes.

12 | -------------------------------------------------------------------------------- /change-notes/0_2_0.html: -------------------------------------------------------------------------------- 1 |

0.2.0 (10/11/2019)

2 |

3 | Second alpha release.
4 | New features 5 |

6 | 10 | -------------------------------------------------------------------------------- /change-notes/0_3_0.html: -------------------------------------------------------------------------------- 1 |

0.3.0 (10/11/2019)

2 |

3 | Third alpha release.
4 | New features 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_3_1.html: -------------------------------------------------------------------------------- 1 |

0.3.1 (11/11/2019)

2 |

3 | Third alpha release.
4 | Fixes 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_3_2.html: -------------------------------------------------------------------------------- 1 |

0.3.2 (11/11/2019)

2 |

3 | Third alpha release.
4 | Fixes 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_4_0.html: -------------------------------------------------------------------------------- 1 |

0.4.0 (11/11/2019)

2 |

3 | Fourth alpha release.
4 | New features 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_4_1.html: -------------------------------------------------------------------------------- 1 |

0.4.1 (11/11/2019)

2 |

3 | Fourth alpha release.
4 | New usability feature and bug fixes 5 |

6 | 10 | -------------------------------------------------------------------------------- /change-notes/0_4_2.html: -------------------------------------------------------------------------------- 1 |

0.4.2 (11/11/2019)

2 |

3 | Fourth alpha release.
4 | Performance improvements 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_4_3.html: -------------------------------------------------------------------------------- 1 |

0.4.3 (11/11/2019)

2 |

3 | Fourth alpha release.
4 | Performance improvements 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_4_4.html: -------------------------------------------------------------------------------- 1 |

0.4.4 (11/11/2019)

2 |

3 | Fourth alpha release.
4 | Performance and usability improvements 5 |

6 | 10 | -------------------------------------------------------------------------------- /change-notes/0_4_5.html: -------------------------------------------------------------------------------- 1 |

0.4.5 (11/11/2019)

2 |

3 | Fourth alpha release.
4 | Refactoring 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_4_6.html: -------------------------------------------------------------------------------- 1 |

0.4.6 (11/11/2019)

2 |

3 | Fourth alpha release.
4 | Refactoring 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_4_7.html: -------------------------------------------------------------------------------- 1 |

0.4.7 (11/11/2019)

2 |

3 | Fourth alpha release.
4 | Refactoring 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_5_0.html: -------------------------------------------------------------------------------- 1 |

0.5.0 (12/11/2019)

2 |

3 | Fifth alpha release.
4 | New features 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_6_0.html: -------------------------------------------------------------------------------- 1 |

0.6.0 (15/11/2019)

2 |

3 | Sixth alpha release.
4 | New features 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_6_1.html: -------------------------------------------------------------------------------- 1 |

0.6.1 (15/11/2019)

2 |

3 | Sixth alpha release.
4 | Refactoring with bug fixes, and new features 5 |

6 | 10 | -------------------------------------------------------------------------------- /change-notes/0_6_2.html: -------------------------------------------------------------------------------- 1 |

0.6.2 (16/11/2019)

2 |

3 | Sixth alpha release.
4 | Refactoring 5 |

6 | 10 | -------------------------------------------------------------------------------- /change-notes/0_7_0.html: -------------------------------------------------------------------------------- 1 |

0.7.0 (18/11/2019)

2 |

3 | Seventh alpha release.
4 | New features 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_7_1.html: -------------------------------------------------------------------------------- 1 |

0.7.1 (18/11/2019)

2 |

3 | Seventh alpha release.
4 | New features and refactoring 5 |

6 | 10 | -------------------------------------------------------------------------------- /change-notes/0_8_0.html: -------------------------------------------------------------------------------- 1 |

0.8.0 (09/12/2019)

2 |

3 | Eighth alpha release.
4 | New features and refactoring 5 |

6 | 11 | -------------------------------------------------------------------------------- /change-notes/0_8_1.html: -------------------------------------------------------------------------------- 1 |

0.8.1 (08/04/2020)

2 |

3 | Tenth alpha release.
4 | Build changes 5 |

6 | 9 | -------------------------------------------------------------------------------- /change-notes/0_8_2.html: -------------------------------------------------------------------------------- 1 |

0.8.2 (13/12/2021)

2 |

3 | Eleventh alpha release.
4 | Fixes and build changes 5 |

6 | 11 | -------------------------------------------------------------------------------- /change-notes/0_8_3.html: -------------------------------------------------------------------------------- 1 |

0.8.3 (19/03/2023)

2 |

3 | Twelfth alpha release. 4 |
5 | Fixes and build changes 6 |

7 | 10 | -------------------------------------------------------------------------------- /fix-author.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # git clone --bare https://github.com/user/repo.git 4 | # cd repo.git 5 | # - 6 | # git push --force --tags origin 'refs/heads/*' 7 | 8 | git filter-branch --env-filter ' 9 | 10 | OLD_EMAIL="your-old-email@example.com" 11 | CORRECT_NAME="Your Correct Name" 12 | CORRECT_EMAIL="your-correct-email@example.com" 13 | 14 | if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ] 15 | then 16 | export GIT_COMMITTER_NAME="$CORRECT_NAME" 17 | export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL" 18 | fi 19 | if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ] 20 | then 21 | export GIT_AUTHOR_NAME="$CORRECT_NAME" 22 | export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL" 23 | fi 24 | ' --tag-name-filter cat -- --branches --tags 25 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lppedd/idea-return-highlighter/df7e165f11002010cb7cab4feca9f37a27f95633/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lppedd/idea-return-highlighter/df7e165f11002010cb7cab4feca9f37a27f95633/gradlew -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /images/gutter-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lppedd/idea-return-highlighter/df7e165f11002010cb7cab4feca9f37a27f95633/images/gutter-icons.png -------------------------------------------------------------------------------- /images/return-highlighter-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lppedd/idea-return-highlighter/df7e165f11002010cb7cab4feca9f37a27f95633/images/return-highlighter-logo.png -------------------------------------------------------------------------------- /images/scope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lppedd/idea-return-highlighter/df7e165f11002010cb7cab4feca9f37a27f95633/images/scope.png -------------------------------------------------------------------------------- /images/style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lppedd/idea-return-highlighter/df7e165f11002010cb7cab4feca9f37a27f95633/images/style.png -------------------------------------------------------------------------------- /images/usage-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lppedd/idea-return-highlighter/df7e165f11002010cb7cab4feca9f37a27f95633/images/usage-example.png -------------------------------------------------------------------------------- /plugin-description.html: -------------------------------------------------------------------------------- 1 |

2 | Highlight return statements.
3 | Useful for hard-to-read sources. 4 |

5 |
6 |

The plugin

7 | 11 |
12 |

Supported languages are

13 | 20 |
21 |

22 | Read the full description here at GitHub. 23 |

24 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "idea-return-highlighter" 2 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/java/JavaReturnHighlighterConfigurableGui.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 |
54 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/java/JavaReturnHighlighterConfigurableGui.java: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.java; 2 | 3 | import javax.swing.*; 4 | 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import com.github.lppedd.highlighter.ReturnHighlighterBundle; 8 | import com.intellij.ui.ContextHelpLabel; 9 | import com.intellij.ui.components.JBCheckBox; 10 | import com.intellij.ui.components.JBLabel; 11 | 12 | /** 13 | * @author Edoardo Luppi 14 | */ 15 | public class JavaReturnHighlighterConfigurableGui { 16 | private JPanel rootPanel; 17 | private JBLabel info; 18 | private JPanel skipSimpleGettersPanel; 19 | private JBCheckBox isOnlyTopLevelReturns; 20 | private JBCheckBox isSkipSimpleGetters; 21 | 22 | public JavaReturnHighlighterConfigurableGui(final ReturnHighlighterBundle bundle) { 23 | this(); 24 | finishUpComponents(bundle); 25 | } 26 | 27 | private JavaReturnHighlighterConfigurableGui() {} 28 | 29 | @NotNull 30 | public JPanel getRootPanel() { 31 | return rootPanel; 32 | } 33 | 34 | @NotNull 35 | public Boolean isOnlyTopLevelReturns() { 36 | return isOnlyTopLevelReturns.isSelected(); 37 | } 38 | 39 | @NotNull 40 | public Boolean isSkipSimpleGetters() { 41 | return isSkipSimpleGetters.isSelected(); 42 | } 43 | 44 | public void setOnlyTopLevelReturns(@NotNull final Boolean value) { 45 | isOnlyTopLevelReturns.setSelected(value); 46 | } 47 | 48 | public void setSkipSimpleGetters(@NotNull final Boolean value) { 49 | isSkipSimpleGetters.setSelected(value); 50 | } 51 | 52 | private void finishUpComponents(final ReturnHighlighterBundle bundle) { 53 | info.setText(bundle.get("rh.settings.custom.java")); 54 | isOnlyTopLevelReturns.setText(bundle.get("rh.settings.custom.java.topLevel")); 55 | isSkipSimpleGetters.setText(bundle.get("rh.settings.custom.java.simpleGetters")); 56 | 57 | final String simpleGettersTooltip = bundle.get("rh.settings.custom.java.simpleGetters.tooltip"); 58 | skipSimpleGettersPanel.add(ContextHelpLabel.create(simpleGettersTooltip)); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/javascript/JavaScriptReturnHighlighterConfigurableGui.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
56 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/javascript/JavaScriptReturnHighlighterConfigurableGui.java: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.javascript; 2 | 3 | import javax.swing.*; 4 | 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import com.github.lppedd.highlighter.ReturnHighlighterBundle; 8 | import com.intellij.ui.ContextHelpLabel; 9 | import com.intellij.ui.components.JBCheckBox; 10 | import com.intellij.ui.components.JBLabel; 11 | 12 | /** 13 | * @author Edoardo Luppi 14 | */ 15 | public class JavaScriptReturnHighlighterConfigurableGui { 16 | private JPanel rootPanel; 17 | private JBLabel info; 18 | private JPanel skipSimpleGettersPanel; 19 | private JBCheckBox isOnlyTopLevelReturns; 20 | private JBCheckBox isSkipSimpleGetters; 21 | 22 | public JavaScriptReturnHighlighterConfigurableGui(final ReturnHighlighterBundle bundle) { 23 | this(); 24 | finishUpComponents(bundle); 25 | } 26 | 27 | private JavaScriptReturnHighlighterConfigurableGui() {} 28 | 29 | @NotNull 30 | public JPanel getRootPanel() { 31 | return rootPanel; 32 | } 33 | 34 | @NotNull 35 | public Boolean isOnlyTopLevelReturns() { 36 | return isOnlyTopLevelReturns.isSelected(); 37 | } 38 | 39 | @NotNull 40 | public Boolean isSkipSimpleGetters() { 41 | return isSkipSimpleGetters.isSelected(); 42 | } 43 | 44 | public void setOnlyTopLevelReturns(@NotNull final Boolean value) { 45 | isOnlyTopLevelReturns.setSelected(value); 46 | } 47 | 48 | public void setSkipSimpleGetters(@NotNull final Boolean value) { 49 | isSkipSimpleGetters.setSelected(value); 50 | } 51 | 52 | private void finishUpComponents(final ReturnHighlighterBundle bundle) { 53 | info.setText(bundle.get("rh.settings.custom.javascript")); 54 | isOnlyTopLevelReturns.setText(bundle.get("rh.settings.custom.javascript.topLevel")); 55 | isSkipSimpleGetters.setText(bundle.get("rh.settings.custom.javascript.simpleGetters")); 56 | 57 | final String simpleGettersTooltip = 58 | bundle.get("rh.settings.custom.javascript.simpleGetters.tooltip"); 59 | skipSimpleGettersPanel.add(ContextHelpLabel.create(simpleGettersTooltip)); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/php/PhpReturnHighlighterConfigurableGui.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/php/PhpReturnHighlighterConfigurableGui.java: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.php; 2 | 3 | import javax.swing.*; 4 | 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import com.github.lppedd.highlighter.ReturnHighlighterBundle; 8 | import com.intellij.ui.components.JBCheckBox; 9 | import com.intellij.ui.components.JBLabel; 10 | 11 | /** 12 | * @author Edoardo Luppi 13 | */ 14 | public class PhpReturnHighlighterConfigurableGui { 15 | private JPanel rootPanel; 16 | private JBLabel info; 17 | private JBCheckBox isOnlyTopLevelReturns; 18 | 19 | public PhpReturnHighlighterConfigurableGui(final ReturnHighlighterBundle bundle) { 20 | this(); 21 | finishUpComponents(bundle); 22 | } 23 | 24 | private PhpReturnHighlighterConfigurableGui() {} 25 | 26 | @NotNull 27 | public JPanel getRootPanel() { 28 | return rootPanel; 29 | } 30 | 31 | @NotNull 32 | public Boolean isOnlyTopLevelReturns() { 33 | return isOnlyTopLevelReturns.isSelected(); 34 | } 35 | 36 | public void setOnlyTopLevelReturns(@NotNull final Boolean value) { 37 | isOnlyTopLevelReturns.setSelected(value); 38 | } 39 | 40 | private void finishUpComponents(final ReturnHighlighterBundle bundle) { 41 | info.setText(bundle.get("rh.settings.custom.php")); 42 | isOnlyTopLevelReturns.setText(bundle.get("rh.settings.custom.php.topLevel")); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/python/PythonReturnHighlighterConfigurableGui.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/python/PythonReturnHighlighterConfigurableGui.java: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.python; 2 | 3 | import javax.swing.*; 4 | 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import com.github.lppedd.highlighter.ReturnHighlighterBundle; 8 | import com.intellij.ui.components.JBCheckBox; 9 | import com.intellij.ui.components.JBLabel; 10 | 11 | /** 12 | * @author Edoardo Luppi 13 | */ 14 | public class PythonReturnHighlighterConfigurableGui { 15 | private JPanel rootPanel; 16 | private JBLabel info; 17 | private JBCheckBox isOnlyTopLevelReturns; 18 | 19 | public PythonReturnHighlighterConfigurableGui(@NotNull final ReturnHighlighterBundle bundle) { 20 | this(); 21 | finishUpComponents(bundle); 22 | } 23 | 24 | private PythonReturnHighlighterConfigurableGui() {} 25 | 26 | @NotNull 27 | public JPanel getRootPanel() { 28 | return rootPanel; 29 | } 30 | 31 | @NotNull 32 | public Boolean isOnlyTopLevelReturns() { 33 | return isOnlyTopLevelReturns.isSelected(); 34 | } 35 | 36 | public void setOnlyTopLevelReturns(@NotNull final Boolean value) { 37 | isOnlyTopLevelReturns.setSelected(value); 38 | } 39 | 40 | private void finishUpComponents(@NotNull final ReturnHighlighterBundle bundle) { 41 | info.setText(bundle.get("rh.settings.custom.python")); 42 | isOnlyTopLevelReturns.setText(bundle.get("rh.settings.custom.python.topLevel")); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/settings/ReturnHighlighterConfigurableGui.form: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | -------------------------------------------------------------------------------- /src/main/java/com/github/lppedd/highlighter/settings/ReturnHighlighterConfigurableGui.java: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.settings; 2 | 3 | import java.awt.*; 4 | 5 | import javax.swing.*; 6 | 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import com.github.lppedd.highlighter.ReturnHighlighterBundle; 10 | import com.intellij.ui.components.JBLabel; 11 | import com.intellij.util.ui.JBUI; 12 | import com.intellij.util.ui.JBUI.Borders; 13 | 14 | /** 15 | * @author Edoardo Luppi 16 | */ 17 | public class ReturnHighlighterConfigurableGui { 18 | private JPanel rootPanel; 19 | private JPanel listPanel; 20 | 21 | @NotNull 22 | public JPanel getRootPanel() { 23 | return rootPanel; 24 | } 25 | 26 | @NotNull 27 | public JPanel getListPanel() { 28 | return listPanel; 29 | } 30 | 31 | private void createUIComponents() { 32 | final JPanel rootPanel = new JPanel(); 33 | rootPanel.setLayout(new BorderLayout()); 34 | rootPanel.add( 35 | new JBLabel(ReturnHighlighterBundle.INSTANCE.get("rh.settings.custom.global")), 36 | BorderLayout.NORTH 37 | ); 38 | 39 | final JPanel listPanel = buildListPanel(); 40 | rootPanel.add(listPanel, BorderLayout.WEST); 41 | 42 | this.rootPanel = rootPanel; 43 | this.listPanel = listPanel; 44 | } 45 | 46 | private JPanel buildListPanel() { 47 | final JPanel listPanel = new JPanel(); 48 | listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS)); 49 | listPanel.setBorder(Borders.emptyLeft(10)); 50 | listPanel.add(Box.createRigidArea(JBUI.size(0, 10))); 51 | return listPanel; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/AbstractReturnAnnotator.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter 2 | 3 | import com.intellij.lang.annotation.AnnotationHolder 4 | import com.intellij.lang.annotation.Annotator 5 | import com.intellij.lang.annotation.HighlightSeverity 6 | import com.intellij.openapi.editor.colors.EditorColorsManager 7 | import com.intellij.openapi.editor.colors.TextAttributesKey 8 | import com.intellij.psi.PsiElement 9 | 10 | /** 11 | * @author Edoardo Luppi 12 | */ 13 | abstract class AbstractReturnAnnotator(private val klass: Class) : Annotator { 14 | companion object { 15 | val TAK_RETURN: TextAttributesKey = TextAttributesKey.createTextAttributesKey( 16 | "RH_RETURN_KEYWORD", 17 | TextAttributesKey.createTextAttributesKey("Return Highlighter defaults") 18 | ) 19 | } 20 | 21 | private val returnKeywordAttributes = EditorColorsManager.getInstance() 22 | .globalScheme 23 | .getAttributes(TAK_RETURN) 24 | 25 | final override fun annotate(psiElement: PsiElement, holder: AnnotationHolder) { 26 | @Suppress("UNCHECKED_CAST") 27 | if (!returnKeywordAttributes.isEmpty 28 | && klass.isAssignableFrom(psiElement::class.java) 29 | && isValidContext(psiElement as T) 30 | ) { 31 | getPsiElement(psiElement)?.also { 32 | holder.newSilentAnnotation(HighlightSeverity.INFORMATION) 33 | .enforcedTextAttributes(returnKeywordAttributes) 34 | .range(it) 35 | .create() 36 | } 37 | } 38 | } 39 | 40 | protected open fun getPsiElement(psiElement: T): PsiElement? = psiElement.firstChild ?: psiElement 41 | protected open fun isValidContext(psiElement: T): Boolean = true 42 | } 43 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/AbstractReturnLineMarkerProvider.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter 2 | 3 | import com.intellij.codeInsight.daemon.LineMarkerInfo 4 | import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor 5 | import com.intellij.openapi.editor.markup.GutterIconRenderer 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.util.PsiNavigateUtil 8 | import javax.swing.Icon 9 | 10 | /** 11 | * @author Edoardo Luppi 12 | */ 13 | abstract class AbstractReturnLineMarkerProvider(private val klass: Class) : LineMarkerProviderDescriptor() { 14 | final override fun getIcon(): Icon = Icons.GUTTER_RETURN 15 | final override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo? { 16 | @Suppress("UNCHECKED_CAST") 17 | if (klass.isAssignableFrom(element::class.java) && isValidContext(element as T)) { 18 | return createLineMarkerInfo(getPsiElement(element)) 19 | } 20 | 21 | return null 22 | } 23 | 24 | protected open fun getPsiElement(psiElement: T): PsiElement? = psiElement.firstChild ?: psiElement 25 | protected open fun isValidContext(psiElement: T): Boolean = true 26 | 27 | private fun createLineMarkerInfo(psiElement: PsiElement?): LineMarkerInfo? = 28 | if (psiElement == null) null 29 | else LineMarkerInfo( 30 | psiElement, 31 | psiElement.textRange, 32 | Icons.GUTTER_RETURN, 33 | { ReturnHighlighterBundle["rh.gutter.text"] }, 34 | { _, elt -> PsiNavigateUtil.navigate(elt) }, 35 | GutterIconRenderer.Alignment.LEFT 36 | ) 37 | } 38 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/Application.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter 2 | 3 | import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer 4 | import com.intellij.openapi.project.ProjectManager 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | object Application { 10 | fun refreshFiles() { 11 | ProjectManager.getInstance() 12 | .openProjects 13 | .map { DaemonCodeAnalyzer.getInstance(it) } 14 | .forEach(DaemonCodeAnalyzer::restart) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter 2 | 3 | /** 4 | * @author Edoardo Luppi 5 | */ 6 | @Suppress("SpellCheckingInspection") 7 | object Constants { 8 | const val IAPP_NAME: String = "ReturnHighlighter" 9 | const val ISTORAGE_FILE: String = "returnHighlighter.xml" 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/Icons.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter 2 | 3 | import com.intellij.openapi.util.IconLoader 4 | import javax.swing.Icon 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | object Icons { 10 | val GUTTER_RETURN: Icon = IconLoader.getIcon("/icons/return.svg") 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/ReturnHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter 2 | 3 | import com.intellij.psi.PsiElement 4 | 5 | /** 6 | * @author Edoardo Luppi 7 | */ 8 | interface ReturnHighlightStrategy { 9 | fun isValidContext(psiElement: T): Boolean 10 | 11 | enum class PsiResult { 12 | VALID, 13 | INVALID, 14 | CONTINUE 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/ReturnHighlighterBundle.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter 2 | 3 | import com.intellij.BundleBase 4 | import org.jetbrains.annotations.NonNls 5 | import org.jetbrains.annotations.PropertyKey 6 | import java.lang.ref.Reference 7 | import java.lang.ref.SoftReference 8 | import java.util.* 9 | 10 | /** 11 | * @author Edoardo Luppi 12 | */ 13 | object ReturnHighlighterBundle { 14 | private const val BUNDLE = "messages.ReturnHighlighterBundle" 15 | private var bundle: Reference? = null 16 | 17 | operator fun get(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): String = 18 | BundleBase.message(getBundle(), key, *params) 19 | 20 | @NonNls 21 | private fun getBundle(): ResourceBundle { 22 | var derefBundle = com.intellij.reference.SoftReference.dereference(bundle) 23 | 24 | if (derefBundle == null) { 25 | derefBundle = ResourceBundle.getBundle(BUNDLE) 26 | bundle = SoftReference(derefBundle) 27 | return derefBundle 28 | } 29 | 30 | return derefBundle 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/TopLevelReturnHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult 4 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult.* 5 | import com.intellij.openapi.progress.ProgressManager 6 | import com.intellij.psi.PsiElement 7 | 8 | /** 9 | * @author Edoardo Luppi 10 | */ 11 | abstract class TopLevelReturnHighlightStrategy : ReturnHighlightStrategy { 12 | override fun isValidContext(psiElement: T): Boolean { 13 | var psi: PsiElement? = psiElement 14 | 15 | while (psi != null) { 16 | ProgressManager.checkCanceled() 17 | psi = when (check(psi)) { 18 | VALID -> return true 19 | INVALID -> return false 20 | CONTINUE -> psi.parent 21 | } 22 | } 23 | 24 | return false 25 | } 26 | 27 | protected abstract fun check(psiElement: PsiElement): PsiResult 28 | } 29 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/java/JavaAlwaysHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.java 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 4 | import com.intellij.psi.PsiKeyword 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | internal object JavaAlwaysHighlightStrategy : ReturnHighlightStrategy { 10 | // Note: it seems the Java Psi structure isn't quite right when errors are 11 | // present. Thus, we need to intercept a lower-level PsiElement 12 | override fun isValidContext(psiElement: PsiKeyword) = 13 | psiElement.text == PsiKeyword.RETURN 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/java/JavaReturnAnnotator.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.java 2 | 3 | import com.intellij.psi.PsiKeyword 4 | import com.github.lppedd.highlighter.AbstractReturnAnnotator as ARA 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | internal class JavaReturnAnnotator : ARA(PsiKeyword::class.java) { 10 | private val config = JavaReturnHighlighterConfig.getInstance() 11 | 12 | override fun getPsiElement(psiElement: PsiKeyword) = psiElement 13 | override fun isValidContext(psiElement: PsiKeyword) = 14 | config.getHighlightStrategy().isValidContext(psiElement) 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/java/JavaReturnHighlighterConfig.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.java 2 | 3 | import com.github.lppedd.highlighter.Application 4 | import com.github.lppedd.highlighter.Constants 5 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 6 | import com.github.lppedd.highlighter.java.JavaReturnHighlighterConfig.JavaConfig 7 | import com.intellij.openapi.components.PersistentStateComponent 8 | import com.intellij.openapi.components.ServiceManager 9 | import com.intellij.openapi.components.State 10 | import com.intellij.openapi.components.Storage 11 | import com.intellij.psi.PsiKeyword 12 | 13 | /** 14 | * @author Edoardo Luppi 15 | */ 16 | @State( 17 | name = "Java", 18 | storages = [Storage(Constants.ISTORAGE_FILE)] 19 | ) 20 | internal class JavaReturnHighlighterConfig : PersistentStateComponent { 21 | companion object { 22 | fun getInstance(): JavaReturnHighlighterConfig = 23 | ServiceManager.getService(JavaReturnHighlighterConfig::class.java) 24 | } 25 | 26 | private var state = JavaConfig() 27 | private var highlightStrategy: ReturnHighlightStrategy = JavaAlwaysHighlightStrategy 28 | 29 | override fun getState(): JavaConfig = state.copy() 30 | override fun loadState(state: JavaConfig) { 31 | this.state = state 32 | updateCurrentHighlightStrategy() 33 | } 34 | 35 | fun setState(state: JavaConfig) { 36 | this.state = state 37 | updateCurrentHighlightStrategy() 38 | Application.refreshFiles() 39 | } 40 | 41 | fun getHighlightStrategy() = highlightStrategy 42 | 43 | private fun updateCurrentHighlightStrategy() { 44 | var highlightStrategy: ReturnHighlightStrategy = JavaAlwaysHighlightStrategy 45 | 46 | if (state.isOnlyTopLevelReturns) { 47 | highlightStrategy = JavaTopLevelHighlightStrategy 48 | } 49 | 50 | if (state.isSkipSimpleGetters) { 51 | highlightStrategy = JavaSimpleGetterHighlightStrategy(highlightStrategy) 52 | } 53 | 54 | this.highlightStrategy = highlightStrategy 55 | } 56 | 57 | data class JavaConfig( 58 | var isOnlyTopLevelReturns: Boolean = false, 59 | var isSkipSimpleGetters: Boolean = false 60 | ) 61 | } 62 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/java/JavaReturnHighlighterConfigurable.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.java 2 | 3 | import com.github.lppedd.highlighter.Constants 4 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 5 | import com.intellij.openapi.options.SearchableConfigurable 6 | import javax.swing.JComponent 7 | 8 | /** 9 | * @author Edoardo Luppi 10 | */ 11 | internal class JavaReturnHighlighterConfigurable : SearchableConfigurable { 12 | private val config = JavaReturnHighlighterConfig.getInstance() 13 | private val gui = JavaReturnHighlighterConfigurableGui(ReturnHighlighterBundle) 14 | 15 | override fun getId() = "preferences.${Constants.IAPP_NAME}.java" 16 | override fun getDisplayName() = ReturnHighlighterBundle["rh.settings.java"] 17 | 18 | override fun apply() { 19 | config.state = config.state.copy( 20 | isOnlyTopLevelReturns = gui.isOnlyTopLevelReturns, 21 | isSkipSimpleGetters = gui.isSkipSimpleGetters 22 | ) 23 | } 24 | 25 | override fun reset() { 26 | gui.isOnlyTopLevelReturns = config.state.isOnlyTopLevelReturns 27 | gui.isSkipSimpleGetters = config.state.isSkipSimpleGetters 28 | } 29 | 30 | override fun isModified() = 31 | gui.isOnlyTopLevelReturns != config.state.isOnlyTopLevelReturns 32 | || gui.isSkipSimpleGetters != config.state.isSkipSimpleGetters 33 | 34 | override fun createComponent(): JComponent? { 35 | gui.isOnlyTopLevelReturns = config.state.isOnlyTopLevelReturns 36 | gui.isSkipSimpleGetters = config.state.isSkipSimpleGetters 37 | return gui.rootPanel 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/java/JavaReturnLineMarkerProvider.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.java 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 4 | import com.intellij.psi.PsiKeyword 5 | import com.github.lppedd.highlighter.AbstractReturnLineMarkerProvider as ARLMP 6 | 7 | /** 8 | * @author Edoardo Luppi 9 | */ 10 | internal class JavaReturnLineMarkerProvider : ARLMP(PsiKeyword::class.java) { 11 | private val config = JavaReturnHighlighterConfig.getInstance() 12 | 13 | override fun getName() = ReturnHighlighterBundle["rh.settings.java"] 14 | override fun getPsiElement(psiElement: PsiKeyword) = psiElement 15 | override fun isValidContext(psiElement: PsiKeyword) = 16 | config.getHighlightStrategy().isValidContext(psiElement) 17 | } 18 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/java/JavaSimpleGetterHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.java 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 4 | import com.intellij.openapi.progress.ProgressManager 5 | import com.intellij.psi.* 6 | import com.intellij.psi.util.PsiTreeUtil 7 | 8 | /** 9 | * @author Edoardo Luppi 10 | */ 11 | internal class JavaSimpleGetterHighlightStrategy( 12 | private val delegate: ReturnHighlightStrategy 13 | ) : ReturnHighlightStrategy { 14 | override fun isValidContext(psiElement: PsiKeyword): Boolean { 15 | if (!delegate.isValidContext(psiElement)) { 16 | return false 17 | } 18 | 19 | ProgressManager.checkCanceled() 20 | 21 | val psiCodeBlock = PsiTreeUtil.getParentOfType( 22 | psiElement, 23 | PsiReturnStatement::class.java, 24 | true 25 | )?.parent 26 | 27 | return if (psiCodeBlock is PsiCodeBlock && psiCodeBlock.parent is PsiMethod) { 28 | ProgressManager.checkCanceled() 29 | checkPsiCodeBlock(psiCodeBlock) 30 | } else { 31 | true 32 | } 33 | } 34 | 35 | private fun checkPsiCodeBlock(psiCodeBlock: PsiCodeBlock): Boolean { 36 | val nonEmptyStatements = psiCodeBlock.children.filter { 37 | it !is PsiJavaToken 38 | && it !is PsiEmptyStatement 39 | && it !is PsiWhiteSpace 40 | } 41 | 42 | return when { 43 | nonEmptyStatements.isEmpty() -> false 44 | nonEmptyStatements.size == 1 -> !containsOnlyReferences(nonEmptyStatements[0]) 45 | else -> true 46 | } 47 | } 48 | 49 | private fun containsOnlyReferences(psiElement: PsiElement) = 50 | PsiTreeUtil.findChildOfAnyType( 51 | psiElement, 52 | PsiMethodCallExpression::class.java, 53 | PsiPolyadicExpression::class.java 54 | ) == null 55 | } 56 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/java/JavaTopLevelHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.java 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult 4 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult.* 5 | import com.github.lppedd.highlighter.TopLevelReturnHighlightStrategy 6 | import com.intellij.psi.* 7 | import com.intellij.psi.util.PsiTreeUtil 8 | 9 | /** 10 | * @author Edoardo Luppi 11 | */ 12 | internal object JavaTopLevelHighlightStrategy : TopLevelReturnHighlightStrategy() { 13 | override fun isValidContext(psiElement: PsiKeyword): Boolean { 14 | // Note: it seems the Java Psi structure isn't quite right when errors are 15 | // present. Thus, we need to intercept a lower-level PsiElement 16 | return if (psiElement.text != PsiKeyword.RETURN) { 17 | false 18 | } else { 19 | super.isValidContext(psiElement) 20 | } 21 | } 22 | 23 | override fun check(psiElement: PsiElement): PsiResult = 24 | when (psiElement) { 25 | is PsiLambdaExpression -> checkLambdaExpression(psiElement) 26 | is PsiMethod -> VALID 27 | else -> CONTINUE 28 | } 29 | 30 | private fun checkLambdaExpression(psiElement: PsiLambdaExpression): PsiResult { 31 | // Lambda expressions are valid only if immediately assigned to a Field 32 | val psiField = PsiTreeUtil.getParentOfType( 33 | psiElement, 34 | PsiField::class.java, 35 | true, 36 | PsiLambdaExpression::class.java 37 | ) 38 | 39 | return if (psiField is PsiField) VALID else INVALID 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/javascript/JavaScriptAlwaysHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.javascript 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 4 | import com.intellij.lang.javascript.psi.JSReturnStatement 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | internal object JavaScriptAlwaysHighlightStrategy : ReturnHighlightStrategy { 10 | override fun isValidContext(psiElement: JSReturnStatement) = true 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/javascript/JavaScriptReturnAnnotator.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.javascript 2 | 3 | import com.intellij.lang.javascript.psi.JSReturnStatement 4 | import com.github.lppedd.highlighter.AbstractReturnAnnotator as ARA 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | internal class JavaScriptReturnAnnotator : ARA(JSReturnStatement::class.java) { 10 | private val config = JavaScriptReturnHighlighterConfig.getInstance() 11 | 12 | override fun isValidContext(psiElement: JSReturnStatement) = 13 | config.getHighlightStrategy().isValidContext(psiElement) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/javascript/JavaScriptReturnHighlighterConfig.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.javascript 2 | 3 | import com.github.lppedd.highlighter.Application 4 | import com.github.lppedd.highlighter.Constants 5 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 6 | import com.github.lppedd.highlighter.javascript.JavaScriptReturnHighlighterConfig.JavaScriptConfig 7 | import com.intellij.lang.javascript.psi.JSReturnStatement 8 | import com.intellij.openapi.components.PersistentStateComponent 9 | import com.intellij.openapi.components.ServiceManager 10 | import com.intellij.openapi.components.State 11 | import com.intellij.openapi.components.Storage 12 | 13 | /** 14 | * @author Edoardo Luppi 15 | */ 16 | @State( 17 | name = "JavaScript", 18 | storages = [Storage(Constants.ISTORAGE_FILE)] 19 | ) 20 | internal class JavaScriptReturnHighlighterConfig : PersistentStateComponent { 21 | companion object { 22 | fun getInstance(): JavaScriptReturnHighlighterConfig = 23 | ServiceManager.getService(JavaScriptReturnHighlighterConfig::class.java) 24 | } 25 | 26 | private var state = JavaScriptConfig() 27 | private var highlightStrategy: ReturnHighlightStrategy = JavaScriptAlwaysHighlightStrategy 28 | 29 | override fun getState(): JavaScriptConfig = state.copy() 30 | override fun loadState(state: JavaScriptConfig) { 31 | this.state = state 32 | updateCurrentHighlightStrategy() 33 | } 34 | 35 | fun setState(state: JavaScriptConfig) { 36 | this.state = state 37 | updateCurrentHighlightStrategy() 38 | Application.refreshFiles() 39 | } 40 | 41 | fun getHighlightStrategy() = highlightStrategy 42 | 43 | private fun updateCurrentHighlightStrategy() { 44 | var highlightStrategy: ReturnHighlightStrategy = 45 | JavaScriptAlwaysHighlightStrategy 46 | 47 | if (state.isOnlyTopLevelReturns) { 48 | highlightStrategy = JavaScriptTopLevelHighlightStrategy 49 | } 50 | 51 | if (state.isSkipSimpleGetters) { 52 | highlightStrategy = JavaScriptSimpleGetterHighlightStrategy(highlightStrategy) 53 | } 54 | 55 | this.highlightStrategy = highlightStrategy 56 | } 57 | 58 | data class JavaScriptConfig( 59 | var isOnlyTopLevelReturns: Boolean = false, 60 | var isSkipSimpleGetters: Boolean = false 61 | ) 62 | } 63 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/javascript/JavaScriptReturnHighlighterConfigurable.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.javascript 2 | 3 | import com.github.lppedd.highlighter.Constants 4 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 5 | import com.intellij.openapi.options.SearchableConfigurable 6 | import javax.swing.JComponent 7 | 8 | /** 9 | * @author Edoardo Luppi 10 | */ 11 | internal class JavaScriptReturnHighlighterConfigurable : SearchableConfigurable { 12 | private val config = JavaScriptReturnHighlighterConfig.getInstance() 13 | private val gui = JavaScriptReturnHighlighterConfigurableGui(ReturnHighlighterBundle) 14 | 15 | override fun getId() = "preferences.${Constants.IAPP_NAME}.JavaScript" 16 | override fun getDisplayName() = ReturnHighlighterBundle["rh.settings.javascript"] 17 | 18 | override fun apply() { 19 | config.state = config.state.copy( 20 | isOnlyTopLevelReturns = gui.isOnlyTopLevelReturns, 21 | isSkipSimpleGetters = gui.isSkipSimpleGetters 22 | ) 23 | } 24 | 25 | override fun reset() { 26 | gui.isOnlyTopLevelReturns = config.state.isOnlyTopLevelReturns 27 | gui.isSkipSimpleGetters = config.state.isSkipSimpleGetters 28 | } 29 | 30 | override fun isModified() = 31 | gui.isOnlyTopLevelReturns != config.state.isOnlyTopLevelReturns 32 | || gui.isSkipSimpleGetters != config.state.isSkipSimpleGetters 33 | 34 | override fun createComponent(): JComponent? { 35 | gui.isOnlyTopLevelReturns = config.state.isOnlyTopLevelReturns 36 | gui.isSkipSimpleGetters = config.state.isSkipSimpleGetters 37 | return gui.rootPanel 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/javascript/JavaScriptReturnLineMarkerProvider.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.javascript 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 4 | import com.intellij.lang.javascript.psi.JSReturnStatement 5 | import com.github.lppedd.highlighter.AbstractReturnLineMarkerProvider as ARLMP 6 | 7 | /** 8 | * @author Edoardo Luppi 9 | */ 10 | internal class JavaScriptReturnLineMarkerProvider : ARLMP(JSReturnStatement::class.java) { 11 | private val config = JavaScriptReturnHighlighterConfig.getInstance() 12 | 13 | override fun getName() = ReturnHighlighterBundle["rh.settings.javascript"] 14 | override fun isValidContext(psiElement: JSReturnStatement) = 15 | config.getHighlightStrategy().isValidContext(psiElement) 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/javascript/JavaScriptSimpleGetterHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.javascript 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 4 | import com.intellij.lang.javascript.psi.* 5 | import com.intellij.openapi.progress.ProgressManager 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.psi.PsiWhiteSpace 8 | import com.intellij.psi.impl.source.tree.LeafPsiElement 9 | import com.intellij.psi.util.PsiTreeUtil 10 | 11 | /** 12 | * @author Edoardo Luppi 13 | */ 14 | internal class JavaScriptSimpleGetterHighlightStrategy( 15 | private val delegate: ReturnHighlightStrategy 16 | ) : ReturnHighlightStrategy { 17 | override fun isValidContext(psiElement: JSReturnStatement): Boolean { 18 | if (!delegate.isValidContext(psiElement)) { 19 | return false 20 | } 21 | 22 | ProgressManager.checkCanceled() 23 | 24 | val jsBlockStatement = PsiTreeUtil.getParentOfType( 25 | psiElement, 26 | JSBlockStatement::class.java, 27 | true 28 | ) 29 | 30 | return if (jsBlockStatement is JSBlockStatement && jsBlockStatement.parent is JSFunction) { 31 | checkJSBlockStatement(jsBlockStatement, psiElement) 32 | } else { 33 | true 34 | } 35 | } 36 | 37 | private fun checkJSBlockStatement( 38 | jsBlockStatement: JSBlockStatement, 39 | jsReturnStatement: JSReturnStatement 40 | ): Boolean { 41 | // To be considered a simple getter, only a return statement must be present, 42 | // and that return statement must contain a simple expression (a reference or a literal) 43 | // Valid examples are: 44 | // return a; 45 | // return a.b; 46 | // return a.b.c.d.e.f.length; 47 | val innerStatementsCount = jsBlockStatement.children.count { 48 | it !is LeafPsiElement && 49 | it !is JSEmptyStatement && 50 | it !is PsiWhiteSpace 51 | } 52 | 53 | if (innerStatementsCount != 1) { 54 | // There are other statements in addition to the return one 55 | return true 56 | } 57 | 58 | ProgressManager.checkCanceled() 59 | 60 | val nonEmptyExpressions = jsReturnStatement.children.filter { 61 | it !is JSEmptyStatement && it !is PsiWhiteSpace 62 | } 63 | 64 | return when { 65 | nonEmptyExpressions.isEmpty() -> false 66 | nonEmptyExpressions.size == 1 -> { 67 | val expression = nonEmptyExpressions[0] 68 | when { 69 | expression !is JSLiteralExpression && 70 | expression !is JSQualifiedExpression -> true 71 | else -> !containsOnlyReferences(expression) 72 | } 73 | } 74 | else -> true 75 | } 76 | } 77 | 78 | private fun containsOnlyReferences(psiElement: PsiElement) = 79 | PsiTreeUtil.findChildOfAnyType(psiElement, JSCallExpression::class.java) == null 80 | } 81 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/javascript/JavaScriptTopLevelHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.javascript 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult 4 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult.* 5 | import com.github.lppedd.highlighter.TopLevelReturnHighlightStrategy 6 | import com.intellij.lang.javascript.psi.* 7 | import com.intellij.lang.javascript.psi.ecmal4.JSClass 8 | import com.intellij.lang.javascript.psi.ecmal4.JSQualifiedNamedElement 9 | import com.intellij.openapi.progress.ProgressManager 10 | import com.intellij.psi.PsiElement 11 | import com.intellij.psi.util.PsiTreeUtil 12 | 13 | /** 14 | * @author Edoardo Luppi 15 | */ 16 | internal object JavaScriptTopLevelHighlightStrategy : TopLevelReturnHighlightStrategy() { 17 | override fun check(psiElement: PsiElement): PsiResult = 18 | when (psiElement) { 19 | is JSFunctionExpression -> checkJSFunctionExpression(psiElement) 20 | is JSFunction -> checkJSFunction(psiElement) 21 | else -> CONTINUE 22 | } 23 | 24 | private fun checkJSFunctionExpression(psiElement: JSFunctionExpression): PsiResult { 25 | // Function Expressions are valid only if immediately assigned 26 | // to a Class Field, when in Class scope 27 | val jsField = PsiTreeUtil.getParentOfType( 28 | psiElement, 29 | JSField::class.java, 30 | true, 31 | JSQualifiedNamedElement::class.java, 32 | JSFile::class.java 33 | ) 34 | 35 | if (jsField is JSField) { 36 | return VALID 37 | } 38 | 39 | ProgressManager.checkCanceled() 40 | 41 | // Or when directly assigned to a Module Variable. 42 | // Note: we need to ensure the Variable is really top-level (Module), 43 | // and this is done with the second isChildOf call 44 | val jsFile: JSFile? = PsiTreeUtil.getParentOfType( 45 | psiElement, 46 | JSVariable::class.java, 47 | true, 48 | JSQualifiedNamedElement::class.java 49 | )?.let { 50 | PsiTreeUtil.getParentOfType( 51 | it, 52 | JSFile::class.java, 53 | true, 54 | JSQualifiedNamedElement::class.java 55 | ) 56 | } 57 | 58 | return if (jsFile is JSFile) VALID else INVALID 59 | } 60 | 61 | private fun checkJSFunction(psiElement: JSFunction): PsiResult { 62 | // A return statement is valid inside a Function which is a direct 63 | // child of a Class, or a Module (file). 64 | val parent: PsiElement? = psiElement.parent 65 | val isParentValid = parent is JSClass || parent is JSFile 66 | return if (isParentValid) VALID else INVALID 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/php/PhpAlwaysHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.php 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 4 | import com.jetbrains.php.lang.psi.elements.PhpReturn 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | internal object PhpAlwaysHighlightStrategy : ReturnHighlightStrategy { 10 | override fun isValidContext(psiElement: PhpReturn) = true 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/php/PhpReturnAnnotator.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.php 2 | 3 | import com.jetbrains.php.lang.psi.elements.PhpReturn 4 | import com.github.lppedd.highlighter.AbstractReturnAnnotator as ARA 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | internal class PhpReturnAnnotator : ARA(PhpReturn::class.java) { 10 | private val config = PhpReturnHighlighterConfig.getInstance() 11 | 12 | override fun isValidContext(psiElement: PhpReturn) = 13 | config.getHighlightStrategy().isValidContext(psiElement) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/php/PhpReturnHighlighterConfig.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.php 2 | 3 | import com.github.lppedd.highlighter.Application 4 | import com.github.lppedd.highlighter.Constants 5 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 6 | import com.github.lppedd.highlighter.php.PhpReturnHighlighterConfig.PhpConfig 7 | import com.intellij.openapi.components.PersistentStateComponent 8 | import com.intellij.openapi.components.ServiceManager 9 | import com.intellij.openapi.components.State 10 | import com.intellij.openapi.components.Storage 11 | import com.jetbrains.php.lang.psi.elements.PhpReturn 12 | 13 | /** 14 | * @author Edoardo Luppi 15 | */ 16 | @State( 17 | name = "PHP", 18 | storages = [Storage(Constants.ISTORAGE_FILE)] 19 | ) 20 | internal class PhpReturnHighlighterConfig : PersistentStateComponent { 21 | companion object { 22 | fun getInstance(): PhpReturnHighlighterConfig = 23 | ServiceManager.getService(PhpReturnHighlighterConfig::class.java) 24 | } 25 | 26 | private var state = PhpConfig() 27 | private var highlightStrategy: ReturnHighlightStrategy = PhpAlwaysHighlightStrategy 28 | 29 | override fun getState(): PhpConfig = state.copy() 30 | override fun loadState(state: PhpConfig) { 31 | this.state = state 32 | updateCurrentHighlightStrategy() 33 | } 34 | 35 | fun setState(state: PhpConfig) { 36 | this.state = state 37 | updateCurrentHighlightStrategy() 38 | Application.refreshFiles() 39 | } 40 | 41 | fun getHighlightStrategy() = highlightStrategy 42 | 43 | private fun updateCurrentHighlightStrategy() { 44 | var highlightStrategy: ReturnHighlightStrategy = 45 | PhpAlwaysHighlightStrategy 46 | 47 | if (state.isOnlyTopLevelReturns) { 48 | highlightStrategy = PhpTopLevelHighlightStrategy 49 | } 50 | 51 | this.highlightStrategy = highlightStrategy 52 | } 53 | 54 | data class PhpConfig(var isOnlyTopLevelReturns: Boolean = false) 55 | } 56 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/php/PhpReturnHighlighterConfigurable.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.php 2 | 3 | import com.github.lppedd.highlighter.Constants 4 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 5 | import com.intellij.openapi.options.SearchableConfigurable 6 | import javax.swing.JComponent 7 | 8 | /** 9 | * @author Edoardo Luppi 10 | */ 11 | internal class PhpReturnHighlighterConfigurable : SearchableConfigurable { 12 | private val config = PhpReturnHighlighterConfig.getInstance() 13 | private val gui = PhpReturnHighlighterConfigurableGui(ReturnHighlighterBundle) 14 | 15 | override fun getId() = "preferences.${Constants.IAPP_NAME}.php" 16 | override fun getDisplayName() = ReturnHighlighterBundle["rh.settings.php"] 17 | 18 | override fun apply() { 19 | config.state = config.state.copy( 20 | isOnlyTopLevelReturns = gui.isOnlyTopLevelReturns 21 | ) 22 | } 23 | 24 | override fun reset() { 25 | gui.isOnlyTopLevelReturns = config.state.isOnlyTopLevelReturns 26 | } 27 | 28 | override fun isModified() = 29 | gui.isOnlyTopLevelReturns != config.state.isOnlyTopLevelReturns 30 | 31 | override fun createComponent(): JComponent? { 32 | gui.isOnlyTopLevelReturns = config.state.isOnlyTopLevelReturns 33 | return gui.rootPanel 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/php/PhpReturnLineMarkerProvider.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.php 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 4 | import com.jetbrains.php.lang.psi.elements.PhpReturn 5 | import com.github.lppedd.highlighter.AbstractReturnLineMarkerProvider as ARLMP 6 | 7 | /** 8 | * @author Edoardo Luppi 9 | */ 10 | internal class PhpReturnLineMarkerProvider : ARLMP(PhpReturn::class.java) { 11 | private val config = PhpReturnHighlighterConfig.getInstance() 12 | 13 | override fun getName() = ReturnHighlighterBundle["rh.settings.php"] 14 | override fun isValidContext(psiElement: PhpReturn) = 15 | config.getHighlightStrategy().isValidContext(psiElement) 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/php/PhpTopLevelHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.php 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult 4 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult.* 5 | import com.github.lppedd.highlighter.TopLevelReturnHighlightStrategy 6 | import com.intellij.openapi.progress.ProgressManager 7 | import com.intellij.psi.PsiElement 8 | import com.intellij.psi.util.PsiTreeUtil 9 | import com.jetbrains.php.lang.parser.PhpElementTypes 10 | import com.jetbrains.php.lang.psi.PhpFile 11 | import com.jetbrains.php.lang.psi.elements.* 12 | import com.jetbrains.php.lang.psi.elements.Function 13 | 14 | /** 15 | * @author Edoardo Luppi 16 | */ 17 | internal object PhpTopLevelHighlightStrategy : TopLevelReturnHighlightStrategy() { 18 | override fun check(psiElement: PsiElement): PsiResult = 19 | when (psiElement) { 20 | is PhpExpression -> checkExpression(psiElement) 21 | is Function -> checkFunction(psiElement) 22 | else -> CONTINUE 23 | } 24 | 25 | private fun checkExpression(psiExpression: PhpExpression): PsiResult { 26 | if (!isClosure(psiExpression)) return VALID 27 | if (psiExpression.parent !is AssignmentExpression) return INVALID 28 | 29 | val psiMethod = PsiTreeUtil.getParentOfType( 30 | psiExpression, 31 | Method::class.java, 32 | true, 33 | Function::class.java 34 | ) 35 | 36 | if (psiMethod?.name == "__construct") { 37 | return VALID 38 | } 39 | 40 | ProgressManager.checkCanceled() 41 | 42 | val phpFile = PsiTreeUtil.getParentOfType( 43 | psiExpression, 44 | GroupStatement::class.java, 45 | true, 46 | Function::class.java 47 | )?.parent 48 | 49 | return if (phpFile is PhpFile) VALID else INVALID 50 | } 51 | 52 | /** 53 | * A Function can be both a file Function and a class Method, 54 | * thus a return statement is valid inside a Function which is 55 | * a direct child of a Class, or a top-level statement group (). 56 | */ 57 | private fun checkFunction(psiFunction: Function): PsiResult { 58 | if (isClosure(psiFunction.parent)) { 59 | return CONTINUE 60 | } 61 | 62 | ProgressManager.checkCanceled() 63 | 64 | val psiClass = PsiTreeUtil.getParentOfType( 65 | psiFunction, 66 | PhpClass::class.java, 67 | true, 68 | Function::class.java 69 | ) 70 | 71 | if (psiClass != null) { 72 | return VALID 73 | } 74 | 75 | val parent: PsiElement? = psiFunction.parent 76 | val isParentValid = parent is GroupStatement && parent.parent is PhpFile 77 | return if (isParentValid) VALID else INVALID 78 | } 79 | 80 | private fun isClosure(psiElement: PsiElement) = 81 | psiElement is PhpExpression && psiElement.node.elementType == PhpElementTypes.CLOSURE 82 | } 83 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/python/PythonAlwaysHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.python 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 4 | import com.jetbrains.python.psi.PyReturnStatement 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | internal object PythonAlwaysHighlightStrategy : ReturnHighlightStrategy { 10 | override fun isValidContext(psiElement: PyReturnStatement) = true 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/python/PythonReturnAnnotator.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.python 2 | 3 | import com.jetbrains.python.psi.PyReturnStatement 4 | import com.github.lppedd.highlighter.AbstractReturnAnnotator as ARA 5 | 6 | /** 7 | * @author Edoardo Luppi 8 | */ 9 | internal class PythonReturnAnnotator : ARA(PyReturnStatement::class.java) { 10 | private val config = PythonReturnHighlighterConfig.getInstance() 11 | 12 | override fun isValidContext(psiElement: PyReturnStatement) = 13 | config.getHighlightStrategy().isValidContext(psiElement) 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/python/PythonReturnHighlighterConfig.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.python 2 | 3 | import com.github.lppedd.highlighter.Application 4 | import com.github.lppedd.highlighter.Constants 5 | import com.github.lppedd.highlighter.ReturnHighlightStrategy 6 | import com.github.lppedd.highlighter.python.PythonReturnHighlighterConfig.PythonConfig 7 | import com.intellij.openapi.components.PersistentStateComponent 8 | import com.intellij.openapi.components.ServiceManager 9 | import com.intellij.openapi.components.State 10 | import com.intellij.openapi.components.Storage 11 | import com.jetbrains.python.psi.PyReturnStatement 12 | 13 | /** 14 | * @author Edoardo Luppi 15 | */ 16 | @State( 17 | name = "Python", 18 | storages = [Storage(Constants.ISTORAGE_FILE)] 19 | ) 20 | internal class PythonReturnHighlighterConfig : PersistentStateComponent { 21 | companion object { 22 | fun getInstance(): PythonReturnHighlighterConfig = 23 | ServiceManager.getService(PythonReturnHighlighterConfig::class.java) 24 | } 25 | 26 | private var state = PythonConfig() 27 | private var highlightStrategy: ReturnHighlightStrategy = PythonAlwaysHighlightStrategy 28 | 29 | override fun getState(): PythonConfig = state.copy() 30 | override fun loadState(state: PythonConfig) { 31 | this.state = state 32 | updateCurrentHighlightStrategy() 33 | } 34 | 35 | fun setState(state: PythonConfig) { 36 | this.state = state 37 | updateCurrentHighlightStrategy() 38 | Application.refreshFiles() 39 | } 40 | 41 | fun getHighlightStrategy() = highlightStrategy 42 | 43 | private fun updateCurrentHighlightStrategy() { 44 | var highlightStrategy: ReturnHighlightStrategy = 45 | PythonAlwaysHighlightStrategy 46 | 47 | if (state.isOnlyTopLevelReturns) { 48 | highlightStrategy = PythonTopLevelHighlightStrategy 49 | } 50 | 51 | this.highlightStrategy = highlightStrategy 52 | } 53 | 54 | data class PythonConfig(var isOnlyTopLevelReturns: Boolean = false) 55 | } 56 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/python/PythonReturnHighlighterConfigurable.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.python 2 | 3 | import com.github.lppedd.highlighter.Constants 4 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 5 | import com.intellij.openapi.options.SearchableConfigurable 6 | import javax.swing.JComponent 7 | 8 | /** 9 | * @author Edoardo Luppi 10 | */ 11 | internal class PythonReturnHighlighterConfigurable : SearchableConfigurable { 12 | private val config = PythonReturnHighlighterConfig.getInstance() 13 | private val gui = PythonReturnHighlighterConfigurableGui(ReturnHighlighterBundle) 14 | 15 | override fun getId() = "preferences.${Constants.IAPP_NAME}.python" 16 | override fun getDisplayName() = ReturnHighlighterBundle["rh.settings.python"] 17 | 18 | override fun apply() { 19 | config.state = config.state.copy( 20 | isOnlyTopLevelReturns = gui.isOnlyTopLevelReturns 21 | ) 22 | } 23 | 24 | override fun reset() { 25 | gui.isOnlyTopLevelReturns = config.state.isOnlyTopLevelReturns 26 | } 27 | 28 | override fun isModified() = 29 | gui.isOnlyTopLevelReturns != config.state.isOnlyTopLevelReturns 30 | 31 | override fun createComponent(): JComponent? { 32 | gui.isOnlyTopLevelReturns = config.state.isOnlyTopLevelReturns 33 | return gui.rootPanel 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/python/PythonReturnLineMarkerProvider.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.python 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 4 | import com.jetbrains.python.psi.PyReturnStatement 5 | import com.github.lppedd.highlighter.AbstractReturnLineMarkerProvider as ARLMP 6 | 7 | /** 8 | * @author Edoardo Luppi 9 | */ 10 | internal class PythonReturnLineMarkerProvider : ARLMP(PyReturnStatement::class.java) { 11 | private val config = PythonReturnHighlighterConfig.getInstance() 12 | 13 | override fun getName() = ReturnHighlighterBundle["rh.settings.python"] 14 | override fun isValidContext(psiElement: PyReturnStatement) = 15 | config.getHighlightStrategy().isValidContext(psiElement) 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/python/PythonTopLevelHighlightStrategy.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.python 2 | 3 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult 4 | import com.github.lppedd.highlighter.ReturnHighlightStrategy.PsiResult.* 5 | import com.github.lppedd.highlighter.TopLevelReturnHighlightStrategy 6 | import com.intellij.psi.PsiElement 7 | import com.intellij.psi.PsiWhiteSpace 8 | import com.intellij.psi.util.PsiTreeUtil 9 | import com.jetbrains.python.psi.* 10 | 11 | /** 12 | * @author Edoardo Luppi 13 | */ 14 | internal object PythonTopLevelHighlightStrategy : TopLevelReturnHighlightStrategy() { 15 | override fun check(psiElement: PsiElement): PsiResult = 16 | when (psiElement) { 17 | is PyFunction -> checkFunction(psiElement) 18 | is PyReturnStatement -> checkReturnStatement(psiElement) 19 | else -> CONTINUE 20 | } 21 | 22 | /** 23 | * A return statement is valid inside a function which is a direct child 24 | * of a [PyFile] or [PyClass]. The class check is handled by [checkStatementList], 25 | * being that the PSI structure shows a class function is contained inside a [PyStatementList]. 26 | */ 27 | private fun checkFunction(pyFunction: PyFunction) = 28 | when (val parent = pyFunction.parent) { 29 | is PyFile -> VALID 30 | is PyStatementList -> checkStatementList(parent) 31 | else -> INVALID 32 | } 33 | 34 | private fun checkStatementList(pyStatementList: PyStatementList) = 35 | if (pyStatementList.parent is PyClass) VALID else INVALID 36 | 37 | /** 38 | * This check is meant to avoid highlighting the return keyword in case of grammar errors. 39 | * As of now it handles cases like: 40 | * 41 | * ``` 42 | * f = lambda x: return x + 1 43 | * ``` 44 | */ 45 | private fun checkReturnStatement(pyReturnStatement: PyReturnStatement) = 46 | PsiTreeUtil.skipSiblingsBackward(pyReturnStatement, PsiWhiteSpace::class.java)?.let { 47 | if (PsiTreeUtil.getChildOfType(it, PyLambdaExpression::class.java) != null) { 48 | INVALID 49 | } else { 50 | CONTINUE 51 | } 52 | } ?: CONTINUE 53 | } 54 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/settings/ReturnHighlighterColorSettingsPage.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.settings 2 | 3 | import com.github.lppedd.highlighter.AbstractReturnAnnotator 4 | import com.github.lppedd.highlighter.Icons 5 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 6 | import com.intellij.openapi.fileTypes.PlainSyntaxHighlighter 7 | import com.intellij.openapi.options.colors.AttributesDescriptor 8 | import com.intellij.openapi.options.colors.ColorDescriptor 9 | import com.intellij.openapi.options.colors.ColorSettingsPage 10 | import com.intellij.psi.codeStyle.DisplayPriority 11 | import com.intellij.psi.codeStyle.DisplayPrioritySortable 12 | 13 | /** 14 | * @author Edoardo Luppi 15 | */ 16 | internal class ReturnHighlighterColorSettingsPage : ColorSettingsPage, DisplayPrioritySortable { 17 | override fun getDisplayName() = ReturnHighlighterBundle["rh.app.presentableName"] 18 | override fun getIcon() = Icons.GUTTER_RETURN 19 | override fun getPriority() = DisplayPriority.COMMON_SETTINGS 20 | override fun getAttributeDescriptors() = 21 | arrayOf(AttributesDescriptor( 22 | ReturnHighlighterBundle["rh.settings.colors.attr.retKey"], 23 | AbstractReturnAnnotator.TAK_RETURN 24 | )) 25 | 26 | override fun getHighlighter() = PlainSyntaxHighlighter() 27 | override fun getColorDescriptors(): Array = ColorDescriptor.EMPTY_ARRAY 28 | override fun getDemoText() = ReturnHighlighterBundle["rh.settings.colors.demoText"] 29 | 30 | override fun getAdditionalHighlightingTagToDescriptorMap() = 31 | mapOf(Pair("return", AbstractReturnAnnotator.TAK_RETURN)) 32 | } 33 | -------------------------------------------------------------------------------- /src/main/kotlin/com/github/lppedd/highlighter/settings/ReturnHighlighterConfigurable.kt: -------------------------------------------------------------------------------- 1 | package com.github.lppedd.highlighter.settings 2 | 3 | import com.github.lppedd.highlighter.Constants 4 | import com.github.lppedd.highlighter.ReturnHighlighterBundle 5 | import com.intellij.ide.DataManager 6 | import com.intellij.openapi.options.Configurable 7 | import com.intellij.openapi.options.ConfigurableEP 8 | import com.intellij.openapi.options.SearchableConfigurable 9 | import com.intellij.openapi.options.ex.Settings 10 | import com.intellij.ui.components.JBLabel 11 | import com.intellij.ui.components.labels.LinkLabel 12 | import java.awt.Font 13 | import javax.swing.border.EmptyBorder 14 | 15 | /** 16 | * @author Edoardo Luppi 17 | */ 18 | internal class ReturnHighlighterConfigurable : SearchableConfigurable { 19 | private val noSupportedLanguage = 20 | JBLabel(ReturnHighlighterBundle["rh.settings.custom.global.noLang"]).apply { 21 | font = font.deriveFont(font.style or Font.BOLD) 22 | } 23 | 24 | private var gui = ReturnHighlighterConfigurableGui() 25 | 26 | init { 27 | Configurable.APPLICATION_CONFIGURABLE.extensionList 28 | .filter { it.id?.startsWith("preferences.${Constants.IAPP_NAME}.") ?: false } 29 | .map { 30 | val language = it.id.split(".")[2] 31 | val text = ReturnHighlighterBundle["rh.settings.$language"] 32 | LinkLabel.create(text, buildRunnable(it)).apply { 33 | alignmentX = 0f 34 | border = EmptyBorder(1, 1, 3, 1) 35 | } 36 | } 37 | .ifEmpty { listOf(noSupportedLanguage) } 38 | .forEach { gui.listPanel.add(it) } 39 | } 40 | 41 | override fun getId() = "preferences.${Constants.IAPP_NAME}" 42 | override fun getDisplayName() = ReturnHighlighterBundle["rh.app.presentableName"] 43 | override fun isModified() = false 44 | override fun apply() = Unit 45 | override fun createComponent() = gui.rootPanel 46 | 47 | private fun buildRunnable(configurableEP: ConfigurableEP): () -> Unit = 48 | { 49 | val settings = Settings.KEY.getData(DataManager.getInstance().getDataContext(gui.rootPanel)) 50 | val configurable = settings?.find(configurableEP.id) 51 | settings?.select(configurable) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/java.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/javascript.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 18 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/php.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | com.github.lppedd.idea-return-highlighter 3 | Return Highlighter 4 | 6 | Edoardo Luppi 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | com.intellij.modules.platform 23 | com.intellij.java 24 | JavaScript 25 | Pythonid 26 | com.jetbrains.php 27 | 28 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/pluginIcon.svg: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 19 | 23 | 29 | 34 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/pluginIcon_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 19 | 23 | 29 | 34 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/python.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/resources/colorSchemes/return-highlighter-default-darcula.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/resources/colorSchemes/return-highlighter-default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/resources/icons/return.svg: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 19 | 23 | 29 | 34 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/main/resources/icons/return_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 8 | 12 | 19 | 23 | 29 | 34 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/main/resources/messages/ReturnHighlighterBundle.properties: -------------------------------------------------------------------------------- 1 | rh.app.presentableName=Return Highlighter 2 | 3 | rh.gutter.text=Return statement 4 | 5 | rh.settings.java=Java 6 | rh.settings.javascript=JavaScript and TypeScript 7 | rh.settings.php=PHP 8 | rh.settings.python=Python 9 | 10 | rh.settings.colors.attr.retKey=Return keyword 11 | rh.settings.colors.demoText=\ 12 | final String value = getValue();\n\ 13 | return value; 14 | 15 | rh.settings.custom.global=Configure highlighting for specific languages. 16 | rh.settings.custom.global.noLang=No supported languages found in your environment. 17 | 18 | rh.settings.custom.java=Configure highlighting for Java. 19 | rh.settings.custom.java.topLevel=Only top-level return keywords 20 | rh.settings.custom.java.simpleGetters=Skip simple getters 21 | rh.settings.custom.java.simpleGetters.tooltip=\ 22 |

\ 23 | Examples of simple getters:\ 24 |

\ 25 |
\ 26 |
\
27 |   \u0020boolean isEnabled() {
\ 28 | \u0020\u0020\u0020return true;
\ 29 | \u0020}
\ 30 |
\ 31 | \u0020Long getId() {
\ 32 | \u0020\u0020\u0020return myField.id;
\ 33 | \u0020}\ 34 |
35 | 36 | rh.settings.custom.javascript=Configure highlighting for JavaScript and TypeScript. 37 | rh.settings.custom.javascript.topLevel=Only top-level return keywords 38 | rh.settings.custom.javascript.simpleGetters=Skip simple getters 39 | rh.settings.custom.javascript.simpleGetters.tooltip=\ 40 |

\ 41 | Examples of simple getters:\ 42 |

\ 43 |
\ 44 |
\
45 |   \u0020isEnabled(): boolean {
\ 46 | \u0020\u0020\u0020return true;
\ 47 | \u0020}
\ 48 |
\ 49 | \u0020get id(): number {
\ 50 | \u0020\u0020\u0020return myField.id;
\ 51 | \u0020}\ 52 |
53 | 54 | rh.settings.custom.php=Configure highlighting for PHP. 55 | rh.settings.custom.php.topLevel=Only top-level return keywords 56 | 57 | rh.settings.custom.python=Configure highlighting for Python. 58 | rh.settings.custom.python.topLevel=Only top-level return keywords 59 | -------------------------------------------------------------------------------- /src/main/resources/messages/ReturnHighlighterBundle_it_IT.properties: -------------------------------------------------------------------------------- 1 | rh.settings.javascript=JavaScript e TypeScript 2 | 3 | rh.settings.custom.noOptionsAvailable=Nessuna opzione disponibile al momento. 4 | 5 | rh.settings.custom.global=Configura l'evidenziazione per linguaggio specifico. 6 | rh.settings.custom.global.noLang=Nessun linguaggio supportato trovato nell'ambiente. 7 | 8 | rh.settings.custom.java=Configura l'evidenziazione per Java. 9 | rh.settings.custom.java.topLevel=Solo keyword return top-level 10 | rh.settings.custom.java.simpleGetters=Salta funzioni semplici 11 | rh.settings.custom.java.simpleGetters.tooltip=\ 12 |

\ 13 | Esempi di funzioni semplici:\ 14 |

\ 15 |
\ 16 |
\
17 |   \u0020boolean isEnabled() {
\ 18 | \u0020\u0020\u0020return true;
\ 19 | \u0020}
\ 20 |
\ 21 | \u0020Long getId() {
\ 22 | \u0020\u0020\u0020return myField.id;
\ 23 | \u0020}\ 24 |
25 | 26 | 27 | rh.settings.custom.javascript=Configura l'evidenziazione per JavaScript e TypeScript. 28 | rh.settings.custom.javascript.topLevel=Solo keyword return top-level 29 | rh.settings.custom.javascript.simpleGetters=Salta funzioni semplici 30 | rh.settings.custom.javascript.simpleGetters.tooltip=\ 31 |

\ 32 | Esempi di funzioni semplici:\ 33 |

\ 34 |
\ 35 |
\
36 |   \u0020isEnabled(): boolean {
\ 37 | \u0020\u0020\u0020return true;
\ 38 | \u0020}
\ 39 |
\ 40 | \u0020get id(): number {
\ 41 | \u0020\u0020\u0020return myField.id;
\ 42 | \u0020}\ 43 |
44 | 45 | rh.settings.custom.php=Configura l'evidenziazione per PHP. 46 | rh.settings.custom.php.topLevel=Solo keyword return top-level 47 | 48 | rh.settings.custom.python=Configura l'evidenziazione per Python. 49 | rh.settings.custom.python.topLevel=Solo keyword return top-level 50 | --------------------------------------------------------------------------------