# HG changeset patch # User Michael Van De Vanter # Date 1431388197 25200 # Node ID 70bbc530a2d305aceccd705ca0ec06f74903eed1 # Parent ed1fcadffda113cc01318cf62ee39e0dbbbdf0d1 Truffle/Source: - factory methods for a new kind of Source representing the contents of a sub-range of an existing Source; - hide the Appendable subclass; Source.append() now throws UnsupportedOperationException if called on a non-appendable subclass. diff -r ed1fcadffda1 -r 70bbc530a2d3 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java Mon May 11 18:06:44 2015 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java Mon May 11 16:49:57 2015 -0700 @@ -61,6 +61,11 @@ * (non-indexed) Literal .
* See {@link Source#fromReader(Reader, String)} *

+ *

  • Sub-Source: A representation of the contents of a sub-range of another + * {@link Source}.
    + * See @link {@link Source#subSource(Source, int, int)}
    + * See @link {@link Source#subSource(Source, int)}
  • + *

    *

  • AppendableSource: Literal contents are provided by the client, * incrementally, after the instance is created.
    * See {@link Source#fromAppendableText(String)}
    @@ -250,8 +255,8 @@ * @param description a note about the origin, for error messages and debugging * @return a newly created, non-indexed, initially empty, appendable source representation */ - public static AppendableSource fromAppendableText(String description) { - final AppendableSource source = new AppendableLiteralSource(description); + public static Source fromAppendableText(String description) { + final Source source = new AppendableLiteralSource(description); notifyNewSource(source).tagAs(Tags.FROM_LITERAL); return source; } @@ -281,11 +286,39 @@ * @param name string to use for indexing/lookup * @return a newly created, indexed, initially empty, appendable source representation */ - public static AppendableSource fromNamedAppendableText(String name) { + public static Source fromNamedAppendableText(String name) { final Source source = new AppendableLiteralSource(name); nameToSource.put(name, new WeakReference<>(source)); notifyNewSource(source).tagAs(Tags.FROM_LITERAL); - return (AppendableSource) source; + return source; + } + + /** + * Creates a {@linkplain Source Source instance} that represents the contents of a sub-range of + * an existing {@link Source}. + * + * @param base an existing Source instance + * @param baseCharIndex 0-based index of the first character of the sub-range + * @param length the number of characters in the sub-range + * @return a new instance representing a sub-range of another Source + * @throws IllegalArgumentException if the specified sub-range is not contained in the base + */ + public static Source subSource(Source base, int baseCharIndex, int length) { + final SubSource subSource = SubSource.create(base, baseCharIndex, length); + return subSource; + } + + /** + * Creates a {@linkplain Source Source instance} that represents the contents of a sub-range at + * the end of an existing {@link Source}. + * + * @param base an existing Source instance + * @param baseCharIndex 0-based index of the first character of the sub-range + * @return a new instance representing a sub-range at the end of another Source + * @throws IllegalArgumentException if the index is out of range + */ + public static Source subSource(Source base, int baseCharIndex) { + return subSource(base, baseCharIndex, base.getLength() - baseCharIndex); } /** @@ -418,23 +451,59 @@ return builder.toString(); } - public abstract static class AppendableSource extends Source { + private static final class SubSource extends Source { + private final Source base; + private final int baseIndex; + private final int subLength; - /** - * Sets the mark. - */ - public void setMark() { + private static SubSource create(Source base, int baseIndex, int length) { + if (baseIndex < 0 || length < 0 || baseIndex + length > base.getLength()) { + throw new IllegalArgumentException("text positions out of range"); + } + return new SubSource(base, baseIndex, length); + } + + private SubSource(Source base, int baseIndex, int length) { + this.base = base; + this.baseIndex = baseIndex; + this.subLength = length; + } + + @Override + protected void reset() { + assert false; } - public abstract void appendCode(CharSequence chars); + @Override + public String getName() { + return base.getName(); + } - /** - * Gets the code from the mark to the end. - */ - public String getCodeFromMark() { - return getCode(); + @Override + public String getShortName() { + return base.getShortName(); + } + + @Override + public String getPath() { + return base.getPath(); } + @Override + public URL getURL() { + return null; + } + + @Override + public Reader getReader() { + assert false; + return null; + } + + @Override + public String getCode() { + return base.getCode(baseIndex, subLength); + } } private final ArrayList tags = new ArrayList<>(); @@ -587,6 +656,16 @@ } /** + * Append text to a Source explicitly created as Appendable. + * + * @param chars the text to append + * @throws UnsupportedOperationException by concrete subclasses that do not support appending + */ + public void appendCode(CharSequence chars) { + throw new UnsupportedOperationException(); + } + + /** * Creates a representation of a contiguous region of text in the source. *

    * This method performs no checks on the validity of the arguments. @@ -786,9 +865,8 @@ } } - private static final class AppendableLiteralSource extends AppendableSource { + private static final class AppendableLiteralSource extends Source { private String description; - private int mark = 0; final List codeList = new ArrayList<>(); public AppendableLiteralSource(String description) { @@ -839,20 +917,11 @@ } @Override - public String getCodeFromMark() { - return getCodeFromIndex(mark); - } - - @Override public void appendCode(CharSequence chars) { codeList.add(chars); clearTextMap(); } - @Override - public void setMark() { - mark = codeList.size(); - } } private static final class FileSource extends Source {