diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/AbstractFormatter2.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/AbstractFormatter2.java index b739f05f7..0845957a6 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/AbstractFormatter2.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/AbstractFormatter2.java @@ -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 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 postProcess(IFormattableDocument document, List replacements) { List 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; + } + } diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/IFormattableDocument.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/IFormattableDocument.java index 1829b57da..29a6e6082 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/IFormattableDocument.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/IFormattableDocument.java @@ -161,4 +161,8 @@ public interface IFormattableDocument { // Pair interior(Pair pair, Procedure1 init); + + T interior(T object, Procedure1 init); + + T format(T obj); } diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/internal/FormattableDocument.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/internal/FormattableDocument.java index c2bad9052..eecd84804 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/internal/FormattableDocument.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/formatting2/internal/FormattableDocument.java @@ -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 format(T obj) { + AbstractFormatter2 formatter = getFormatter(); + if (formatter.shouldFormat(obj, this)) { + try { + formatter.format(obj, this); + } catch (Exception e) { + IAcceptor 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 // + Pair interior(Pair pair, Procedure1 init) { + return interior(pair.getKey(), pair.getValue(), init); + } + + @Override + public T interior(T object, Procedure1 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 // + Pair interior(T1 first, T2 second, Procedure1 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 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 set(IHiddenRegion first, IHiddenRegion second, Procedure1 init) { @@ -266,6 +299,18 @@ public abstract class FormattableDocument implements IFormattableDocument { return Pair.of(first, second); } + @Override + public IHiddenRegion set(IHiddenRegion hiddenRegion, Procedure1 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 beforeAndAfter) { if (token != null) { @@ -287,21 +332,6 @@ public abstract class FormattableDocument implements IFormattableDocument { return owner; } - @Override - public // - Pair interior(Pair pair, Procedure1 init) { - return interior(pair.getKey(), pair.getValue(), init); - } - - @Override - public // - Pair interior(T1 first, T2 second, Procedure1 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 filter) { return new FilteredSubDocument(getRegion(), this, filter); } - }