From 5aef0db2fdecb92cb1e3d2e926cacb5dc3923a00 Mon Sep 17 00:00:00 2001 From: Soy Authors Date: Fri, 20 Mar 2020 13:10:59 -0700 Subject: [PATCH] Add SourceLocation.fullyContainsRange(SourceLocation other) for partial formatting. GITHUB_BREAKING_CHANGES=NA ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=302085853 --- .../template/soy/base/SourceLocation.java | 15 +++ .../soy/soyparse/SourceLocationTest.java | 95 +++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/java/src/com/google/template/soy/base/SourceLocation.java b/java/src/com/google/template/soy/base/SourceLocation.java index cde19fb9b8..9692f9b626 100644 --- a/java/src/com/google/template/soy/base/SourceLocation.java +++ b/java/src/com/google/template/soy/base/SourceLocation.java @@ -266,6 +266,21 @@ public SourceLocation.Point getBeginPoint() { return begin; } + /** Whether this source location fully contains the given {@code range}, inclusively. */ + public boolean fullyContainsRange(SourceLocation range) { + // If either location is unknown, return false. + if (!this.isKnown() || !range.isKnown()) { + return false; + } + // This source location should start before or at the same point as the given range. + boolean rangeStartsAfterOrAtBeginPoint = !this.begin.isAfter(range.begin); + + // This source location should end after or at the same point as the given range. + boolean rangeEndsAfterOrAtEndPoint = !this.end.isBefore(range.end); + + return rangeStartsAfterOrAtBeginPoint && rangeEndsAfterOrAtEndPoint; + } + /** Returns a new location that points to the last character of this location. */ public SourceLocation getEndLocation() { return new SourceLocation(filePath, end, end); diff --git a/java/tests/com/google/template/soy/soyparse/SourceLocationTest.java b/java/tests/com/google/template/soy/soyparse/SourceLocationTest.java index f3c3cc7485..1f5d70358d 100644 --- a/java/tests/com/google/template/soy/soyparse/SourceLocationTest.java +++ b/java/tests/com/google/template/soy/soyparse/SourceLocationTest.java @@ -55,6 +55,7 @@ public final class SourceLocationTest { private static final Joiner JOINER = Joiner.on('\n'); + private static final String FAKE_FILE_PATH = "fakefile.soy"; @Test public void testLocationsInParsedContent() throws Exception { @@ -833,6 +834,100 @@ public void testUnion() throws Exception { assertThat(innerRange.unionWith(outerRange)).isEqualTo(outerRange); } + @Test + public void testFullyContainsRange() throws Exception { + // One is a subset of another. + SourceLocation outerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(8, 7)); + SourceLocation innerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(2, 4), Point.create(5, 7)); + + assertThat(outerRange.fullyContainsRange(innerRange)).isTrue(); + assertThat(innerRange.fullyContainsRange(outerRange)).isFalse(); + } + + @Test + public void testFullyContainsRange_sameStartPoint() throws Exception { + // One is a subset of another. + SourceLocation outerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(8, 7)); + SourceLocation innerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(5, 7)); + + assertThat(outerRange.fullyContainsRange(innerRange)).isTrue(); + assertThat(innerRange.fullyContainsRange(outerRange)).isFalse(); + } + + @Test + public void testFullyContainsRange_sameEndPoint() throws Exception { + // One is a subset of another. + SourceLocation outerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(8, 7)); + SourceLocation innerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 5), Point.create(8, 7)); + + assertThat(outerRange.fullyContainsRange(innerRange)).isTrue(); + assertThat(innerRange.fullyContainsRange(outerRange)).isFalse(); + } + + @Test + public void testFullyContainsRange_sameRange() throws Exception { + // One is a subset of another. + SourceLocation outerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(8, 7)); + SourceLocation innerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(8, 7)); + + assertThat(outerRange.fullyContainsRange(innerRange)).isTrue(); + assertThat(innerRange.fullyContainsRange(outerRange)).isTrue(); + } + + @Test + public void testFullyContainsRange_failsIfEndsAfter() throws Exception { + // One is not a subset of another. + SourceLocation outerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(8, 7)); + SourceLocation innerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 5), Point.create(10, 7)); + + assertThat(outerRange.fullyContainsRange(innerRange)).isFalse(); + assertThat(innerRange.fullyContainsRange(outerRange)).isFalse(); + } + + @Test + public void testFullyContainsRange_failsIfBeginsBefore() throws Exception { + // One is a not subset of another. + SourceLocation outerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(8, 7)); + SourceLocation innerRange = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 1), Point.create(6, 7)); + + assertThat(outerRange.fullyContainsRange(innerRange)).isFalse(); + assertThat(innerRange.fullyContainsRange(outerRange)).isFalse(); + } + + @Test + public void testFullyContainsRange_failsIfBothUnknown() throws Exception { + SourceLocation range1 = + new SourceLocation(FAKE_FILE_PATH, Point.UNKNOWN_POINT, Point.UNKNOWN_POINT); + SourceLocation range2 = + new SourceLocation(FAKE_FILE_PATH, Point.UNKNOWN_POINT, Point.UNKNOWN_POINT); + + assertThat(range1.fullyContainsRange(range2)).isFalse(); + assertThat(range2.fullyContainsRange(range1)).isFalse(); + } + + @Test + public void testFullyContainsRange_failsIfOneUnknown() throws Exception { + SourceLocation range1 = + new SourceLocation(FAKE_FILE_PATH, Point.create(1, 3), Point.create(5, 8)); + SourceLocation range2 = + new SourceLocation(FAKE_FILE_PATH, Point.UNKNOWN_POINT, Point.UNKNOWN_POINT); + + assertThat(range1.fullyContainsRange(range2)).isFalse(); + assertThat(range2.fullyContainsRange(range1)).isFalse(); + } + @Test public void testRawTextSourceLocations() throws Exception { // RawTextNode has some special methods to calculating the source location of characters within