mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 08:48:55 +00:00
[formatter] several smaller improvements
- on exception, only cancle formatting of the current subtree - don't format EObjects located outside the requested regions - introduce document.interior(EObject, ) - introduce document.format for convenience - introduce formatter.shouldFormat() Signed-off-by: Moritz Eysholdt <moritz.eysholdt@itemis.de>
This commit is contained in:
parent
20fbbfaaf7
commit
14e4b55734
3 changed files with 94 additions and 31 deletions
|
@ -7,6 +7,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.formatting2;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.emf.ecore.EObject;
|
||||
|
@ -29,11 +30,12 @@ import org.eclipse.xtext.formatting2.internal.TextReplacerContext;
|
|||
import org.eclipse.xtext.formatting2.internal.TextReplacerMerger;
|
||||
import org.eclipse.xtext.formatting2.internal.WhitespaceReplacer;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.IComment;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionExtensions;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.IEObjectRegion;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegion;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.IHiddenRegionPart;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ISemanticRegion;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ITextRegionExtensions;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ITextReplacement;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ITextSegment;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.internal.TextRegions;
|
||||
|
@ -42,6 +44,7 @@ import org.eclipse.xtext.grammaranalysis.impl.GrammarElementTitleSwitch;
|
|||
import org.eclipse.xtext.preferences.ITypedPreferenceValues;
|
||||
import org.eclipse.xtext.preferences.TypedPreferenceKey;
|
||||
import org.eclipse.xtext.resource.XtextResource;
|
||||
import org.eclipse.xtext.util.ITextRegion;
|
||||
import org.eclipse.xtext.xbase.lib.Extension;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
@ -160,14 +163,14 @@ import com.google.common.collect.Lists;
|
|||
*/
|
||||
public abstract class AbstractFormatter2 implements IFormatter2 {
|
||||
|
||||
private FormatterRequest request = null;
|
||||
|
||||
/**
|
||||
* Offer subclasses access to the methods from {@link ITextRegionAccess} as extension methods.
|
||||
*/
|
||||
@Extension
|
||||
protected ITextRegionExtensions textRegionExtensions;
|
||||
|
||||
private FormatterRequest request = null;
|
||||
|
||||
/**
|
||||
* Fall-back for types that are not handled by a subclasse's dispatch method.
|
||||
*/
|
||||
|
@ -310,6 +313,27 @@ public abstract class AbstractFormatter2 implements IFormatter2 {
|
|||
this.textRegionExtensions = request.getTextRegionAccess().getExtensions();
|
||||
}
|
||||
|
||||
protected boolean isInRequestedRange(EObject obj) {
|
||||
Collection<ITextRegion> regions = request.getRegions();
|
||||
if (regions.isEmpty())
|
||||
return true;
|
||||
ITextRegionAccess access = request.getTextRegionAccess();
|
||||
IEObjectRegion objRegion = access.regionForEObject(obj);
|
||||
if (objRegion == null)
|
||||
return false;
|
||||
IHiddenRegion previousHidden = objRegion.getPreviousHiddenRegion();
|
||||
IHiddenRegion nextHidden = objRegion.getNextHiddenRegion();
|
||||
int objOffset = previousHidden != null ? previousHidden.getOffset() : 0;
|
||||
int objEnd = nextHidden != null ? nextHidden.getEndOffset() : access.regionForRootEObject().getEndOffset();
|
||||
for (ITextRegion region : regions) {
|
||||
int regionOffset = region.getOffset();
|
||||
int regionEnd = regionOffset + region.getLength();
|
||||
if (regionOffset <= objEnd && regionEnd >= objOffset)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected List<ITextReplacement> postProcess(IFormattableDocument document, List<ITextReplacement> replacements) {
|
||||
List<ITextSegment> expected = Lists.newArrayList();
|
||||
IHiddenRegion current = getTextRegionAccess().regionForRootEObject().getPreviousHiddenRegion();
|
||||
|
@ -347,4 +371,10 @@ public abstract class AbstractFormatter2 implements IFormatter2 {
|
|||
this.textRegionExtensions = null;
|
||||
}
|
||||
|
||||
public boolean shouldFormat(Object obj, IFormattableDocument document) {
|
||||
if (obj instanceof EObject)
|
||||
return isInRequestedRange((EObject) obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -161,4 +161,8 @@ public interface IFormattableDocument {
|
|||
|
||||
<T1 extends ISemanticRegion, T2 extends ISemanticRegion> //
|
||||
Pair<T1, T2> interior(Pair<T1, T2> pair, Procedure1<? super IHiddenRegionFormatter> init);
|
||||
|
||||
<T extends EObject> T interior(T object, Procedure1<? super IHiddenRegionFormatter> init);
|
||||
|
||||
<T> T format(T obj);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.xtext.formatting2.regionaccess.ITextRegionAccess;
|
|||
import org.eclipse.xtext.formatting2.regionaccess.ITextReplacement;
|
||||
import org.eclipse.xtext.formatting2.regionaccess.ITextSegment;
|
||||
import org.eclipse.xtext.preferences.ITypedPreferenceValues;
|
||||
import org.eclipse.xtext.util.IAcceptor;
|
||||
import org.eclipse.xtext.util.Tuples;
|
||||
import org.eclipse.xtext.xbase.lib.Pair;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
||||
|
@ -171,6 +172,20 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T format(T obj) {
|
||||
AbstractFormatter2 formatter = getFormatter();
|
||||
if (formatter.shouldFormat(obj, this)) {
|
||||
try {
|
||||
formatter.format(obj, this);
|
||||
} catch (Exception e) {
|
||||
IAcceptor<Exception> handler = getRequest().getExceptionHandler();
|
||||
handler.accept(e);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void formatConditionally(EObject owner, ISubFormatter... formatters) {
|
||||
IEObjectRegion region = getTextRegionAccess().regionForEObject(owner);
|
||||
|
@ -192,6 +207,36 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
return getRequest().getTextRegionAccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T1 extends ISemanticRegion, T2 extends ISemanticRegion> //
|
||||
Pair<T1, T2> interior(Pair<T1, T2> pair, Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
return interior(pair.getKey(), pair.getValue(), init);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends EObject> T interior(T object, Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
if (object != null) {
|
||||
IEObjectRegion objRegion = getTextRegionAccess().regionForEObject(object);
|
||||
if (objRegion != null) {
|
||||
IHiddenRegion previous = objRegion.getPreviousHiddenRegion();
|
||||
IHiddenRegion next = objRegion.getNextHiddenRegion();
|
||||
if (previous != null && next != null && previous != next) {
|
||||
interior(previous.getNextSemanticRegion(), next.getPreviousSemanticRegion(), init);
|
||||
}
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T1 extends ISemanticRegion, T2 extends ISemanticRegion> //
|
||||
Pair<T1, T2> interior(T1 first, T2 second, Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
if (first != null && second != null) {
|
||||
set(first.getNextHiddenRegion(), second.getPreviousHiddenRegion(), init);
|
||||
}
|
||||
return Pair.of(first, second);
|
||||
}
|
||||
|
||||
protected boolean needsAutowrap(ITextReplacerContext wrappable, ITextReplacerContext context, int maxLineWidth) {
|
||||
if (context.getLeadingCharsInLineCount() > maxLineWidth)
|
||||
return true;
|
||||
|
@ -238,18 +283,6 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
return replacements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IHiddenRegion set(IHiddenRegion hiddenRegion, Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
if (hiddenRegion != null) {
|
||||
AbstractFormatter2 formatter = getFormatter();
|
||||
IHiddenRegionFormatting formatting = formatter.createHiddenRegionFormatting();
|
||||
init.apply(formatter.createHiddenRegionFormatter(formatting));
|
||||
ITextReplacer replacer = formatter.createHiddenRegionReplacer(hiddenRegion, formatting);
|
||||
addReplacer(replacer);
|
||||
}
|
||||
return hiddenRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<IHiddenRegion, IHiddenRegion> set(IHiddenRegion first, IHiddenRegion second,
|
||||
Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
|
@ -266,6 +299,18 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
return Pair.of(first, second);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IHiddenRegion set(IHiddenRegion hiddenRegion, Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
if (hiddenRegion != null) {
|
||||
AbstractFormatter2 formatter = getFormatter();
|
||||
IHiddenRegionFormatting formatting = formatter.createHiddenRegionFormatting();
|
||||
init.apply(formatter.createHiddenRegionFormatter(formatting));
|
||||
ITextReplacer replacer = formatter.createHiddenRegionReplacer(hiddenRegion, formatting);
|
||||
addReplacer(replacer);
|
||||
}
|
||||
return hiddenRegion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISemanticRegion surround(ISemanticRegion token, Procedure1<? super IHiddenRegionFormatter> beforeAndAfter) {
|
||||
if (token != null) {
|
||||
|
@ -287,21 +332,6 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
return owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T1 extends ISemanticRegion, T2 extends ISemanticRegion> //
|
||||
Pair<T1, T2> interior(Pair<T1, T2> pair, Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
return interior(pair.getKey(), pair.getValue(), init);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T1 extends ISemanticRegion, T2 extends ISemanticRegion> //
|
||||
Pair<T1, T2> interior(T1 first, T2 second, Procedure1<? super IHiddenRegionFormatter> init) {
|
||||
if (first != null && second != null) {
|
||||
set(first.getNextHiddenRegion(), second.getPreviousHiddenRegion(), init);
|
||||
}
|
||||
return Pair.of(first, second);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
TextRegionsToString toString = new TextRegionsToString();
|
||||
|
@ -316,5 +346,4 @@ public abstract class FormattableDocument implements IFormattableDocument {
|
|||
public IFormattableSubDocument withReplacerFilter(Predicate<? super ITextReplacer> filter) {
|
||||
return new FilteredSubDocument(getRegion(), this, filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue