Interface TextDocument

  • All Superinterfaces:
    AutoCloseable, Closeable

    public interface TextDocument
    extends Closeable
    Represents a textual document, providing methods to edit it incrementally and address regions of text. A text document delegates IO operations to a TextFile. It reflects some in-memory snapshot of the file, though the file may still be edited externally.

    TextDocument is meant to replace CPD's SourceCode and PMD's DataSource, though the abstraction level of DataSource is the TextFile.

    Note that the backing TextFile is purposefully not accessible from a text document. Exposing it here could lead to files being written to from within rules, while we want to eventually build an API that allows file edition based on AST manipulation.

    Coordinates in TextDocument

    This interface is an abstraction over a piece of text, which might not correspond to the backing source file. This allows the document to be a view on a piece of a larger document (eg, a Javadoc comment, or a string in which a language is injected). Another use case is to perform escape translation, while preserving the line breaks of the original source.

    This complicates addressing within a text document. To explain it, consider that there is always *one* text document that corresponds to the backing text file, which we call the root text document. Logical documents built on top of it are called views. Text documents use offsets and TextRegion to address their contents. These are always relative to the text of the document. Line and column information are provided by FileLocation (see toLocation(TextRegion)), and are always absolute (ie, represent actual source lines in the file).

    For instance, say you have the following file (and root text document):

    
     l1
     l2 (* comment *)
     l3
     
    and you create a view for just the section (* comment *). Then, that view's offset 0 (start of the document) will map to the ( character, while the root document's offset 0 maps to the start of l1. When calling toLocation(caretAt(0)), the view will however return line 2, column 4, ie, a line/column that can be found when inspecting the file.

    To reduce the potential for mistakes, views do not provide access to their underlying text document. That way, nodes only have access to a single document, and their offsets can be assumed to be in the coordinate system of that document.

    This interface does not provide a way to obtain line/column coordinates that are relative to a view's coordinate system. This would complicate the construction of views significantly.

    • Method Detail

      • getLanguageVersion

        LanguageVersion getLanguageVersion()
        Returns the language version that should be used to parse this file.
      • sliceOriginalText

        Chars sliceOriginalText​(TextRegion region)
        Returns a slice of the original text. Note that this is not the same as getText().subsequence, as if this document has translated escapes, the returned char slice will contain the untranslated escapes, whereas getText() would return the translated characters.
        Parameters:
        region - A region, in the coordinate system of this document
        Returns:
        The slice of the original text that corresponds to the region
        Throws:
        IndexOutOfBoundsException - If the region is not a valid range
      • sliceTranslatedText

        default Chars sliceTranslatedText​(TextRegion region)
        Returns a slice of the source text. This is always equal to getText().slice(region), as the text is the translated text.
        Parameters:
        region - A region, in the coordinate system of this document
        Returns:
        The slice of the original text that corresponds to the region
        Throws:
        IndexOutOfBoundsException - If the region is not a valid range
      • newReader

        default Reader newReader()
        Returns a reader over the text of this document.
      • getLength

        default int getLength()
        Returns the length in characters of the text.
      • getEntireRegion

        default TextRegion getEntireRegion()
        Returns a text region that corresponds to the entire document, in the coordinate system of this document.
      • createLineRange

        TextRegion createLineRange​(int startLineInclusive,
                                   int endLineInclusive)
        Returns a region that spans the text of all the given lines.

        Note that, as line numbers may only be obtained from toLocation(TextRegion), and hence are line numbers of the original source, both parameters must be line numbers of the source text and not the translated text that this represents.

        Parameters:
        startLineInclusive - Inclusive start line number (1-based)
        endLineInclusive - Inclusive end line number (1-based)
        Throws:
        IndexOutOfBoundsException - If the arguments do not identify a valid region in the source document
      • toLocation

        FileLocation toLocation​(TextRegion region)
        Turn a text region into a FileLocation. This computes the line/column information for both start and end offset of the region.
        Parameters:
        region - A region, in the coordinate system of this document
        Returns:
        A new file position, with absolute coordinates
        Throws:
        IndexOutOfBoundsException - If the argument is not a valid region in this document
      • lineColumnAtOffset

        default TextPos2d lineColumnAtOffset​(int offset)
        Returns the line and column at the given offset (inclusive). Note that the line/column cannot be converted back. They are absolute in the coordinate system of the original document.
        Parameters:
        offset - A source offset (0-based), can range in [0, length].
        Throws:
        IndexOutOfBoundsException - if the offset is out of bounds
      • lineColumnAtOffset

        TextPos2d lineColumnAtOffset​(int offset,
                                     boolean inclusive)
        Returns the line and column at the given offset. Both the input offset and the output range are in the coordinates of this document.
        Parameters:
        offset - A source offset (0-based), can range in [0, length].
        inclusive - If the offset falls right after a line terminator, two behaviours are possible. If the parameter is true, choose the position at the start of the next line, otherwise choose the position at the end of the line.
        Returns:
        A position, in the coordinate system of the root document
        Throws:
        IndexOutOfBoundsException - if the offset is out of bounds
      • close

        void close()
            throws IOException
        Closing a document closes the underlying TextFile. New editors cannot be produced after that, and the document otherwise remains in its current state.
        Specified by:
        close in interface AutoCloseable
        Specified by:
        close in interface Closeable
        Throws:
        IOException - If TextFile.close() throws
        IllegalStateException - If an editor is currently open. In this case the editor is rendered ineffective before the exception is thrown. This indicates a programming mistake.