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 <code>source</code>, and returns a text edit that correspond to the difference between the given * string and the formatted string. * <p> * It returns null if the given string cannot be formatted. * </p> * * <p> * 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. * </p> * * @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 <code>null</code>, 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 <code>source</code>, and returns a text edit that correspond to the difference between the given * string and the formatted string. * <p> * It returns null if the given string cannot be formatted. * </p> * * <p> * 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. * </p> * * @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 <code>null</code>, 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); } }