mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 16:58:56 +00:00
[xtext][formatter] Javadoc proofreading
Also a few minor typos in method or parameter names. Added two methods to interfaces to avoid bogus cast operations in the implementation classes. Change-Id: I662d3c9a1028e489b00adcbf6921a13f0d07f44c
This commit is contained in:
parent
eb6ecc5183
commit
617965332c
39 changed files with 553 additions and 262 deletions
|
@ -9,12 +9,12 @@ package org.eclipse.xtext.formatting2;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.emf.common.util.EList;
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.emf.ecore.EStructuralFeature;
|
||||
import org.eclipse.xtext.AbstractRule;
|
||||
import org.eclipse.xtext.Keyword;
|
||||
import org.eclipse.xtext.RuleCall;
|
||||
import org.eclipse.xtext.formatting2.internal.CommentReplacer;
|
||||
import org.eclipse.xtext.formatting2.internal.FormattableDocument;
|
||||
import org.eclipse.xtext.formatting2.internal.HiddenRegionFormatting;
|
||||
import org.eclipse.xtext.formatting2.internal.HiddenRegionFormattingMerger;
|
||||
import org.eclipse.xtext.formatting2.internal.HiddenRegionReplacer;
|
||||
|
@ -38,38 +38,53 @@ import org.eclipse.xtext.resource.XtextResource;
|
|||
import org.eclipse.xtext.xbase.lib.Extension;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This is an abstract base class for language-specific formatters.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* It is the formatters responsibility to create a list of text replacements, which, when applied to a text document,
|
||||
* increase the documents readability for humans. At the same time the text changes should not have an impact on the
|
||||
* semantic model a parser would create from the document.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Formatters based on this class compute text replacements in two logical steps: First, they traverses the semantic
|
||||
* model and collect {@link ITextReplacer}s. Each TextReplacer is responsible for a (small) section of the document. In
|
||||
* a second step, the TextReplacers are are executed from the beginning to the end of the document and create the actual
|
||||
* text replacements. This decoupling allows it to traverse the semantic model in arbitrary order and yet compute
|
||||
* information that requires sequential processing of the document, e.g. indentation.
|
||||
* model and collect {@link ITextReplacer text replaces}. Each replacer is responsible for a (small) section of the
|
||||
* document. In a second step, the replacers are executed from the beginning to the end of the document and create the
|
||||
* actual {@link TextReplacement text replacements}. This decoupling allows it to traverse the semantic model in
|
||||
* arbitrary order and yet compute information that requires sequential processing of the document, e.g. indentation.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* To allow subclasses to implement this mechanism conveniently, there are several helper classes:
|
||||
* </p>
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link ITextRegionAccess} allows to obtain text regions for elements from the semantic model.</li>
|
||||
* <li>{@link ITextReplacer} creates {@link ITextReplacement}s for a specific region in the document.</li>
|
||||
* <li>{@link IFormattableDocument} collects {@link ITextReplacer}s and validates if they overlap.</li>
|
||||
* <li>{@link ITextRegionAccess} allows to obtain text regions for elements in the semantic model.</li>
|
||||
* <li>{@link ITextReplacer} creates {@link ITextReplacement replacements} for a specific region in the document.</li>
|
||||
* <li>{@link IFormattableDocument} collects {@link ITextReplacer replacers} and validates if they overlap.</li>
|
||||
* </ul>
|
||||
*
|
||||
* A formatter based on this class typically uses {@link ITextRegionAccess} to obtain the {@link IHiddenRegion} which
|
||||
* precedes or trails EObjects, EStructuralFeatures, Keywords, RuleCalls. This {@link IHiddenRegion} represents the
|
||||
* whitespace, newlines and comments between semantic tokens. No matter if there are zero or N hidden tokens between two
|
||||
* semantic tokens, there is always exactly one {@link IHiddenRegion}. In other words, the {@link IHiddenRegion} groups
|
||||
* all hidden tokens between two semantic tokens.
|
||||
* <p>
|
||||
* A formatter based on this class typically uses the {@link ITextRegionAccess} to obtain the {@link IHiddenRegion}
|
||||
* which precedes or trails {@link EObject semantic object}, {@link EStructuralFeature features}, {@link Keyword
|
||||
* keywords}, or {@link RuleCall rule calls}. This {@link IHiddenRegion} represents the whitespace, newlines and
|
||||
* comments between semantic tokens. No matter if there are zero or N hidden tokens between two semantic tokens, there
|
||||
* is always exactly one {@link IHiddenRegion}. In other words, the {@link IHiddenRegion} groups all hidden tokens
|
||||
* between two semantic tokens.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* For the {@link IHiddenRegion}, the formatter will create a {@link ITextReplacer} and store the replacer in the
|
||||
* {@link IFormattableDocument}. Typically this is a {@link HiddenRegionReplacer} parameterized with an
|
||||
* {@link IHiddenRegionFormatting}. The {@link HiddenRegionReplacer} will then delegate to {@link WhitespaceReplacer} or
|
||||
* {@link CommentReplacer}, depending on which kind of tokens are inside the hidden region.
|
||||
* {@link IHiddenRegionFormatting}. The {@link HiddenRegionReplacer} will then delegate to a {@link WhitespaceReplacer}
|
||||
* or {@link CommentReplacer}, depending on which kind of tokens are inside the hidden region.
|
||||
* </p>
|
||||
*
|
||||
* To format a document with syntax confirming to the parser rule
|
||||
* <p>
|
||||
* To format a document with syntax confirming to the parser rule:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* Entity:
|
||||
|
@ -78,7 +93,9 @@ import org.eclipse.xtext.xbase.lib.Extension;
|
|||
* '}';
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* the following formatter implementation (Xtend code) can be used:
|
||||
* </p>
|
||||
*
|
||||
* <pre>
|
||||
* def dispatch void format(Entity entity, extension IFormattableDocument document) {
|
||||
|
@ -92,25 +109,42 @@ import org.eclipse.xtext.xbase.lib.Extension;
|
|||
* }
|
||||
* </pre>
|
||||
*
|
||||
* For the full example, see the DomainModel Example. It can be accessed via Eclipse -> File -> New -> Example.
|
||||
* <p>
|
||||
* For the full example, see the DomainModel Example. It can be accessed via {@code Eclipse -> File -> New -> Example.}
|
||||
* </p>
|
||||
*
|
||||
* The class 'Entity' is part of the semantic model.
|
||||
* <p>
|
||||
* The class {@code Entity} is part of the semantic model.
|
||||
* </p>
|
||||
*
|
||||
* The methods 'regionForFeature()' and 'regionForKeyword' are extension methods:
|
||||
* <p>
|
||||
* The methods {@code regionForFeature()} and {@code regionForKeyword} are extension methods:
|
||||
* {@link ITextRegionAccess#regionForFeature(EObject, EStructuralFeature)} and
|
||||
* {@link ITextRegionAccess#regionForKeyword(EObject, String)}. They return an {@link ISemanticRegion}.
|
||||
* </p>
|
||||
*
|
||||
* The methods 'prepend', 'append' and 'surround' are extension methods from {@link IFormattableDocument}. They create
|
||||
* and register an {@link HiddenRegionReplacer} for the {@link IHiddenRegion} before and/or after the provided
|
||||
* {@link ISemanticRegion}.
|
||||
* <p>
|
||||
* The methods {@code prepend()}, {@code append()} and {@code surround()} are extension methods from
|
||||
* {@link IFormattableDocument}. They create and register an {@link HiddenRegionReplacer} for the {@link IHiddenRegion}
|
||||
* before and/or after the provided {@link ISemanticRegion}.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* Override {@code create*()} methods to customize formatter-local services.
|
||||
* </p>
|
||||
*
|
||||
* @see org.eclipse.xtext.formatting2 for an introduction to the topic
|
||||
* @see IFormatter2 to invoke a formatter
|
||||
* <p>
|
||||
* This implementation is stateful and cannot be used in parallel.
|
||||
* </p>
|
||||
*
|
||||
* @see #format(Object, IFormattableDocument) - overwrite to implement a formatter
|
||||
* @see #initalize(FormatterRequest) - overwrite to set values of member fields
|
||||
* @see #reset() - overwrite to cleanup after execution
|
||||
* @see "overwrite create*() methods to customize formatter-local services"
|
||||
* @see org.eclipse.xtext.formatting2 The package {@code org.eclipse.xtext.formatting2} for an introduction to the topic
|
||||
* @see IFormatter2 {@code IFormatter2}: the interface to invoke the formatter
|
||||
*
|
||||
* @see #format(Object, IFormattableDocument) The method {@code format(Object, IFormattableDocument)} should be
|
||||
* overridden to implement a formatter
|
||||
* @see #initalize(FormatterRequest) The method {@code initalize(FormatterRequest)} should be overridden to set values
|
||||
* of member fields
|
||||
* @see #reset() The method {@code reset()} should be overridden to cleanup after execution.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
|
@ -132,17 +166,17 @@ public abstract class AbstractFormatter2 implements IFormatter2 {
|
|||
}
|
||||
|
||||
/**
|
||||
* Fall-back for null-values in a subclasse's dispatch method.
|
||||
* Fall-back for subclasses that accidently try to dispatch over null values.
|
||||
*/
|
||||
protected void _format(Void obj, IFormattableDocument document) {
|
||||
}
|
||||
|
||||
/**
|
||||
* For {@link XtextResource}s, assume we want to format the first EObject from the contents list only. Because
|
||||
* For {@link XtextResource resources}, assume we want to format the first EObject from the contents list only. Because
|
||||
* that's where the parser puts the semantic model.
|
||||
*/
|
||||
protected void _format(XtextResource resource, IFormattableDocument document) {
|
||||
EList<EObject> contents = resource.getContents();
|
||||
List<EObject> contents = resource.getContents();
|
||||
if (!contents.isEmpty()) {
|
||||
EObject model = contents.get(0);
|
||||
format(model, document);
|
||||
|
@ -166,10 +200,6 @@ public abstract class AbstractFormatter2 implements IFormatter2 {
|
|||
throw new IllegalStateException("No " + ITextReplacer.class.getSimpleName() + " configured for " + elementName);
|
||||
}
|
||||
|
||||
public IFormattableDocument createFormattableDocument() {
|
||||
return new RootDocument(this);
|
||||
}
|
||||
|
||||
public IFormattableSubDocument createFormattableSubDocument(ITextSegment region, IFormattableDocument parent) {
|
||||
return new SubDocument(region, parent);
|
||||
}
|
||||
|
@ -201,15 +231,19 @@ public abstract class AbstractFormatter2 implements IFormatter2 {
|
|||
public ITextReplacer createWhitespaceReplacer(ITextSegment hiddens, IHiddenRegionFormatting formatting) {
|
||||
return new WhitespaceReplacer(hiddens, formatting);
|
||||
}
|
||||
|
||||
public IFormattableDocument createFormattableRootDocument() {
|
||||
return new RootDocument(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
final public List<ITextReplacement> format(FormatterRequest request) {
|
||||
public final List<ITextReplacement> format(FormatterRequest request) {
|
||||
try {
|
||||
initalize(request);
|
||||
IFormattableDocument document = createFormattableDocument();
|
||||
IFormattableDocument document = createFormattableRootDocument();
|
||||
XtextResource xtextResource = request.getTextRegionAccess().getResource();
|
||||
format(xtextResource, document);
|
||||
List<ITextReplacement> replacements = ((FormattableDocument) document).renderToTextReplacements();
|
||||
List<ITextReplacement> replacements = document.renderToTextReplacements();
|
||||
return replacements;
|
||||
} finally {
|
||||
reset();
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
/**
|
||||
* An exception to indicate that a region of the document was formatted with
|
||||
* conflicting settings.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*/
|
||||
public class ConflictingFormattingException extends RuntimeException {
|
||||
|
|
|
@ -11,19 +11,20 @@ import static java.lang.System.*;
|
|||
|
||||
import org.eclipse.xtext.preferences.ITypedPreferenceValues;
|
||||
import org.eclipse.xtext.preferences.IntegerKey;
|
||||
import org.eclipse.xtext.preferences.PreferenceKeysProvider;
|
||||
import org.eclipse.xtext.preferences.StringKey;
|
||||
import org.eclipse.xtext.preferences.TypedPreferenceKey;
|
||||
import org.eclipse.xtext.preferences.TypedPreferenceValues;
|
||||
|
||||
/**
|
||||
* General preference keys used by this formatting infrastructure. Formatters based on this infrastructure should honor
|
||||
* these keys as well.
|
||||
* <p>General preference keys used by this formatting infrastructure. Formatters based on this infrastructure should honor
|
||||
* these keys as well.</p>
|
||||
*
|
||||
* To set a values for one of these keys, use {@link FormatterRequest#setPreferences(ITypedPreferenceValues)}.
|
||||
* <p>To set a values for one of these keys, use {@link FormatterRequest#setPreferences(ITypedPreferenceValues)}.</p>
|
||||
*
|
||||
* To access a value for one of these keys, use {@link AbstractFormatter2#getPreference(TypedPreferenceKey)}.
|
||||
* <p>To access a value for one of these keys, use {@link AbstractFormatter2#getPreference(TypedPreferenceKey)}.</p>
|
||||
*
|
||||
* To introduce new keys, subclass this class.
|
||||
* <p>To introduce new keys, subclass this class (see also {@link PreferenceKeysProvider#allConstantKeys(Class...)}.</p>
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
|
@ -32,7 +33,7 @@ import org.eclipse.xtext.preferences.TypedPreferenceValues;
|
|||
public class FormatterPreferenceKeys {
|
||||
|
||||
/**
|
||||
* The characters used to wrap lines. Usually "\n" or "\r\n".
|
||||
* The characters used to wrap lines. Usually {@code \n} or {@code \r\n}.
|
||||
*/
|
||||
public static StringKey lineSeparator = new StringKey("line.separator", getProperty("line.separator"));
|
||||
|
||||
|
@ -42,7 +43,7 @@ public class FormatterPreferenceKeys {
|
|||
public static StringKey indentation = new StringKey("indentation", "\t");
|
||||
|
||||
/**
|
||||
* The width of one level of indentation counted in characters. If {@link #indentation} is "\t" and the
|
||||
* The width of one level of indentation counted in characters. If {@link #indentation} is {@code \t} and the
|
||||
* display-width of one tab is fours, then this values should be four. The formatter uses this value to compute when
|
||||
* {@link #maxLineWidth} has been exceeded.
|
||||
*/
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
|
@ -15,15 +16,15 @@ import org.eclipse.xtext.preferences.IPreferenceValuesProvider;
|
|||
import com.google.inject.BindingAnnotation;
|
||||
|
||||
/**
|
||||
* A marker annotation for Google Guice.
|
||||
* <p>Marks an instance of {@link IPreferenceValuesProvider} as the one that should be used by the formatter.</p>
|
||||
*
|
||||
* Marks an instance of {@link IPreferenceValuesProvider} as the one that should be used by the formatter.
|
||||
* <p>A {@link BindingAnnotation marker annotation} for Google Guice.</p>
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
*/
|
||||
@BindingAnnotation
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface FormatterPreferences {
|
||||
|
||||
}
|
||||
|
|
|
@ -21,15 +21,18 @@ import com.google.common.collect.Lists;
|
|||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
* A Request tells the formatter what and how to format.
|
||||
* <p>A request tells the formatter what and how to format.</p>
|
||||
*
|
||||
* When invoking the formatter, the request is passed into {@link IFormatter2#format(FormatterRequest)}.
|
||||
* <p>When invoking the formatter, the request is passed into {@link IFormatter2#format(FormatterRequest)}.</p>
|
||||
*
|
||||
* @see #textRegionAccess - the to-be-formatted semantic model with text regions.
|
||||
* @see #preferences - provide for preferences key from e.g. {@link FormatterPreferenceKeys}.
|
||||
* @see #regions - restrict the text regions for which {@link ITextReplacement}s are produced.
|
||||
* @see #allowIdentityEdits - do not suppress text replacements that do not cause changes.
|
||||
* @see #formatUndenfinedTokensOnly - only format regions that have no whitespace information yet.
|
||||
* <p>A request carries information about:<p>
|
||||
* <ul>
|
||||
* <li> The {@link #textRegionAccess} which allows to obtain the to-be-formatted semantic model with text regions.</li>
|
||||
* <li>{@link #preferences Preferences} with keys from e.g. {@link FormatterPreferenceKeys}.</li>
|
||||
* <li>{@link #regions} that describe how to restrict the text regions for which {@link ITextReplacement replacements} are produced.</li>
|
||||
* <li>An option to {@link #allowIdentityEdits()} which will disable to automated suppression of text replacements that do not cause changes.</li>
|
||||
* <li>A setting for green-field formatting ({@link #formatUndenfinedTokensOnly}): only format regions that have no whitespace information yet.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
|
@ -37,21 +40,30 @@ import com.google.common.collect.Maps;
|
|||
public class FormatterRequest {
|
||||
|
||||
/**
|
||||
* Restrict the formatter to produce {@link ITextReplacement}s inside the specified regions only. If no regions are
|
||||
* Restrict the formatter to produce {@link ITextReplacement replacements} inside the specified regions only. If no regions are
|
||||
* specified, the whole document is formatted.
|
||||
*/
|
||||
private Collection<ITextRegion> regions = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* @see #regions
|
||||
*/
|
||||
public FormatterRequest addRegion(ITextRegion region) {
|
||||
this.regions.add(region);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #regions
|
||||
*/
|
||||
public FormatterRequest setRegions(Collection<ITextRegion> regions) {
|
||||
this.regions = regions;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #regions
|
||||
*/
|
||||
public Collection<ITextRegion> getRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
@ -61,6 +73,9 @@ public class FormatterRequest {
|
|||
*/
|
||||
private ITextRegionAccess textRegionAccess;
|
||||
|
||||
/**
|
||||
* @see #textRegionAccess
|
||||
*/
|
||||
public ITextRegionAccess getTextRegionAccess() {
|
||||
return textRegionAccess;
|
||||
}
|
||||
|
@ -78,18 +93,24 @@ public class FormatterRequest {
|
|||
}
|
||||
|
||||
/**
|
||||
* Allow the formatter to produce {@link ITextReplacement}s that replace regions with text equal to the text of the
|
||||
* region. Since these TextReplacements do not cause text changes, one usually doens't want to have them in a
|
||||
* Allow the formatter to produce {@link ITextReplacement replacements} that replace regions with text equal to the text of the
|
||||
* region. Since these replacements do not cause text changes, one usually doens't want to have them in a
|
||||
* production environment. However, they are useful to test if a formatter considers all significant regions, e.g.
|
||||
* all {@link IHiddenRegion}s.
|
||||
* all {@link IHiddenRegion hidden regions}.
|
||||
*/
|
||||
private boolean allowIdentityEdits;
|
||||
|
||||
/**
|
||||
* @see #allowIdentityEdits
|
||||
*/
|
||||
public FormatterRequest setAllowIdentityEdits(boolean allowIdentityEdits) {
|
||||
this.allowIdentityEdits = allowIdentityEdits;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #allowIdentityEdits
|
||||
*/
|
||||
public boolean allowIdentityEdits() {
|
||||
return allowIdentityEdits;
|
||||
}
|
||||
|
@ -99,11 +120,17 @@ public class FormatterRequest {
|
|||
*/
|
||||
private ITypedPreferenceValues preferences;
|
||||
|
||||
/**
|
||||
* @see #preferences
|
||||
*/
|
||||
public FormatterRequest setPreferences(ITypedPreferenceValues preferenceValues) {
|
||||
this.preferences = preferenceValues;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #preferences
|
||||
*/
|
||||
public ITypedPreferenceValues getPreferences() {
|
||||
if (preferences == null)
|
||||
preferences = new MapBasedPreferenceValues(Maps.<String, String> newLinkedHashMap());
|
||||
|
@ -111,34 +138,40 @@ public class FormatterRequest {
|
|||
}
|
||||
|
||||
/**
|
||||
* {@link IHiddenRegion}s are considers undefined when their whitespace/comments are unknown. This happens for
|
||||
* HiddenRegions that emerged between programmatically created (not parsed!) model elements.
|
||||
* {@link IHiddenRegion Hidden regions} are considered undefined when their whitespace/comments are unknown. This happens for
|
||||
* regions that emerged between programmatically created (not parsed!) model elements.
|
||||
*
|
||||
* Enable this options if, for example, you serialize a model after applying a quick fix, refactoring or have it
|
||||
* edited in a graphical editor and you want to keep the whitespace-changes to a minimum.
|
||||
*/
|
||||
private boolean formatUndenfinedTokensOnly;
|
||||
|
||||
/**
|
||||
* @see #formatUndenfinedTokensOnly
|
||||
*/
|
||||
public boolean isFormatUndefinedHiddenRegionsOnly() {
|
||||
return formatUndenfinedTokensOnly;
|
||||
}
|
||||
|
||||
private boolean formatUndenfinedTokensOnly;
|
||||
|
||||
/**
|
||||
* @see #formatUndenfinedTokensOnly
|
||||
*/
|
||||
public FormatterRequest setFormatUndenfinedTokensOnly(boolean formatUndenfinedTokensOnly) {
|
||||
this.formatUndenfinedTokensOnly = formatUndenfinedTokensOnly;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exceptions that occur during formatting are passed to this handler. The handler may choose to throw them, log
|
||||
* them, or ignore them. Formatting continues, unless the handler throws an exception.
|
||||
* <p>Exceptions that occur during formatting are passed to this handler. The handler may choose to throw them, log
|
||||
* them, or ignore them. Formatting continues, unless the handler throws an exception.</p>
|
||||
*
|
||||
* Logging exceptions and continuing formatting is the default behavior.
|
||||
* <p>Logging exceptions and continuing formatting is the default behavior.</p>
|
||||
*
|
||||
* Throwing exceptions is useful in unit tests.
|
||||
* <p>Throwing exceptions is useful in unit tests.</p>
|
||||
*
|
||||
* Ignoring exceptions is useful when formatting a document with syntax errors.
|
||||
* <p>Ignoring exceptions is useful when formatting a document with syntax errors.</p>
|
||||
*
|
||||
* Defaults to the {@link ExceptionAcceptor#LOGGING Logging Acceptor}
|
||||
* <p>Defaults to the {@link ExceptionAcceptor#LOGGING Logging Acceptor}</p>
|
||||
*
|
||||
* @see ExceptionAcceptor#LOGGING
|
||||
* @see ExceptionAcceptor#THROWING
|
||||
|
@ -146,12 +179,18 @@ public class FormatterRequest {
|
|||
*/
|
||||
private IAcceptor<Exception> exceptionHandler;
|
||||
|
||||
/**
|
||||
* @see #exceptionHandler
|
||||
*/
|
||||
public IAcceptor<Exception> getExceptionHandler() {
|
||||
if (exceptionHandler == null)
|
||||
return ExceptionAcceptor.LOGGING;
|
||||
return exceptionHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #exceptionHandler
|
||||
*/
|
||||
public FormatterRequest setExceptionHandler(IAcceptor<Exception> problemHandler) {
|
||||
this.exceptionHandler = problemHandler;
|
||||
return this;
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
/**
|
||||
* Indicates that a condition formatting attempt failed.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class FormattingNotApplicableException extends RuntimeException {
|
||||
}
|
|
@ -7,6 +7,16 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
/**
|
||||
* A strategy for formatting that is to be applied on auto wrapping.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*
|
||||
* @see IHiddenRegionFormatter#setOnAutowrap(IAutowrapFormatter)
|
||||
*/
|
||||
public interface IAutowrapFormatter { // TODO: add region
|
||||
/**
|
||||
* Called if the region is supposed to wrapped.
|
||||
*/
|
||||
void format(IHiddenRegionFormatter wrapped, IFormattableDocument document);
|
||||
}
|
|
@ -7,6 +7,8 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
|
||||
|
@ -16,16 +18,22 @@ import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
|||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
* A FormattableDocument is a stateful object that holds a list of {@link ITextReplacer}s. Each TextReplacer is
|
||||
* responsible for a text region inside this document. The document can be populated with TextReplacers in any order.
|
||||
* However, it is not possible and not intended to register two or more TextReplacers for the same or overlapping
|
||||
* TextRegion.
|
||||
* <p>
|
||||
* A FormattableDocument is a stateful object that holds a list of {@link ITextReplacer replacers}. Each replacer is
|
||||
* responsible for a text region inside this document. The document can be populated with replacers in any order.
|
||||
* However, it is not possible and not intended to register two or more replacers for the same or overlapping
|
||||
* {@link ITextSegment region}.
|
||||
* </p>
|
||||
*
|
||||
* Eventually, all TextReplacers are invoked from the beginning of the document to the end of the document. Each
|
||||
* TextReplacer produces {@link ITextReplacement}s for their region. A {@link ITextReplacerContext} is passed on from
|
||||
* Replacer to Replacer and holds state such as the current indentation level.
|
||||
* <p>
|
||||
* Eventually, all replacers are invoked from the beginning of the document to the end of the document. Each replacer
|
||||
* produces {@link ITextReplacement text replacements} for their region. A {@link ITextReplacerContext} is passed on
|
||||
* from replacer to replacer and holds state such as the current indentation level.
|
||||
* </p>
|
||||
*
|
||||
* Besides this, a FormattableDocument
|
||||
* <p>
|
||||
* Besides this, a formattable document
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>offers convenience API to define formatting for HiddenRegions. See {@link ITextRegionAccess} for a definition of
|
||||
* HiddenRegions and {@link IHiddenRegionFormatter} for how they can be formatted.</li>
|
||||
|
@ -41,32 +49,99 @@ import com.google.common.base.Predicate;
|
|||
*/
|
||||
public interface IFormattableDocument {
|
||||
|
||||
IFormattableDocument withReplacerFilter(Predicate<ITextReplacer> filter);
|
||||
/**
|
||||
* Creates a delegate that allows to filter subsequent replacers based on the
|
||||
* given condition. Replacers are used if the predicate yields <code>true</code>.
|
||||
*/
|
||||
IFormattableDocument withReplacerFilter(Predicate<? super ITextReplacer> filter);
|
||||
|
||||
/**
|
||||
* Returns the region that is formatted.
|
||||
*/
|
||||
ITextSegment getRegion();
|
||||
|
||||
/**
|
||||
* Returns the formatter that is being used.
|
||||
*/
|
||||
AbstractFormatter2 getFormatter();
|
||||
|
||||
/**
|
||||
* Returns the current formatting request.
|
||||
*/
|
||||
FormatterRequest getRequest();
|
||||
|
||||
/**
|
||||
* Add a new replacer to the document.
|
||||
*/
|
||||
void addReplacer(ITextReplacer replacer);
|
||||
|
||||
/**
|
||||
* Render the document.
|
||||
*/
|
||||
List<ITextReplacement> renderToTextReplacements();
|
||||
|
||||
ISemanticRegion append(ISemanticRegion semanticRegion, Procedure1<IHiddenRegionFormatter> after);
|
||||
/**
|
||||
* Append the given semantic region and obtain the formatting information for trailing
|
||||
* whitespace and comments from the given procedure.
|
||||
*
|
||||
* Returns the given semantic region.
|
||||
*/
|
||||
ISemanticRegion append(ISemanticRegion semanticRegion, Procedure1<? super IHiddenRegionFormatter> after);
|
||||
|
||||
<T extends EObject> T append(T semanticRegion, Procedure1<IHiddenRegionFormatter> after);
|
||||
/**
|
||||
* Append the given information and obtain the formatting information for trailing
|
||||
* whitespace and comments from the given procedure.
|
||||
*
|
||||
* Returns the given semantic object.
|
||||
*/
|
||||
<T extends EObject> T append(T semanticRegion, Procedure1<? super IHiddenRegionFormatter> after);
|
||||
|
||||
/**
|
||||
* Append the given semantic region and obtain the formatting information for leading
|
||||
* whitespace and comments from the given procedure.
|
||||
*
|
||||
* Returns the given semantic region.
|
||||
*/
|
||||
ISemanticRegion prepend(ISemanticRegion semanticRegion, Procedure1<? super IHiddenRegionFormatter> before);
|
||||
|
||||
/**
|
||||
* Append the given information and obtain the formatting information for leading
|
||||
* whitespace and comments from the given procedure.
|
||||
*
|
||||
* Returns the given semantic object.
|
||||
*/
|
||||
<T extends EObject> T prepend(T semanticRegion, Procedure1<? super IHiddenRegionFormatter> before);
|
||||
|
||||
/**
|
||||
* Append the given semantic region and obtain the formatting information for leading and trailing
|
||||
* whitespace and comments from the given procedure.
|
||||
*
|
||||
* Returns the given semantic region.
|
||||
*/
|
||||
ISemanticRegion surround(ISemanticRegion semanticRegion, Procedure1<? super IHiddenRegionFormatter> beforeAndAfter);
|
||||
|
||||
/**
|
||||
* Append the given information and obtain the formatting information for leading and trailing
|
||||
* whitespace and comments from the given procedure.
|
||||
*
|
||||
* Returns the given semantic object.
|
||||
*/
|
||||
<T extends EObject> T surround(T owner, Procedure1<? super IHiddenRegionFormatter> beforeAndAfter);
|
||||
|
||||
/**
|
||||
* Apply the formatting of the first sub formatter that succeeds to the given owner's region.
|
||||
*/
|
||||
void formatConditionally(EObject owner, ISubFormatter... formatters) throws FormattingNotApplicableException;
|
||||
|
||||
/**
|
||||
* Apply the formatting of the first sub formatter that succeeds to the given region.
|
||||
*/
|
||||
void formatConditionally(int offset, int length, ISubFormatter... formatters)
|
||||
throws FormattingNotApplicableException;
|
||||
|
||||
AbstractFormatter2 getFormatter();
|
||||
/**
|
||||
* Format the given hidden region with the initialized formatter.
|
||||
*/
|
||||
IHiddenRegion set(IHiddenRegion hiddenRegion, Procedure1<? super IHiddenRegionFormatter> init);
|
||||
|
||||
FormatterRequest getRequest();
|
||||
|
||||
ISemanticRegion prepend(ISemanticRegion semanticRegion, Procedure1<IHiddenRegionFormatter> before);
|
||||
|
||||
<T extends EObject> T prepend(T semanticRegion, Procedure1<IHiddenRegionFormatter> before);
|
||||
|
||||
IHiddenRegion set(IHiddenRegion hiddenRegion, Procedure1<IHiddenRegionFormatter> init);
|
||||
|
||||
ISemanticRegion surround(ISemanticRegion semanticRegion, Procedure1<IHiddenRegionFormatter> beforeAndAfter);
|
||||
|
||||
<T extends EObject> T surround(T owner, Procedure1<IHiddenRegionFormatter> beforeAndAfter);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,13 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
/**
|
||||
* A sub document describes the formatting for a part of the entire document.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*
|
||||
* @see AbstractFormatter2#createFormattableSubDocument(ITextSegment, IFormattableDocument)
|
||||
*/
|
||||
public interface IFormattableSubDocument extends IFormattableDocument {
|
||||
IFormattableSubDocument requireFitsInLine(); // TODO: fits in line completely vs. first line fits in line.
|
||||
|
||||
|
|
|
@ -10,14 +10,19 @@ package org.eclipse.xtext.formatting2;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Use this interface to invoke a formatter.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* An Xtext language should have an implementation for this interface bound in its runtime module.
|
||||
* </p>
|
||||
*
|
||||
* @see org.eclipse.xtext.formatting2 for an introduction to formatting
|
||||
* @see AbstractFormatter2 to implement your own formatter
|
||||
* @see FormatterRequest to specify what an how sould be formatted
|
||||
* @see TextReplacements#apply(CharSequence, Iterable) to apply {@link ITextReplacement}s to a CharSequence or String.
|
||||
* @see org.eclipse.xtext.formatting2 The package org.eclipse.xtext.formatting2 for an introduction to formatting
|
||||
* @see AbstractFormatter2 The base class {@code AbstractFormatter2} to implement your own formatter.
|
||||
* @see FormatterRequest The class {@code FormatterRequest} to specify what and how sould be formatted.
|
||||
* @see TextReplacements#apply(CharSequence, Iterable) {@çode Textplacements#apply} to apply replacements to a
|
||||
* CharSequence or String.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
/**
|
||||
* An {@link IHiddenRegionFormatter} is used to build a formatting
|
||||
* setting for a hidden region.
|
||||
*
|
||||
* @see IHiddenRegionFormatting
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
|
@ -18,46 +22,123 @@ public interface IHiddenRegionFormatter {
|
|||
final int LOW_PRIORITY = -1;
|
||||
final int NORMAL_PRIORITY = 0;
|
||||
|
||||
/**
|
||||
* Allows to obtain the configured formatting setting.
|
||||
*/
|
||||
IHiddenRegionFormatting asBean();
|
||||
|
||||
/**
|
||||
* Configure autowrap. Same as {@link #autowrap(int) autowrap(0)}.
|
||||
*/
|
||||
void autowrap();
|
||||
|
||||
void autowrap(int triggerLenght);
|
||||
|
||||
void decreaseIndentation();
|
||||
|
||||
FormatterRequest getRequest();
|
||||
|
||||
void highPriority();
|
||||
|
||||
void increaseIndentation();
|
||||
|
||||
void noIndentation();
|
||||
|
||||
void lowPriority();
|
||||
|
||||
void newLine();
|
||||
|
||||
/**
|
||||
* Configure autowrap. The triggerLength allows to shift the wrapping point
|
||||
* beyond its actual position in the file. If a line has multiple wrapping points
|
||||
* it will scan backwards for the first autowrapped region. The triggerLength
|
||||
* moves this region logically such it will be found earlier.
|
||||
*/
|
||||
void autowrap(int triggerLength);
|
||||
|
||||
/**
|
||||
* Suppresses auto wrap in this hidden region.
|
||||
*/
|
||||
void noAutowrap();
|
||||
|
||||
void noSpace();
|
||||
|
||||
void oneSpace();
|
||||
|
||||
void setDecreaseIndentation(int indentation);
|
||||
|
||||
void setIncreaseIndentation(int indentation);
|
||||
|
||||
void setNewLines(int newLines);
|
||||
|
||||
void setNewLines(int minNewLines, int defaultNewLines, int maxNewLines);
|
||||
|
||||
|
||||
/**
|
||||
* Callback if autowrapping was applied.
|
||||
*/
|
||||
void setOnAutowrap(IAutowrapFormatter formatter);
|
||||
|
||||
/**
|
||||
* Returns teh current formatter request and allows to read configuration settings.
|
||||
*/
|
||||
FormatterRequest getRequest();
|
||||
|
||||
/**
|
||||
* When merging, treat this configuration with a high priority.
|
||||
* @see #lowPriority()
|
||||
* @see #HIGH_PRIORITY
|
||||
*/
|
||||
void highPriority();
|
||||
|
||||
/**
|
||||
* When merging, treat this configuration with a low priority.
|
||||
* @see #highPriority()
|
||||
* @see #LOW_PRIORITY
|
||||
*/
|
||||
void lowPriority();
|
||||
|
||||
/**
|
||||
* Sets the priority of this formatting configuration. Used when two
|
||||
* configurations should be merged.
|
||||
* The priority of this formatter; the default value is {@link #NORMAL_PRIORITY}.
|
||||
*/
|
||||
void setPriority(int priority);
|
||||
|
||||
/**
|
||||
* Decrease the indentation by one level.
|
||||
* Subsequent calls decrease the indentation further.
|
||||
* @see #setDecreaseIndentation(int)
|
||||
*/
|
||||
void decreaseIndentation();
|
||||
|
||||
/**
|
||||
* Increase the indentation by one level.
|
||||
*/
|
||||
void increaseIndentation();
|
||||
|
||||
/**
|
||||
* Decreases the indentation by the given number of levels.
|
||||
* @see #setIncreaseIndentation(int)
|
||||
*/
|
||||
void setDecreaseIndentation(int indentation);
|
||||
|
||||
/**
|
||||
* Increases the indentation by the given number of levels.
|
||||
*/
|
||||
void setIncreaseIndentation(int indentation);
|
||||
|
||||
/**
|
||||
* Resets the indentation level to zero.
|
||||
*/
|
||||
void noIndentation();
|
||||
|
||||
/**
|
||||
* Forces a line break in this hidden region.
|
||||
* Same as {@link #setNewLines(int) setNewLines(1)}.
|
||||
*/
|
||||
void newLine();
|
||||
|
||||
/**
|
||||
* Forces the number of newlines in this hidden region.
|
||||
* Same as {@link #setNewLines(int, int, int) setNewLines(nl, nl, nl)}
|
||||
*/
|
||||
void setNewLines(int newLines);
|
||||
|
||||
/**
|
||||
* Configures the given new lines for this hidden region.
|
||||
* Keeps the current configuration if it is in the valid boundaries
|
||||
* of {@code minNewLines} and {@code maxNewLines}. Applies {@code defaultNewLines}
|
||||
* otherwise.
|
||||
*/
|
||||
void setNewLines(int minNewLines, int defaultNewLines, int maxNewLines);
|
||||
|
||||
/**
|
||||
* No space is added at this hidden region.
|
||||
* Same as {@link #setSpace(String) setSpace("")}.
|
||||
*/
|
||||
void noSpace();
|
||||
|
||||
/**
|
||||
* One space is added at this hidden region.
|
||||
* Same as {@link #setSpace(String) setSpace(" ")}.
|
||||
*/
|
||||
void oneSpace();
|
||||
|
||||
/**
|
||||
* The given space is used for this hidden region.
|
||||
*/
|
||||
void setSpace(String space);
|
||||
|
||||
}
|
|
@ -10,13 +10,17 @@ package org.eclipse.xtext.formatting2;
|
|||
import org.eclipse.xtext.formatting2.internal.HiddenRegionFormatting;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* HiddenRegionFormatting specifies formatting information for a HiddenRegion. A HiddenRegion is the group of all hidden
|
||||
* tokens (whitespace and commend) between to non-hidden tokens.
|
||||
*
|
||||
* HiddenRegionFormattings can sometimes be automatically merged when two are registered for the same region in an
|
||||
* {@link IFormattableDocument}.
|
||||
* tokens (whitespace and comments) between to non-hidden tokens.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* HiddenRegionFormattings can sometimes be automatically {@link #mergeValuesFrom(IHiddenRegionFormatting) merged} when
|
||||
* two different formattings are registered for the same region in an {@link IFormattableDocument}.
|
||||
* </p>
|
||||
*
|
||||
* @see IHiddenRegionFormatter
|
||||
* @noimplement This interface is not intended to be implemented by clients, use {@link HiddenRegionFormatting}
|
||||
* @noextend This interface is not intended to be extended by clients, use {@link HiddenRegionFormatting}
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
|
@ -40,7 +44,7 @@ public interface IHiddenRegionFormatting {
|
|||
|
||||
Integer getNewLineMin();
|
||||
|
||||
Boolean getNoIndetation();
|
||||
Boolean getNoIndentation();
|
||||
|
||||
IAutowrapFormatter getOnAutowrap();
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ package org.eclipse.xtext.formatting2;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Generic interface to describe an external merger for some
|
||||
* mergable type.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
*/
|
||||
|
|
|
@ -8,10 +8,15 @@
|
|||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
/**
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* An ISubFormatter is responsible to format a sub document.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
*/
|
||||
public interface ISubFormatter {
|
||||
/**
|
||||
* Format the given document or throw a {@link FormattingNotApplicableException}
|
||||
* if the document cannot be formatted by this formatter.
|
||||
*/
|
||||
void format(IFormattableSubDocument document) throws FormattingNotApplicableException;
|
||||
}
|
|
@ -8,6 +8,9 @@
|
|||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
/**
|
||||
* A replacement describes which new text is to be inserted
|
||||
* at a given offset and length.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
*/
|
||||
|
|
|
@ -10,17 +10,24 @@ package org.eclipse.xtext.formatting2;
|
|||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
* A TextReplacer is responsible for a text region inside a {@link IFormattableDocument} and produces
|
||||
* {@link ITextReplacement}s for that region.
|
||||
* <p>
|
||||
* A TextReplacer is responsible for a {@link ITextSegment text region} inside a {@link IFormattableDocument} and
|
||||
* produces {@link ITextReplacement replacements} for that region.
|
||||
* </p>
|
||||
*
|
||||
* The {@link IFormattableDocument} ensures that TextReplacers are executed in the correct order, i.e. from the
|
||||
* beginning of the document to the end of the document.
|
||||
* <p>
|
||||
* The {@link IFormattableDocument} ensures that replacers are executed in the correct order, i.e. from the beginning of
|
||||
* the document to the end of the document.
|
||||
* </p>
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
*/
|
||||
public interface ITextReplacer {
|
||||
|
||||
/**
|
||||
* A function that maps a given replacer to the region that it replaces.
|
||||
*/
|
||||
public final static Function<ITextReplacer, ITextSegment> GET_REGION = new Function<ITextReplacer, ITextSegment>() {
|
||||
@Override
|
||||
public ITextSegment apply(ITextReplacer input) {
|
||||
|
@ -28,7 +35,14 @@ public interface ITextReplacer {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The replaced region.
|
||||
*/
|
||||
ITextSegment getRegion();
|
||||
|
||||
/**
|
||||
* Creates the real replacements for this region. The given context
|
||||
* may be altered and returned afterwards.
|
||||
*/
|
||||
ITextReplacerContext createReplacements(ITextReplacerContext context);
|
||||
}
|
||||
|
|
|
@ -10,10 +10,12 @@ package org.eclipse.xtext.formatting2;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Relevant state and methods during execution of a TextReplacer.
|
||||
* Relevant state and methods during execution of a {@link ITextReplacer text replacer}.
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
* @since 2.8
|
||||
* @author Moritz Eysholdt - Initial API and implementation
|
||||
*/
|
||||
public interface ITextReplacerContext {
|
||||
|
||||
|
@ -25,6 +27,11 @@ public interface ITextReplacerContext {
|
|||
|
||||
int getIndentation();
|
||||
|
||||
/**
|
||||
* Returns the current indentation as a string.
|
||||
* @see #getIndentationString(int)
|
||||
* @see #getIndentation()
|
||||
*/
|
||||
String getIndentationString();
|
||||
|
||||
String getIndentationString(int indentationLevel);
|
||||
|
@ -47,7 +54,7 @@ public interface ITextReplacerContext {
|
|||
|
||||
void replaceText(CharSequence text);
|
||||
|
||||
void replaceText(int offset, int lenght, CharSequence text);
|
||||
void replaceText(int offset, int length, CharSequence text);
|
||||
|
||||
void replaceText(ITextReplacement replacement);
|
||||
|
||||
|
@ -60,6 +67,8 @@ public interface ITextReplacerContext {
|
|||
void setNextReplacerIsChild();
|
||||
|
||||
ITextReplacerContext withIndentation(int indentation);
|
||||
|
||||
ITextReplacerContext withDocument(IFormattableDocument document);
|
||||
|
||||
ITextReplacerContext withReplacer(ITextReplacer replacer);
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@ import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;
|
|||
import org.eclipse.xtext.util.ITextRegion;
|
||||
|
||||
/**
|
||||
* A text segment describes a part of a document and carries a few more information,
|
||||
* e.g. about the current indentation level.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
*/
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -22,25 +21,15 @@ import org.eclipse.xtext.formatting2.internal.TextReplacementList;
|
|||
*/
|
||||
public class TextReplacements {
|
||||
/**
|
||||
* Applies all 'replacements' on 'input'.
|
||||
* <p>Applies all 'replacements' on 'input'.</p>
|
||||
*
|
||||
* Replaces the text regions in 'input' identified by {@link ITextReplacement#getOffset()} and
|
||||
* {@link ITextReplacement#getLength()} with {@link ITextReplacement#getReplacementText()}.
|
||||
* <p>Replaces the text regions in 'input' identified by {@link ITextReplacement#getOffset()} and
|
||||
* {@link ITextReplacement#getLength()} with {@link ITextReplacement#getReplacementText()}.</p>
|
||||
*
|
||||
* @return The text after the replacements have been applied.
|
||||
*/
|
||||
public static String apply(CharSequence input, Iterable<? extends ITextReplacement> replacements) {
|
||||
ArrayList<ITextReplacement> list = new TextReplacementList<ITextReplacement>(replacements);
|
||||
Collections.sort(list);
|
||||
int lastOffset = 0;
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (ITextReplacement r : list) {
|
||||
result.append(input.subSequence(lastOffset, r.getOffset()));
|
||||
result.append(r.getReplacementText());
|
||||
lastOffset = r.getOffset() + r.getLength();
|
||||
}
|
||||
result.append(input.subSequence(lastOffset, input.length()));
|
||||
return result.toString();
|
||||
return doApply(input, 0, replacements);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,18 +37,20 @@ public class TextReplacements {
|
|||
* is treated as relative to {@link ITextSegment#getOffset()} from 'input'.
|
||||
*/
|
||||
public static String apply(ITextSegment input, Iterable<? extends ITextReplacement> replacements) {
|
||||
return doApply(input.getText(), input.getOffset(), replacements);
|
||||
}
|
||||
|
||||
private static String doApply(CharSequence input, int offset, Iterable<? extends ITextReplacement> replacements) {
|
||||
List<ITextReplacement> list = new TextReplacementList<ITextReplacement>(replacements);
|
||||
Collections.sort(list);
|
||||
String text = input.getText();
|
||||
int offset = input.getOffset();
|
||||
int lastOffset = 0;
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (ITextReplacement r : list) {
|
||||
result.append(text.subSequence(lastOffset, r.getOffset() - offset));
|
||||
result.append(input.subSequence(lastOffset, r.getOffset() - offset));
|
||||
result.append(r.getReplacementText());
|
||||
lastOffset = (r.getOffset() - offset) + r.getLength();
|
||||
}
|
||||
result.append(text.subSequence(lastOffset, text.length()));
|
||||
result.append(input.subSequence(lastOffset, input.length()));
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,23 +54,23 @@ public class TextRegionListToString {
|
|||
@Override
|
||||
public String toString() {
|
||||
int offsetDigits = 0;
|
||||
int lenghtDigits = 0;
|
||||
int lengthDigits = 0;
|
||||
for (Item item : items) {
|
||||
if (item.region != null) {
|
||||
int lenghtD = String.valueOf(item.region.getLength()).length();
|
||||
if (lenghtDigits < lenghtD)
|
||||
lenghtDigits = lenghtD;
|
||||
int lenghtO = String.valueOf(item.region.getOffset()).length();
|
||||
if (offsetDigits < lenghtO)
|
||||
offsetDigits = lenghtO;
|
||||
int lengthD = String.valueOf(item.region.getLength()).length();
|
||||
if (lengthDigits < lengthD)
|
||||
lengthDigits = lengthD;
|
||||
int lengthO = String.valueOf(item.region.getOffset()).length();
|
||||
if (offsetDigits < lengthO)
|
||||
offsetDigits = lengthO;
|
||||
}
|
||||
}
|
||||
List<String> result = Lists.newArrayListWithExpectedSize(items.size());
|
||||
String prefix = Strings.repeat(" ", offsetDigits + lenghtDigits + 2);
|
||||
String prefix = Strings.repeat(" ", offsetDigits + lengthDigits + 2);
|
||||
for (Item item : items) {
|
||||
if (item.region != null) {
|
||||
String offset = Strings.padStart(String.valueOf(item.region.getOffset()), offsetDigits, ' ');
|
||||
String length = Strings.padStart(String.valueOf(item.region.getLength()), lenghtDigits, ' ');
|
||||
String length = Strings.padStart(String.valueOf(item.region.getLength()), lengthDigits, ' ');
|
||||
result.add(offset + " " + length + " " + item.text);
|
||||
} else if (item.indented) {
|
||||
result.add(prefix + item.text);
|
||||
|
|
|
@ -44,15 +44,15 @@ public class TextRegionsInTextToString {
|
|||
protected String box(String title, String content) {
|
||||
final int width = 80;
|
||||
final int min = 3;
|
||||
int titleLenght = title.length() + 2;
|
||||
final int left = Math.max((width - titleLenght) / 2, min);
|
||||
int titleLength = title.length() + 2;
|
||||
final int left = Math.max((width - titleLength) / 2, min);
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(Strings.repeat("-", left));
|
||||
result.append(" ");
|
||||
result.append(title);
|
||||
result.append(" ");
|
||||
if (left > min)
|
||||
result.append(Strings.repeat("-", width - left - titleLenght));
|
||||
result.append(Strings.repeat("-", width - left - titleLength));
|
||||
result.append("\n");
|
||||
result.append(org.eclipse.xtext.util.Strings.trimTrailingLineBreak(content));
|
||||
result.append("\n");
|
||||
|
|
|
@ -59,11 +59,11 @@ public class TextRegionsToString {
|
|||
return "<" + region.getOffset() + ":" + region.getLength() + "|" + replacement + ">";
|
||||
}
|
||||
|
||||
protected String quote(String string, int maxLenght) {
|
||||
protected String quote(String string, int maxLength) {
|
||||
if (string == null)
|
||||
return "null";
|
||||
if (string.length() > maxLenght)
|
||||
string = string.substring(0, maxLenght - 3) + "...";
|
||||
if (string.length() > maxLength)
|
||||
string = string.substring(0, maxLength - 3) + "...";
|
||||
string = string.replace("\n", "\\n").replace("\r", "\\r");
|
||||
return "\"" + string + "\"";
|
||||
}
|
||||
|
|
|
@ -56,15 +56,15 @@ public class TextRegionsWithTitleToString {
|
|||
protected String box(String title, String content) {
|
||||
final int width = 80;
|
||||
final int min = 3;
|
||||
int titleLenght = title.length() + 2;
|
||||
final int left = Math.max((width - titleLenght) / 2, min);
|
||||
int titleLength = title.length() + 2;
|
||||
final int left = Math.max((width - titleLength) / 2, min);
|
||||
StringBuilder result = new StringBuilder();
|
||||
result.append(Strings.repeat("-", left));
|
||||
result.append(" ");
|
||||
result.append(title);
|
||||
result.append(" ");
|
||||
if (left > min)
|
||||
result.append(Strings.repeat("-", width - left - titleLenght));
|
||||
result.append(Strings.repeat("-", width - left - titleLength));
|
||||
result.append("\n");
|
||||
result.append(org.eclipse.xtext.util.Strings.trimTrailingLineBreak(content));
|
||||
result.append("\n");
|
||||
|
@ -139,7 +139,7 @@ public class TextRegionsWithTitleToString {
|
|||
for (int i = 0; i < this.items.size(); i++) {
|
||||
Item item = this.items.get(i);
|
||||
ITextSegment region = item.getRegion();
|
||||
String regionStr = "offset=" + region.getOffset() + " lenght=" + region.getLength();
|
||||
String regionStr = "offset=" + region.getOffset() + " length=" + region.getLength();
|
||||
String open = i < BRACKETS_OPEN.length ? BRACKETS_OPEN[i] : "[" + i + "[";
|
||||
String close = i < BRACKETS_CLOSE.length ? BRACKETS_CLOSE[i] : "]" + i + "]";
|
||||
builder.append(open + close + ": " + item.getTitle() + " at " + regionStr + "\n");
|
||||
|
|
|
@ -74,11 +74,11 @@ public class TokenAccessToString {
|
|||
return hightlightOrigin;
|
||||
}
|
||||
|
||||
protected String quote(String string, int maxLenght) {
|
||||
protected String quote(String string, int maxLength) {
|
||||
if (string == null)
|
||||
return "null";
|
||||
if (string.length() > maxLenght)
|
||||
string = string.substring(0, maxLenght - 3) + "...";
|
||||
if (string.length() > maxLength)
|
||||
string = string.substring(0, maxLength - 3) + "...";
|
||||
string = string.replace("\n", "\\n").replace("\r", "\\r");
|
||||
return "\"" + string + "\"";
|
||||
}
|
||||
|
|
|
@ -82,13 +82,13 @@ public class ArrayListTextSegmentSet<T> extends TextSegmentSet<T> {
|
|||
contents.add(low + 1, merged);
|
||||
} else {
|
||||
int segmentLengh = getRegion(segment).getLength();
|
||||
int totalLenght = 0;
|
||||
int totalLength = 0;
|
||||
for (int i = 1; i < conflicting.size(); i++)
|
||||
totalLenght += getRegion(conflicting.get(i)).getLength();
|
||||
if (segmentLengh >= totalLenght)
|
||||
totalLength += getRegion(conflicting.get(i)).getLength();
|
||||
if (segmentLengh >= totalLength)
|
||||
for (int i = high - 1; i > low; i--)
|
||||
contents.remove(i);
|
||||
if (segmentLengh > totalLenght) {
|
||||
if (segmentLengh > totalLength) {
|
||||
getTraces().put(segment, new RegionTrace(getTitle(segment), getRegion(segment)));
|
||||
contents.add(low + 1, segment);
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ import com.google.common.base.Predicate;
|
|||
*/
|
||||
public class FilteredSubDocument extends SubDocument {
|
||||
|
||||
private final Predicate<ITextReplacer> filter;
|
||||
private final Predicate<? super ITextReplacer> filter;
|
||||
|
||||
public FilteredSubDocument(ITextSegment region, IFormattableDocument parent, Predicate<ITextReplacer> filter) {
|
||||
public FilteredSubDocument(ITextSegment region, IFormattableDocument parent, Predicate<? super ITextReplacer> filter) {
|
||||
super(region, parent);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ISemanticRegion append(ISemanticRegion token, Procedure1<IHiddenRegionFormatter> after) {
|
||||
public ISemanticRegion append(ISemanticRegion token, Procedure1<? super IHiddenRegionFormatter> after) {
|
||||
if (token != null) {
|
||||
IHiddenRegion gap = token.getNextHiddenRegion();
|
||||
set(gap, after);
|
||||
|
@ -82,7 +82,7 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T extends EObject> T append(T owner, Procedure1<IHiddenRegionFormatter> after) {
|
||||
public <T extends EObject> T append(T owner, Procedure1<? super IHiddenRegionFormatter> after) {
|
||||
if (owner != null) {
|
||||
IHiddenRegion gap = getTextRegionAccess().trailingHiddenRegion(owner);
|
||||
set(gap, after);
|
||||
|
@ -111,7 +111,7 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
|
||||
protected ITextReplacerContext createReplacements(ITextReplacerContext previous) {
|
||||
Integer maxLineWidth = getRequest().getPreferences().getPreference(FormatterPreferenceKeys.maxLineWidth);
|
||||
ITextReplacerContext context = ((TextReplacerContext) previous).withDocument(this);
|
||||
ITextReplacerContext context = previous.withDocument(this);
|
||||
ITextReplacerContext wrappable = null;
|
||||
Set<ITextReplacer> wrapped = Sets.newHashSet();
|
||||
LinkedList<ITextReplacer> queue = new LinkedList<ITextReplacer>();
|
||||
|
@ -149,7 +149,7 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
}
|
||||
context = nextContext;
|
||||
}
|
||||
return ((TextReplacerContext) context).withDocument(previous.getDocument());
|
||||
return context.withDocument(previous.getDocument());
|
||||
}
|
||||
|
||||
protected TextSegmentSet<ITextReplacer> createTextReplacerSet() {
|
||||
|
@ -203,7 +203,7 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ISemanticRegion prepend(ISemanticRegion token, Procedure1<IHiddenRegionFormatter> before) {
|
||||
public ISemanticRegion prepend(ISemanticRegion token, Procedure1<? super IHiddenRegionFormatter> before) {
|
||||
if (token != null) {
|
||||
IHiddenRegion gap = token.getPreviousHiddenRegion();
|
||||
set(gap, before);
|
||||
|
@ -212,7 +212,7 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T extends EObject> T prepend(T owner, Procedure1<IHiddenRegionFormatter> before) {
|
||||
public <T extends EObject> T prepend(T owner, Procedure1<? super IHiddenRegionFormatter> before) {
|
||||
if (owner != null) {
|
||||
IHiddenRegion gap = getTextRegionAccess().leadingHiddenRegion(owner);
|
||||
set(gap, before);
|
||||
|
@ -220,6 +220,7 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ITextReplacement> renderToTextReplacements() {
|
||||
ITextReplacerContext first = getFormatter().createTextReplacerContext(this);
|
||||
ITextReplacerContext last = createReplacements(first);
|
||||
|
@ -228,11 +229,11 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IHiddenRegion set(IHiddenRegion hiddenRegion, Procedure1<IHiddenRegionFormatter> init) {
|
||||
public IHiddenRegion set(IHiddenRegion hiddenRegion, Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
if (hiddenRegion != null) {
|
||||
AbstractFormatter2 formatter = getFormatter();
|
||||
IHiddenRegionFormatting formatting = formatter.createHiddenRegionFormatting();
|
||||
init.apply((IHiddenRegionFormatter) formatting);
|
||||
init.apply(formatting.asFormatter());
|
||||
ITextReplacer replacer = formatter.createHiddenRegionReplacer(hiddenRegion, formatting);
|
||||
addReplacer(replacer);
|
||||
}
|
||||
|
@ -240,14 +241,14 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ISemanticRegion surround(ISemanticRegion token, Procedure1<IHiddenRegionFormatter> beforeAndAfter) {
|
||||
public ISemanticRegion surround(ISemanticRegion token, Procedure1<? super IHiddenRegionFormatter> beforeAndAfter) {
|
||||
prepend(token, beforeAndAfter);
|
||||
append(token, beforeAndAfter);
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends EObject> T surround(T owner, Procedure1<IHiddenRegionFormatter> beforeAndAfter) {
|
||||
public <T extends EObject> T surround(T owner, Procedure1<? super IHiddenRegionFormatter> beforeAndAfter) {
|
||||
prepend(owner, beforeAndAfter);
|
||||
append(owner, beforeAndAfter);
|
||||
return owner;
|
||||
|
@ -264,7 +265,7 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IFormattableSubDocument withReplacerFilter(Predicate<ITextReplacer> filter) {
|
||||
public IFormattableSubDocument withReplacerFilter(Predicate<? super ITextReplacer> filter) {
|
||||
return new FilteredSubDocument(getRegion(), this, filter);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@ public class HiddenRegionFormatting implements IHiddenRegionFormatter, IHiddenRe
|
|||
}
|
||||
|
||||
@Override
|
||||
public void autowrap(int triggerLenght) {
|
||||
autowrap = triggerLenght;
|
||||
public void autowrap(int triggerLength) {
|
||||
autowrap = triggerLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -96,7 +96,7 @@ public class HiddenRegionFormatting implements IHiddenRegionFormatter, IHiddenRe
|
|||
}
|
||||
|
||||
@Override
|
||||
public Boolean getNoIndetation() {
|
||||
public Boolean getNoIndentation() {
|
||||
return noIndentation;
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ public class HiddenRegionFormatting implements IHiddenRegionFormatter, IHiddenRe
|
|||
setNewLinesMax(merge(getNewLineMax(), other.getNewLineMax(), strategy, "newLineMax"));
|
||||
setAutowrap(merge(getAutowrap(), other.getAutowrap(), strategy, "autowrap"));
|
||||
setOnAutowrap(merge(getOnAutowrap(), other.getOnAutowrap(), strategy, "onAutowrap"));
|
||||
setNoIndentation(merge(getNoIndetation(), other.getNoIndetation(), strategy, "noIndentation"));
|
||||
setNoIndentation(merge(getNoIndentation(), other.getNoIndentation(), strategy, "noIndentation"));
|
||||
|
||||
if (getIndentationIncrease() != null && other.getIndentationIncrease() != null)
|
||||
setIndentationIncrease(getIndentationIncrease() + other.getIndentationIncrease());
|
||||
|
|
|
@ -19,7 +19,7 @@ public class RegionTrace extends RuntimeException {
|
|||
private final ITextSegment region;
|
||||
|
||||
public RegionTrace(String message, ITextSegment region) {
|
||||
super(message + " at offset=" + region.getOffset() + " lenght=" + region.getLength());
|
||||
super(message + " at offset=" + region.getOffset() + " length=" + region.getLength());
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,13 +110,13 @@ public class TextReplacerContext implements ITextReplacerContext {
|
|||
String between = access.getText(endOffset, lastOffset - endOffset);
|
||||
int idx = between.lastIndexOf('\n');
|
||||
if (idx >= 0)
|
||||
return count + logicalLenght(between.substring(idx + 1));
|
||||
count += logicalLenght(between);
|
||||
return count + logicalLength(between.substring(idx + 1));
|
||||
count += logicalLength(between);
|
||||
String text = rep.getReplacementText();
|
||||
int idx2 = text.lastIndexOf('\n');
|
||||
if (idx2 >= 0)
|
||||
return count + logicalLenght(text.substring(idx2 + 1));
|
||||
count += logicalLenght(text);
|
||||
return count + logicalLength(text.substring(idx2 + 1));
|
||||
count += logicalLength(text);
|
||||
lastOffset = rep.getOffset();
|
||||
}
|
||||
current = current.getPreviousContext();
|
||||
|
@ -124,7 +124,7 @@ public class TextReplacerContext implements ITextReplacerContext {
|
|||
String rest = access.getText(0, lastOffset);
|
||||
int idx = rest.lastIndexOf('\n');
|
||||
if (idx >= 0)
|
||||
return count + logicalLenght(rest.substring(idx + 1));
|
||||
return count + logicalLength(rest.substring(idx + 1));
|
||||
count += lastOffset;
|
||||
return count;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ public class TextReplacerContext implements ITextReplacerContext {
|
|||
return true; // TODO: implement
|
||||
}
|
||||
|
||||
protected int logicalLenght(String text) {
|
||||
protected int logicalLength(String text) {
|
||||
ITypedPreferenceValues preferences = getDocument().getRequest().getPreferences();
|
||||
String indentation = preferences.getPreference(FormatterPreferenceKeys.indentation);
|
||||
if (!"\t".equals(indentation))
|
||||
|
@ -214,9 +214,9 @@ public class TextReplacerContext implements ITextReplacerContext {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void replaceText(int offset, int lenght, CharSequence text) {
|
||||
public void replaceText(int offset, int length, CharSequence text) {
|
||||
Preconditions.checkNotNull(text);
|
||||
ITextReplacement replacement = document.getFormatter().createTextReplacement(offset, lenght, text.toString());
|
||||
ITextReplacement replacement = document.getFormatter().createTextReplacement(offset, length, text.toString());
|
||||
replaceText(replacement);
|
||||
}
|
||||
|
||||
|
@ -299,6 +299,7 @@ public class TextReplacerContext implements ITextReplacerContext {
|
|||
return Joiner.on("; ").join(items);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextReplacerContext withDocument(IFormattableDocument document) {
|
||||
TextReplacerContext context = new TextReplacerContext(document, this, indentation, null);
|
||||
if (this.nextReplacerIsChild)
|
||||
|
|
|
@ -86,7 +86,7 @@ public class WhitespaceReplacer implements ITextReplacer {
|
|||
if (space != null)
|
||||
context.replaceText(region, space);
|
||||
} else {
|
||||
boolean noIndentation = formatting.getNoIndetation() == Boolean.TRUE;
|
||||
boolean noIndentation = formatting.getNoIndentation() == Boolean.TRUE;
|
||||
String newLines = context.getNewLinesString(newLineCount);
|
||||
String indentation = noIndentation ? "" : context.getIndentationString(indentationCount);
|
||||
context.replaceText(region, newLines + indentation);
|
||||
|
|
|
@ -1,31 +1,30 @@
|
|||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
/**
|
||||
* Xtext formatting infrastructure 2.0.
|
||||
* <p>Xtext formatting infrastructure since Xtext 2.8.</p>
|
||||
*
|
||||
* A formatter is responsible for arranging line-wraps, indentation, whitespace, etc. in a text document to improve is
|
||||
* <p>A formatter is responsible for arranging line-wraps, indentation, whitespace, etc. in a text document to improve its
|
||||
* readability and emphasize its structure. A formatter is not supposed to alter a document in a way that impacts the
|
||||
* semantic model.
|
||||
* semantic model.</p>
|
||||
*
|
||||
* This infrastructure is capable of formatting documents based on the node model and based on the serializer's output.
|
||||
* <p>This infrastructure is capable of formatting documents based on the node model and based on the serializer's output.
|
||||
* The actual formatting is done by constructing a list of text replacements. Applying the text replacement turns the
|
||||
* unformatted document into a formatted document. Purpose of this infrastructure is to make it convenient for
|
||||
* implementers to construct these text replacements.
|
||||
* implementers to construct these text replacements.</p>
|
||||
*
|
||||
* To run the formatter, you'll need to construct a {@link FormatterRequest}, get an instance of {@link IFormatter2}
|
||||
* from your language's Guice Injector and call {@link IFormatter2#format(FormatterRequest)}. The result will be a list
|
||||
* of text replacements. Use {@link TextReplacements#apply(CharSequence, Iterable)} to apply the replacements to a
|
||||
* String/CharSequence, if desired.
|
||||
* <p>To run the formatter, you'll need to construct a {@link org.eclipse.xtext.formatting2.FormatterRequest}, get an instance of {@link org.eclipse.xtext.formatting2.IFormatter2}
|
||||
* from your language's Guice Injector and call {@link org.eclipse.xtext.formatting2.IFormatter2#format(FormatterRequest)}. The result will be a list
|
||||
* of text replacements. Use {@link org.eclipse.xtext.formatting2.TextReplacements#apply(CharSequence, Iterable)} to apply the replacements to a
|
||||
* String/CharSequence, if desired.</p>
|
||||
*
|
||||
* To implement a formatter or to understand how to implement a formatter, see {@link AbstractFormatter2}.
|
||||
* <p>To implement a formatter or to understand how to implement a formatter, see {@link org.eclipse.xtext.formatting2.AbstractFormatter2}.</p>
|
||||
*
|
||||
* @see IFormatter2 - use this interface to invoke the formatter
|
||||
* @see AbstractFormatter2 - subclass this class to implement a formatter
|
||||
* @see ITextReplacement - a text-substitution at a defined offset inside a larger text
|
||||
* @see FormatterRequest - per-execution scoped configuration for the formatter.
|
||||
* Per-language configuration is handled by the Guice-Injector
|
||||
* @see org.eclipse.xtext.formatting2.IFormatter2 Use the IFormatter2 to invoke the formatter
|
||||
* @see org.eclipse.xtext.formatting2.AbstractFormatter2 Extend the AbstractFormatter2 to implement a formatter
|
||||
* @see org.eclipse.xtext.formatting2.FormatterRequest The FormatterRequest is a per-execution scoped configuration for the formatter.
|
||||
* Per-language configuration is handled by the injector
|
||||
* or {@link org.eclipse.xtext.formatting2.AbstractFormatter2}.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
* @since 2.8
|
||||
*/
|
||||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
|
|
|
@ -8,14 +8,13 @@
|
|||
package org.eclipse.xtext.formatting2.regionaccess;
|
||||
|
||||
/**
|
||||
* Represents a comment.
|
||||
* <p>Represents a comment.</p>
|
||||
*
|
||||
* For Xtext languages extending common.Terminals, these are tokens parsed with the terminal rules 'ML_COMMENT' and
|
||||
* 'SL_COMMENT'.
|
||||
* <p>For Xtext languages extending common.Terminals, these are tokens parsed with the terminal rules 'ML_COMMENT' and
|
||||
* 'SL_COMMENT'.</p>
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*
|
||||
*
|
||||
* @see IWhitespace
|
||||
* @see IHiddenRegionPart
|
||||
*
|
||||
|
|
|
@ -10,7 +10,7 @@ package org.eclipse.xtext.formatting2.regionaccess;
|
|||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents and groups all {@link IWhitespace} and {@link IComment}s between two {@link ISemanticRegion}s. May be
|
||||
* <p>Represents and groups all {@link IWhitespace} and {@link IComment comments} between two {@link ISemanticRegion semantic regions}. May be
|
||||
* empty.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
|
@ -30,7 +30,7 @@ public interface IHiddenRegion extends ISequentialRegion {
|
|||
boolean containsComment();
|
||||
|
||||
/**
|
||||
* @return all {@link IWhitespace}s and {@link IComment}s that belong to this {@link IHiddenRegion}.
|
||||
* @return all {@link IWhitespace white spaces} and {@link IComment comments} that belong to this {@link IHiddenRegion}.
|
||||
*/
|
||||
List<IHiddenRegionPart> getParts();
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.eclipse.xtext.TerminalRule;
|
|||
import org.eclipse.xtext.formatting2.ITextSegment;
|
||||
|
||||
/**
|
||||
* Super-Interface for {@link IWhitespace} and {@link IComment}.
|
||||
* Common interface for {@link IWhitespace} and {@link IComment}.
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*/
|
||||
|
|
|
@ -10,10 +10,10 @@ package org.eclipse.xtext.formatting2.regionaccess;
|
|||
import org.eclipse.xtext.formatting2.ITextSegment;
|
||||
|
||||
/**
|
||||
* Super-Interface for {@link IHiddenRegion} and {@link ISemanticRegion}.
|
||||
* <p>Common interface for {@link IHiddenRegion} and {@link ISemanticRegion}.</p>
|
||||
*
|
||||
* {@link IHiddenRegion} and {@link ISemanticRegion} are arranged strictly alternating in a linked list. This interface
|
||||
* provides the method to navigate that list.
|
||||
* <p>{@link IHiddenRegion} and {@link ISemanticRegion} are arranged strictly alternating in a linked list. This interface
|
||||
* provides the method to navigate that list.</p>
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*/
|
||||
|
|
|
@ -20,30 +20,29 @@ import org.eclipse.xtext.nodemodel.ILeafNode;
|
|||
import org.eclipse.xtext.resource.XtextResource;
|
||||
|
||||
/**
|
||||
* This class provides access to text regions ({@link ITextSegment}s) based on the semantic model. A text region
|
||||
* describes the offset and length in characters of a semantic elements within a text document.
|
||||
* <p>This class provides access to {@link ITextSegment text regions } based on the semantic model. A text region
|
||||
* describes the offset and length in characters of a semantic elements within a text document.</p>
|
||||
*
|
||||
* Technically, it is a lightweight facade over the node model or the serializer's output.
|
||||
* <p>Technically, it is a lightweight facade over the node model or the serializer's output.</p>
|
||||
*
|
||||
* The text regions are arranged as a linked list of strictly alternating {@link ISemanticRegion}s and
|
||||
* {@link IHiddenRegion}s. HiddenRegions group all hidden tokens (typically whitespace, newlines, tabs and comments)
|
||||
* <p>The text regions are arranged as a linked list of strictly alternating {@link ISemanticRegion semantic regions} and
|
||||
* {@link IHiddenRegion hidden region}. HiddenRegions group all hidden tokens (typically whitespace, newlines, tabs and comments)
|
||||
* between two semantic tokens. HiddenRegions are empty, but do exist, if there are no hidden tokens between two
|
||||
* semantic elements.
|
||||
* semantic elements.</p>
|
||||
*
|
||||
* Tokens are considered to be hidden, when they have been parsed via terminal rule referenced in "hidden(...)" in the
|
||||
* Xtext grammar. In the node model, hidden tokens carry {@link ILeafNode#isHidden()} == true.
|
||||
* <p>Tokens are considered to be hidden, when they have been parsed via terminal rule referenced in "hidden(...)" in the
|
||||
* Xtext grammar. In the node model, hidden tokens are usually marked as {@link ILeafNode#isHidden() hidden == true}.</p>
|
||||
*
|
||||
* A semantic token can be the value of an EAttribute, a CrossReference or a keyword.
|
||||
* <p>A semantic token can be the value of an EAttribute, a CrossReference or a keyword.</p>
|
||||
*
|
||||
* A {@link IHiddenRegion} contains a list of {@link IHiddenRegionPart}s, which are either {@link IWhitespace}s or
|
||||
* {@link IComment}s. A HidenRegion can be empty.
|
||||
* <p>A {@link IHiddenRegion} contains a list of {@link IHiddenRegionPart parts}, which are either {@link IWhitespace white space} or
|
||||
* {@link IComment comments}. A HiddenRegion can be empty.</p>
|
||||
*
|
||||
* The purpose of this class is:
|
||||
* <ul>
|
||||
* <li>Allow the formatter to operate on a parsed document (node model) and a serialized model.</li>
|
||||
* <li>Provide a convenient abstraction for formatting (tokens, HiddenRegions).
|
||||
* <li>Fast access to TextRegions. The node model would be too slow to traverse due to its large expression trees.</li>
|
||||
* <li>Shield users from surprises due to the node model's structure.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
|
@ -64,8 +63,8 @@ public interface ITextRegionAccess {
|
|||
ITextSegment expandRegionsByLines(int leadingLines, int trailingLines, ITextSegment... regions);
|
||||
|
||||
/**
|
||||
* @return The very first {@link IHiddenRegion} inside the linked list of alternating {@link IHiddenRegion}s and
|
||||
* {@link ISemanticRegion}s.
|
||||
* @return The very first {@link IHiddenRegion} inside the linked list of alternating {@link IHiddenRegion hidden regions} and
|
||||
* {@link ISemanticRegion semantic regions}.
|
||||
*/
|
||||
IHiddenRegion getFirstRegionInFile();
|
||||
|
||||
|
@ -75,7 +74,7 @@ public interface ITextRegionAccess {
|
|||
AbstractElement getInvokingGrammarElement(EObject obj);
|
||||
|
||||
/**
|
||||
* @return The XtextResource that backs the document this class provides access to.
|
||||
* @return The {@link XtextResource} that backs the document this class provides access to.
|
||||
*/
|
||||
XtextResource getResource();
|
||||
|
||||
|
@ -152,7 +151,7 @@ public interface ITextRegionAccess {
|
|||
ITextSegment regionForEObject(EObject object); // TODO: should be semantic region?
|
||||
|
||||
/**
|
||||
* @return returns the first {@link ISemanticRegion} that represents the value of owner.eGet(feature). May be null.
|
||||
* @return returns the first {@link ISemanticRegion} that represents the value of {@code owner.eGet(feature)}. May be null.
|
||||
*/
|
||||
ISemanticRegion regionForFeature(EObject owner, EStructuralFeature feature);
|
||||
|
||||
|
@ -169,13 +168,13 @@ public interface ITextRegionAccess {
|
|||
ISemanticRegion regionForRuleCallTo(EObject owner, AbstractRule rule);
|
||||
|
||||
/**
|
||||
* @return All {@link ISemanticRegion}s that represent one of the provided 'keyword's and directly belong to the
|
||||
* @return All {@link ISemanticRegion semantic regions} that represent one of the provided 'keyword's and directly belong to the
|
||||
* provided 'EObject'. Keywords of child-EObjects are not considered.
|
||||
*/
|
||||
List<ISemanticRegion> regionsForKeywords(EObject owner, String... string);
|
||||
|
||||
/**
|
||||
* @return All {@link ISemanticRegion}s that represent a RuleCall to one of the provided AbstractRules and directly
|
||||
* @return All {@link ISemanticRegion semantic regions} that represent a RuleCall to one of the provided AbstractRules and directly
|
||||
* belong to the provided 'EObject'. RuleCalls of child-EObjects are not considered. May be null.
|
||||
*/
|
||||
List<ISemanticRegion> regionsForRuleCallsTo(EObject owner, AbstractRule... rule);
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
package org.eclipse.xtext.formatting2.regionaccess;
|
||||
|
||||
/**
|
||||
* Represents a whitespace token inside a {@link IHiddenRegion}.
|
||||
* <p>Represents a whitespace token inside a {@link IHiddenRegion}.</p>
|
||||
*
|
||||
* Whitespace are usually hidden tokens for which all characters have {@link Character#isWhitespace(char)} == true.
|
||||
* <p>Whitespace are usually hidden tokens for which all characters have {@link Character#isWhitespace(char) isWhitespace == true}.</p>
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*
|
||||
|
@ -21,5 +21,4 @@ package org.eclipse.xtext.formatting2.regionaccess;
|
|||
* @since 2.8
|
||||
*/
|
||||
public interface IWhitespace extends IHiddenRegionPart {
|
||||
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package org.eclipse.xtext.formatting2.regionaccess;
|
||||
|
||||
/**
|
||||
* This package contains the {@link ITextRegionAccess} and related classes.
|
||||
* This package contains the {@link org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess} and related classes.
|
||||
* They map semantic model elements to regions within a text document.
|
||||
*
|
||||
* @see ITextRegionAccess
|
||||
* @see org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess
|
||||
*
|
||||
* @since 2.8
|
||||
*
|
||||
* @author Moritz Eysholdt - Initial contribution and API
|
||||
*/
|
||||
package org.eclipse.xtext.formatting2.regionaccess;
|
||||
|
||||
|
|
Loading…
Reference in a new issue