[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:
Moritz Eysholdt 2015-04-29 14:49:55 +02:00
parent 20fbbfaaf7
commit 14e4b55734
3 changed files with 94 additions and 31 deletions

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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);
}
}