diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..a7649b7 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: [krasa] diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 51015ed..f943552 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,15 @@ -> Do me a favor, if something fails in a method named #loadImportOrderFile, then attach the file... you get the idea. +> If the formating is different than expected: +> - make sure you are comparing with the same Eclipse version +> - provide a code example (both from Eclipse and from IntelliJ) and settings files + +> What steps will reproduce the issue? + +> What is the expected result? + +> What happens instead? + +> Сonsider attaching a screenshot, screencast, or a code sample when it's hard to articulate the problem. + +> Paste information about IDE and OS (it can be copied from Help | About dialog). > Please use triple backticks ``` before and after the stacktrace block. diff --git a/.gitignore b/.gitignore index 39f7f28..5b094b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,9 @@ -/EclipseFormatter.zip \ No newline at end of file +/.gradle +**/build +**/out +**/target +*.iws +*.ipr +*.zip +.shelf +.idea diff --git a/.idea/icon.png b/.idea/icon.png new file mode 100644 index 0000000..f5dcef2 Binary files /dev/null and b/.idea/icon.png differ diff --git a/.run/EclipseCodeFormatter [buildPlugin].run.xml b/.run/EclipseCodeFormatter [buildPlugin].run.xml new file mode 100644 index 0000000..0b5c803 --- /dev/null +++ b/.run/EclipseCodeFormatter [buildPlugin].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/.run/EclipseCodeFormatter [runIde].run.xml b/.run/EclipseCodeFormatter [runIde].run.xml new file mode 100644 index 0000000..2656e15 --- /dev/null +++ b/.run/EclipseCodeFormatter [runIde].run.xml @@ -0,0 +1,24 @@ + + + + + + + true + true + false + false + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..32c7f40 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +## [Unreleased] + +## [23.5.241.000.0-Eclipse_2024-09] - 2024-09-24 +Bundled Eclipse 2024-09 + +[Unreleased]: https://github.com/krasa/EclipseCodeFormatter/compare/v23.5.241.000.0-Eclipse_2024-09...HEAD +[23.5.241.000.0-Eclipse_2024-09]: https://github.com/krasa/EclipseCodeFormatter/commits/v23.5.241.000.0-Eclipse_2024-09 diff --git a/EclipseAdapter/EclipseAdapter.iml b/EclipseAdapter/EclipseAdapter.iml index bc366a4..e5b9abc 100644 --- a/EclipseAdapter/EclipseAdapter.iml +++ b/EclipseAdapter/EclipseAdapter.iml @@ -29,5 +29,16 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/EclipseAdapter/src/krasa/formatter/adapter/CppCodeFormatterFacade.java b/EclipseAdapter/src/krasa/formatter/adapter/CppCodeFormatterFacade.java deleted file mode 100644 index 47ff2ba..0000000 --- a/EclipseAdapter/src/krasa/formatter/adapter/CppCodeFormatterFacade.java +++ /dev/null @@ -1,67 +0,0 @@ -package krasa.formatter.adapter; - -import krasa.formatter.common.ModifiableFile; -import krasa.formatter.eclipse.CodeFormatterFacade; -import krasa.formatter.exception.FileDoesNotExistsException; -import krasa.formatter.exception.FormattingFailedException; -import krasa.formatter.plugin.InvalidPropertyFile; -import krasa.formatter.settings.Settings; -import krasa.formatter.settings.provider.CppPropertiesProvider; - -import org.eclipse.cdt.core.ToolFactory; -import org.eclipse.cdt.core.formatter.CodeFormatter; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.text.edits.TextEdit; - -import com.intellij.psi.PsiFile; - -/** - * @author Vojtech Krasa - */ -public class CppCodeFormatterFacade extends CodeFormatterFacade { - protected CodeFormatter codeFormatter; - - private CppPropertiesProvider propertiesProvider; - protected ModifiableFile.Monitor modifiedMonitor; - - public CppCodeFormatterFacade(CppPropertiesProvider propertiesProvider) { - this.propertiesProvider = propertiesProvider; - } - - private CodeFormatter getCodeFormatter() throws FileDoesNotExistsException { - if (codeFormatter == null || propertiesProvider.wasChanged(modifiedMonitor)) { - return newCodeFormatter(); - } - return codeFormatter; - } - - private CodeFormatter newCodeFormatter() throws InvalidPropertyFile { - modifiedMonitor = propertiesProvider.getModifiedMonitor(); - codeFormatter = ToolFactory.createDefaultCodeFormatter(toMap(propertiesProvider.get())); - return codeFormatter; - } - - @Override - public String format(String text, int startOffset, int endOffset, PsiFile psiFile) - throws FileDoesNotExistsException { - IDocument doc = new Document(); - try { - // format the file (the meat and potatoes) - doc.set(text); - TextEdit edit = getCodeFormatter().format(CodeFormatter.K_UNKNOWN, text, startOffset, - endOffset - startOffset, 0, Settings.LINE_SEPARATOR); - if (edit != null) { - edit.apply(doc); - } else { - throw new FormattingFailedException(); - } - - return doc.get(); - } catch (BadLocationException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/EclipseAdapter/src/krasa/formatter/adapter/EclipseJavaFormatterAdapter.java b/EclipseAdapter/src/krasa/formatter/adapter/EclipseJavaFormatterAdapter.java index b79fd7f..8889e2f 100644 --- a/EclipseAdapter/src/krasa/formatter/adapter/EclipseJavaFormatterAdapter.java +++ b/EclipseAdapter/src/krasa/formatter/adapter/EclipseJavaFormatterAdapter.java @@ -1,20 +1,15 @@ package krasa.formatter.adapter; -import java.util.Map; - import krasa.formatter.eclipse.EclipseFormatterAdapter; import krasa.formatter.exception.FileDoesNotExistsException; import krasa.formatter.exception.FormattingFailedException; -import krasa.formatter.settings.Settings; - -import org.eclipse.jdt.core.formatter.CodeFormatter; import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.text.edits.TextEdit; -import com.intellij.pom.java.LanguageLevel; +import java.util.Map; @SuppressWarnings("Duplicates") public class EclipseJavaFormatterAdapter extends EclipseFormatterAdapter { @@ -26,12 +21,9 @@ public EclipseJavaFormatterAdapter(Map options) { } @Override - public String format(String text, int startOffset, int endOffset, LanguageLevel level) + public String format(int kind, String text, int startOffset, int length, int indentationLevel, String lineSeparator, String languageLevel) throws FileDoesNotExistsException { - LOG.debug("#formatInternal"); - if (endOffset > text.length()) { - endOffset = text.length(); - } + IDocument doc = new Document(); try { doc.set(text); @@ -78,17 +70,15 @@ public String format(String text, int startOffset, int endOffset, LanguageLevel * if offset is lower than 0, length is lower than 0 or length is greater than source length. */ - LOG.debug("#starting to format by eclipse formatter"); - TextEdit edit = defaultCodeFormatter.format( - CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, text, startOffset, - endOffset - startOffset, 0, Settings.LINE_SEPARATOR); + TextEdit edit = defaultCodeFormatter.format(kind, text, startOffset, length, indentationLevel, lineSeparator); if (edit != null) { - LOG.debug("reformatting done"); edit.apply(doc); } else { - throw new FormattingFailedException(getErrorMessage(level)); + throw new FormattingFailedException(getErrorMessage(languageLevel)); } return doc.get(); + } catch (IndexOutOfBoundsException e) { + throw new FormattingFailedException(e, getErrorMessage(languageLevel)); } catch (BadLocationException e) { throw new RuntimeException(e); } diff --git a/EclipseAdapter/test/krasa/formatter/adapter/CppCodeFormatterFacadeTest.java b/EclipseAdapter/test/krasa/formatter/adapter/CppCodeFormatterFacadeTest.java deleted file mode 100644 index cdf597d..0000000 --- a/EclipseAdapter/test/krasa/formatter/adapter/CppCodeFormatterFacadeTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package krasa.formatter.adapter; - -import java.io.File; - -import org.junit.Before; -import org.junit.Test; - -import junit.framework.Assert; -import krasa.formatter.settings.Settings; -import krasa.formatter.settings.provider.CppPropertiesProvider; - -public class CppCodeFormatterFacadeTest { - - protected static final String INPUT = "#include \n" + "\n" + " using namespace std;\n" + "\n" - + " int main() {\n" + " cout << \"Hello, World!\" << endl;\n" + " return 0;\n" + " }"; - protected static final String FORMATTED = "#include \n" + "\n" + "using namespace std;\n" + "\n" - + "int main() {\n" + " cout << \"Hello, World!\" << endl;\n" + " return 0;\n" + "}\n"; - private String prefix = ""; - - @Before - public void setUp() throws Exception { - if (!new File("test/resources").exists()) { - prefix = "../"; - } - } - - @Test - public void xmlConfig() throws Exception { - Settings settings = new Settings(); - settings.setPathToConfigFileCpp(prefix + "test/resources/cpp.xml"); - settings.setSelectedCppProfile("KR"); - CppCodeFormatterFacade cppCodeFormatterFacade = new CppCodeFormatterFacade(new CppPropertiesProvider(settings)); - String s = cppCodeFormatterFacade.format(INPUT, 0, INPUT.length(), null); - System.err.println(s); - Assert.assertEquals(FORMATTED, s); - } - - @Test - public void propertiesConfig() throws Exception { - Settings settings = new Settings(); - settings.setPathToConfigFileCpp(prefix + "test/resources/org.eclipse.cdt.core.prefs"); - CppCodeFormatterFacade cppCodeFormatterFacade = new CppCodeFormatterFacade(new CppPropertiesProvider(settings)); - String s = cppCodeFormatterFacade.format(INPUT, 0, INPUT.length(), null); - System.err.println(s); - Assert.assertEquals(FORMATTED, s); - } -} \ No newline at end of file diff --git a/EclipseAdapter44/EclipseAdapter44.iml b/EclipseAdapter44/EclipseAdapter44.iml deleted file mode 100644 index 7427fb8..0000000 --- a/EclipseAdapter44/EclipseAdapter44.iml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/EclipseAdapter44/src/krasa/formatter/adapter/EclipseJavaFormatterAdapter44.java b/EclipseAdapter44/src/krasa/formatter/adapter/EclipseJavaFormatterAdapter44.java deleted file mode 100644 index a237314..0000000 --- a/EclipseAdapter44/src/krasa/formatter/adapter/EclipseJavaFormatterAdapter44.java +++ /dev/null @@ -1,96 +0,0 @@ -package krasa.formatter.adapter; - -import com.intellij.pom.java.LanguageLevel; -import krasa.formatter.eclipse.EclipseFormatterAdapter; -import krasa.formatter.exception.FileDoesNotExistsException; -import krasa.formatter.exception.FormattingFailedException; -import krasa.formatter.settings.Settings; -import org.eclipse.jdt.core.formatter.CodeFormatter; -import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.text.edits.TextEdit; - -import java.util.Map; - -@SuppressWarnings("Duplicates") -public class EclipseJavaFormatterAdapter44 extends EclipseFormatterAdapter { - - protected DefaultCodeFormatter defaultCodeFormatter; - - @SuppressWarnings("unused") - public EclipseJavaFormatterAdapter44(Map options) { - defaultCodeFormatter = new DefaultCodeFormatter(options); - } - - @Override - public String format(String text, int startOffset, int endOffset, LanguageLevel level) - throws FileDoesNotExistsException { - - LOG.debug("#formatInternal"); - if (endOffset > text.length()) { - endOffset = text.length(); - } - IDocument doc = new Document(); - try { - doc.set(text); - /** - * Format source, and returns a text edit that correspond to the difference between the given - * string and the formatted string. - *

- * It returns null if the given string cannot be formatted. - *

- *

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

- * - * @param kind - * Use to specify the kind of the code snippet to format. It can be any of these: - *
    - *
  • {@link #K_EXPRESSION}
  • - *
  • {@link #K_STATEMENTS}
  • - *
  • {@link #K_CLASS_BODY_DECLARATIONS}
  • - *
  • {@link #K_COMPILATION_UNIT}
    - * Since 3.4, the comments can be formatted on the fly while using this kind of code - * snippet
    - * (see {@link #F_INCLUDE_COMMENTS} for more detailed explanation on this flag)
  • - *
  • {@link #K_UNKNOWN}
  • - *
  • {@link #K_SINGLE_LINE_COMMENT}
  • - *
  • {@link #K_MULTI_LINE_COMMENT}
  • - *
  • {@link #K_JAVA_DOC}
  • - *
- * @param source - * the source to format - * @param offset - * the given offset to start recording the edits (inclusive). - * @param length - * the given length to stop recording the edits (exclusive). - * @param indentationLevel - * the initial indentation level, used to shift left/right the entire source fragment. An initial - * indentation level of zero or below has no effect. - * @param lineSeparator - * the line separator to use in formatted source, if set to null, then the platform - * default one will be used. - * @return the text edit - * @throws IllegalArgumentException - * if offset is lower than 0, length is lower than 0 or length is greater than source length. - */ - - LOG.debug("#starting to format by eclipse formatter"); - TextEdit edit = defaultCodeFormatter.format( - CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, text, startOffset, - endOffset - startOffset, 0, Settings.LINE_SEPARATOR); - if (edit != null) { - LOG.debug("reformatting done"); - edit.apply(doc); - } else { - throw new FormattingFailedException(getErrorMessage(level)); - } - return doc.get(); - } catch (BadLocationException e) { - throw new RuntimeException(e); - } - } -} diff --git a/EclipseAdapter44/src/krasa/formatter/adapter/EclipseJsFormatterAdapter44.java b/EclipseAdapter44/src/krasa/formatter/adapter/EclipseJsFormatterAdapter44.java deleted file mode 100644 index f3ed50c..0000000 --- a/EclipseAdapter44/src/krasa/formatter/adapter/EclipseJsFormatterAdapter44.java +++ /dev/null @@ -1,96 +0,0 @@ -package krasa.formatter.adapter; - -import com.intellij.pom.java.LanguageLevel; -import krasa.formatter.eclipse.EclipseFormatterAdapter; -import krasa.formatter.exception.FileDoesNotExistsException; -import krasa.formatter.exception.FormattingFailedException; -import krasa.formatter.settings.Settings; -import org.eclipse.jdt.core.formatter.CodeFormatter; -import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.text.edits.TextEdit; - -import java.util.Map; - -@SuppressWarnings("Duplicates") -public class EclipseJsFormatterAdapter44 extends EclipseFormatterAdapter { - - protected DefaultCodeFormatter defaultCodeFormatter; - - @SuppressWarnings("unused") - public EclipseJsFormatterAdapter44(Map options) { - defaultCodeFormatter = new DefaultCodeFormatter(options); - } - - @Override - public String format(String text, int startOffset, int endOffset, LanguageLevel level) - throws FileDoesNotExistsException { - - LOG.debug("#formatInternal"); - if (endOffset > text.length()) { - endOffset = text.length(); - } - IDocument doc = new Document(); - try { - doc.set(text); - /** - * Format source, and returns a text edit that correspond to the difference between the given - * string and the formatted string. - *

- * It returns null if the given string cannot be formatted. - *

- *

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

- * - * @param kind - * Use to specify the kind of the code snippet to format. It can be any of these: - *
    - *
  • {@link #K_EXPRESSION}
  • - *
  • {@link #K_STATEMENTS}
  • - *
  • {@link #K_CLASS_BODY_DECLARATIONS}
  • - *
  • {@link #K_COMPILATION_UNIT}
    - * Since 3.4, the comments can be formatted on the fly while using this kind of code - * snippet
    - * (see {@link #F_INCLUDE_COMMENTS} for more detailed explanation on this flag)
  • - *
  • {@link #K_UNKNOWN}
  • - *
  • {@link #K_SINGLE_LINE_COMMENT}
  • - *
  • {@link #K_MULTI_LINE_COMMENT}
  • - *
  • {@link #K_JAVA_DOC}
  • - *
- * @param source - * the source to format - * @param offset - * the given offset to start recording the edits (inclusive). - * @param length - * the given length to stop recording the edits (exclusive). - * @param indentationLevel - * the initial indentation level, used to shift left/right the entire source fragment. An initial - * indentation level of zero or below has no effect. - * @param lineSeparator - * the line separator to use in formatted source, if set to null, then the platform - * default one will be used. - * @return the text edit - * @throws IllegalArgumentException - * if offset is lower than 0, length is lower than 0 or length is greater than source length. - */ - - LOG.debug("#starting to format by eclipse formatter"); - TextEdit edit = defaultCodeFormatter.format( - CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, text, startOffset, - endOffset - startOffset, 0, Settings.LINE_SEPARATOR); - if (edit != null) { - LOG.debug("reformatting done"); - edit.apply(doc); - } else { - throw new FormattingFailedException(getErrorMessage(level)); - } - return doc.get(); - } catch (BadLocationException e) { - throw new RuntimeException(e); - } - } -} diff --git a/EclipseAdapter44/src/krasa/formatter/adapter/JSCodeFormatterFacade.java b/EclipseAdapter44/src/krasa/formatter/adapter/JSCodeFormatterFacade.java deleted file mode 100644 index 5e83ba1..0000000 --- a/EclipseAdapter44/src/krasa/formatter/adapter/JSCodeFormatterFacade.java +++ /dev/null @@ -1,154 +0,0 @@ -package krasa.formatter.adapter; - -import krasa.formatter.common.ModifiableFile; -import krasa.formatter.eclipse.CodeFormatterFacade; -import krasa.formatter.exception.FileDoesNotExistsException; -import krasa.formatter.exception.FormattingFailedException; -import krasa.formatter.plugin.InvalidPropertyFile; -import krasa.formatter.settings.Settings; -import krasa.formatter.settings.provider.JSPropertiesProvider; - -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.text.edits.TextEdit; -import org.eclipse.wst.jsdt.core.formatter.CodeFormatter; - -import com.intellij.psi.PsiFile; - -/** - * @author Vojtech Krasa - */ -public class JSCodeFormatterFacade extends CodeFormatterFacade { - protected org.eclipse.wst.jsdt.core.formatter.CodeFormatter codeFormatter; - - private JSPropertiesProvider propertiesProvider; - protected ModifiableFile.Monitor modifiedMonitor; - - public JSCodeFormatterFacade(JSPropertiesProvider propertiesProvider) { - this.propertiesProvider = propertiesProvider; - } - - private org.eclipse.wst.jsdt.core.formatter.CodeFormatter getCodeFormatter() throws FileDoesNotExistsException { - if (codeFormatter == null || propertiesProvider.wasChanged(modifiedMonitor)) { - return newCodeFormatter(); - } - return codeFormatter; - } - - private org.eclipse.wst.jsdt.core.formatter.CodeFormatter newCodeFormatter() throws InvalidPropertyFile { - modifiedMonitor = propertiesProvider.getModifiedMonitor(); - codeFormatter = org.eclipse.wst.jsdt.core.ToolFactory.createCodeFormatter(propertiesProvider.get()); - return codeFormatter; - } - - @Override - public String format(String text, int startOffset, int endOffset, PsiFile psiFile) - throws FileDoesNotExistsException { - IDocument doc = new Document(); - try { - // format the file (the meat and potatoes) - doc.set(text); - /** - * Format source, and returns a text edit that correspond to the difference between the given - * string and the formatted string. - *

- * It returns null if the given string cannot be formatted. - *

- * - *

- * If the offset position is matching a whitespace, the result can include whitespaces. It would be up to - * the caller to get rid of preceeding whitespaces. - *

- * - * @param kind - * Use to specify the kind of the code snippet to format. It can be any of these: K_EXPRESSION, - * K_STATEMENTS, K_CLASS_BODY_DECLARATIONS, K_JAVASCRIPT_UNIT, K_UNKNOWN, K_SINGLE_LINE_COMMENT, - * K_MULTI_LINE_COMMENT, K_JAVA_DOC - * @param source - * the source to format - * @param offset - * the given offset to start recording the edits (inclusive). - * @param length - * the given length to stop recording the edits (exclusive). - * @param indentationLevel - * the initial indentation level, used to shift left/right the entire source fragment. An initial - * indentation level of zero or below has no effect. - * @param lineSeparator - * the line separator to use in formatted source, if set to null, then the platform - * default one will be used. - * @return the text edit - * @throws IllegalArgumentException - * if offset is lower than 0, length is lower than 0 or length is greater than source length. - */ - TextEdit edit = getCodeFormatter().format(CodeFormatter.K_JAVASCRIPT_UNIT, text, startOffset, - endOffset - startOffset, 0, Settings.LINE_SEPARATOR); - if (edit != null) { - edit.apply(doc); - } else { - throw new FormattingFailedException(); - } - - return doc.get(); - } catch (BadLocationException e) { - throw new RuntimeException(e); - } - } - - public String format(String text, int startOffset, int endOffset, int kJavascriptUnit) - throws FileDoesNotExistsException { - IDocument doc = new Document(); - try { - // format the file (the meat and potatoes) - doc.set(text); - /** - * Format source, and returns a text edit that correspond to the difference between the given - * string and the formatted string. - *

- * It returns null if the given string cannot be formatted. - *

- * - *

- * If the offset position is matching a whitespace, the result can include whitespaces. It would be up to - * the caller to get rid of preceeding whitespaces. - *

- * - * @param kind - * Use to specify the kind of the code snippet to format. It can be any of these: K_EXPRESSION, - * K_STATEMENTS, K_CLASS_BODY_DECLARATIONS, K_JAVASCRIPT_UNIT, K_UNKNOWN, K_SINGLE_LINE_COMMENT, - * K_MULTI_LINE_COMMENT, K_JAVA_DOC - * @param source - * the source to format - * @param offset - * the given offset to start recording the edits (inclusive). - * @param length - * the given length to stop recording the edits (exclusive). - * @param indentationLevel - * the initial indentation level, used to shift left/right the entire source fragment. An initial - * indentation level of zero or below has no effect. - * @param lineSeparator - * the line separator to use in formatted source, if set to null, then the platform - * default one will be used. - * @return the text edit - * @throws IllegalArgumentException - * if offset is lower than 0, length is lower than 0 or length is greater than source length. - */ - TextEdit edit = getCodeFormatter().format(kJavascriptUnit, text, startOffset, endOffset - startOffset, 0, - Settings.LINE_SEPARATOR); - if (edit != null) { - edit.apply(doc); - } else { - throw new FormattingFailedException(); - } - - return doc.get(); - } catch (BadLocationException e) { - throw new RuntimeException(e); - } - } - - public TextEdit format(int kind, String source, int offset, int length, int indentationLevel, - String lineSeparator) { - return getCodeFormatter().format(kind, source, offset, length, indentationLevel, lineSeparator); - } -} diff --git a/EclipseAdapter44/src/krasa/formatter/adapter/JsniFormattingUtil.java b/EclipseAdapter44/src/krasa/formatter/adapter/JsniFormattingUtil.java deleted file mode 100644 index 0584bf3..0000000 --- a/EclipseAdapter44/src/krasa/formatter/adapter/JsniFormattingUtil.java +++ /dev/null @@ -1,283 +0,0 @@ -/******************************************************************************* - * Copyright 2011 Google Inc. All Rights Reserved. - *

- * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package krasa.formatter.adapter; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import krasa.formatter.plugin.Range; -import krasa.formatter.settings.Settings; - -import org.eclipse.jdt.core.formatter.IndentManipulation; -import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; -import org.eclipse.jface.text.*; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.ReplaceEdit; -import org.eclipse.text.edits.TextEdit; -import org.eclipse.wst.jsdt.core.ToolFactory; -import org.eclipse.wst.jsdt.core.formatter.CodeFormatter; - -import com.google.gwt.eclipse.core.editors.java.GWTPartitions; -import com.google.gwt.eclipse.core.validators.java.JsniParser; - -/** - * Utility methods for formatting JSNI methods. This is not a full-blown JavaScript pretty-printer, but it does apply - * the correct outer indentation to JSNI blocks, to correct the JDT bug which slides them to the right. - */ -@SuppressWarnings("restriction") -public class JsniFormattingUtil { - - private static class JsniJavaRefReplacementResult { - private String jsni; - private Map replacements; - - public JsniJavaRefReplacementResult(String jsni, Map replacements) { - this.jsni = jsni; - this.replacements = replacements; - } - - public String getJsni() { - return jsni; - } - - public Map getReplacements() { - return replacements; - } - } - - /** - * Returns a text edit that formats the given document according to the given settings. - * - * @param document - * The document to format. - * @param javaFormattingPrefs - * The formatting preferences for Java, used to determine the method level indentation. - * @param javaScriptFormattingPrefs - * The formatting preferences for JavaScript. See org.eclipse.wst.jsdt.internal.formatter - * .DefaultCodeFormatterOptions and org.eclipse.wst.jsdt.core.formatter.DefaultCodeFormatterConstants - * @param originalJsniMethods - * The original jsni methods to use if the formatter fails to format the method. The original jsni - * Strings must be in the same order that the jsni methods occur in the document. This is to work around - * the Java formatter blasting the jsni tabbing for the format-on-save action. May be null. - * @return A text edit that when applied to the document, will format the jsni methods. - */ - @SuppressWarnings("unchecked") - public TextEdit format(IDocument document, Map javaFormattingPrefs, Map javaScriptFormattingPrefs, Range range) { - TextEdit combinedEdit = new MultiTextEdit(); - ITypedRegion[] regions = computePartitioning(document, range); - - // Format all JSNI blocks in the document - int i = 0; - for (ITypedRegion region : regions) { - if (region.getType().equals(GWTPartitions.JSNI_METHOD)) { - String originalJsniMethod = null; - TextEdit edit = format(document, new TypedPosition(region), javaFormattingPrefs, - javaScriptFormattingPrefs, originalJsniMethod); - if (edit != null) { - combinedEdit.addChild(edit); - } - i++; - } - } - return combinedEdit; - - } - - private static ITypedRegion[] computePartitioning(IDocument document, Range range) { - ArrayList iTypedRegions = new ArrayList(); - String str = document.get(); - String prefix = "/*-"; - String postfix = "-*/"; - int startIndex = 0; - int endIndex = 0; - - while (startIndex != -1) { - startIndex = str.indexOf(prefix, startIndex); - endIndex = str.indexOf(postfix, startIndex); - - if (startIndex != -1 && endIndex != -1) { - endIndex = endIndex + 3; - if (isInRange(range, startIndex, endIndex)) { - iTypedRegions.add(new TypedRegion(startIndex, endIndex - startIndex, GWTPartitions.JSNI_METHOD)); - } - startIndex += prefix.length(); - } - } - return iTypedRegions.toArray(new ITypedRegion[iTypedRegions.size()]); - - } - - private static boolean isInRange(Range range, int startIndex, int endIndex) { - boolean b = range.getStartOffset() < startIndex && range.getEndOffset() > endIndex; - boolean b1 = startIndex < range.getEndOffset() && range.getEndOffset() < endIndex; - boolean b2 = startIndex < range.getStartOffset() && range.getStartOffset() < endIndex; - return range.isWholeFile() || b || b1 || b2; - } - - public TextEdit format(IDocument document, TypedPosition partition, Map javaFormattingPrefs, - Map javaScriptFormattingPrefs, String original) { - try { - // Extract the JSNI block out of the document - int offset = partition.getOffset(); - int length = partition.getLength(); - - // Determine the line delimiter, indent string, and tab/indent widths - String lineDelimiter = Settings.LINE_SEPARATOR; - int tabWidth = IndentManipulation.getTabWidth(javaFormattingPrefs); - int indentWidth = IndentManipulation.getIndentWidth(javaFormattingPrefs); - - // Get indentation level of the first line of the JSNI block (this should - // be the line containing the JSNI method declaration) - int methodDeclarationOffset = getMethodDeclarationOffset(document, offset); - - int jsniLine1 = document.getLineOfOffset(methodDeclarationOffset); - int methodIndentLevel = getLineIndentLevel(document, jsniLine1, tabWidth, indentWidth); - DefaultCodeFormatter defaultCodeFormatter = new DefaultCodeFormatter(javaFormattingPrefs); - String indentLine = defaultCodeFormatter.createIndentationString(methodIndentLevel); - - // Extract the JSNI body out of the block and split it up by line - String jsniSource = document.get(offset, length); - String body = JsniParser.extractMethodBody(jsniSource); - - String formattedJs; - - // JSNI Java references mess up the JS formatter, so replace them - // with place holder values - JsniJavaRefReplacementResult replacementResults = replaceJsniJavaRefs(body); - body = replacementResults.getJsni(); - CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(javaScriptFormattingPrefs); - - TextEdit formatEdit = codeFormatter.format(CodeFormatter.K_STATEMENTS, body, 0, body.length(), - methodIndentLevel + 1, lineDelimiter); - - if (formatEdit != null) { - - body = restoreJsniJavaRefs(replacementResults); - - Document d = new Document(body); - formatEdit.apply(d); - - formattedJs = d.get(); - - if (!formattedJs.startsWith(lineDelimiter)) { - formattedJs = lineDelimiter + formattedJs; - } - - if (!formattedJs.endsWith(lineDelimiter)) { - formattedJs = formattedJs + lineDelimiter; - } - - formattedJs = formattedJs + indentLine; - - formattedJs = "/*-{" + formattedJs + "}-*/"; - - } else { - - if (original == null) { - return null; - } - - formattedJs = original; // formatting failed, use the original string - } - - return new ReplaceEdit(offset, length, formattedJs); - - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static int getMethodDeclarationOffset(IDocument document, int offset) { - int methodDeclarationOffset = offset; - - // jsniMethodWithDeclarationLineThatWraps - String s = document.get(); - int i = s.lastIndexOf("\n", offset); - String substring = s.substring(i + 1, offset); - substring = substring.trim(); - if (!substring.isEmpty() && !substring.contains("(")) { - methodDeclarationOffset = i - 2; - } - return methodDeclarationOffset; - } - - private static int getLineIndentLevel(IDocument document, int line, int tabWidth, int indentWidth) - throws BadLocationException { - int lineOffset = document.getLineOffset(line); - return getLineIndentLevel(document.get(lineOffset, document.getLineLength(line)), tabWidth, indentWidth); - } - - private static int getLineIndentLevel(String line, int tabWidth, int indentWidth) { - return IndentManipulation.measureIndentUnits(line, tabWidth, indentWidth); - } - - private static String makeJsToken(String s) { - int hashCode = s.hashCode(); - // js variable names can't have negative signs in them - String jsToken = "_" + (hashCode < 0 ? "N" + Math.abs(hashCode) : hashCode); - - // pad the hash so it's the same length as the original reference so that - // things like formatting line wrap works - while (jsToken.length() < s.length()) { - jsToken = jsToken + "_"; - } - return jsToken; - } - - private static JsniJavaRefReplacementResult replaceJsniJavaRefs(String jsni) { - - Map replacements = new HashMap(); - - Pattern p = Pattern.compile("@[a-zA-Z0-9._$]+::[a-zA-Z0-9_$]+(\\(.*?\\)\\(.*?\\))?"); - - Matcher m = p.matcher(jsni); - - while (m.find()) { - int start = m.start(); - int end = m.end(); - - String ref = jsni.substring(start, end); - String jsToken = makeJsToken(ref); - - // if the map already contains the js token, and the token's original jsni - // ref is not the one we've found, js-tokenize the token - while (replacements.containsKey(jsToken) && !replacements.get(jsToken).equals(ref)) { - jsToken = makeJsToken(jsToken); - } - - replacements.put(jsToken, ref); - } - - for (Entry kvp : replacements.entrySet()) { - jsni = jsni.replace(kvp.getValue(), kvp.getKey()); - } - - return new JsniJavaRefReplacementResult(jsni, replacements); - } - - private static String restoreJsniJavaRefs(JsniJavaRefReplacementResult result) { - - String jsni = result.getJsni(); - for (Entry kvp : result.getReplacements().entrySet()) { - jsni = jsni.replace(kvp.getKey(), kvp.getValue()); - } - - return jsni; - } -} diff --git a/EclipseAdapter44/src/krasa/formatter/adapter/processor/GWTProcessor.java b/EclipseAdapter44/src/krasa/formatter/adapter/processor/GWTProcessor.java deleted file mode 100644 index e347573..0000000 --- a/EclipseAdapter44/src/krasa/formatter/adapter/processor/GWTProcessor.java +++ /dev/null @@ -1,47 +0,0 @@ -package krasa.formatter.adapter.processor; - -import java.util.Properties; - -import krasa.formatter.adapter.JsniFormattingUtil; -import krasa.formatter.plugin.Range; -import krasa.formatter.processor.Processor; -import krasa.formatter.settings.Settings; -import krasa.formatter.utils.FileUtils; - -import org.eclipse.jface.text.IDocument; -import org.eclipse.text.edits.TextEdit; - -import com.intellij.openapi.editor.Document; -import com.intellij.psi.PsiFile; - -/** - * @author Vojtech Krasa - */ -public class GWTProcessor implements Processor { - private Settings settings; - - public GWTProcessor(Settings settings) { - this.settings = settings; - } - - @Override - public boolean process(Document documentIJ, PsiFile file, Range range) { - if (FileUtils.isJava(file) && settings.isEnableGWT()) { - try { - IDocument document = new org.eclipse.jface.text.Document(documentIJ.getText()); - Properties javaFormattingPrefs = settings.getJavaProperties().get(); - Properties jsFormattingPrefs = settings.getJSProperties().get(); - - JsniFormattingUtil jsniFormattingUtil = new JsniFormattingUtil(); - TextEdit formatEdit = jsniFormattingUtil.format(document, javaFormattingPrefs, jsFormattingPrefs, - range); - formatEdit.apply(document); - documentIJ.setText(document.get()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - return true; - } - -} diff --git a/EclipseAdapter44/src/krasa/formatter/adapter/processor/JSCommentsFormatterProcessor.java b/EclipseAdapter44/src/krasa/formatter/adapter/processor/JSCommentsFormatterProcessor.java deleted file mode 100644 index 594a15f..0000000 --- a/EclipseAdapter44/src/krasa/formatter/adapter/processor/JSCommentsFormatterProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -package krasa.formatter.adapter.processor; - -import java.util.ArrayList; - -import krasa.formatter.adapter.JSCodeFormatterFacade; -import krasa.formatter.plugin.Range; -import krasa.formatter.processor.Processor; -import krasa.formatter.settings.Settings; -import krasa.formatter.utils.FileUtils; - -import org.eclipse.jdt.core.formatter.IndentManipulation; -import org.eclipse.jface.text.*; -import org.eclipse.text.edits.MultiTextEdit; -import org.eclipse.text.edits.ReplaceEdit; -import org.eclipse.text.edits.TextEdit; -import org.eclipse.wst.jsdt.core.formatter.CodeFormatter; - -import com.google.gwt.eclipse.core.editors.java.GWTPartitions; -import com.intellij.openapi.editor.Document; -import com.intellij.psi.PsiFile; - -/** - * @author Vojtech Krasa - */ -public class JSCommentsFormatterProcessor implements Processor { - private Settings settings; - private JSCodeFormatterFacade jsCodeFormatterFacade; - - public JSCommentsFormatterProcessor(Settings settings) { - this.settings = settings; - jsCodeFormatterFacade = new JSCodeFormatterFacade(settings.getJSProperties()); - } - - @Override - public boolean process(Document documentIJ, PsiFile file, Range range) { - if (FileUtils.isJavaScript(file) && settings.isEnableJSProcessor()) { - try { - String text = documentIJ.getText(); - IDocument document = new org.eclipse.jface.text.Document(text); - - TextEdit formatEdit = format(document, range); - - formatEdit.apply(document); - documentIJ.setText(document.get()); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - return true; - } - - private TextEdit format(IDocument document, Range range) { - TextEdit combinedEdit = new MultiTextEdit(); - ITypedRegion[] regions = computePartitioning(document, range); - - // Format all JSNI blocks in the document - int i = 0; - for (ITypedRegion region : regions) { - if (region.getType().equals(GWTPartitions.JSNI_METHOD)) { - TextEdit edit = format(document, new TypedPosition(region)); - if (edit != null) { - combinedEdit.addChild(edit); - } - i++; - } - } - return combinedEdit; - - } - - public TextEdit format(IDocument document, TypedPosition partition) { - try { - // Extract the JSNI block out of the document - int offset = partition.getOffset(); - int length = partition.getLength(); - - // Determine the line delimiter, indent string, and tab/indent widths - String lineDelimiter = Settings.LINE_SEPARATOR; - int tabWidth = IndentManipulation.getTabWidth(settings.getJSProperties().get()); - int indentWidth = IndentManipulation.getIndentWidth(settings.getJSProperties().get()); - - // Get indentation level of the first line of the JSNI block (this should - // be the line containing the JSNI method declaration) - int methodDeclarationOffset = getMethodDeclarationOffset(document, offset); - - int jsniLine1 = document.getLineOfOffset(methodDeclarationOffset); - int methodIndentLevel = getLineIndentLevel(document, jsniLine1, tabWidth, indentWidth); - // String indentLine = defaultCodeFormatter.createIndentationString(methodIndentLevel); - - // Extract the JSNI body out of the block and split it up by line - String jsniSource = document.get(offset, length); - - String formattedJs; - - TextEdit formatEdit = jsCodeFormatterFacade.format(CodeFormatter.K_JAVA_DOC, jsniSource, 0, - jsniSource.length(), methodIndentLevel, lineDelimiter); - - org.eclipse.jface.text.Document d = new org.eclipse.jface.text.Document(jsniSource); - formatEdit.apply(d); - - formattedJs = d.get(); - - // if (!formattedJs.startsWith(lineDelimiter)) { - // formattedJs = indentLine+formattedJs ; - // formattedJs = lineDelimiter + formattedJs; - // } - // - if (!formattedJs.endsWith(lineDelimiter)) { - formattedJs = formattedJs + lineDelimiter; - } - - // formattedJs = formattedJs + indentLine; - - return new ReplaceEdit(offset, length, formattedJs); - - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static int getLineIndentLevel(IDocument document, int line, int tabWidth, int indentWidth) - throws BadLocationException { - int lineOffset = document.getLineOffset(line); - return getLineIndentLevel(document.get(lineOffset, document.getLineLength(line)), tabWidth, indentWidth); - } - - private static int getLineIndentLevel(String line, int tabWidth, int indentWidth) { - return IndentManipulation.measureIndentUnits(line, tabWidth, indentWidth); - } - - private static int getMethodDeclarationOffset(IDocument document, int offset) { - int methodDeclarationOffset = offset; - - // jsniMethodWithDeclarationLineThatWraps - String s = document.get(); - int i = s.lastIndexOf("\n", offset); - String substring = s.substring(i + 1, offset); - substring = substring.trim(); - if (!substring.isEmpty() && !substring.contains("(")) { - methodDeclarationOffset = i - 2; - } - return methodDeclarationOffset; - } - - private static ITypedRegion[] computePartitioning(IDocument document, Range range) { - ArrayList iTypedRegions = new ArrayList(); - String str = document.get(); - String prefix = "/**"; - String postfix = "*/"; - int startIndex = 0; - int endIndex = 0; - - while (startIndex != -1) { - startIndex = str.indexOf(prefix, startIndex); - endIndex = str.indexOf(postfix, startIndex); - - if (startIndex != -1 && endIndex != -1) { - endIndex = endIndex + 3; - if (isInRange(range, startIndex, endIndex)) { - iTypedRegions.add(new TypedRegion(startIndex, endIndex - startIndex, GWTPartitions.JSNI_METHOD)); - } - startIndex += prefix.length(); - } - } - return iTypedRegions.toArray(new ITypedRegion[iTypedRegions.size()]); - - } - - private static boolean isInRange(Range range, int startIndex, int endIndex) { - boolean b = range.getStartOffset() < startIndex && range.getEndOffset() > endIndex; - boolean b1 = startIndex < range.getEndOffset() && range.getEndOffset() < endIndex; - boolean b2 = startIndex < range.getStartOffset() && range.getStartOffset() < endIndex; - return range.isWholeFile() || b || b1 || b2; - } -} diff --git a/EclipseAdapter44/test/krasa/formatter/eclipse/GWTTest.java b/EclipseAdapter44/test/krasa/formatter/eclipse/GWTTest.java deleted file mode 100644 index 52e7bca..0000000 --- a/EclipseAdapter44/test/krasa/formatter/eclipse/GWTTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package krasa.formatter.eclipse; - -import java.util.HashMap; - -import junit.framework.Assert; -import krasa.formatter.adapter.JsniFormattingUtil; - -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.jface.text.TypedPosition; -import org.eclipse.text.edits.TextEdit; -import org.junit.Test; - -/** - * @author Vojtech Krasa - */ -public class GWTTest { - public static final String INPUT = "package aaa.shared;\n" - + "\n" - + "import krasa.JavaScriptObject;\n" - + "\n" - + "public class FieldVerifier {\n" - + "\n" - + "\tprivate native JavaScriptObject jsInit() /*-{\tvar self = this;\t(function() {\talert(\"Hello\");\t})();\t}-*/;\n" - + "}"; - - public static final String FORMATTED = "package aaa.shared;\n" + "\n" + "import krasa.JavaScriptObject;\n" + "\n" - + "public class FieldVerifier {\n" + "\n" + "\tprivate native JavaScriptObject jsInit() /*-{\n" - + "\t\tvar self = this;\n" + "\t\t(function() {\n" + "\t\t\talert(\"Hello\");\n" + "\t\t})();\n" - + "\t}-*/;\n" + "}"; - - @Test - public void testName() throws Exception { - HashMap javaFormattingPrefs = TestUtils.getJavaProperties(); - - int i = INPUT.indexOf("/*-"); - int i2 = INPUT.indexOf("-*/"); - TypedPosition partition = new TypedPosition(i, i2 - i + 3, ""); - HashMap jsMap = TestUtils.getJSProperties(); - - IDocument document = new Document(INPUT); - JsniFormattingUtil jsniFormattingUtil = new JsniFormattingUtil(); - TextEdit format1 = jsniFormattingUtil.format(document, partition, javaFormattingPrefs, jsMap, null); - // TextEdit format1 = JsniFormattingUtil.format(document,javaFormattingPrefs, jsMap, null); - format1.apply(document); - Assert.assertEquals(FORMATTED, document.get()); - System.err.println(FORMATTED); - } - -} diff --git a/EclipseAdapter44/test/krasa/formatter/eclipse/JsniFormattingUtilTest.java b/EclipseAdapter44/test/krasa/formatter/eclipse/JsniFormattingUtilTest.java deleted file mode 100644 index 1418503..0000000 --- a/EclipseAdapter44/test/krasa/formatter/eclipse/JsniFormattingUtilTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* - * Copyright 2011 Google Inc. All Rights Reserved. - *

- * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package krasa.formatter.eclipse; - -import java.util.Arrays; -import java.util.Map; - -import krasa.formatter.adapter.JsniFormattingUtil; -import krasa.formatter.plugin.Range; - -import org.apache.commons.lang.StringUtils; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.text.edits.TextEdit; -import org.eclipse.wst.jsdt.core.JavaScriptCore; -import org.junit.Assert; -import org.junit.Test; - -/** - * Test cases for the {@link com.google.gwt.eclipse.core.editors.java.JsniFormattingUtil} class. - */ -public class JsniFormattingUtilTest { - private String[] testClass; - - @Test - public void testFormat() throws Exception { - // Use GWT indentation settings - Map javaPrefs = TestUtils.getJavaProperties(); - javaPrefs.put(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, "2"); - javaPrefs.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE); - javaPrefs.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "2"); - javaPrefs.put(DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY, "0"); - - Map javaScriptPrefs = TestUtils.getJSProperties(); - javaScriptPrefs.put( - org.eclipse.wst.jsdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, "2"); - javaScriptPrefs.put(org.eclipse.wst.jsdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, - JavaScriptCore.SPACE); - javaScriptPrefs.put(org.eclipse.wst.jsdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "2"); - javaScriptPrefs.put( - org.eclipse.wst.jsdt.core.formatter.DefaultCodeFormatterConstants.FORMATTER_BLANK_LINES_AT_BEGINNING_OF_METHOD_BODY, - "0"); - - // Get the IDocument for the test class - - IDocument document = new Document(createString(getTestClasses())); - - // Apply the formatting and test the result - Range range = new Range(0, document.get().length(), true); - JsniFormattingUtil jsniFormattingUtil = new JsniFormattingUtil(); - TextEdit formatEdit = jsniFormattingUtil.format(document, javaPrefs, javaScriptPrefs, range); - formatEdit.apply(document); - Assert.assertEquals(getFormattedDocument(), document.get()); - System.err.println("---------------------------"); - System.err.println(getFormattedDocument()); - System.err.println("---------------------------"); - System.err.println(document.get()); - } - - protected String[] getTestClasses() { - testClass = new String[]{"package com.hello.client;", "", "public class FormattingUtilTest {", "", - " private static native void jsniMethod()/*-{", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", "", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", " }", "", - " var text = obj.@com.hello.client.FormattingUtilTest::toString()();", " }-*/;", "", - " private static native void jsniMethodWithNoIndent()/*-{", - "var obj = @com.hello.client.FormattingUtilTest::new()();", "var x = 777;", "", "if (x == 777) {", - " x += 207;", " alert(\"Hello!\");", "}", "}-*/;", "", - " private static native void jsniMethodWithExtraIndent()/*-{", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", "", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", " }", "", - " var text = obj.@com.hello.client.FormattingUtilTest::toString()();", " }-*/;", - "", " private static native void jsniMethodWithStartTokenOnSeparateLine()", " /*-{", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", " ", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", " }", "", - " var text = obj.@com.hello.client.FormattingUtilTest::toString()();", " }-*/;", - "", " private static native void jsniMethodWithOuterBlankLines()/*-{", "", "", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", " ", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", - " }", " ", " var text = obj.@com.hello.client.FormattingUtilTest::toString()();", - " ", " ", " }-*/;", "", - " private static native void emptyJsniMethod()/*-{}-*/;", "", - " private static native void jsniMethodWithSpace() /*-{", " var x = 777;", - " }-*/;", "", - " private static native void jsniMethodWithDeclarationLineThatWraps(Object o,", - " String s, int x)/*-{", " var x = 777;", " }-*/;", - "", "}"}; - return testClass; - } - - public static String createString(String[] lines) { - return StringUtils.join(Arrays.asList(lines), "\n"); - } - - private String getFormattedDocument() { - return createString(new String[]{"package com.hello.client;", "", "public class FormattingUtilTest {", "", - " private static native void jsniMethod()/*-{", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", "", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", " }", "", - " var text = obj.@com.hello.client.FormattingUtilTest::toString()();", " }-*/;", "", - " private static native void jsniMethodWithNoIndent()/*-{", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", "", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", " }", " }-*/;", "", - " private static native void jsniMethodWithExtraIndent()/*-{", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", "", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", " }", "", - " var text = obj.@com.hello.client.FormattingUtilTest::toString()();", " }-*/;", "", - " private static native void jsniMethodWithStartTokenOnSeparateLine()", " /*-{", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", "", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", " }", "", - " var text = obj.@com.hello.client.FormattingUtilTest::toString()();", " }-*/;", "", - " private static native void jsniMethodWithOuterBlankLines()/*-{", "", - " var obj = @com.hello.client.FormattingUtilTest::new()();", " var x = 777;", "", - " if (x == 777) {", " x += 207;", " alert(\"Hello!\");", " }", "", - " var text = obj.@com.hello.client.FormattingUtilTest::toString()();", "", " }-*/;", "", - " private static native void emptyJsniMethod()/*-{}-*/;", "", - " private static native void jsniMethodWithSpace() /*-{", " var x = 777;", " }-*/;", "", - " private static native void jsniMethodWithDeclarationLineThatWraps(Object o,", - " String s, int x)/*-{", " var x = 777;", " }-*/;", "", "}"}); - } - -} diff --git a/EclipseFormatter.iml b/EclipseFormatter.iml index 6380c5f..dcb31cd 100644 --- a/EclipseFormatter.iml +++ b/EclipseFormatter.iml @@ -1,87 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/EclipseFormatter.ipr b/EclipseFormatter.ipr index a72f0ec..8e32c95 100644 --- a/EclipseFormatter.ipr +++ b/EclipseFormatter.ipr @@ -32,19 +32,13 @@ - - - + + - - - - - - + @@ -52,7 +46,7 @@ - + @@ -60,24 +54,42 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -249,6 +331,22 @@ + +

Eclipse Public License - v 2.0

+

THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE (“AGREEMENT”). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. +

+

1. DEFINITIONS

+

“Contribution” means:

+
    +
  • a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and +
  • +
  • + b) in the case of each subsequent Contributor: +
      +
    • i) changes to the Program, and
    • +
    • ii) additions to the Program;
    • +
    + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + “originates” from a Contributor if it was added to the Program by such + Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. +
  • +
+

“Contributor” means any person or entity that Distributes the Program.

+

“Licensed Patents” mean patent claims licensable by a Contributor which + are necessarily infringed by the use or sale of its Contribution alone + or when combined with the Program. +

+

“Program” means the Contributions Distributed in accordance with this + Agreement. +

+

“Recipient” means anyone who receives the Program under this Agreement + or any Secondary License (as applicable), including Contributors. +

+

“Derivative Works” shall mean any work, whether in Source Code or other + form, that is based on (or derived from) the Program and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. +

+

“Modified Works” shall mean any work in Source Code or other form that + results from an addition to, deletion from, or modification of the + contents of the Program, including, for purposes of clarity any new file + in Source Code form that contains any contents of the Program. Modified + Works shall not include works that contain only declarations, interfaces, + types, classes, structures, or files of the Program solely in each case + in order to link to, bind by name, or subclass the Program or Modified + Works thereof. +

+

“Distribute” means the acts of a) distributing or b) making available + in any manner that enables the transfer of a copy. +

+

“Source Code” means the form of a Program preferred for making + modifications, including but not limited to software source code, + documentation source, and configuration files. +

+

“Secondary License” means either the GNU General Public License, + Version 2.0, or any later versions of that license, including any + exceptions or additional permissions as identified by the initial + Contributor. +

+

2. GRANT OF RIGHTS

+
    +
  • a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. +
  • +
  • b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, + at the time the Contribution is added by the Contributor, such + addition of the Contribution causes such combination to be covered + by the Licensed Patents. The patent license shall not apply to any + other combinations which include the Contribution. No hardware per + se is licensed hereunder. +
  • +
  • c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the rights + and licenses granted hereunder, each Recipient hereby assumes sole + responsibility to secure any other intellectual property rights needed, + if any. For example, if a third party patent license is required to + allow Recipient to Distribute the Program, it is Recipient's + responsibility to acquire that license before distributing the Program. +
  • +
  • d) Each Contributor represents that to its knowledge it has sufficient + copyright rights in its Contribution, if any, to grant the copyright + license set forth in this Agreement. +
  • +
  • e) Notwithstanding the terms of any Secondary License, no Contributor + makes additional grants to any Recipient (other than those set forth + in this Agreement) as a result of such Recipient's receipt of the + Program under the terms of a Secondary License (if permitted under + the terms of Section 3). +
  • +
+

3. REQUIREMENTS

+

3.1 If a Contributor Distributes the Program in any form, then:

+
    +
  • a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and +
  • +
  • + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: +
      +
    • i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including warranties + or conditions of title and non-infringement, and implied warranties + or conditions of merchantability and fitness for a particular purpose; +
    • +
    • ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, incidental + and consequential damages, such as lost profits; +
    • +
    • iii) does not attempt to limit or alter the recipients' rights in the + Source Code under section 3.2; and +
    • +
    • iv) requires any subsequent distribution of the Program by any party + to be under a license that satisfies the requirements of this section 3. +
    • +
    +
  • +
+

3.2 When the Program is Distributed as Source Code:

+
    +
  • a) it must be made available under this Agreement, or if the Program (i) + is combined with other material in a separate file or files made available + under a Secondary License, and (ii) the initial Contributor attached to + the Source Code the notice described in Exhibit A of this Agreement, + then the Program may be made available under the terms of such + Secondary Licenses, and +
  • +
  • b) a copy of this Agreement must be included with each copy of the Program.
  • +
+

3.3 Contributors may not remove or alter any copyright, patent, trademark, + attribution notices, disclaimers of warranty, or limitations of liability + (‘notices’) contained within the Program from any copy of the Program which + they Distribute, provided that Contributors may add their own appropriate + notices. +

+

4. COMMERCIAL DISTRIBUTION

+

Commercial distributors of software may accept certain responsibilities + with respect to end users, business partners and the like. While this + license is intended to facilitate the commercial use of the Program, the + Contributor who includes the Program in a commercial product offering should + do so in a manner which does not create potential liability for other + Contributors. Therefore, if a Contributor includes the Program in a + commercial product offering, such Contributor (“Commercial Contributor”) + hereby agrees to defend and indemnify every other Contributor + (“Indemnified Contributor”) against any losses, damages and costs + (collectively “Losses”) arising from claims, lawsuits and other legal actions + brought by a third party against the Indemnified Contributor to the extent + caused by the acts or omissions of such Commercial Contributor in connection + with its distribution of the Program in a commercial product offering. + The obligations in this section do not apply to any claims or Losses relating + to any actual or alleged intellectual property infringement. In order to + qualify, an Indemnified Contributor must: a) promptly notify the + Commercial Contributor in writing of such claim, and b) allow the Commercial + Contributor to control, and cooperate with the Commercial Contributor in, + the defense and any related settlement negotiations. The Indemnified + Contributor may participate in any such claim at its own expense. +

+

For example, a Contributor might include the Program + in a commercial product offering, Product X. That Contributor is then a + Commercial Contributor. If that Commercial Contributor then makes performance + claims, or offers warranties related to Product X, those performance claims + and warranties are such Commercial Contributor's responsibility alone. + Under this section, the Commercial Contributor would have to defend claims + against the other Contributors related to those performance claims and + warranties, and if a court requires any other Contributor to pay any damages + as a result, the Commercial Contributor must pay those damages. +

+

5. NO WARRANTY

+

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED + BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN “AS IS” BASIS, WITHOUT + WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, + WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, + MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is + solely responsible for determining the appropriateness of using and + distributing the Program and assumes all risks associated with its + exercise of rights under this Agreement, including but not limited to the + risks and costs of program errors, compliance with applicable laws, damage + to or loss of data, programs or equipment, and unavailability or + interruption of operations. +

+

6. DISCLAIMER OF LIABILITY

+

EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT PERMITTED + BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY + LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS + GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +

+

7. GENERAL

+

If any provision of this Agreement is invalid or unenforceable under + applicable law, it shall not affect the validity or enforceability of the + remainder of the terms of this Agreement, and without further action by the + parties hereto, such provision shall be reformed to the minimum extent + necessary to make such provision valid and enforceable. +

+

If Recipient institutes patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Program itself + (excluding combinations of the Program with other software or hardware) + infringes such Recipient's patent(s), then such Recipient's rights granted + under Section 2(b) shall terminate as of the date such litigation is filed. +

+

All Recipient's rights under this Agreement shall terminate if it fails to + comply with any of the material terms or conditions of this Agreement and + does not cure such failure in a reasonable period of time after becoming + aware of such noncompliance. If all Recipient's rights under this Agreement + terminate, Recipient agrees to cease use and distribution of the Program + as soon as reasonably practicable. However, Recipient's obligations under + this Agreement and any licenses granted by Recipient relating to the + Program shall continue and survive. +

+

Everyone is permitted to copy and distribute copies of this Agreement, + but in order to avoid inconsistency the Agreement is copyrighted and may + only be modified in the following manner. The Agreement Steward reserves + the right to publish new versions (including revisions) of this Agreement + from time to time. No one other than the Agreement Steward has the right + to modify this Agreement. The Eclipse Foundation is the initial Agreement + Steward. The Eclipse Foundation may assign the responsibility to serve as + the Agreement Steward to a suitable separate entity. Each new version of + the Agreement will be given a distinguishing version number. The Program + (including Contributions) may always be Distributed subject to the version + of the Agreement under which it was received. In addition, after a new + version of the Agreement is published, Contributor may elect to Distribute + the Program (including its Contributions) under the new version. +

+

Except as expressly stated in Sections 2(a) and 2(b) above, Recipient + receives no rights or licenses to the intellectual property of any + Contributor under this Agreement, whether expressly, by implication, + estoppel or otherwise. All rights in the Program not expressly granted + under this Agreement are reserved. Nothing in this Agreement is intended + to be enforceable by any entity that is not a Contributor or Recipient. + No third-party beneficiary rights are created under this Agreement. +

+

Exhibit A – Form of Secondary Licenses Notice

+

“This Source Code may also be made available under the following + Secondary Licenses when the conditions for such availability set forth + in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), + version(s), and exceptions or additional permissions here}.” +

+
+

Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. +

+

If it is not possible or desirable to put the notice in a particular file, + then You may include the notice in a location (such as a LICENSE file in a + relevant directory) where a recipient would be likely to look for + such a notice. +

+

You may add additional accurate notices of copyright ownership.

+
+ + \ No newline at end of file diff --git a/lib/eclipse/README.md b/lib/eclipse/README.md new file mode 100644 index 0000000..75e8633 --- /dev/null +++ b/lib/eclipse/README.md @@ -0,0 +1,7 @@ +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). + +The original version was changed as follows: +* It is repackaged together with all its dependencies into a single jar file ([`eclipse.jar`](eclipse.jar)) +* From all modules, the `META-INF/*.SF`, `META-INF/*.DSA`, `META-INF/*.RSA` and `plugin.xml` are removed + +The "modified" source code can be found in [`eclipse-sources.jar`](eclipse-sources.jar). diff --git a/lib/eclipse/adapter.jar b/lib/eclipse/adapter.jar index e25a973..87dfb7a 100644 Binary files a/lib/eclipse/adapter.jar and b/lib/eclipse/adapter.jar differ diff --git a/lib/eclipse44/eclipse44.jar b/lib/eclipse/eclipse-sources.jar similarity index 54% rename from lib/eclipse44/eclipse44.jar rename to lib/eclipse/eclipse-sources.jar index 1702b00..9cfba3f 100644 Binary files a/lib/eclipse44/eclipse44.jar and b/lib/eclipse/eclipse-sources.jar differ diff --git a/lib/eclipse/eclipse.jar b/lib/eclipse/eclipse.jar index aed1787..6ca7d0d 100644 Binary files a/lib/eclipse/eclipse.jar and b/lib/eclipse/eclipse.jar differ diff --git a/lib/eclipse44/adapter44.jar b/lib/eclipse44/adapter44.jar deleted file mode 100644 index 2d9be85..0000000 Binary files a/lib/eclipse44/adapter44.jar and /dev/null differ diff --git a/lib/test/cglib-nodep-2.2.2-sources.jar b/lib/test/cglib-nodep-2.2.2-sources.jar deleted file mode 100644 index ef9a73a..0000000 Binary files a/lib/test/cglib-nodep-2.2.2-sources.jar and /dev/null differ diff --git a/lib/test/cglib-nodep-2.2.2.jar b/lib/test/cglib-nodep-2.2.2.jar deleted file mode 100644 index 02d81e8..0000000 Binary files a/lib/test/cglib-nodep-2.2.2.jar and /dev/null differ diff --git a/lib/test/easymock-3.1-sources.jar b/lib/test/easymock-3.1-sources.jar deleted file mode 100644 index b10785a..0000000 Binary files a/lib/test/easymock-3.1-sources.jar and /dev/null differ diff --git a/lib/test/easymock-3.1.jar b/lib/test/easymock-3.1.jar deleted file mode 100644 index 4b79dd1..0000000 Binary files a/lib/test/easymock-3.1.jar and /dev/null differ diff --git a/lib/test/objenesis-1.2-sources.jar b/lib/test/objenesis-1.2-sources.jar deleted file mode 100644 index f332840..0000000 Binary files a/lib/test/objenesis-1.2-sources.jar and /dev/null differ diff --git a/lib/test/objenesis-1.2.jar b/lib/test/objenesis-1.2.jar deleted file mode 100644 index fb04d7f..0000000 Binary files a/lib/test/objenesis-1.2.jar and /dev/null differ diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..1215ddd --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,8 @@ +pluginManagement { + repositories { + maven("https://oss.sonatype.org/content/repositories/snapshots/") + gradlePluginPortal() + } +} + +rootProject.name = "EclipseFormatter" diff --git a/src/java/krasa/formatter/eclipse/ConfigurableEclipseLocation.java b/src/java/krasa/formatter/eclipse/ConfigurableEclipseLocation.java deleted file mode 100644 index f3828a4..0000000 --- a/src/java/krasa/formatter/eclipse/ConfigurableEclipseLocation.java +++ /dev/null @@ -1,96 +0,0 @@ -package krasa.formatter.eclipse; - -import krasa.formatter.exception.FormattingFailedException; - -import com.intellij.openapi.diagnostic.Logger; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.filefilter.FileFilterUtils; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.*; - -public class ConfigurableEclipseLocation { - private static final Logger LOG = Logger.getInstance(ConfigurableEclipseLocation.class.getName()); - private static final int TIMEOUT = 5000; - - //@formatter:off - String[] JAR_NAMES = { - "org.eclipse.core.contenttype_", - "org.eclipse.core.jobs_", - "org.eclipse.core.resources_", - "org.eclipse.core.runtime_", - "org.eclipse.equinox.app_",//probably useless - "org.eclipse.equinox.common_", - "org.eclipse.equinox.preferences_", - "org.eclipse.jdt.core_", - "org.eclipse.osgi_", - "org.eclipse.text_" - }; - //@formatter:on - - public Set jarNames; - - public ConfigurableEclipseLocation() { - jarNames = new HashSet(); - jarNames.addAll(Arrays.asList(JAR_NAMES)); - - } - - public static void main(String[] args) throws IOException { - List urlList = new ConfigurableEclipseLocation().run("F:\\workspace\\eclipse-jee 4.5.2"); - for (URL jar : urlList) { - System.out.println(jar); - } - } - - public List run(String from) { - long start = System.currentTimeMillis(); - List jars = null; - try { - jars = findJars(start, new File(from)); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - if (!jarNames.isEmpty()) { - throw new FormattingFailedException("Required jars not found in '" + from + "': " + jarNames.toString(), true); - } - - long total = System.currentTimeMillis() - start; - LOG.info("found " + jars.size() + " jars in " + total + "ms, (" + from + ")"); - return jars; - } - - @NotNull - private List findJars(long start, File from) throws MalformedURLException { - if (System.currentTimeMillis() - start > TIMEOUT) { - throw new FormattingFailedException("Timeout, aborting search for jars.", true); - } - - List files = new ArrayList(); - Iterator iterator = FileUtils.iterateFiles(from, FileFilterUtils.trueFileFilter(), FileFilterUtils.trueFileFilter()); - while (iterator.hasNext()) { - File next = iterator.next(); - if (next.isDirectory()) { - files.addAll(findJars(start, next)); - } else { - String name = next.getName(); - if (name.endsWith(".jar")) { - int i = name.indexOf("_"); - if (i <= 0) - continue; - String jarName = name.substring(0, i + 1); - if (jarNames.contains(jarName)) { - jarNames.remove(jarName); - files.add(next.toURI().toURL()); - } - } - } - } - return files; - } -} diff --git a/src/java/krasa/formatter/eclipse/JavaCodeFormatterFacade.java b/src/java/krasa/formatter/eclipse/JavaCodeFormatterFacade.java deleted file mode 100644 index 92673e6..0000000 --- a/src/java/krasa/formatter/eclipse/JavaCodeFormatterFacade.java +++ /dev/null @@ -1,155 +0,0 @@ -package krasa.formatter.eclipse; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; -import java.net.URL; -import java.util.List; -import java.util.Map; -import java.util.Properties; - -import krasa.formatter.common.ModifiableFile; -import krasa.formatter.exception.FileDoesNotExistsException; -import krasa.formatter.exception.FormattingFailedException; -import krasa.formatter.plugin.Notifier; -import krasa.formatter.settings.Settings; -import krasa.formatter.settings.provider.JavaPropertiesProvider; - -import org.jetbrains.annotations.NotNull; - -import com.intellij.openapi.command.impl.DummyProject; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.pom.java.LanguageLevel; -import com.intellij.psi.PsiFile; -import com.intellij.psi.impl.JavaPsiImplementationHelper; - -/** - * @author Vojtech Krasa - */ -public class JavaCodeFormatterFacade extends CodeFormatterFacade { - - private static final Logger LOG = Logger.getInstance(JavaCodeFormatterFacade.class.getName()); - - private Settings.FormatterVersion version; - private Project project; - private String pathToEclipse; - protected EclipseFormatterAdapter codeFormatter; - private LanguageLevel effectiveLanguageLevel; - private JavaPropertiesProvider javaPropertiesProvider; - protected ModifiableFile.Monitor lastState; - - public JavaCodeFormatterFacade(JavaPropertiesProvider javaPropertiesProvider, Settings.FormatterVersion version, - Project project, String pathToEclipse) { - this.javaPropertiesProvider = javaPropertiesProvider; - this.version = version; - this.project = project; - this.pathToEclipse = pathToEclipse; - } - - @Override - public String format(String text, int startOffset, int endOffset, PsiFile psiFile) - throws FileDoesNotExistsException { - LanguageLevel languageLevel = getLanguageLevel(psiFile); - return getCodeFormatter(languageLevel).format(text, startOffset, endOffset, languageLevel); - } - - private EclipseFormatterAdapter getCodeFormatter(LanguageLevel level) throws FileDoesNotExistsException { - if (codeFormatter == null || javaPropertiesProvider.wasChanged(lastState) - || this.effectiveLanguageLevel != level) { - return newCodeFormatter(level); - } - return codeFormatter; - } - - private EclipseFormatterAdapter newCodeFormatter(LanguageLevel level) { - lastState = javaPropertiesProvider.getModifiedMonitor(); - Properties options = javaPropertiesProvider.get(); - String substring = level.name().replace("_", ".").substring(4); - // test - new Double(substring); - options.setProperty("org.eclipse.jdt.core.compiler.source", substring); - options.setProperty("org.eclipse.jdt.core.compiler.codegen.targetPlatform", substring); - options.setProperty("org.eclipse.jdt.core.compiler.compliance", substring); - this.effectiveLanguageLevel = level; - - try { - Class aClass; - if (version == Settings.FormatterVersion.ECLIPSE_44) { - aClass = getAdapter44(); - } else { - if (version == Settings.FormatterVersion.CUSTOM && SystemInfo.isJavaVersionAtLeast("1.7")) { - aClass = getCustomAdapter(pathToEclipse); - } else if (SystemInfo.isJavaVersionAtLeast("1.8")) { - aClass = getAdapter(); - } else { - aClass = getAdapter44(); - Notifier.notifyOldJRE(project); - } - } - Constructor constructor = aClass.getConstructor(Map.class); - codeFormatter = (EclipseFormatterAdapter) constructor.newInstance(toMap(options)); - } catch (FormattingFailedException e) { - throw e; - } catch (Throwable e) { - // rethrow to have this plugin as a cause of the error report - throw new RuntimeException(e); - } - return codeFormatter; - } - - /** - * TODO CACHE BETWEEN PROJECTS - */ - private Class getCustomAdapter(String pathToEclipse) throws ClassNotFoundException { - ConfigurableEclipseLocation configurableEclipseLocation = new ConfigurableEclipseLocation(); - List urlList = configurableEclipseLocation.run(pathToEclipse.trim()); - if (urlList.isEmpty()) { - throw new FormattingFailedException("Invalid path to Eclipse, no jars found in '" + pathToEclipse + "'", true); - } - ClassLoader classLoader = Classloaders.getCustomClassloader(urlList); - Class aClass = Class.forName("krasa.formatter.adapter.EclipseJavaFormatterAdapter", true, classLoader); - return aClass; - } - - private Class getAdapter44() throws ClassNotFoundException { - ClassLoader classLoader = Classloaders.getEclipse44(); - Class aClass = Class.forName("krasa.formatter.adapter.EclipseJavaFormatterAdapter44", true, classLoader); - return aClass; - } - - private Class getAdapter() throws ClassNotFoundException { - ClassLoader classLoader = Classloaders.getEclipse(); - Class aClass = Class.forName("krasa.formatter.adapter.EclipseJavaFormatterAdapter", true, classLoader); - return aClass; - } - - @NotNull - protected LanguageLevel getLanguageLevel(@NotNull PsiFile psiFile) { - if (DummyProject.getInstance() == project) { - return LanguageLevel.JDK_1_7; // tests hack - } - JavaPsiImplementationHelper instance = JavaPsiImplementationHelper.getInstance(project); - LanguageLevel languageLevel = null; - try { - Method getClassesLanguageLevel = instance.getClass().getMethod("getClassesLanguageLevel", - VirtualFile.class); - languageLevel = (LanguageLevel) getClassesLanguageLevel.invoke(instance, psiFile.getVirtualFile()); - } catch (Exception e) { - try { - Method getClassesLanguageLevel = instance.getClass().getMethod("getEffectiveLanguageLevel", - VirtualFile.class); - languageLevel = (LanguageLevel) getClassesLanguageLevel.invoke(instance, psiFile.getVirtualFile()); - } catch (Exception e1) { - LOG.error("Please report this", e); - LOG.error("Please report this", e1); - } - } - if (languageLevel == null) { - languageLevel = LanguageLevel.JDK_1_7; - } - return languageLevel; - } - -} diff --git a/src/java/krasa/formatter/plugin/Notifier.java b/src/java/krasa/formatter/plugin/Notifier.java deleted file mode 100644 index f7b6cd8..0000000 --- a/src/java/krasa/formatter/plugin/Notifier.java +++ /dev/null @@ -1,106 +0,0 @@ -package krasa.formatter.plugin; - -import com.intellij.notification.Notification; -import com.intellij.notification.NotificationType; -import com.intellij.notification.Notifications; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiFile; - -import krasa.formatter.settings.ProjectComponent; - -/** - * @author Vojtech Krasa - */ -public class Notifier { - - public static final String NO_FILE_TO_FORMAT = "No file to format"; - public static final String ECLIPSE_CURRENT = "Eclipse 4.7 Oxygen"; - - public void notifyFailedFormatting(PsiFile psiFile, boolean formattedByIntelliJ, Exception e) { - String error = e.getMessage() == null ? "" : e.getMessage(); - notifyFailedFormatting(psiFile, formattedByIntelliJ, error); - } - - public void notifyFailedFormatting(PsiFile psiFile, boolean formattedByIntelliJ, final String reason) { - String content; - if (!formattedByIntelliJ) { - content = psiFile.getName() + " failed to format with Eclipse code formatter. " + reason + "\n"; - } else { - content = psiFile.getName() + " failed to format with IntelliJ code formatter.\n" + reason; - } - Notification notification = ProjectComponent.GROUP_DISPLAY_ID_ERROR.createNotification(content, - NotificationType.ERROR); - showNotification(notification, psiFile.getProject()); - } - - void notifyFormattingWasDisabled(PsiFile psiFile) { - Notification notification = ProjectComponent.GROUP_DISPLAY_ID_INFO.createNotification( - psiFile.getName() + " - formatting was disabled for this file type", NotificationType.WARNING); - showNotification(notification, psiFile.getProject()); - } - - void notifySuccessFormatting(PsiFile psiFile, boolean formattedByIntelliJ) { - String content; - if (formattedByIntelliJ) { - content = psiFile.getName() + " formatted successfully by IntelliJ code formatter"; - } else { - content = psiFile.getName() + " formatted successfully by Eclipse code formatter"; - } - Notification notification = ProjectComponent.GROUP_DISPLAY_ID_INFO.createNotification(content, - NotificationType.INFORMATION); - showNotification(notification, psiFile.getProject()); - } - - void showNotification(final Notification notification, final Project project) { - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - Notifications.Bus.notify(notification, project); - } - }); - } - - public void notifyBrokenImportSorter(Project project) { - String content = "Formatting failed due to new Import optimizer."; - Notification notification = ProjectComponent.GROUP_DISPLAY_ID_ERROR.createNotification(content, - NotificationType.ERROR); - showNotification(notification, project); - - } - - public static void notifyDeletedSettings(final Project project) { - String content = "Eclipse formatter settings profile was deleted for project " + project.getName() - + ". Check the configuration."; - final Notification notification = ProjectComponent.GROUP_DISPLAY_ID_ERROR.createNotification(content, - NotificationType.ERROR); - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - Notifications.Bus.notify(notification, project); - } - }); - } - - public static void notifyOldJRE(final Project project) { - String content = ECLIPSE_CURRENT + " formatter requires JRE 1.8+, using formatter from Eclipse 4.4. " - + "You can configure to use 4.4 in the plugin settings to avoid this warning, or use a custom eclipse location for Eclipse 4.5 (JDK 1.7)."; - - final Notification notification = ProjectComponent.GROUP_DISPLAY_ID_ERROR.createNotification(content, - NotificationType.WARNING); - if (ApplicationManager.getApplication() != null) {// tests hack - ApplicationManager.getApplication().invokeLater(new Runnable() { - @Override - public void run() { - Notifications.Bus.notify(notification, project); - } - }); - } - } - - public void configurationError(Exception e, Project project) { - Notification notification = ProjectComponent.GROUP_DISPLAY_ID_ERROR.createNotification( - "Eclipse Formatter configuration error: " + e.getMessage(), NotificationType.ERROR); - showNotification(notification, project); - } -} diff --git a/src/java/krasa/formatter/plugin/ProjectSettingsForm.form b/src/java/krasa/formatter/plugin/ProjectSettingsForm.form deleted file mode 100644 index 9a64be6..0000000 --- a/src/java/krasa/formatter/plugin/ProjectSettingsForm.form +++ /dev/null @@ -1,679 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/java/krasa/formatter/plugin/ProxyUtils.java b/src/java/krasa/formatter/plugin/ProxyUtils.java deleted file mode 100644 index 833c5af..0000000 --- a/src/java/krasa/formatter/plugin/ProxyUtils.java +++ /dev/null @@ -1,26 +0,0 @@ -package krasa.formatter.plugin; - - -import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.codeStyle.FormattingModeAwareIndentAdjuster; -import org.jetbrains.annotations.NotNull; - -public class ProxyUtils { - public static CodeStyleManager createProxy(CodeStyleManager manager, EclipseCodeStyleManager overridingObject) { - return (CodeStyleManager) net.sf.cglib.proxy.Enhancer.create(CodeStyleManager.class, - getInterfaces(), - new ProxyCodeStyleManagerDelegator(manager, overridingObject)); - } - - @NotNull - private static Class[] getInterfaces() { - try { - return new Class[]{FormattingModeAwareIndentAdjuster.class}; - } catch (Throwable e) { - //old API < IJ ~2017 - return new Class[]{}; - } - } - - -} diff --git a/src/java/krasa/formatter/settings/GlobalSettings.java b/src/java/krasa/formatter/settings/GlobalSettings.java deleted file mode 100644 index 604a473..0000000 --- a/src/java/krasa/formatter/settings/GlobalSettings.java +++ /dev/null @@ -1,171 +0,0 @@ -package krasa.formatter.settings; - -import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import org.apache.commons.beanutils.BeanUtils; -import org.jetbrains.annotations.NotNull; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.components.*; -import com.intellij.openapi.project.Project; -import com.intellij.util.xmlb.XmlSerializerUtil; - -import krasa.formatter.plugin.Notifier; -import krasa.formatter.utils.ProjectUtils; -import krasa.formatter.utils.StringUtils; - -/** - * @author Vojtech Krasa - */ -@State(name = "EclipseCodeFormatterSettings", storages = { - @Storage(id = "EclipseCodeFormatterSettings", file = "$APP_CONFIG$/eclipseCodeFormatter.xml") }) -public class GlobalSettings - implements ApplicationComponent, PersistentStateComponent, ExportableApplicationComponent { - private List settingsList = new ArrayList(); - private List deletedSettingsId = new ArrayList(); - - public static GlobalSettings getInstance() { - return ApplicationManager.getApplication().getComponent(GlobalSettings.class); - } - - @Override - public GlobalSettings getState() { - return this; - } - - @Override - public void loadState(GlobalSettings state) { - XmlSerializerUtil.copyBean(state, this); - } - - public List getSettingsList() { - return settingsList; - } - - public void setSettingsList(List settingsList) { - this.settingsList = settingsList; - } - - public Settings newSettings() { - String name = StringUtils.generateName(settingsList, 1, "new"); - Settings aNew = new Settings(generateId(), name); - settingsList.add(aNew); - return aNew; - } - - public Settings copySettings(Project project, Settings settings) { - Settings newSettings = clone(settings); - if (settings.isProjectSpecific()) { - newSettings.setName(StringUtils.generateName(settingsList, 1, project.getName(), project.getName())); - } else { - newSettings.setName(settings.getName() + " copy"); - } - newSettings.setId(generateId()); - settingsList.add(newSettings); - return newSettings; - } - - public static Settings clone(Settings settings) { - Settings newSettings = new Settings(); - try { - BeanUtils.copyProperties(newSettings, settings); - } catch (Exception e) { - throw new RuntimeException(e); - } - return newSettings; - } - - public void updateSettings(Settings settings, Project project) { - if (settings.getId() == null) { - addToGlobalSettings(settings, project); - } else { - for (Settings settings1 : settingsList) { - if (settings1.getId().equals(settings.getId())) { - XmlSerializerUtil.copyBean(settings, settings1); - } - } - } - } - private void addToGlobalSettings(@NotNull Settings newSettings, @NotNull Project project) { - if (newSettings.getId() == null) { - newSettings.setId(generateId()); - } - if (newSettings.getName() == null) { - String name = StringUtils.generateName(settingsList, 1, project.getName(), project.getName()); - newSettings.setName(name); - } - settingsList.add(newSettings); - } - - private Long generateId() { - long newId = new Date().getTime(); - for (Settings settings : settingsList) { - if (settings.getId().equals(newId)) { - newId = generateId(); - } - } - return newId; - } - - @NotNull - public Settings getGlobalProfile(@NotNull Settings state, @NotNull Project project) throws DeletedProfileException { - if (state.isNotSaved()) { - addToGlobalSettings(state, project); - return state; - } else { - for (Settings settings : settingsList) { - if (settings.getId().equals(state.getId())) { - return settings; - } - } - for (Settings settings : settingsList) { - if (settings.getName().equals(state.getName())) { - return settings; - } - } - if (deletedSettingsId.contains(state.getId())) { - Notifier.notifyDeletedSettings(project); - throw new DeletedProfileException(); - } - addToGlobalSettings(state, project); - return state; - } - } - - @Override - public void initComponent() { - } - - @Override - public void disposeComponent() { - } - - @NotNull - @Override - public String getComponentName() { - return "EclipseCodeFormatterGlobalSettings"; - } - - @NotNull - @Override - public File[] getExportFiles() { - return new File[] { PathManager.getOptionsFile("eclipseCodeFormatter") }; - } - - @NotNull - @Override - public String getPresentableName() { - return "Eclipse Code Formatter"; - } - - public void delete(Settings settings, Project project) { - settingsList.remove(settings); - deletedSettingsId.add(settings.getId()); - ProjectUtils.notifyProjectsWhichUsesThisSettings(settings, project); - } - -} diff --git a/src/java/krasa/formatter/settings/ProjectPersistentStateComponent_Old.java b/src/java/krasa/formatter/settings/ProjectPersistentStateComponent_Old.java deleted file mode 100644 index 9e037f7..0000000 --- a/src/java/krasa/formatter/settings/ProjectPersistentStateComponent_Old.java +++ /dev/null @@ -1,35 +0,0 @@ -package krasa.formatter.settings; - -import org.jetbrains.annotations.Nullable; - -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; - -@Deprecated -@State(name = "EclipseCodeFormatter", storages = { @Storage(id = "other", file = "$PROJECT_FILE$") }) -public class ProjectPersistentStateComponent_Old implements PersistentStateComponent { - - protected Settings settings; - - @Override - @Nullable - public Settings getState() { - return settings; - } - - @Override - public void loadState(Settings state) { - settings = state; - } - - public Settings migrateSettings() { - if (settings != null) { - Settings settings = this.settings; - this.settings = new Settings(); - return settings; - } - return null; - } - -} diff --git a/src/java/krasa/formatter/settings/ProjectSettings.java b/src/java/krasa/formatter/settings/ProjectSettings.java deleted file mode 100644 index 1d5df2e..0000000 --- a/src/java/krasa/formatter/settings/ProjectSettings.java +++ /dev/null @@ -1,106 +0,0 @@ -package krasa.formatter.settings; - -import com.intellij.openapi.components.*; -import com.intellij.openapi.project.Project; -import com.intellij.util.xmlb.XmlSerializerUtil; -import com.intellij.util.xmlb.annotations.Transient; -import krasa.formatter.plugin.Notifier; -import org.jetbrains.annotations.NotNull; - -@State(name = "EclipseCodeFormatterProjectSettings", storages = { - @Storage(file = StoragePathMacros.PROJECT_FILE), - @Storage(file = StoragePathMacros.PROJECT_CONFIG_DIR + "/eclipseCodeFormatter.xml", scheme = StorageScheme.DIRECTORY_BASED)}) -public class ProjectSettings implements PersistentStateComponent { - - private ProjectSpecificProfile projectSpecificProfile = new ProjectSpecificProfile(); - private Settings selectedGlobalProfile; - @Transient - private transient Project project; - - public ProjectSettings() { - } - - public ProjectSettings(@NotNull Project project) { - this.project = project; - } - - @NotNull - public ProjectSpecificProfile getProjectSpecificProfile() { - return projectSpecificProfile; - } - - public void setProjectSpecificProfile(ProjectSpecificProfile projectSpecificProfile) { - this.projectSpecificProfile = projectSpecificProfile; - } - - public Settings getSelectedGlobalProfile() { - return selectedGlobalProfile; - } - - public void setSelectedGlobalProfile(Settings selectedGlobalProfile) { - this.selectedGlobalProfile = selectedGlobalProfile; - } - - @Override - @NotNull - public ProjectSettings getState() { - return this; - } - - @Override - public void loadState(ProjectSettings state) { - XmlSerializerUtil.copyBean(state, this); - } - - public static ProjectSettings getInstance(Project project) { - return ServiceManager.getService(project, ProjectSettings.class); - } - - public Settings getSelectedProfile() { - Settings selectedGlobalProfile = getSelectedGlobalProfile(); - if (selectedGlobalProfile != null) { - return selectedGlobalProfile; - } - return getProjectSpecificProfile(); - } - - public void setProfile(Settings profile) { - if (profile.isProjectSpecific()) { - this.setProjectSpecificProfile((ProjectSpecificProfile) profile); - this.setSelectedGlobalProfile(null); - } else { - this.setSelectedGlobalProfile(profile); - } - } - - public void globalProfileUpdated(Settings updatedGlobalProfile) { - final Settings.Formatter formatter = getSelectedProfile().getFormatter(); - setProfile(GlobalSettings.clone(updatedGlobalProfile)); - getSelectedProfile().setFormatter(formatter); - } - - public void projectOpened() { - Settings selectedProfile = ServiceManager.getService(project, - ProjectPersistentStateComponent_Old.class).migrateSettings(); - if (selectedProfile != null) { - this.setSelectedGlobalProfile(selectedProfile); - } - syncGlobalProfile(); - } - - private void syncGlobalProfile() { - Settings selectedGlobalProfile = getSelectedGlobalProfile(); - if (selectedGlobalProfile != null) { - Settings.Formatter formatter = selectedGlobalProfile.getFormatter(); - Settings clone = null; - try { - clone = GlobalSettings.clone( - GlobalSettings.getInstance().getGlobalProfile(selectedGlobalProfile, project)); - clone.setFormatter(formatter); - } catch (DeletedProfileException e) { - Notifier.notifyDeletedSettings(project); - } - setSelectedGlobalProfile(clone); - } - } -} diff --git a/src/java/krasa/formatter/settings/provider/CppPropertiesProvider.java b/src/java/krasa/formatter/settings/provider/CppPropertiesProvider.java deleted file mode 100644 index d2ad84c..0000000 --- a/src/java/krasa/formatter/settings/provider/CppPropertiesProvider.java +++ /dev/null @@ -1,41 +0,0 @@ -package krasa.formatter.settings.provider; - -import krasa.formatter.common.ModifiableFile; -import krasa.formatter.plugin.InvalidPropertyFile; -import krasa.formatter.settings.Settings; - -import java.io.File; -import java.util.*; - -/** - * @author Vojtech Krasa - */ -public class CppPropertiesProvider extends CachedPropertiesProvider { - protected String profile; - - public CppPropertiesProvider(Settings settings) { - super(new ModifiableFile(settings.getPathToConfigFileCpp())); - this.profile = settings.getSelectedCppProfile(); - } - - @Override - protected Properties createDefaultConfig() { - return new Properties(); - } - - @Override - protected void validateConfig(Properties config, File file) { - super.validateConfig(config, file); - } - - @Override - protected Properties readFile(File file) throws InvalidPropertyFile { - if (file.getName().endsWith("xml")) { - return readXmlFile(file, profile); - } else { - // properties file - return super.readFile(file); - } - } - -} diff --git a/src/java/krasa/formatter/settings/provider/JSPropertiesProvider.java b/src/java/krasa/formatter/settings/provider/JSPropertiesProvider.java deleted file mode 100644 index f35db00..0000000 --- a/src/java/krasa/formatter/settings/provider/JSPropertiesProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -package krasa.formatter.settings.provider; - -import java.io.File; -import java.util.Properties; - -import krasa.formatter.common.ModifiableFile; -import krasa.formatter.plugin.InvalidPropertyFile; -import krasa.formatter.settings.Settings; - -/** - * @author Vojtech Krasa - */ -public class JSPropertiesProvider extends CachedPropertiesProvider { - protected String profile; - - public JSPropertiesProvider(Settings settings) { - super(new ModifiableFile(settings.getPathToConfigFileJS())); - this.profile = settings.getSelectedJavaScriptProfile(); - } - - @Override - protected Properties readFile(File file) throws InvalidPropertyFile { - if (file.getName().endsWith("xml")) { - return readXmlFile(file, profile); - } else { - // properties file - return super.readFile(file); - } - } -} diff --git a/src/java/krasa/formatter/settings/provider/JavaPropertiesProvider.java b/src/java/krasa/formatter/settings/provider/JavaPropertiesProvider.java deleted file mode 100644 index 28b9e7a..0000000 --- a/src/java/krasa/formatter/settings/provider/JavaPropertiesProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -package krasa.formatter.settings.provider; - -import krasa.formatter.common.ModifiableFile; -import krasa.formatter.plugin.InvalidPropertyFile; -import krasa.formatter.settings.Settings; - -import java.io.File; -import java.util.Properties; - -/** - * @author Vojtech Krasa - */ -public class JavaPropertiesProvider extends CachedPropertiesProvider { - protected String profile; - - public JavaPropertiesProvider(Settings settings) { - super(new ModifiableFile(settings.getPathToConfigFileJava())); - this.profile = settings.getSelectedJavaProfile(); - } - - @Override - protected Properties readFile(File file) throws InvalidPropertyFile { - if (file.getName().endsWith("xml")) { - return readXmlFile(file, profile); - } else if (file.getName().endsWith("epf")) { - return readConfigFromWorkspaceMechanicFile(file); - } else { - // properties file - return super.readFile(file); - } - } - - private Properties readConfigFromWorkspaceMechanicFile(final File file) { - Properties result = new Properties(); - Properties properties = super.readFile(file); - final String prefix = "/instance/org.eclipse.jdt.core/"; - for (Object object : properties.keySet()) { - String key = (String) object; - if (key.startsWith(prefix)) { - String value = properties.getProperty(key); - result.put(key.substring(prefix.length()), value); - } - } - return result; - } - -} diff --git a/src/java/krasa/formatter/Messages.java b/src/main/java/krasa/formatter/Messages.java similarity index 99% rename from src/java/krasa/formatter/Messages.java rename to src/main/java/krasa/formatter/Messages.java index 1ec55f0..0823d40 100644 --- a/src/java/krasa/formatter/Messages.java +++ b/src/main/java/krasa/formatter/Messages.java @@ -8,16 +8,14 @@ package krasa.formatter; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; -import java.util.ResourceBundle; - +import com.intellij.CommonBundle; import krasa.formatter.settings.IllegalSettingsException; - import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.PropertyKey; -import com.intellij.CommonBundle; +import java.lang.ref.Reference; +import java.lang.ref.SoftReference; +import java.util.ResourceBundle; /** * @author Esko Luontola diff --git a/src/java/krasa/formatter/Resources.java b/src/main/java/krasa/formatter/Resources.java similarity index 86% rename from src/java/krasa/formatter/Resources.java rename to src/main/java/krasa/formatter/Resources.java index 4211ebb..f3a2e09 100644 --- a/src/java/krasa/formatter/Resources.java +++ b/src/main/java/krasa/formatter/Resources.java @@ -1,5 +1,5 @@ /* - * Eclipse Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the + * Adapter for Eclipse Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for diff --git a/src/java/krasa/formatter/action/ChangeFormatterToolbarAction.java b/src/main/java/krasa/formatter/action/ChangeFormatterToolbarAction.java similarity index 69% rename from src/java/krasa/formatter/action/ChangeFormatterToolbarAction.java rename to src/main/java/krasa/formatter/action/ChangeFormatterToolbarAction.java index 15e4e32..9314961 100644 --- a/src/java/krasa/formatter/action/ChangeFormatterToolbarAction.java +++ b/src/main/java/krasa/formatter/action/ChangeFormatterToolbarAction.java @@ -1,25 +1,26 @@ package krasa.formatter.action; -import javax.swing.*; - -import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.ActionUpdateThread; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; - import krasa.formatter.settings.ProjectComponent; import krasa.formatter.settings.Settings; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; /** * @author Vojtech Krasa */ -public class ChangeFormatterToolbarAction extends AnAction { +public class ChangeFormatterToolbarAction extends DumbAwareAction { private static final Logger LOG = Logger.getInstance(ChangeFormatterToolbarAction.class.getName()); - public static final Icon ICON = IconLoader.getIcon("/krasa/formatter/eclipse.gif"); - public static final Icon ICON1 = IconLoader.getIcon("/krasa/formatter/IDEA.gif"); + public static final Icon ECLIPSE = IconLoader.getIcon("/krasa/formatter/eclipse.png", ChangeFormatterToolbarAction.class); + public static final Icon IDEA = IconLoader.getIcon("/krasa/formatter/IDEA.png", ChangeFormatterToolbarAction.class); @Override public void actionPerformed(AnActionEvent e) { @@ -51,9 +52,11 @@ public void update(AnActionEvent e) { private void updateIcon(Settings state, Presentation presentation) { if (state.getFormatter() == Settings.Formatter.DEFAULT) { - presentation.setIcon(ICON1); + presentation.setIcon(IDEA); + presentation.setDescription("Click to use Eclipse formatter"); } else { - presentation.setIcon(ICON); + presentation.setIcon(ECLIPSE); + presentation.setDescription("Click to use IntelliJ formatter"); } } @@ -67,4 +70,8 @@ private Settings getSettings(AnActionEvent e) { return settings; } + @Override + public @NotNull ActionUpdateThread getActionUpdateThread() { + return ActionUpdateThread.BGT; + } } diff --git a/src/java/krasa/formatter/action/QuickChangeCodeFormatterAction.java b/src/main/java/krasa/formatter/action/QuickChangeCodeFormatterAction.java similarity index 86% rename from src/java/krasa/formatter/action/QuickChangeCodeFormatterAction.java rename to src/main/java/krasa/formatter/action/QuickChangeCodeFormatterAction.java index 52d44dc..cf7d20b 100644 --- a/src/java/krasa/formatter/action/QuickChangeCodeFormatterAction.java +++ b/src/main/java/krasa/formatter/action/QuickChangeCodeFormatterAction.java @@ -1,19 +1,24 @@ package krasa.formatter.action; +import com.intellij.icons.AllIcons; import com.intellij.ide.actions.QuickSwitchSchemeAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; - import krasa.formatter.settings.ProjectComponent; import krasa.formatter.settings.Settings; +import javax.swing.*; + /** * @author Vojtech Krasa */ -public class QuickChangeCodeFormatterAction extends QuickSwitchSchemeAction { +public class QuickChangeCodeFormatterAction extends QuickSwitchSchemeAction implements DumbAware { + + protected static final Icon ourCurrentAction = AllIcons.Actions.Forward; @Override protected void fillActions(final Project project, DefaultActionGroup group, DataContext dataContext) { diff --git a/src/java/krasa/formatter/common/ModifiableFile.java b/src/main/java/krasa/formatter/common/ModifiableFile.java similarity index 77% rename from src/java/krasa/formatter/common/ModifiableFile.java rename to src/main/java/krasa/formatter/common/ModifiableFile.java index 3403240..a5164db 100644 --- a/src/java/krasa/formatter/common/ModifiableFile.java +++ b/src/main/java/krasa/formatter/common/ModifiableFile.java @@ -1,8 +1,10 @@ package krasa.formatter.common; -import java.io.File; - +import com.intellij.util.PathUtil; import krasa.formatter.exception.FileDoesNotExistsException; +import org.jetbrains.annotations.NotNull; + +import java.io.File; /** * @author Vojtech Krasa @@ -15,7 +17,7 @@ public ModifiableFile(String pathToConfigFileJava) { public boolean wasChanged(Monitor lastState) { checkIfExists(); - return this.lastModified() > lastState.getLastStateTime(); + return this.lastModified() != lastState.getLastStateTime(); } public void checkIfExists() throws FileDoesNotExistsException { @@ -28,6 +30,11 @@ public Monitor getModifiedMonitor() { return new Monitor(this); } + @NotNull + public String getSystemIndependentPath() { + return PathUtil.toSystemIndependentName(getAbsolutePath()); + } + /** * @author Vojtech Krasa */ diff --git a/src/java/krasa/formatter/eclipse/Classloaders.java b/src/main/java/krasa/formatter/eclipse/Classloaders.java similarity index 52% rename from src/java/krasa/formatter/eclipse/Classloaders.java rename to src/main/java/krasa/formatter/eclipse/Classloaders.java index 70f6f79..a06f3a7 100644 --- a/src/java/krasa/formatter/eclipse/Classloaders.java +++ b/src/main/java/krasa/formatter/eclipse/Classloaders.java @@ -1,38 +1,21 @@ package krasa.formatter.eclipse; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.diagnostic.Logger; +import org.jetbrains.annotations.NotNull; + import java.io.File; -import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import java.util.List; -import krasa.formatter.processor.Processor; -import krasa.formatter.settings.Settings; -import krasa.formatter.settings.provider.CppPropertiesProvider; -import krasa.formatter.settings.provider.JSPropertiesProvider; - -import org.jetbrains.annotations.NotNull; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.diagnostic.Logger; - public class Classloaders { private static final Logger LOG = Logger.getInstance(Classloaders.class.getName()); - private static ClassLoader eclipse44; private static ClassLoader newEclipse; - public static ClassLoader getEclipse44() { - if (eclipse44 == null) { - eclipse44 = classLoader(getPluginLibHomeEclipse44(), - "adapter44.jar", - "eclipse44.jar" - ); - } - return eclipse44; - } public static ClassLoader getEclipse() { if (newEclipse == null) { @@ -52,15 +35,11 @@ public static ClassLoader getCustomClassloader(List jars) { URL[] a = jars.toArray(new URL[jars.size()]); LOG.info("Creating classloader for " + Arrays.toString(a)); return new ParentLastURLClassLoader(Classloaders.class.getClassLoader(), a); - } catch (Exception e) { + } catch (Throwable e) { throw new RuntimeException(e); } } - @NotNull - private static File getPluginLibHomeEclipse44() { - return getPluginHome("eclipse44"); - } @NotNull private static File getPluginLibHomeEclipse() { @@ -109,64 +88,13 @@ private static ClassLoader classLoader(File parent, String... jarFiles) { // return UrlClassLoader.classLoader().urls(jarFile).useCache().get(); LOG.info("Creating classloader for " + Arrays.toString(urls)); return new ParentLastURLClassLoader(Classloaders.class.getClassLoader(), urls); - } catch (Exception e) { + } catch (Throwable e) { throw new RuntimeException(e); } } - @NotNull - public static CodeFormatterFacade getCppFormatter(CppPropertiesProvider cppProperties) { - Object o = null; - try { - ClassLoader classLoader = getEclipse(); - Class aClass = Class.forName("krasa.formatter.adapter.CppCodeFormatterFacade", true, classLoader); - Constructor constructor = aClass.getConstructor(CppPropertiesProvider.class); - o = constructor.newInstance(cppProperties); - } catch (Exception e) { - throw new RuntimeException(e); - } - return (CodeFormatterFacade) o; - } - @NotNull - public static CodeFormatterFacade getJsFormatter(JSPropertiesProvider propertiesProvider) { - Object o = null; - try { - ClassLoader classLoader = getEclipse44(); - Class aClass = Class.forName("krasa.formatter.adapter.JSCodeFormatterFacade", true, classLoader); - Constructor constructor = aClass.getConstructor(JSPropertiesProvider.class); - o = constructor.newInstance(propertiesProvider); - } catch (Exception e) { - throw new RuntimeException(e); - } - return (CodeFormatterFacade) o; - } - public static Processor getGWTProcessor(Settings settings) { - Object o = null; - try { - ClassLoader classLoader = getEclipse44(); - Class aClass = Class.forName("krasa.formatter.adapter.processor.GWTProcessor", true, classLoader); - Constructor constructor = aClass.getConstructor(Settings.class); - o = constructor.newInstance(settings); - } catch (Exception e) { - throw new RuntimeException(e); - } - return (Processor) o; - } - public static Processor getJSCommentsFormatterProcessor(Settings settings) { - Object o = null; - try { - ClassLoader classLoader = getEclipse44(); - Class aClass = Class.forName("krasa.formatter.adapter.processor.JSCommentsFormatterProcessor", true, - classLoader); - Constructor constructor = aClass.getConstructor(Settings.class); - o = constructor.newInstance(settings); - } catch (Exception e) { - throw new RuntimeException(e); - } - return (Processor) o; - } } diff --git a/src/java/krasa/formatter/eclipse/CodeFormatterFacade.java b/src/main/java/krasa/formatter/eclipse/CodeFormatterFacade.java similarity index 99% rename from src/java/krasa/formatter/eclipse/CodeFormatterFacade.java rename to src/main/java/krasa/formatter/eclipse/CodeFormatterFacade.java index 2c30ee7..0d5cf7d 100644 --- a/src/java/krasa/formatter/eclipse/CodeFormatterFacade.java +++ b/src/main/java/krasa/formatter/eclipse/CodeFormatterFacade.java @@ -1,14 +1,12 @@ package krasa.formatter.eclipse; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - +import com.intellij.psi.PsiFile; import krasa.formatter.exception.FileDoesNotExistsException; - import org.jetbrains.annotations.NotNull; -import com.intellij.psi.PsiFile; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; /** * @author Vojtech Krasa diff --git a/src/main/java/krasa/formatter/eclipse/ConfigFileLocator.java b/src/main/java/krasa/formatter/eclipse/ConfigFileLocator.java new file mode 100644 index 0000000..4e8eef7 --- /dev/null +++ b/src/main/java/krasa/formatter/eclipse/ConfigFileLocator.java @@ -0,0 +1,333 @@ +package krasa.formatter.eclipse; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.ui.SortedComboBoxModel; +import krasa.formatter.exception.FileDoesNotExistsException; +import krasa.formatter.exception.ParsingFailedException; +import krasa.formatter.plugin.ProjectSettingsForm; +import krasa.formatter.utils.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; + +@SuppressWarnings("rawtypes") +public class ConfigFileLocator { + private static final Logger LOG = Logger.getInstance(ConfigFileLocator.class.getName()); + + private static IModuleResolverStrategy moduleResolver = new DefaultModuleResolverStrategy(); + private static VirtualFile mostRecentFormatterFile = null; + + public static final String ECLIPSE_CODE_FORMATTER_XML = "eclipse-code-formatter.xml"; + private final List CONVENTIONFILENAMES = Arrays.asList(// + ".settings/org.eclipse.jdt.core.prefs", // + ".settings/mechanic-formatter.epf", // + "mechanic-formatter.epf", // + ECLIPSE_CODE_FORMATTER_XML // + ); + + public String resolveConfigFilePath(String path) { + File file = new File(path); + + if (!file.exists()) { + throw new FileDoesNotExistsException(file); + } + + if (file.isDirectory()) { + File resolve = resolveFolder(file); + if (resolve != null) + return resolve.getAbsolutePath(); + + throw new FileDoesNotExistsException("Invalid config location: " + path); + } + + return path; + } + + public void validate(ProjectSettingsForm projectSettingsForm, SortedComboBoxModel profilesModel, String path) { + if (StringUtils.isBlank(path)) { + return; + } + File file = new File(path); + JComboBox comboBox = projectSettingsForm.javaFormatterProfile; + comboBox.setEnabled(true); + comboBox.setBorder(projectSettingsForm.normalBorder); + + try { + if (!file.exists()) { + invalid("invalid location", profilesModel, comboBox); + return; + } + if (file.isDirectory()) { + file = resolveFolder(file); + if (file == null) { + invalid("invalid location", profilesModel, comboBox); + return; + } + } + String lowerCaseName = file.getName().toLowerCase().trim(); + + if (lowerCaseName.equals("org.eclipse.jdt.ui.prefs")) { + processWorkspaceConfig(profilesModel, comboBox, file); + } else if (lowerCaseName.endsWith(".prefs")) { + processPrefs(projectSettingsForm, profilesModel, comboBox, file); + } else if (lowerCaseName.endsWith(".epf")) { + processEPF(projectSettingsForm, profilesModel, file, comboBox); + } else if (lowerCaseName.endsWith(".xml")) { + processXml(profilesModel, file, comboBox); + } else { + // lets assume it is properties + processPrefs(projectSettingsForm, profilesModel, comboBox, file); + } + } catch (IOException e) { + invalid("Plugin error:" + e.toString(), profilesModel, comboBox); + throw new RuntimeException(e); + } catch (FileDoesNotExistsException e) { + invalid("invalid location", profilesModel, comboBox); + } + + } + + @Nullable + private File resolveFolder(File folder) { + File mechanicFormatterEpf = org.apache.commons.io.FileUtils.getFile(folder, ".settings", + "mechanic-formatter.epf"); + if (mechanicFormatterEpf.exists()) { + return mechanicFormatterEpf; + } + + File corePrefs = org.apache.commons.io.FileUtils.getFile(folder, ".settings", "org.eclipse.jdt.core.prefs"); + if (corePrefs.exists()) { + return corePrefs; + } + + File uiPrefs = org.apache.commons.io.FileUtils.getFile(folder, ".metadata", ".plugins", + "org.eclipse.core.runtime", ".settings", "org.eclipse.jdt.ui.prefs"); + if (uiPrefs.exists()) { + return uiPrefs; + } + return null; + } + + private void processWorkspaceConfig(SortedComboBoxModel profilesModel, JComboBox comboBox, File uiPrefs) + throws IOException { + Properties properties = FileUtils.readPropertiesFile(uiPrefs); + String xml = properties.getProperty("org.eclipse.jdt.ui.formatterprofiles"); + InputStream s = IOUtils.toInputStream(xml, "UTF-8"); + List profileNamesFromConfigXML = FileUtils.getProfileNamesFromConfigXML(s); + + if (profileNamesFromConfigXML.isEmpty()) { + invalid("Workspace does not contain custom formatter profiles!", profilesModel, comboBox); + } else { + profilesModel.addAll(profileNamesFromConfigXML); + + String formatter_profile1 = properties.getProperty("formatter_profile"); + String substring = formatter_profile1.substring(1); + if (new HashSet<>(profileNamesFromConfigXML).contains(substring)) { + profilesModel.setSelectedItem(substring); + } + } + } + + private void processEPF(ProjectSettingsForm projectSettingsForm, SortedComboBoxModel profilesModel, File file, + JComboBox comboBox) { + if (isValidEPF(file)) { + valid("valid EPF config", projectSettingsForm, profilesModel, comboBox); + } else { + invalid("Invalid EPF config, should contain 100+ 'org.eclipse.jdt.core.formatter' properties", profilesModel, + comboBox); + } + } + + private boolean isValidEPF(File file) { + Properties properties = FileUtils.readPropertiesFile(file); + Properties result = FileUtils.convertEPF(properties, new Properties()); + return result.size() > 100; + } + + private void processXml(SortedComboBoxModel profilesModel, File file, JComboBox comboBox) { + try { + profilesModel.addAll(FileUtils.getProfileNamesFromConfigXML(file)); + if (profilesModel.getSize() == 0) { + invalid(ProjectSettingsForm.CONTAINS_NO_PROFILES, profilesModel, comboBox); + } + } catch (ParsingFailedException e) { + invalid(ProjectSettingsForm.PARSING_FAILED, profilesModel, comboBox); + } + } + + private void processPrefs(@NotNull ProjectSettingsForm projectSettingsForm, + @NotNull SortedComboBoxModel profilesModel, @NotNull JComboBox comboBox, @NotNull File file) { + if (isValidCorePrefs(file)) { + valid("valid '" + file.getName() + "' config", projectSettingsForm, profilesModel, comboBox); + } else { + invalid("Enable 'Project Specific Settings' in Eclipse!", profilesModel, comboBox); + } + } + + private boolean isValidCorePrefs(@NotNull File file) { + Properties properties = FileUtils.readPropertiesFile(file); + return properties.size() > 100; + } + + private void valid(String valid_config, ProjectSettingsForm projectSettingsForm, SortedComboBoxModel profilesModel, + JComboBox comboBox) { + profilesModel.add(valid_config); + comboBox.setEnabled(false); + comboBox.setBorder(projectSettingsForm.normalBorder); + } + + private void invalid(String text, SortedComboBoxModel profilesModel, JComboBox comboBox) { + profilesModel.add(text); + comboBox.setEnabled(false); + comboBox.setBorder(ProjectSettingsForm.ERROR_BORDER); + } + + @Nullable + VirtualFile traverseToFindConfigurationFileByConvention(PsiFile psiFile, Project project) { + int i = 0; + VirtualFile moduleFileDir = getModuleDirForFile(psiFile.getVirtualFile(), project); + + while (moduleFileDir != null) { + if (++i > 1000) { + throw new IllegalStateException("loop bug: " + moduleFileDir.getPath()); + } + if (LOG.isDebugEnabled()) { + LOG.debug("moduleFileDir=" + moduleFileDir.getPath()); + } + + VirtualFile configFile = findConfigFile(moduleFileDir); + if (configFile != null) { + return configFile; + } + + moduleFileDir = getNextParentModuleDirectory(moduleFileDir, project); + } + + // fallback to the project root for gradle projects + VirtualFile projectDir = ProjectUtil.guessProjectDir(project); + VirtualFile configFile = findConfigFile(projectDir); + return configFile; + } + + @Nullable + private VirtualFile findConfigFile(VirtualFile dir) { + if (dir == null) { + return null; + } + for (String conventionFileName : CONVENTIONFILENAMES) { + VirtualFile configFile = dir.findFileByRelativePath(conventionFileName); + if (configFile != null && configFile.exists()) { + if (!isValid(configFile)) { + LOG.info("Found a config file, but is invalid, skipping. " + configFile); + continue; + } + mostRecentFormatterFile = configFile; + return configFile; + } + } + return null; + } + + private boolean isValid(VirtualFile virtualFile) { + try { + if ("org.eclipse.jdt.core.prefs".equals(virtualFile.getName())) { + return isValidCorePrefs(new File(virtualFile.getPath())); + } + if (virtualFile.getName().endsWith(".epf")) { + return isValidEPF(new File(virtualFile.getPath())); + } + if (ECLIPSE_CODE_FORMATTER_XML.equals(virtualFile.getName())) { + List profileNamesFromConfigXML = FileUtils.getProfileNamesFromConfigXML(new File(virtualFile.getPath())); + return profileNamesFromConfigXML.size() == 1; + } + return true; + } catch (Throwable e) { + LOG.error(e); + return false; + } + } + + private VirtualFile getModuleDirForFile(VirtualFile virtualFile, Project project) { + // delegate to a strategy which can be overriden in unit tests + return moduleResolver.getModuleDirForFile(virtualFile, project); + } + + private VirtualFile getNextParentModuleDirectory(VirtualFile currentModuleDir, Project project) { + int i = 0; + // Jump outside the current project + VirtualFile parent = currentModuleDir.getParent(); + while (parent != null && parent.exists()) { + if (++i > 1000) { + throw new IllegalStateException("loop bug: " + parent.getPath()); + } + // the file/dir outside the project may be within another loaded module + // NOTE all modules must be loaded for detecting the parent module of the current one + VirtualFile dirOfParentModule = getModuleDirForFile(parent, project); + if (dirOfParentModule == null) { + return null; + } + // module file can be is some subfolder, so find a parent which is actually from a different module + if (dirOfParentModule.equals(currentModuleDir)) { + parent = parent.getParent(); + continue; + } + return dirOfParentModule; + } + return null; + } + + public interface IModuleResolverStrategy { + VirtualFile getModuleDirForFile(VirtualFile virtualFile, Project project); + } + + static class DefaultModuleResolverStrategy implements IModuleResolverStrategy { + @Override + public VirtualFile getModuleDirForFile(VirtualFile virtualFile, Project project) { + Module moduleForFile = ModuleUtil.findModuleForFile(virtualFile, project); + if (moduleForFile != null) { + return ProjectUtil.guessModuleDir(moduleForFile); + } + return null; + } + } + + /** + * VisibleForTesting + */ + @Deprecated + public static void TESTING_setModuleResolver(IModuleResolverStrategy otherModuleResolver) { + moduleResolver = otherModuleResolver; + } + + /** + * VisibleForTesting + */ + @Deprecated + public static IModuleResolverStrategy TESTING_getModuleResolver() { + return moduleResolver; + } + + /** + * VisibleForTesting + */ + @Deprecated + public static VirtualFile TESTING_getMostRecentFormatterFile() { + return mostRecentFormatterFile; + } +} diff --git a/src/main/java/krasa/formatter/eclipse/ConfigurableEclipseLocation.java b/src/main/java/krasa/formatter/eclipse/ConfigurableEclipseLocation.java new file mode 100644 index 0000000..637fde5 --- /dev/null +++ b/src/main/java/krasa/formatter/eclipse/ConfigurableEclipseLocation.java @@ -0,0 +1,129 @@ +package krasa.formatter.eclipse; + +import com.intellij.openapi.diagnostic.Logger; +import krasa.formatter.exception.FormattingFailedException; +import krasa.formatter.exception.InvalidSettingsException; +import org.apache.commons.io.FileUtils; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.*; + +public class ConfigurableEclipseLocation { + private static final Logger LOG = Logger.getInstance(ConfigurableEclipseLocation.class.getName()); +// private static final Logger LOG = new PrintingLogger(System.out); + + private static final int TIMEOUT = 500; + + //@formatter:off + String[] JAR_NAMES = { + "org.eclipse.core.contenttype", + "org.eclipse.core.jobs", + "org.eclipse.core.resources", + "org.eclipse.core.runtime", + "org.eclipse.equinox.app",//probably useless + "org.eclipse.equinox.common", + "org.eclipse.equinox.preferences", + "org.eclipse.jdt.core", + "org.eclipse.jdt.core.compiler.batch", + "org.eclipse.osgi", + "org.eclipse.text" + }; + String[] OPTIONAL_JAR_NAMES = { + "org.eclipse.jdt.core.compiler.batch" + }; + //@formatter:on + + public Set jarNames; + + public ConfigurableEclipseLocation() { + jarNames = new HashSet(); + jarNames.addAll(Arrays.asList(JAR_NAMES)); + + } + + + public List run(String from) { + long start = System.currentTimeMillis(); + List jars = null; + try { + File root = new File(from); + root = findEclipseRoot(root, start); + + if (root == null || !root.exists()) { + throw new InvalidSettingsException("Invalid Eclipse location, it must contain '.eclipseproduct' file"); + } + + LOG.debug("found root=" + root.getAbsolutePath() + " in " + (System.currentTimeMillis() - start) + "ms"); + + jars = findJars(root); + + } catch (InvalidSettingsException e) { + throw e; + } catch (Throwable e) { + throw new RuntimeException("from=" + from, e); + } + + List.of(OPTIONAL_JAR_NAMES).forEach(jarNames::remove); + + if (!jarNames.isEmpty()) { + throw new FormattingFailedException("Required jars not found in '" + from + "': " + jarNames.toString(), true); + } + + long total = System.currentTimeMillis() - start; + LOG.debug("found " + jars.size() + " jars in " + total + "ms, (" + from + ")"); + return jars; + } + + private File findEclipseRoot(File root, long start) { + if (System.currentTimeMillis() - start > TIMEOUT) { + throw new FormattingFailedException("Timeout, Eclipse installation containing '.eclipseproduct' not found.", true); + } + File stick = FileUtils.getFile(root, ".eclipseproduct"); + if (!stick.exists()) { + File[] files = root.listFiles(); + if (files != null) { + for (File childDir : files) { + if (childDir.isDirectory()) { + stick = findEclipseRoot(childDir, start); + if (stick != null) { + return stick; + } + } + } + } + return null; + } else { + return root; + } + } + + @NotNull + private List findJars(File root) throws IOException { + long start = System.currentTimeMillis(); + String rootURI = root.toURI().toString(); + File bundlesInfo = FileUtils.getFile(root, "configuration", "org.eclipse.equinox.simpleconfigurator", "bundles.info"); + List files = new ArrayList<>(); + List strings = FileUtils.readLines(bundlesInfo, "UTF-8"); + for (String string : strings) { + String[] split = string.split(","); + if (split.length >= 3) { + String name = split[0]; + String path = split[2]; + if (jarNames.contains(name)) { + jarNames.remove(name); + if (!path.startsWith("file:")) { + files.add(new URL(rootURI + path)); + } else { + files.add(new URL(path)); + } + } + } + } + LOG.debug("#findJarsFromRepository took " + (System.currentTimeMillis() - start) + "ms"); + return files; + } + +} diff --git a/src/java/krasa/formatter/eclipse/EclipseFormatterAdapter.java b/src/main/java/krasa/formatter/eclipse/EclipseFormatterAdapter.java similarity index 62% rename from src/java/krasa/formatter/eclipse/EclipseFormatterAdapter.java rename to src/main/java/krasa/formatter/eclipse/EclipseFormatterAdapter.java index 87df15a..986a355 100644 --- a/src/java/krasa/formatter/eclipse/EclipseFormatterAdapter.java +++ b/src/main/java/krasa/formatter/eclipse/EclipseFormatterAdapter.java @@ -1,16 +1,15 @@ package krasa.formatter.eclipse; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.pom.java.LanguageLevel; import krasa.formatter.exception.FileDoesNotExistsException; public abstract class EclipseFormatterAdapter { protected final Logger LOG = Logger.getInstance(this.getClass().getName()); - public abstract String format(String text, int startOffset, int endOffset, LanguageLevel level) + public abstract String format(int kind, String text, int startOffset, int length, int indentationLevel, String lineSeparator, String languageLevel) throws FileDoesNotExistsException; - protected String getErrorMessage(LanguageLevel effectiveLanguageLevel) { + protected String getErrorMessage(String effectiveLanguageLevel) { return "languageLevel=" + effectiveLanguageLevel; } } diff --git a/src/main/java/krasa/formatter/eclipse/JavaCodeFormatterFacade.java b/src/main/java/krasa/formatter/eclipse/JavaCodeFormatterFacade.java new file mode 100644 index 0000000..bf7aa4d --- /dev/null +++ b/src/main/java/krasa/formatter/eclipse/JavaCodeFormatterFacade.java @@ -0,0 +1,212 @@ +package krasa.formatter.eclipse; + +import com.intellij.openapi.command.impl.DummyProject; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.JavaPsiImplementationHelper; +import krasa.formatter.exception.FileDoesNotExistsException; +import krasa.formatter.exception.FormattingFailedException; +import krasa.formatter.exception.InvalidSettingsException; +import krasa.formatter.plugin.InvalidPropertyFile; +import krasa.formatter.settings.GlobalSettings; +import krasa.formatter.settings.Settings; +import krasa.formatter.settings.provider.JavaPropertiesProvider; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jdt.core.formatter.CodeFormatter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * @author Vojtech Krasa + */ +public class JavaCodeFormatterFacade extends CodeFormatterFacade { + + private static final Logger LOG = Logger.getInstance(JavaCodeFormatterFacade.class.getName()); + + private final Settings settings; + private Project project; + + protected EclipseFormatterAdapter codeFormatter; + + private LanguageLevel effectiveLanguageLevel; + + private ConfigFileLocator configFileLocator = new ConfigFileLocator(); + @Nullable + private JavaPropertiesProvider javaPropertiesProvider; + + public JavaCodeFormatterFacade(Settings settings, Project project) { + this.settings = settings; + this.project = project; + } + + @Override + public String format(String text, int startOffset, int endOffset, PsiFile psiFile) + throws FileDoesNotExistsException { + LanguageLevel languageLevel = getLanguageLevel(psiFile); + EclipseFormatterAdapter adapter = getCodeFormatter(languageLevel, psiFile); + int kind = CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS; + String lineSeparator = "\n"; + + if (endOffset > text.length()) { + endOffset = text.length(); + } + LOG.debug("EclipseFormatterAdapter#format"); + String format = adapter.format(kind, text, startOffset, endOffset - startOffset, 0, lineSeparator, languageLevel.toString()); + LOG.debug("EclipseFormatterAdapter#format done"); + return format; + } + + + private EclipseFormatterAdapter getCodeFormatter(LanguageLevel level, PsiFile psiFile) throws FileDoesNotExistsException { + if (settings.getConfigType() == Settings.ConfigType.RESOLVE) { + + long start = System.currentTimeMillis(); + VirtualFile configFile = configFileLocator.traverseToFindConfigurationFileByConvention(psiFile, project); + LOG.debug("config located in " + (System.currentTimeMillis() - start) + "ms (" + configFile + ")"); + + if (configFile == null) { + throw new FormattingFailedException("Formatter config file not resolved.", true); + } + if (codeFormatter == null || javaPropertiesProvider == null || !javaPropertiesProvider.isSameFile(configFile) || javaPropertiesProvider.wasChanged()) { + javaPropertiesProvider = new JavaPropertiesProvider(configFile.getCanonicalPath(), ""); + return newCodeFormatter(level, configFile); + } + return codeFormatter; + } + + if (codeFormatter == null || configFileRefresh() || this.effectiveLanguageLevel != level) { + return newCodeFormatter(level, null); + } + + return codeFormatter; + } + + private boolean configFileRefresh() { + return settings.getConfigType() == Settings.ConfigType.CUSTOM && (javaPropertiesProvider == null || javaPropertiesProvider.wasChanged()); + } + + private EclipseFormatterAdapter newCodeFormatter(LanguageLevel level, VirtualFile configFile) { + long start = System.currentTimeMillis(); + + try { + ClassLoader classLoader; + if (settings.getEclipseVersion() == Settings.FormatterVersion.CUSTOM) { + classLoader = getCustomClassloader(GlobalSettings.getInstance().getPathToEclipse()); + } else { + classLoader = Classloaders.getEclipse(); + } + + Map options = getEclipseProfileOptions(level, configFile, classLoader); + + Class aClass1 = Class.forName("krasa.formatter.adapter.EclipseJavaFormatterAdapter", true, classLoader); + Constructor constructor = aClass1.getConstructor(Map.class); + codeFormatter = (EclipseFormatterAdapter) constructor.newInstance(options); + } catch (FormattingFailedException e) { + throw e; + } catch (InvalidPropertyFile e) { + throw e; + } catch (FileDoesNotExistsException e) { + throw e; + } catch (Throwable e) { + // rethrow to have this plugin as a cause of the error report + throw new RuntimeException(e); + } + LOG.info("newCodeFormatter in " + (System.currentTimeMillis() - start) + "ms, (" + configFile + ")"); + return codeFormatter; + } + + @NotNull + private Map getEclipseProfileOptions(LanguageLevel level, VirtualFile configFile, ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Map options = getEclipseProfileOptions(configFile, classLoader); + + if (options.size() < 100) { + throw new FormattingFailedException("Invalid config file, it should contain 100+ properties.", true); + } + String languageLevel = toEclipseLanguageLevel(level); + options.put("org.eclipse.jdt.core.compiler.source", languageLevel); + options.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", languageLevel); + options.put("org.eclipse.jdt.core.compiler.compliance", languageLevel); + this.effectiveLanguageLevel = level; + return options; + } + + private Map getEclipseProfileOptions(VirtualFile configFile, ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Class aClass1 = Class.forName("org.eclipse.jdt.internal.formatter.DefaultCodeFormatterOptions", true, classLoader); + Method getMap = aClass1.getMethod("getMap"); + Properties options; + + switch (settings.getConfigType()) { + + case RESOLVE: + javaPropertiesProvider = new JavaPropertiesProvider(configFile.getPath(), null); + options = javaPropertiesProvider.get(); + return toMap(options); + case ECLIPSE: + return (Map) getMap.invoke(aClass1.getDeclaredMethod("getEclipseDefaultSettings").invoke(null)); + case ECLIPSE_2_1: + return (Map) getMap.invoke(aClass1.getDeclaredMethod("getDefaultSettings").invoke(null)); + case JAVA_CONVENTIONS: + return (Map) getMap.invoke(aClass1.getDeclaredMethod("getJavaConventionsSettings").invoke(null)); + case CUSTOM: + javaPropertiesProvider = settings.getJavaProperties(); + options = javaPropertiesProvider.get(); + return toMap(options); + } + throw new IllegalStateException(); + } + + @NotNull + protected static String toEclipseLanguageLevel(LanguageLevel level) { + int feature = level.toJavaVersion().feature; + if (feature < 10) { + return "1." + feature; + } + return String.valueOf(feature); + } + + /** + * TODO CACHE BETWEEN PROJECTS + * + * @return + */ + private ClassLoader getCustomClassloader(String pathToEclipse) throws ClassNotFoundException { + if (StringUtils.isBlank(pathToEclipse)) { + throw new InvalidSettingsException("Please set Eclipse installation location.", true); + } + ConfigurableEclipseLocation configurableEclipseLocation = new ConfigurableEclipseLocation(); + List urlList = configurableEclipseLocation.run(pathToEclipse.trim()); + if (urlList.isEmpty()) { + throw new InvalidSettingsException("Invalid path to Eclipse, no jars found in '" + pathToEclipse + "'", + true); + } + ClassLoader classLoader = Classloaders.getCustomClassloader(urlList); + return classLoader; + } + + + @NotNull + protected LanguageLevel getLanguageLevel(@NotNull PsiFile psiFile) { + if (DummyProject.getInstance() == project) { + return LanguageLevel.JDK_1_7; // tests hack + } + JavaPsiImplementationHelper instance = JavaPsiImplementationHelper.getInstance(project); + LanguageLevel languageLevel = instance.getEffectiveLanguageLevel(psiFile.getVirtualFile()); + + return languageLevel; + } + + public ConfigFileLocator getConfigFileLocator() { + return configFileLocator; + } +} diff --git a/src/java/krasa/formatter/eclipse/ParentLastURLClassLoader.java b/src/main/java/krasa/formatter/eclipse/ParentLastURLClassLoader.java similarity index 100% rename from src/java/krasa/formatter/eclipse/ParentLastURLClassLoader.java rename to src/main/java/krasa/formatter/eclipse/ParentLastURLClassLoader.java diff --git a/src/java/krasa/formatter/exception/FileDoesNotExistsException.java b/src/main/java/krasa/formatter/exception/FileDoesNotExistsException.java similarity index 100% rename from src/java/krasa/formatter/exception/FileDoesNotExistsException.java rename to src/main/java/krasa/formatter/exception/FileDoesNotExistsException.java diff --git a/src/java/krasa/formatter/exception/FormattingFailedException.java b/src/main/java/krasa/formatter/exception/FormattingFailedException.java similarity index 53% rename from src/java/krasa/formatter/exception/FormattingFailedException.java rename to src/main/java/krasa/formatter/exception/FormattingFailedException.java index 789985d..a99ffa9 100644 --- a/src/java/krasa/formatter/exception/FormattingFailedException.java +++ b/src/main/java/krasa/formatter/exception/FormattingFailedException.java @@ -1,9 +1,14 @@ package krasa.formatter.exception; +import com.intellij.openapi.diagnostic.Logger; +import krasa.formatter.plugin.InvalidPropertyFile; + /** * @author Vojtech Krasa */ public class FormattingFailedException extends RuntimeException { + protected final Logger LOG = Logger.getInstance(this.getClass().getName()); + private boolean userError; public FormattingFailedException(String s) { @@ -15,6 +20,16 @@ public FormattingFailedException(String s, boolean userError) { this.userError = userError; } + public FormattingFailedException(InvalidPropertyFile e) { + super(e); + } + + public FormattingFailedException(Exception e, String errorMessage) { + super(errorMessage, e); + //todo hack + LOG.debug(e); + } + public boolean isUserError() { return userError; diff --git a/src/main/java/krasa/formatter/exception/InvalidSettingsException.java b/src/main/java/krasa/formatter/exception/InvalidSettingsException.java new file mode 100644 index 0000000..bfbaabd --- /dev/null +++ b/src/main/java/krasa/formatter/exception/InvalidSettingsException.java @@ -0,0 +1,20 @@ +package krasa.formatter.exception; + +import krasa.formatter.plugin.InvalidPropertyFile; + +public class InvalidSettingsException extends FormattingFailedException { + public InvalidSettingsException(String s) { + super(s,true); + } + + public InvalidSettingsException(String s, boolean userError) { + super(s, userError); + } + + public InvalidSettingsException(InvalidPropertyFile e) { + super(e); + } + + public InvalidSettingsException() { + } +} diff --git a/src/java/krasa/formatter/exception/ParsingFailedException.java b/src/main/java/krasa/formatter/exception/ParsingFailedException.java similarity index 100% rename from src/java/krasa/formatter/exception/ParsingFailedException.java rename to src/main/java/krasa/formatter/exception/ParsingFailedException.java diff --git a/src/java/krasa/formatter/plugin/DelegatingCodeStyleManager.java b/src/main/java/krasa/formatter/plugin/DelegatingCodeStyleManager.java similarity index 88% rename from src/java/krasa/formatter/plugin/DelegatingCodeStyleManager.java rename to src/main/java/krasa/formatter/plugin/DelegatingCodeStyleManager.java index f6aaf4a..e492a5c 100644 --- a/src/java/krasa/formatter/plugin/DelegatingCodeStyleManager.java +++ b/src/main/java/krasa/formatter/plugin/DelegatingCodeStyleManager.java @@ -1,5 +1,5 @@ /* - * Eclipse Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the + * Adapter for Eclipse Code Formatter Copyright (c) 2007-2009 Esko Luontola, www.orfjackal.net Licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for @@ -29,11 +29,14 @@ /** * for tracking api changes only */ -@SuppressWarnings({ "deprecation" }) +@SuppressWarnings({"deprecation"}) public class DelegatingCodeStyleManager extends CodeStyleManager { @NotNull - protected final CodeStyleManager original; + protected CodeStyleManager original; + + public DelegatingCodeStyleManager() { + } public DelegatingCodeStyleManager(@NotNull CodeStyleManager original) { this.original = original; @@ -71,7 +74,7 @@ public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, in @Override public PsiElement reformatRange(@NotNull PsiElement element, int startOffset, int endOffset, - boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException { + boolean canChangeWhiteSpacesOnly) throws IncorrectOperationException { return original.reformatRange(element, startOffset, endOffset, canChangeWhiteSpacesOnly); } @@ -81,6 +84,7 @@ public void reformatText(@NotNull PsiFile element, int startOffset, int endOffse original.reformatText(element, startOffset, endOffset); } + @Override public void adjustLineIndent(@NotNull PsiFile file, TextRange rangeToAdjust) throws IncorrectOperationException { original.adjustLineIndent(file, rangeToAdjust); @@ -92,10 +96,10 @@ public int adjustLineIndent(@NotNull PsiFile file, int offset) throws IncorrectO } @Override - public int adjustLineIndent(@NotNull Document document, int i) { - return original.adjustLineIndent(document, i); - } - // 2017.1 EAP + public int adjustLineIndent(@NotNull Document document, int i) { + return original.adjustLineIndent(document, i); + } + // 2017.1 EAP // @Override // public int adjustLineIndent(@NotNull Document document, int i, FormattingMode formattingMode) { // return original.adjustLineIndent(document, i, formattingMode); @@ -176,7 +180,7 @@ public T performActionWithFormatterDisabled(Computable r) { // 11.1 // @Override @Override - public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges) + public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges) throws IncorrectOperationException { original.reformatText(psiFile, textRanges); } @@ -188,10 +192,10 @@ public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull ChangedRa } // 15 - @Override - public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collection collection) throws IncorrectOperationException { - original.reformatTextWithContext(psiFile, collection); - } + @Override + public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collection collection) throws IncorrectOperationException { + original.reformatTextWithContext(psiFile, collection); + } // 2017.2 @Override diff --git a/src/main/java/krasa/formatter/plugin/Donate.java b/src/main/java/krasa/formatter/plugin/Donate.java new file mode 100644 index 0000000..d1fe278 --- /dev/null +++ b/src/main/java/krasa/formatter/plugin/Donate.java @@ -0,0 +1,34 @@ +package krasa.formatter.plugin; + +import com.intellij.ide.BrowserUtil; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.IconLoader; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class Donate { + private static final Logger LOG = Logger.getInstance(Donate.class); + + public static final @NotNull + Icon ICON = IconLoader.getIcon("/krasa/formatter/coins_in_hand.png", Donate.class); + + public static JButton newDonateButton() { + JButton donate = new JButton(); + initDonateButton(donate); + return donate; + } + + public static void initDonateButton(JButton donate) { + donate.setText("Donate"); + donate.setIcon(ICON); + donate.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + BrowserUtil.browse("https://github.com/sponsors/krasa"); + } + }); + } +} diff --git a/src/java/krasa/formatter/plugin/EclipseCodeFormatter.java b/src/main/java/krasa/formatter/plugin/EclipseCodeFormatter.java similarity index 94% rename from src/java/krasa/formatter/plugin/EclipseCodeFormatter.java rename to src/main/java/krasa/formatter/plugin/EclipseCodeFormatter.java index f176d84..496307c 100644 --- a/src/java/krasa/formatter/plugin/EclipseCodeFormatter.java +++ b/src/main/java/krasa/formatter/plugin/EclipseCodeFormatter.java @@ -9,7 +9,6 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilBase; -import krasa.formatter.eclipse.Classloaders; import krasa.formatter.eclipse.CodeFormatterFacade; import krasa.formatter.exception.FileDoesNotExistsException; import krasa.formatter.processor.Processor; @@ -37,8 +36,6 @@ public EclipseCodeFormatter(@NotNull Settings settings, @NotNull CodeFormatterFa this.settings = settings; codeFormatterFacade = codeFormatterFacade1; postProcessors = new ArrayList(); - postProcessors.add(Classloaders.getGWTProcessor(settings)); - postProcessors.add(Classloaders.getJSCommentsFormatterProcessor(settings)); } public void format(PsiFile psiFile, int startOffset, int endOffset) throws FileDoesNotExistsException { @@ -56,7 +53,7 @@ public void format(PsiFile psiFile, int startOffset, int endOffset) throws FileD } else { formatWhenEditorIsClosed(range, psiFile); } - + } private void formatWhenEditorIsClosed(Range range, PsiFile psiFile) throws FileDoesNotExistsException { @@ -98,13 +95,15 @@ private void formatWhenEditorIsOpen(Editor editor, Range range, PsiFile file) th } private void postProcess(Document document, PsiFile file, Range range, FileDocumentManager fileDocumentManager) { - for (Processor postProcessor : postProcessors) { - postProcessor.process(document, file, range); - } - // updates psi, so comments from import statements does not get duplicated +// for (Processor postProcessor : postProcessors) { +// postProcessor.process(document, file, range); +// } +// // updates psi, so comments from import statements does not get duplicated - probably obsolete final PsiDocumentManager manager = PsiDocumentManager.getInstance(file.getProject()); + //commitDocument needed for intellij-plugin-save-actions manager.commitDocument(document); - fileDocumentManager.saveDocument(document); + // TODO needed? +// fileDocumentManager.saveDocument(document); } private String reformat(int startOffset, int endOffset, String text, PsiFile psiFile) diff --git a/src/java/krasa/formatter/plugin/EclipseCodeStyleManager.java b/src/main/java/krasa/formatter/plugin/EclipseCodeStyleManager.java similarity index 78% rename from src/java/krasa/formatter/plugin/EclipseCodeStyleManager.java rename to src/main/java/krasa/formatter/plugin/EclipseCodeStyleManager.java index dd88f4d..36e748f 100644 --- a/src/java/krasa/formatter/plugin/EclipseCodeStyleManager.java +++ b/src/main/java/krasa/formatter/plugin/EclipseCodeStyleManager.java @@ -14,16 +14,12 @@ import com.intellij.psi.impl.CheckUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.IncorrectOperationException; -import krasa.formatter.eclipse.Classloaders; -import krasa.formatter.eclipse.CodeFormatterFacade; import krasa.formatter.eclipse.JavaCodeFormatterFacade; import krasa.formatter.exception.FileDoesNotExistsException; import krasa.formatter.exception.FormattingFailedException; import krasa.formatter.settings.DisabledFileTypeSettings; import krasa.formatter.settings.ProjectComponent; import krasa.formatter.settings.Settings; -import krasa.formatter.settings.provider.CppPropertiesProvider; -import krasa.formatter.settings.provider.JSPropertiesProvider; import krasa.formatter.utils.FileUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,13 +35,9 @@ public class EclipseCodeStyleManager { @NotNull protected volatile Settings settings; @NotNull - private Notifier notifier; + protected Notifier notifier; @Nullable private volatile EclipseCodeFormatter eclipseCodeFormatterJava; - @Nullable - private volatile EclipseCodeFormatter eclipseCodeFormatterJs; - @Nullable - private volatile EclipseCodeFormatter eclipseCodeFormatterCpp; public EclipseCodeStyleManager(@NotNull CodeStyleManager original, @NotNull Settings settings) { this.original = original; @@ -56,8 +48,6 @@ public EclipseCodeStyleManager(@NotNull CodeStyleManager original, @NotNull Sett public void updateSettings(@NotNull Settings settings) { this.settings = settings; eclipseCodeFormatterJava = null; - eclipseCodeFormatterJs = null; - eclipseCodeFormatterCpp = null; } private final static Comparator RANGE_COMPARATOR = new Comparator() { @@ -70,7 +60,7 @@ public int compare(TextRange range1, TextRange range2) { // 15 // @Override - public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collection textRanges) throws IncorrectOperationException { + public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collection textRanges) throws IncorrectOperationException { if (shouldReformatByEclipse(psiFile)) { reformatText(psiFile, textRanges); } else if (shouldSkipFormatting(psiFile, textRanges)) { @@ -81,7 +71,7 @@ public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collectio } // @Override - public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges) throws IncorrectOperationException { + public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges) throws IncorrectOperationException { if (shouldReformatByEclipse(psiFile)) { List list = new ArrayList(textRanges); Collections.sort(list, Collections.reverseOrder(RANGE_COMPARATOR)); @@ -93,6 +83,20 @@ public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges, boolean processChangedTextOnly) throws IncorrectOperationException { + if (shouldReformatByEclipse(psiFile)) { + List list = new ArrayList(textRanges); + Collections.sort(list, Collections.reverseOrder(RANGE_COMPARATOR)); + formatInternal(psiFile, list, Mode.ALWAYS_FORMAT); + } else if (shouldSkipFormatting(psiFile, textRanges)) { + notifier.notifyFormattingWasDisabled(psiFile); + } else { + //since IJ 241 + original.reformatText(psiFile, textRanges, processChangedTextOnly); + } + } + // @Override // todo should I even override this method? public void reformatText(@NotNull final PsiFile psiFile, final int startOffset, final int endOffset) throws IncorrectOperationException { @@ -107,14 +111,14 @@ public void reformatText(@NotNull final PsiFile psiFile, final int startOffset, } } - private void formatInternal(PsiFile psiFile, List list, Mode mode) { + private void formatInternal(PsiFile psiFile, List list, Mode mode) { ApplicationManager.getApplication().assertWriteAccessAllowed(); PsiDocumentManager.getInstance(original.getProject()).commitAllDocuments(); CheckUtil.checkWritable(psiFile); if (psiFile.getVirtualFile() == null) { LOG.debug("virtual file is null"); - Notification notification = ProjectComponent.GROUP_DISPLAY_ID_ERROR.createNotification( + Notification notification = ProjectComponent.getNotificationGroupError().createNotification( Notifier.NO_FILE_TO_FORMAT, NotificationType.ERROR); notifier.showNotification(notification, psiFile.getProject()); return; @@ -162,7 +166,7 @@ private void formatInternal(PsiFile psiFile, List list, Mode mode) { } catch (final FormattingFailedException e) { LOG.debug("startOffset" + startOffset + ", endOffset:" + endOffset + ", length of file " + psiFile.getText().length(), e); - notifier.notifyFailedFormatting(psiFile, formattedByIntelliJ, getReason(e)); + notifier.notifyFailedFormatting(psiFile, formattedByIntelliJ, e, getReason(e)); } catch (final Throwable e) { LOG.error(e); } @@ -175,7 +179,7 @@ private boolean shouldNotify(PsiFile psiFile, int startOffset, int endOffset) { return !skipSuccessFormattingNotification; } - private boolean wholeFileOrSelectedText(PsiFile psiFile, List list) { + private boolean wholeFileOrSelectedText(PsiFile psiFile, List list) { boolean wholeFileOrSelectedText = false; final Editor editor = PsiUtilBase.findEditor(psiFile); boolean result; @@ -198,7 +202,7 @@ private String getReason(FormattingFailedException e) { if (e.isUserError() && e.getMessage() != null) { return "
" + e.getMessage(); } - String result = "Probably due to syntax error or wrong configuration file."; + String result = "Probably due to a syntax error or a wrong configuration file."; String message = e.getMessage(); if (message != null) { result = result + "
" + message; @@ -207,33 +211,17 @@ private String getReason(FormattingFailedException e) { } private void formatWithEclipse(PsiFile psiFile, int startOffset, int endOffset) throws FileDoesNotExistsException { - if (FileUtils.isJavaScript(psiFile)) { - if (eclipseCodeFormatterJs == null) { - JSPropertiesProvider jsProperties = settings.getJSProperties(); - CodeFormatterFacade jsFormatter = Classloaders.getJsFormatter(jsProperties); - eclipseCodeFormatterJs = new EclipseCodeFormatter(settings, jsFormatter); - } - eclipseCodeFormatterJs.format(psiFile, startOffset, endOffset); - } else if (FileUtils.isCpp(psiFile)) { - if (eclipseCodeFormatterCpp == null) { - CppPropertiesProvider cppProperties = settings.getCppProperties(); - CodeFormatterFacade cpp = Classloaders.getCppFormatter(cppProperties); - eclipseCodeFormatterCpp = new EclipseCodeFormatter(settings, cpp); - } - eclipseCodeFormatterCpp.format(psiFile, startOffset, endOffset); - } else { if (eclipseCodeFormatterJava == null) { - JavaCodeFormatterFacade facade = new JavaCodeFormatterFacade(settings.getJavaProperties(), - settings.getEclipseVersion(), original.getProject(), settings.getPathToEclipse()); + JavaCodeFormatterFacade facade = new JavaCodeFormatterFacade(settings, original.getProject()); eclipseCodeFormatterJava = new EclipseCodeFormatter(settings, facade); } eclipseCodeFormatterJava.format(psiFile, startOffset, endOffset); - } } - private boolean shouldSkipFormatting(PsiFile psiFile, Collection textRanges) { - VirtualFile virtualFile = psiFile.getVirtualFile(); - if (settings.isFormatSeletedTextInAllFileTypes()) { + + protected boolean shouldSkipFormatting(PsiFile psiFile, Collection textRanges) { + + if (settings.isFormatSeletedTextInAllFileTypes()) { // when file is being edited, it is important to load text from editor, i think final Editor editor = PsiUtilBase.findEditor(psiFile); if (editor != null) { @@ -246,14 +234,16 @@ private boolean shouldSkipFormatting(PsiFile psiFile, Collection text } //not else if (settings.isFormatOtherFileTypesWithIntelliJ()) { - return isDisabledFileType(virtualFile); + return isDisabledFileType(psiFile.getVirtualFile()); } return true; } public boolean shouldReformatByEclipse(PsiFile psiFile) { - return settings.isEnabled() && fileTypeIsEnabled(psiFile) && psiFile.getVirtualFile().isInLocalFileSystem() + return settings.isEnabled() && fileTypeIsEnabled(psiFile) + && psiFile.getVirtualFile() != null + && psiFile.getVirtualFile().isInLocalFileSystem() // not sure why that is here && FileUtils.isWritable(psiFile); } @@ -262,17 +252,19 @@ private boolean formatWithIntelliJ(PsiFile psiFile, int startOffset, int endOffs original.reformatText(psiFile, startOffset, endOffset); return true; } - + private boolean isDisabledFileType(VirtualFile virtualFile) { + //https://github.com/krasa/EclipseCodeFormatter/issues/227 + if (virtualFile == null) { + return false; + } String path = virtualFile.getPath(); DisabledFileTypeSettings disabledFileTypeSettings = settings.getDisabledFileTypeSettings(); return disabledFileTypeSettings.isDisabled(path); } private boolean fileTypeIsEnabled(@NotNull PsiFile psiFile) { - return (FileUtils.isJava(psiFile) && settings.isEnableJavaFormatting()) - || (FileUtils.isJavaScript(psiFile) && settings.isEnableJSFormatting()) - || (FileUtils.isCpp(psiFile) && settings.isEnableCppFormatting()); + return (FileUtils.isJava(psiFile) && settings.isEnableJavaFormatting()); } public boolean isEnabled() { diff --git a/src/java/krasa/formatter/plugin/EclipseCodeStyleManager_IJ_2016_3plus.java b/src/main/java/krasa/formatter/plugin/EclipseCodeStyleManager_IJ_2016_3plus.java similarity index 68% rename from src/java/krasa/formatter/plugin/EclipseCodeStyleManager_IJ_2016_3plus.java rename to src/main/java/krasa/formatter/plugin/EclipseCodeStyleManager_IJ_2016_3plus.java index 3e53d61..4f2de58 100644 --- a/src/java/krasa/formatter/plugin/EclipseCodeStyleManager_IJ_2016_3plus.java +++ b/src/main/java/krasa/formatter/plugin/EclipseCodeStyleManager_IJ_2016_3plus.java @@ -1,16 +1,15 @@ package krasa.formatter.plugin; -import java.util.List; - -import org.jetbrains.annotations.NotNull; - import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.util.IncorrectOperationException; - import krasa.formatter.settings.Settings; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; public class EclipseCodeStyleManager_IJ_2016_3plus extends EclipseCodeStyleManager { @@ -22,14 +21,16 @@ public EclipseCodeStyleManager_IJ_2016_3plus(@NotNull CodeStyleManager original, // 16.3 // @Override - public void reformatTextWithContext(@NotNull PsiFile psiFile, - @NotNull com.intellij.psi.codeStyle.ChangedRangesInfo changedRangesInfo) + public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull com.intellij.psi.codeStyle.ChangedRangesInfo changedRangesInfo) throws IncorrectOperationException { - if (!shouldReformatByEclipse(psiFile)) { - original.reformatTextWithContext(psiFile, changedRangesInfo); - } else { + if (shouldReformatByEclipse(psiFile)) { List allChangedRanges = changedRangesInfo.allChangedRanges; reformatText(psiFile, allChangedRanges); + // TODO check if file is being commited. rather than faking TextRange + } else if (shouldSkipFormatting(psiFile, Collections.singletonList(new TextRange(0, psiFile.getTextLength())))) { + notifier.notifyFormattingWasDisabled(psiFile); + } else { + original.reformatTextWithContext(psiFile, changedRangesInfo); } } diff --git a/src/java/krasa/formatter/plugin/EclipseImportOptimizer.java b/src/main/java/krasa/formatter/plugin/EclipseImportOptimizer.java similarity index 84% rename from src/java/krasa/formatter/plugin/EclipseImportOptimizer.java rename to src/main/java/krasa/formatter/plugin/EclipseImportOptimizer.java index 12975ec..451e6a8 100644 --- a/src/java/krasa/formatter/plugin/EclipseImportOptimizer.java +++ b/src/main/java/krasa/formatter/plugin/EclipseImportOptimizer.java @@ -1,21 +1,21 @@ package krasa.formatter.plugin; -import org.jetbrains.annotations.NotNull; - import com.intellij.lang.ImportOptimizer; import com.intellij.lang.java.JavaImportOptimizer; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.IndexNotReadyException; +import com.intellij.openapi.util.EmptyRunnable; import com.intellij.psi.*; - import krasa.formatter.exception.FileDoesNotExistsException; import krasa.formatter.exception.ParsingFailedException; import krasa.formatter.settings.ProjectComponent; import krasa.formatter.settings.Settings; import krasa.formatter.settings.provider.ImportOrderProvider; import krasa.formatter.utils.FileUtils; +import org.jetbrains.annotations.NotNull; /** * @author Vojtech Krasa @@ -29,7 +29,12 @@ public class EclipseImportOptimizer implements ImportOptimizer { @NotNull @Override public Runnable processFile(final PsiFile file) { - final Runnable intellijRunnable = new JavaImportOptimizer().processFile(file); + if (!(file instanceof PsiJavaFile)) { + return EmptyRunnable.getInstance(); + } + final PsiJavaFile dummyFile = (PsiJavaFile) file.copy(); + + final Runnable intellijRunnable = new JavaImportOptimizer().processFile(dummyFile); if (!(file instanceof PsiJavaFile)) { return intellijRunnable; } @@ -37,7 +42,6 @@ public Runnable processFile(final PsiFile file) { if (!isEnabled(file)) { return intellijRunnable; } - return new Runnable() { @Override @@ -46,7 +50,7 @@ public void run() { try { Settings settings = ProjectComponent.getSettings(file); if (isEnabled(settings)) { - optimizeImportsByEclipse((PsiJavaFile) file, settings); + optimizeImportsByEclipse((PsiJavaFile) file, settings, dummyFile); } } catch (ParsingFailedException e) { notifier.configurationError(e, file.getProject()); @@ -56,14 +60,16 @@ public void run() { LOG.info("Eclipse Import Optimizer failed", e); } catch (IndexNotReadyException e) { throw e; - } catch (Exception e) { + } catch (ProcessCanceledException e) { + throw e; + } catch (Throwable e) { LOG.error("Eclipse Import Optimizer failed", e); } } }; } - private void optimizeImportsByEclipse(PsiJavaFile psiFile, Settings settings) { + private void optimizeImportsByEclipse(PsiJavaFile psiFile, Settings settings, PsiJavaFile dummy) { ImportSorterAdapter importSorter = null; try { importSorter = getImportSorter(settings); @@ -71,15 +77,17 @@ private void optimizeImportsByEclipse(PsiJavaFile psiFile, Settings settings) { PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(psiFile.getProject()); commitDocument(psiFile, psiDocumentManager); - importSorter.sortImports(psiFile); - commitDocumentAndSave(psiFile, psiDocumentManager); + importSorter.sortImports(psiFile, dummy); +// commitDocumentAndSave(psiFile, psiDocumentManager); } catch (ParsingFailedException e) { throw e; } catch (IndexNotReadyException e) { throw e; + } catch (ProcessCanceledException e) { + throw e; } catch (FileDoesNotExistsException e) { throw e; - } catch (Exception e) { + } catch (Throwable e) { final PsiImportList oldImportList = (psiFile).getImportList(); StringBuilder stringBuilder = new StringBuilder(); if (oldImportList != null) { @@ -105,6 +113,9 @@ private void commitDocument(PsiJavaFile psiFile, PsiDocumentManager psiDocumentM } } + /** + * 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 + */ private void commitDocumentAndSave(PsiJavaFile psiFile, PsiDocumentManager psiDocumentManager) { Document document = psiDocumentManager.getDocument(psiFile); if (document != null) { diff --git a/src/java/krasa/formatter/plugin/ImportSorterAdapter.java b/src/main/java/krasa/formatter/plugin/ImportSorterAdapter.java similarity index 87% rename from src/java/krasa/formatter/plugin/ImportSorterAdapter.java rename to src/main/java/krasa/formatter/plugin/ImportSorterAdapter.java index c3f9d08..6d64257 100644 --- a/src/java/krasa/formatter/plugin/ImportSorterAdapter.java +++ b/src/main/java/krasa/formatter/plugin/ImportSorterAdapter.java @@ -1,16 +1,14 @@ package krasa.formatter.plugin; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - +import com.intellij.openapi.fileTypes.StdFileTypes; +import com.intellij.psi.*; import krasa.formatter.settings.Settings; import krasa.formatter.utils.StringUtils; - import org.jetbrains.annotations.NotNull; -import com.intellij.openapi.fileTypes.StdFileTypes; -import com.intellij.psi.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * @author Vojtech Krasa @@ -30,16 +28,20 @@ public String getImportsOrderAsString() { return Arrays.toString(importsOrder.toArray()); } - public void sortImports(PsiJavaFile file) { + public void sortImports(PsiJavaFile file, PsiJavaFile dummy) { List imports = new ArrayList(); List nonImports = new ArrayList(); - PsiImportList importList = file.getImportList(); - if (importList == null) { + PsiImportList actualImportList = file.getImportList(); + if (actualImportList == null) { + return; + } + PsiImportList dummyImportList = dummy.getImportList(); + if (dummyImportList == null) { return; } - PsiElement[] children = importList.getChildren(); + PsiElement[] children = dummyImportList.getChildren(); for (int i = 0; i < children.length; i++) { PsiElement child = children[i]; if (child instanceof PsiImportStatementBase) { @@ -67,8 +69,7 @@ public void sortImports(PsiJavaFile file) { PsiImportList newImportList = dummyFile.getImportList(); PsiImportList result = (PsiImportList) newImportList.copy(); - PsiImportList oldList = file.getImportList(); - if (oldList.isReplaceEquivalent(result)) + if (actualImportList.isReplaceEquivalent(result)) return; if (!nonImports.isEmpty()) { PsiElement firstPrevious = newImportList.getPrevSibling(); @@ -84,7 +85,8 @@ public void sortImports(PsiJavaFile file) { result.add(element.copy()); } } - importList.replace(result); + + actualImportList.replace(result); } @NotNull diff --git a/src/java/krasa/formatter/plugin/ImportSorterException.java b/src/main/java/krasa/formatter/plugin/ImportSorterException.java similarity index 100% rename from src/java/krasa/formatter/plugin/ImportSorterException.java rename to src/main/java/krasa/formatter/plugin/ImportSorterException.java diff --git a/src/java/krasa/formatter/plugin/ImportsComparator.java b/src/main/java/krasa/formatter/plugin/ImportsComparator.java similarity index 99% rename from src/java/krasa/formatter/plugin/ImportsComparator.java rename to src/main/java/krasa/formatter/plugin/ImportsComparator.java index 70c14bd..03d6bac 100644 --- a/src/java/krasa/formatter/plugin/ImportsComparator.java +++ b/src/main/java/krasa/formatter/plugin/ImportsComparator.java @@ -1,14 +1,13 @@ package krasa.formatter.plugin; -import java.util.Comparator; - -import krasa.formatter.utils.StringUtils; - import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.impl.JavaPsiFacadeImpl; import com.intellij.psi.search.GlobalSearchScope; +import krasa.formatter.utils.StringUtils; + +import java.util.Comparator; class ImportsComparator implements Comparator { diff --git a/src/java/krasa/formatter/plugin/ImportsSorter.java b/src/main/java/krasa/formatter/plugin/ImportsSorter.java similarity index 100% rename from src/java/krasa/formatter/plugin/ImportsSorter.java rename to src/main/java/krasa/formatter/plugin/ImportsSorter.java diff --git a/src/java/krasa/formatter/plugin/ImportsSorter450.java b/src/main/java/krasa/formatter/plugin/ImportsSorter450.java similarity index 97% rename from src/java/krasa/formatter/plugin/ImportsSorter450.java rename to src/main/java/krasa/formatter/plugin/ImportsSorter450.java index 1d59079..c1f8aa4 100644 --- a/src/java/krasa/formatter/plugin/ImportsSorter450.java +++ b/src/main/java/krasa/formatter/plugin/ImportsSorter450.java @@ -1,16 +1,16 @@ package krasa.formatter.plugin; -import java.util.*; - +import com.intellij.util.containers.MultiMap; import krasa.formatter.utils.StringUtils; -import com.intellij.openapi.util.MultiValuesMap; +import java.util.*; + /*not thread safe*/ class ImportsSorter450 implements ImportsSorter { private List template = new ArrayList(); - private MultiValuesMap matchingImports = new MultiValuesMap(); + private MultiMap matchingImports = new MultiMap(); private ArrayList notMatching = new ArrayList(); private Set allImportOrderItems = new HashSet(); private Comparator comparator; @@ -87,7 +87,7 @@ private void filterMatchingImports(List imports) { for (String anImport : imports) { String orderItem = getBestMatchingImportOrderItem(anImport); if (orderItem != null) { - matchingImports.put(orderItem, anImport); + matchingImports.putValue(orderItem, anImport); } else { notMatching.add(anImport); } diff --git a/src/java/krasa/formatter/plugin/ImportsSorter452.java b/src/main/java/krasa/formatter/plugin/ImportsSorter452.java similarity index 97% rename from src/java/krasa/formatter/plugin/ImportsSorter452.java rename to src/main/java/krasa/formatter/plugin/ImportsSorter452.java index 251c31a..e836f11 100644 --- a/src/java/krasa/formatter/plugin/ImportsSorter452.java +++ b/src/main/java/krasa/formatter/plugin/ImportsSorter452.java @@ -1,19 +1,17 @@ package krasa.formatter.plugin; -import java.util.*; - +import com.intellij.util.containers.MultiMap; import krasa.formatter.utils.StringUtils; - import org.jetbrains.annotations.NotNull; -import com.intellij.openapi.util.MultiValuesMap; +import java.util.*; /*not thread safe*/ @SuppressWarnings("Duplicates") class ImportsSorter452 implements ImportsSorter { private List template = new ArrayList(); - private MultiValuesMap matchingImports = new MultiValuesMap(); + private MultiMap matchingImports = new MultiMap(); private ArrayList notMatching = new ArrayList(); private Set allImportOrderItems = new HashSet(); private Comparator importsComparator; @@ -113,7 +111,7 @@ private void filterMatchingImports(List imports) { for (String anImport : imports) { String orderItem = getBestMatchingImportOrderItem(anImport); if (orderItem != null) { - matchingImports.put(orderItem, anImport); + matchingImports.putValue(orderItem, anImport); } else { notMatching.add(anImport); } diff --git a/src/java/krasa/formatter/plugin/InvalidPropertyFile.java b/src/main/java/krasa/formatter/plugin/InvalidPropertyFile.java similarity index 86% rename from src/java/krasa/formatter/plugin/InvalidPropertyFile.java rename to src/main/java/krasa/formatter/plugin/InvalidPropertyFile.java index 3889f96..59aada1 100644 --- a/src/java/krasa/formatter/plugin/InvalidPropertyFile.java +++ b/src/main/java/krasa/formatter/plugin/InvalidPropertyFile.java @@ -8,7 +8,7 @@ public class InvalidPropertyFile extends RuntimeException { public InvalidPropertyFile(String s, File file) { - super("Property " + s + " does not exists in " + file.getAbsolutePath()); + super(s); } public InvalidPropertyFile(File file) { diff --git a/src/java/krasa/formatter/plugin/ManualCodeStyleManagerDelegator.java b/src/main/java/krasa/formatter/plugin/ManualCodeStyleManagerDelegator.java similarity index 70% rename from src/java/krasa/formatter/plugin/ManualCodeStyleManagerDelegator.java rename to src/main/java/krasa/formatter/plugin/ManualCodeStyleManagerDelegator.java index 6126ded..e4e969e 100644 --- a/src/java/krasa/formatter/plugin/ManualCodeStyleManagerDelegator.java +++ b/src/main/java/krasa/formatter/plugin/ManualCodeStyleManagerDelegator.java @@ -3,11 +3,15 @@ import com.intellij.formatting.FormattingMode; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.codeStyle.FormattingModeAwareIndentAdjuster; +import com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl; +import com.intellij.serviceContainer.NonInjectable; import com.intellij.util.IncorrectOperationException; +import krasa.formatter.settings.ProjectComponent; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -15,21 +19,28 @@ public class ManualCodeStyleManagerDelegator extends DelegatingCodeStyleManager implements FormattingModeAwareIndentAdjuster { private static final Logger log = Logger.getInstance(ManualCodeStyleManagerDelegator.class.getName()); - private final EclipseCodeStyleManager eclipseCodeStyleManager; + private EclipseCodeStyleManager eclipseCodeStyleManager; + public ManualCodeStyleManagerDelegator(Project p) { + CodeStyleManagerImpl codeStyleManager = new CodeStyleManagerImpl(p); + this.eclipseCodeStyleManager = new EclipseCodeStyleManager_IJ_2016_3plus(codeStyleManager, ProjectComponent.getSettings(p)); + this.original = codeStyleManager; + } + + @NonInjectable public ManualCodeStyleManagerDelegator(@NotNull CodeStyleManager original, EclipseCodeStyleManager eclipseCodeStyleManager) { super(original); this.eclipseCodeStyleManager = eclipseCodeStyleManager; } @Override - public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collection collection) throws IncorrectOperationException { + public void reformatTextWithContext(@NotNull PsiFile psiFile, @NotNull Collection collection) throws IncorrectOperationException { eclipseCodeStyleManager.reformatTextWithContext(psiFile, collection); } @Override - public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges) throws IncorrectOperationException { + public void reformatText(@NotNull PsiFile psiFile, @NotNull Collection textRanges) throws IncorrectOperationException { eclipseCodeStyleManager.reformatText(psiFile, textRanges); } @@ -55,4 +66,8 @@ public FormattingMode getCurrentFormattingMode() { return FormattingMode.REFORMAT; } } + + public EclipseCodeStyleManager getEclipseCodeStyleManager() { + return eclipseCodeStyleManager; + } } diff --git a/src/java/krasa/formatter/plugin/Mode.java b/src/main/java/krasa/formatter/plugin/Mode.java similarity index 100% rename from src/java/krasa/formatter/plugin/Mode.java rename to src/main/java/krasa/formatter/plugin/Mode.java diff --git a/src/main/java/krasa/formatter/plugin/Notifier.java b/src/main/java/krasa/formatter/plugin/Notifier.java new file mode 100644 index 0000000..d30b222 --- /dev/null +++ b/src/main/java/krasa/formatter/plugin/Notifier.java @@ -0,0 +1,117 @@ +package krasa.formatter.plugin; + +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationType; +import com.intellij.notification.Notifications; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.options.ShowSettingsUtil; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import krasa.formatter.exception.InvalidSettingsException; +import krasa.formatter.settings.ProjectComponent; +import org.jetbrains.annotations.NotNull; + +/** + * @author Vojtech Krasa + */ +public class Notifier { + + public static final String NO_FILE_TO_FORMAT = "No file to format"; + + + + public void notifyFailedFormatting(PsiFile psiFile, boolean formattedByIntelliJ, Exception e) { + String error = e.getMessage() == null ? "" : e.getMessage(); + notifyFailedFormatting(psiFile, formattedByIntelliJ, e, error); + } + + public void notifyFailedFormatting(PsiFile psiFile, boolean formattedByIntelliJ, Exception e, final String reason) { + String content; + if (!formattedByIntelliJ) { + if (e instanceof InvalidSettingsException) { + content = psiFile.getName() + " failed to format. " + reason + "\n"; + } else { + content = psiFile.getName() + " failed to format with Adapter for Eclipse Code Formatter. " + reason + + "\n"; + } + } else { + content = psiFile.getName() + " failed to format with IntelliJ code formatter.\n" + reason; + } + Notification notification = ProjectComponent.getNotificationGroupError().createNotification(content, + NotificationType.ERROR); + + if (e instanceof InvalidSettingsException) { + notification.addAction(new AnAction("Open Settings") { + @Override + public void actionPerformed(@NotNull AnActionEvent anActionEvent) { + notification.expire(); + ShowSettingsUtil.getInstance().showSettingsDialog(getEventProject(anActionEvent), + "Adapter for Eclipse Code Formatter"); + } + }); + } + showNotification(notification, psiFile.getProject()); + } + + void notifyFormattingWasDisabled(PsiFile psiFile) { + Notification notification = ProjectComponent.getNotificationGroupInfo().createNotification( + psiFile.getName() + " - formatting was disabled for this file type", NotificationType.WARNING); + showNotification(notification, psiFile.getProject()); + } + + void notifySuccessFormatting(PsiFile psiFile, boolean formattedByIntelliJ) { + String content; + if (formattedByIntelliJ) { + content = psiFile.getName() + " formatted successfully by IntelliJ code formatter"; + } else { + content = psiFile.getName() + " formatted successfully by Adapter for Eclipse Code Formatter"; + } + Notification notification = ProjectComponent.getNotificationGroupInfo().createNotification(content, + NotificationType.INFORMATION); + showNotification(notification, psiFile.getProject()); + } + + void showNotification(final Notification notification, final Project project) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + Notifications.Bus.notify(notification, project); + } + }); + } + + public void notifyBrokenImportSorter(Project project) { + String content = "Formatting failed due to a new Import optimizer."; + Notification notification = ProjectComponent.getNotificationGroupError().createNotification(content, + NotificationType.ERROR); + showNotification(notification, project); + + } + + public static void notifyDeletedSettings(final Project project) { + String content = "Adapter for Eclipse Code Formatter - settings profile was deleted for project " + project.getName() + + ". Check the configuration."; + final Notification notification = ProjectComponent.getNotificationGroupError().createNotification(content, + NotificationType.ERROR); + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + Notifications.Bus.notify(notification, project); + } + }); + } + public static void notifyProfileDoesNotExist(Project project) { + String content = "Adapter for Eclipse Code Formatter - Global profile does not exist for project " + project.getName() + + ". Check the configuration."; + final Notification notification = ProjectComponent.getNotificationGroupError().createNotification(content, + NotificationType.ERROR); + ApplicationManager.getApplication().invokeLater(() -> Notifications.Bus.notify(notification, project)); + } + public void configurationError(Exception e, Project project) { + Notification notification = ProjectComponent.getNotificationGroupError() + .createNotification("Eclipse Formatter configuration error: " + e.getMessage(), NotificationType.ERROR); + showNotification(notification, project); + } +} diff --git a/src/java/krasa/formatter/plugin/ProjectCodeStyleInstaller.java b/src/main/java/krasa/formatter/plugin/ProjectCodeStyleInstaller.java similarity index 78% rename from src/java/krasa/formatter/plugin/ProjectCodeStyleInstaller.java rename to src/main/java/krasa/formatter/plugin/ProjectCodeStyleInstaller.java index 04fda35..5e08c0b 100644 --- a/src/java/krasa/formatter/plugin/ProjectCodeStyleInstaller.java +++ b/src/main/java/krasa/formatter/plugin/ProjectCodeStyleInstaller.java @@ -8,12 +8,15 @@ package krasa.formatter.plugin; +import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.ide.plugins.PluginManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.PluginId; import com.intellij.openapi.project.Project; import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.serviceContainer.ComponentManagerImpl; import krasa.formatter.settings.Settings; import org.jetbrains.annotations.NotNull; -import org.picocontainer.MutablePicoContainer; import static krasa.formatter.plugin.ProxyUtils.createProxy; @@ -51,10 +54,11 @@ public EclipseCodeStyleManager install(@NotNull Settings settings) { overridingObject = new EclipseCodeStyleManager(currentManager, settings); } CodeStyleManager proxy = createProxy(currentManager, overridingObject); -// CodeStyleManager proxy = new ManualCodeStyleManagerDelegator(currentManager, overridingObject); + // CodeStyleManager proxy = new ManualCodeStyleManagerDelegator(currentManager, overridingObject); - LOG.info("Overriding " + currentManager.getClass().getCanonicalName() + " with " + overridingObject.getClass().getCanonicalName() + "' for project '" - + project.getName() + "' using CGLIB proxy"); + LOG.info("Overriding " + currentManager.getClass().getCanonicalName() + " with " + + overridingObject.getClass().getCanonicalName() + "' for project '" + project.getName() + + "' using CGLIB proxy"); registerCodeStyleManager(project, proxy); return overridingObject; } @@ -68,7 +72,6 @@ private boolean compatibleWith_2016_3_API() { return aClass != null; } - /** * Dmitry Jemerov in unrelated discussion: "Trying to replace IDEA's core components with your custom * implementations is something that we consider a very bad idea, and it's pretty much guaranteed to break in future @@ -78,8 +81,9 @@ private boolean compatibleWith_2016_3_API() { * lol */ private static void registerCodeStyleManager(@NotNull Project project, @NotNull CodeStyleManager newManager) { - MutablePicoContainer container = (MutablePicoContainer) project.getPicoContainer(); - container.unregisterComponent(CODE_STYLE_MANAGER_KEY); - container.registerComponentInstance(CODE_STYLE_MANAGER_KEY, newManager); + ComponentManagerImpl platformComponentManager = (ComponentManagerImpl) project; + IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId("EclipseCodeFormatter")); + platformComponentManager.registerServiceInstance(CodeStyleManager.class, newManager, plugin); } -} + +} diff --git a/src/main/java/krasa/formatter/plugin/ProjectSettingsForm.form b/src/main/java/krasa/formatter/plugin/ProjectSettingsForm.form new file mode 100644 index 0000000..3bcf765 --- /dev/null +++ b/src/main/java/krasa/formatter/plugin/ProjectSettingsForm.form @@ -0,0 +1,616 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/java/krasa/formatter/plugin/ProjectSettingsForm.java b/src/main/java/krasa/formatter/plugin/ProjectSettingsForm.java similarity index 60% rename from src/java/krasa/formatter/plugin/ProjectSettingsForm.java rename to src/main/java/krasa/formatter/plugin/ProjectSettingsForm.java index df27715..5a02eca 100644 --- a/src/java/krasa/formatter/plugin/ProjectSettingsForm.java +++ b/src/main/java/krasa/formatter/plugin/ProjectSettingsForm.java @@ -8,27 +8,6 @@ package krasa.formatter.plugin; -import static com.intellij.openapi.fileChooser.FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor; -import static com.intellij.openapi.fileChooser.FileChooserDescriptorFactory.createSingleFolderDescriptor; - -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import javax.swing.*; -import javax.swing.event.AncestorEvent; -import javax.swing.event.AncestorListener; -import javax.swing.event.DocumentEvent; - -import org.apache.commons.lang.ObjectUtils; -import org.apache.commons.lang.StringUtils; -import org.jetbrains.annotations.NotNull; - import com.centerkey.utils.BareBonesBrowserLaunch; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.application.ex.ApplicationManagerEx; @@ -44,18 +23,35 @@ import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.ui.ColoredSideBorder; import com.intellij.ui.DocumentAdapter; import com.intellij.ui.ListCellRendererWrapper; import com.intellij.ui.SortedComboBoxModel; import com.intellij.ui.popup.list.ListPopupImpl; import com.intellij.ui.popup.mock.MockConfirmation; - -import krasa.formatter.exception.ParsingFailedException; +import krasa.formatter.eclipse.ConfigFileLocator; import krasa.formatter.settings.GlobalSettings; import krasa.formatter.settings.MyConfigurable; import krasa.formatter.settings.ProjectSettings; import krasa.formatter.settings.Settings; -import krasa.formatter.utils.FileUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.event.AncestorEvent; +import javax.swing.event.AncestorListener; +import javax.swing.event.DocumentEvent; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.lang.reflect.Field; +import java.util.List; +import java.util.*; + +import static com.intellij.openapi.fileChooser.FileChooserDescriptorFactory.*; /** * Configuration dialog for changing the {@link krasa.formatter.settings.Settings} of the plugin. @@ -66,7 +62,11 @@ */ public class ProjectSettingsForm { private static final Logger LOG = Logger.getInstance(ProjectSettingsForm.class.getName()); + public static final String NOT_EXISTS = "NOT EXISTS"; public static final String PARSING_FAILED = "PARSING FAILED"; + public static final String CONTAINS_NO_PROFILES = "CONTAINS NO PROFILES"; + public Border normalBorder; + public static final ColoredSideBorder ERROR_BORDER = new ColoredSideBorder(Color.RED, Color.RED, Color.RED, Color.RED, 1); private JPanel rootComponent; @@ -82,22 +82,16 @@ public class ProjectSettingsForm { private JCheckBox formatSelectedTextInAllFileTypes; private JLabel eclipsePreferenceFileJavaLabel; - private JLabel eclipsePreferenceFileJSLabel; private JTextField pathToEclipsePreferenceFileJava; - private JTextField pathToEclipsePreferenceFileJS; private JLabel eclipsePrefsExample; - private JLabel eclipsePrefsExampleJS; private JCheckBox enableJavaFormatting; - private JCheckBox enableJSFormatting; private JButton eclipsePreferenceFilePathJavaBrowse; - private JButton eclipsePreferenceFilePathJSBrowse; private JCheckBox optimizeImportsCheckBox; - private JLabel importOrderLabel; private JFormattedTextField importOrder; private JLabel importOrderManualExample; private JTextField pathToImportOrderPreferenceFile; @@ -113,33 +107,27 @@ public class ProjectSettingsForm { private JButton exportToProjectProfile; private JButton delete; private Settings displayedSettings; - private JButton DONATEButton; - private JComboBox javaFormatterProfile; + private JButton donateButton; + public JComboBox javaFormatterProfile; private JLabel javaFormatterProfileLabel; private JButton helpButton; private JButton homepage; - private JCheckBox enableGWTNativeMethodsCheckBox; - private JCheckBox enableJavaScriptCommentsPostProcessor; - private JLabel formatterProfileLabelJS; - private JComboBox formatterProfileJS; private JCheckBox useForLiveTemplates; - private JCheckBox enableCppFormatting; - private JComboBox formatterProfileCpp; - private JTextField pathToEclipsePreferenceFileCpp; - private JLabel eclipsePreferenceFileCppLabel; - private JButton eclipsePreferenceFilePathCppBrowse; - private JLabel formatterProfileLabelCpp; - private JLabel eclipsePrefsExampleCpp; - private JTextField pathToCustomEclipse; + public JTextField pathToCustomEclipse; private JButton customEclipseLocationBrowse; - private JRadioButton useEclipse44; private JRadioButton useEclipseNewest; private JRadioButton useEclipseCustom; private JLabel javaFormatterVersionLabel; private JRadioButton importOrdering451; private JRadioButton importOrdering452; - private JButton profileHelp; + private JLabel importStyleLabel; + private JRadioButton schemeEclipseJC; + private JRadioButton schemeEclipse; + private JRadioButton schemeEclipse21; + private JRadioButton schemeEclipseFile; + private JRadioButton schemeCurrentProject; + private JCheckBox backupToProjectCheckBox; private final List visiblePopups = new ArrayList(); @NotNull @@ -149,56 +137,46 @@ public class ProjectSettingsForm { private void updateComponents() { hidePopups(); - enabledBy(new JComponent[] { eclipseSupportedFileTypesLabel, enableJavaFormatting, enableJSFormatting, - enableCppFormatting, doNotFormatOtherFilesRadioButton, formatOtherFilesWithExceptionsRadioButton, + + enabledBy(new JComponent[]{eclipseSupportedFileTypesLabel, enableJavaFormatting, doNotFormatOtherFilesRadioButton, + formatOtherFilesWithExceptionsRadioButton, importOrderPreferenceFileExample, importOrderConfigurationFromFileRadioButton, - importOrderConfigurationManualRadioButton, useEclipse44, useEclipseNewest, useEclipseCustom, - formatSelectedTextInAllFileTypes, useForLiveTemplates, importOrdering451, importOrdering452 }, - useEclipseFormatter); - - enabledBy(new JComponent[] { pathToEclipsePreferenceFileJava, eclipsePrefsExample, - eclipsePreferenceFileJavaLabel, optimizeImportsCheckBox, eclipsePreferenceFilePathJavaBrowse, - javaFormatterProfileLabel, javaFormatterProfile, enableGWTNativeMethodsCheckBox, - customEclipseLocationBrowse, pathToCustomEclipse, useEclipse44, useEclipseNewest, useEclipseCustom, - javaFormatterVersionLabel, importOrdering451, importOrdering452 }, enableJavaFormatting); - - enabledBy(new JComponent[] { pathToCustomEclipse, customEclipseLocationBrowse, }, useEclipseCustom); - - enabledBy( - new JComponent[] { importOrder, pathToImportOrderPreferenceFile, pathToImportOrderPreferenceFileBrowse, - importOrderManualExample, importOrderLabel, importOrderPreferenceFileExample, - importOrderConfigurationFromFileRadioButton, importOrderConfigurationManualRadioButton }, + importOrderConfigurationManualRadioButton, useEclipseNewest, useEclipseCustom, + formatSelectedTextInAllFileTypes, useForLiveTemplates, importOrdering451, importOrdering452}, useEclipseFormatter); + + enabledBy(new JComponent[]{pathToEclipsePreferenceFileJava, schemeEclipseJC, + schemeEclipse, schemeCurrentProject, + schemeEclipse21, + schemeEclipseFile, eclipsePrefsExample, eclipsePreferenceFileJavaLabel, optimizeImportsCheckBox, + eclipsePreferenceFilePathJavaBrowse, javaFormatterProfileLabel, javaFormatterProfile, customEclipseLocationBrowse, pathToCustomEclipse, + useEclipseNewest, useEclipseCustom, javaFormatterVersionLabel, importStyleLabel, + importOrdering451, importOrdering452}, enableJavaFormatting); + + enabledBy(new JComponent[]{importOrder, pathToImportOrderPreferenceFile, pathToImportOrderPreferenceFileBrowse, importOrderManualExample, + importOrderPreferenceFileExample, importOrderConfigurationFromFileRadioButton, importOrderConfigurationManualRadioButton}, optimizeImportsCheckBox); - enabledBy(new JComponent[] { pathToImportOrderPreferenceFile, importOrderPreferenceFileExample, - pathToImportOrderPreferenceFileBrowse }, importOrderConfigurationFromFileRadioButton); + enabledBy(new JComponent[]{pathToImportOrderPreferenceFile, importOrderPreferenceFileExample, pathToImportOrderPreferenceFileBrowse}, + importOrderConfigurationFromFileRadioButton); - enabledBy(new JComponent[] { importOrder, importOrderManualExample, }, - importOrderConfigurationManualRadioButton); + enabledBy(new JComponent[]{importOrder, importOrderManualExample,}, importOrderConfigurationManualRadioButton); - enabledByAny(new JComponent[] { pathToEclipsePreferenceFileJS, formatterProfileLabelJS, formatterProfileJS, - eclipsePrefsExampleJS, eclipsePreferenceFileJSLabel, eclipsePreferenceFilePathJSBrowse, - enableJavaScriptCommentsPostProcessor }, enableJSFormatting, enableGWTNativeMethodsCheckBox); - enabledByAny( - new JComponent[] { pathToEclipsePreferenceFileCpp, formatterProfileLabelCpp, formatterProfileCpp, - eclipsePrefsExampleCpp, eclipsePreferenceFileCppLabel, eclipsePreferenceFilePathCppBrowse }, - enableCppFormatting); + enabledBy(new JComponent[]{disabledFileTypes, disabledFileTypesHelpLabel,}, formatOtherFilesWithExceptionsRadioButton); - enabledBy(new JComponent[] { disabledFileTypes, disabledFileTypesHelpLabel, }, - formatOtherFilesWithExceptionsRadioButton); + enabledBy(new JComponent[]{pathToEclipsePreferenceFileJava, eclipsePreferenceFilePathJavaBrowse, javaFormatterProfile, eclipsePrefsExample, javaFormatterProfileLabel}, schemeEclipseFile); disableJavaProfilesIfNecessary(); - disableJavaScriptProfilesIfNecessary(); - disableCppProfilesIfNecessary(); delete.setEnabled(!displayedSettings.isProjectSpecific()); rename.setEnabled(!displayedSettings.isProjectSpecific()); exportToProjectProfile.setEnabled(!displayedSettings.isProjectSpecific()); + backupToProjectCheckBox.setEnabled(!displayedSettings.isProjectSpecific()); + setJavaFormatterProfileModel(); + } - private void enabledByAny(@NotNull JComponent[] targets, @NotNull JToggleButton[] negated, - @NotNull JToggleButton... control) { + private void enabledByAny(@NotNull JComponent[] targets, @NotNull JToggleButton[] negated, @NotNull JToggleButton... control) { boolean b = false; for (JToggleButton jToggleButton : control) { @@ -215,29 +193,15 @@ private void enabledByAny(@NotNull JComponent[] targets, @NotNull JToggleButton[ private void disableJavaProfilesIfNecessary() { String text = pathToEclipsePreferenceFileJava.getText(); - if (!text.endsWith("xml")) { + if (!text.toLowerCase().endsWith("xml")) { javaFormatterProfile.setEnabled(false); } } - private void disableJavaScriptProfilesIfNecessary() { - String text = pathToEclipsePreferenceFileJS.getText(); - if (!text.endsWith("xml")) { - formatterProfileJS.setEnabled(false); - } - } - - private void disableCppProfilesIfNecessary() { - String text = pathToEclipsePreferenceFileCpp.getText(); - if (!text.endsWith("xml")) { - formatterProfileCpp.setEnabled(false); - } - } public ProjectSettingsForm(final Project project, MyConfigurable myConfigurable) { + Donate.initDonateButton(donateButton); this.myConfigurable = myConfigurable; - DONATEButton.setBorder(BorderFactory.createEmptyBorder()); - DONATEButton.setContentAreaFilled(false); this.project = project; for (Field field : ProjectSettingsForm.class.getDeclaredFields()) { try { @@ -268,34 +232,19 @@ protected void textChanged(DocumentEvent e) { eclipsePreferenceFilePathJavaBrowse.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - browseForFile(pathToEclipsePreferenceFileJava, createSingleFileNoJarsDescriptor(), - "Select config file"); + browseForFile(pathToEclipsePreferenceFileJava, createSingleFileOrFolderDescriptor(), "Select Eclipse workspace/project/config file"); } }); pathToImportOrderPreferenceFileBrowse.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - browseForFile(pathToImportOrderPreferenceFile, createSingleFileNoJarsDescriptor(), - "Select config file"); - } - }); - eclipsePreferenceFilePathJSBrowse.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - browseForFile(pathToEclipsePreferenceFileJS, createSingleFileNoJarsDescriptor(), "Select config file"); - } - }); - eclipsePreferenceFilePathCppBrowse.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - browseForFile(pathToEclipsePreferenceFileCpp, createSingleFileNoJarsDescriptor(), "Select config file"); + browseForFile(pathToImportOrderPreferenceFile, createSingleFileNoJarsDescriptor(), "Select config file"); } }); customEclipseLocationBrowse.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { browseForFile(pathToCustomEclipse, createSingleFolderDescriptor(), "Select Eclipse location"); - useEclipseCustom.setSelected(true); } }); @@ -324,44 +273,29 @@ protected void textChanged(DocumentEvent e) { } }); - pathToEclipsePreferenceFileJS.getDocument().addDocumentListener(new DocumentAdapter() { - @Override - protected void textChanged(DocumentEvent e) { - setJavaScriptFormatterProfileModel(); - } - }); - - pathToEclipsePreferenceFileCpp.getDocument().addDocumentListener(new DocumentAdapter() { - @Override - protected void textChanged(DocumentEvent e) { - setCppFormatterProfileModel(); - } - }); - newProfile.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (isModified(displayedSettings)) { - createConfirmation("Profile was modified, save changes to the current profile?", "Yes", "No", - new Runnable() { - @Override - public void run() { - try { - apply(); - createProfile(); - } catch (ConfigurationException e) { - Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, - e.getMessage(), e.getTitle(), Messages.getErrorIcon()); - } - } - }, new Runnable() { - @Override - public void run() { - importFrom(displayedSettings); - createProfile(); - } - }, 0).showInFocusCenter(); + createConfirmation("Profile was modified, save changes to the current profile?", "Yes", "No", new Runnable() { + @Override + public void run() { + try { + apply(); + createProfile(); + } catch (ConfigurationException e) { + SwingUtilities.invokeLater(() -> Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, e.getMessage(), + e.getTitle(), Messages.getErrorIcon())); + } + } + }, new Runnable() { + @Override + public void run() { + importFrom(displayedSettings); + createProfile(); + } + }, 0).showInFocusCenter(); } else { createProfile(); } @@ -377,25 +311,23 @@ private void createProfile() { @Override public void actionPerformed(ActionEvent e) { if (isModified(displayedSettings)) { - ListPopup confirmation = createConfirmation( - "Profile was modified, save changes to the current profile?", "Yes", "No", new Runnable() { - @Override - public void run() { - try { - apply(); - copyProfile(); - } catch (ConfigurationException e) { - Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, - e.getMessage(), e.getTitle(), Messages.getErrorIcon()); - } - } - }, new Runnable() { - @Override - public void run() { - importFrom(displayedSettings); - copyProfile(); - } - }, 0); + ListPopup confirmation = createConfirmation("Profile was modified, save changes to the current profile?", "Yes", "No", new Runnable() { + @Override + public void run() { + try { + apply(); + copyProfile(); + } catch (ConfigurationException e) { + SwingUtilities.invokeLater(() -> Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, e.getMessage(), e.getTitle(), Messages.getErrorIcon())); + } + } + }, new Runnable() { + @Override + public void run() { + importFrom(displayedSettings); + copyProfile(); + } + }, 0); confirmation.showInFocusCenter(); } else { @@ -413,24 +345,22 @@ private void copyProfile() { @Override public void actionPerformed(ActionEvent e) { if (isModified(displayedSettings)) { - ListPopup confirmation = createConfirmation( - "Profile was modified, save changes to the current profile?", "Yes", "No", new Runnable() { - @Override - public void run() { - try { - apply(); - exportProfile(); - } catch (ConfigurationException e) { - Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, - e.getMessage(), e.getTitle(), Messages.getErrorIcon()); - } - } - }, new Runnable() { - @Override - public void run() { - exportProfile(); - } - }, 0); + ListPopup confirmation = createConfirmation("Profile was modified, save changes to the current profile?", "Yes", "No", new Runnable() { + @Override + public void run() { + try { + apply(); + exportProfile(); + } catch (ConfigurationException e) { + SwingUtilities.invokeLater(() -> Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, e.getMessage(), e.getTitle(), Messages.getErrorIcon())); + } + } + }, new Runnable() { + @Override + public void run() { + exportProfile(); + } + }, 0); confirmation.showInFocusCenter(); } else { @@ -444,8 +374,6 @@ private void exportProfile() { } }); setJavaFormatterProfileModel(); - setJavaScriptFormatterProfileModel(); - setCppFormatterProfileModel(); profilesModel = createProfilesModel(); profiles.setModel(profilesModel); @@ -479,15 +407,14 @@ public void actionPerformed(ActionEvent e) { // Damn you're ugly try { apply(); - String s = Messages.showInputDialog(rename, "New profile name:", "Rename profile", - Messages.getQuestionIcon(), displayedSettings.getName(), new NonEmptyInputValidator()); + String s = Messages.showInputDialog(rename, "New profile name:", "Rename profile", Messages.getQuestionIcon(), displayedSettings.getName(), + new NonEmptyInputValidator()); if (s != null) { displayedSettings.setName(s); apply(); } } catch (ConfigurationException e1) { - Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, e1.getMessage(), e1.getTitle(), - Messages.getErrorIcon()); + Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, e1.getMessage(), e1.getTitle(), Messages.getErrorIcon()); } } }); @@ -513,11 +440,11 @@ public void actionPerformed(ActionEvent e) { } }); - DONATEButton.addActionListener(new ActionListener() { + donateButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { BareBonesBrowserLaunch.openURL( - "https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=75YN7U7H7D7XU&lc=CZ&item_name=Eclipse%20code%20formatter%20%2d%20IntelliJ%20plugin%20%2d%20Donation¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHostedGuest"); + "https://www.paypal.me/VojtechKrasa"); } }); helpButton.addActionListener(new ActionListener() { @@ -533,31 +460,12 @@ public void actionPerformed(ActionEvent e) { BareBonesBrowserLaunch.openURL("http://plugins.intellij.net/plugin/?idea&id=6546"); } }); - useEclipse44.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - importOrdering451.setSelected(true); - - } - }); useEclipseNewest.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { importOrdering452.setSelected(true); } }); - profileHelp.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - Messages.showInfoMessage(project, - " profile is not shared between projects. Other profiles are global - shared, synchronized and stored in the IDE." - + "\nChange of a global profile will result in a change in all opened or closed projects using such profile." - + "\nThe selected global profile is also fully persisted within a project, but most of the data is used only as a backup for syncing between different computers." - + "\n\nPaths macros are automatically managed by the IDE. That can result in '$PROJECT_DIR$' being used for a global profile within a project config file," - + "\nbut an absolute path is actually stored and used in the IDE config file.", - "Profiles and persistence explanation"); - } - }); } private void apply() throws ConfigurationException { @@ -569,16 +477,6 @@ private void setJavaFormatterProfileModel() { javaFormatterProfile.setModel(createProfilesModel(pathToEclipsePreferenceFileJava, selectedProfile)); } - private void setJavaScriptFormatterProfileModel() { - String selectedProfile = displayedSettings != null ? displayedSettings.getSelectedJavaScriptProfile() : null; - formatterProfileJS.setModel(createProfilesModel(pathToEclipsePreferenceFileJS, selectedProfile)); - } - - private void setCppFormatterProfileModel() { - String selectedProfile = displayedSettings != null ? displayedSettings.getSelectedCppProfile() : null; - formatterProfileCpp.setModel(createProfilesModel(pathToEclipsePreferenceFileCpp, selectedProfile)); - } - private ComboBoxModel createProfilesModel(JTextField pathToEclipsePreferenceFile, String selectedProfile) { @SuppressWarnings("unchecked") SortedComboBoxModel profilesModel = new SortedComboBoxModel(new Comparator() { @@ -588,19 +486,18 @@ public int compare(String o1, String o2) { } }); String text = pathToEclipsePreferenceFile.getText(); - if (!text.isEmpty()) { - if (text.endsWith("xml")) { - try { - profilesModel.addAll(FileUtils.getProfileNamesFromConfigXML(new File(text))); - } catch (ParsingFailedException e) { - profilesModel.add(PARSING_FAILED); - } - } else { - // not xml - } + if (normalBorder == null) { + this.normalBorder = javaFormatterProfile.getBorder(); + } + if (!text.isEmpty() && schemeEclipseFile.isSelected()) { + ConfigFileLocator configFileLocator = new ConfigFileLocator(); + + configFileLocator.validate(this, profilesModel, text); } else { - // empty + javaFormatterProfile.setEnabled(false); + javaFormatterProfile.setBorder(this.normalBorder); } + List items = profilesModel.getItems(); if (items.size() > 0) { for (String item : items) { @@ -647,8 +544,8 @@ public void run() { apply(); importFrom(getSelectedItem()); } catch (ConfigurationException e) { - Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, e.getMessage(), e.getTitle(), - Messages.getErrorIcon()); + profiles.setSelectedItem(displayedSettings); + SwingUtilities.invokeLater(() -> Messages.showMessageDialog(ProjectSettingsForm.this.rootComponent, e.getMessage(), e.getTitle(), Messages.getErrorIcon())); } } }, new Runnable() { @@ -675,8 +572,7 @@ private boolean browseForFile(@NotNull final JTextField target, FileChooserDescr descriptor.setTitle(title); String text = target.getText(); - final VirtualFile toSelect = text == null || text.isEmpty() ? getProject().getBaseDir() - : LocalFileSystem.getInstance().findFileByPath(text); + final VirtualFile toSelect = text == null || text.isEmpty() ? getProject().getBaseDir() : LocalFileSystem.getInstance().findFileByPath(text); // 10.5 does not have #chooseFile VirtualFile[] virtualFile = FileChooser.chooseFiles(descriptor, getProject(), toSelect); @@ -737,18 +633,23 @@ private void importFromInternal(Settings in) { displayedSettings = in; formatOtherFilesWithExceptionsRadioButton.setSelected(in.isFormatOtherFileTypesWithIntelliJ()); doNotFormatOtherFilesRadioButton.setSelected(!in.isFormatOtherFileTypesWithIntelliJ()); - useDefaultFormatter.setSelected(in.getFormatter().equals(Settings.Formatter.DEFAULT)); - useEclipseFormatter.setSelected(in.getFormatter().equals(Settings.Formatter.ECLIPSE)); - useEclipse44.setSelected(in.getEclipseVersion().equals(Settings.FormatterVersion.ECLIPSE_44)); - useEclipseNewest.setSelected(in.getEclipseVersion().equals(Settings.FormatterVersion.NEWEST)); - useEclipseCustom.setSelected(in.getEclipseVersion().equals(Settings.FormatterVersion.CUSTOM)); - importOrdering451.setSelected(in.getImportOrdering().equals(Settings.ImportOrdering.ECLIPSE_44)); - importOrdering452.setSelected(in.getImportOrdering().equals(Settings.ImportOrdering.ECLIPSE_452)); + useDefaultFormatter.setSelected(Objects.equals(in.getFormatter(), Settings.Formatter.DEFAULT)); + useEclipseFormatter.setSelected(Objects.equals(in.getFormatter(), Settings.Formatter.ECLIPSE)); + useEclipseNewest.setSelected(Objects.equals(in.getEclipseVersion(), Settings.FormatterVersion.NEWEST)); + useEclipseCustom.setSelected(Objects.equals(in.getEclipseVersion(), Settings.FormatterVersion.CUSTOM)); + importOrdering451.setSelected(Objects.equals(in.getImportOrdering(), Settings.ImportOrdering.ECLIPSE_44)); + importOrdering452.setSelected(Objects.equals(in.getImportOrdering(), Settings.ImportOrdering.ECLIPSE_452)); importOrderConfigurationFromFileRadioButton.setSelected(in.isImportOrderFromFile()); importOrderConfigurationManualRadioButton.setSelected(!in.isImportOrderFromFile()); javaFormatterProfile.setSelectedItem(in.getSelectedJavaProfile()); - formatterProfileJS.setSelectedItem(in.getSelectedJavaScriptProfile()); - formatterProfileCpp.setSelectedItem(in.getSelectedCppProfile()); + + schemeEclipse.setSelected(Objects.equals(Settings.ConfigType.ECLIPSE, in.getConfigType())); + schemeCurrentProject.setSelected(Objects.equals(Settings.ConfigType.RESOLVE, in.getConfigType())); + schemeEclipse21.setSelected(Objects.equals(Settings.ConfigType.ECLIPSE_2_1, in.getConfigType())); + schemeEclipseJC.setSelected(Objects.equals(in.getConfigType(), Settings.ConfigType.JAVA_CONVENTIONS)); + schemeEclipseFile.setSelected(Objects.equals(in.getConfigType(), Settings.ConfigType.CUSTOM)); + + setData(in); updateComponents(); } @@ -764,46 +665,53 @@ public Settings exportDisplayedSettings() { } else if (importOrdering452.isSelected()) { displayedSettings.setImportOrdering(Settings.ImportOrdering.ECLIPSE_452); } - if (useEclipse44.isSelected()) { - displayedSettings.setEclipseVersion(Settings.FormatterVersion.ECLIPSE_44); - } else if (useEclipseNewest.isSelected()) { + if (useEclipseNewest.isSelected()) { displayedSettings.setEclipseVersion(Settings.FormatterVersion.NEWEST); } else if (useEclipseCustom.isSelected()) { displayedSettings.setEclipseVersion(Settings.FormatterVersion.CUSTOM); } + if (schemeEclipse.isSelected()) { + displayedSettings.setConfigType(Settings.ConfigType.ECLIPSE); + } else if (schemeEclipse21.isSelected()) { + displayedSettings.setConfigType(Settings.ConfigType.ECLIPSE_2_1); + } else if (schemeEclipseJC.isSelected()) { + displayedSettings.setConfigType(Settings.ConfigType.JAVA_CONVENTIONS); + } else if (schemeEclipseFile.isSelected()) { + displayedSettings.setConfigType(Settings.ConfigType.CUSTOM); + } else if (schemeCurrentProject.isSelected()) { + displayedSettings.setConfigType(Settings.ConfigType.RESOLVE); + } + + displayedSettings.setFormatOtherFileTypesWithIntelliJ(formatOtherFilesWithExceptionsRadioButton.isSelected()); displayedSettings.setImportOrderFromFile(importOrderConfigurationFromFileRadioButton.isSelected()); displayedSettings.setSelectedJavaProfile(profileCheck(javaFormatterProfile.getSelectedItem())); - displayedSettings.setSelectedJavaScriptProfile(profileCheck(formatterProfileJS.getSelectedItem())); - displayedSettings.setSelectedCppProfile(profileCheck(formatterProfileCpp.getSelectedItem())); + + getData(displayedSettings); return displayedSettings; } private String profileCheck(final Object selectedItem) { final String selectedItem1 = (String) selectedItem; - if (PARSING_FAILED.equals(selectedItem1)) { + if (isErrorProfile(selectedItem1)) { return null; } return selectedItem1; } + private boolean isErrorProfile(String selectedItem1) { + return ProjectSettingsForm.ERROR_BORDER.equals(javaFormatterProfile.getBorder()) || NOT_EXISTS.equals(selectedItem1) || PARSING_FAILED.equals(selectedItem1) || CONTAINS_NO_PROFILES.equals(selectedItem1); + } + public void validate() throws ConfigurationException { if (pathToEclipsePreferenceFileJava.isEnabled()) { if (StringUtils.isBlank(pathToEclipsePreferenceFileJava.getText())) { throw new ConfigurationException("Path to Java config file is not valid"); } if (!new File(pathToEclipsePreferenceFileJava.getText()).exists()) { - throw new ConfigurationException("Path to Java config file is not valid - file does not exist"); - } - } - if (pathToEclipsePreferenceFileJS.isEnabled()) { - if (StringUtils.isBlank(pathToEclipsePreferenceFileJS.getText())) { - throw new ConfigurationException("Path to JS config file is not valid"); - } - if (!new File(pathToEclipsePreferenceFileJS.getText()).exists()) { - throw new ConfigurationException("Path to JS config file is not valid - file does not exist"); + throw new ConfigurationException("Path to Java config file is not valid - the file does not exist"); } } if (pathToImportOrderPreferenceFile.isEnabled()) { @@ -811,50 +719,61 @@ public void validate() throws ConfigurationException { throw new ConfigurationException("Path to Import Order file is not valid"); } if (!new File(pathToImportOrderPreferenceFile.getText()).exists()) { - throw new ConfigurationException("Path to Import Order file is not valid - file does not exist"); + throw new ConfigurationException("Path to Import Order file is not valid - the file does not exist"); } } - if (pathToCustomEclipse.isEnabled()) { + if (pathToCustomEclipse.isEnabled() && useEclipseCustom.isSelected()) { if (StringUtils.isBlank(pathToCustomEclipse.getText())) { - throw new ConfigurationException("Path to custom Eclipse folder is not valid"); + throw new ConfigurationException("Path to 'Eclipse installation folder' is not valid"); } if (!new File(pathToCustomEclipse.getText()).exists()) { - throw new ConfigurationException("Path to custom Eclipse folder is not valid - folder does not exist"); + throw new ConfigurationException("Path to 'Eclipse installation folder' is not valid - folder does not exist"); } } } private boolean customIsModified(Settings data) { - if (!ObjectUtils.equals(javaFormatterProfile.getSelectedItem(), data.getSelectedJavaProfile())) { + if (javaFormatterProfile.isEnabled() + && !ObjectUtils.equals(javaFormatterProfile.getSelectedItem(), data.getSelectedJavaProfile()) + && !isErrorProfile(data.getSelectedJavaProfile())) { + return true; + } + if (useDefaultFormatter.isSelected() != Settings.Formatter.DEFAULT.equals(data.getFormatter())) { + return true; + } + if (useEclipseFormatter.isSelected() != Settings.Formatter.ECLIPSE.equals(data.getFormatter())) { return true; } - if (!ObjectUtils.equals(formatterProfileJS.getSelectedItem(), data.getSelectedJavaScriptProfile())) { + if (useEclipseNewest.isSelected() != Settings.FormatterVersion.NEWEST.equals(data.getEclipseVersion())) { return true; } - if (!ObjectUtils.equals(formatterProfileCpp.getSelectedItem(), data.getSelectedCppProfile())) { + if (useEclipseCustom.isSelected() != Settings.FormatterVersion.CUSTOM.equals(data.getEclipseVersion())) { return true; } - if (useDefaultFormatter.isSelected() != data.getFormatter().equals(Settings.Formatter.DEFAULT)) { + if (importOrdering451.isSelected() != Settings.ImportOrdering.ECLIPSE_44.equals(data.getImportOrdering())) { return true; } - if (useEclipseFormatter.isSelected() != data.getFormatter().equals(Settings.Formatter.ECLIPSE)) { + if (importOrdering452.isSelected() != Settings.ImportOrdering.ECLIPSE_452.equals(data.getImportOrdering())) { return true; } - if (useEclipse44.isSelected() != data.getEclipseVersion().equals(Settings.FormatterVersion.ECLIPSE_44)) { + + if (schemeCurrentProject.isSelected() != Settings.ConfigType.RESOLVE.equals(data.getConfigType())) { return true; } - if (useEclipseNewest.isSelected() != data.getEclipseVersion().equals(Settings.FormatterVersion.NEWEST)) { + if (schemeEclipse.isSelected() != Settings.ConfigType.ECLIPSE.equals(data.getConfigType())) { return true; } - if (useEclipseCustom.isSelected() != data.getEclipseVersion().equals(Settings.FormatterVersion.CUSTOM)) { + if (schemeEclipseFile.isSelected() != Settings.ConfigType.CUSTOM.equals(data.getConfigType())) { return true; } - if (importOrdering451.isSelected() != data.getImportOrdering().equals(Settings.ImportOrdering.ECLIPSE_44)) { + if (schemeEclipseJC.isSelected() != Settings.ConfigType.JAVA_CONVENTIONS.equals(data.getConfigType())) { return true; } - if (importOrdering452.isSelected() != data.getImportOrdering().equals(Settings.ImportOrdering.ECLIPSE_452)) { + if (schemeEclipse21.isSelected() != Settings.ConfigType.ECLIPSE_2_1.equals(data.getConfigType())) { return true; } + + if (formatOtherFilesWithExceptionsRadioButton.isSelected() != data.isFormatOtherFileTypesWithIntelliJ()) { return true; } @@ -871,10 +790,9 @@ public Settings getDisplayedSettings() { return displayedSettings; } - public ListPopup createConfirmation(String title, final String yesText, String noText, final Runnable onYes, - final Runnable onNo, int defaultOptionIndex) { + public ListPopup createConfirmation(String title, final String yesText, String noText, final Runnable onYes, final Runnable onNo, int defaultOptionIndex) { - final BaseListPopupStep step = new BaseListPopupStep(title, new String[] { yesText, noText }) { + final BaseListPopupStep step = new BaseListPopupStep(title, new String[]{yesText, noText}) { @Override public PopupStep onChosen(String selectedValue, final boolean finalChoice) { if (selectedValue.equals(yesText)) { @@ -908,36 +826,24 @@ public void setData(Settings data) { optimizeImportsCheckBox.setSelected(data.isOptimizeImports()); formatSelectedTextInAllFileTypes.setSelected(data.isFormatSeletedTextInAllFileTypes()); pathToEclipsePreferenceFileJava.setText(data.getPathToConfigFileJava()); - pathToEclipsePreferenceFileJS.setText(data.getPathToConfigFileJS()); disabledFileTypes.setText(data.getDisabledFileTypes()); - enableJSFormatting.setSelected(data.isEnableJSFormatting()); enableJavaFormatting.setSelected(data.isEnableJavaFormatting()); importOrder.setText(data.getImportOrder()); pathToImportOrderPreferenceFile.setText(data.getImportOrderConfigFilePath()); - enableJavaScriptCommentsPostProcessor.setSelected(data.isEnableJSProcessor()); useForLiveTemplates.setSelected(data.isUseForLiveTemplates()); - enableCppFormatting.setSelected(data.isEnableCppFormatting()); - pathToEclipsePreferenceFileCpp.setText(data.getPathToConfigFileCpp()); - enableGWTNativeMethodsCheckBox.setSelected(data.isEnableGWT()); - pathToCustomEclipse.setText(data.getPathToEclipse()); + backupToProjectCheckBox.setSelected(data.isBackupToProjectConfigFile()); } public void getData(Settings data) { data.setOptimizeImports(optimizeImportsCheckBox.isSelected()); data.setFormatSeletedTextInAllFileTypes(formatSelectedTextInAllFileTypes.isSelected()); data.setPathToConfigFileJava(pathToEclipsePreferenceFileJava.getText()); - data.setPathToConfigFileJS(pathToEclipsePreferenceFileJS.getText()); data.setDisabledFileTypes(disabledFileTypes.getText()); - data.setEnableJSFormatting(enableJSFormatting.isSelected()); data.setEnableJavaFormatting(enableJavaFormatting.isSelected()); data.setImportOrder(importOrder.getText()); data.setImportOrderConfigFilePath(pathToImportOrderPreferenceFile.getText()); - data.setEnableJSProcessor(enableJavaScriptCommentsPostProcessor.isSelected()); data.setUseForLiveTemplates(useForLiveTemplates.isSelected()); - data.setEnableCppFormatting(enableCppFormatting.isSelected()); - data.setPathToConfigFileCpp(pathToEclipsePreferenceFileCpp.getText()); - data.setEnableGWT(enableGWTNativeMethodsCheckBox.isSelected()); - data.setPathToEclipse(pathToCustomEclipse.getText()); + data.setBackupToProjectConfigFile(backupToProjectCheckBox.isSelected()); } public boolean isModified(Settings data) { @@ -945,47 +851,26 @@ public boolean isModified(Settings data) { if (customIsModified(data)) { return true; } + if (backupToProjectCheckBox.isSelected() != data.isBackupToProjectConfigFile()) + return true; if (optimizeImportsCheckBox.isSelected() != data.isOptimizeImports()) return true; if (formatSelectedTextInAllFileTypes.isSelected() != data.isFormatSeletedTextInAllFileTypes()) return true; - if (pathToEclipsePreferenceFileJava.getText() != null - ? !pathToEclipsePreferenceFileJava.getText().equals(data.getPathToConfigFileJava()) + if (pathToEclipsePreferenceFileJava.getText() != null ? !pathToEclipsePreferenceFileJava.getText().equals(data.getPathToConfigFileJava()) : data.getPathToConfigFileJava() != null) return true; - if (pathToEclipsePreferenceFileJS.getText() != null - ? !pathToEclipsePreferenceFileJS.getText().equals(data.getPathToConfigFileJS()) - : data.getPathToConfigFileJS() != null) - return true; - if (disabledFileTypes.getText() != null ? !disabledFileTypes.getText().equals(data.getDisabledFileTypes()) - : data.getDisabledFileTypes() != null) - return true; - if (enableJSFormatting.isSelected() != data.isEnableJSFormatting()) + if (disabledFileTypes.getText() != null ? !disabledFileTypes.getText().equals(data.getDisabledFileTypes()) : data.getDisabledFileTypes() != null) return true; if (enableJavaFormatting.isSelected() != data.isEnableJavaFormatting()) return true; - if (importOrder.getText() != null ? !importOrder.getText().equals(data.getImportOrder()) - : data.getImportOrder() != null) + if (importOrder.getText() != null ? !importOrder.getText().equals(data.getImportOrder()) : data.getImportOrder() != null) return true; - if (pathToImportOrderPreferenceFile.getText() != null - ? !pathToImportOrderPreferenceFile.getText().equals(data.getImportOrderConfigFilePath()) + if (pathToImportOrderPreferenceFile.getText() != null ? !pathToImportOrderPreferenceFile.getText().equals(data.getImportOrderConfigFilePath()) : data.getImportOrderConfigFilePath() != null) return true; - if (enableJavaScriptCommentsPostProcessor.isSelected() != data.isEnableJSProcessor()) - return true; if (useForLiveTemplates.isSelected() != data.isUseForLiveTemplates()) return true; - if (enableCppFormatting.isSelected() != data.isEnableCppFormatting()) - return true; - if (pathToEclipsePreferenceFileCpp.getText() != null - ? !pathToEclipsePreferenceFileCpp.getText().equals(data.getPathToConfigFileCpp()) - : data.getPathToConfigFileCpp() != null) - return true; - if (enableGWTNativeMethodsCheckBox.isSelected() != data.isEnableGWT()) - return true; - if (pathToCustomEclipse.getText() != null ? !pathToCustomEclipse.getText().equals(data.getPathToEclipse()) - : data.getPathToEclipse() != null) - return true; return false; } } diff --git a/src/java/krasa/formatter/plugin/ProxyCodeStyleManagerDelegator.java b/src/main/java/krasa/formatter/plugin/ProxyCodeStyleManagerDelegator.java similarity index 67% rename from src/java/krasa/formatter/plugin/ProxyCodeStyleManagerDelegator.java rename to src/main/java/krasa/formatter/plugin/ProxyCodeStyleManagerDelegator.java index 20d9fa8..132bcda 100644 --- a/src/java/krasa/formatter/plugin/ProxyCodeStyleManagerDelegator.java +++ b/src/main/java/krasa/formatter/plugin/ProxyCodeStyleManagerDelegator.java @@ -1,26 +1,25 @@ package krasa.formatter.plugin; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.codeStyle.CodeStyleManager; +import net.sf.cglib.proxy.InvocationHandler; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashSet; import java.util.Set; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.codeStyle.CodeStyleManager; - -import net.sf.cglib.proxy.InvocationHandler; - public class ProxyCodeStyleManagerDelegator implements InvocationHandler { private static final Logger log = Logger.getInstance(ProxyCodeStyleManagerDelegator.class.getName()); - private final CodeStyleManager delegatedObject; + private final CodeStyleManager original; private final EclipseCodeStyleManager overridingObject; private final Set notOverriddenMethods = new HashSet(); - public ProxyCodeStyleManagerDelegator(CodeStyleManager delegatedObject, EclipseCodeStyleManager overridingObject) { - this.delegatedObject = delegatedObject; - this.overridingObject = overridingObject; + public ProxyCodeStyleManagerDelegator(CodeStyleManager original, EclipseCodeStyleManager overriding) { + this.original = original; + this.overridingObject = overriding; } @Override @@ -32,7 +31,9 @@ public Object invoke(Object proxy, Method method, Object[] rawArguments) throws Method overridingMethod = getOverridingMethod(method); if (!compatibleReturnTypes(method.getReturnType(), overridingMethod.getReturnType())) { - overridingMethodHasWrongReturnType(method, overridingMethod, proxy, overridingObject); + log.error("IntelliJ API changed, install proper/updated version of Eclipse Formatter plugin. " + "Incompatible return types when calling: " + method + + " on: " + proxy.getClass().getSimpleName() + " return type should be: " + method.getReturnType().getSimpleName() + ", but was: " + + overridingMethod.getReturnType().getSimpleName() + " (delegate instance had type: " + ((Object) overridingObject).getClass().getSimpleName() + ")"); return PLEASE_REPORT_BUGS_TO_JETBRAINS_IF_IT_FAILS_HERE____ORIGINAL_INTELLIJ_FORMATTER_WAS_USED(method, rawArguments); } if (log.isDebugEnabled()) { @@ -56,24 +57,18 @@ public Object invoke(Object proxy, Method method, Object[] rawArguments) throws private Object PLEASE_REPORT_BUGS_TO_JETBRAINS_IF_IT_FAILS_HERE____ORIGINAL_INTELLIJ_FORMATTER_WAS_USED(Method invokedMethod, Object[] rawArguments) throws Throwable { try { - return invokedMethod.invoke(delegatedObject, rawArguments); + return invokedMethod.invoke(original, rawArguments); } catch (InvocationTargetException e) { throw e.getCause(); } } - public void overridingMethodHasWrongReturnType(Method mockMethod, Method overridingMethod, Object mock, Object overridingObject) { - log.error("IntelliJ API changed, install proper/updated version of Eclipse Formatter plugin. " + "Incompatible return types when calling: " + mockMethod - + " on: " + mock.getClass().getSimpleName() + " return type should be: " + mockMethod.getReturnType().getSimpleName() + ", but was: " - + overridingMethod.getReturnType().getSimpleName() + " (delegate instance had type: " + overridingObject.getClass().getSimpleName() + ")"); - } - private Method getOverridingMethod(Method mockMethod) throws NoSuchMethodException { return overridingObject.getClass().getMethod(mockMethod.getName(), mockMethod.getParameterTypes()); } - private static boolean compatibleReturnTypes(Class superType, Class subType) { - return superType.equals(subType) || superType.isAssignableFrom(subType); + private static boolean compatibleReturnTypes(Class required, Class overriding) { + return required.equals(overriding) || required.isAssignableFrom(overriding); } } diff --git a/src/main/java/krasa/formatter/plugin/ProxyUtils.java b/src/main/java/krasa/formatter/plugin/ProxyUtils.java new file mode 100644 index 0000000..74e3903 --- /dev/null +++ b/src/main/java/krasa/formatter/plugin/ProxyUtils.java @@ -0,0 +1,28 @@ +package krasa.formatter.plugin; + + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.codeStyle.CodeStyleManager; +import org.apache.commons.lang3.ClassUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class ProxyUtils { + private static final Logger LOG = Logger.getInstance(ProxyUtils.class.getName()); + + public static CodeStyleManager createProxy(CodeStyleManager original, EclipseCodeStyleManager overriding) { + return (CodeStyleManager) net.sf.cglib.proxy.Enhancer.create(CodeStyleManager.class, + getInterfaces(original), + new ProxyCodeStyleManagerDelegator(original, overriding)); + } + + @NotNull + private static Class[] getInterfaces(CodeStyleManager manager) { + List> allInterfaces = ClassUtils.getAllInterfaces(manager.getClass()); + LOG.debug("Proxy interfaces " + allInterfaces); + return allInterfaces.toArray(new Class[0]); + } + + +} diff --git a/src/java/krasa/formatter/plugin/Range.java b/src/main/java/krasa/formatter/plugin/Range.java similarity index 100% rename from src/java/krasa/formatter/plugin/Range.java rename to src/main/java/krasa/formatter/plugin/Range.java diff --git a/src/java/krasa/formatter/plugin/ReformatItInIntelliJ.java b/src/main/java/krasa/formatter/plugin/ReformatItInIntelliJ.java similarity index 100% rename from src/java/krasa/formatter/plugin/ReformatItInIntelliJ.java rename to src/main/java/krasa/formatter/plugin/ReformatItInIntelliJ.java diff --git a/src/java/krasa/formatter/processor/Processor.java b/src/main/java/krasa/formatter/processor/Processor.java similarity index 99% rename from src/java/krasa/formatter/processor/Processor.java rename to src/main/java/krasa/formatter/processor/Processor.java index 55b9ee0..48480c1 100644 --- a/src/java/krasa/formatter/processor/Processor.java +++ b/src/main/java/krasa/formatter/processor/Processor.java @@ -1,9 +1,8 @@ package krasa.formatter.processor; -import krasa.formatter.plugin.Range; - import com.intellij.openapi.editor.Document; import com.intellij.psi.PsiFile; +import krasa.formatter.plugin.Range; /** * @author Vojtech Krasa diff --git a/src/java/krasa/formatter/settings/DeletedProfileException.java b/src/main/java/krasa/formatter/settings/DeletedProfileException.java similarity index 100% rename from src/java/krasa/formatter/settings/DeletedProfileException.java rename to src/main/java/krasa/formatter/settings/DeletedProfileException.java diff --git a/src/java/krasa/formatter/settings/DisabledFileTypeSettings.java b/src/main/java/krasa/formatter/settings/DisabledFileTypeSettings.java similarity index 100% rename from src/java/krasa/formatter/settings/DisabledFileTypeSettings.java rename to src/main/java/krasa/formatter/settings/DisabledFileTypeSettings.java diff --git a/src/main/java/krasa/formatter/settings/GlobalProfileReference.java b/src/main/java/krasa/formatter/settings/GlobalProfileReference.java new file mode 100644 index 0000000..cd26787 --- /dev/null +++ b/src/main/java/krasa/formatter/settings/GlobalProfileReference.java @@ -0,0 +1,55 @@ +package krasa.formatter.settings; + +import java.util.Objects; + +public class GlobalProfileReference { + private String name = null; + private Long id = null; + + public GlobalProfileReference() { + } + + public GlobalProfileReference(Long id, String name) { + this.name = name; + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GlobalProfileReference that = (GlobalProfileReference) o; + return Objects.equals(name, that.name) && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return Objects.hash(name, id); + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("GlobalProfileReference{"); + sb.append("id=").append(id); + sb.append(", name='").append(name).append('\''); + sb.append('}'); + return sb.toString(); + } + +} diff --git a/src/main/java/krasa/formatter/settings/GlobalSettings.java b/src/main/java/krasa/formatter/settings/GlobalSettings.java new file mode 100644 index 0000000..c283de0 --- /dev/null +++ b/src/main/java/krasa/formatter/settings/GlobalSettings.java @@ -0,0 +1,224 @@ +package krasa.formatter.settings; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.components.ApplicationComponent; +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.project.Project; +import com.intellij.util.xmlb.XmlSerializerUtil; +import krasa.formatter.plugin.Notifier; +import krasa.formatter.utils.ProjectUtils; +import krasa.formatter.utils.StringUtils; +import org.apache.commons.beanutils.BeanUtils; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.apache.commons.lang3.StringUtils.isBlank; + +/** + * @author Vojtech Krasa + */ +@State(name = "EclipseCodeFormatterSettings", storages = {@Storage("eclipseCodeFormatter.xml")}) +public class GlobalSettings + implements ApplicationComponent, PersistentStateComponent { + private List settingsList = new ArrayList(); + private List deletedSettingsId = new ArrayList(); + private String pathToEclipse = ""; + + public static GlobalSettings getInstance() { + return ApplicationManager.getApplication().getComponent(GlobalSettings.class); + } + + @Override + public GlobalSettings getState() { + return this; + } + + @Override + public void loadState(GlobalSettings state) { + XmlSerializerUtil.copyBean(state, this); + + migrateSettings(); + } + + + public List getSettingsList() { + return settingsList; + } + + public String getPathToEclipse() { + return pathToEclipse; + } + + public void setPathToEclipse(String pathToEclipse) { + this.pathToEclipse = pathToEclipse; + } + + public void setSettingsList(List settingsList) { + this.settingsList = settingsList; + } + + public Settings newSettings() { + String name = StringUtils.generateName(settingsList, 1, "new"); + Settings aNew = new Settings(generateId(), name); + aNew.setBackupToProjectConfigFile(false); + settingsList.add(aNew); + return aNew; + } + + public Settings copySettings(Project project, Settings settings) { + Settings newSettings = clone(settings); + if (settings.isProjectSpecific()) { + newSettings.setName(StringUtils.generateName(settingsList, 1, project.getName(), project.getName())); + } else { + newSettings.setName(settings.getName() + " copy"); + } + newSettings.setId(generateId()); + settingsList.add(newSettings); + return newSettings; + } + + public static Settings clone(Settings settings) { + Settings newSettings = new Settings(); + try { + BeanUtils.copyProperties(newSettings, settings); + } catch (Throwable e) { + throw new RuntimeException(e); + } + return newSettings; + } + + public void updateSettings(Settings settings, Project project) { + if (settings.getId() == null) { + addToGlobalSettings(settings, project); + } else { + for (Settings settings1 : settingsList) { + if (settings1.getId().equals(settings.getId())) { + XmlSerializerUtil.copyBean(settings, settings1); + } + } + } + } + + private void addToGlobalSettings(@NotNull Settings newSettings, @NotNull Project project) { + if (newSettings.getId() == null) { + newSettings.setId(generateId()); + } + if (newSettings.getName() == null) { + String name = StringUtils.generateName(settingsList, 1, project.getName(), project.getName()); + newSettings.setName(name); + } + settingsList.add(newSettings); + } + + private Long generateId() { + long newId = new Date().getTime(); + for (Settings settings : settingsList) { + if (settings.getId().equals(newId)) { + newId = generateId(); + } + } + return newId; + } + + @NotNull + public Settings findGlobalProfile(@NotNull Settings state, @NotNull Project project) throws DeletedProfileException { + if (state.isNotSaved()) { + addToGlobalSettings(state, project); + return state; + } else { + for (Settings settings : settingsList) { + if (settings.getId().equals(state.getId())) { + return settings; + } + } + for (Settings settings : settingsList) { + if (settings.getName().equals(state.getName())) { + return settings; + } + } + if (deletedSettingsId.contains(state.getId())) { + throw new DeletedProfileException(); + } + addToGlobalSettings(state, project); + return state; + } + } + + public Settings findGlobalProfile(GlobalProfileReference globalProfileReference, Project project) throws DeletedProfileException { + for (Settings settings : settingsList) { + if (settings.getId().equals(globalProfileReference.getId())) { + return settings; + } + } + for (Settings settings : settingsList) { + if (settings.getName().equals(globalProfileReference.getName())) { + return settings; + } + } + + if (deletedSettingsId.contains(globalProfileReference.getId())) { + throw new DeletedProfileException(); + } + + return null; + } + + @Override + public void initComponent() { + } + + @Override + public void disposeComponent() { + } + + @NotNull + @Override + public String getComponentName() { + return "EclipseCodeFormatterGlobalSettings"; + } + + + public void delete(Settings settings, Project project) { + settingsList.remove(settings); + deletedSettingsId.add(settings.getId()); + ProjectUtils.notifyProjectsWhichUsesThisSettings(settings, project); + } + + private void migrateSettings() { + if (isBlank(pathToEclipse)) { + for (Settings settings : settingsList) { + pathToEclipse = settings.getPathToEclipse(); + if (!isBlank(pathToEclipse)) { + break; + } + } + } + + for (Settings settings : settingsList) { + settings.setPathToEclipse(""); + } + + } + + public void migrateSettings(ProjectSettings projectSettings) { + if (isBlank(pathToEclipse)) { + Settings selectedProfile = projectSettings.getSelectedProfile(); + pathToEclipse = selectedProfile.getPathToEclipse(); + } + + Settings selectedGlobalProfile = projectSettings.getSelectedGlobalProfile(); + if (selectedGlobalProfile != null) { + selectedGlobalProfile.setPathToEclipse(""); + } + + ProjectSpecificProfile projectSpecificProfile = projectSettings.getProjectSpecificProfile(); + projectSpecificProfile.setPathToEclipse(""); + } + + +} diff --git a/src/java/krasa/formatter/settings/IllegalSettingsException.java b/src/main/java/krasa/formatter/settings/IllegalSettingsException.java similarity index 100% rename from src/java/krasa/formatter/settings/IllegalSettingsException.java rename to src/main/java/krasa/formatter/settings/IllegalSettingsException.java diff --git a/src/java/krasa/formatter/settings/MyConfigurable.java b/src/main/java/krasa/formatter/settings/MyConfigurable.java similarity index 81% rename from src/java/krasa/formatter/settings/MyConfigurable.java rename to src/main/java/krasa/formatter/settings/MyConfigurable.java index bc78f26..8398273 100644 --- a/src/java/krasa/formatter/settings/MyConfigurable.java +++ b/src/main/java/krasa/formatter/settings/MyConfigurable.java @@ -1,20 +1,18 @@ package krasa.formatter.settings; -import javax.swing.*; - -import org.apache.commons.lang.ObjectUtils; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.project.Project; - import krasa.formatter.Messages; import krasa.formatter.plugin.ProjectSettingsForm; import krasa.formatter.utils.ProjectUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; // implements Configurable public class MyConfigurable implements Configurable { @@ -54,8 +52,11 @@ public JComponent createComponent() { @Override public boolean isModified() { - return form != null && (form.isModified(projectSettings.getSelectedProfile()) - || (form.getDisplayedSettings() != null && !isSameId())); + return form != null && + (form.isModified(projectSettings.getSelectedProfile()) + || (form.getDisplayedSettings() != null && !isSameId()) + || (!ObjectUtils.equals(GlobalSettings.getInstance().getPathToEclipse(), form.pathToCustomEclipse.getText())) + ); } private boolean isSameId() { @@ -68,6 +69,8 @@ public void apply() throws ConfigurationException { form.validate(); Settings profile = form.exportDisplayedSettings(); + GlobalSettings.getInstance().setPathToEclipse(form.pathToCustomEclipse.getText()); + projectSettings.setProfile(profile); if (!profile.isProjectSpecific()) { @@ -88,6 +91,7 @@ public void apply() throws ConfigurationException { public void reset() { if (form != null) { form.importFrom(projectSettings.getSelectedProfile()); + form.pathToCustomEclipse.setText(GlobalSettings.getInstance().getPathToEclipse()); } } diff --git a/src/java/krasa/formatter/settings/MyConfigurableProvider.java b/src/main/java/krasa/formatter/settings/MyConfigurableProvider.java similarity index 99% rename from src/java/krasa/formatter/settings/MyConfigurableProvider.java rename to src/main/java/krasa/formatter/settings/MyConfigurableProvider.java index 5c2d487..bceeb19 100644 --- a/src/java/krasa/formatter/settings/MyConfigurableProvider.java +++ b/src/main/java/krasa/formatter/settings/MyConfigurableProvider.java @@ -1,12 +1,11 @@ package krasa.formatter.settings; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurableProvider; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class MyConfigurableProvider extends ConfigurableProvider { private final Project myProject; diff --git a/src/java/krasa/formatter/settings/ProjectComponent.java b/src/main/java/krasa/formatter/settings/ProjectComponent.java similarity index 82% rename from src/java/krasa/formatter/settings/ProjectComponent.java rename to src/main/java/krasa/formatter/settings/ProjectComponent.java index 30e9e3b..e423851 100644 --- a/src/java/krasa/formatter/settings/ProjectComponent.java +++ b/src/main/java/krasa/formatter/settings/ProjectComponent.java @@ -7,16 +7,14 @@ */ -import org.jetbrains.annotations.NotNull; - -import com.intellij.notification.NotificationDisplayType; import com.intellij.notification.NotificationGroup; +import com.intellij.notification.NotificationGroupManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; - import krasa.formatter.plugin.EclipseCodeStyleManager; import krasa.formatter.plugin.ProjectCodeStyleInstaller; +import org.jetbrains.annotations.NotNull; /** * Takes care of initializing a project's CodeFormatter and disposing of it when the project is closed. Updates the @@ -28,10 +26,17 @@ public class ProjectComponent implements com.intellij.openapi.components.ProjectComponent { private static final Logger LOG = Logger.getInstance(ProjectComponent.class.getName()); - public static final NotificationGroup GROUP_DISPLAY_ID_ERROR = new NotificationGroup("Eclipse code formatter error", - NotificationDisplayType.BALLOON, true); - public static final NotificationGroup GROUP_DISPLAY_ID_INFO = new NotificationGroup("Eclipse code formatter info", - NotificationDisplayType.NONE, true); + + @NotNull + public static NotificationGroup getNotificationGroupError() { + return NotificationGroupManager.getInstance().getNotificationGroup("Adapter for Eclipse Code Formatter error"); + } + + @NotNull + public static NotificationGroup getNotificationGroupInfo() { + return NotificationGroupManager.getInstance().getNotificationGroup("Adapter for Eclipse Code Formatter info"); + + } @NotNull private final ProjectCodeStyleInstaller projectCodeStyle; @@ -41,16 +46,20 @@ public class ProjectComponent implements com.intellij.openapi.components.Project private ProjectSettings projectSettings; private EclipseCodeStyleManager eclipseCodeStyleManager; - public ProjectComponent(@NotNull Project project, @NotNull ProjectSettings projectSettings) { + public ProjectComponent(@NotNull Project project) { this.projectCodeStyle = new ProjectCodeStyleInstaller(project); this.project = project; - this.projectSettings = projectSettings; + this.projectSettings = ProjectSettings.getInstance(project); } public static Settings getSettings(PsiFile psiFile) { return getInstance(psiFile.getProject()).getSelectedProfile(); } + public static Settings getSettings(Project project) { + return getInstance(project).getSelectedProfile(); + } + @Override public void initComponent() { } diff --git a/src/main/java/krasa/formatter/settings/ProjectSettings.java b/src/main/java/krasa/formatter/settings/ProjectSettings.java new file mode 100644 index 0000000..6e7ed79 --- /dev/null +++ b/src/main/java/krasa/formatter/settings/ProjectSettings.java @@ -0,0 +1,131 @@ +package krasa.formatter.settings; + +import com.intellij.openapi.components.PersistentStateComponent; +import com.intellij.openapi.components.State; +import com.intellij.openapi.components.Storage; +import com.intellij.openapi.project.Project; +import com.intellij.util.xmlb.XmlSerializerUtil; +import com.intellij.util.xmlb.annotations.Transient; +import krasa.formatter.plugin.Notifier; +import org.jetbrains.annotations.NotNull; + +@State(name = "EclipseCodeFormatterProjectSettings", storages = {@Storage("eclipseCodeFormatter.xml")}) +public class ProjectSettings implements PersistentStateComponent { + + private ProjectSpecificProfile projectSpecificProfile = new ProjectSpecificProfile(); + private Settings selectedGlobalProfile; + private GlobalProfileReference selectedGlobalProfileReference; + @Transient + private transient Project project; + + public ProjectSettings() { + } + + public ProjectSettings(@NotNull Project project) { + this.project = project; + } + + @NotNull + public ProjectSpecificProfile getProjectSpecificProfile() { + return projectSpecificProfile; + } + + public void setProjectSpecificProfile(ProjectSpecificProfile projectSpecificProfile) { + this.projectSpecificProfile = projectSpecificProfile; + } + + public Settings getSelectedGlobalProfile() { + return selectedGlobalProfile; + } + + public void setSelectedGlobalProfile(Settings selectedGlobalProfile) { + this.selectedGlobalProfile = selectedGlobalProfile; + } + + @Override + @NotNull + public ProjectSettings getState() { + if (this.selectedGlobalProfile != null && !this.selectedGlobalProfile.isBackupToProjectConfigFile()) { + ProjectSettings projectSettings = new ProjectSettings(); + projectSettings.projectSpecificProfile = this.projectSpecificProfile; + projectSettings.selectedGlobalProfileReference = new GlobalProfileReference(this.selectedGlobalProfile.getId(), selectedGlobalProfile.getName()); + return projectSettings; + } else { + return this; + } + } + + @Override + public void loadState(ProjectSettings state) { + XmlSerializerUtil.copyBean(state, this); + } + + public static ProjectSettings getInstance(Project project) { + return project.getService(ProjectSettings.class); + } + + public Settings getSelectedProfile() { + Settings selectedGlobalProfile = getSelectedGlobalProfile(); + if (selectedGlobalProfile != null) { + return selectedGlobalProfile; + } + return getProjectSpecificProfile(); + } + + public void setProfile(Settings profile) { + if (profile.isProjectSpecific()) { + this.setProjectSpecificProfile((ProjectSpecificProfile) profile); + this.setSelectedGlobalProfile(null); + this.setSelectedGlobalProfileReference(null); + } else { + this.setSelectedGlobalProfile(profile); + this.setSelectedGlobalProfileReference(null); + } + } + + public void globalProfileUpdated(Settings updatedGlobalProfile) { + final Settings.Formatter formatter = getSelectedProfile().getFormatter(); + setProfile(GlobalSettings.clone(updatedGlobalProfile)); + getSelectedProfile().setFormatter(formatter); + } + + public void projectOpened() { + syncGlobalProfile(); + GlobalSettings.getInstance().migrateSettings(this); + } + + private void syncGlobalProfile() { + Settings selectedGlobalProfile = this.selectedGlobalProfile; + if (selectedGlobalProfile != null) { + Settings.Formatter formatter = selectedGlobalProfile.getFormatter(); + Settings clone = null; + try { + Settings globalProfile = GlobalSettings.getInstance().findGlobalProfile(selectedGlobalProfile, project); + clone = GlobalSettings.clone(globalProfile); + clone.setFormatter(formatter); + } catch (DeletedProfileException e) { + Notifier.notifyDeletedSettings(project); + } + this.selectedGlobalProfile = clone; + } else if (selectedGlobalProfileReference != null) { + try { + Settings globalProfile = GlobalSettings.getInstance().findGlobalProfile(selectedGlobalProfileReference, project); + if (globalProfile != null) { + this.selectedGlobalProfile = GlobalSettings.clone(globalProfile); + } else { + Notifier.notifyProfileDoesNotExist(project); + } + } catch (DeletedProfileException e) { + Notifier.notifyDeletedSettings(project); + } + } + } + + public GlobalProfileReference getSelectedGlobalProfileReference() { + return selectedGlobalProfileReference; + } + + public void setSelectedGlobalProfileReference(GlobalProfileReference selectedGlobalProfileReference) { + this.selectedGlobalProfileReference = selectedGlobalProfileReference; + } +} diff --git a/src/java/krasa/formatter/settings/ProjectSpecificProfile.java b/src/main/java/krasa/formatter/settings/ProjectSpecificProfile.java similarity index 100% rename from src/java/krasa/formatter/settings/ProjectSpecificProfile.java rename to src/main/java/krasa/formatter/settings/ProjectSpecificProfile.java diff --git a/src/java/krasa/formatter/settings/Settings.java b/src/main/java/krasa/formatter/settings/Settings.java similarity index 71% rename from src/java/krasa/formatter/settings/Settings.java rename to src/main/java/krasa/formatter/settings/Settings.java index 130bf78..ff8749c 100644 --- a/src/java/krasa/formatter/settings/Settings.java +++ b/src/main/java/krasa/formatter/settings/Settings.java @@ -9,9 +9,8 @@ package krasa.formatter.settings; import com.intellij.util.xmlb.annotations.Transient; -import krasa.formatter.settings.provider.CppPropertiesProvider; +import krasa.formatter.eclipse.ConfigFileLocator; import krasa.formatter.settings.provider.ImportOrderProvider; -import krasa.formatter.settings.provider.JSPropertiesProvider; import krasa.formatter.settings.provider.JavaPropertiesProvider; import org.jetbrains.annotations.NotNull; @@ -52,10 +51,6 @@ public class Settings { @Transient protected transient JavaPropertiesProvider javaPropertiesProvider; @Transient - protected transient JSPropertiesProvider jsPropertiesProvider; - @Transient - protected transient CppPropertiesProvider cppPropertiesProvider; - @Transient protected transient ImportOrderProvider importOrderProvider; @Transient private transient DisabledFileTypeSettings disabledFileTypeSettings; @@ -68,14 +63,23 @@ public class Settings { private boolean useOldEclipseJavaFormatter = false; private FormatterVersion eclipseVersion = FormatterVersion.NEWEST; private ImportOrdering importOrdering = ImportOrdering.ECLIPSE_452; + private ConfigType configType = ConfigType.CUSTOM; + @Deprecated private String pathToEclipse = ""; + private boolean backupToProjectConfigFile = true; - /** - * NEVER FORGET: add fields to #equalsContent !! - */ public Settings() { } + public ConfigType getConfigType() { + return configType; + } + + public void setConfigType(ConfigType configType) { + this.configType = configType; + } + + @Deprecated public String getPathToEclipse() { return pathToEclipse; } @@ -88,15 +92,15 @@ public void setEclipseVersion(FormatterVersion eclipseVersion) { this.eclipseVersion = eclipseVersion; switch (eclipseVersion) { - case ECLIPSE_44: - useOldEclipseJavaFormatter = true; - break; - case NEWEST: - useOldEclipseJavaFormatter = false; - break; - case CUSTOM: - useOldEclipseJavaFormatter = false; - break; + case ECLIPSE_44: + useOldEclipseJavaFormatter = true; + break; + case NEWEST: + useOldEclipseJavaFormatter = false; + break; + case CUSTOM: + useOldEclipseJavaFormatter = false; + break; } } @@ -111,6 +115,7 @@ public void setImportOrdering(ImportOrdering importOrdering) { } } + @Deprecated public void setPathToEclipse(String pathToEclipse) { this.pathToEclipse = pathToEclipse; } @@ -141,7 +146,6 @@ public String getPathToConfigFileJS() { } public void setPathToConfigFileJS(final String pathToConfigFileJS) { - jsPropertiesProvider = null; this.pathToConfigFileJS = pathToConfigFileJS; } @@ -210,23 +214,10 @@ public void setEnableGWT(final boolean enableGWT) { this.enableGWT = enableGWT; } - public JSPropertiesProvider getJSProperties() { - if (jsPropertiesProvider == null) { - jsPropertiesProvider = new JSPropertiesProvider(this); - } - return jsPropertiesProvider; - } - - public CppPropertiesProvider getCppProperties() { - if (cppPropertiesProvider == null) { - cppPropertiesProvider = new CppPropertiesProvider(this); - } - return cppPropertiesProvider; - } - public JavaPropertiesProvider getJavaProperties() { if (javaPropertiesProvider == null) { - javaPropertiesProvider = new JavaPropertiesProvider(this); + String pathToConfigFileJava = new ConfigFileLocator().resolveConfigFilePath(this.getPathToConfigFileJava()); + javaPropertiesProvider = new JavaPropertiesProvider(pathToConfigFileJava, getSelectedJavaProfile()); } return javaPropertiesProvider; } @@ -251,7 +242,6 @@ public String getSelectedJavaScriptProfile() { } public void setSelectedJavaScriptProfile(String selectedJavaScriptProfile) { - jsPropertiesProvider = null; this.selectedJavaScriptProfile = selectedJavaScriptProfile; } @@ -289,17 +279,14 @@ public boolean isProjectSpecific() { } public static enum FormatterVersion { - ECLIPSE_44, - NEWEST, - CUSTOM + ECLIPSE_44, NEWEST, CUSTOM } public static enum ImportOrdering { /** * not matching imports -> between groups */ - ECLIPSE_44, - @Deprecated + ECLIPSE_44, @Deprecated ECLIPSE_451, /** * not matching imports -> on the end, actually since Eclipse 4.5.1 :( oops @@ -307,14 +294,16 @@ public static enum ImportOrdering { ECLIPSE_452, } + public static enum ConfigType { + RESOLVE, ECLIPSE, ECLIPSE_2_1, JAVA_CONVENTIONS, CUSTOM, + } + public static enum Formatter { - DEFAULT, - ECLIPSE + DEFAULT, ECLIPSE } public static enum Location { - PROJECT, - APPLICATION + PROJECT, APPLICATION } public boolean isFormatSeletedTextInAllFileTypes() { @@ -393,81 +382,10 @@ public void setId(Long id) { this.id = id; } - public boolean equalsContent(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - Settings settings = (Settings) o; - - if (enableJavaFormatting != settings.enableJavaFormatting) - return false; - if (enableJSFormatting != settings.enableJSFormatting) - return false; - if (enableCppFormatting != settings.enableCppFormatting) - return false; - if (optimizeImports != settings.optimizeImports) - return false; - if (useOldEclipseJavaFormatter != settings.useOldEclipseJavaFormatter) - return false; - if (importOrderFromFile != settings.importOrderFromFile) - return false; - if (formatOtherFileTypesWithIntelliJ != settings.formatOtherFileTypesWithIntelliJ) - return false; - if (formatSeletedTextInAllFileTypes != settings.formatSeletedTextInAllFileTypes) - return false; - if (enableGWT != settings.enableGWT) - return false; - if (enableJSProcessor != settings.enableJSProcessor) - return false; - if (useForLiveTemplates != settings.useForLiveTemplates) - return false; - if (useOldEclipseJavaFormatter != settings.useOldEclipseJavaFormatter) - return false; - if (pathToConfigFileJS != null ? !pathToConfigFileJS.equals(settings.pathToConfigFileJS) - : settings.pathToConfigFileJS != null) - return false; - if (pathToConfigFileCpp != null ? !pathToConfigFileCpp.equals(settings.pathToConfigFileCpp) - : settings.pathToConfigFileCpp != null) - return false; - if (formatter != settings.formatter) - return false; - if (!pathToConfigFileJava.equals(settings.pathToConfigFileJava)) - return false; - if (disabledFileTypes != null ? !disabledFileTypes.equals(settings.disabledFileTypes) - : settings.disabledFileTypes != null) - return false; - if (notifyFromTextLenght != null ? !notifyFromTextLenght.equals(settings.notifyFromTextLenght) - : settings.notifyFromTextLenght != null) - return false; - if (importOrder != null ? !importOrder.equals(settings.importOrder) : settings.importOrder != null) - return false; - if (importOrderConfigFilePath != null ? !importOrderConfigFilePath.equals(settings.importOrderConfigFilePath) - : settings.importOrderConfigFilePath != null) - return false; - if (selectedJavaProfile != null ? !selectedJavaProfile.equals(settings.selectedJavaProfile) - : settings.selectedJavaProfile != null) - return false; - if (selectedJavaScriptProfile != null ? !selectedJavaScriptProfile.equals(settings.selectedJavaScriptProfile) - : settings.selectedJavaScriptProfile != null) - return false; - if (selectedCppProfile != null ? !selectedCppProfile.equals(settings.selectedCppProfile) - : settings.selectedCppProfile != null) - return false; - if (eclipseVersion != settings.eclipseVersion) - return false; - if (importOrdering != settings.importOrdering) - return false; - return pathToEclipse != null ? pathToEclipse.equals(settings.pathToEclipse) : settings.pathToEclipse == null; - - } - public boolean isImportOrderFromFile() { return importOrderFromFile; } - public void setImportOrderFromFile(boolean importOrderFromFile) { this.importOrderFromFile = importOrderFromFile; } @@ -500,4 +418,12 @@ public String toString() { sb.append('}'); return sb.toString(); } + + public boolean isBackupToProjectConfigFile() { + return backupToProjectConfigFile; + } + + public void setBackupToProjectConfigFile(boolean backupToProjectConfigFile) { + this.backupToProjectConfigFile = backupToProjectConfigFile; + } } diff --git a/src/java/krasa/formatter/settings/provider/CachedPropertiesProvider.java b/src/main/java/krasa/formatter/settings/provider/CachedPropertiesProvider.java similarity index 79% rename from src/java/krasa/formatter/settings/provider/CachedPropertiesProvider.java rename to src/main/java/krasa/formatter/settings/provider/CachedPropertiesProvider.java index 01fa673..42018d6 100644 --- a/src/java/krasa/formatter/settings/provider/CachedPropertiesProvider.java +++ b/src/main/java/krasa/formatter/settings/provider/CachedPropertiesProvider.java @@ -1,14 +1,14 @@ package krasa.formatter.settings.provider; +import krasa.formatter.common.ModifiableFile; +import krasa.formatter.plugin.InvalidPropertyFile; +import krasa.formatter.utils.FileUtils; + import java.io.File; import java.util.HashMap; import java.util.Map; import java.util.Properties; -import krasa.formatter.common.ModifiableFile; -import krasa.formatter.plugin.InvalidPropertyFile; -import krasa.formatter.utils.FileUtils; - /** * @author Vojtech Krasa */ @@ -53,8 +53,14 @@ protected void trimTrailingWhitespaceFromConfigValues(Properties config) { } protected void validateConfig(Properties config, File file) { - if (config.isEmpty()) { - throw new InvalidPropertyFile(file); + if (config.size() < 100) { + 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); + } + } + + protected void validateEPFConfig(Properties config, File file) { + if (config.size() < 100) { + throw new InvalidPropertyFile("Invalid EPF config!" + " Loaded only " + config.size() + " `org.eclipse.jdt.core.formatter` properties from: " + file.getAbsolutePath() + ", should be 100+.", file); } } diff --git a/src/java/krasa/formatter/settings/provider/CachedProvider.java b/src/main/java/krasa/formatter/settings/provider/CachedProvider.java similarity index 88% rename from src/java/krasa/formatter/settings/provider/CachedProvider.java rename to src/main/java/krasa/formatter/settings/provider/CachedProvider.java index e5eacb9..c72cd94 100644 --- a/src/java/krasa/formatter/settings/provider/CachedProvider.java +++ b/src/main/java/krasa/formatter/settings/provider/CachedProvider.java @@ -1,10 +1,8 @@ package krasa.formatter.settings.provider; -import java.io.File; - import krasa.formatter.common.ModifiableFile; -import org.jetbrains.annotations.Nullable; +import java.io.File; /** * @author Vojtech Krasa @@ -18,12 +16,16 @@ protected CachedProvider(ModifiableFile modifiableFile) { this.modifiableFile = modifiableFile; } + public ModifiableFile getModifiableFile() { + return modifiableFile; + } + protected abstract T readFile(File file); public T get() { if (cachedValue == null || modifiableFile.wasChanged(lastState)) { - saveLastModified(); cachedValue = readFile(modifiableFile); + saveLastModified(); } return cachedValue; } @@ -32,7 +34,7 @@ public ModifiableFile.Monitor getModifiedMonitor() { return modifiableFile.getModifiedMonitor(); } - public boolean wasChanged(@Nullable ModifiableFile.Monitor lastState) { + public boolean wasChanged() { return lastState == null || modifiableFile.wasChanged(lastState); } diff --git a/src/java/krasa/formatter/settings/provider/ImportOrderProvider.java b/src/main/java/krasa/formatter/settings/provider/ImportOrderProvider.java similarity index 91% rename from src/java/krasa/formatter/settings/provider/ImportOrderProvider.java rename to src/main/java/krasa/formatter/settings/provider/ImportOrderProvider.java index 2644e4c..c50d0c4 100644 --- a/src/java/krasa/formatter/settings/provider/ImportOrderProvider.java +++ b/src/main/java/krasa/formatter/settings/provider/ImportOrderProvider.java @@ -29,10 +29,10 @@ protected List readFile(File file) { List order; if (property != null) { order = toList(property); - } else if (property == null && file.getName().endsWith(".prefs")) { + } else if (property == null && file.getName().toLowerCase().endsWith(".prefs")) { throw new ParsingFailedException( "File is missing a property 'org.eclipse.jdt.ui.importorder', see instructions."); - } else if (file.getName().endsWith(".importorder")) { + } else if (file.getName().toLowerCase().endsWith(".importorder")) { order = loadImportOrderFile(properties); } else { throw new ParsingFailedException( @@ -53,5 +53,4 @@ public int compare(String o1, String o2) { } - } diff --git a/src/main/java/krasa/formatter/settings/provider/JavaPropertiesProvider.java b/src/main/java/krasa/formatter/settings/provider/JavaPropertiesProvider.java new file mode 100644 index 0000000..8b09a47 --- /dev/null +++ b/src/main/java/krasa/formatter/settings/provider/JavaPropertiesProvider.java @@ -0,0 +1,65 @@ +package krasa.formatter.settings.provider; + +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.PathUtil; +import krasa.formatter.common.ModifiableFile; +import krasa.formatter.plugin.InvalidPropertyFile; +import krasa.formatter.settings.Settings; +import krasa.formatter.utils.FileUtils; + +import java.io.File; +import java.util.Properties; + +/** + * @author Vojtech Krasa + */ +public class JavaPropertiesProvider extends CachedPropertiesProvider { + protected String profile; + + + public JavaPropertiesProvider(Settings settings) { + this(settings.getPathToConfigFileJava(), settings.getSelectedJavaProfile()); + } + + public JavaPropertiesProvider(String pathToConfigFileJava, String selectedJavaProfile) { + super(new ModifiableFile(pathToConfigFileJava)); + this.profile = selectedJavaProfile; + } + + @Override + protected Properties readFile(File file) throws InvalidPropertyFile { + if (file.getName().toLowerCase().endsWith("xml")) { + return readXmlFile(file, profile); + } else if (file.getName().toLowerCase().endsWith("epf")) { + return readWorkspaceMechanicFile(file); + } else if (file.getName().toLowerCase().equals("org.eclipse.jdt.ui.prefs")) { + return readWorkspaceFile(file); + } else { + // org.eclipse.jdt.core.prefs + return super.readFile(file); + } + } + + private Properties readWorkspaceFile(File file) { + Properties properties = FileUtils.readPropertiesFile(file); + String xml = properties.getProperty("org.eclipse.jdt.ui.formatterprofiles"); + Properties result = FileUtils.readXmlJavaSettingsFile(xml, properties, profile); + trimTrailingWhitespaceFromConfigValues(result); + validateConfig(result, file); + return result; + } + + private Properties readWorkspaceMechanicFile(final File file) { + Properties properties = FileUtils.readPropertiesFile(file); + Properties result = FileUtils.convertEPF(properties, createDefaultConfig()); + validateEPFConfig(result, file); + return result; + } + + public boolean isSameFile(VirtualFile fileB) { + String path = PathUtil.toSystemIndependentName(fileB.getPath()); + String current = getModifiableFile().getSystemIndependentPath(); + return current.equals(path); + } + +} diff --git a/src/java/krasa/formatter/templates/LiveTemplatesProvider.java b/src/main/java/krasa/formatter/templates/LiveTemplatesProvider.java similarity index 100% rename from src/java/krasa/formatter/templates/LiveTemplatesProvider.java rename to src/main/java/krasa/formatter/templates/LiveTemplatesProvider.java diff --git a/src/java/krasa/formatter/utils/FileUtils.java b/src/main/java/krasa/formatter/utils/FileUtils.java similarity index 60% rename from src/java/krasa/formatter/utils/FileUtils.java rename to src/main/java/krasa/formatter/utils/FileUtils.java index 6f34ab7..0041908 100644 --- a/src/java/krasa/formatter/utils/FileUtils.java +++ b/src/main/java/krasa/formatter/utils/FileUtils.java @@ -1,7 +1,6 @@ package krasa.formatter.utils; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; @@ -13,12 +12,15 @@ import krasa.formatter.plugin.InvalidPropertyFile; import org.apache.commons.io.IOUtils; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; import javax.xml.parsers.DocumentBuilderFactory; import java.io.*; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -33,12 +35,12 @@ public class FileUtils { public static boolean isWritable(PsiFile psiFile) { return isWritable(psiFile.getVirtualFile(), psiFile.getProject()); } - + public static boolean isWritable(@NotNull VirtualFile file, @NotNull Project project) { return !ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(file).hasReadonlyFiles(); } - public static boolean isWholeFile(Collection textRanges, String text) { + public static boolean isWholeFile(Collection textRanges, String text) { for (TextRange textRange : textRanges) { if (isWholeFile(textRange.getStartOffset(), textRange.getEndOffset(), text)) { return true; @@ -46,36 +48,25 @@ public static boolean isWholeFile(Collection textRanges, String text) } return false; } - + public static boolean isWholeFile(int startOffset, int endOffset, String text) { return startOffset == 0 && endOffset == text.length(); } - public static boolean isJavaScript(PsiFile psiFile) { - FileType fileType = psiFile.getFileType(); - return StdFileTypes.JS.equals(fileType) || "JavaScript".equals(fileType.getName()); - } - - public static boolean isCpp(PsiFile psiFile) { - String name = psiFile.getFileType().getName(); - return name.equals("C++") || name.equals("C/C++") || name.equals("ObjectiveC") ; // CLion calls it ObjectiveC... wtf - } - public static boolean isJava(PsiFile psiFile) { return StdFileTypes.JAVA.equals(psiFile.getFileType()); } - public static Properties readPropertiesFile(File file, Properties defaultConfig) { + public static Properties readPropertiesFile(@NotNull File file, @Nullable Properties defaultConfig) { if (!file.exists()) { throw new FileDoesNotExistsException(file); - } BufferedInputStream stream = null; final Properties formatterOptions; try { stream = new BufferedInputStream(new FileInputStream(file)); formatterOptions = new Properties(defaultConfig); - String s = IOUtils.toString(stream); + String s = IOUtils.toString(stream, StandardCharsets.UTF_8); StringReader reader = new StringReader(s.replace("=\\#", "=#")); formatterOptions.load(reader); } catch (IOException e) { @@ -91,39 +82,52 @@ public static Properties readPropertiesFile(File file, Properties defaultConfig) return formatterOptions; } - public static Properties readPropertiesFile(File file) { + public static Properties readPropertiesFile(@NotNull File file) { return readPropertiesFile(file, null); } public static Properties readXmlJavaSettingsFile(File file, Properties properties, String profile) { - int defaultSize = properties.size(); if (!file.exists()) { throw new FileDoesNotExistsException(file); } - if (profile == null) { - throw new IllegalStateException("no profile selected, go to settings and select proper settings file"); + try { + return readXmlJavaSettingsFile(org.apache.commons.io.FileUtils.readFileToString(file, "UTF-8"), properties, + profile); + } catch (IOException e) { + throw new RuntimeException(e); } + } + + public static Properties readXmlJavaSettingsFile(String xml, Properties properties, String profile) { + int defaultSize = properties.size(); boolean profileFound = false; - try { // load file profiles - org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file); + try { + + // load file profiles + InputStream is = IOUtils.toInputStream(xml, "UTF-8"); + org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is); doc.getDocumentElement().normalize(); NodeList profiles = doc.getElementsByTagName("profile"); if (profiles.getLength() == 0) { throw new IllegalStateException( - "loading of profile settings failed, file does not contain any profiles"); + "Loading of profile settings failed, the file does not contain any profiles."); + } + if (profiles.getLength() > 1 && profile == null) { + throw new IllegalStateException( + "No Eclipse formatter profile selected, go to settings and properly configure it."); } for (int temp = 0; temp < profiles.getLength(); temp++) { Node profileNode = profiles.item(temp); if (profileNode.getNodeType() == Node.ELEMENT_NODE) { Element profileElement = (Element) profileNode; String name = profileElement.getAttribute("name"); - if (profile.equals(name)) { + if ((profile != null && profile.equals(name)) || profiles.getLength() == 1) { profileFound = true; NodeList childNodes = profileElement.getElementsByTagName("setting"); if (childNodes.getLength() == 0) { throw new IllegalStateException( - "loading of profile settings failed, profile has no settings elements"); + "Loading of profile settings failed, the profile has no settings elements."); } for (int i = 0; i < childNodes.getLength(); i++) { Node item = childNodes.item(i); @@ -137,16 +141,16 @@ public static Properties readXmlJavaSettingsFile(File file, Properties propertie } } } - } catch (Exception e) { - LOG.error("file: " + file.getAbsolutePath() + ", profile: " + profile, e); + if (!profileFound) { + throw new IllegalStateException("profile not found in the xml: " + xml); + } + if (properties.size() == defaultSize) { + throw new IllegalStateException("no properties loaded, something is broken, xml:" + xml); + } + } catch (Throwable e) { + LOG.warn("xml: " + xml + ", profile: " + profile, e); throw new InvalidPropertyFile(e.getMessage(), e); } - if (!profileFound) { - throw new IllegalStateException("profile not found in the file " + file.getAbsolutePath()); - } - if (properties.size() == defaultSize) { - throw new IllegalStateException("no properties loaded, something is broken, file:" + file.getAbsolutePath()); - } return properties; } @@ -154,11 +158,13 @@ public static List getProfileNamesFromConfigXML(File file) throws Parsin List profileNames = new ArrayList(); if (file.exists()) { try { // load file profiles - // delete eclipse dependency to fix java.lang.ClassCastException: - // org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to - // javax.xml.parsers.DocumentBuilderFactory + // delete eclipse dependency to fix java.lang.ClassCastException: + // org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to + // javax.xml.parsers.DocumentBuilderFactory - org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file); + InputSource in = new InputSource(file.toURI().toASCIIString()); + in.setEncoding("UTF-8"); + org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in); doc.getDocumentElement().normalize(); NodeList nList = doc.getElementsByTagName("profile"); @@ -181,4 +187,44 @@ public static List getProfileNamesFromConfigXML(File file) throws Parsin return profileNames; } + public static List getProfileNamesFromConfigXML(InputStream s) throws ParsingFailedException { + List profileNames = new ArrayList(); + try { // load file profiles + // delete eclipse dependency to fix java.lang.ClassCastException: + // org.apache.xerces.jaxp.DocumentBuilderFactoryImpl cannot be cast to + // javax.xml.parsers.DocumentBuilderFactory + + org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(s); + doc.getDocumentElement().normalize(); + + NodeList nList = doc.getElementsByTagName("profile"); + for (int temp = 0; temp < nList.getLength(); temp++) { + Node nNode = nList.item(temp); + if (nNode.getNodeType() == Node.ELEMENT_NODE) { + Element eElement = (Element) nNode; + String name = eElement.getAttribute("name"); + profileNames.add(name); + } + } + } catch (Exception e) { + LOG.info(e); + throw new ParsingFailedException(e); + } + + return profileNames; + } + + @NotNull + public static Properties convertEPF(Properties properties, Properties defaultConfig) { + int beginIndex = "/instance/org.eclipse.jdt.core/".length(); + Properties result = new Properties(defaultConfig); + for (Object object : properties.keySet()) { + String key = (String) object; + if (key.startsWith("/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter")) { + String value = properties.getProperty(key); + result.put(key.substring(beginIndex), value); + } + } + return result; + } } diff --git a/src/java/krasa/formatter/utils/ProjectUtils.java b/src/main/java/krasa/formatter/utils/ProjectUtils.java similarity index 85% rename from src/java/krasa/formatter/utils/ProjectUtils.java rename to src/main/java/krasa/formatter/utils/ProjectUtils.java index 585c323..c34816f 100644 --- a/src/java/krasa/formatter/utils/ProjectUtils.java +++ b/src/main/java/krasa/formatter/utils/ProjectUtils.java @@ -1,8 +1,7 @@ package krasa.formatter.utils; import com.intellij.openapi.project.Project; -import com.intellij.openapi.project.impl.ProjectManagerImpl; - +import com.intellij.openapi.project.ProjectManager; import krasa.formatter.plugin.Notifier; import krasa.formatter.settings.ProjectComponent; import krasa.formatter.settings.Settings; @@ -13,7 +12,7 @@ public class ProjectUtils { public static void notifyProjectsWhichUsesThisSettings(Settings deletedSettings, Project project) { - Project[] openProjects = ProjectManagerImpl.getInstance().getOpenProjects(); + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); for (Project openProject : openProjects) { ProjectComponent component = openProject.getComponent(ProjectComponent.class); if (component != null) { @@ -29,7 +28,7 @@ public static void notifyProjectsWhichUsesThisSettings(Settings deletedSettings, } public static void applyToAllOpenedProjects(Settings updatedSettings) { - Project[] openProjects = ProjectManagerImpl.getInstance().getOpenProjects(); + Project[] openProjects = ProjectManager.getInstance().getOpenProjects(); for (Project openProject : openProjects) { ProjectComponent component = openProject.getComponent(ProjectComponent.class); if (component != null) { diff --git a/src/java/krasa/formatter/utils/StringUtils.java b/src/main/java/krasa/formatter/utils/StringUtils.java similarity index 100% rename from src/java/krasa/formatter/utils/StringUtils.java rename to src/main/java/krasa/formatter/utils/StringUtils.java diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml new file mode 100644 index 0000000..71a653e --- /dev/null +++ b/src/main/resources/META-INF/plugin.xml @@ -0,0 +1,68 @@ + + + + Adapter for Eclipse Code Formatter + EclipseCodeFormatter + + + Solves the problem of maintaining a common code style in team environments where both IDEA and Eclipse are used. +

+ + Go to https://github.com/krasa/EclipseCodeFormatter#instructions + for instructions how to use it. + +

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

+ Donations | GitHub | Issues + ]]>
+ Formatting + + Vojtech + Krasa + + + + com.intellij.modules.lang + com.intellij.modules.java + + + + krasa.formatter.settings.GlobalSettings + + + + + krasa.formatter.settings.ProjectComponent + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/resources/krasa/formatter/IDEA.png b/src/main/resources/krasa/formatter/IDEA.png new file mode 100644 index 0000000..1f6e511 Binary files /dev/null and b/src/main/resources/krasa/formatter/IDEA.png differ diff --git a/src/main/resources/krasa/formatter/IDEA@2x.png b/src/main/resources/krasa/formatter/IDEA@2x.png new file mode 100644 index 0000000..07ab4ff Binary files /dev/null and b/src/main/resources/krasa/formatter/IDEA@2x.png differ diff --git a/src/main/resources/krasa/formatter/coins_in_hand.png b/src/main/resources/krasa/formatter/coins_in_hand.png new file mode 100644 index 0000000..5044d0b Binary files /dev/null and b/src/main/resources/krasa/formatter/coins_in_hand.png differ diff --git a/src/main/resources/krasa/formatter/coins_in_hand@2x.png b/src/main/resources/krasa/formatter/coins_in_hand@2x.png new file mode 100644 index 0000000..aaceea1 Binary files /dev/null and b/src/main/resources/krasa/formatter/coins_in_hand@2x.png differ diff --git a/src/main/resources/krasa/formatter/donate.png b/src/main/resources/krasa/formatter/donate.png new file mode 100644 index 0000000..20914f3 Binary files /dev/null and b/src/main/resources/krasa/formatter/donate.png differ diff --git a/src/main/resources/krasa/formatter/eclipse.png b/src/main/resources/krasa/formatter/eclipse.png new file mode 100644 index 0000000..48a0009 Binary files /dev/null and b/src/main/resources/krasa/formatter/eclipse.png differ diff --git a/src/resources/krasa/formatter/eclipse@2x.gif b/src/main/resources/krasa/formatter/eclipse@2x.png similarity index 100% rename from src/resources/krasa/formatter/eclipse@2x.gif rename to src/main/resources/krasa/formatter/eclipse@2x.png diff --git a/src/main/resources/krasa/formatter/help.png b/src/main/resources/krasa/formatter/help.png new file mode 100644 index 0000000..d6d15ab Binary files /dev/null and b/src/main/resources/krasa/formatter/help.png differ diff --git a/src/main/resources/krasa/formatter/help@2x.png b/src/main/resources/krasa/formatter/help@2x.png new file mode 100644 index 0000000..fef9b64 Binary files /dev/null and b/src/main/resources/krasa/formatter/help@2x.png differ diff --git a/src/resources/krasa/formatter/messages.properties b/src/main/resources/krasa/formatter/messages.properties similarity index 59% rename from src/resources/krasa/formatter/messages.properties rename to src/main/resources/krasa/formatter/messages.properties index 7e7ee25..5abe43d 100644 --- a/src/resources/krasa/formatter/messages.properties +++ b/src/main/resources/krasa/formatter/messages.properties @@ -1,9 +1,8 @@ action.pluginSettings=Eclipse\nCode Formatter action.browse=Browse... -settings.useEclipse=Use the Eclipse code formatter +settings.useEclipse=Use the Adapter for Eclipse Code Formatter settings.useDefault=Disabled settings.eclipseSupportedFileTypes=Supported file types\: -settings.eclipsePrefs=Eclipse Java Formatter config file settings.eclipsePrefsExample=Example: ...\\project\\.settings\\org.eclipse.jdt.core.prefs or ...\\exportedProfiles.xml or ...\\workspaceMechanic.epf error.errorInField=Error in the "{0}" field: {1} settings.optimizeImports=Optimize Imports (IntelliJ's Import Optimizing must be turned ON) @@ -11,16 +10,9 @@ settings.disableFileTypesHelp=Example\: html; groovy; css; settings.disableFileTypesFormattingCheckbox=Format other file types by IntelliJ with this exception\: settings.formatOtherFileTypesByIntellij=Do not format other file types by IntelliJ formatter settings.formatAllFilesPartial=Format selected text in all file types -settings.eclipsePrefs.js=Eclipse JavaScript Formatter config file -settings.eclipsePrefsExampleJS=Example\: ...\\project\\.settings\\org.eclipse.wst.jdt.core.prefs or ...\\exportedProfiles.xml settings.enableJava=Enable Java -settings.enableJS=Enable JavaScript -settings.importOrder=Import order settings.importOrder.help=Example: \\#org;\\#java;java;javax;org;com;;\\# settings.eclipsePrefsExample2=Example\: ...\\project\\.settings\\org.eclipse.jdt.ui.prefs or ..\\*.importorder settings.selectedProfile=Selected profile\: -selectedEclipseJavaFormatterProfile=Java formatter profile -settings.enable.cpp=Enable C/C++ -settings.eclipsePrefs.cpp=Eclipse C/C++ Formatter config file -settings.eclipsePrefsExample.cpp=Example\: ...\\project\\.settings\\org.eclipse.cdt.core.prefs or ...\\exportedProfiles.xml -settings.eclipse.newest=Eclipse 4.7 Oxygen +settings.eclipse.newest=Bundled Eclipse 2024-09 +settings.eclipse.custom=Configured Eclipse installation folder diff --git a/src/resources/liveTemplates/templates.xml b/src/main/resources/liveTemplates/templates.xml similarity index 100% rename from src/resources/liveTemplates/templates.xml rename to src/main/resources/liveTemplates/templates.xml diff --git a/src/resources/krasa/formatter/IDEA.gif b/src/resources/krasa/formatter/IDEA.gif deleted file mode 100644 index 451ed58..0000000 Binary files a/src/resources/krasa/formatter/IDEA.gif and /dev/null differ diff --git a/src/resources/krasa/formatter/IDEA@2x.gif b/src/resources/krasa/formatter/IDEA@2x.gif deleted file mode 100644 index 0daf48a..0000000 Binary files a/src/resources/krasa/formatter/IDEA@2x.gif and /dev/null differ diff --git a/src/resources/krasa/formatter/btn_donate_LG.gif b/src/resources/krasa/formatter/btn_donate_LG.gif deleted file mode 100644 index 43cef69..0000000 Binary files a/src/resources/krasa/formatter/btn_donate_LG.gif and /dev/null differ diff --git a/src/resources/krasa/formatter/eclipse.gif b/src/resources/krasa/formatter/eclipse.gif deleted file mode 100644 index eb7b90c..0000000 Binary files a/src/resources/krasa/formatter/eclipse.gif and /dev/null differ diff --git a/test/java/krasa/easymock/EasyMockTest.java b/src/test/java/krasa/easymock/EasyMockTest.java similarity index 100% rename from test/java/krasa/easymock/EasyMockTest.java rename to src/test/java/krasa/easymock/EasyMockTest.java index 81bf81b..9087622 100644 --- a/test/java/krasa/easymock/EasyMockTest.java +++ b/src/test/java/krasa/easymock/EasyMockTest.java @@ -1,13 +1,13 @@ package krasa.easymock; -import static org.easymock.EasyMock.*; +import org.junit.After; +import org.junit.Before; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; -import org.junit.After; -import org.junit.Before; +import static org.easymock.EasyMock.*; public class EasyMockTest { diff --git a/test/java/krasa/easymock/MockAnnotationUtil.java b/src/test/java/krasa/easymock/MockAnnotationUtil.java similarity index 100% rename from test/java/krasa/easymock/MockAnnotationUtil.java rename to src/test/java/krasa/easymock/MockAnnotationUtil.java diff --git a/src/test/java/krasa/easymock/Mocked.java b/src/test/java/krasa/easymock/Mocked.java new file mode 100644 index 0000000..8bfafd3 --- /dev/null +++ b/src/test/java/krasa/easymock/Mocked.java @@ -0,0 +1,9 @@ +package krasa.easymock; + +import java.lang.annotation.*; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Mocked { +} diff --git a/src/test/java/krasa/formatter/Version.java b/src/test/java/krasa/formatter/Version.java new file mode 100644 index 0000000..9bcab08 --- /dev/null +++ b/src/test/java/krasa/formatter/Version.java @@ -0,0 +1,19 @@ +package krasa.formatter; + +import org.junit.Assert; +import org.junit.Test; + +import static com.intellij.util.text.VersionComparatorUtil.compare; + +public class Version { + @Test + public void name() { + Assert.assertEquals(1, compare("17.4.132.637.0-Eclipse_4.7", "17.4.132.637.0-Eclipse_4.6")); + Assert.assertEquals(1, compare("17.3.132.637.0-Eclipse_4.7.3a", "17.2.132.637.0-Eclipse_4.7.3a")); + Assert.assertEquals(1, compare("17.4.132.637.0-Eclipse_4.7.3a", "17.3.132.637.0-Eclipse_4.7.3a")); + Assert.assertEquals(1, compare("17.4.132.637.0-Eclipse_4.7.3a", "17.3.132.637.0-Eclipse_4.6")); + Assert.assertEquals(1, compare("18.132.637.0-Eclipse_4.7.3a", "17.3.132.637.0-Eclipse_4.7.3a")); + Assert.assertEquals(1, compare("18.2.181.000.0-Eclipse_4.8.0", "18.1.181.000.0-Eclipse_4.7.3a")); + Assert.assertEquals(1, compare("18.2.181.000.0-Eclipse_4.9.0", "18.1.181.000.0-Eclipse_4.8.0")); + } +} diff --git a/src/test/java/krasa/formatter/eclipse/ConfigurableEclipseLocationTest.java b/src/test/java/krasa/formatter/eclipse/ConfigurableEclipseLocationTest.java new file mode 100644 index 0000000..066053f --- /dev/null +++ b/src/test/java/krasa/formatter/eclipse/ConfigurableEclipseLocationTest.java @@ -0,0 +1,30 @@ +package krasa.formatter.eclipse; + +import org.junit.Test; + +import java.net.URL; +import java.util.List; + +public class ConfigurableEclipseLocationTest { + + @Test + public void run() { + List urlList; + urlList = new ConfigurableEclipseLocation().run("C:/Users/vojtisek/eclipse/java-2023-03"); +// urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-macosx-cocoa"); +// urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-linux-gtk"); +// urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-win32"); +// List urlList = new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-jee-2020-06-R-win32-x86_64"); + for (URL jar : urlList) { + System.out.println(jar); + } + urlList = new ConfigurableEclipseLocation().run("C:\\Users\\vojtisek\\eclipse\\java-2021-12"); +// urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-macosx-cocoa"); +// urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-linux-gtk"); +// urlList= new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-standard-kepler-R-win32"); +// List urlList = new ConfigurableEclipseLocation().run("C:\\workspace\\eclipse-jee-2020-06-R-win32-x86_64"); + for (URL jar : urlList) { + System.out.println(jar); + } + } +} \ No newline at end of file diff --git a/test/java/krasa/formatter/eclipse/JavaCodeFormatterFacadeTest.java b/src/test/java/krasa/formatter/eclipse/JavaCodeFormatterFacadeTest.java similarity index 64% rename from test/java/krasa/formatter/eclipse/JavaCodeFormatterFacadeTest.java rename to src/test/java/krasa/formatter/eclipse/JavaCodeFormatterFacadeTest.java index 7d344f9..4bfd768 100644 --- a/test/java/krasa/formatter/eclipse/JavaCodeFormatterFacadeTest.java +++ b/src/test/java/krasa/formatter/eclipse/JavaCodeFormatterFacadeTest.java @@ -1,16 +1,23 @@ package krasa.formatter.eclipse; -import java.io.UnsupportedEncodingException; - -import org.junit.Before; -import org.junit.Test; - +import com.intellij.mock.MockApplication; import com.intellij.openapi.command.impl.DummyProject; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.util.PsiUtilCore; - -import junit.framework.Assert; +import krasa.formatter.settings.GlobalSettings; import krasa.formatter.settings.Settings; +import org.apache.commons.io.FileUtils; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.UnsupportedEncodingException; + +import static org.junit.Assert.assertEquals; /** * @author Vojtech Krasa @@ -51,12 +58,45 @@ public class JavaCodeFormatterFacadeTest { + "\t\tEclipseCodeFormatterFacade eclipseCodeFormatterFacade = new EclipseCodeFormatterFacade(pathToConfigFile);\n" + "\t\tString output = eclipseCodeFormatterFacade.format(INPUT, Settings.LINE_SEPARATOR);\n" + "\t\tAssert.assertEquals(INPUT, output);\n" + "\n" + "\t}\n" + "}"; + public static final String FORMATTED_EPF = "public class EclipseCodeFormatterFacadeTest {\n" + + "\n" + + " public static final String INPUT =\n" + + " \"ღმ⠀⠑⠁⠞色は匂へど 散りぬるを⠀⠛⠇⠁⠎⠎⠀⠁⠝⠙⠀⠊⠞⠀⠙⠕⠑⠎⠝⠞⠀⠓⠥⠗⠞⠀⠍⠑ერთსი შემვედრე, ნუთუ კვლა დამხსნას სოფლისა შრომასა, ცეცხლს, წყალსა და მიწასა, ჰაერთა თანა მრომასა; მომცნეს ფრთენი და აღვფრინდე, მივჰხვდე მას ჩემსა ნდომასა, დღისით და ღამით ვჰხედვიდე யாமறிந்த மொழிகளி+ěščřრუსთაველიžýáíé=ê¹ś¿źæñ³ó\";\n" + + "\n" + + " @Test\n" + + " public void testFormat() throws Exception {\n" + + " String pathToCo色は匂へどnfigFile = \"org.eclipse.jdt.core.prefs\";\n" + + " EclipseCodeFormatterFacade eclipseCodeFormatterFacade = new EclipseCodeFormatterFacade(pathToConfigFile);\n" + + " String output = eclipseCodeFormatterFacade.format(INPUT, Settings.LINE_SEPARATOR);\n" + + " Assert.assertEquals(INPUT, output);\n" + + "\n" + + " }\n" + + "}\n"; public static final String FORMATTED2 = "package krasa;\n" + "\n" + "import org.xml.sax.InputSource;\n" + "\n" + "/**\n" + " * @author Vojtech Krasa\n" + " */\n" + "public class Test2 {\n" + "\n" + "\tpublic static final InputSource INPUT_SOURCE = new InputSource();\n" + "\n" + "\tpublic static void main(String[] args) {\n" + "\n" + "\t\tSystem.err.println(\"\" + \"\" + \"\" + \"\" + \"\");\n" + "\t\tSystem.err.println(\"\" + \"\" + \"\" + \"\" + \"\");\n" + "\n" + "\t}\n" + "\n" + "}"; + public static final String FORMATTED_2_EPF = "package krasa;\n" + + "\n" + + "import org.xml.sax.InputSource;\n" + + "\n" + + "/**\n" + + " * @author Vojtech Krasa\n" + + " */\n" + + "public class Test2 {\n" + + "\n" + + " public static final InputSource INPUT_SOURCE = new InputSource();\n" + + "\n" + + " public static void main(String[] args) {\n" + + "\n" + + " System.err.println(\"\" + \"\" + \"\" + \"\" + \"\");\n" + + " System.err.println(\"\" + \"\" + \"\" + \"\" + \"\");\n" + + "\n" + + " }\n" + + "\n" + + "}\n"; public static final String PATH_TO_CONFIG_FILE = "resources/org.eclipse.jdt.core.prefs"; @@ -76,10 +116,15 @@ public static Project getProject() { public void setUp() throws Exception { Settings settings = new Settings(); setPathToConfigFileJava(settings, PATH_TO_CONFIG_FILE); - eclipseCodeFormatterFacade = new JavaCodeFormatterFacade(settings.getJavaProperties(), - settings.getEclipseVersion(), getProject(), settings.getPathToEclipse()); + eclipseCodeFormatterFacade = getEclipseCodeFormatterFacade(settings); } + @NotNull + private JavaCodeFormatterFacade getEclipseCodeFormatterFacade(Settings settings) { + return new JavaCodeFormatterFacade(settings, getProject()); + } + + private void setPathToConfigFileJava(Settings settings, String pathToConfigFile) { pathToConfigFile = TestUtils.normalizeUnitTestPath(pathToConfigFile); settings.setPathToConfigFileJava(pathToConfigFile); @@ -102,24 +147,40 @@ public void testFormatByXML() throws Exception { Settings settings = new Settings(); setPathToConfigFileJava(settings, "resources/format.xml"); settings.setSelectedJavaProfile("kuk"); - eclipseCodeFormatterFacade = new JavaCodeFormatterFacade(settings.getJavaProperties(), - settings.getEclipseVersion(), getProject(), settings.getPathToEclipse()); + eclipseCodeFormatterFacade = getEclipseCodeFormatterFacade(settings); String output = format(INPUT); Assert.assertEquals(FORMATTED, output); output = format(INPUT2); Assert.assertEquals(FORMATTED2, output); } + @Test + public void testFormatByXML_Formatter_20160606() throws Exception { + MockApplication app = MockApplication.setUp(Disposer.newDisposable()); + app.registerService(GlobalSettings.class, new GlobalSettings()); + GlobalSettings instance = GlobalSettings.getInstance(); + instance.setPathToEclipse("C:/Users/vojtisek/eclipse/java-2023-03"); + + Settings settings = new Settings(); + setPathToConfigFileJava(settings, "resources/Formatter_20160606.xml"); + settings.setSelectedJavaProfile("Formatter_20160606"); + settings.setEclipseVersion(Settings.FormatterVersion.CUSTOM); + + eclipseCodeFormatterFacade = getEclipseCodeFormatterFacade(settings); + String input = FileUtils.readFileToString(new File("src/test/resources/example/Example.java"), "UTF-8"); + String output = format(input); + Assert.assertEquals(input, output); + } + @Test public void testFormatByEPF() throws Exception { Settings settings = new Settings(); setPathToConfigFileJava(settings, "resources/mechanic-formatter.epf"); - eclipseCodeFormatterFacade = new JavaCodeFormatterFacade(settings.getJavaProperties(), - settings.getEclipseVersion(), getProject(), settings.getPathToEclipse()); + eclipseCodeFormatterFacade = getEclipseCodeFormatterFacade(settings); String output = format(INPUT); - Assert.assertEquals(FORMATTED, output); + Assert.assertEquals(FORMATTED_EPF, output); output = format(INPUT2); - Assert.assertEquals(FORMATTED2, output); + Assert.assertEquals(FORMATTED_2_EPF, output); } @Test @@ -128,40 +189,11 @@ public void testFormatByXML_assertionError() throws Exception { setPathToConfigFileJava(settings, "resources/format.xml"); settings.setSelectedJavaProfile("kuk"); - eclipseCodeFormatterFacade = new JavaCodeFormatterFacade(settings.getJavaProperties(), - settings.getEclipseVersion(), getProject(), settings.getPathToEclipse()); + eclipseCodeFormatterFacade = getEclipseCodeFormatterFacade(settings); String output = format(INPUT_3); Assert.assertEquals(EXPECTED_3, output); } - @Test - public void testFormatByXML_oldFormatter() throws Exception { - Settings settings = new Settings(); - setPathToConfigFileJava(settings, "resources/format.xml"); - settings.setSelectedJavaProfile("kuk"); - settings.setUseOldEclipseJavaFormatter(true); - eclipseCodeFormatterFacade = new JavaCodeFormatterFacade(settings.getJavaProperties(), - settings.getEclipseVersion(), getProject(), settings.getPathToEclipse()); - String output = format(INPUT); - Assert.assertEquals(FORMATTED, output); - output = format(INPUT2); - Assert.assertEquals(FORMATTED2, output); - } - - @Test - public void testFormatByXML_oldFormatter_againToTestClassloader() throws Exception { - Settings settings = new Settings(); - setPathToConfigFileJava(settings, "resources/format.xml"); - settings.setSelectedJavaProfile("kuk"); - settings.setUseOldEclipseJavaFormatter(true); - eclipseCodeFormatterFacade = new JavaCodeFormatterFacade(settings.getJavaProperties(), - settings.getEclipseVersion(), getProject(), settings.getPathToEclipse()); - String output = format(INPUT); - Assert.assertEquals(FORMATTED, output); - output = format(INPUT2); - Assert.assertEquals(FORMATTED2, output); - } - @Test public void testFormat2() throws Exception { String input2 = INPUT2; @@ -184,4 +216,11 @@ public String convert(String s, String utf8) throws UnsupportedEncodingException return new String(s.getBytes("UTF8"), utf8); } + @Test + public void toEclipseLanguageLevel() { + assertEquals("1.8", JavaCodeFormatterFacade.toEclipseLanguageLevel(LanguageLevel.JDK_1_8)); + assertEquals("10", JavaCodeFormatterFacade.toEclipseLanguageLevel(LanguageLevel.JDK_10)); + assertEquals("13", JavaCodeFormatterFacade.toEclipseLanguageLevel(LanguageLevel.JDK_13)); +// assertEquals("15", JavaCodeFormatterFacade.toEclipseLanguageLevel(LanguageLevel.JDK_15_PREVIEW)); + } } diff --git a/src/test/java/krasa/formatter/eclipse/PlatformFormatterTest.java b/src/test/java/krasa/formatter/eclipse/PlatformFormatterTest.java new file mode 100644 index 0000000..b1903db --- /dev/null +++ b/src/test/java/krasa/formatter/eclipse/PlatformFormatterTest.java @@ -0,0 +1,181 @@ +package krasa.formatter.eclipse; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.module.StdModuleTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.codeStyle.JavaCodeStyleSettings; +import com.intellij.psi.formatter.FormatterTestCase; +import com.intellij.testFramework.IdeaTestUtil; +import com.intellij.testFramework.UsefulTestCase; +import com.intellij.util.IncorrectOperationException; +import krasa.formatter.settings.ProjectComponent; +import krasa.formatter.settings.Settings; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.Arrays; + +public class PlatformFormatterTest extends FormatterTestCase { + + private static final String BASE_PATH = "testProject"; + ConfigFileLocator.IModuleResolverStrategy previousResolver; + + @Override + public void setUp() throws Exception { + super.setUp(); + Settings settings = new Settings(); + settings.setFormatter(Settings.Formatter.ECLIPSE); + settings.setConfigType(Settings.ConfigType.RESOLVE); + ProjectComponent.getInstance(getProject()).installOrUpdate(settings); + previousResolver = ConfigFileLocator.TESTING_getModuleResolver(); + } + + public void testFormatting() { + + + ConfigFileLocator.TESTING_setModuleResolver(new ConfigFileLocator.IModuleResolverStrategy() { + @Override + public VirtualFile getModuleDirForFile(VirtualFile virtualFile, Project project) { + + String path = virtualFile.getPath(); + if (path.contains("/testProject/submodule-a")) { + return UsefulTestCase.refreshAndFindFile(new File("testProject/submodule-a")); + } + if (path.contains("/testProject/submodule-b")) { + return UsefulTestCase.refreshAndFindFile(new File("testProject/submodule-b")); + } + if (path.contains("/testProject")) { + return UsefulTestCase.refreshAndFindFile(new File("testProject")); + } + throw new UnsupportedOperationException("Not expected " + virtualFile); + } + }); + + { + VirtualFile virtualFile = refreshAndFindFile(new File("testProject/submodule-a/src/main/java/aaa/XAAA.java")); + + PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(virtualFile); + + CommandProcessor.getInstance().executeCommand(getProject(), () -> ApplicationManager.getApplication().runWriteAction(() -> performFormatting(psiFile)), "", + ""); + + Document document = getDocument(psiFile); + String fileText = document.getText(); + assertEquals("package aaa;\n" + + "\n" + + "public class XAAA {\n" + + "\tpublic static void aaa() {\n" + + "\n" + + "\t}\n" + + "}\n", fileText); + //submodule-a has no own formatter configuration, so it uses the one of its parent + assertFormatterFile("testProject/.settings/org.eclipse.jdt.core.prefs"); + + } + + { + VirtualFile virtualFile = refreshAndFindFile(new File("testProject/submodule-b/src/main/java/bbb/XBBB.java")); + + PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(virtualFile); + + CommandProcessor.getInstance().executeCommand(getProject(), () -> ApplicationManager.getApplication().runWriteAction(() -> performFormatting(psiFile)), "", + ""); + + assertFormatterFile("testProject/submodule-b/mechanic-formatter.epf"); + Document document = getDocument(psiFile); + String fileText = document.getText(); + assertEquals("package bbb;\n" + + "\n" + + "public class XBBB {\n" + + " public static void bbb() {\n" + + "\n" + + " }\n" + + "}\n", fileText); + //submodule-b has its own formatter configuration + } + + { + VirtualFile virtualFile = refreshAndFindFile(new File("testProject/src/main/java/aaa/XAAA.java")); + + PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(virtualFile); + + CommandProcessor.getInstance().executeCommand(getProject(), () -> ApplicationManager.getApplication().runWriteAction(() -> performFormatting(psiFile)), "", + ""); + + Document document = getDocument(psiFile); + String fileText = document.getText(); + assertEquals("package aaa;\n" + + "\n" + + "public class XAAA {\n" + + "\tpublic static void aaa() {\n" + + "\n" + + "\t}\n" + + "}\n", fileText); + //the parent project has its own formatter configuration + assertFormatterFile("testProject/.settings/org.eclipse.jdt.core.prefs"); + } + + } + + private void assertFormatterFile(String s) { + String filePath = ConfigFileLocator.TESTING_getMostRecentFormatterFile().getPath(); + assertTrue("Used " + filePath, filePath.endsWith(s)); + } + + @Override + protected void tearDown() throws Exception { + + ConfigFileLocator.TESTING_setModuleResolver(previousResolver); + + try { + super.tearDown(); + } catch (RuntimeException exception) { + // TODO: Fix inability to free pointer + if (exception.getMessage().contains("Virtual pointer hasn't been disposed")) { + throw exception; + } + } + } + + + protected void performFormatting(PsiFile file) { + try { + CodeStyleManager.getInstance(this.getProject()).reformatText(file, Arrays.asList(new TextRange(0, file.getTextLength()))); + } catch (IncorrectOperationException var3) { + fail(); + } + } + + @Override + protected Sdk getProjectJDK() { + return IdeaTestUtil.getMockJdk17(); + } + + @NotNull + protected ModuleType getModuleType() { + return StdModuleTypes.JAVA; + } + + @Override + protected String getFileExtension() { + return "java"; + } + + protected JavaCodeStyleSettings getCustomJavaSettings() { + return JavaCodeStyleSettings.getInstance(getProject()); + } + + @Override + protected String getBasePath() { + return BASE_PATH; + } +} diff --git a/test/java/krasa/formatter/eclipse/TestUtils.java b/src/test/java/krasa/formatter/eclipse/TestUtils.java similarity index 98% rename from test/java/krasa/formatter/eclipse/TestUtils.java rename to src/test/java/krasa/formatter/eclipse/TestUtils.java index c5b71b5..7a6f232 100644 --- a/test/java/krasa/formatter/eclipse/TestUtils.java +++ b/src/test/java/krasa/formatter/eclipse/TestUtils.java @@ -1,12 +1,12 @@ package krasa.formatter.eclipse; +import krasa.formatter.utils.FileUtils; +import org.jetbrains.annotations.NotNull; + import java.io.File; import java.util.HashMap; import java.util.Properties; -import krasa.formatter.utils.FileUtils; -import org.jetbrains.annotations.NotNull; - /** * @author Vojtech Krasa */ @@ -38,7 +38,7 @@ public static HashMap getJavaProperties() { @NotNull public static String normalizeUnitTestPath(String path) { if (!new File(path).exists()) { - path = "test/" + path; + path = "src/test/" + path; } return path; } diff --git a/test/java/krasa/formatter/plugin/ImportsSorter450Test.java b/src/test/java/krasa/formatter/plugin/ImportsSorter450Test.java similarity index 99% rename from test/java/krasa/formatter/plugin/ImportsSorter450Test.java rename to src/test/java/krasa/formatter/plugin/ImportsSorter450Test.java index 3d4bcc9..d30d0cd 100644 --- a/test/java/krasa/formatter/plugin/ImportsSorter450Test.java +++ b/src/test/java/krasa/formatter/plugin/ImportsSorter450Test.java @@ -1,17 +1,16 @@ package krasa.formatter.plugin; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - import krasa.formatter.eclipse.TestUtils; import krasa.formatter.settings.Settings; import krasa.formatter.settings.provider.ImportOrderProvider; import krasa.formatter.utils.StringUtils; - import org.junit.Assert; import org.junit.Test; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + /** * @author Vojtech Krasa */ @@ -235,7 +234,7 @@ public void test5() throws Exception { // @Test // public void test6() throws Exception { // String document = "package jobs;\n" + "\n" + "import models.Album;\n" + "import models.Picture;\n" -// + "import org.apache.commons.lang.StringUtils;\n" + "import org.apache.http.HttpEntity;\n" +// + "import org.apache.commons.lang3.StringUtils;\n" + "import org.apache.http.HttpEntity;\n" // + "import org.apache.http.HttpResponse;\n" + "import org.apache.http.HttpStatus;\n" // + "import org.apache.http.client.methods.HttpGet;\n" // + "import org.apache.http.impl.client.DefaultHttpClient;\n" diff --git a/test/java/krasa/formatter/plugin/ImportsSorter452Test.java b/src/test/java/krasa/formatter/plugin/ImportsSorter452Test.java similarity index 98% rename from test/java/krasa/formatter/plugin/ImportsSorter452Test.java rename to src/test/java/krasa/formatter/plugin/ImportsSorter452Test.java index 041c3c2..e88591d 100644 --- a/test/java/krasa/formatter/plugin/ImportsSorter452Test.java +++ b/src/test/java/krasa/formatter/plugin/ImportsSorter452Test.java @@ -1,20 +1,19 @@ package krasa.formatter.plugin; -import java.io.File; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - +import com.intellij.psi.PsiClass; +import krasa.formatter.eclipse.TestUtils; import krasa.formatter.settings.Settings; import krasa.formatter.settings.provider.ImportOrderProvider; import krasa.formatter.utils.StringUtils; - import org.apache.commons.io.FileUtils; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; -import com.intellij.psi.PsiClass; +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; /** * @author Vojtech Krasa @@ -171,7 +170,7 @@ public void issue104a() throws Exception { Collections.shuffle(importsList); Settings settings = new Settings(); - File file = FileUtils.getFile("resources/issue104.importorder"); + File file = FileUtils.getFile(TestUtils.normalizeUnitTestPath("resources/issue104.importorder")); setPath(settings, file); ImportOrderProvider importOrderProvider = new ImportOrderProvider(settings); @@ -454,7 +453,7 @@ public void test5() // @Test // public void test6() throws Exception { // String document = "package jobs;\n" + "\n" + "import models.Album;\n" + "import models.Picture;\n" -// + "import org.apache.commons.lang.StringUtils;\n" + "import org.apache.http.HttpEntity;\n" +// + "import org.apache.commons.lang3.StringUtils;\n" + "import org.apache.http.HttpEntity;\n" // + "import org.apache.http.HttpResponse;\n" + "import org.apache.http.HttpStatus;\n" // + "import org.apache.http.client.methods.HttpGet;\n" // + "import org.apache.http.impl.client.DefaultHttpClient;\n" diff --git a/test/java/krasa/formatter/settings/DisabledFileTypeSettingsTest.java b/src/test/java/krasa/formatter/settings/DisabledFileTypeSettingsTest.java similarity index 100% rename from test/java/krasa/formatter/settings/DisabledFileTypeSettingsTest.java rename to src/test/java/krasa/formatter/settings/DisabledFileTypeSettingsTest.java diff --git a/test/java/krasa/formatter/settings/provider/CachedProviderTest.java b/src/test/java/krasa/formatter/settings/provider/CachedProviderTest.java similarity index 84% rename from test/java/krasa/formatter/settings/provider/CachedProviderTest.java rename to src/test/java/krasa/formatter/settings/provider/CachedProviderTest.java index ecd013a..0df93d3 100644 --- a/test/java/krasa/formatter/settings/provider/CachedProviderTest.java +++ b/src/test/java/krasa/formatter/settings/provider/CachedProviderTest.java @@ -1,16 +1,14 @@ package krasa.formatter.settings.provider; -import java.io.File; -import java.io.IOException; - -import junit.framework.Assert; +import com.intellij.openapi.util.io.FileUtil; import krasa.formatter.common.ModifiableFile; - import org.apache.commons.io.FileUtils; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import com.intellij.openapi.util.io.FileUtil; +import java.io.File; +import java.io.IOException; /** * @author Vojtech Krasa @@ -38,10 +36,10 @@ protected String readFile(File file) { @Test public void testWasChanged() throws Exception { - ModifiableFile.Monitor modifiedMonitor = cachedProvider.getModifiedMonitor(); - Assert.assertFalse(cachedProvider.wasChanged(modifiedMonitor)); + cachedProvider.get(); + Assert.assertFalse(cachedProvider.wasChanged()); tempFile.setLastModified(tempFile.lastModified() + 1000); - Assert.assertTrue(cachedProvider.wasChanged(modifiedMonitor)); + Assert.assertTrue(cachedProvider.wasChanged()); } @Test diff --git a/test/java/krasa/formatter/settings/provider/ImportOrderProviderTest.java b/src/test/java/krasa/formatter/settings/provider/ImportOrderProviderTest.java similarity index 100% rename from test/java/krasa/formatter/settings/provider/ImportOrderProviderTest.java rename to src/test/java/krasa/formatter/settings/provider/ImportOrderProviderTest.java diff --git a/test/java/krasa/formatter/utils/FileUtilsTest.java b/src/test/java/krasa/formatter/utils/FileUtilsTest.java similarity index 94% rename from test/java/krasa/formatter/utils/FileUtilsTest.java rename to src/test/java/krasa/formatter/utils/FileUtilsTest.java index 157df5c..a15eeaa 100644 --- a/test/java/krasa/formatter/utils/FileUtilsTest.java +++ b/src/test/java/krasa/formatter/utils/FileUtilsTest.java @@ -1,13 +1,12 @@ package krasa.formatter.utils; -import java.io.File; -import java.util.List; - -import junit.framework.Assert; - import krasa.formatter.eclipse.TestUtils; +import org.junit.Assert; import org.junit.Test; +import java.io.File; +import java.util.List; + /** * @author Vojtech Krasa */ diff --git a/src/test/java/krasa/formatter/utils/StringUtilsTest.java b/src/test/java/krasa/formatter/utils/StringUtilsTest.java new file mode 100644 index 0000000..4a5ece6 --- /dev/null +++ b/src/test/java/krasa/formatter/utils/StringUtilsTest.java @@ -0,0 +1,281 @@ +package krasa.formatter.utils; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +import static krasa.formatter.utils.StringUtils.getPackage; +import static krasa.formatter.utils.StringUtils.getSimpleName; + +/** + * @author Vojtech Krasa + */ +public class StringUtilsTest { + @Test + public void test_getSimpleName() throws Exception { + Assert.assertEquals("b", getSimpleName("a.a.b")); + Assert.assertEquals("b", getSimpleName("b")); + } + + @Test + public void test_getPackage() throws Exception { + Assert.assertEquals("a.a", getPackage("a.a.b")); + Assert.assertEquals("", getPackage("b")); + Assert.assertEquals("com.model", getPackage("com.model.Ethernet")); + } + + @Test + public void testBetterMatching() throws Exception { + String order1 = "com.foo"; + String order2 = "com.kuk"; + String s = StringUtils.betterMatching(order2, order1, "com.foo.goo"); + Assert.assertEquals(order1, s); + s = StringUtils.betterMatching(order1, order2, "com.foo.goo"); + Assert.assertEquals(order1, s); + } + + @Test + public void testTrimToList() throws Exception { + List strings = StringUtils.trimToList(""); + Assert.assertFalse(strings.isEmpty()); + strings = StringUtils.trimToList(" "); + Assert.assertFalse(strings.isEmpty()); + } +// todo +// @Test +// public void testGenerateName() throws Exception { +// ArrayList settingsList = new ArrayList(); +// Project instance = new MyDummyProject(); +// String s = StringUtils.generateName(settingsList, 1, instance.getName()); +// Assert.assertEquals("dummy", s); +// settingsList.add(new Settings(1L, "dummy")); +// +// s = StringUtils.generateName(settingsList, 1, instance.getName()); +// Assert.assertEquals("dummy (1)", s); +// settingsList.add(new Settings(1L, "dummy (1)")); +// +// s = StringUtils.generateName(settingsList, 1, instance.getName()); +// Assert.assertEquals("dummy (2)", s); +// } + +// class MyDummyProject extends UserDataHolderBase implements Project { +// +// +// @NotNull +// @Override +// public ExtensionsArea getExtensionArea() { +// return null; +// } +// +// @Override +// public T instantiateClassWithConstructorInjection(@NotNull Class aClass, @NotNull Object o, @NotNull PluginId pluginId) { +// return null; +// } +// +// @Override +// public @NotNull +// RuntimeException createError(@NotNull Throwable throwable, @NotNull PluginId pluginId) { +// return null; +// } +// +// @Override +// public @NotNull +// RuntimeException createError(@NotNull @NonNls String s, @NotNull PluginId pluginId) { +// return null; +// } +// +// @Override +// public @NotNull +// RuntimeException createError(@NotNull @NonNls String s, @Nullable Throwable throwable, @NotNull PluginId pluginId, @Nullable Map map) { +// return null; +// } +// +// +// @Override +// public @NotNull +// Class loadClass(@NotNull String s, @NotNull PluginDescriptor pluginDescriptor) throws ClassNotFoundException { +// return null; +// } +// +// @Override +// public @NotNull T instantiateClass(@NotNull String s, @NotNull PluginDescriptor pluginDescriptor) { +// return null; +// } +// +// @Override +// public @NotNull +// ActivityCategory getActivityCategory(boolean b) { +// return null; +// } +// +// public MyDummyProject() { +// } +// +// @Override +// public VirtualFile getProjectFile() { +// return null; +// } +// +// @Override +// @NotNull +// public String getName() { +// return "dummy"; +// } +// +// @Override +// @Nullable +// @NonNls +// public String getPresentableUrl() { +// return null; +// } +// +// @Override +// @NotNull +// @NonNls +// public String getLocationHash() { +// return "dummy"; +// } +// +// @Nullable +// @NonNls +// public String getLocation() { +// throw new UnsupportedOperationException("Method getLocation not implemented in " + getClass()); +// } +// +// @Override +// @NotNull +// public String getProjectFilePath() { +// return ""; +// } +// +// @Override +// public VirtualFile getWorkspaceFile() { +// return null; +// } +// +// @Override +// @Nullable +// public VirtualFile getBaseDir() { +// return null; +// } +// +// // @Override +// @Override +// public String getBasePath() { +// return null; +// } +// +// @Override +// public void save() { +// } +// +// @Override +// public BaseComponent getComponent(String name) { +// return null; +// } +// +// @Override +// public T getComponent(Class interfaceClass) { +// return null; +// } +// +// @Override +// public boolean hasComponent(@NotNull Class interfaceClass) { +// return false; +// } +// +// @NotNull +// public T[] getComponents(Class baseClass) { +// return (T[]) ArrayUtil.EMPTY_OBJECT_ARRAY; +// } +// +//// @Override +// @NotNull +// public PicoContainer getPicoContainer() { +// throw new UnsupportedOperationException("getPicoContainer is not implement in : " + getClass()); +// } +// +// @Override +// public boolean isInjectionForExtensionSupported() { +// return false; +// } +// +// +// @NotNull +// // @Override +// public Class[] getComponentInterfaces() { +// return new Class[0]; +// } +// +// @Override +// public boolean isDisposed() { +// return false; +// } +// +// @Override +// @NotNull +// public Condition getDisposed() { +// return new Condition() { +// @Override +// public boolean value(final Object o) { +// return isDisposed(); +// } +// }; +// } +// +// @Override +// public T getService(@NotNull Class aClass) { +// return null; +// } +// +// @NotNull +// public ComponentConfig[] getComponentConfigurations() { +// return new ComponentConfig[0]; +// } +// +// @Nullable +// public Object getComponent(final ComponentConfig componentConfig) { +// return null; +// } +// +// @Override +// public boolean isOpen() { +// return false; +// } +// +// @Override +// public boolean isInitialized() { +// return false; +// } +// +// @Override +// public boolean isDefault() { +// return false; +// } +// +//// @Override +// public CoroutineScope getCoroutineScope() { +// return null; +// } +// +// @Override +// public MessageBus getMessageBus() { +// return null; +// } +// +// @Override +// public void dispose() { +// } +// +//// @Override +// public T[] getExtensions(final ExtensionPointName extensionPointName) { +// throw new UnsupportedOperationException("getExtensions()"); +// } +// +// public ComponentConfig getConfig(Class componentImplementation) { +// throw new UnsupportedOperationException("Method getConfig not implemented in " + getClass()); +// } +// } + +} diff --git a/src/test/resources/Formatter_20160606.xml b/src/test/resources/Formatter_20160606.xml new file mode 100644 index 0000000..bd91668 --- /dev/null +++ b/src/test/resources/Formatter_20160606.xml @@ -0,0 +1,295 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/resources/Strata-Eclipse-Preferences.epf b/src/test/resources/Strata-Eclipse-Preferences.epf new file mode 100644 index 0000000..74b9600 --- /dev/null +++ b/src/test/resources/Strata-Eclipse-Preferences.epf @@ -0,0 +1,415 @@ +file_export_version=3.0 +/configuration/org.jboss.tools.usage/allow_usage_report_preference=false +/configuration/org.jboss.tools.usage/ask_user_for_usage_report_preference=false +/configuration/org.jboss.tools.usage/first_visit=1371560166832 +/instance/com.mountainminds.eclemma.ui/com.mountainminds.eclemma.ui.default_scope_same_project_only=true +/instance/net.sf.eclipsecs.core/include.rule.names=true +/instance/net.sf.eclipsecs.ui/ask.before.rebuild=always +/instance/org.eclipse.ant.ui/problem_properties=ignore +/instance/org.eclipse.ant.ui/problem_classpath=warning +/instance/org.eclipse.ant.ui/ignoreAll=true +\!/= +/instance/org.eclipse.core.resources/description.maxfilestates=100 +/instance/org.eclipse.core.resources/description.maxfilestatesize=2097152 +/instance/org.eclipse.core.resources/description.filestatelongevity=1209600000 +/instance/org.eclipse.core.resources/encoding=UTF-8 +/instance/org.eclipse.debug.core/org.eclipse.debug.core.USE_STEP_FILTERS=true +/instance/org.eclipse.debug.ui/org.eclipse.debug.ui.switch_perspective_on_suspend=always +/instance/org.eclipse.debug.ui/Console.console_tab_width=4 +/instance/org.eclipse.debug.ui/Console.highWaterMark=808000 +/instance/org.eclipse.debug.ui/Console.lowWaterMark=800000 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.argumentPrefixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.argumentSuffixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.fieldPrefixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.fieldSuffixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.localPrefixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.localSuffixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFieldPrefixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFieldSuffixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes= +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.codeComplete.visibilityCheck=enabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.methodParameters=generate +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.compliance=1.8 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.discouragedReference=ignore +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.forbiddenReference=ignore +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=ignore +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=protected +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.parameterAssignment=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.problem.unusedWarningToken=ignore +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.compiler.source=1.8 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.align_type_members_on_columns=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_assignment=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=48 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_method_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_after_package=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_field=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_method=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_before_package=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_block_comments=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_header=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_html=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_line_comments=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.format_source_code=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.indent_root_tags=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.line_length=200 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.compact_else_if=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.continuation_indentation=2 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_empty_lines=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.indentation.size=2 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_label=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.join_lines_in_comments=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.join_wrapped_lines=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.lineSplit=130 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.tabulation.char=space +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.tabulation.size=2 +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.use_on_off_tags=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_binary_operator=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=false +/instance/org.eclipse.jdt.core/org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true +/instance/org.eclipse.jdt.debug.ui/org.eclipse.jdt.debug.ui.active_filters=com.ibm.*,com.sun.*,java.*,javax.*,jrockit.*,org.omg.*,sun.*,sunw.*,java.lang.ClassLoader +/instance/org.eclipse.jdt.ui/content_assist_category_order=org.eclipse.jdt.ui.templateProposalCategory\:65535\u0000org.eclipse.jdt.ui.swtProposalCategory\:65536\u0000org.eclipse.jdt.ui.javaNoTypeProposalCategory\:65537\u0000org.eclipse.jdt.ui.javaTypeProposalCategory\:65538\u0000org.eclipse.jdt.ui.textProposalCategory\:65539\u0000org.eclipse.jdt.ui.javaAllProposalCategory\:65540\u0000org.eclipse.pde.api.tools.ui.apitools_proposal_category\:65541\u0000 +/instance/org.eclipse.jdt.ui/content_assist_disabled_computers=org.eclipse.jdt.ui.swtProposalCategory\u0000org.eclipse.jdt.ui.javaNoTypeProposalCategory\u0000org.eclipse.jdt.ui.javaTypeProposalCategory\u0000org.eclipse.jdt.ui.textProposalCategory\u0000org.eclipse.pde.api.tools.ui.apitools_proposal_category\u0000 +/instance/org.eclipse.jdt.ui/content_assist_favorite_static_members=com.opengamma.strata.collect.TestHelper.*;java.time.DayOfWeek.*;java.time.Month.*;java.time.temporal.ChronoField.*;java.time.temporal.ChronoUnit.*;org.testng.Assert.*;org.mockito.Mockito.*;com.opengamma.strata.collect.CollectProjectAssertions.*;com.opengamma.strata.collect.Guavate.*;java.util.stream.Collectors.* +/instance/org.eclipse.jdt.ui/content_assist_guess_method_arguments=true +/instance/org.eclipse.jdt.ui/formatter_profile=_OpenGamma Strata Java Formatter +/instance/org.eclipse.jdt.ui/formatter_settings_version=12 +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.exception.name=ex +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.gettersetter.use.is=true +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.ignorelowercasenames=true +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.importorder=java;javax;org;com; +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.ondemandthreshold=99 +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.overrideannotation=true +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.staticondemandthreshold=99 +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.template.format=false +/instance/org.eclipse.jdt.ui/org.eclipse.jdt.ui.text.custom_code_templates=