├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE.md ├── .gitignore ├── .idea └── icon.png ├── .run ├── EclipseCodeFormatter [buildPlugin].run.xml └── EclipseCodeFormatter [runIde].run.xml ├── CHANGELOG.md ├── EclipseAdapter ├── EclipseAdapter.iml └── src │ └── krasa │ └── formatter │ └── adapter │ └── EclipseJavaFormatterAdapter.java ├── EclipseFormatter.iml ├── EclipseFormatter.ipr ├── LICENSE.txt ├── README.markdown ├── build.gradle.kts ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lib ├── bare-bones-browser-launch-3.1.jar ├── batik-ext-1.11.jar └── eclipse │ ├── EPL-2.0.html │ ├── README.md │ ├── adapter.jar │ ├── eclipse-sources.jar │ └── eclipse.jar ├── settings.gradle.kts ├── src ├── main │ ├── java │ │ └── krasa │ │ │ └── formatter │ │ │ ├── Messages.java │ │ │ ├── Resources.java │ │ │ ├── action │ │ │ ├── ChangeFormatterToolbarAction.java │ │ │ └── QuickChangeCodeFormatterAction.java │ │ │ ├── common │ │ │ └── ModifiableFile.java │ │ │ ├── eclipse │ │ │ ├── Classloaders.java │ │ │ ├── CodeFormatterFacade.java │ │ │ ├── ConfigFileLocator.java │ │ │ ├── ConfigurableEclipseLocation.java │ │ │ ├── EclipseFormatterAdapter.java │ │ │ ├── JavaCodeFormatterFacade.java │ │ │ └── ParentLastURLClassLoader.java │ │ │ ├── exception │ │ │ ├── FileDoesNotExistsException.java │ │ │ ├── FormattingFailedException.java │ │ │ ├── InvalidSettingsException.java │ │ │ └── ParsingFailedException.java │ │ │ ├── plugin │ │ │ ├── DelegatingCodeStyleManager.java │ │ │ ├── Donate.java │ │ │ ├── EclipseCodeFormatter.java │ │ │ ├── EclipseCodeStyleManager.java │ │ │ ├── EclipseCodeStyleManager_IJ_2016_3plus.java │ │ │ ├── EclipseImportOptimizer.java │ │ │ ├── ImportSorterAdapter.java │ │ │ ├── ImportSorterException.java │ │ │ ├── ImportsComparator.java │ │ │ ├── ImportsSorter.java │ │ │ ├── ImportsSorter450.java │ │ │ ├── ImportsSorter452.java │ │ │ ├── InvalidPropertyFile.java │ │ │ ├── ManualCodeStyleManagerDelegator.java │ │ │ ├── Mode.java │ │ │ ├── Notifier.java │ │ │ ├── ProjectCodeStyleInstaller.java │ │ │ ├── ProjectSettingsForm.form │ │ │ ├── ProjectSettingsForm.java │ │ │ ├── ProxyCodeStyleManagerDelegator.java │ │ │ ├── ProxyUtils.java │ │ │ ├── Range.java │ │ │ └── ReformatItInIntelliJ.java │ │ │ ├── processor │ │ │ └── Processor.java │ │ │ ├── settings │ │ │ ├── DeletedProfileException.java │ │ │ ├── DisabledFileTypeSettings.java │ │ │ ├── GlobalProfileReference.java │ │ │ ├── GlobalSettings.java │ │ │ ├── IllegalSettingsException.java │ │ │ ├── MyConfigurable.java │ │ │ ├── MyConfigurableProvider.java │ │ │ ├── ProjectComponent.java │ │ │ ├── ProjectSettings.java │ │ │ ├── ProjectSpecificProfile.java │ │ │ ├── Settings.java │ │ │ └── provider │ │ │ │ ├── CachedPropertiesProvider.java │ │ │ │ ├── CachedProvider.java │ │ │ │ ├── ImportOrderProvider.java │ │ │ │ └── JavaPropertiesProvider.java │ │ │ ├── templates │ │ │ └── LiveTemplatesProvider.java │ │ │ └── utils │ │ │ ├── FileUtils.java │ │ │ ├── ProjectUtils.java │ │ │ └── StringUtils.java │ └── resources │ │ ├── META-INF │ │ └── plugin.xml │ │ ├── krasa │ │ └── formatter │ │ │ ├── IDEA.png │ │ │ ├── IDEA@2x.png │ │ │ ├── coins_in_hand.png │ │ │ ├── coins_in_hand@2x.png │ │ │ ├── donate.png │ │ │ ├── eclipse.png │ │ │ ├── eclipse@2x.png │ │ │ ├── help.png │ │ │ ├── help@2x.png │ │ │ └── messages.properties │ │ └── liveTemplates │ │ └── templates.xml └── test │ ├── java │ └── krasa │ │ ├── easymock │ │ ├── EasyMockTest.java │ │ ├── MockAnnotationUtil.java │ │ └── Mocked.java │ │ └── formatter │ │ ├── Version.java │ │ ├── eclipse │ │ ├── ConfigurableEclipseLocationTest.java │ │ ├── JavaCodeFormatterFacadeTest.java │ │ ├── PlatformFormatterTest.java │ │ └── TestUtils.java │ │ ├── plugin │ │ ├── ImportsSorter450Test.java │ │ └── ImportsSorter452Test.java │ │ ├── settings │ │ ├── DisabledFileTypeSettingsTest.java │ │ └── provider │ │ │ ├── CachedProviderTest.java │ │ │ └── ImportOrderProviderTest.java │ │ └── utils │ │ ├── FileUtilsTest.java │ │ └── StringUtilsTest.java │ ├── resources │ ├── Formatter_20160606.xml │ ├── Strata-Eclipse-Preferences.epf │ ├── bcjur2.importorder │ ├── cpp.xml │ ├── eclipse.importorder │ ├── example │ │ └── Example.java │ ├── format.xml │ ├── format2.xml │ ├── invalidFormat.xml │ ├── issue104.importorder │ ├── issue130.importorder │ ├── issue130.prefs │ ├── jsConfigWithJsDocFormatting.prefs │ ├── kuk.js │ ├── mechanic-formatter.epf │ ├── org.eclipse.cdt.core.prefs │ ├── org.eclipse.jdt.core.prefs │ ├── org.eclipse.jdt.core_DEFAULT.prefs │ ├── org.eclipse.wst.jsdt.core.prefs │ ├── test.js │ └── unitils-default.properties │ └── test.iml ├── support ├── DependencyDownloader │ └── pom.xml ├── README ├── eclipseLibs │ ├── eclipse.iml │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── adapter │ │ └── e45 │ │ └── Dependencies.java └── pom.xml └── testProject ├── .settings └── org.eclipse.jdt.core.prefs ├── krasa.formattertest.iml ├── pom.xml ├── src └── main │ └── java │ ├── ImportTest.java │ ├── aaa │ └── XAAA.java │ ├── bar │ └── foo │ │ └── XBAR.java │ ├── base │ └── LoadUnitTestDataTestCase.java │ ├── comtrollers │ └── deadbolt │ │ └── Restrict.java │ ├── controllers │ └── deadbolt │ │ └── Restricts.java │ ├── foo │ └── bar │ │ └── XFOO.java │ ├── importorder │ └── example │ │ ├── Main.java │ │ ├── Main2.java │ │ ├── Main3.java │ │ └── root │ │ ├── AAAA.java │ │ ├── Aa │ │ └── AFoo.java │ │ ├── Aaa │ │ └── AaaFoo.java │ │ ├── BFoo.java │ │ ├── Bb │ │ └── bb.java │ │ ├── DFoo.java │ │ ├── aB │ │ └── Ab.java │ │ ├── aaa.java │ │ ├── ba │ │ └── ba.java │ │ └── bc │ │ └── bc.java │ ├── javax │ └── Javax.java │ ├── mockit │ └── MockUp.java │ ├── models │ └── Deployment.java │ ├── org │ └── jingle │ │ └── mocquer │ │ └── MockControl.java │ ├── play │ ├── jobs │ │ └── Job.java │ └── mvc │ │ └── Before.java │ └── tmplatform │ ├── authorisation │ └── ApiClientLink.java │ └── comms │ └── common │ └── caaa │ └── EvasLdapInterfaceProfileWrapper.java ├── submodule-a ├── pom.xml ├── src │ └── main │ │ └── java │ │ └── aaa │ │ └── XAAA.java └── submodule-a.iml ├── submodule-b ├── mechanic-formatter.epf ├── pom.xml ├── src │ └── main │ │ └── java │ │ └── bbb │ │ └── XBBB.java └── submodule-b.iml └── testProject.iml /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [krasa] 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | > If the formating is different than expected: 2 | > - make sure you are comparing with the same Eclipse version 3 | > - provide a code example (both from Eclipse and from IntelliJ) and settings files 4 | 5 | > What steps will reproduce the issue? 6 | 7 | > What is the expected result? 8 | 9 | > What happens instead? 10 | 11 | > Сonsider attaching a screenshot, screencast, or a code sample when it's hard to articulate the problem. 12 | 13 | > Paste information about IDE and OS (it can be copied from Help | About dialog). 14 | 15 | > Please use triple backticks ``` before and after the stacktrace block. 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.gradle 2 | **/build 3 | **/out 4 | **/target 5 | *.iws 6 | *.ipr 7 | *.zip 8 | .shelf 9 | .idea 10 | -------------------------------------------------------------------------------- /.idea/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/.idea/icon.png -------------------------------------------------------------------------------- /.run/EclipseCodeFormatter [buildPlugin].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | true 20 | false 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /.run/EclipseCodeFormatter [runIde].run.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 16 | 18 | true 19 | true 20 | false 21 | false 22 | 23 | 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [Unreleased] 4 | 5 | ## [23.5.241.000.0-Eclipse_2024-09] - 2024-09-24 6 | Bundled Eclipse 2024-09 7 | 8 | [Unreleased]: https://github.com/krasa/EclipseCodeFormatter/compare/v23.5.241.000.0-Eclipse_2024-09...HEAD 9 | [23.5.241.000.0-Eclipse_2024-09]: https://github.com/krasa/EclipseCodeFormatter/commits/v23.5.241.000.0-Eclipse_2024-09 10 | -------------------------------------------------------------------------------- /EclipseAdapter/EclipseAdapter.iml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /EclipseAdapter/src/krasa/formatter/adapter/EclipseJavaFormatterAdapter.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.adapter; 2 | 3 | import krasa.formatter.eclipse.EclipseFormatterAdapter; 4 | import krasa.formatter.exception.FileDoesNotExistsException; 5 | import krasa.formatter.exception.FormattingFailedException; 6 | import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; 7 | import org.eclipse.jface.text.BadLocationException; 8 | import org.eclipse.jface.text.Document; 9 | import org.eclipse.jface.text.IDocument; 10 | import org.eclipse.text.edits.TextEdit; 11 | 12 | import java.util.Map; 13 | 14 | @SuppressWarnings("Duplicates") 15 | public class EclipseJavaFormatterAdapter extends EclipseFormatterAdapter { 16 | protected DefaultCodeFormatter defaultCodeFormatter; 17 | 18 | @SuppressWarnings("unused") 19 | public EclipseJavaFormatterAdapter(Map options) { 20 | defaultCodeFormatter = new DefaultCodeFormatter(options); 21 | } 22 | 23 | @Override 24 | public String format(int kind, String text, int startOffset, int length, int indentationLevel, String lineSeparator, String languageLevel) 25 | throws FileDoesNotExistsException { 26 | 27 | IDocument doc = new Document(); 28 | try { 29 | doc.set(text); 30 | /** 31 | * Format source, and returns a text edit that correspond to the difference between the given 32 | * string and the formatted string. 33 | *

34 | * It returns null if the given string cannot be formatted. 35 | *

36 | *

37 | * If the offset position is matching a whitespace, the result can include whitespaces. It would be up to 38 | * the caller to get rid of preceding whitespaces. 39 | *

40 | * 41 | * @param kind 42 | * Use to specify the kind of the code snippet to format. It can be any of these: 43 | * 56 | * @param source 57 | * the source to format 58 | * @param offset 59 | * the given offset to start recording the edits (inclusive). 60 | * @param length 61 | * the given length to stop recording the edits (exclusive). 62 | * @param indentationLevel 63 | * the initial indentation level, used to shift left/right the entire source fragment. An initial 64 | * indentation level of zero or below has no effect. 65 | * @param lineSeparator 66 | * the line separator to use in formatted source, if set to null, then the platform 67 | * default one will be used. 68 | * @return the text edit 69 | * @throws IllegalArgumentException 70 | * if offset is lower than 0, length is lower than 0 or length is greater than source length. 71 | */ 72 | 73 | TextEdit edit = defaultCodeFormatter.format(kind, text, startOffset, length, indentationLevel, lineSeparator); 74 | if (edit != null) { 75 | edit.apply(doc); 76 | } else { 77 | throw new FormattingFailedException(getErrorMessage(languageLevel)); 78 | } 79 | return doc.get(); 80 | } catch (IndexOutOfBoundsException e) { 81 | throw new FormattingFailedException(e, getErrorMessage(languageLevel)); 82 | } catch (BadLocationException e) { 83 | throw new RuntimeException(e); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /EclipseFormatter.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # Adapter for Eclipse Code Formatter [![Donate][badge-paypal-img]][badge-paypal] 2 | 3 | Allows using Eclipse's Java code formatter directly from IntelliJ. Solves the problem of maintaining a common code style 4 | in team environments where both IDEA and Eclipse are used. 5 | 6 | ***Note:*** This project utilizes (and in some manners modifies) code licensed under [EPL-2.0](https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html). For more information see [lib/eclipse](lib/eclipse/README.md). 7 | 8 | --- 9 | 10 | ## Instructions 11 | 12 | 1. Install the plugin 13 | - [Tutorial: Installing, Updating and Uninstalling Repository Plugins](http://www.jetbrains.com/idea/webhelp/installing-updating-and-uninstalling-repository-plugins.html) 14 | - [Plugin repository page](http://plugins.jetbrains.com/plugin/?idea&id=6546) 15 | 2. Configure it 16 | 1. Configure Eclipse location (optional) 17 | - Install Eclipse 18 | - Got To IntelliJ Settings | Other Settings | Adapter for Eclipse Code Formatter 19 | - Set `Eclipse installation folder` (`/Users/xxx/Eclipse.app/Contents/Eclipse` for Mac) 20 | - Change `Java formatter version` to `Configured Eclipse installation folder` 21 | 2. Configure formatter 22 | - Either, export formatter profiles to get a `*.xml` file 23 | 1. Go to `Eclipse | Windows | Preferences | Java | Code Style | Formatter` 24 | 2. Eclipse does not export default profiles, so you have to make your own via the `New` button 25 | 3. Export the profile via the `Export all...` button 26 | - The result should look 27 | like [this](https://github.com/krasa/EclipseCodeFormatter/blob/master/test/resources/format.xml) 28 | 29 | - Or, enable project specific formatter settings to get `org.eclipse.jdt.core.prefs` 30 | 1. With your project open in Eclipse's workspace, `right-click` the project and choose Properties 31 | 2. Go to `Java Code Style | Formatter` and select `Enable project specific settings` 32 | 3. Click `OK` to save the settings 33 | 4. Go to the `.settings` directory inside your project's directory. There you will find 34 | the `org.eclipse.jdt.core.prefs` file which contains the Eclipse formatter settings 35 | - The result should look 36 | like [this](https://github.com/krasa/EclipseCodeFormatter/blob/master/test/resources/org.eclipse.jdt.core.prefs) 37 | - Or, export a [Workspace Mechanic](http://marketplace.eclipse.org/content/workspace-mechanic/) configuration to 38 | get a `*.epf` file 39 | - The result should look 40 | like [this](https://github.com/krasa/EclipseCodeFormatter/blob/master/test/resources/mechanic-formatter.epf) 41 | 42 | - Open a project in IntelliJ 43 | - Set path to the config file 44 | via `IntelliJ | Settings | Other Settings | Adapter for Eclipse Code Formatter | Eclipse preference file` 45 | - When using exported profiles (the xml file), select desired profile in the combobox `Java formatter profile` 46 | 3. Check `Optimizing Imports` configuration 47 | - Set import order 48 | - Either, leave the default 49 | - Or, set path to Eclipse configuration file: 50 | - Go to `Eclipse | Windows | Preferences | Java | Code Style | Organize Imports` 51 | - Either, click on `Export...` 52 | , ([example](https://github.com/krasa/EclipseCodeFormatter/blob/master/test/resources/bcjur2.importorder)) 53 | - Or, enable project specific settings and use `org.eclipse.jdt.ui.prefs` file which should contain 54 | the line `org.eclipse.jdt.ui.importorder=...` 55 | - Set the value of `Class count to use import with` and `Name count to use static import with` 56 | in `Settings | Editor | Code Style | Java | Imports` for Idea 14 or `Settings | Editor | Code Style | Imports` 57 | for older Idea. Eclipse uses 99 by default 58 | - For versions lower than 4.0 - make sure to disable IntelliJ's `Import Optimizing` in the reformat dialog 59 | via `Settings | Editor | Show "Reformat Code" dialog`. The plugin will take care of imports anyway 60 | - For versions higher than 4.0 - imports will be reordered together with normal IntelliJ's import optimizing 61 | - **Disable `Optimize imports on the fly`** 62 | 3. Format code as usual, notice the green bubble notification about successful formatting 63 | - notifications can be disabled at `Settings | Notifications` 64 | 4. Use `Ctrl + Alt + O` as usual, it will use this plugin 65 | 5. Use `Ctrl + ~` for quick switch between formatters or icon at the main toolbar 66 | 6. [Give it 5 stars](http://plugins.jetbrains.com/plugin/?idea&id=6546) 67 | 7. [Make a donation](https://www.paypal.me/VojtechKrasa) 68 | 69 | ## Possible problems with Java formatting 70 | - `@formatter:off` is not working 71 | See: https://github.com/krasa/EclipseCodeFormatter/issues/64 72 | - Nothing was formatted or formatting failed 73 | - Make sure you are using proper language level in `Main Menu | File | Project Structure` 74 | - Trailing spaces inside javadocs are stripped 75 | - Set `Strip trailing spaces on save` to `None` 76 | - File is formatted differently 77 | - The file is actually formatted fine, it just looks different in the editor, as the tab size and indendation are set differently in IntelliJ in `Settings | Editor | Code Style | Java` than in Eclipse. Using of either tab only or space only whitespace is recommended. 78 | - Or it is a bug 79 | - Eclipse indendation is configured for 2 spaces, but a new line gets indented by 4 spaces when Enter is pressed. 80 | - Change code style in IntelliJ. Not all things get formatted by this plugin when you type them. 81 | - If nothing helps 82 | - [check old issues](/issues) 83 | - Create a new issue [here](/issues/new) 84 | 85 | # Troubleshooting 86 | If it is mysteriously not working, go to `Main Menu | Help | Edit Debug Settings` and add: 87 | ``` 88 | krasa.formatter 89 | ```` 90 | Try to reformat something and [create a new issue](https://github.com/krasa/eclipse-code-formatter-intellij-plugin/issues/new), including the log 91 | 92 | 93 | 94 | ------ 95 | ![YourKit-Logo](https://www.yourkit.com/images/yklogo.png) 96 | 97 | YourKit supports open source projects with its full-featured Java Profiler. 98 | YourKit, LLC is the creator of [YourKit Java Profiler](https://www.yourkit.com/java/profiler/) 99 | and [YourKit .NET Profiler](https://www.yourkit.com/.net/profiler/), 100 | innovative and intelligent tools for profiling Java and .NET applications. 101 | 102 | 103 | 104 | [badge-paypal-img]: https://img.shields.io/badge/donate-paypal-green.svg 105 | [badge-paypal]: https://www.paypal.me/VojtechKrasa 106 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("HardCodedStringLiteral") 2 | 3 | import org.jetbrains.changelog.Changelog 4 | 5 | fun properties(key: String) = providers.gradleProperty(key) 6 | fun environment(key: String) = providers.environmentVariable(key) 7 | fun Jar.patchManifest() = manifest { attributes("Version" to project.version) } 8 | 9 | plugins { 10 | id("java") // Java support 11 | alias(libs.plugins.kotlin) 12 | alias(libs.plugins.gradleIntelliJPlugin) // Gradle IntelliJ Plugin 13 | alias(libs.plugins.changelog) // Gradle Changelog Plugin 14 | } 15 | 16 | group = properties("pluginGroup").get() 17 | version = properties("pluginVersion").get() 18 | 19 | // Configure project's dependencies 20 | repositories { 21 | mavenCentral() 22 | maven { 23 | url = uri("https://cache-redirector.jetbrains.com/intellij-dependencies") 24 | } 25 | } 26 | 27 | dependencies { 28 | 29 | // https://mvnrepository.com/artifact/org.easymock/easymock 30 | testImplementation("org.easymock:easymock:5.1.0") 31 | 32 | implementation( 33 | files( 34 | "lib/eclipse/adapter.jar", 35 | "lib/eclipse/eclipse.jar", 36 | "lib/bare-bones-browser-launch-3.1.jar", 37 | "lib/batik-ext-1.11.jar" 38 | ) 39 | ) 40 | 41 | 42 | // https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils 43 | implementation("commons-beanutils:commons-beanutils:1.9.4") 44 | 45 | // https://mvnrepository.com/artifact/commons-io/commons-io 46 | implementation("commons-io:commons-io:2.11.0") 47 | 48 | // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 49 | implementation("org.apache.commons:commons-lang3:3.14.0") 50 | 51 | } 52 | 53 | 54 | kotlin { 55 | jvmToolchain(17) 56 | } 57 | 58 | // Configure Gradle IntelliJ Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html 59 | intellij { 60 | pluginName = properties("pluginName") 61 | version = properties("platformVersion") 62 | type = properties("platformType") 63 | 64 | // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file. 65 | plugins = properties("platformPlugins").map { it.split(',').map(String::trim).filter(String::isNotEmpty) } 66 | } 67 | 68 | 69 | // Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin 70 | changelog { 71 | groups.empty() 72 | repositoryUrl = properties("pluginRepositoryUrl") 73 | } 74 | 75 | 76 | 77 | tasks { 78 | buildSearchableOptions { 79 | enabled = false 80 | } 81 | compileJava { 82 | options.encoding = "UTF-8" 83 | } 84 | compileTestJava { 85 | options.encoding = "UTF-8" 86 | } 87 | 88 | wrapper { 89 | gradleVersion = properties("gradleVersion").get() 90 | } 91 | 92 | patchPluginXml { 93 | version = properties("pluginVersion") 94 | sinceBuild = properties("pluginSinceBuild") 95 | untilBuild = properties("pluginUntilBuild") 96 | 97 | // // Extract the section from README.md and provide for the plugin's manifest 98 | // pluginDescription = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map { 99 | // val start = "" 100 | // val end = "" 101 | // 102 | // with (it.lines()) { 103 | // if (!containsAll(listOf(start, end))) { 104 | // throw GradleException("Plugin description section not found in README.md:\n$start ... $end") 105 | // } 106 | // subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML) 107 | // } 108 | // } 109 | 110 | val changelog = project.changelog // local variable for configuration cache compatibility 111 | // Get the latest available change notes from the changelog file 112 | changeNotes = properties("pluginVersion").map { pluginVersion -> 113 | with(changelog) { 114 | renderItem( 115 | (getOrNull(pluginVersion) ?: getUnreleased()) 116 | .withHeader(false) 117 | .withEmptySections(false), 118 | Changelog.OutputType.HTML, 119 | ) 120 | } 121 | } 122 | } 123 | 124 | // Set the JVM compatibility versions 125 | withType { 126 | sourceCompatibility = "17" 127 | targetCompatibility = "17" 128 | } 129 | 130 | 131 | signPlugin { 132 | certificateChain = environment("CERTIFICATE_CHAIN") 133 | privateKey = environment("PRIVATE_KEY") 134 | password = environment("PRIVATE_KEY_PASSWORD") 135 | } 136 | 137 | publishPlugin { 138 | dependsOn("patchChangelog") 139 | token = environment("PUBLISH_TOKEN") 140 | // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3 141 | // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more: 142 | // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel 143 | // channels = properties("pluginVersion").map { listOf(it.split('-').getOrElse(1) { "default" }.split('.').first()) } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html 2 | pluginGroup=EclipseCodeFormatter 3 | pluginName=EclipseFormatter 4 | pluginRepositoryUrl=https://github.com/krasa/EclipseCodeFormatter 5 | 6 | # SemVer format -> https://semver.org 7 | pluginVersion=23.5.241.000.0-Eclipse_2024-09 8 | 9 | # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html 10 | pluginSinceBuild=241.0 11 | pluginUntilBuild= 12 | 13 | # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension 14 | platformType=IC 15 | #platformVersion=2023.2 16 | platformVersion=LATEST-EAP-SNAPSHOT 17 | 18 | 19 | # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html 20 | # Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22 21 | platformPlugins=com.intellij.java 22 | # Gradle Releases -> https://github.com/gradle/gradle/releases 23 | gradleVersion=8.10.2 24 | # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib 25 | kotlin.stdlib.default.dependency=false 26 | # Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html 27 | org.gradle.configuration-cache=true 28 | # Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html 29 | org.gradle.caching=true 30 | # Enable Gradle Kotlin DSL Lazy Property Assignment -> https://docs.gradle.org/current/userguide/kotlin_dsl.html#kotdsl:assignment 31 | systemProp.org.gradle.unsafe.kotlin.assignment=true 32 | # Temporary workaround for Kotlin Compiler OutOfMemoryError -> https://jb.gg/intellij-platform-kotlin-oom 33 | kotlin.incremental.useClasspathSnapshot=false 34 | -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | # libraries 3 | annotations = "24.0.1" 4 | 5 | # plugins 6 | kotlin = "1.9.0" 7 | changelog = "2.1.2" 8 | gradleIntelliJPlugin = "1.17.0" 9 | qodana = "0.1.13" 10 | kover = "0.7.2" 11 | 12 | [libraries] 13 | annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations" } 14 | 15 | [plugins] 16 | changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } 17 | gradleIntelliJPlugin = { id = "org.jetbrains.intellij", version.ref = "gradleIntelliJPlugin" } 18 | kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } 19 | kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } 20 | qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/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.5-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/bare-bones-browser-launch-3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/lib/bare-bones-browser-launch-3.1.jar -------------------------------------------------------------------------------- /lib/batik-ext-1.11.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/lib/batik-ext-1.11.jar -------------------------------------------------------------------------------- /lib/eclipse/README.md: -------------------------------------------------------------------------------- 1 | This directory contains a repackaged version of [`org.eclipse.jdt.core`](https://www.eclipse.org/jdt/core/) (sources can be found [here](https://git.eclipse.org/c/jdt/eclipse.jdt.core.git/tree/org.eclipse.jdt.core)), which is licensed under [EPL-2.0](https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html). 2 | 3 | The original version was changed as follows: 4 | * It is repackaged together with all its dependencies into a single jar file ([`eclipse.jar`](eclipse.jar)) 5 | * From all modules, the `META-INF/*.SF`, `META-INF/*.DSA`, `META-INF/*.RSA` and `plugin.xml` are removed 6 | 7 | The "modified" source code can be found in [`eclipse-sources.jar`](eclipse-sources.jar). 8 | -------------------------------------------------------------------------------- /lib/eclipse/adapter.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/lib/eclipse/adapter.jar -------------------------------------------------------------------------------- /lib/eclipse/eclipse-sources.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/lib/eclipse/eclipse-sources.jar -------------------------------------------------------------------------------- /lib/eclipse/eclipse.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/lib/eclipse/eclipse.jar -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven("https://oss.sonatype.org/content/repositories/snapshots/") 4 | gradlePluginPortal() 5 | } 6 | } 7 | 8 | rootProject.name = "EclipseFormatter" 9 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/Messages.java: -------------------------------------------------------------------------------- 1 | /* 2 | * External Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the 3 | * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 4 | * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the 5 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 6 | * the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | package krasa.formatter; 10 | 11 | import com.intellij.CommonBundle; 12 | import krasa.formatter.settings.IllegalSettingsException; 13 | import org.jetbrains.annotations.NonNls; 14 | import org.jetbrains.annotations.PropertyKey; 15 | 16 | import java.lang.ref.Reference; 17 | import java.lang.ref.SoftReference; 18 | import java.util.ResourceBundle; 19 | 20 | /** 21 | * @author Esko Luontola 22 | * @since 18.12.2007 23 | */ 24 | public class Messages { 25 | 26 | @NonNls 27 | private static final String BUNDLE_NAME = "krasa.formatter.messages"; 28 | 29 | private static Reference bundle; 30 | 31 | private Messages() { 32 | } 33 | 34 | private static ResourceBundle getBundle() { 35 | ResourceBundle bundle = null; 36 | if (Messages.bundle != null) { 37 | bundle = Messages.bundle.get(); 38 | } 39 | if (bundle == null) { 40 | bundle = ResourceBundle.getBundle(BUNDLE_NAME); 41 | Messages.bundle = new SoftReference(bundle); 42 | } 43 | return bundle; 44 | } 45 | 46 | public static String message(@PropertyKey(resourceBundle = BUNDLE_NAME) String key, Object... params) { 47 | return CommonBundle.message(getBundle(), key, params); 48 | } 49 | 50 | public static String message(IllegalSettingsException e) { 51 | String field = message(e.getField()); 52 | String error = message(e.getErrorKey(), (Object[]) e.getErrorParams()); 53 | return message("error.errorInField", field, error); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/Resources.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Adapter for Eclipse Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the 3 | * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 4 | * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the 5 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 6 | * the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | package krasa.formatter; 10 | 11 | import java.net.URL; 12 | 13 | /** 14 | * Paths to program icons and other resources. 15 | * 16 | * @author Esko Luontola 17 | * @since 5.12.2007 18 | */ 19 | public class Resources { 20 | 21 | public static final URL PROGRAM_LOGO_16 = Resources.class.getResource("icons/logo-16.png"); 22 | public static final URL PROGRAM_LOGO_32 = Resources.class.getResource("icons/logo-32.png"); 23 | 24 | static { 25 | assert PROGRAM_LOGO_16 != null; 26 | assert PROGRAM_LOGO_32 != null; 27 | } 28 | 29 | private Resources() { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/action/ChangeFormatterToolbarAction.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.action; 2 | 3 | import com.intellij.openapi.actionSystem.ActionUpdateThread; 4 | import com.intellij.openapi.actionSystem.AnActionEvent; 5 | import com.intellij.openapi.actionSystem.Presentation; 6 | import com.intellij.openapi.diagnostic.Logger; 7 | import com.intellij.openapi.project.DumbAwareAction; 8 | import com.intellij.openapi.project.Project; 9 | import com.intellij.openapi.util.IconLoader; 10 | import krasa.formatter.settings.ProjectComponent; 11 | import krasa.formatter.settings.Settings; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | import javax.swing.*; 15 | 16 | /** 17 | * @author Vojtech Krasa 18 | */ 19 | public class ChangeFormatterToolbarAction extends DumbAwareAction { 20 | private static final Logger LOG = Logger.getInstance(ChangeFormatterToolbarAction.class.getName()); 21 | 22 | public static final Icon ECLIPSE = IconLoader.getIcon("/krasa/formatter/eclipse.png", ChangeFormatterToolbarAction.class); 23 | public static final Icon IDEA = IconLoader.getIcon("/krasa/formatter/IDEA.png", ChangeFormatterToolbarAction.class); 24 | 25 | @Override 26 | public void actionPerformed(AnActionEvent e) { 27 | Settings settings; 28 | Project project = e.getProject(); 29 | if (project != null) { 30 | ProjectComponent projectComponent = ProjectComponent.getInstance(project); 31 | settings = projectComponent.getSelectedProfile(); 32 | settings.setFormatter(Settings.Formatter.DEFAULT == settings.getFormatter() ? Settings.Formatter.ECLIPSE 33 | : Settings.Formatter.DEFAULT); 34 | projectComponent.installOrUpdate(settings); 35 | updateIcon(settings, e.getPresentation()); 36 | } 37 | } 38 | 39 | @Override 40 | public void update(AnActionEvent e) { 41 | super.update(e); 42 | try { 43 | final Settings settings = getSettings(e); 44 | if (settings != null) { 45 | updateIcon(settings, e.getPresentation()); 46 | } 47 | } catch (Throwable e1) { 48 | e.getPresentation().setEnabled(false); 49 | } 50 | 51 | } 52 | 53 | private void updateIcon(Settings state, Presentation presentation) { 54 | if (state.getFormatter() == Settings.Formatter.DEFAULT) { 55 | presentation.setIcon(IDEA); 56 | presentation.setDescription("Click to use Eclipse formatter"); 57 | } else { 58 | presentation.setIcon(ECLIPSE); 59 | presentation.setDescription("Click to use IntelliJ formatter"); 60 | } 61 | } 62 | 63 | private Settings getSettings(AnActionEvent e) { 64 | Settings settings = null; 65 | Project project = e.getProject(); 66 | if (project != null) { 67 | ProjectComponent instance = ProjectComponent.getInstance(project); 68 | settings = instance.getSelectedProfile(); 69 | } 70 | return settings; 71 | } 72 | 73 | @Override 74 | public @NotNull ActionUpdateThread getActionUpdateThread() { 75 | return ActionUpdateThread.BGT; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/action/QuickChangeCodeFormatterAction.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.action; 2 | 3 | import com.intellij.icons.AllIcons; 4 | import com.intellij.ide.actions.QuickSwitchSchemeAction; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import com.intellij.openapi.actionSystem.DataContext; 7 | import com.intellij.openapi.actionSystem.DefaultActionGroup; 8 | import com.intellij.openapi.project.DumbAware; 9 | import com.intellij.openapi.project.DumbAwareAction; 10 | import com.intellij.openapi.project.Project; 11 | import krasa.formatter.settings.ProjectComponent; 12 | import krasa.formatter.settings.Settings; 13 | 14 | import javax.swing.*; 15 | 16 | /** 17 | * @author Vojtech Krasa 18 | */ 19 | public class QuickChangeCodeFormatterAction extends QuickSwitchSchemeAction implements DumbAware { 20 | 21 | protected static final Icon ourCurrentAction = AllIcons.Actions.Forward; 22 | 23 | @Override 24 | protected void fillActions(final Project project, DefaultActionGroup group, DataContext dataContext) { 25 | Settings.Formatter formatter = ProjectComponent.getInstance(project).getSelectedProfile().getFormatter(); 26 | for (final Settings.Formatter lf : Settings.Formatter.values()) { 27 | group.add(new DumbAwareAction(lf.name(), "", lf == formatter ? ourCurrentAction : ourNotCurrentAction) { 28 | @Override 29 | public void actionPerformed(AnActionEvent e) { 30 | changeFormatter(project, lf); 31 | } 32 | }); 33 | } 34 | } 35 | 36 | private void changeFormatter(Project project, Settings.Formatter formatter) { 37 | ProjectComponent instance = ProjectComponent.getInstance(project); 38 | final Settings state = instance.getSelectedProfile(); 39 | state.setFormatter(formatter); 40 | instance.installOrUpdate(state); 41 | } 42 | 43 | @Override 44 | protected boolean isEnabled() { 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/common/ModifiableFile.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.common; 2 | 3 | import com.intellij.util.PathUtil; 4 | import krasa.formatter.exception.FileDoesNotExistsException; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.io.File; 8 | 9 | /** 10 | * @author Vojtech Krasa 11 | */ 12 | public class ModifiableFile extends File { 13 | 14 | public ModifiableFile(String pathToConfigFileJava) { 15 | super(pathToConfigFileJava); 16 | } 17 | 18 | public boolean wasChanged(Monitor lastState) { 19 | checkIfExists(); 20 | return this.lastModified() != lastState.getLastStateTime(); 21 | } 22 | 23 | public void checkIfExists() throws FileDoesNotExistsException { 24 | if (!this.exists()) { 25 | throw new FileDoesNotExistsException(this); 26 | } 27 | } 28 | 29 | public Monitor getModifiedMonitor() { 30 | return new Monitor(this); 31 | } 32 | 33 | @NotNull 34 | public String getSystemIndependentPath() { 35 | return PathUtil.toSystemIndependentName(getAbsolutePath()); 36 | } 37 | 38 | /** 39 | * @author Vojtech Krasa 40 | */ 41 | public static class Monitor { 42 | private long lastStateTime; 43 | 44 | public Monitor(File file) { 45 | lastStateTime = file.lastModified(); 46 | } 47 | 48 | public long getLastStateTime() { 49 | return lastStateTime; 50 | } 51 | 52 | public boolean wasModified(File l) { 53 | return l.lastModified() > lastStateTime; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/eclipse/Classloaders.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.eclipse; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.application.PathManager; 5 | import com.intellij.openapi.diagnostic.Logger; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.io.File; 9 | import java.net.MalformedURLException; 10 | import java.net.URL; 11 | import java.util.Arrays; 12 | import java.util.List; 13 | 14 | public class Classloaders { 15 | private static final Logger LOG = Logger.getInstance(Classloaders.class.getName()); 16 | 17 | private static ClassLoader newEclipse; 18 | 19 | 20 | public static ClassLoader getEclipse() { 21 | if (newEclipse == null) { 22 | newEclipse = classLoader(getPluginLibHomeEclipse(), "adapter.jar", "eclipse.jar"); 23 | } 24 | return newEclipse; 25 | } 26 | 27 | public static ClassLoader getCustomClassloader(List jars) { 28 | try { 29 | jars.add(new File(getPluginLibHomeEclipse(), "adapter.jar").toURI().toURL()); 30 | for (URL jar : jars) { 31 | if (!new File(jar.toURI()).exists()) { 32 | throw new IllegalStateException("Plugin jar file not found: " + jar.toURI()); 33 | } 34 | } 35 | URL[] a = jars.toArray(new URL[jars.size()]); 36 | LOG.info("Creating classloader for " + Arrays.toString(a)); 37 | return new ParentLastURLClassLoader(Classloaders.class.getClassLoader(), a); 38 | } catch (Throwable e) { 39 | throw new RuntimeException(e); 40 | } 41 | } 42 | 43 | 44 | @NotNull 45 | private static File getPluginLibHomeEclipse() { 46 | return getPluginHome("eclipse"); 47 | } 48 | 49 | @NotNull 50 | private static File getPluginHome(String eclipseVersion) { 51 | File pluginHome; 52 | if (isUnitTest()) { 53 | if (new File("../lib/" + eclipseVersion).exists()) { 54 | pluginHome = new File("../lib/" + eclipseVersion); 55 | } else { 56 | pluginHome = new File("lib/" + eclipseVersion); 57 | } 58 | } else { 59 | pluginHome = new File(PathManager.getPluginsPath(), "EclipseFormatter/lib/"); 60 | File preInstalled = new File(PathManager.getPreInstalledPluginsPath(), "EclipseFormatter/lib/"); 61 | if (!pluginHome.exists() && preInstalled.exists()) { 62 | pluginHome = preInstalled; 63 | } 64 | } 65 | return pluginHome; 66 | } 67 | 68 | private static boolean isUnitTest() { 69 | return ApplicationManager.getApplication() == null || ApplicationManager.getApplication().isUnitTestMode(); 70 | } 71 | 72 | @NotNull 73 | private static ClassLoader classLoader(File parent, String... jarFiles) { 74 | URL[] urls = new URL[jarFiles.length]; 75 | for (int i = 0; i < jarFiles.length; i++) { 76 | String jar = jarFiles[i]; 77 | File jarFile = new File(parent, jar); 78 | if (!jarFile.exists()) { 79 | throw new IllegalStateException("Plugin jar file not found: " + jarFile.getAbsolutePath()); 80 | } 81 | try { 82 | urls[i] = jarFile.toURI().toURL(); 83 | } catch (MalformedURLException e) { 84 | throw new RuntimeException(e); 85 | } 86 | } 87 | try { 88 | // return UrlClassLoader.classLoader().urls(jarFile).useCache().get(); 89 | LOG.info("Creating classloader for " + Arrays.toString(urls)); 90 | return new ParentLastURLClassLoader(Classloaders.class.getClassLoader(), urls); 91 | } catch (Throwable e) { 92 | throw new RuntimeException(e); 93 | } 94 | } 95 | 96 | 97 | 98 | 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/eclipse/CodeFormatterFacade.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.eclipse; 2 | 3 | import com.intellij.psi.PsiFile; 4 | import krasa.formatter.exception.FileDoesNotExistsException; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | import java.util.Properties; 10 | 11 | /** 12 | * @author Vojtech Krasa 13 | */ 14 | public abstract class CodeFormatterFacade { 15 | 16 | @NotNull 17 | protected Map toMap(Properties properties) { 18 | Map options = new HashMap(); 19 | for (final String name : properties.stringPropertyNames()) { 20 | options.put(name, properties.getProperty(name)); 21 | } 22 | return options; 23 | } 24 | 25 | /** 26 | * @param text to format 27 | * @param startOffset start of formatted area - this should be always start of line 28 | * @param endOffset 29 | */ 30 | public abstract String format(String text, int startOffset, int endOffset, PsiFile psiFile) 31 | throws FileDoesNotExistsException; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/eclipse/ConfigurableEclipseLocation.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.eclipse; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import krasa.formatter.exception.FormattingFailedException; 5 | import krasa.formatter.exception.InvalidSettingsException; 6 | import org.apache.commons.io.FileUtils; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.net.URL; 12 | import java.util.*; 13 | 14 | public class ConfigurableEclipseLocation { 15 | private static final Logger LOG = Logger.getInstance(ConfigurableEclipseLocation.class.getName()); 16 | // private static final Logger LOG = new PrintingLogger(System.out); 17 | 18 | private static final int TIMEOUT = 500; 19 | 20 | //@formatter:off 21 | String[] JAR_NAMES = { 22 | "org.eclipse.core.contenttype", 23 | "org.eclipse.core.jobs", 24 | "org.eclipse.core.resources", 25 | "org.eclipse.core.runtime", 26 | "org.eclipse.equinox.app",//probably useless 27 | "org.eclipse.equinox.common", 28 | "org.eclipse.equinox.preferences", 29 | "org.eclipse.jdt.core", 30 | "org.eclipse.jdt.core.compiler.batch", 31 | "org.eclipse.osgi", 32 | "org.eclipse.text" 33 | }; 34 | String[] OPTIONAL_JAR_NAMES = { 35 | "org.eclipse.jdt.core.compiler.batch" 36 | }; 37 | //@formatter:on 38 | 39 | public Set jarNames; 40 | 41 | public ConfigurableEclipseLocation() { 42 | jarNames = new HashSet(); 43 | jarNames.addAll(Arrays.asList(JAR_NAMES)); 44 | 45 | } 46 | 47 | 48 | public List run(String from) { 49 | long start = System.currentTimeMillis(); 50 | List jars = null; 51 | try { 52 | File root = new File(from); 53 | root = findEclipseRoot(root, start); 54 | 55 | if (root == null || !root.exists()) { 56 | throw new InvalidSettingsException("Invalid Eclipse location, it must contain '.eclipseproduct' file"); 57 | } 58 | 59 | LOG.debug("found root=" + root.getAbsolutePath() + " in " + (System.currentTimeMillis() - start) + "ms"); 60 | 61 | jars = findJars(root); 62 | 63 | } catch (InvalidSettingsException e) { 64 | throw e; 65 | } catch (Throwable e) { 66 | throw new RuntimeException("from=" + from, e); 67 | } 68 | 69 | List.of(OPTIONAL_JAR_NAMES).forEach(jarNames::remove); 70 | 71 | if (!jarNames.isEmpty()) { 72 | throw new FormattingFailedException("Required jars not found in '" + from + "': " + jarNames.toString(), true); 73 | } 74 | 75 | long total = System.currentTimeMillis() - start; 76 | LOG.debug("found " + jars.size() + " jars in " + total + "ms, (" + from + ")"); 77 | return jars; 78 | } 79 | 80 | private File findEclipseRoot(File root, long start) { 81 | if (System.currentTimeMillis() - start > TIMEOUT) { 82 | throw new FormattingFailedException("Timeout, Eclipse installation containing '.eclipseproduct' not found.", true); 83 | } 84 | File stick = FileUtils.getFile(root, ".eclipseproduct"); 85 | if (!stick.exists()) { 86 | File[] files = root.listFiles(); 87 | if (files != null) { 88 | for (File childDir : files) { 89 | if (childDir.isDirectory()) { 90 | stick = findEclipseRoot(childDir, start); 91 | if (stick != null) { 92 | return stick; 93 | } 94 | } 95 | } 96 | } 97 | return null; 98 | } else { 99 | return root; 100 | } 101 | } 102 | 103 | @NotNull 104 | private List findJars(File root) throws IOException { 105 | long start = System.currentTimeMillis(); 106 | String rootURI = root.toURI().toString(); 107 | File bundlesInfo = FileUtils.getFile(root, "configuration", "org.eclipse.equinox.simpleconfigurator", "bundles.info"); 108 | List files = new ArrayList<>(); 109 | List strings = FileUtils.readLines(bundlesInfo, "UTF-8"); 110 | for (String string : strings) { 111 | String[] split = string.split(","); 112 | if (split.length >= 3) { 113 | String name = split[0]; 114 | String path = split[2]; 115 | if (jarNames.contains(name)) { 116 | jarNames.remove(name); 117 | if (!path.startsWith("file:")) { 118 | files.add(new URL(rootURI + path)); 119 | } else { 120 | files.add(new URL(path)); 121 | } 122 | } 123 | } 124 | } 125 | LOG.debug("#findJarsFromRepository took " + (System.currentTimeMillis() - start) + "ms"); 126 | return files; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/eclipse/EclipseFormatterAdapter.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.eclipse; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import krasa.formatter.exception.FileDoesNotExistsException; 5 | 6 | public abstract class EclipseFormatterAdapter { 7 | protected final Logger LOG = Logger.getInstance(this.getClass().getName()); 8 | 9 | public abstract String format(int kind, String text, int startOffset, int length, int indentationLevel, String lineSeparator, String languageLevel) 10 | throws FileDoesNotExistsException; 11 | 12 | protected String getErrorMessage(String effectiveLanguageLevel) { 13 | return "languageLevel=" + effectiveLanguageLevel; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/eclipse/ParentLastURLClassLoader.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.eclipse; 2 | 3 | import java.net.URL; 4 | import java.net.URLClassLoader; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | /** 9 | * A parent-last classloader that will try the child classloader first and then the parent. This takes a fair bit of 10 | * doing because java really prefers parent-first. 11 | *

12 | * For those not familiar with class loading trickery, be wary 13 | */ 14 | public class ParentLastURLClassLoader extends ClassLoader { 15 | 16 | final static Set loadFromParent = new HashSet(); 17 | 18 | { 19 | { 20 | loadFromParent.add("org.eclipse.wst.jsdt.core.formatter.CodeFormatter"); 21 | } 22 | } 23 | 24 | final static Set neverLoadFromParentWithPrefix = new HashSet(); 25 | 26 | { 27 | { 28 | neverLoadFromParentWithPrefix.add("org.eclipse."); 29 | neverLoadFromParentWithPrefix.add("krasa.formatter.adapter."); 30 | } 31 | } 32 | 33 | private ChildURLClassLoader childClassLoader; 34 | 35 | /** 36 | * This class allows me to call findClass on a classloader 37 | */ 38 | private static class FindClassClassLoader extends ClassLoader { 39 | public FindClassClassLoader(ClassLoader parent) { 40 | super(parent); 41 | } 42 | 43 | @Override 44 | public Class findClass(String name) throws ClassNotFoundException { 45 | return super.findClass(name); 46 | } 47 | } 48 | 49 | /** 50 | * This class delegates (child then parent) for the findClass method for a URLClassLoader. We need this because 51 | * findClass is protected in URLClassLoader 52 | */ 53 | private static class ChildURLClassLoader extends URLClassLoader { 54 | private FindClassClassLoader realParent; 55 | 56 | public ChildURLClassLoader(URL[] urls, FindClassClassLoader realParent) { 57 | super(urls, null); 58 | 59 | this.realParent = realParent; 60 | } 61 | 62 | @Override 63 | public Class findClass(String name) throws ClassNotFoundException { 64 | try { 65 | if (loadFromParent.contains(name)) { 66 | return realParent.loadClass(name); 67 | } 68 | 69 | //calling twic #findClass with the same classname, you will get a LinkageError, this fixes it 70 | Class loaded = super.findLoadedClass(name); 71 | if (loaded != null) 72 | return loaded; 73 | 74 | // first try to use the URLClassLoader findClass 75 | return super.findClass(name); 76 | } catch (ClassNotFoundException e) { 77 | for (String forbiddenParentPrefixes : neverLoadFromParentWithPrefix) { 78 | if (name.startsWith(forbiddenParentPrefixes)) { 79 | throw new RuntimeException( 80 | name + " not found in child classloader, and cannot be loaded from parent", e); 81 | } 82 | } 83 | // if that fails, we ask our real parent classloader to load the class (we give up) 84 | return realParent.loadClass(name); 85 | } 86 | } 87 | } 88 | 89 | public ParentLastURLClassLoader(ClassLoader parent, URL... urls) { 90 | super(parent); 91 | childClassLoader = new ChildURLClassLoader(urls, 92 | new ParentLastURLClassLoader.FindClassClassLoader(this.getParent())); 93 | childClassLoader.setDefaultAssertionStatus(false); 94 | } 95 | 96 | @Override 97 | protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { 98 | try { 99 | // first we try to find a class inside the child classloader 100 | return childClassLoader.findClass(name); 101 | } catch (ClassNotFoundException e) { 102 | // didn't find it, try the parent 103 | return super.loadClass(name, resolve); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/exception/FileDoesNotExistsException.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.exception; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * @author Vojtech Krasa 7 | */ 8 | public class FileDoesNotExistsException extends RuntimeException { 9 | 10 | public FileDoesNotExistsException(File file) { 11 | super("Configured settings file does not exist, path=\"" + file.getPath() + "\""); 12 | } 13 | 14 | public FileDoesNotExistsException(String message) { 15 | super(message); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/exception/FormattingFailedException.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.exception; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import krasa.formatter.plugin.InvalidPropertyFile; 5 | 6 | /** 7 | * @author Vojtech Krasa 8 | */ 9 | public class FormattingFailedException extends RuntimeException { 10 | protected final Logger LOG = Logger.getInstance(this.getClass().getName()); 11 | 12 | private boolean userError; 13 | 14 | public FormattingFailedException(String s) { 15 | super(s); 16 | } 17 | 18 | public FormattingFailedException(String s, boolean userError) { 19 | super(s); 20 | this.userError = userError; 21 | } 22 | 23 | public FormattingFailedException(InvalidPropertyFile e) { 24 | super(e); 25 | } 26 | 27 | public FormattingFailedException(Exception e, String errorMessage) { 28 | super(errorMessage, e); 29 | //todo hack 30 | LOG.debug(e); 31 | } 32 | 33 | public boolean isUserError() { 34 | 35 | return userError; 36 | } 37 | 38 | public FormattingFailedException() { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/exception/InvalidSettingsException.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.exception; 2 | 3 | import krasa.formatter.plugin.InvalidPropertyFile; 4 | 5 | public class InvalidSettingsException extends FormattingFailedException { 6 | public InvalidSettingsException(String s) { 7 | super(s,true); 8 | } 9 | 10 | public InvalidSettingsException(String s, boolean userError) { 11 | super(s, userError); 12 | } 13 | 14 | public InvalidSettingsException(InvalidPropertyFile e) { 15 | super(e); 16 | } 17 | 18 | public InvalidSettingsException() { 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/exception/ParsingFailedException.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.exception; 2 | 3 | /** 4 | * @author Vojtech Krasa 5 | */ 6 | public class ParsingFailedException extends RuntimeException { 7 | public ParsingFailedException(Exception e) { 8 | super(e); 9 | } 10 | 11 | public ParsingFailedException() { 12 | } 13 | 14 | public ParsingFailedException(String s) { 15 | super(s); 16 | } 17 | 18 | public ParsingFailedException(String message, Throwable cause) { 19 | super(message, cause); 20 | } 21 | 22 | public ParsingFailedException(Throwable cause) { 23 | super(cause); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/DelegatingCodeStyleManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Adapter for Eclipse Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the 3 | * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 4 | * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the 5 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 6 | * the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | package krasa.formatter.plugin; 10 | 11 | import com.intellij.lang.ASTNode; 12 | import com.intellij.openapi.editor.Document; 13 | import com.intellij.openapi.fileTypes.FileType; 14 | import com.intellij.openapi.project.Project; 15 | import com.intellij.openapi.util.Computable; 16 | import com.intellij.openapi.util.TextRange; 17 | import com.intellij.psi.PsiElement; 18 | import com.intellij.psi.PsiFile; 19 | import com.intellij.psi.codeStyle.ChangedRangesInfo; 20 | import com.intellij.psi.codeStyle.CodeStyleManager; 21 | import com.intellij.psi.codeStyle.Indent; 22 | import com.intellij.util.IncorrectOperationException; 23 | import com.intellij.util.ThrowableRunnable; 24 | import org.jetbrains.annotations.NotNull; 25 | import org.jetbrains.annotations.Nullable; 26 | 27 | import java.util.Collection; 28 | 29 | /** 30 | * for tracking api changes only 31 | */ 32 | @SuppressWarnings({"deprecation"}) 33 | public class DelegatingCodeStyleManager extends CodeStyleManager { 34 | 35 | @NotNull 36 | protected CodeStyleManager original; 37 | 38 | public DelegatingCodeStyleManager() { 39 | } 40 | 41 | public DelegatingCodeStyleManager(@NotNull CodeStyleManager original) { 42 | this.original = original; 43 | } 44 | 45 | @NotNull 46 | public CodeStyleManager getOriginal() { 47 | return original; 48 | } 49 | 50 | @Override 51 | @NotNull 52 | public Project getProject() { 53 | return original.getProject(); 54 | } 55 | 56 | @Override 57 | @NotNull 58 | public PsiElement reformat(@NotNull PsiElement element) throws IncorrectOperationException { 59 | return original.reformat(element); 60 | } 61 | 62 | @Override 63 | @NotNull 64 | public PsiElement reformat(@NotNull PsiElement element, boolean canChangeWhiteSpacesOnly) 65 | throws IncorrectOperationException { 66 | return original.reformat(element, canChangeWhiteSpacesOnly); 67 | } 68 | 69 | @Override 70 | public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, int endOffset) 71 | throws IncorrectOperationException { 72 | return original.reformatRange(element, startOffset, endOffset); 73 | } 74 | 75 | @Override 76 | public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, int endOffset, 77 | boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException { 78 | return original.reformatRange(element, startOffset, endOffset, canChangeWhiteSpacesOnly); 79 | } 80 | 81 | @Override 82 | public void reformatText(@NotNull PsiFile element, int startOffset, int endOffset) 83 | throws IncorrectOperationException { 84 | original.reformatText(element, startOffset, endOffset); 85 | } 86 | 87 | 88 | @Override 89 | public void adjustLineIndent(@NotNull PsiFile file, TextRange rangeToAdjust) throws IncorrectOperationException { 90 | original.adjustLineIndent(file, rangeToAdjust); 91 | } 92 | 93 | @Override 94 | public int adjustLineIndent(@NotNull PsiFile file, int offset) throws IncorrectOperationException { 95 | return original.adjustLineIndent(file, offset); 96 | } 97 | 98 | @Override 99 | public int adjustLineIndent(@NotNull Document document, int i) { 100 | return original.adjustLineIndent(document, i); 101 | } 102 | // 2017.1 EAP 103 | // @Override 104 | // public int adjustLineIndent(@NotNull Document document, int i, FormattingMode formattingMode) { 105 | // return original.adjustLineIndent(document, i, formattingMode); 106 | // } 107 | 108 | @Override 109 | public boolean isLineToBeIndented(@NotNull PsiFile file, int offset) { 110 | return original.isLineToBeIndented(file, offset); 111 | } 112 | 113 | @Override 114 | @Nullable 115 | public String getLineIndent(@NotNull PsiFile file, int offset) { 116 | return original.getLineIndent(file, offset); 117 | } 118 | 119 | @Override 120 | public Indent getIndent(String text, FileType fileType) { 121 | return original.getIndent(text, fileType); 122 | } 123 | 124 | @Override 125 | public String fillIndent(Indent indent, FileType fileType) { 126 | return original.fillIndent(indent, fileType); 127 | } 128 | 129 | @Override 130 | public Indent zeroIndent() { 131 | return original.zeroIndent(); 132 | } 133 | 134 | @Override 135 | public void reformatNewlyAddedElement(@NotNull ASTNode block, @NotNull ASTNode addedElement) 136 | throws IncorrectOperationException { 137 | original.reformatNewlyAddedElement(block, addedElement); 138 | } 139 | 140 | @Override 141 | public boolean isSequentialProcessingAllowed() { 142 | return original.isSequentialProcessingAllowed(); 143 | } 144 | 145 | // 10.5 146 | // @Override 147 | // public String getLineIndent(@NotNull Editor editor) { 148 | // return original.getLineIndent(editor); 149 | // } 150 | 151 | // 11.0 152 | @Override 153 | public String getLineIndent(@NotNull Document document, int offset) { 154 | return original.getLineIndent(document, offset); 155 | 156 | } 157 | 158 | @Override 159 | public void performActionWithFormatterDisabled(Runnable r) { 160 | original.performActionWithFormatterDisabled(r); 161 | } 162 | 163 | @Override 164 | public void performActionWithFormatterDisabled(ThrowableRunnable r) throws T { 165 | original.performActionWithFormatterDisabled(r); 166 | } 167 | 168 | @Override 169 | public T performActionWithFormatterDisabled(Computable r) { 170 | return original.performActionWithFormatterDisabled(r); 171 | 172 | } 173 | 174 | // 2017.1 EAP 175 | // @Override 176 | // public FormattingMode getCurrentFormattingMode() { 177 | // return original.getCurrentFormattingMode(); 178 | // } 179 | 180 | // 11.1 181 | // @Override 182 | @Override 183 | public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges) 184 | throws IncorrectOperationException { 185 | original.reformatText(psiFile, textRanges); 186 | } 187 | 188 | // 16.3 189 | @Override 190 | public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull ChangedRangesInfo changedRangesInfo) throws IncorrectOperationException { 191 | original.reformatTextWithContext(psiFile, changedRangesInfo); 192 | } 193 | 194 | // 15 195 | @Override 196 | public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collection collection) throws IncorrectOperationException { 197 | original.reformatTextWithContext(psiFile, collection); 198 | } 199 | 200 | // 2017.2 201 | @Override 202 | public int getSpacing(@NotNull PsiFile file, int offset) { 203 | return original.getSpacing(file, offset); 204 | } 205 | 206 | // 2017.2 207 | @Override 208 | public int getMinLineFeeds(@NotNull PsiFile file, int offset) { 209 | return original.getMinLineFeeds(file, offset); 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/Donate.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.ide.BrowserUtil; 4 | import com.intellij.openapi.diagnostic.Logger; 5 | import com.intellij.openapi.util.IconLoader; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import javax.swing.*; 9 | import java.awt.event.ActionEvent; 10 | import java.awt.event.ActionListener; 11 | 12 | public class Donate { 13 | private static final Logger LOG = Logger.getInstance(Donate.class); 14 | 15 | public static final @NotNull 16 | Icon ICON = IconLoader.getIcon("/krasa/formatter/coins_in_hand.png", Donate.class); 17 | 18 | public static JButton newDonateButton() { 19 | JButton donate = new JButton(); 20 | initDonateButton(donate); 21 | return donate; 22 | } 23 | 24 | public static void initDonateButton(JButton donate) { 25 | donate.setText("Donate"); 26 | donate.setIcon(ICON); 27 | donate.addActionListener(new ActionListener() { 28 | @Override 29 | public void actionPerformed(ActionEvent e) { 30 | BrowserUtil.browse("https://github.com/sponsors/krasa"); 31 | } 32 | }); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/EclipseCodeFormatter.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.codeInsight.template.impl.TemplateManagerImpl; 4 | import com.intellij.codeInsight.template.impl.TemplateState; 5 | import com.intellij.openapi.diagnostic.Logger; 6 | import com.intellij.openapi.editor.*; 7 | import com.intellij.openapi.fileEditor.FileDocumentManager; 8 | import com.intellij.openapi.vfs.VirtualFile; 9 | import com.intellij.psi.PsiDocumentManager; 10 | import com.intellij.psi.PsiFile; 11 | import com.intellij.psi.util.PsiUtilBase; 12 | import krasa.formatter.eclipse.CodeFormatterFacade; 13 | import krasa.formatter.exception.FileDoesNotExistsException; 14 | import krasa.formatter.processor.Processor; 15 | import krasa.formatter.settings.Settings; 16 | import krasa.formatter.utils.FileUtils; 17 | import org.jetbrains.annotations.NotNull; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | /** 23 | * @author Vojtech Krasa 24 | */ 25 | public class EclipseCodeFormatter { 26 | 27 | private static final Logger LOG = Logger.getInstance(EclipseCodeFormatter.class.getName()); 28 | 29 | private Settings settings; 30 | @NotNull 31 | protected final CodeFormatterFacade codeFormatterFacade; 32 | 33 | private List postProcessors; 34 | 35 | public EclipseCodeFormatter(@NotNull Settings settings, @NotNull CodeFormatterFacade codeFormatterFacade1) { 36 | this.settings = settings; 37 | codeFormatterFacade = codeFormatterFacade1; 38 | postProcessors = new ArrayList(); 39 | } 40 | 41 | public void format(PsiFile psiFile, int startOffset, int endOffset) throws FileDoesNotExistsException { 42 | LOG.debug("#format " + startOffset + "-" + endOffset); 43 | boolean wholeFile = FileUtils.isWholeFile(startOffset, endOffset, psiFile.getText()); 44 | Range range = new Range(startOffset, endOffset, wholeFile); 45 | 46 | final Editor editor = PsiUtilBase.findEditor(psiFile); 47 | if (editor != null) { 48 | TemplateState templateState = TemplateManagerImpl.getTemplateState(editor); 49 | if (templateState != null && !settings.isUseForLiveTemplates()) { 50 | throw new ReformatItInIntelliJ(); 51 | } 52 | formatWhenEditorIsOpen(editor, range, psiFile); 53 | } else { 54 | formatWhenEditorIsClosed(range, psiFile); 55 | } 56 | 57 | } 58 | 59 | private void formatWhenEditorIsClosed(Range range, PsiFile psiFile) throws FileDoesNotExistsException { 60 | LOG.debug("#formatWhenEditorIsClosed " + psiFile.getName()); 61 | 62 | VirtualFile virtualFile = psiFile.getVirtualFile(); 63 | FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance(); 64 | Document document = fileDocumentManager.getDocument(virtualFile); 65 | fileDocumentManager.saveDocument(document); // when file is edited and editor is closed, it is needed to save 66 | // the text 67 | String text = document.getText(); 68 | String reformat = reformat(range.getStartOffset(), range.getEndOffset(), text, psiFile); 69 | 70 | document.setText(reformat); 71 | postProcess(document, psiFile, range, fileDocumentManager); 72 | } 73 | 74 | /* when file is being edited, it is important to load text from editor, i think */ 75 | private void formatWhenEditorIsOpen(Editor editor, Range range, PsiFile file) throws FileDoesNotExistsException { 76 | LOG.debug("#formatWhenEditorIsOpen " + file.getName()); 77 | int visualColumnToRestore = getVisualColumnToRestore(editor); 78 | 79 | Document document = editor.getDocument(); 80 | // http://code.google.com/p/eclipse-code-formatter-intellij-plugin/issues/detail?id=7 81 | PsiDocumentManager.getInstance(editor.getProject()).doPostponedOperationsAndUnblockDocument(document); 82 | 83 | int caretOffset = editor.getCaretModel().getOffset(); 84 | RangeMarker rangeMarker = document.createRangeMarker(caretOffset, caretOffset); 85 | 86 | String text = document.getText(); 87 | String reformat = reformat(range.getStartOffset(), range.getEndOffset(), text, file); 88 | document.setText(reformat); 89 | postProcess(document, file, range, FileDocumentManager.getInstance()); 90 | 91 | restoreVisualColumn(editor, visualColumnToRestore, rangeMarker); 92 | rangeMarker.dispose(); 93 | 94 | LOG.debug("#formatWhenEditorIsOpen done"); 95 | } 96 | 97 | private void postProcess(Document document, PsiFile file, Range range, FileDocumentManager fileDocumentManager) { 98 | // for (Processor postProcessor : postProcessors) { 99 | // postProcessor.process(document, file, range); 100 | // } 101 | // // updates psi, so comments from import statements does not get duplicated - probably obsolete 102 | final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject()); 103 | //commitDocument needed for intellij-plugin-save-actions 104 | manager.commitDocument(document); 105 | // TODO needed? 106 | // fileDocumentManager.saveDocument(document); 107 | } 108 | 109 | private String reformat(int startOffset, int endOffset, String text, PsiFile psiFile) 110 | throws FileDoesNotExistsException { 111 | return codeFormatterFacade.format(text, getLineStartOffset(startOffset, text), endOffset, psiFile); 112 | } 113 | 114 | /** 115 | * start offset must be on the start of line 116 | */ 117 | private int getLineStartOffset(int startOffset, String text) { 118 | if (startOffset == 0) { 119 | return 0; 120 | } 121 | return text.substring(0, startOffset).lastIndexOf(Settings.LINE_SEPARATOR) + 1; 122 | } 123 | 124 | private void restoreVisualColumn(Editor editor, int visualColumnToRestore, RangeMarker rangeMarker) { 125 | // CaretImpl.updateCaretPosition() contains some magic which moves the caret on bad position, this should 126 | // restore it on a better place 127 | int endOffset = rangeMarker.getEndOffset(); 128 | if (endOffset < editor.getDocument().getTextLength()) { 129 | editor.getCaretModel().moveToOffset(endOffset); 130 | } 131 | 132 | if (visualColumnToRestore < 0) { 133 | } else { 134 | CaretModel caretModel = editor.getCaretModel(); 135 | VisualPosition position = caretModel.getVisualPosition(); 136 | if (visualColumnToRestore != position.column) { 137 | caretModel.moveToVisualPosition(new VisualPosition(position.line, visualColumnToRestore)); 138 | } 139 | } 140 | } 141 | 142 | // There is a possible case that cursor is located at the end of the line that contains only white spaces. For 143 | // example: 144 | // public void foo() { 145 | // 146 | // } 147 | // Formatter removes such white spaces, i.e. keeps only line feed symbol. But we want to preserve caret position 148 | // then. 149 | // So, we check if it should be preserved and restore it after formatting if necessary 150 | /** copypaste from intellij, todo update it from IJ 15 - not compatible with IJ 13 */ 151 | private int getVisualColumnToRestore(Editor editor) { 152 | int visualColumnToRestore = -1; 153 | 154 | if (editor != null) { 155 | Document document1 = editor.getDocument(); 156 | int caretOffset = editor.getCaretModel().getOffset(); 157 | caretOffset = Math.max(Math.min(caretOffset, document1.getTextLength() - 1), 0); 158 | CharSequence text1 = document1.getCharsSequence(); 159 | int caretLine = document1.getLineNumber(caretOffset); 160 | int lineStartOffset = document1.getLineStartOffset(caretLine); 161 | int lineEndOffset = document1.getLineEndOffset(caretLine); 162 | boolean fixCaretPosition = true; 163 | for (int i = lineStartOffset; i < lineEndOffset; i++) { 164 | char c = text1.charAt(i); 165 | if (c != ' ' && c != '\t' && c != '\n') { 166 | fixCaretPosition = false; 167 | break; 168 | } 169 | } 170 | if (fixCaretPosition) { 171 | visualColumnToRestore = editor.getCaretModel().getVisualPosition().column; 172 | } 173 | } 174 | return visualColumnToRestore; 175 | } 176 | 177 | } 178 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/EclipseCodeStyleManager_IJ_2016_3plus.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import com.intellij.openapi.util.TextRange; 5 | import com.intellij.psi.PsiFile; 6 | import com.intellij.psi.codeStyle.CodeStyleManager; 7 | import com.intellij.util.IncorrectOperationException; 8 | import krasa.formatter.settings.Settings; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.util.Collections; 12 | import java.util.List; 13 | 14 | public class EclipseCodeStyleManager_IJ_2016_3plus extends EclipseCodeStyleManager { 15 | 16 | private static final Logger LOG = Logger.getInstance(EclipseCodeStyleManager_IJ_2016_3plus.class.getName()); 17 | 18 | public EclipseCodeStyleManager_IJ_2016_3plus(@NotNull CodeStyleManager original, @NotNull Settings settings) { 19 | super(original, settings); 20 | } 21 | 22 | // 16.3 23 | // @Override 24 | public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull com.intellij.psi.codeStyle.ChangedRangesInfo changedRangesInfo) 25 | throws IncorrectOperationException { 26 | if (shouldReformatByEclipse(psiFile)) { 27 | List allChangedRanges = changedRangesInfo.allChangedRanges; 28 | reformatText(psiFile, allChangedRanges); 29 | // TODO check if file is being commited. rather than faking TextRange 30 | } else if (shouldSkipFormatting(psiFile, Collections.singletonList(new TextRange(0, psiFile.getTextLength())))) { 31 | notifier.notifyFormattingWasDisabled(psiFile); 32 | } else { 33 | original.reformatTextWithContext(psiFile, changedRangesInfo); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/EclipseImportOptimizer.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.lang.ImportOptimizer; 4 | import com.intellij.lang.java.JavaImportOptimizer; 5 | import com.intellij.openapi.diagnostic.Logger; 6 | import com.intellij.openapi.editor.Document; 7 | import com.intellij.openapi.fileEditor.FileDocumentManager; 8 | import com.intellij.openapi.progress.ProcessCanceledException; 9 | import com.intellij.openapi.project.IndexNotReadyException; 10 | import com.intellij.openapi.util.EmptyRunnable; 11 | import com.intellij.psi.*; 12 | import krasa.formatter.exception.FileDoesNotExistsException; 13 | import krasa.formatter.exception.ParsingFailedException; 14 | import krasa.formatter.settings.ProjectComponent; 15 | import krasa.formatter.settings.Settings; 16 | import krasa.formatter.settings.provider.ImportOrderProvider; 17 | import krasa.formatter.utils.FileUtils; 18 | import org.jetbrains.annotations.NotNull; 19 | 20 | /** 21 | * @author Vojtech Krasa 22 | */ 23 | public class EclipseImportOptimizer implements ImportOptimizer { 24 | 25 | private static final Logger LOG = Logger.getInstance("#krasa.formatter.plugin.processor.ImportOrderProcessor"); 26 | 27 | private Notifier notifier = new Notifier(); 28 | 29 | @NotNull 30 | @Override 31 | public Runnable processFile(final PsiFile file) { 32 | if (!(file instanceof PsiJavaFile)) { 33 | return EmptyRunnable.getInstance(); 34 | } 35 | final PsiJavaFile dummyFile = (PsiJavaFile) file.copy(); 36 | 37 | final Runnable intellijRunnable = new JavaImportOptimizer().processFile(dummyFile); 38 | if (!(file instanceof PsiJavaFile)) { 39 | return intellijRunnable; 40 | } 41 | 42 | if (!isEnabled(file)) { 43 | return intellijRunnable; 44 | } 45 | return new Runnable() { 46 | 47 | @Override 48 | public void run() { 49 | intellijRunnable.run(); 50 | try { 51 | Settings settings = ProjectComponent.getSettings(file); 52 | if (isEnabled(settings)) { 53 | optimizeImportsByEclipse((PsiJavaFile) file, settings, dummyFile); 54 | } 55 | } catch (ParsingFailedException e) { 56 | notifier.configurationError(e, file.getProject()); 57 | LOG.info("Eclipse Import Optimizer failed", e); 58 | } catch (FileDoesNotExistsException e) { 59 | notifier.configurationError(e, file.getProject()); 60 | LOG.info("Eclipse Import Optimizer failed", e); 61 | } catch (IndexNotReadyException e) { 62 | throw e; 63 | } catch (ProcessCanceledException e) { 64 | throw e; 65 | } catch (Throwable e) { 66 | LOG.error("Eclipse Import Optimizer failed", e); 67 | } 68 | } 69 | }; 70 | } 71 | 72 | private void optimizeImportsByEclipse(PsiJavaFile psiFile, Settings settings, PsiJavaFile dummy) { 73 | ImportSorterAdapter importSorter = null; 74 | try { 75 | importSorter = getImportSorter(settings); 76 | 77 | PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(psiFile.getProject()); 78 | commitDocument(psiFile, psiDocumentManager); 79 | 80 | importSorter.sortImports(psiFile, dummy); 81 | // commitDocumentAndSave(psiFile, psiDocumentManager); 82 | } catch (ParsingFailedException e) { 83 | throw e; 84 | } catch (IndexNotReadyException e) { 85 | throw e; 86 | } catch (ProcessCanceledException e) { 87 | throw e; 88 | } catch (FileDoesNotExistsException e) { 89 | throw e; 90 | } catch (Throwable e) { 91 | final PsiImportList oldImportList = (psiFile).getImportList(); 92 | StringBuilder stringBuilder = new StringBuilder(); 93 | if (oldImportList != null) { 94 | PsiImportStatementBase[] allImportStatements = oldImportList.getAllImportStatements(); 95 | for (PsiImportStatementBase allImportStatement : allImportStatements) { 96 | String text = allImportStatement.getText(); 97 | stringBuilder.append(text); 98 | } 99 | } 100 | String message = "imports: " + stringBuilder.toString() + ", settings: " 101 | + (importSorter != null ? importSorter.getImportsOrderAsString() : null); 102 | throw new ImportSorterException(message, e); 103 | } 104 | } 105 | 106 | /** 107 | * very strange, https://github.com/krasa/EclipseCodeFormatter/issues/59 108 | */ 109 | private void commitDocument(PsiJavaFile psiFile, PsiDocumentManager psiDocumentManager) { 110 | Document document = psiDocumentManager.getDocument(psiFile); 111 | if (document != null) { 112 | psiDocumentManager.commitDocument(document); 113 | } 114 | } 115 | 116 | /** 117 | * was needed for #87+#94 - saveDocument un-blues changed files - where content is equal, but now not changing PSI when imports are not changed (#179) makes it obsolete 118 | */ 119 | private void commitDocumentAndSave(PsiJavaFile psiFile, PsiDocumentManager psiDocumentManager) { 120 | Document document = psiDocumentManager.getDocument(psiFile); 121 | if (document != null) { 122 | psiDocumentManager.doPostponedOperationsAndUnblockDocument(document); 123 | psiDocumentManager.commitDocument(document); 124 | FileDocumentManager.getInstance().saveDocument(document); 125 | } 126 | } 127 | 128 | protected ImportSorterAdapter getImportSorter(Settings settings) { 129 | if (settings.isImportOrderFromFile()) { 130 | final ImportOrderProvider importOrderProviderFromFile = settings.getImportOrderProvider(); 131 | return new ImportSorterAdapter(settings.getImportOrdering(), importOrderProviderFromFile.get()); 132 | } else { 133 | return new ImportSorterAdapter(settings.getImportOrdering(), ImportOrderProvider.toList(settings.getImportOrder())); 134 | } 135 | } 136 | 137 | @Override 138 | public boolean supports(PsiFile file) { 139 | return FileUtils.isJava(file) && isEnabled(file); 140 | } 141 | 142 | private boolean isEnabled(Settings settings) { 143 | return settings.isEnabled() && settings.isEnableJavaFormatting() && settings.isOptimizeImports(); 144 | } 145 | 146 | private boolean isEnabled(PsiFile file) { 147 | Settings settings = ProjectComponent.getSettings(file); 148 | return isEnabled(settings); 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ImportSorterAdapter.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.openapi.fileTypes.StdFileTypes; 4 | import com.intellij.psi.*; 5 | import krasa.formatter.settings.Settings; 6 | import krasa.formatter.utils.StringUtils; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | /** 14 | * @author Vojtech Krasa 15 | */ 16 | public class ImportSorterAdapter { 17 | public static final String N = Settings.LINE_SEPARATOR; 18 | 19 | private Settings.ImportOrdering importOrdering; 20 | private List importsOrder; 21 | 22 | public ImportSorterAdapter(Settings.ImportOrdering importOrdering, List importsOrder) { 23 | this.importOrdering = importOrdering; 24 | this.importsOrder = new ArrayList(importsOrder); 25 | } 26 | 27 | public String getImportsOrderAsString() { 28 | return Arrays.toString(importsOrder.toArray()); 29 | } 30 | 31 | public void sortImports(PsiJavaFile file, PsiJavaFile dummy) { 32 | List imports = new ArrayList(); 33 | List nonImports = new ArrayList(); 34 | 35 | PsiImportList actualImportList = file.getImportList(); 36 | if (actualImportList == null) { 37 | return; 38 | } 39 | PsiImportList dummyImportList = dummy.getImportList(); 40 | if (dummyImportList == null) { 41 | return; 42 | } 43 | 44 | PsiElement[] children = dummyImportList.getChildren(); 45 | for (int i = 0; i < children.length; i++) { 46 | PsiElement child = children[i]; 47 | if (child instanceof PsiImportStatementBase) { 48 | imports.add(child.getText()); 49 | } else if (!(child instanceof PsiWhiteSpace)) { //todo wild guess 50 | nonImports.add(child); 51 | } 52 | } 53 | 54 | List sort = getImportsSorter(file).sort(StringUtils.trimImports(imports)); 55 | 56 | StringBuilder text = new StringBuilder(); 57 | for (int i = 0; i < sort.size(); i++) { 58 | text.append(sort.get(i)); 59 | } 60 | for (int i = 0; i < nonImports.size(); i++) { 61 | PsiElement psiElement = nonImports.get(i); 62 | text.append("\n").append(psiElement.getText()); 63 | } 64 | 65 | PsiFileFactory factory = PsiFileFactory.getInstance(file.getProject()); 66 | String ext = StdFileTypes.JAVA.getDefaultExtension(); 67 | final PsiJavaFile dummyFile = (PsiJavaFile) factory.createFileFromText("_Dummy_." + ext, StdFileTypes.JAVA, 68 | text); 69 | 70 | PsiImportList newImportList = dummyFile.getImportList(); 71 | PsiImportList result = (PsiImportList) newImportList.copy(); 72 | if (actualImportList.isReplaceEquivalent(result)) 73 | return; 74 | if (!nonImports.isEmpty()) { 75 | PsiElement firstPrevious = newImportList.getPrevSibling(); 76 | while (firstPrevious != null && firstPrevious.getPrevSibling() != null) { 77 | firstPrevious = firstPrevious.getPrevSibling(); 78 | } 79 | for (PsiElement element = firstPrevious; 80 | element != null && element != newImportList; element = element.getNextSibling()) { 81 | result.add(element.copy()); 82 | } 83 | for (PsiElement element = newImportList.getNextSibling(); 84 | element != null; element = element.getNextSibling()) { 85 | result.add(element.copy()); 86 | } 87 | } 88 | 89 | actualImportList.replace(result); 90 | } 91 | 92 | @NotNull 93 | private ImportsSorter getImportsSorter(PsiJavaFile file) { 94 | switch (importOrdering) { 95 | case ECLIPSE_44: 96 | return new ImportsSorter450(importsOrder); 97 | case ECLIPSE_452: 98 | return new ImportsSorter452(importsOrder, new ImportsComparator(file.getProject())); 99 | } 100 | throw new RuntimeException(String.valueOf(importOrdering)); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ImportSorterException.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | /** 4 | * @author Vojtech Krasa 5 | */ 6 | public class ImportSorterException extends RuntimeException { 7 | public ImportSorterException() { 8 | } 9 | 10 | public ImportSorterException(String message) { 11 | super(message); 12 | } 13 | 14 | public ImportSorterException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | 18 | public ImportSorterException(Throwable cause) { 19 | super(cause); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ImportsComparator.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.openapi.project.Project; 4 | import com.intellij.psi.JavaPsiFacade; 5 | import com.intellij.psi.PsiClass; 6 | import com.intellij.psi.impl.JavaPsiFacadeImpl; 7 | import com.intellij.psi.search.GlobalSearchScope; 8 | import krasa.formatter.utils.StringUtils; 9 | 10 | import java.util.Comparator; 11 | 12 | class ImportsComparator implements Comparator { 13 | 14 | private JavaPsiFacade javaPsiFacade; 15 | private GlobalSearchScope scope; 16 | 17 | public ImportsComparator(Project project) { 18 | javaPsiFacade = JavaPsiFacadeImpl.getInstance(project); 19 | scope = GlobalSearchScope.allScope(project); 20 | } 21 | 22 | public ImportsComparator() { 23 | } 24 | 25 | @Override 26 | public int compare(String o1, String o2) { 27 | String simpleName1 = simpleName(o1); 28 | String containerName1 = getPackage(o1, simpleName1); 29 | 30 | String simpleName2 = simpleName(o2); 31 | String containerName2 = getPackage(o2, simpleName2); 32 | 33 | 34 | int i = containerName1.compareTo(containerName2); 35 | 36 | if (i == 0) { 37 | i = simpleName1.compareTo(simpleName2); 38 | } 39 | return i; 40 | } 41 | 42 | private String getPackage(String qualified, String simple) { 43 | String substring; 44 | if (qualified.length() > simple.length()) { 45 | substring = qualified.substring(0, qualified.length() - simple.length() - 1); 46 | } else { 47 | substring = StringUtils.getPackage(qualified); 48 | } 49 | return substring; 50 | } 51 | 52 | private String simpleName(String qualified) { 53 | String simpleName; 54 | 55 | PsiClass aClass = getPsiClass(qualified); 56 | if (aClass != null) { 57 | PsiClass containingClass = aClass; 58 | simpleName = aClass.getName(); 59 | while (containingClass != null && containingClass.getContainingClass() != null) { 60 | containingClass = containingClass.getContainingClass(); 61 | if (containingClass != null) { 62 | simpleName = containingClass.getName() + "." + simpleName; 63 | } 64 | } 65 | } else { 66 | simpleName = StringUtils.getSimpleName(qualified); 67 | } 68 | return simpleName; 69 | } 70 | 71 | protected PsiClass getPsiClass(String qualified) { 72 | return javaPsiFacade.findClass(qualified, scope); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ImportsSorter.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import java.util.List; 4 | 5 | public interface ImportsSorter { 6 | List sort(List imports); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ImportsSorter452.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.util.containers.MultiMap; 4 | import krasa.formatter.utils.StringUtils; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.util.*; 8 | 9 | /*not thread safe*/ 10 | @SuppressWarnings("Duplicates") 11 | class ImportsSorter452 implements ImportsSorter { 12 | 13 | private List template = new ArrayList(); 14 | private MultiMap matchingImports = new MultiMap(); 15 | private ArrayList notMatching = new ArrayList(); 16 | private Set allImportOrderItems = new HashSet(); 17 | private Comparator importsComparator; 18 | 19 | public ImportsSorter452(List importOrder, ImportsComparator comparator) { 20 | importsComparator = comparator; 21 | List importOrderCopy = new ArrayList(importOrder); 22 | normalizeStaticOrderItems(importOrderCopy); 23 | putStaticItemIfNotExists(importOrderCopy); 24 | template.addAll(importOrderCopy); 25 | this.allImportOrderItems.addAll(importOrderCopy); 26 | } 27 | 28 | @Override 29 | public List sort(List imports) { 30 | filterMatchingImports(imports); 31 | mergeMatchingItems(); 32 | mergeNotMatchingItems(); 33 | removeNewLines(); 34 | return getResult(); 35 | } 36 | 37 | private void removeNewLines() { 38 | List temp = new ArrayList(); 39 | 40 | boolean previousWasNewLine = false; 41 | boolean anyContent = false; 42 | for (int i = 0; i < template.size(); i++) { 43 | String s = template.get(i); 44 | if (!anyContent && s.equals(ImportSorterAdapter.N)) { 45 | continue; 46 | } 47 | if (s.equals(ImportSorterAdapter.N)) { 48 | if (previousWasNewLine) { 49 | continue; 50 | } else { 51 | temp.add(s); 52 | } 53 | previousWasNewLine = true; 54 | } else { 55 | previousWasNewLine = false; 56 | anyContent = true; 57 | temp.add(s); 58 | } 59 | } 60 | 61 | 62 | Collections.reverse(temp); 63 | List temp2 = trimNewLines(temp); 64 | Collections.reverse(temp2); 65 | 66 | template = temp2; 67 | } 68 | 69 | 70 | @NotNull 71 | private List trimNewLines(List temp) { 72 | List temp2 = new ArrayList(); 73 | boolean anyContent = false; 74 | for (int i = 0; i < temp.size(); i++) { 75 | String s = temp.get(i); 76 | if (!anyContent && s.equals(ImportSorterAdapter.N)) { 77 | continue; 78 | } 79 | anyContent = true; 80 | temp2.add(s); 81 | } 82 | return temp2; 83 | } 84 | 85 | private void putStaticItemIfNotExists(List allImportOrderItems) { 86 | boolean contains = false; 87 | for (int i = 0; i < allImportOrderItems.size(); i++) { 88 | String allImportOrderItem = allImportOrderItems.get(i); 89 | if (allImportOrderItem.equals("static ")) { 90 | contains = true; 91 | } 92 | } 93 | if (!contains) { 94 | allImportOrderItems.add(0, "static "); 95 | } 96 | } 97 | 98 | private void normalizeStaticOrderItems(List allImportOrderItems) { 99 | for (int i = 0; i < allImportOrderItems.size(); i++) { 100 | String s = allImportOrderItems.get(i); 101 | if (s.startsWith("\\#") || s.startsWith("#")) { 102 | allImportOrderItems.set(i, s.replace("\\#", "static ").replace("#", "static ")); 103 | } 104 | } 105 | } 106 | 107 | /** 108 | * returns not matching items and initializes internal state 109 | */ 110 | private void filterMatchingImports(List imports) { 111 | for (String anImport : imports) { 112 | String orderItem = getBestMatchingImportOrderItem(anImport); 113 | if (orderItem != null) { 114 | matchingImports.putValue(orderItem, anImport); 115 | } else { 116 | notMatching.add(anImport); 117 | } 118 | } 119 | notMatching.addAll(allImportOrderItems); 120 | } 121 | 122 | private String getBestMatchingImportOrderItem(String anImport) { 123 | String matchingImport = null; 124 | for (String orderItem : allImportOrderItems) { 125 | if (anImport.startsWith( 126 | // 4.5.1+ matches exact package name 127 | orderItem.equals("static ") || orderItem.equals("") ? orderItem : orderItem + ".")) { 128 | if (matchingImport == null) { 129 | matchingImport = orderItem; 130 | } else { 131 | matchingImport = StringUtils.betterMatching(matchingImport, orderItem, anImport); 132 | } 133 | } 134 | } 135 | return matchingImport; 136 | } 137 | 138 | /** 139 | * not matching means it does not match any order item, so it will be appended before or after order items 140 | */ 141 | private void mergeNotMatchingItems() { 142 | Collections.sort(notMatching, importsComparator); 143 | 144 | template.add(ImportSorterAdapter.N); 145 | for (int i = 0; i < notMatching.size(); i++) { 146 | String notMatchingItem = notMatching.get(i); 147 | if (!matchesStatic(false, notMatchingItem)) { 148 | continue; 149 | } 150 | boolean isOrderItem = isOrderItem(notMatchingItem, false); 151 | if (!isOrderItem) { 152 | template.add(notMatchingItem); 153 | } 154 | } 155 | template.add(ImportSorterAdapter.N); 156 | } 157 | 158 | private boolean isOrderItem(String notMatchingItem, boolean staticItems) { 159 | boolean contains = allImportOrderItems.contains(notMatchingItem); 160 | return contains && matchesStatic(staticItems, notMatchingItem); 161 | } 162 | 163 | 164 | private boolean matchesStatic(boolean staticItems, String notMatchingItem) { 165 | boolean isStatic = notMatchingItem.startsWith("static "); 166 | return (isStatic && staticItems) || (!isStatic && !staticItems); 167 | } 168 | 169 | private void mergeMatchingItems() { 170 | for (int i = 0; i < template.size(); i++) { 171 | String item = template.get(i); 172 | if (allImportOrderItems.contains(item)) { 173 | // find matching items for order item 174 | Collection strings = matchingImports.get(item); 175 | if (strings == null || strings.isEmpty()) { 176 | // if there is none, just remove order item 177 | template.remove(i); 178 | i--; 179 | continue; 180 | } 181 | ArrayList matchingItems = new ArrayList(strings); 182 | Collections.sort(matchingItems, importsComparator); 183 | 184 | // replace order item by matching import statements 185 | // this is a mess and it is only a luck that it works :-] 186 | template.remove(i); 187 | if (i != 0 && !template.get(i - 1).equals(ImportSorterAdapter.N)) { 188 | template.add(i, ImportSorterAdapter.N); 189 | i++; 190 | } 191 | if (i + 1 < template.size() && !template.get(i + 1).equals(ImportSorterAdapter.N) 192 | && !template.get(i).equals(ImportSorterAdapter.N)) { 193 | template.add(i, ImportSorterAdapter.N); 194 | } 195 | template.addAll(i, matchingItems); 196 | if (i != 0 && !template.get(i - 1).equals(ImportSorterAdapter.N)) { 197 | template.add(i, ImportSorterAdapter.N); 198 | } 199 | 200 | } 201 | } 202 | // if there is \n on the end, remove it 203 | if (template.size() > 0 && template.get(template.size() - 1).equals(ImportSorterAdapter.N)) { 204 | template.remove(template.size() - 1); 205 | } 206 | } 207 | 208 | private List getResult() { 209 | ArrayList strings = new ArrayList(); 210 | 211 | for (String s : template) { 212 | if (s.equals(ImportSorterAdapter.N)) { 213 | strings.add(s); 214 | } else { 215 | strings.add("import " + s + ";" + ImportSorterAdapter.N); 216 | } 217 | } 218 | return strings; 219 | } 220 | 221 | } 222 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/InvalidPropertyFile.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * @author Vojtech Krasa 7 | */ 8 | public class InvalidPropertyFile extends RuntimeException { 9 | 10 | public InvalidPropertyFile(String s, File file) { 11 | super(s); 12 | } 13 | 14 | public InvalidPropertyFile(File file) { 15 | super("Property file does not contains any properties, " + file.getAbsolutePath()); 16 | } 17 | 18 | public InvalidPropertyFile(String message, Throwable cause) { 19 | super(message, cause); 20 | } 21 | 22 | public InvalidPropertyFile(Throwable cause) { 23 | super(cause); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ManualCodeStyleManagerDelegator.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.formatting.FormattingMode; 4 | import com.intellij.openapi.diagnostic.Logger; 5 | import com.intellij.openapi.editor.Document; 6 | import com.intellij.openapi.project.Project; 7 | import com.intellij.openapi.util.TextRange; 8 | import com.intellij.psi.PsiFile; 9 | import com.intellij.psi.codeStyle.CodeStyleManager; 10 | import com.intellij.psi.codeStyle.FormattingModeAwareIndentAdjuster; 11 | import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl; 12 | import com.intellij.serviceContainer.NonInjectable; 13 | import com.intellij.util.IncorrectOperationException; 14 | import krasa.formatter.settings.ProjectComponent; 15 | import org.jetbrains.annotations.NotNull; 16 | 17 | import java.util.Collection; 18 | 19 | public class ManualCodeStyleManagerDelegator extends DelegatingCodeStyleManager implements FormattingModeAwareIndentAdjuster { 20 | private static final Logger log = Logger.getInstance(ManualCodeStyleManagerDelegator.class.getName()); 21 | 22 | private EclipseCodeStyleManager eclipseCodeStyleManager; 23 | 24 | public ManualCodeStyleManagerDelegator(Project p) { 25 | CodeStyleManagerImpl codeStyleManager = new CodeStyleManagerImpl(p); 26 | 27 | this.eclipseCodeStyleManager = new EclipseCodeStyleManager_IJ_2016_3plus(codeStyleManager, ProjectComponent.getSettings(p)); 28 | this.original = codeStyleManager; 29 | } 30 | 31 | @NonInjectable 32 | public ManualCodeStyleManagerDelegator(@NotNull CodeStyleManager original, EclipseCodeStyleManager eclipseCodeStyleManager) { 33 | super(original); 34 | this.eclipseCodeStyleManager = eclipseCodeStyleManager; 35 | } 36 | 37 | @Override 38 | public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collection collection) throws IncorrectOperationException { 39 | eclipseCodeStyleManager.reformatTextWithContext(psiFile, collection); 40 | } 41 | 42 | @Override 43 | public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges) throws IncorrectOperationException { 44 | eclipseCodeStyleManager.reformatText(psiFile, textRanges); 45 | } 46 | 47 | @Override 48 | public void reformatText(@NotNull PsiFile psiFile, int startOffset, int endOffset) throws IncorrectOperationException { 49 | eclipseCodeStyleManager.reformatText(psiFile, startOffset, endOffset); 50 | } 51 | 52 | @Override 53 | public int adjustLineIndent(@NotNull Document document, int offset, FormattingMode formattingMode) { 54 | if (original instanceof FormattingModeAwareIndentAdjuster) { 55 | return ((FormattingModeAwareIndentAdjuster) original).adjustLineIndent(document, offset, formattingMode); 56 | } else { 57 | return offset; 58 | } 59 | } 60 | 61 | @Override 62 | public FormattingMode getCurrentFormattingMode() { 63 | if (original instanceof FormattingModeAwareIndentAdjuster) { 64 | return ((FormattingModeAwareIndentAdjuster) original).getCurrentFormattingMode(); 65 | } else { 66 | return FormattingMode.REFORMAT; 67 | } 68 | } 69 | 70 | public EclipseCodeStyleManager getEclipseCodeStyleManager() { 71 | return eclipseCodeStyleManager; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/Mode.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | /** 4 | * @author Vojtech Krasa 5 | */ 6 | public enum Mode { 7 | ALWAYS_FORMAT, 8 | WITH_CTRL_SHIFT_ENTER_CHECK; 9 | 10 | boolean shouldReformat(boolean wholeFileOrSelectedText) { 11 | switch (this) { 12 | /* when formatting only vcs changes, this is needed. */ 13 | case ALWAYS_FORMAT: 14 | return true; 15 | /* live templates gets broken without that */ 16 | case WITH_CTRL_SHIFT_ENTER_CHECK: 17 | return wholeFileOrSelectedText; 18 | } 19 | return true; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/Notifier.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.notification.Notification; 4 | import com.intellij.notification.NotificationType; 5 | import com.intellij.notification.Notifications; 6 | import com.intellij.openapi.actionSystem.AnAction; 7 | import com.intellij.openapi.actionSystem.AnActionEvent; 8 | import com.intellij.openapi.application.ApplicationManager; 9 | import com.intellij.openapi.options.ShowSettingsUtil; 10 | import com.intellij.openapi.project.Project; 11 | import com.intellij.psi.PsiFile; 12 | import krasa.formatter.exception.InvalidSettingsException; 13 | import krasa.formatter.settings.ProjectComponent; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | /** 17 | * @author Vojtech Krasa 18 | */ 19 | public class Notifier { 20 | 21 | public static final String NO_FILE_TO_FORMAT = "No file to format"; 22 | 23 | 24 | 25 | public void notifyFailedFormatting(PsiFile psiFile, boolean formattedByIntelliJ, Exception e) { 26 | String error = e.getMessage() == null ? "" : e.getMessage(); 27 | notifyFailedFormatting(psiFile, formattedByIntelliJ, e, error); 28 | } 29 | 30 | public void notifyFailedFormatting(PsiFile psiFile, boolean formattedByIntelliJ, Exception e, final String reason) { 31 | String content; 32 | if (!formattedByIntelliJ) { 33 | if (e instanceof InvalidSettingsException) { 34 | content = psiFile.getName() + " failed to format. " + reason + "\n"; 35 | } else { 36 | content = psiFile.getName() + " failed to format with Adapter for Eclipse Code Formatter. " + reason 37 | + "\n"; 38 | } 39 | } else { 40 | content = psiFile.getName() + " failed to format with IntelliJ code formatter.\n" + reason; 41 | } 42 | Notification notification = ProjectComponent.getNotificationGroupError().createNotification(content, 43 | NotificationType.ERROR); 44 | 45 | if (e instanceof InvalidSettingsException) { 46 | notification.addAction(new AnAction("Open Settings") { 47 | @Override 48 | public void actionPerformed(@NotNull AnActionEvent anActionEvent) { 49 | notification.expire(); 50 | ShowSettingsUtil.getInstance().showSettingsDialog(getEventProject(anActionEvent), 51 | "Adapter for Eclipse Code Formatter"); 52 | } 53 | }); 54 | } 55 | showNotification(notification, psiFile.getProject()); 56 | } 57 | 58 | void notifyFormattingWasDisabled(PsiFile psiFile) { 59 | Notification notification = ProjectComponent.getNotificationGroupInfo().createNotification( 60 | psiFile.getName() + " - formatting was disabled for this file type", NotificationType.WARNING); 61 | showNotification(notification, psiFile.getProject()); 62 | } 63 | 64 | void notifySuccessFormatting(PsiFile psiFile, boolean formattedByIntelliJ) { 65 | String content; 66 | if (formattedByIntelliJ) { 67 | content = psiFile.getName() + " formatted successfully by IntelliJ code formatter"; 68 | } else { 69 | content = psiFile.getName() + " formatted successfully by Adapter for Eclipse Code Formatter"; 70 | } 71 | Notification notification = ProjectComponent.getNotificationGroupInfo().createNotification(content, 72 | NotificationType.INFORMATION); 73 | showNotification(notification, psiFile.getProject()); 74 | } 75 | 76 | void showNotification(final Notification notification, final Project project) { 77 | ApplicationManager.getApplication().invokeLater(new Runnable() { 78 | @Override 79 | public void run() { 80 | Notifications.Bus.notify(notification, project); 81 | } 82 | }); 83 | } 84 | 85 | public void notifyBrokenImportSorter(Project project) { 86 | String content = "Formatting failed due to a new Import optimizer."; 87 | Notification notification = ProjectComponent.getNotificationGroupError().createNotification(content, 88 | NotificationType.ERROR); 89 | showNotification(notification, project); 90 | 91 | } 92 | 93 | public static void notifyDeletedSettings(final Project project) { 94 | String content = "Adapter for Eclipse Code Formatter - settings profile was deleted for project " + project.getName() 95 | + ". Check the configuration."; 96 | final Notification notification = ProjectComponent.getNotificationGroupError().createNotification(content, 97 | NotificationType.ERROR); 98 | ApplicationManager.getApplication().invokeLater(new Runnable() { 99 | @Override 100 | public void run() { 101 | Notifications.Bus.notify(notification, project); 102 | } 103 | }); 104 | } 105 | public static void notifyProfileDoesNotExist(Project project) { 106 | String content = "Adapter for Eclipse Code Formatter - Global profile does not exist for project " + project.getName() 107 | + ". Check the configuration."; 108 | final Notification notification = ProjectComponent.getNotificationGroupError().createNotification(content, 109 | NotificationType.ERROR); 110 | ApplicationManager.getApplication().invokeLater(() -> Notifications.Bus.notify(notification, project)); 111 | } 112 | public void configurationError(Exception e, Project project) { 113 | Notification notification = ProjectComponent.getNotificationGroupError() 114 | .createNotification("Eclipse Formatter configuration error: " + e.getMessage(), NotificationType.ERROR); 115 | showNotification(notification, project); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ProjectCodeStyleInstaller.java: -------------------------------------------------------------------------------- 1 | /* 2 | * External Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the 3 | * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 4 | * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the 5 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 6 | * the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | package krasa.formatter.plugin; 10 | 11 | import com.intellij.ide.plugins.IdeaPluginDescriptor; 12 | import com.intellij.ide.plugins.PluginManager; 13 | import com.intellij.openapi.diagnostic.Logger; 14 | import com.intellij.openapi.extensions.PluginId; 15 | import com.intellij.openapi.project.Project; 16 | import com.intellij.psi.codeStyle.CodeStyleManager; 17 | import com.intellij.serviceContainer.ComponentManagerImpl; 18 | import krasa.formatter.settings.Settings; 19 | import org.jetbrains.annotations.NotNull; 20 | 21 | import static krasa.formatter.plugin.ProxyUtils.createProxy; 22 | 23 | /** 24 | * Switches a project's {@link CodeStyleManager} to a eclipse formatter and back. 25 | * 26 | * @author Esko Luontola 27 | * @author Vojtech Krasa 28 | * @since 2.12.2007 29 | */ 30 | public class ProjectCodeStyleInstaller { 31 | 32 | private static final String CODE_STYLE_MANAGER_KEY = CodeStyleManager.class.getName(); 33 | private static final Logger LOG = Logger.getInstance(ProjectCodeStyleInstaller.class.getName()); 34 | 35 | @NotNull 36 | private final Project project; 37 | 38 | public ProjectCodeStyleInstaller(@NotNull Project project) { 39 | this.project = project; 40 | } 41 | 42 | @NotNull 43 | public Project getProject() { 44 | return project; 45 | } 46 | 47 | public EclipseCodeStyleManager install(@NotNull Settings settings) { 48 | CodeStyleManager currentManager = CodeStyleManager.getInstance(project); 49 | 50 | EclipseCodeStyleManager overridingObject; 51 | if (compatibleWith_2016_3_API()) { 52 | overridingObject = new EclipseCodeStyleManager_IJ_2016_3plus(currentManager, settings); 53 | } else { 54 | overridingObject = new EclipseCodeStyleManager(currentManager, settings); 55 | } 56 | CodeStyleManager proxy = createProxy(currentManager, overridingObject); 57 | // CodeStyleManager proxy = new ManualCodeStyleManagerDelegator(currentManager, overridingObject); 58 | 59 | LOG.info("Overriding " + currentManager.getClass().getCanonicalName() + " with " 60 | + overridingObject.getClass().getCanonicalName() + "' for project '" + project.getName() 61 | + "' using CGLIB proxy"); 62 | registerCodeStyleManager(project, proxy); 63 | return overridingObject; 64 | } 65 | 66 | private boolean compatibleWith_2016_3_API() { 67 | Class aClass = null; 68 | try { 69 | aClass = Class.forName("com.intellij.psi.codeStyle.ChangedRangesInfo"); 70 | } catch (ClassNotFoundException e) { 71 | } 72 | return aClass != null; 73 | } 74 | 75 | /** 76 | * Dmitry Jemerov in unrelated discussion: "Trying to replace IDEA's core components with your custom 77 | * implementations is something that we consider a very bad idea, and it's pretty much guaranteed to break in future 78 | * versions of IntelliJ IDEA. I certainly hope that you won't stomp on any other plugins doing that, because no one 79 | * else is doing it. It would be better to find another approach to solving your problem." 80 | *

81 | * lol 82 | */ 83 | private static void registerCodeStyleManager(@NotNull Project project, @NotNull CodeStyleManager newManager) { 84 | ComponentManagerImpl platformComponentManager = (ComponentManagerImpl) project; 85 | IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId("EclipseCodeFormatter")); 86 | platformComponentManager.registerServiceInstance(CodeStyleManager.class, newManager, plugin); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ProxyCodeStyleManagerDelegator.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | import com.intellij.openapi.diagnostic.Logger; 4 | import com.intellij.psi.codeStyle.CodeStyleManager; 5 | import net.sf.cglib.proxy.InvocationHandler; 6 | 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | import java.util.Arrays; 10 | import java.util.HashSet; 11 | import java.util.Set; 12 | 13 | public class ProxyCodeStyleManagerDelegator implements InvocationHandler { 14 | private static final Logger log = Logger.getInstance(ProxyCodeStyleManagerDelegator.class.getName()); 15 | 16 | private final CodeStyleManager original; 17 | private final EclipseCodeStyleManager overridingObject; 18 | private final Set notOverriddenMethods = new HashSet(); 19 | 20 | public ProxyCodeStyleManagerDelegator(CodeStyleManager original, EclipseCodeStyleManager overriding) { 21 | this.original = original; 22 | this.overridingObject = overriding; 23 | } 24 | 25 | @Override 26 | public Object invoke(Object proxy, Method method, Object[] rawArguments) throws Throwable { 27 | if (!overridingObject.isEnabled() || notOverriddenMethods.contains(method)) { 28 | return PLEASE_REPORT_BUGS_TO_JETBRAINS_IF_IT_FAILS_HERE____ORIGINAL_INTELLIJ_FORMATTER_WAS_USED(method, rawArguments); 29 | } else { 30 | try { 31 | Method overridingMethod = getOverridingMethod(method); 32 | 33 | if (!compatibleReturnTypes(method.getReturnType(), overridingMethod.getReturnType())) { 34 | log.error("IntelliJ API changed, install proper/updated version of Eclipse Formatter plugin. " + "Incompatible return types when calling: " + method 35 | + " on: " + proxy.getClass().getSimpleName() + " return type should be: " + method.getReturnType().getSimpleName() + ", but was: " 36 | + overridingMethod.getReturnType().getSimpleName() + " (delegate instance had type: " + ((Object) overridingObject).getClass().getSimpleName() + ")"); 37 | return PLEASE_REPORT_BUGS_TO_JETBRAINS_IF_IT_FAILS_HERE____ORIGINAL_INTELLIJ_FORMATTER_WAS_USED(method, rawArguments); 38 | } 39 | if (log.isDebugEnabled()) { 40 | log.debug("invoking overriding {}({})", method.getName(), Arrays.toString(rawArguments)); 41 | } 42 | return overridingMethod.invoke(overridingObject, rawArguments); 43 | } catch (NoSuchMethodException e) { 44 | notOverriddenMethods.add(method); 45 | if (log.isDebugEnabled()) { 46 | log.debug("invoking original {}({})", method.getName(), Arrays.toString(rawArguments)); 47 | } 48 | 49 | return PLEASE_REPORT_BUGS_TO_JETBRAINS_IF_IT_FAILS_HERE____ORIGINAL_INTELLIJ_FORMATTER_WAS_USED(method, rawArguments); 50 | } catch (InvocationTargetException e) { 51 | // propagate the original exception from the delegate 52 | throw e.getCause(); 53 | } 54 | } 55 | } 56 | 57 | private Object PLEASE_REPORT_BUGS_TO_JETBRAINS_IF_IT_FAILS_HERE____ORIGINAL_INTELLIJ_FORMATTER_WAS_USED(Method invokedMethod, Object[] rawArguments) 58 | throws Throwable { 59 | try { 60 | return invokedMethod.invoke(original, rawArguments); 61 | } catch (InvocationTargetException e) { 62 | throw e.getCause(); 63 | } 64 | } 65 | 66 | private Method getOverridingMethod(Method mockMethod) throws NoSuchMethodException { 67 | return overridingObject.getClass().getMethod(mockMethod.getName(), mockMethod.getParameterTypes()); 68 | } 69 | 70 | private static boolean compatibleReturnTypes(Class required, Class overriding) { 71 | return required.equals(overriding) || required.isAssignableFrom(overriding); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ProxyUtils.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | 4 | import com.intellij.openapi.diagnostic.Logger; 5 | import com.intellij.psi.codeStyle.CodeStyleManager; 6 | import org.apache.commons.lang3.ClassUtils; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.List; 10 | 11 | public class ProxyUtils { 12 | private static final Logger LOG = Logger.getInstance(ProxyUtils.class.getName()); 13 | 14 | public static CodeStyleManager createProxy(CodeStyleManager original, EclipseCodeStyleManager overriding) { 15 | return (CodeStyleManager) net.sf.cglib.proxy.Enhancer.create(CodeStyleManager.class, 16 | getInterfaces(original), 17 | new ProxyCodeStyleManagerDelegator(original, overriding)); 18 | } 19 | 20 | @NotNull 21 | private static Class[] getInterfaces(CodeStyleManager manager) { 22 | List> allInterfaces = ClassUtils.getAllInterfaces(manager.getClass()); 23 | LOG.debug("Proxy interfaces " + allInterfaces); 24 | return allInterfaces.toArray(new Class[0]); 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/Range.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | /** 4 | * @author Vojtech Krasa 5 | */ 6 | public class Range { 7 | 8 | private int startOffset; 9 | private int endOffset; 10 | private boolean wholeFile; 11 | 12 | public Range(int startOffset, int endOffset, boolean wholeFile) { 13 | this.startOffset = startOffset; 14 | this.endOffset = endOffset; 15 | this.wholeFile = wholeFile; 16 | } 17 | 18 | public int getStartOffset() { 19 | return startOffset; 20 | } 21 | 22 | public void setStartOffset(int startOffset) { 23 | this.startOffset = startOffset; 24 | } 25 | 26 | public int getEndOffset() { 27 | return endOffset; 28 | } 29 | 30 | public void setEndOffset(int endOffset) { 31 | this.endOffset = endOffset; 32 | } 33 | 34 | public boolean isWholeFile() { 35 | return wholeFile; 36 | } 37 | 38 | public void setWholeFile(boolean wholeFile) { 39 | this.wholeFile = wholeFile; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/plugin/ReformatItInIntelliJ.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.plugin; 2 | 3 | /** 4 | * I know, don't judge me. 5 | * 6 | * @author Vojtech Krasa 7 | */ 8 | public class ReformatItInIntelliJ extends RuntimeException { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/processor/Processor.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.processor; 2 | 3 | import com.intellij.openapi.editor.Document; 4 | import com.intellij.psi.PsiFile; 5 | import krasa.formatter.plugin.Range; 6 | 7 | /** 8 | * @author Vojtech Krasa 9 | */ 10 | public interface Processor { 11 | boolean process(Document document, PsiFile psiFile, Range range); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/DeletedProfileException.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings; 2 | 3 | public class DeletedProfileException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/DisabledFileTypeSettings.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author Vojtech Krasa 8 | */ 9 | public class DisabledFileTypeSettings { 10 | 11 | private List disabledTypes = new ArrayList(); 12 | 13 | public DisabledFileTypeSettings(String disabledFileTypes) { 14 | for (String group : disabledFileTypes.split(";")) { 15 | if (group.isEmpty()) { 16 | continue; 17 | } 18 | disabledTypes.add(group.trim()); 19 | } 20 | } 21 | 22 | public boolean isDisabled(String path) { 23 | for (String disabledType : disabledTypes) { 24 | boolean b = path.endsWith(disabledType); 25 | if (b) { 26 | return true; 27 | } 28 | } 29 | return false; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/GlobalProfileReference.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings; 2 | 3 | import java.util.Objects; 4 | 5 | public class GlobalProfileReference { 6 | private String name = null; 7 | private Long id = null; 8 | 9 | public GlobalProfileReference() { 10 | } 11 | 12 | public GlobalProfileReference(Long id, String name) { 13 | this.name = name; 14 | this.id = id; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public Long getId() { 26 | return id; 27 | } 28 | 29 | public void setId(Long id) { 30 | this.id = id; 31 | } 32 | 33 | @Override 34 | public boolean equals(Object o) { 35 | if (this == o) return true; 36 | if (o == null || getClass() != o.getClass()) return false; 37 | GlobalProfileReference that = (GlobalProfileReference) o; 38 | return Objects.equals(name, that.name) && Objects.equals(id, that.id); 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | return Objects.hash(name, id); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | final StringBuilder sb = new StringBuilder("GlobalProfileReference{"); 49 | sb.append("id=").append(id); 50 | sb.append(", name='").append(name).append('\''); 51 | sb.append('}'); 52 | return sb.toString(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/IllegalSettingsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * External Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the 3 | * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 4 | * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the 5 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 6 | * the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | package krasa.formatter.settings; 10 | 11 | import org.jetbrains.annotations.NotNull; 12 | 13 | /** 14 | * @author Esko Luontola 15 | * @since 5.12.2007 16 | */ 17 | public class IllegalSettingsException extends Exception { 18 | 19 | @NotNull 20 | private final String field; 21 | @NotNull 22 | private final String errorKey; 23 | @NotNull 24 | private final String[] errorParams; 25 | 26 | public IllegalSettingsException(@NotNull String field, @NotNull String errorKey, @NotNull String... errorParams) { 27 | super(field + ": " + errorKey); 28 | this.field = field; 29 | this.errorKey = errorKey; 30 | this.errorParams = errorParams; 31 | } 32 | 33 | @NotNull 34 | public String getField() { 35 | return field; 36 | } 37 | 38 | @NotNull 39 | public String getErrorKey() { 40 | return errorKey; 41 | } 42 | 43 | @NotNull 44 | public String[] getErrorParams() { 45 | return errorParams; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/MyConfigurable.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings; 2 | 3 | import com.intellij.openapi.options.Configurable; 4 | import com.intellij.openapi.options.ConfigurationException; 5 | import com.intellij.openapi.project.Project; 6 | import krasa.formatter.Messages; 7 | import krasa.formatter.plugin.ProjectSettingsForm; 8 | import krasa.formatter.utils.ProjectUtils; 9 | import org.apache.commons.lang3.ObjectUtils; 10 | import org.jetbrains.annotations.Nls; 11 | import org.jetbrains.annotations.NonNls; 12 | import org.jetbrains.annotations.NotNull; 13 | import org.jetbrains.annotations.Nullable; 14 | 15 | import javax.swing.*; 16 | 17 | // implements Configurable 18 | public class MyConfigurable implements Configurable { 19 | 20 | private final ProjectSettings projectSettings; 21 | private Project project; 22 | @Nullable 23 | private ProjectSettingsForm form; 24 | 25 | public MyConfigurable(ProjectSettings projectSettings, Project project) { 26 | this.projectSettings = projectSettings; 27 | this.project = project; 28 | } 29 | 30 | @Override 31 | @Nls 32 | public String getDisplayName() { 33 | return Messages.message("action.pluginSettings"); 34 | } 35 | 36 | 37 | @Override 38 | @Nullable 39 | @NonNls 40 | public String getHelpTopic() { 41 | return "EclipseCodeFormatter.Configuration"; 42 | } 43 | 44 | @Override 45 | @NotNull 46 | public JComponent createComponent() { 47 | if (form == null) { 48 | form = new ProjectSettingsForm(project, this); 49 | } 50 | return form.getRootComponent(); 51 | } 52 | 53 | @Override 54 | public boolean isModified() { 55 | return form != null && 56 | (form.isModified(projectSettings.getSelectedProfile()) 57 | || (form.getDisplayedSettings() != null && !isSameId()) 58 | || (!ObjectUtils.equals(GlobalSettings.getInstance().getPathToEclipse(), form.pathToCustomEclipse.getText())) 59 | ); 60 | } 61 | 62 | private boolean isSameId() { 63 | return ObjectUtils.equals(form.getDisplayedSettings().getId(), projectSettings.getSelectedProfile().getId()); 64 | } 65 | 66 | @Override 67 | public void apply() throws ConfigurationException { 68 | if (form != null) { 69 | form.validate(); 70 | Settings profile = form.exportDisplayedSettings(); 71 | 72 | GlobalSettings.getInstance().setPathToEclipse(form.pathToCustomEclipse.getText()); 73 | 74 | projectSettings.setProfile(profile); 75 | 76 | if (!profile.isProjectSpecific()) { 77 | GlobalSettings.getInstance().updateSettings(profile, project); 78 | } 79 | 80 | if (!project.isDefault()) { 81 | if (profile.isProjectSpecific()) { 82 | ProjectComponent.getInstance(project).installOrUpdate(profile); 83 | } else { 84 | ProjectUtils.applyToAllOpenedProjects(profile); 85 | } 86 | } 87 | } 88 | } 89 | 90 | @Override 91 | public void reset() { 92 | if (form != null) { 93 | form.importFrom(projectSettings.getSelectedProfile()); 94 | form.pathToCustomEclipse.setText(GlobalSettings.getInstance().getPathToEclipse()); 95 | } 96 | } 97 | 98 | @Override 99 | public void disposeUIResources() { 100 | form = null; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/MyConfigurableProvider.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings; 2 | 3 | import com.intellij.openapi.components.ServiceManager; 4 | import com.intellij.openapi.options.Configurable; 5 | import com.intellij.openapi.options.ConfigurableProvider; 6 | import com.intellij.openapi.project.Project; 7 | import org.jetbrains.annotations.NotNull; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public class MyConfigurableProvider extends ConfigurableProvider { 11 | private final Project myProject; 12 | 13 | public MyConfigurableProvider(@NotNull Project project) { 14 | myProject = project; 15 | } 16 | 17 | @Nullable 18 | @Override 19 | public Configurable createConfigurable() { 20 | return new MyConfigurable(ServiceManager.getService(myProject, ProjectSettings.class), myProject); 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/ProjectComponent.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings;/* 2 | * External Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the 3 | * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 4 | * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the 5 | * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for 6 | * the specific language governing permissions and limitations under the License. 7 | */ 8 | 9 | 10 | import com.intellij.notification.NotificationGroup; 11 | import com.intellij.notification.NotificationGroupManager; 12 | import com.intellij.openapi.diagnostic.Logger; 13 | import com.intellij.openapi.project.Project; 14 | import com.intellij.psi.PsiFile; 15 | import krasa.formatter.plugin.EclipseCodeStyleManager; 16 | import krasa.formatter.plugin.ProjectCodeStyleInstaller; 17 | import org.jetbrains.annotations.NotNull; 18 | 19 | /** 20 | * Takes care of initializing a project's CodeFormatter and disposing of it when the project is closed. Updates the 21 | * formatter whenever the plugin stateComponent.getState() are changed. 22 | * 23 | * @author Esko Luontola 24 | * @since 4.12.2007 25 | */ 26 | public class ProjectComponent implements com.intellij.openapi.components.ProjectComponent { 27 | 28 | private static final Logger LOG = Logger.getInstance(ProjectComponent.class.getName()); 29 | 30 | @NotNull 31 | public static NotificationGroup getNotificationGroupError() { 32 | return NotificationGroupManager.getInstance().getNotificationGroup("Adapter for Eclipse Code Formatter error"); 33 | } 34 | 35 | @NotNull 36 | public static NotificationGroup getNotificationGroupInfo() { 37 | return NotificationGroupManager.getInstance().getNotificationGroup("Adapter for Eclipse Code Formatter info"); 38 | 39 | } 40 | 41 | @NotNull 42 | private final ProjectCodeStyleInstaller projectCodeStyle; 43 | @NotNull 44 | protected Project project; 45 | @NotNull 46 | private ProjectSettings projectSettings; 47 | private EclipseCodeStyleManager eclipseCodeStyleManager; 48 | 49 | public ProjectComponent(@NotNull Project project) { 50 | this.projectCodeStyle = new ProjectCodeStyleInstaller(project); 51 | this.project = project; 52 | this.projectSettings = ProjectSettings.getInstance(project); 53 | } 54 | 55 | public static Settings getSettings(PsiFile psiFile) { 56 | return getInstance(psiFile.getProject()).getSelectedProfile(); 57 | } 58 | 59 | public static Settings getSettings(Project project) { 60 | return getInstance(project).getSelectedProfile(); 61 | } 62 | 63 | @Override 64 | public void initComponent() { 65 | } 66 | 67 | 68 | @Override 69 | public void disposeComponent() { 70 | } 71 | 72 | @Override 73 | @NotNull 74 | public String getComponentName() { 75 | return "ProjectSettingsComponent"; 76 | } 77 | 78 | @Override 79 | public void projectOpened() { 80 | projectSettings.projectOpened(); 81 | installOrUpdate(projectSettings.getSelectedProfile()); 82 | } 83 | 84 | public void installOrUpdate(@NotNull Settings settings) { 85 | if (eclipseCodeStyleManager == null) { 86 | eclipseCodeStyleManager = projectCodeStyle.install(settings); 87 | } else { 88 | eclipseCodeStyleManager.updateSettings(settings); 89 | } 90 | } 91 | 92 | @Override 93 | public void projectClosed() { 94 | } 95 | 96 | @NotNull 97 | public Project getProject() { 98 | return project; 99 | } 100 | 101 | @NotNull 102 | public Settings getSelectedProfile() { 103 | return projectSettings.getSelectedProfile(); 104 | } 105 | 106 | public void globalProfileUpdated(@NotNull Settings updatedGlobalProfile) { 107 | projectSettings.globalProfileUpdated(updatedGlobalProfile); 108 | installOrUpdate(projectSettings.getSelectedProfile()); 109 | } 110 | 111 | @NotNull 112 | public ProjectSettings getProjectSettings() { 113 | return projectSettings; 114 | } 115 | 116 | public static ProjectComponent getInstance(Project project) { 117 | return project.getComponent(ProjectComponent.class); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/ProjectSettings.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings; 2 | 3 | import com.intellij.openapi.components.PersistentStateComponent; 4 | import com.intellij.openapi.components.State; 5 | import com.intellij.openapi.components.Storage; 6 | import com.intellij.openapi.project.Project; 7 | import com.intellij.util.xmlb.XmlSerializerUtil; 8 | import com.intellij.util.xmlb.annotations.Transient; 9 | import krasa.formatter.plugin.Notifier; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | @State(name = "EclipseCodeFormatterProjectSettings", storages = {@Storage("eclipseCodeFormatter.xml")}) 13 | public class ProjectSettings implements PersistentStateComponent { 14 | 15 | private ProjectSpecificProfile projectSpecificProfile = new ProjectSpecificProfile(); 16 | private Settings selectedGlobalProfile; 17 | private GlobalProfileReference selectedGlobalProfileReference; 18 | @Transient 19 | private transient Project project; 20 | 21 | public ProjectSettings() { 22 | } 23 | 24 | public ProjectSettings(@NotNull Project project) { 25 | this.project = project; 26 | } 27 | 28 | @NotNull 29 | public ProjectSpecificProfile getProjectSpecificProfile() { 30 | return projectSpecificProfile; 31 | } 32 | 33 | public void setProjectSpecificProfile(ProjectSpecificProfile projectSpecificProfile) { 34 | this.projectSpecificProfile = projectSpecificProfile; 35 | } 36 | 37 | public Settings getSelectedGlobalProfile() { 38 | return selectedGlobalProfile; 39 | } 40 | 41 | public void setSelectedGlobalProfile(Settings selectedGlobalProfile) { 42 | this.selectedGlobalProfile = selectedGlobalProfile; 43 | } 44 | 45 | @Override 46 | @NotNull 47 | public ProjectSettings getState() { 48 | if (this.selectedGlobalProfile != null && !this.selectedGlobalProfile.isBackupToProjectConfigFile()) { 49 | ProjectSettings projectSettings = new ProjectSettings(); 50 | projectSettings.projectSpecificProfile = this.projectSpecificProfile; 51 | projectSettings.selectedGlobalProfileReference = new GlobalProfileReference(this.selectedGlobalProfile.getId(), selectedGlobalProfile.getName()); 52 | return projectSettings; 53 | } else { 54 | return this; 55 | } 56 | } 57 | 58 | @Override 59 | public void loadState(ProjectSettings state) { 60 | XmlSerializerUtil.copyBean(state, this); 61 | } 62 | 63 | public static ProjectSettings getInstance(Project project) { 64 | return project.getService(ProjectSettings.class); 65 | } 66 | 67 | public Settings getSelectedProfile() { 68 | Settings selectedGlobalProfile = getSelectedGlobalProfile(); 69 | if (selectedGlobalProfile != null) { 70 | return selectedGlobalProfile; 71 | } 72 | return getProjectSpecificProfile(); 73 | } 74 | 75 | public void setProfile(Settings profile) { 76 | if (profile.isProjectSpecific()) { 77 | this.setProjectSpecificProfile((ProjectSpecificProfile) profile); 78 | this.setSelectedGlobalProfile(null); 79 | this.setSelectedGlobalProfileReference(null); 80 | } else { 81 | this.setSelectedGlobalProfile(profile); 82 | this.setSelectedGlobalProfileReference(null); 83 | } 84 | } 85 | 86 | public void globalProfileUpdated(Settings updatedGlobalProfile) { 87 | final Settings.Formatter formatter = getSelectedProfile().getFormatter(); 88 | setProfile(GlobalSettings.clone(updatedGlobalProfile)); 89 | getSelectedProfile().setFormatter(formatter); 90 | } 91 | 92 | public void projectOpened() { 93 | syncGlobalProfile(); 94 | GlobalSettings.getInstance().migrateSettings(this); 95 | } 96 | 97 | private void syncGlobalProfile() { 98 | Settings selectedGlobalProfile = this.selectedGlobalProfile; 99 | if (selectedGlobalProfile != null) { 100 | Settings.Formatter formatter = selectedGlobalProfile.getFormatter(); 101 | Settings clone = null; 102 | try { 103 | Settings globalProfile = GlobalSettings.getInstance().findGlobalProfile(selectedGlobalProfile, project); 104 | clone = GlobalSettings.clone(globalProfile); 105 | clone.setFormatter(formatter); 106 | } catch (DeletedProfileException e) { 107 | Notifier.notifyDeletedSettings(project); 108 | } 109 | this.selectedGlobalProfile = clone; 110 | } else if (selectedGlobalProfileReference != null) { 111 | try { 112 | Settings globalProfile = GlobalSettings.getInstance().findGlobalProfile(selectedGlobalProfileReference, project); 113 | if (globalProfile != null) { 114 | this.selectedGlobalProfile = GlobalSettings.clone(globalProfile); 115 | } else { 116 | Notifier.notifyProfileDoesNotExist(project); 117 | } 118 | } catch (DeletedProfileException e) { 119 | Notifier.notifyDeletedSettings(project); 120 | } 121 | } 122 | } 123 | 124 | public GlobalProfileReference getSelectedGlobalProfileReference() { 125 | return selectedGlobalProfileReference; 126 | } 127 | 128 | public void setSelectedGlobalProfileReference(GlobalProfileReference selectedGlobalProfileReference) { 129 | this.selectedGlobalProfileReference = selectedGlobalProfileReference; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/ProjectSpecificProfile.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings; 2 | 3 | public class ProjectSpecificProfile extends Settings { 4 | public ProjectSpecificProfile() { 5 | super(null, ""); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/provider/CachedPropertiesProvider.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings.provider; 2 | 3 | import krasa.formatter.common.ModifiableFile; 4 | import krasa.formatter.plugin.InvalidPropertyFile; 5 | import krasa.formatter.utils.FileUtils; 6 | 7 | import java.io.File; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Properties; 11 | 12 | /** 13 | * @author Vojtech Krasa 14 | */ 15 | public class CachedPropertiesProvider extends CachedProvider { 16 | 17 | protected CachedPropertiesProvider(ModifiableFile modifiableFile) { 18 | super(modifiableFile); 19 | } 20 | 21 | /** 22 | * Return a Java Properties object representing the options that are in the specified configuration file. 23 | */ 24 | @Override 25 | protected Properties readFile(File file) throws InvalidPropertyFile { 26 | final Properties formatterOptions = FileUtils.readPropertiesFile(file, createDefaultConfig()); 27 | // Properties.load() does not trim trailing whitespace from prop values, so trim it ourselves, since it would 28 | // cause the Eclipse formatter to fail to parse the values. 29 | trimTrailingWhitespaceFromConfigValues(formatterOptions); 30 | validateConfig(formatterOptions, file); 31 | return formatterOptions; 32 | } 33 | 34 | protected Properties readXmlFile(File file, String profile) { 35 | final Properties formatterOptions = FileUtils.readXmlJavaSettingsFile(file, createDefaultConfig(), profile); 36 | trimTrailingWhitespaceFromConfigValues(formatterOptions); 37 | validateConfig(formatterOptions, file); 38 | return formatterOptions; 39 | } 40 | 41 | protected void trimTrailingWhitespaceFromConfigValues(Properties config) { 42 | // First trim the values and store the trimmed values in a temporary map. 43 | Map map = new HashMap(config.size()); 44 | for (Object key : config.keySet()) { 45 | String optionName = (String) key; 46 | String optionValue = config.getProperty(optionName); 47 | map.put(optionName, (optionValue != null) ? optionValue.trim() : null); 48 | } 49 | // Then copy the values back to the original Properties object. 50 | for (String key : map.keySet()) { 51 | config.setProperty(key, map.get(key)); 52 | } 53 | } 54 | 55 | protected void validateConfig(Properties config, File file) { 56 | if (config.size() < 100) { 57 | throw new InvalidPropertyFile("Use a project specific or custom formatter profile in Eclipse!" + " Loaded only " + config.size() + " properties from: " + file.getAbsolutePath() + ", should be 100+.", file); 58 | } 59 | } 60 | 61 | protected void validateEPFConfig(Properties config, File file) { 62 | if (config.size() < 100) { 63 | throw new InvalidPropertyFile("Invalid EPF config!" + " Loaded only " + config.size() + " `org.eclipse.jdt.core.formatter` properties from: " + file.getAbsolutePath() + ", should be 100+.", file); 64 | } 65 | } 66 | 67 | protected Properties createDefaultConfig() { 68 | return new Properties(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/provider/CachedProvider.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings.provider; 2 | 3 | import krasa.formatter.common.ModifiableFile; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | * @author Vojtech Krasa 9 | */ 10 | public abstract class CachedProvider { 11 | private ModifiableFile modifiableFile; 12 | private ModifiableFile.Monitor lastState; 13 | private T cachedValue; 14 | 15 | protected CachedProvider(ModifiableFile modifiableFile) { 16 | this.modifiableFile = modifiableFile; 17 | } 18 | 19 | public ModifiableFile getModifiableFile() { 20 | return modifiableFile; 21 | } 22 | 23 | protected abstract T readFile(File file); 24 | 25 | public T get() { 26 | if (cachedValue == null || modifiableFile.wasChanged(lastState)) { 27 | cachedValue = readFile(modifiableFile); 28 | saveLastModified(); 29 | } 30 | return cachedValue; 31 | } 32 | 33 | public ModifiableFile.Monitor getModifiedMonitor() { 34 | return modifiableFile.getModifiedMonitor(); 35 | } 36 | 37 | public boolean wasChanged() { 38 | return lastState == null || modifiableFile.wasChanged(lastState); 39 | } 40 | 41 | private void saveLastModified() { 42 | lastState = modifiableFile.getModifiedMonitor(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/provider/ImportOrderProvider.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings.provider; 2 | 3 | import krasa.formatter.common.ModifiableFile; 4 | import krasa.formatter.exception.ParsingFailedException; 5 | import krasa.formatter.settings.Settings; 6 | import krasa.formatter.utils.FileUtils; 7 | import krasa.formatter.utils.StringUtils; 8 | 9 | import java.io.File; 10 | import java.util.*; 11 | 12 | /** 13 | * @author Vojtech Krasa 14 | */ 15 | public class ImportOrderProvider extends CachedProvider> { 16 | 17 | public ImportOrderProvider(Settings settings) { 18 | super(new ModifiableFile(settings.getImportOrderConfigFilePath())); 19 | } 20 | 21 | public static List toList(String importOrder) { 22 | return StringUtils.trimToList(importOrder); 23 | } 24 | 25 | @Override 26 | protected List readFile(File file) { 27 | Properties properties = FileUtils.readPropertiesFile(file); 28 | String property = properties.getProperty("org.eclipse.jdt.ui.importorder"); 29 | List order; 30 | if (property != null) { 31 | order = toList(property); 32 | } else if (property == null && file.getName().toLowerCase().endsWith(".prefs")) { 33 | throw new ParsingFailedException( 34 | "File is missing a property 'org.eclipse.jdt.ui.importorder', see instructions."); 35 | } else if (file.getName().toLowerCase().endsWith(".importorder")) { 36 | order = loadImportOrderFile(properties); 37 | } else { 38 | throw new ParsingFailedException( 39 | "You must provide either *.importorder file or 'org.eclipse.jdt.ui.prefs' file, see instructions."); 40 | } 41 | return order; 42 | } 43 | 44 | private List loadImportOrderFile(Properties file) { 45 | TreeMap treeMap = new TreeMap(new Comparator() { 46 | @Override 47 | public int compare(String o1, String o2) { 48 | return Integer.parseInt(o1) - Integer.parseInt(o2); 49 | } 50 | }); 51 | treeMap.putAll(file); 52 | return new ArrayList(treeMap.values()); 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/settings/provider/JavaPropertiesProvider.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings.provider; 2 | 3 | import com.intellij.openapi.vfs.VirtualFile; 4 | import com.intellij.util.PathUtil; 5 | import krasa.formatter.common.ModifiableFile; 6 | import krasa.formatter.plugin.InvalidPropertyFile; 7 | import krasa.formatter.settings.Settings; 8 | import krasa.formatter.utils.FileUtils; 9 | 10 | import java.io.File; 11 | import java.util.Properties; 12 | 13 | /** 14 | * @author Vojtech Krasa 15 | */ 16 | public class JavaPropertiesProvider extends CachedPropertiesProvider { 17 | protected String profile; 18 | 19 | 20 | public JavaPropertiesProvider(Settings settings) { 21 | this(settings.getPathToConfigFileJava(), settings.getSelectedJavaProfile()); 22 | } 23 | 24 | public JavaPropertiesProvider(String pathToConfigFileJava, String selectedJavaProfile) { 25 | super(new ModifiableFile(pathToConfigFileJava)); 26 | this.profile = selectedJavaProfile; 27 | } 28 | 29 | @Override 30 | protected Properties readFile(File file) throws InvalidPropertyFile { 31 | if (file.getName().toLowerCase().endsWith("xml")) { 32 | return readXmlFile(file, profile); 33 | } else if (file.getName().toLowerCase().endsWith("epf")) { 34 | return readWorkspaceMechanicFile(file); 35 | } else if (file.getName().toLowerCase().equals("org.eclipse.jdt.ui.prefs")) { 36 | return readWorkspaceFile(file); 37 | } else { 38 | // org.eclipse.jdt.core.prefs 39 | return super.readFile(file); 40 | } 41 | } 42 | 43 | private Properties readWorkspaceFile(File file) { 44 | Properties properties = FileUtils.readPropertiesFile(file); 45 | String xml = properties.getProperty("org.eclipse.jdt.ui.formatterprofiles"); 46 | Properties result = FileUtils.readXmlJavaSettingsFile(xml, properties, profile); 47 | trimTrailingWhitespaceFromConfigValues(result); 48 | validateConfig(result, file); 49 | return result; 50 | } 51 | 52 | private Properties readWorkspaceMechanicFile(final File file) { 53 | Properties properties = FileUtils.readPropertiesFile(file); 54 | Properties result = FileUtils.convertEPF(properties, createDefaultConfig()); 55 | validateEPFConfig(result, file); 56 | return result; 57 | } 58 | 59 | public boolean isSameFile(VirtualFile fileB) { 60 | String path = PathUtil.toSystemIndependentName(fileB.getPath()); 61 | String current = getModifiableFile().getSystemIndependentPath(); 62 | return current.equals(path); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/templates/LiveTemplatesProvider.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.templates; 2 | 3 | import com.intellij.codeInsight.template.impl.DefaultLiveTemplatesProvider; 4 | 5 | public class LiveTemplatesProvider implements DefaultLiveTemplatesProvider { 6 | @Override 7 | public String[] getDefaultLiveTemplateFiles() { 8 | return new String[]{"/liveTemplates/templates"}; 9 | } 10 | 11 | @Override 12 | public String[] getHiddenLiveTemplateFiles() { 13 | return null; 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/utils/ProjectUtils.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.utils; 2 | 3 | import com.intellij.openapi.project.Project; 4 | import com.intellij.openapi.project.ProjectManager; 5 | import krasa.formatter.plugin.Notifier; 6 | import krasa.formatter.settings.ProjectComponent; 7 | import krasa.formatter.settings.Settings; 8 | 9 | /** 10 | * @author Vojtech Krasa 11 | */ 12 | public class ProjectUtils { 13 | 14 | public static void notifyProjectsWhichUsesThisSettings(Settings deletedSettings, Project project) { 15 | Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); 16 | for (Project openProject : openProjects) { 17 | ProjectComponent component = openProject.getComponent(ProjectComponent.class); 18 | if (component != null) { 19 | Settings state = component.getSelectedProfile(); 20 | if (deletedSettings.getId().equals(state.getId())) { 21 | component.getProjectSettings().getState().setSelectedGlobalProfile(null); 22 | if (project != openProject) { 23 | Notifier.notifyDeletedSettings(component.getProject()); 24 | } 25 | } 26 | } 27 | } 28 | } 29 | 30 | public static void applyToAllOpenedProjects(Settings updatedSettings) { 31 | Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); 32 | for (Project openProject : openProjects) { 33 | ProjectComponent component = openProject.getComponent(ProjectComponent.class); 34 | if (component != null) { 35 | Settings state = component.getSelectedProfile(); 36 | if (updatedSettings.getId().equals(state.getId())) { 37 | component.globalProfileUpdated(updatedSettings); 38 | } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/krasa/formatter/utils/StringUtils.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.utils; 2 | 3 | import krasa.formatter.settings.Settings; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * @author Vojtech Krasa 10 | */ 11 | public class StringUtils { 12 | 13 | public static String betterMatching(String order1, String order2, String anImport) { 14 | if (order1.equals(order2)) { 15 | throw new IllegalArgumentException("orders are same"); 16 | } 17 | for (int i = 0; i < anImport.length() - 1; i++) { 18 | if (order1.length() - 1 == i && order2.length() - 1 != i) { 19 | return order2; 20 | } 21 | if (order2.length() - 1 == i && order1.length() - 1 != i) { 22 | return order1; 23 | } 24 | char orderChar1 = order1.length() != 0 ? order1.charAt(i) : ' '; 25 | char orderChar2 = order2.length() != 0 ? order2.charAt(i) : ' '; 26 | char importChar = anImport.charAt(i); 27 | 28 | if (importChar == orderChar1 && importChar != orderChar2) { 29 | return order1; 30 | } else if (importChar != orderChar1 && importChar == orderChar2) { 31 | return order2; 32 | } 33 | 34 | } 35 | return null; 36 | } 37 | 38 | public static List trimToList(String importOrder1) { 39 | ArrayList strings = new ArrayList(); 40 | String[] split = importOrder1.split(";"); 41 | for (String s : split) { 42 | String trim = s.trim(); 43 | strings.add(trim); 44 | } 45 | return strings; 46 | } 47 | 48 | public static List trimImports(String imports) { 49 | String[] split = imports.split("\n"); 50 | ArrayList strings = new ArrayList(); 51 | for (int i = 0; i < split.length; i++) { 52 | String s = split[i]; 53 | if (s.startsWith("import ")) { 54 | s = s.substring(7, s.indexOf(";")); 55 | strings.add(s); 56 | } 57 | } 58 | return strings; 59 | } 60 | 61 | public static List trimImports(List imports) { 62 | ArrayList strings = new ArrayList(); 63 | for (int i = 0; i < imports.size(); i++) { 64 | String s = imports.get(i); 65 | if (s.startsWith("import ")) { 66 | s = s.substring(7, s.indexOf(";")); 67 | strings.add(s.trim()); 68 | } else { 69 | strings.add(s.trim()); 70 | } 71 | } 72 | return strings; 73 | } 74 | 75 | 76 | public static String generateName(List settingsList, int i, String name, String resultName) { 77 | if (resultName == null) { 78 | resultName = name; 79 | } 80 | for (Settings settings : settingsList) { 81 | if (resultName.equals(settings.getName())) { 82 | resultName = name + " (" + i + ")"; 83 | resultName = generateName(settingsList, ++i, name, resultName); 84 | } 85 | } 86 | return resultName; 87 | } 88 | 89 | public static String generateName(List settingsList, int i, String name) { 90 | return generateName(settingsList, i, name, name); 91 | 92 | } 93 | 94 | public static String getSimpleName(String s) { 95 | int lastDot = s.lastIndexOf("."); 96 | if (lastDot == -1) { 97 | return s; 98 | } 99 | return s.substring(lastDot + 1, s.length()); 100 | } 101 | 102 | public static String getPackage(String s) { 103 | int lastDot = s.lastIndexOf("."); 104 | if (lastDot == -1) { 105 | return ""; 106 | } 107 | return s.substring(0, lastDot); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | Adapter for Eclipse Code Formatter 6 | EclipseCodeFormatter 7 | 8 | 10 | Solves the problem of maintaining a common code style in team environments where both IDEA and Eclipse are used. 11 |

12 | 13 | Go to https://github.com/krasa/EclipseCodeFormatter#instructions 14 | for instructions how to use it. 15 | 16 |

17 | 18 | Note: This project utilizes (and in some manners modifies) code licensed under EPL-2.0. 19 | For more information see lib/eclipse/README.md. 20 |

21 | Donations | GitHub | Issues 22 | ]]>
23 | Formatting 24 | 25 | Vojtech 26 | Krasa 27 | 28 | 29 | 30 | com.intellij.modules.lang 31 | com.intellij.modules.java 32 | 33 | 34 | 35 | krasa.formatter.settings.GlobalSettings 36 | 37 | 38 | 39 | 40 | krasa.formatter.settings.ProjectComponent 41 | 42 | 43 | 44 | 46 | 47 | 48 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 61 | 63 | 65 | 66 | 67 | 68 |
69 | -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/IDEA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/IDEA.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/IDEA@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/IDEA@2x.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/coins_in_hand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/coins_in_hand.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/coins_in_hand@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/coins_in_hand@2x.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/donate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/donate.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/eclipse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/eclipse.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/eclipse@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/eclipse@2x.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/help.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/help@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krasa/EclipseCodeFormatter/cd37772c14cf94deaa1a803184cef6fff448902b/src/main/resources/krasa/formatter/help@2x.png -------------------------------------------------------------------------------- /src/main/resources/krasa/formatter/messages.properties: -------------------------------------------------------------------------------- 1 | action.pluginSettings=Eclipse\nCode Formatter 2 | action.browse=Browse... 3 | settings.useEclipse=Use the Adapter for Eclipse Code Formatter 4 | settings.useDefault=Disabled 5 | settings.eclipseSupportedFileTypes=Supported file types\: 6 | settings.eclipsePrefsExample=Example: ...\\project\\.settings\\org.eclipse.jdt.core.prefs or ...\\exportedProfiles.xml or ...\\workspaceMechanic.epf 7 | error.errorInField=Error in the "{0}" field: {1} 8 | settings.optimizeImports=Optimize Imports (IntelliJ's Import Optimizing must be turned ON) 9 | settings.disableFileTypesHelp=Example\: html; groovy; css; 10 | settings.disableFileTypesFormattingCheckbox=Format other file types by IntelliJ with this exception\: 11 | settings.formatOtherFileTypesByIntellij=Do not format other file types by IntelliJ formatter 12 | settings.formatAllFilesPartial=Format selected text in all file types 13 | settings.enableJava=Enable Java 14 | settings.importOrder.help=Example: \\#org;\\#java;java;javax;org;com;;\\# 15 | settings.eclipsePrefsExample2=Example\: ...\\project\\.settings\\org.eclipse.jdt.ui.prefs or ..\\*.importorder 16 | settings.selectedProfile=Selected profile\: 17 | settings.eclipse.newest=Bundled Eclipse 2024-09 18 | settings.eclipse.custom=Configured Eclipse installation folder 19 | -------------------------------------------------------------------------------- /src/main/resources/liveTemplates/templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | -------------------------------------------------------------------------------- /src/test/java/krasa/easymock/EasyMockTest.java: -------------------------------------------------------------------------------- 1 | package krasa.easymock; 2 | 3 | import org.junit.After; 4 | import org.junit.Before; 5 | 6 | import java.lang.reflect.Field; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import static org.easymock.EasyMock.*; 11 | 12 | public class EasyMockTest { 13 | 14 | private List mocks = new ArrayList(); 15 | 16 | @Before 17 | public void setUp() throws Exception { 18 | List mockFields = MockAnnotationUtil.findFieldsThatAreMarkedForMocking(this); 19 | makeFieldsAccessibleForMocking(mockFields); 20 | defineMocks(mockFields, this); 21 | } 22 | 23 | @After 24 | public void tearDown() throws Exception { 25 | verify(mocks.toArray()); 26 | } 27 | 28 | public void replayAll() { 29 | replay(mocks.toArray()); 30 | } 31 | 32 | private void defineMocks(List mockedFields, Object testInstance) throws Exception { 33 | for (Field field : mockedFields) { 34 | String fieldName = field.getName(); 35 | Class type = field.getType(); 36 | Object mock = createMock(fieldName, type); 37 | mocks.add(mock); 38 | field.set(testInstance, mock); 39 | } 40 | } 41 | 42 | private void makeFieldsAccessibleForMocking(List mockFields) { 43 | for (Field f : mockFields) { 44 | f.setAccessible(true); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/krasa/easymock/MockAnnotationUtil.java: -------------------------------------------------------------------------------- 1 | package krasa.easymock; 2 | 3 | import java.lang.reflect.Field; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class MockAnnotationUtil { 8 | 9 | public static List findFieldsThatAreMarkedForMocking(EasyMockTest clazz) { 10 | List results = new ArrayList(); 11 | Class current = clazz.getClass(); 12 | while (current != Object.class) { 13 | Field[] fields = current.getDeclaredFields(); 14 | for (Field f : fields) { 15 | if (f.isAnnotationPresent(Mocked.class)) { 16 | results.add(f); 17 | } 18 | } 19 | current = current.getSuperclass(); 20 | } 21 | return results; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/krasa/easymock/Mocked.java: -------------------------------------------------------------------------------- 1 | package krasa.easymock; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Documented 6 | @Retention(RetentionPolicy.RUNTIME) 7 | @Target(ElementType.FIELD) 8 | public @interface Mocked { 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/Version.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import static com.intellij.util.text.VersionComparatorUtil.compare; 7 | 8 | public class Version { 9 | @Test 10 | public void name() { 11 | Assert.assertEquals(1, compare("17.4.132.637.0-Eclipse_4.7", "17.4.132.637.0-Eclipse_4.6")); 12 | Assert.assertEquals(1, compare("17.3.132.637.0-Eclipse_4.7.3a", "17.2.132.637.0-Eclipse_4.7.3a")); 13 | Assert.assertEquals(1, compare("17.4.132.637.0-Eclipse_4.7.3a", "17.3.132.637.0-Eclipse_4.7.3a")); 14 | Assert.assertEquals(1, compare("17.4.132.637.0-Eclipse_4.7.3a", "17.3.132.637.0-Eclipse_4.6")); 15 | Assert.assertEquals(1, compare("18.132.637.0-Eclipse_4.7.3a", "17.3.132.637.0-Eclipse_4.7.3a")); 16 | Assert.assertEquals(1, compare("18.2.181.000.0-Eclipse_4.8.0", "18.1.181.000.0-Eclipse_4.7.3a")); 17 | Assert.assertEquals(1, compare("18.2.181.000.0-Eclipse_4.9.0", "18.1.181.000.0-Eclipse_4.8.0")); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/eclipse/ConfigurableEclipseLocationTest.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.eclipse; 2 | 3 | import org.junit.Test; 4 | 5 | import java.net.URL; 6 | import java.util.List; 7 | 8 | public class ConfigurableEclipseLocationTest { 9 | 10 | @Test 11 | public void run() { 12 | List urlList; 13 | urlList = new ConfigurableEclipseLocation().run("C:/Users/vojtisek/eclipse/java-2023-03"); 14 | // urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-macosx-cocoa"); 15 | // urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-linux-gtk"); 16 | // urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-win32"); 17 | // List urlList = new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-jee-2020-06-R-win32-x86_64"); 18 | for (URL jar : urlList) { 19 | System.out.println(jar); 20 | } 21 | urlList = new ConfigurableEclipseLocation().run("C:\\Users\\vojtisek\\eclipse\\java-2021-12"); 22 | // urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-macosx-cocoa"); 23 | // urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-linux-gtk"); 24 | // urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-win32"); 25 | // List urlList = new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-jee-2020-06-R-win32-x86_64"); 26 | for (URL jar : urlList) { 27 | System.out.println(jar); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/eclipse/PlatformFormatterTest.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.eclipse; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.command.CommandProcessor; 5 | import com.intellij.openapi.editor.Document; 6 | import com.intellij.openapi.module.ModuleType; 7 | import com.intellij.openapi.module.StdModuleTypes; 8 | import com.intellij.openapi.project.Project; 9 | import com.intellij.openapi.projectRoots.Sdk; 10 | import com.intellij.openapi.util.TextRange; 11 | import com.intellij.openapi.vfs.VirtualFile; 12 | import com.intellij.psi.PsiFile; 13 | import com.intellij.psi.PsiManager; 14 | import com.intellij.psi.codeStyle.CodeStyleManager; 15 | import com.intellij.psi.codeStyle.JavaCodeStyleSettings; 16 | import com.intellij.psi.formatter.FormatterTestCase; 17 | import com.intellij.testFramework.IdeaTestUtil; 18 | import com.intellij.testFramework.UsefulTestCase; 19 | import com.intellij.util.IncorrectOperationException; 20 | import krasa.formatter.settings.ProjectComponent; 21 | import krasa.formatter.settings.Settings; 22 | import org.jetbrains.annotations.NotNull; 23 | 24 | import java.io.File; 25 | import java.util.Arrays; 26 | 27 | public class PlatformFormatterTest extends FormatterTestCase { 28 | 29 | private static final String BASE_PATH = "testProject"; 30 | ConfigFileLocator.IModuleResolverStrategy previousResolver; 31 | 32 | @Override 33 | public void setUp() throws Exception { 34 | super.setUp(); 35 | Settings settings = new Settings(); 36 | settings.setFormatter(Settings.Formatter.ECLIPSE); 37 | settings.setConfigType(Settings.ConfigType.RESOLVE); 38 | ProjectComponent.getInstance(getProject()).installOrUpdate(settings); 39 | previousResolver = ConfigFileLocator.TESTING_getModuleResolver(); 40 | } 41 | 42 | public void testFormatting() { 43 | 44 | 45 | ConfigFileLocator.TESTING_setModuleResolver(new ConfigFileLocator.IModuleResolverStrategy() { 46 | @Override 47 | public VirtualFile getModuleDirForFile(VirtualFile virtualFile, Project project) { 48 | 49 | String path = virtualFile.getPath(); 50 | if (path.contains("/testProject/submodule-a")) { 51 | return UsefulTestCase.refreshAndFindFile(new File("testProject/submodule-a")); 52 | } 53 | if (path.contains("/testProject/submodule-b")) { 54 | return UsefulTestCase.refreshAndFindFile(new File("testProject/submodule-b")); 55 | } 56 | if (path.contains("/testProject")) { 57 | return UsefulTestCase.refreshAndFindFile(new File("testProject")); 58 | } 59 | throw new UnsupportedOperationException("Not expected " + virtualFile); 60 | } 61 | }); 62 | 63 | { 64 | VirtualFile virtualFile = refreshAndFindFile(new File("testProject/submodule-a/src/main/java/aaa/XAAA.java")); 65 | 66 | PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(virtualFile); 67 | 68 | CommandProcessor.getInstance().executeCommand(getProject(), () -> ApplicationManager.getApplication().runWriteAction(() -> performFormatting(psiFile)), "", 69 | ""); 70 | 71 | Document document = getDocument(psiFile); 72 | String fileText = document.getText(); 73 | assertEquals("package aaa;\n" + 74 | "\n" + 75 | "public class XAAA {\n" + 76 | "\tpublic static void aaa() {\n" + 77 | "\n" + 78 | "\t}\n" + 79 | "}\n", fileText); 80 | //submodule-a has no own formatter configuration, so it uses the one of its parent 81 | assertFormatterFile("testProject/.settings/org.eclipse.jdt.core.prefs"); 82 | 83 | } 84 | 85 | { 86 | VirtualFile virtualFile = refreshAndFindFile(new File("testProject/submodule-b/src/main/java/bbb/XBBB.java")); 87 | 88 | PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(virtualFile); 89 | 90 | CommandProcessor.getInstance().executeCommand(getProject(), () -> ApplicationManager.getApplication().runWriteAction(() -> performFormatting(psiFile)), "", 91 | ""); 92 | 93 | assertFormatterFile("testProject/submodule-b/mechanic-formatter.epf"); 94 | Document document = getDocument(psiFile); 95 | String fileText = document.getText(); 96 | assertEquals("package bbb;\n" + 97 | "\n" + 98 | "public class XBBB {\n" + 99 | " public static void bbb() {\n" + 100 | "\n" + 101 | " }\n" + 102 | "}\n", fileText); 103 | //submodule-b has its own formatter configuration 104 | } 105 | 106 | { 107 | VirtualFile virtualFile = refreshAndFindFile(new File("testProject/src/main/java/aaa/XAAA.java")); 108 | 109 | PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(virtualFile); 110 | 111 | CommandProcessor.getInstance().executeCommand(getProject(), () -> ApplicationManager.getApplication().runWriteAction(() -> performFormatting(psiFile)), "", 112 | ""); 113 | 114 | Document document = getDocument(psiFile); 115 | String fileText = document.getText(); 116 | assertEquals("package aaa;\n" + 117 | "\n" + 118 | "public class XAAA {\n" + 119 | "\tpublic static void aaa() {\n" + 120 | "\n" + 121 | "\t}\n" + 122 | "}\n", fileText); 123 | //the parent project has its own formatter configuration 124 | assertFormatterFile("testProject/.settings/org.eclipse.jdt.core.prefs"); 125 | } 126 | 127 | } 128 | 129 | private void assertFormatterFile(String s) { 130 | String filePath = ConfigFileLocator.TESTING_getMostRecentFormatterFile().getPath(); 131 | assertTrue("Used " + filePath, filePath.endsWith(s)); 132 | } 133 | 134 | @Override 135 | protected void tearDown() throws Exception { 136 | 137 | ConfigFileLocator.TESTING_setModuleResolver(previousResolver); 138 | 139 | try { 140 | super.tearDown(); 141 | } catch (RuntimeException exception) { 142 | // TODO: Fix inability to free pointer 143 | if (exception.getMessage().contains("Virtual pointer hasn't been disposed")) { 144 | throw exception; 145 | } 146 | } 147 | } 148 | 149 | 150 | protected void performFormatting(PsiFile file) { 151 | try { 152 | CodeStyleManager.getInstance(this.getProject()).reformatText(file, Arrays.asList(new TextRange(0, file.getTextLength()))); 153 | } catch (IncorrectOperationException var3) { 154 | fail(); 155 | } 156 | } 157 | 158 | @Override 159 | protected Sdk getProjectJDK() { 160 | return IdeaTestUtil.getMockJdk17(); 161 | } 162 | 163 | @NotNull 164 | protected ModuleType getModuleType() { 165 | return StdModuleTypes.JAVA; 166 | } 167 | 168 | @Override 169 | protected String getFileExtension() { 170 | return "java"; 171 | } 172 | 173 | protected JavaCodeStyleSettings getCustomJavaSettings() { 174 | return JavaCodeStyleSettings.getInstance(getProject()); 175 | } 176 | 177 | @Override 178 | protected String getBasePath() { 179 | return BASE_PATH; 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/eclipse/TestUtils.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.eclipse; 2 | 3 | import krasa.formatter.utils.FileUtils; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | import java.io.File; 7 | import java.util.HashMap; 8 | import java.util.Properties; 9 | 10 | /** 11 | * @author Vojtech Krasa 12 | */ 13 | public class TestUtils { 14 | 15 | public static final String TEST_RESOURCES_ORG_ECLIPSE_JDT_CORE_PREFS = "test/resources/org.eclipse.jdt.core.prefs"; 16 | public static final String TEST_RESOURCES_ORG_ECLIPSE_JDT_CORE_PREFS_DEFAULT = "../test/resources/org.eclipse.jdt.core_DEFAULT.prefs"; 17 | public static final String TEST_RESOURCES_ORG_ECLIPSE_WST_JSDT_CORE_PREFS = "../test/resources/org.eclipse.wst.jsdt.core.prefs"; 18 | 19 | public static HashMap getJSProperties() { 20 | HashMap jsMap = new HashMap(); 21 | Properties js = FileUtils.readPropertiesFile(new File(normalizeUnitTestPath(TEST_RESOURCES_ORG_ECLIPSE_WST_JSDT_CORE_PREFS))); 22 | for (Object o : js.keySet()) { 23 | jsMap.put(String.valueOf(o), (String) js.get(o)); 24 | } 25 | return jsMap; 26 | } 27 | 28 | public static HashMap getJavaProperties() { 29 | Properties javaProperties = FileUtils.readPropertiesFile(new File( 30 | normalizeUnitTestPath(TEST_RESOURCES_ORG_ECLIPSE_JDT_CORE_PREFS_DEFAULT))); 31 | HashMap javaFormattingPrefs = new HashMap(); 32 | for (Object o : javaProperties.keySet()) { 33 | javaFormattingPrefs.put(String.valueOf(o), (String) javaProperties.get(o)); 34 | } 35 | return javaFormattingPrefs; 36 | } 37 | 38 | @NotNull 39 | public static String normalizeUnitTestPath(String path) { 40 | if (!new File(path).exists()) { 41 | path = "src/test/" + path; 42 | } 43 | return path; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/settings/DisabledFileTypeSettingsTest.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | /** 7 | * @author Vojtech Krasa 8 | */ 9 | public class DisabledFileTypeSettingsTest { 10 | 11 | @Test 12 | public void testIsDisabled() throws Exception { 13 | DisabledFileTypeSettings disabledFileTypeSettings = new DisabledFileTypeSettings("html; groovy;"); 14 | Assert.assertFalse(disabledFileTypeSettings.isDisabled("sadasd/aasdasdas.java")); 15 | Assert.assertTrue(disabledFileTypeSettings.isDisabled("sadasd/aasdasdas.html")); 16 | Assert.assertTrue(disabledFileTypeSettings.isDisabled("sadasd/aasdasdas.groovy")); 17 | Assert.assertFalse(disabledFileTypeSettings.isDisabled("sadasd/aasdasdas.groovy1")); 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/settings/provider/CachedProviderTest.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings.provider; 2 | 3 | import com.intellij.openapi.util.io.FileUtil; 4 | import krasa.formatter.common.ModifiableFile; 5 | import org.apache.commons.io.FileUtils; 6 | import org.junit.Assert; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | 13 | /** 14 | * @author Vojtech Krasa 15 | */ 16 | public class CachedProviderTest { 17 | 18 | protected CachedProvider cachedProvider; 19 | protected File tempFile; 20 | 21 | @Before 22 | public void setUp() throws Exception { 23 | tempFile = File.createTempFile("12311", "2"); 24 | cachedProvider = new CachedProvider(new ModifiableFile(tempFile.getPath())) { 25 | 26 | @Override 27 | protected String readFile(File file) { 28 | try { 29 | return FileUtils.readFileToString(file); 30 | } catch (IOException e) { 31 | throw new RuntimeException(e); 32 | } 33 | } 34 | }; 35 | } 36 | 37 | @Test 38 | public void testWasChanged() throws Exception { 39 | cachedProvider.get(); 40 | Assert.assertFalse(cachedProvider.wasChanged()); 41 | tempFile.setLastModified(tempFile.lastModified() + 1000); 42 | Assert.assertTrue(cachedProvider.wasChanged()); 43 | } 44 | 45 | @Test 46 | public void testGet() throws Exception { 47 | FileUtil.writeToFile(tempFile, "foo"); 48 | tempFile.setLastModified(1000); 49 | String s = cachedProvider.get(); 50 | Assert.assertEquals("foo", s); 51 | 52 | FileUtil.writeToFile(tempFile, "bar"); 53 | 54 | tempFile.setLastModified(1000); 55 | s = cachedProvider.get(); 56 | Assert.assertEquals("foo", s); 57 | 58 | tempFile.setLastModified(2000); 59 | s = cachedProvider.get(); 60 | Assert.assertEquals("bar", s); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/settings/provider/ImportOrderProviderTest.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.settings.provider; 2 | 3 | import krasa.formatter.eclipse.TestUtils; 4 | import krasa.formatter.settings.Settings; 5 | import org.apache.commons.io.FileUtils; 6 | import org.junit.Test; 7 | 8 | import java.util.List; 9 | 10 | public class ImportOrderProviderTest { 11 | 12 | public static final String[] ORDER = new String[] { "java", "javax", "org", "com", "br.gov.bcb", "foo", "#" }; 13 | private static final String[] ORDER_2 = { "com.mycorp", "#com.mycorp", "com", "#com" }; 14 | 15 | @Test 16 | public void testReadFile() throws Exception { 17 | List importOrder = getOrderFromFile("resources/bcjur2.importorder"); 18 | 19 | org.junit.Assert.assertArrayEquals(ORDER, importOrder.toArray(new String[importOrder.size()])); 20 | } 21 | 22 | @Test 23 | public void issue104() throws Exception { 24 | List importOrder = getOrderFromFile("resources/issue104.importorder"); 25 | 26 | org.junit.Assert.assertArrayEquals(ORDER_2, importOrder.toArray(new String[importOrder.size()])); 27 | } 28 | 29 | @Test 30 | public void issue130_incorrect_parsing_of_import_order_from_prefs() throws Exception { 31 | List importOrder = getOrderFromFile("resources/issue130.importorder"); 32 | List importOrder2 = getOrderFromFile("resources/issue130.prefs"); 33 | 34 | org.junit.Assert.assertEquals(importOrder, importOrder2); 35 | } 36 | 37 | private List getOrderFromFile(String path) { 38 | Settings settings = new Settings(); 39 | path = TestUtils.normalizeUnitTestPath(path); 40 | settings.setImportOrderConfigFilePath(FileUtils.getFile(path).getAbsolutePath()); 41 | ImportOrderProvider importOrderProvider = new ImportOrderProvider(settings); 42 | return importOrderProvider.get(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/utils/FileUtilsTest.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.utils; 2 | 3 | import krasa.formatter.eclipse.TestUtils; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | import java.io.File; 8 | import java.util.List; 9 | 10 | /** 11 | * @author Vojtech Krasa 12 | */ 13 | public class FileUtilsTest { 14 | @Test 15 | public void testGetProfileNamesFromConfigXML() throws Exception { 16 | File file = new File(TestUtils.normalizeUnitTestPath("resources/format.xml")); 17 | System.err.println(file.getAbsolutePath()); 18 | List profileNamesFromConfigXML = FileUtils.getProfileNamesFromConfigXML(file); 19 | Assert.assertFalse(profileNamesFromConfigXML.isEmpty()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/krasa/formatter/utils/StringUtilsTest.java: -------------------------------------------------------------------------------- 1 | package krasa.formatter.utils; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | import java.util.List; 7 | 8 | import static krasa.formatter.utils.StringUtils.getPackage; 9 | import static krasa.formatter.utils.StringUtils.getSimpleName; 10 | 11 | /** 12 | * @author Vojtech Krasa 13 | */ 14 | public class StringUtilsTest { 15 | @Test 16 | public void test_getSimpleName() throws Exception { 17 | Assert.assertEquals("b", getSimpleName("a.a.b")); 18 | Assert.assertEquals("b", getSimpleName("b")); 19 | } 20 | 21 | @Test 22 | public void test_getPackage() throws Exception { 23 | Assert.assertEquals("a.a", getPackage("a.a.b")); 24 | Assert.assertEquals("", getPackage("b")); 25 | Assert.assertEquals("com.model", getPackage("com.model.Ethernet")); 26 | } 27 | 28 | @Test 29 | public void testBetterMatching() throws Exception { 30 | String order1 = "com.foo"; 31 | String order2 = "com.kuk"; 32 | String s = StringUtils.betterMatching(order2, order1, "com.foo.goo"); 33 | Assert.assertEquals(order1, s); 34 | s = StringUtils.betterMatching(order1, order2, "com.foo.goo"); 35 | Assert.assertEquals(order1, s); 36 | } 37 | 38 | @Test 39 | public void testTrimToList() throws Exception { 40 | List strings = StringUtils.trimToList(""); 41 | Assert.assertFalse(strings.isEmpty()); 42 | strings = StringUtils.trimToList(" "); 43 | Assert.assertFalse(strings.isEmpty()); 44 | } 45 | // todo 46 | // @Test 47 | // public void testGenerateName() throws Exception { 48 | // ArrayList settingsList = new ArrayList(); 49 | // Project instance = new MyDummyProject(); 50 | // String s = StringUtils.generateName(settingsList, 1, instance.getName()); 51 | // Assert.assertEquals("dummy", s); 52 | // settingsList.add(new Settings(1L, "dummy")); 53 | // 54 | // s = StringUtils.generateName(settingsList, 1, instance.getName()); 55 | // Assert.assertEquals("dummy (1)", s); 56 | // settingsList.add(new Settings(1L, "dummy (1)")); 57 | // 58 | // s = StringUtils.generateName(settingsList, 1, instance.getName()); 59 | // Assert.assertEquals("dummy (2)", s); 60 | // } 61 | 62 | // class MyDummyProject extends UserDataHolderBase implements Project { 63 | // 64 | // 65 | // @NotNull 66 | // @Override 67 | // public ExtensionsArea getExtensionArea() { 68 | // return null; 69 | // } 70 | // 71 | // @Override 72 | // public T instantiateClassWithConstructorInjection(@NotNull Class aClass, @NotNull Object o, @NotNull PluginId pluginId) { 73 | // return null; 74 | // } 75 | // 76 | // @Override 77 | // public @NotNull 78 | // RuntimeException createError(@NotNull Throwable throwable, @NotNull PluginId pluginId) { 79 | // return null; 80 | // } 81 | // 82 | // @Override 83 | // public @NotNull 84 | // RuntimeException createError(@NotNull @NonNls String s, @NotNull PluginId pluginId) { 85 | // return null; 86 | // } 87 | // 88 | // @Override 89 | // public @NotNull 90 | // RuntimeException createError(@NotNull @NonNls String s, @Nullable Throwable throwable, @NotNull PluginId pluginId, @Nullable Map map) { 91 | // return null; 92 | // } 93 | // 94 | // 95 | // @Override 96 | // public @NotNull 97 | // Class loadClass(@NotNull String s, @NotNull PluginDescriptor pluginDescriptor) throws ClassNotFoundException { 98 | // return null; 99 | // } 100 | // 101 | // @Override 102 | // public @NotNull T instantiateClass(@NotNull String s, @NotNull PluginDescriptor pluginDescriptor) { 103 | // return null; 104 | // } 105 | // 106 | // @Override 107 | // public @NotNull 108 | // ActivityCategory getActivityCategory(boolean b) { 109 | // return null; 110 | // } 111 | // 112 | // public MyDummyProject() { 113 | // } 114 | // 115 | // @Override 116 | // public VirtualFile getProjectFile() { 117 | // return null; 118 | // } 119 | // 120 | // @Override 121 | // @NotNull 122 | // public String getName() { 123 | // return "dummy"; 124 | // } 125 | // 126 | // @Override 127 | // @Nullable 128 | // @NonNls 129 | // public String getPresentableUrl() { 130 | // return null; 131 | // } 132 | // 133 | // @Override 134 | // @NotNull 135 | // @NonNls 136 | // public String getLocationHash() { 137 | // return "dummy"; 138 | // } 139 | // 140 | // @Nullable 141 | // @NonNls 142 | // public String getLocation() { 143 | // throw new UnsupportedOperationException("Method getLocation not implemented in " + getClass()); 144 | // } 145 | // 146 | // @Override 147 | // @NotNull 148 | // public String getProjectFilePath() { 149 | // return ""; 150 | // } 151 | // 152 | // @Override 153 | // public VirtualFile getWorkspaceFile() { 154 | // return null; 155 | // } 156 | // 157 | // @Override 158 | // @Nullable 159 | // public VirtualFile getBaseDir() { 160 | // return null; 161 | // } 162 | // 163 | // // @Override 164 | // @Override 165 | // public String getBasePath() { 166 | // return null; 167 | // } 168 | // 169 | // @Override 170 | // public void save() { 171 | // } 172 | // 173 | // @Override 174 | // public BaseComponent getComponent(String name) { 175 | // return null; 176 | // } 177 | // 178 | // @Override 179 | // public T getComponent(Class interfaceClass) { 180 | // return null; 181 | // } 182 | // 183 | // @Override 184 | // public boolean hasComponent(@NotNull Class interfaceClass) { 185 | // return false; 186 | // } 187 | // 188 | // @NotNull 189 | // public T[] getComponents(Class baseClass) { 190 | // return (T[]) ArrayUtil.EMPTY_OBJECT_ARRAY; 191 | // } 192 | // 193 | //// @Override 194 | // @NotNull 195 | // public PicoContainer getPicoContainer() { 196 | // throw new UnsupportedOperationException("getPicoContainer is not implement in : " + getClass()); 197 | // } 198 | // 199 | // @Override 200 | // public boolean isInjectionForExtensionSupported() { 201 | // return false; 202 | // } 203 | // 204 | // 205 | // @NotNull 206 | // // @Override 207 | // public Class[] getComponentInterfaces() { 208 | // return new Class[0]; 209 | // } 210 | // 211 | // @Override 212 | // public boolean isDisposed() { 213 | // return false; 214 | // } 215 | // 216 | // @Override 217 | // @NotNull 218 | // public Condition getDisposed() { 219 | // return new Condition() { 220 | // @Override 221 | // public boolean value(final Object o) { 222 | // return isDisposed(); 223 | // } 224 | // }; 225 | // } 226 | // 227 | // @Override 228 | // public T getService(@NotNull Class aClass) { 229 | // return null; 230 | // } 231 | // 232 | // @NotNull 233 | // public ComponentConfig[] getComponentConfigurations() { 234 | // return new ComponentConfig[0]; 235 | // } 236 | // 237 | // @Nullable 238 | // public Object getComponent(final ComponentConfig componentConfig) { 239 | // return null; 240 | // } 241 | // 242 | // @Override 243 | // public boolean isOpen() { 244 | // return false; 245 | // } 246 | // 247 | // @Override 248 | // public boolean isInitialized() { 249 | // return false; 250 | // } 251 | // 252 | // @Override 253 | // public boolean isDefault() { 254 | // return false; 255 | // } 256 | // 257 | //// @Override 258 | // public CoroutineScope getCoroutineScope() { 259 | // return null; 260 | // } 261 | // 262 | // @Override 263 | // public MessageBus getMessageBus() { 264 | // return null; 265 | // } 266 | // 267 | // @Override 268 | // public void dispose() { 269 | // } 270 | // 271 | //// @Override 272 | // public T[] getExtensions(final ExtensionPointName extensionPointName) { 273 | // throw new UnsupportedOperationException("getExtensions()"); 274 | // } 275 | // 276 | // public ComponentConfig getConfig(Class componentImplementation) { 277 | // throw new UnsupportedOperationException("Method getConfig not implemented in " + getClass()); 278 | // } 279 | // } 280 | 281 | } 282 | -------------------------------------------------------------------------------- /src/test/resources/bcjur2.importorder: -------------------------------------------------------------------------------- 1 | #Organize Import Order 2 | #Mon Jan 14 17:18:26 BRST 2013 3 | 3=com 4 | 4=br.gov.bcb 5 | 1=javax 6 | 100=foo 7 | 2=org 8 | 0=java 9 | 411=\# -------------------------------------------------------------------------------- /src/test/resources/eclipse.importorder: -------------------------------------------------------------------------------- 1 | 116=javax 2 | 115=java 3 | 114=wowza 4 | 113=woolfel 5 | 112=winstone 6 | 111=wet 7 | 110=weka 8 | 109=ViolinStrings 9 | 108=uk 10 | 107=twitter4j 11 | 106=testsuite 12 | 105=testshell 13 | 104=testdata 14 | 103=tcl 15 | 102=sunlabs 16 | 101=sun 17 | 100=ssa 18 | 99=src 19 | 98=sqlj 20 | 97=soot 21 | 96=simple 22 | 95=serp 23 | 94=se 24 | 93=scm 25 | 92=repackage 26 | 91=proguard 27 | 90=prefuse 28 | 89=pl 29 | 88=pennconverter 30 | 87=penn2dg 31 | 86=org 32 | 85=oracle 33 | 84=opennlp 34 | 83=oauthognl 35 | 82=nu 36 | 81=nl 37 | 80=netscape 38 | 79=net 39 | 78=mx4j 40 | 77=mt 41 | 76=mockit 42 | 75=memetic 43 | 74=lti 44 | 73=libsvm 45 | 72=libcore 46 | 71=kea 47 | 70=kawa 48 | 69=jxxload_help 49 | 68=jxl 50 | 67=junit 51 | 66=jsr166y 52 | 65=JSci 53 | 64=jp 54 | 63=jline 55 | 62=jj2000 56 | 61=JFlex 57 | 60=jetty 58 | 59=jcifs 59 | 58=javazoom 60 | 57=javassist 61 | 56=javanet 62 | 55=javancss 63 | 54=java_cup 64 | 53=jasmin 65 | 52=jas 66 | 51=japacheckers 67 | 50=japa 68 | 49=Jama 69 | 48=jal 70 | 47=it 71 | 46=info 72 | 45=imageinfo 73 | 44=ie 74 | 43=hep 75 | 42=hak 76 | 41=groovyjarjarasm 77 | 40=groovyjarjarantlr 78 | 39=groovy 79 | 38=gnu 80 | 37=freemarker 81 | 36=fmpp 82 | 35=fitlibrary 83 | 34=fit 84 | 33=fat 85 | 32=examples 86 | 31=eu 87 | 30=eg 88 | 29=EDU 89 | 28=de 90 | 27=danbikel 91 | 26=dalvik 92 | 25=cybervillains 93 | 24=cryptix 94 | 23=corejava 95 | 22=contribs 96 | 21=common 97 | 20=COM 98 | 19=com 99 | 18=checkers 100 | 17=ChartDirector 101 | 16=cern 102 | 15=ccl 103 | 14=bsh 104 | 13=bmsi 105 | 12=bibtex 106 | 11=beaver 107 | 10=au 108 | 9=atg 109 | 8=asquare 110 | 7=asposewobfuscated 111 | 6=ar 112 | 5=antlr 113 | 4=antenna 114 | 3=android 115 | 2= 116 | 1=com.google 117 | 0=\# 118 | -------------------------------------------------------------------------------- /src/test/resources/example/Example.java: -------------------------------------------------------------------------------- 1 | /** 2 | * An example for comment formatting. This example is meant to illustrate the 3 | * various possibilities offered by Eclipse in order to format comments. 4 | */ 5 | package mypackage; 6 | 7 | /** 8 | * This is the comment for the example interface. 9 | */ 10 | interface Example { 11 | // This is a long comment with whitespace that should be split in multiple 12 | // line comments in case the line comment formatting is enabled 13 | int foo3(); 14 | 15 | // void commented() { 16 | // System.out.println("indented"); 17 | // } 18 | 19 | // void indentedCommented() { 20 | // System.out.println("indented"); 21 | // } 22 | 23 | /* block comment on first column */ 24 | int bar(); 25 | 26 | /* 27 | * These possibilities include:
  • Formatting of header 28 | * comments.
  • Formatting of Javadoc tags
29 | */ 30 | int bar2(); // This is a long comment that should be split in multiple line 31 | // comments in case the line comment formatting is enabled 32 | 33 | /** 34 | * The following is some sample code which illustrates source formatting 35 | * within javadoc comments: 36 | * 37 | *
38 |      * public class Example {
39 |      *     final int a = 1;
40 |      *     final boolean b = true;
41 |      * }
42 |      * 
43 | * 44 | * Descriptions of parameters and return values are best appended at end of 45 | * the javadoc comment. 46 | * @param first 47 | * The first parameter. For an optimum result, this should be an 48 | * odd number between 0 and 100. 49 | * @param second 50 | * The second parameter. 51 | * @throws Exception 52 | * when the foo operation cannot be performed for one reason or 53 | * another. 54 | * @return The result of the foo operation, usually an even number within 0 55 | * and 1000. 56 | */ 57 | int foo(int first, int second) throws Exception; 58 | } 59 | 60 | class Test { 61 | void trailingCommented() { 62 | System.out.println("indented"); // comment 63 | System.out.println("indent"); // comment 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/resources/invalidFormat.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/resources/issue104.importorder: -------------------------------------------------------------------------------- 1 | 0=com.mycorp 2 | 1=\#com.mycorp 3 | 2=com 4 | 3=\#com -------------------------------------------------------------------------------- /src/test/resources/issue130.importorder: -------------------------------------------------------------------------------- 1 | #Organize Import Order 2 | #Thu Mar 30 14:07:30 CDT 2017 3 | 9= 4 | 8=com.datalogics 5 | 7=com.adobe 6 | 6=\#javax 7 | 5=\#java 8 | 13=javax 9 | 4=\#com 10 | 12=java 11 | 3=\#org 12 | 11=com 13 | 2=\# 14 | 10=org 15 | 1=\#com.datalogics 16 | 0=\#com.adobe -------------------------------------------------------------------------------- /src/test/resources/issue130.prefs: -------------------------------------------------------------------------------- 1 | org.eclipse.jdt.ui.importorder=\#com.adobe;\#com.datalogics;\#;\#org;\#com;\#java;\#javax;com.adobe;com.datalogics;;org;com;java;javax; -------------------------------------------------------------------------------- /src/test/resources/kuk.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Wrapper for java.lang.Object.wait 3 | * 4 | * can be called only within a sync method 5 | */ 6 | function wait(object) { 7 | var objClazz = java.lang.Class.forName('java.lang.Object'); 8 | var waitMethod = objClazz.getMethod('wait', null); 9 | waitMethod.invoke(object, null); 10 | } 11 | wait.docString = "convenient wrapper for java.lang.Object.wait method"; -------------------------------------------------------------------------------- /src/test/resources/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Plugin used to check the component has at least one of the permissions 3 | * provided. 4 | * 5 | * Usage: 6 | * 7 | * This checks only for one permission 8 | * 9 | * var button = new Ext.Button({ plugins: new 10 | * Abc.security.AnyGranted('PERM_LOGIN') }); 11 | * 12 | * This checks only for all permissions 13 | * 14 | * var button = new Ext.Button({ plugins: new 15 | * Abc.security.AnyGranted(['PERM_LOGIN','PERM_DASHBOARD']) }); 16 | * 17 | * / 18 | */ 19 | function wait(object) { 20 | var objClazz = java.lang.Class.forName('java.lang.Object'); 21 | var waitMethod = objClazz.getMethod('wait', null); 22 | waitMethod.invoke(object, null); 23 | } 24 | wait.docString = "convenient wrapper for java.lang.Object.wait method"; 25 | -------------------------------------------------------------------------------- /src/test/resources/unitils-default.properties: -------------------------------------------------------------------------------- 1 | unitils.configuration.customFileName=unitils-default.properties 2 | unitils.configuration.localFileName=unitils-default.properties -------------------------------------------------------------------------------- /src/test/test.iml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /support/DependencyDownloader/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | krasa 8 | DependencyDownloader 9 | 1.0 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-dependency-plugin 15 | 2.5 16 | 17 | 18 | copy-dependencies 19 | package 20 | 21 | copy-dependencies 22 | 23 | 24 | ${project.basedir}/../lib/ 25 | false 26 | false 27 | true 28 | true 29 | 30 | 31 | 32 | copy-sources 33 | package 34 | 35 | copy-dependencies 36 | 37 | 38 | ${project.basedir}/../lib/source 39 | false 40 | false 41 | true` 42 | true 43 | sources 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.kohsuke 55 | file-leak-detector 56 | 1.13 57 | 58 | 59 | commons-io 60 | commons-io 61 | 2.4 62 | 63 | 64 | 65 | org.easymock 66 | easymock 67 | 3.1 68 | test 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /support/README: -------------------------------------------------------------------------------- 1 | -run mvn package on support/eclipseLibs/pom.xml 2 | -run tests on test module with $MODULE_DIR$ working directory 3 | -commit to git 4 | -------------------------------------------------------------------------------- /support/eclipseLibs/eclipse.iml: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /support/eclipseLibs/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 4.0.0 7 | krasa 8 | eclipseLibs 9 | 1.0-SNAPSHOT 10 | 11 | 1.8 12 | 1.8 13 | 14 | 15 | 16 | 17 | org.apache.maven.plugins 18 | maven-shade-plugin 19 | 3.6.0 20 | 21 | 22 | 23 | 24 | *:* 25 | 26 | META-INF/*.SF 27 | META-INF/*.DSA 28 | META-INF/*.RSA 29 | plugin.xml 30 | 31 | 32 | 33 | 34 | 35 | 36 | package 37 | 38 | shade 39 | 40 | 41 | true 42 | true 43 | eclipse 44 | ${project.basedir}/../../lib/eclipse 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.eclipse.jdt 55 | org.eclipse.jdt.core 56 | 57 | 3.39.0 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /support/eclipseLibs/src/main/java/adapter/e45/Dependencies.java: -------------------------------------------------------------------------------- 1 | package adapter.e45; 2 | 3 | public class Dependencies { 4 | org.eclipse.jface.text.BadLocationException a3; 5 | org.eclipse.jface.text.Document a4; 6 | org.eclipse.jface.text.IDocument a5; 7 | org.eclipse.text.edits.TextEdit a6; 8 | org.eclipse.jdt.core.formatter.CodeFormatter a7; 9 | org.eclipse.jdt.internal.formatter.DefaultCodeFormatter a8; 10 | org.eclipse.jface.text.BadLocationException a9; 11 | org.eclipse.jface.text.Document a10; 12 | org.eclipse.jface.text.IDocument a11; 13 | org.eclipse.text.edits.TextEdit a12; 14 | org.eclipse.jdt.core.compiler.InvalidInputException a13; 15 | org.eclipse.jdt.internal.compiler.util.SuffixConstants a14; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /support/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | krasa 8 | repackager 9 | 1.0 10 | pom 11 | 12 | 13 | eclipseLibs 14 | 15 | -------------------------------------------------------------------------------- /testProject/krasa.formattertest.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /testProject/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | krasa.formattertest 8 | krasa.formattertest 9 | 1.0-SNAPSHOT 10 | pom 11 | 12 | 13 | 14 | true 15 | org.apache.maven.plugins 16 | maven-compiler-plugin 17 | 2.5.1 18 | 19 | 1.7 20 | 1.7 21 | true 22 | true 23 | 24 | 25 | 26 | 27 | 28 | 29 | com.google.guava 30 | guava 31 | 15.0 32 | 33 | 34 | org.springframework 35 | spring-core 36 | 3.2.4.RELEASE 37 | 38 | 39 | org.easymock 40 | easymock 41 | 3.3.1 42 | 43 | 44 | 45 | submodule-a 46 | submodule-b 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /testProject/src/main/java/ImportTest.java: -------------------------------------------------------------------------------- 1 | import java.io.IOException; 2 | 3 | import org.junit.Before; 4 | import org.junit.Test; 5 | 6 | import mockit.MockUp; 7 | 8 | /** 9 | * Test. 10 | */ 11 | public class ImportTest { 12 | 13 | @Before 14 | public void beforeTest() throws Exception { 15 | new MockUp() { 16 | @Override 17 | 18 | public String toString() { 19 | return null; 20 | } 21 | }; 22 | } 23 | 24 | @Test(expected = IOException.class) 25 | public void test() throws Exception { 26 | throw new IOException(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /testProject/src/main/java/aaa/XAAA.java: -------------------------------------------------------------------------------- 1 | package aaa; 2 | 3 | public class XAAA { 4 | public static void aaa() { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /testProject/src/main/java/bar/foo/XBAR.java: -------------------------------------------------------------------------------- 1 | package bar.foo; 2 | 3 | import static aaa.XAAA.aaa; 4 | import static com.google.common.collect.Multimaps.forMap; 5 | import static foo.bar.XFOO.foo; 6 | import static org.easymock.EasyMock.createControl; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | 12 | import org.easymock.IMocksControl; 13 | 14 | import com.google.common.collect.SetMultimap; 15 | 16 | import aaa.XAAA; 17 | import foo.bar.XFOO; 18 | 19 | public class XBAR { 20 | 21 | public static void bar() { 22 | new XAAA(); 23 | aaa(); 24 | new XFOO(); 25 | foo(); 26 | 27 | SetMultimap objectObjectSetMultimap = forMap(new HashMap()); 28 | IMocksControl control = createControl(); 29 | List s = new ArrayList(); 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /testProject/src/main/java/base/LoadUnitTestDataTestCase.java: -------------------------------------------------------------------------------- 1 | package base; 2 | 3 | public class LoadUnitTestDataTestCase { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/comtrollers/deadbolt/Restrict.java: -------------------------------------------------------------------------------- 1 | package comtrollers.deadbolt; 2 | 3 | public class Restrict { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/controllers/deadbolt/Restricts.java: -------------------------------------------------------------------------------- 1 | package controllers.deadbolt; 2 | 3 | public class Restricts { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/foo/bar/XFOO.java: -------------------------------------------------------------------------------- 1 | package foo.bar; 2 | 3 | public class XFOO { 4 | public static void foo() { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/Main.java: -------------------------------------------------------------------------------- 1 | package importorder.example; 2 | 3 | import importorder.example.root.AAAA; 4 | import importorder.example.root.BFoo; 5 | import importorder.example.root.DFoo; 6 | import importorder.example.root.aaa; 7 | import importorder.example.root.Aa.AFoo; 8 | import importorder.example.root.Aaa.AaaFoo; 9 | import importorder.example.root.Bb.bb; 10 | import importorder.example.root.aB.Ab; 11 | import importorder.example.root.ba.ba; 12 | import importorder.example.root.bc.bc; 13 | 14 | public class Main { 15 | public static void main(String[] args) { 16 | new AaaFoo(); 17 | new AAAA(); 18 | new aaa(); 19 | new DFoo(); 20 | new AFoo(); 21 | new BFoo(); 22 | new Ab(); 23 | new bc(); 24 | new bb(); 25 | new ba(); 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/Main2.java: -------------------------------------------------------------------------------- 1 | package importorder.example; 2 | 3 | import java.util.Arrays; 4 | 5 | import javax.Javax; 6 | 7 | import comtrollers.deadbolt.Restrict; 8 | import controllers.deadbolt.Restricts; 9 | import models.Deployment; 10 | import play.jobs.Job; 11 | import play.mvc.Before; 12 | 13 | public class Main2 { 14 | public static void main(String[] args) { 15 | Arrays.asList(""); 16 | new Deployment(); 17 | new Job(); 18 | new Before(); 19 | new Restrict(); 20 | new Javax(); 21 | new Restricts(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/Main3.java: -------------------------------------------------------------------------------- 1 | package importorder.example; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.jingle.mocquer.MockControl; 7 | 8 | import com.sun.rmi.rmid.ExecOptionPermission; 9 | 10 | import base.LoadUnitTestDataTestCase; 11 | import sun.security.action.GetLongAction; 12 | import tmplatform.authorisation.ApiClientLink; 13 | import tmplatform.comms.common.caaa.EvasLdapInterfaceProfileWrapper; 14 | 15 | public class Main3 { 16 | 17 | public static void main(String[] args) { 18 | 19 | Map s = new HashMap(); 20 | 21 | new MockControl(); 22 | 23 | GetLongAction sdd; 24 | new ApiClientLink(); 25 | new EvasLdapInterfaceProfileWrapper(); 26 | new LoadUnitTestDataTestCase(); 27 | 28 | ExecOptionPermission ss; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/AAAA.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root; 2 | 3 | public class AAAA { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/Aa/AFoo.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root.Aa; 2 | 3 | public class AFoo { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/Aaa/AaaFoo.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root.Aaa; 2 | 3 | public class AaaFoo { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/BFoo.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root; 2 | 3 | public class BFoo { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/Bb/bb.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root.Bb; 2 | 3 | public class bb { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/DFoo.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root; 2 | 3 | public class DFoo { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/aB/Ab.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root.aB; 2 | 3 | public class Ab { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/aaa.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root; 2 | 3 | public class aaa { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/ba/ba.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root.ba; 2 | 3 | public class ba { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/importorder/example/root/bc/bc.java: -------------------------------------------------------------------------------- 1 | package importorder.example.root.bc; 2 | 3 | public class bc { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/javax/Javax.java: -------------------------------------------------------------------------------- 1 | package javax; 2 | 3 | public class Javax { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/mockit/MockUp.java: -------------------------------------------------------------------------------- 1 | package mockit; 2 | 3 | public class MockUp { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/models/Deployment.java: -------------------------------------------------------------------------------- 1 | package models; 2 | 3 | public class Deployment { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/org/jingle/mocquer/MockControl.java: -------------------------------------------------------------------------------- 1 | package org.jingle.mocquer; 2 | 3 | public class MockControl { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/play/jobs/Job.java: -------------------------------------------------------------------------------- 1 | package play.jobs; 2 | 3 | public class Job { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/play/mvc/Before.java: -------------------------------------------------------------------------------- 1 | package play.mvc; 2 | 3 | public class Before { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/tmplatform/authorisation/ApiClientLink.java: -------------------------------------------------------------------------------- 1 | package tmplatform.authorisation; 2 | 3 | public class ApiClientLink { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/src/main/java/tmplatform/comms/common/caaa/EvasLdapInterfaceProfileWrapper.java: -------------------------------------------------------------------------------- 1 | package tmplatform.comms.common.caaa; 2 | 3 | public class EvasLdapInterfaceProfileWrapper { 4 | } 5 | -------------------------------------------------------------------------------- /testProject/submodule-a/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | krasa.formattertest 9 | krasa.formattertest 10 | 1.0-SNAPSHOT 11 | 12 | 13 | submodule-a 14 | 15 | -------------------------------------------------------------------------------- /testProject/submodule-a/src/main/java/aaa/XAAA.java: -------------------------------------------------------------------------------- 1 | package aaa; 2 | 3 | public class XAAA { 4 | public static void aaa() { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /testProject/submodule-a/submodule-a.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /testProject/submodule-b/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | krasa.formattertest 9 | krasa.formattertest 10 | 1.0-SNAPSHOT 11 | 12 | 13 | submodule-b 14 | 15 | -------------------------------------------------------------------------------- /testProject/submodule-b/src/main/java/bbb/XBBB.java: -------------------------------------------------------------------------------- 1 | package bbb; 2 | 3 | public class XBBB { 4 | public static void bbb() { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /testProject/submodule-b/submodule-b.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /testProject/testProject.iml: -------------------------------------------------------------------------------- 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 | --------------------------------------------------------------------------------