-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Source coordinates encode location in source files and information about these locations. They are used by parsers, debuggers, and other tools. Signed-off-by: Stefan Marr <[email protected]>
- Loading branch information
Showing
4 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package bd.source; | ||
|
||
import java.net.URI; | ||
import java.util.Objects; | ||
|
||
|
||
/** | ||
* Is a {@link SourceCoordinate} with an extra URI to identify it globally. | ||
* Otherwise, behaves the same. | ||
*/ | ||
public class FullSourceCoordinate extends SourceCoordinate { | ||
public final URI uri; | ||
|
||
protected FullSourceCoordinate(final URI uri, final int startLine, | ||
final int startColumn, final int charIndex, final int length) { | ||
super(startLine, startColumn, charIndex, length); | ||
this.uri = uri; | ||
} | ||
|
||
protected FullSourceCoordinate() { | ||
this(null, 0, 0, 0, 0); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
// ignore charIndex, not always set | ||
return Objects.hash(uri, startLine, startColumn, /* charIndex, */ charLength); | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (!(o instanceof FullSourceCoordinate)) { | ||
return false; | ||
} | ||
|
||
FullSourceCoordinate sc = (FullSourceCoordinate) o; | ||
// ignore charIndex, not always set | ||
return sc.uri.equals(uri) && | ||
sc.startLine == startLine && sc.startColumn == startColumn && | ||
// sc.charIndex == charIndex && | ||
sc.charLength == charLength; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "SrcCoord(line: " + startLine + ", col: " + startColumn + ", charlength:" | ||
+ charLength + ", uri: " + uri.getPath() + ")"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package bd.source; | ||
|
||
import java.net.URI; | ||
import java.net.URISyntaxException; | ||
import java.util.Set; | ||
|
||
import com.oracle.truffle.api.instrumentation.Tag; | ||
import com.oracle.truffle.api.source.Source; | ||
import com.oracle.truffle.api.source.SourceSection; | ||
|
||
|
||
/** | ||
* Represents a potentially empty range of source characters, for a potentially | ||
* not yet loaded source. | ||
* | ||
* <p> | ||
* The {@code charIndex} may not be set. It can be derived from startLine and startColumn, | ||
* if the source file is present. | ||
*/ | ||
public class SourceCoordinate { | ||
public final int startLine; | ||
public final int startColumn; | ||
public final transient int charIndex; | ||
public final int charLength; | ||
|
||
protected SourceCoordinate(final int startLine, final int startColumn, | ||
final int charIndex, final int length) { | ||
this.startLine = startLine; | ||
this.startColumn = startColumn; | ||
this.charIndex = charIndex; | ||
this.charLength = length; | ||
assert startLine >= 0; | ||
assert startColumn >= 0; | ||
assert charIndex >= 0 || charIndex == -1; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "SrcCoord(line: " + startLine + ", col: " + startColumn + ", charlength:" | ||
+ charLength + ")"; | ||
} | ||
|
||
public static SourceCoordinate createEmpty() { | ||
return new SourceCoordinate(0, 0, 0, 0); | ||
} | ||
|
||
public static SourceCoordinate create(final int startLine, final int startColumn, | ||
final int charIndex) { | ||
return new SourceCoordinate(startLine, startColumn, charIndex, 0); | ||
} | ||
|
||
public static SourceCoordinate create(final int startLine, final int startColumn, | ||
final int charIndex, final int length) { | ||
return new SourceCoordinate(startLine, startColumn, charIndex, length); | ||
} | ||
|
||
public static SourceCoordinate create(final SourceSection section) { | ||
return new SourceCoordinate(section.getStartLine(), section.getStartColumn(), | ||
section.getCharIndex(), section.getCharLength()); | ||
} | ||
|
||
public static FullSourceCoordinate createFull(final SourceSection section) { | ||
return new FullSourceCoordinate(section.getSource().getURI(), | ||
section.getStartLine(), section.getStartColumn(), | ||
section.getCharIndex(), section.getCharLength()); | ||
} | ||
|
||
public static FullSourceCoordinate create(final URI sourceUri, final int startLine, | ||
final int startColumn, final int charLength) { | ||
return new FullSourceCoordinate(sourceUri, startLine, startColumn, -1, charLength); | ||
} | ||
|
||
public static FullSourceCoordinate create(final String sourceUri, final int startLine, | ||
final int startColumn, final int charLength) { | ||
try { | ||
return create(new URI(sourceUri), startLine, startColumn, charLength); | ||
} catch (URISyntaxException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public static FullSourceCoordinate create(final String sourceUri, final int startLine, | ||
final int startColumn, final int charIndex, final int charLength) { | ||
try { | ||
return new FullSourceCoordinate( | ||
new URI(sourceUri), startLine, startColumn, charIndex, charLength); | ||
} catch (URISyntaxException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public static TaggedSourceCoordinate create(final SourceSection section, | ||
final Set<Class<? extends Tag>> tags) { | ||
String[] strTags = new String[tags.size()]; | ||
|
||
int i = 0; | ||
for (Class<? extends Tag> tagClass : tags) { | ||
strTags[i] = tagClass.getSimpleName(); | ||
i += 1; | ||
} | ||
|
||
return new TaggedSourceCoordinate(section.getStartLine(), section.getStartColumn(), | ||
section.getCharIndex(), section.getCharLength(), strTags); | ||
} | ||
|
||
public static String getLocationQualifier(final SourceSection section) { | ||
return ":" + section.getStartLine() + ":" + section.getStartColumn(); | ||
} | ||
|
||
public static String getURI(final Source source) { | ||
return source.getURI().toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package bd.source; | ||
|
||
/** | ||
* Is a {@link SourceCoordinate} with additional tags to characterize the source range. | ||
* Otherwise, behaves the same. | ||
*/ | ||
public class TaggedSourceCoordinate extends SourceCoordinate { | ||
public final String[] tags; | ||
|
||
protected TaggedSourceCoordinate(final int startLine, final int startColumn, | ||
final int charIndex, final int length, final String[] tags) { | ||
super(startLine, startColumn, charIndex, length); | ||
this.tags = tags; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package source; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotSame; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
import org.junit.Test; | ||
|
||
import bd.source.SourceCoordinate; | ||
|
||
|
||
public class SourceCoordinateTests { | ||
|
||
@Test | ||
public void testBasicEqualsHash() { | ||
SourceCoordinate a = SourceCoordinate.create("file:///", 1, 2, 2, 4); | ||
SourceCoordinate b = SourceCoordinate.create("file:///", 1, 2, 2, 4); | ||
|
||
assertNotSame(a, b); | ||
assertEquals(a.hashCode(), b.hashCode()); | ||
|
||
assertTrue(a.equals(b)); | ||
} | ||
|
||
@Test | ||
public void testEqualsHashWithUnsetCharIndex() { | ||
SourceCoordinate a = SourceCoordinate.create("file:///", 1, 2, 2, 4); | ||
|
||
// underlying source might not be loaded, should still match | ||
SourceCoordinate b = SourceCoordinate.create("file:///", 1, 2, 4); | ||
|
||
assertNotSame(a, b); | ||
assertEquals(a.hashCode(), b.hashCode()); | ||
|
||
assertTrue(a.equals(b)); | ||
} | ||
} |