Class Source

java.lang.Object
com.oracle.truffle.api.source.Source

public abstract class Source extends Object
Representation of a source code unit and its contents that can be evaluated in a language. Each source is associated with the the ID of the language.

From a file on disk

Each file is represented as a canonical object, indexed by the absolute, canonical path name of the file. File content is read eagerly and may be optionally cached. Sample usage:
assert file.getName().endsWith(".java") :
    "Imagine 'c:\\sources\\Example.java' file";

String language = Source.findLanguage(file);
Source source = Source.newBuilder(language, file).build();

assert file.getName().equals(source.getName());
assert file.getPath().equals(source.getPath());
assert file.toUri().equals(source.getURI());
The starting point is newBuilder(String, TruffleFile) method.

Read from a URL

One can read remote or in JAR resources using the newBuilder(String, java.net.URL) factory:
URL resource = relativeClass.getResource("sample.js");
Source source = Source.newBuilder("js", resource)
                .build();
assert resource.toExternalForm().equals(source.getPath());
assert "sample.js".equals(source.getName());
assert resource.toURI().equals(source.getURI());
Each URL source is represented as a canonical object, indexed by the URL. Contents are read eagerly once the Source.SourceBuilder.build() method is called.

Source from a literal text

An anonymous immutable code snippet can be created from a string via the newBuilder(String, CharSequence, String) factory method:
Source source = Source.newBuilder("js", "function() {\n"
                + "  return 'Hi';\n"
                + "}\n", "hi.js").build();
assert "hi.js".equals(source.getName());

Reading from a stream

If one has a Reader one can convert its content into a Source via newBuilder(String, java.io.Reader, String) method:
Reader stream = new InputStreamReader(
                relativeClass.getResourceAsStream("sample.js")
);
Source source = Source.newBuilder("js", stream, "sample.js")
    .build();
assert "sample.js".equals(source.getName());
the content is read eagerly once the Source.SourceBuilder.build() method is called.

Reading from bytes

Sources can be created from bytes. Please note that all character related methods will throw an UnsupportedOperationException if that is the case.
byte[] bytes = new byte[] {/* Binary */};
Source source = Source.newBuilder("llvm",
                ByteSequence.create(bytes),
                "<literal>").build();

Attributes

The source object can be associated with various attributes like getName() , (), getMimeType() and these are immutable. The system makes the best effort to derive values of these attributes from the location and/or content of the Source object. However, to give the user that creates the source control over these attributes, the API offers an easy way to alter values of these attributes.

Character and binary based Sources

A source is byte or character based, or none of those when no content is specified. For literal sources it depends on whether the byte or character based factory method was used. When the source was loaded from a file or url then the default MIME type of the provided language will be used to determine whether bytes or characters should be loaded. The behavior can be customized by specifying a MIME type or content explicitly. If the specified or inferred MIME type starts with 'text/ or the MIME types is null then it will be interpreted as character based, otherwise byte based.
Since:
0.8 or earlier
  • Field Details

    • CONTENT_NONE

      public static final CharSequence CONTENT_NONE
      Constant to be used as an argument to Source.SourceBuilder.content(CharSequence) to set no content to the Source built. The created sections will contain location information only and no characters. That's useful mainly when the source code is not available, but there are relative file paths, like in Java bytecode or LLVM bitcode. It's up to tools to resolve those relative paths and use the section location in resolved sources.
      Since:
      19.0
  • Method Details

    • getLanguage

      public abstract String getLanguage()
      Returns the language this source was created with. The string returned matches the id of the language.
      Returns:
      the language of this source.
      Since:
      0.28
    • getName

      public abstract String getName()
      Returns the name of this resource holding a guest language program. An example would be the name of a guest language source code file. Name is supposed to be shorter than getPath().
      Returns:
      the name of the guest language program
      Since:
      0.8 or earlier
    • getPath

      public abstract String getPath()
      The fully qualified name of the source. In case this source originates from a File or TruffleFile, then the path is the normalized, canonical path. If canonicalizePath(false) is used when building the source then TruffleFile.getPath() is used instead. If the source originates from an URL, then it's the path component of the URL.
      Since:
      0.8 or earlier
    • isInternal

      public abstract boolean isInternal()
      Check whether this source has been marked as internal, meaning that it has been provided by the infrastructure, language implementation, or system library. Internal sources are presumed to be irrelevant to guest language programmers, as well as possibly confusing and revealing of language implementation details.

      On the other hand, tools should be free to make internal sources visible in (possibly privileged) modes that are useful for language implementors.

      One can specify whether a source is internal when building it.

      Returns:
      whether this source is marked as internal
      Since:
      0.15
    • isCached

      public abstract boolean isCached()
      Returns true if code caching is enabled for this source. If true then the source does not require parsing every time this source is evaluated. If false then the source requires parsing every time the source is evaluated but does not remember any state. Disabling caching may be useful if the source is known to only be evaluated once.
      Returns:
      whether this source is allowed to be cached
      Since:
      19.0
    • isInteractive

      public abstract boolean isInteractive()
      Check whether this source has been marked as interactive. Interactive sources are provided by an entity which is able to interactively read output and provide an input during the source execution; that can be a user I/O through an interactive shell for instance.

      Depending on language interactive capability, when interactive sources are executed, the appropriate result can be passed directly to the environment output stream or error stream and input stream can be used to read user input during the execution, to clarify the execution behavior by asking questions for instance. Non-interactive languages are expected to ignore this property.

      One can specify whether a source is interactive when building it.

      Returns:
      whether this source is marked as interactive
      Since:
      0.21
    • equals

      public final boolean equals(Object obj)
      Overrides:
      equals in class Object
      Since:
      19.0
    • hashCode

      public final int hashCode()
      Overrides:
      hashCode in class Object
      Since:
      19.0
    • subSource

      public Source subSource(int baseCharIndex, int length)
      Creates a Source instance that represents the contents of a sub-range of an this Source.
      Parameters:
      baseCharIndex - 0-based index of the first character of the sub-range
      length - the number of characters in the sub-range
      Returns:
      a new instance representing a sub-range of another Source
      Throws:
      IllegalArgumentException - if the specified sub-range is not contained in the base
      UnsupportedOperationException - if this source cannot contain characters.
      Since:
      0.15
    • getCharacters

      public abstract CharSequence getCharacters()
      Returns all characters of the source.
      Throws:
      UnsupportedOperationException - if this source cannot contain characters.
      Since:
      0.28
    • hasBytes

      public abstract boolean hasBytes()
      Returns true if this source represents a byte based source, else false. A source is either a byte based, a character based, or with no content, but never both byte and character based at the same time.

      The method getBytes() is only supported if this method returns true.

      Since:
      19.0
      See Also:
    • hasCharacters

      public abstract boolean hasCharacters()
      Returns true if this source represents a character based source, else false. A source is either a byte based, a character based, or with no content, but never both byte and character based at the same time.

      The following methods are only supported if hasCharacters() is true:

      Since:
      19.0
    • getBytes

      public abstract ByteSequence getBytes()
      Returns the bytes of the source if it is a byte based source.
      Throws:
      UnsupportedOperationException - if this source cannot contain bytes .
      Since:
      19.0
      See Also:
    • getURL

      public abstract URL getURL()
      The URL if the source is retrieved via URL.
      Returns:
      URL or null
      Since:
      0.8 or earlier
    • getURI

      public final URI getURI()
      Get URI of the source. Every source has an associated URI, which can be used as a persistent identification of the source. For example one can register a breakpoint using a URI to a source that isn't loaded yet and it will be activated when the source is evaluated. The URI returned by this method should be as unique as possible, yet it can happen that different sources return the same getURI() - for example when content of a file on a disk changes and is re-loaded.
      Returns:
      a URI, it's never null
      Since:
      0.14
    • getMimeType

      public abstract String getMimeType()
      Returns the MIME type that is associated with this source. Sources have a null MIME type by default. If the MIME type is null then the default MIME type of the language will be used to interpret the source. If set explicitly then the language needs to support the MIME type in order to Context.eval(org.graalvm.polyglot.Source) evaluate} the source. If not null the MIME type is already verified containing no spaces and a '/' between group and sub-group. An example for a valid MIME type is: text/javascript.

      The MIME type can be guessed by the system based on files or urls

      Returns:
      MIME type of this source or null, if not explicitly set.
      Since:
      19.0
      See Also:
    • getReader

      public final Reader getReader()
      Access to the source contents.
      Since:
      0.8 or earlier
    • getLength

      public final int getLength()
      Gets the number of characters or bytes of the source.
      Throws:
      UnsupportedOperationException - if this source does not contain characters, nor bytes.
      Since:
      0.8
    • getCharacters

      public final CharSequence getCharacters(int lineNumber)
      Gets the text (not including a possible terminating newline) in a (1-based) numbered line. Causes the contents of this source to be loaded if they are loaded lazily.
      Throws:
      UnsupportedOperationException - if this source cannot contain characters.
      Since:
      0.28
    • getLineCount

      public final int getLineCount()
      The number of text lines in the source, including empty lines; characters at the end of the source without a terminating newline count as a line. Causes the contents of this source to be loaded if they are loaded lazily.
      Throws:
      UnsupportedOperationException - if this source cannot contain characters.
      Since:
      0.8 or earlier
    • getLineNumber

      public final int getLineNumber(int offset) throws IllegalArgumentException
      Given a 0-based character offset, return the 1-based number of the line that includes the position. Causes the contents of this source to be loaded if they are loaded lazily.
      Throws:
      UnsupportedOperationException - if this source cannot contain characters.
      IllegalArgumentException - if the offset is outside the text contents
      Since:
      0.8 or earlier
    • getColumnNumber

      public final int getColumnNumber(int offset) throws IllegalArgumentException
      Given a 0-based character offset, return the 1-based number of the column at the position. Causes the contents of this source to be loaded if they are loaded lazily.
      Throws:
      UnsupportedOperationException - if this source cannot contain characters.
      IllegalArgumentException - if the offset is outside the text contents
      Since:
      0.8 or earlier
    • getLineStartOffset

      public final int getLineStartOffset(int lineNumber) throws IllegalArgumentException
      Given a 1-based line number, return the 0-based offset of the first character in the line.
      Throws:
      UnsupportedOperationException - if this source cannot contain characters.
      IllegalArgumentException - if there is no such line in the text
      Since:
      0.8 or earlier
    • getLineLength

      public final int getLineLength(int lineNumber) throws IllegalArgumentException
      The number of characters (not counting a possible terminating newline) in a (1-based) numbered line. Causes the contents of this source to be loaded if they are loaded lazily.
      Throws:
      UnsupportedOperationException - if this source cannot contain characters.
      IllegalArgumentException - if there is no such line in the text
      Since:
      0.8 or earlier
    • createUnavailableSection

      public final SourceSection createUnavailableSection()
      Returns an unavailable source section indicating that the source location is not available. Unavailable source sections have the same characteristics as empty source sections with character index 0, but returns false for SourceSection.isAvailable(). Unavailable source sections may be created for character and byte based sources.
      Since:
      0.18
      See Also:
    • createSection

      public final SourceSection createSection(int startLine, int startColumn, int endLine, int endColumn)
      Create representation of a contiguous region in the source that does not have the character content available.
      Parameters:
      startLine - 1-based line number of the first character in the section
      startColumn - 1-based column number of the first character in the section, or -1 when the column is not defined
      endLine - 1-based line number of the last character in the section
      endColumn - 1-based column number of the last character in the section, or -1 when the column is not defined
      Throws:
      UnsupportedOperationException - if this source has bytes.
      Since:
      19.0
    • createSection

      public final SourceSection createSection(int lineNumber)
      Creates a representation of a line of text in the source identified only by line number, from which the character information will be computed. Please note that calling this method does cause the code of this source to be loaded, if there is any. If no code is available, a SourceSection without character content is created with the start line and the same end line defined only.
      Parameters:
      lineNumber - 1-based line number of the first character in the section
      Returns:
      newly created object representing the specified line
      Throws:
      UnsupportedOperationException - if this source contains bytes.
      IllegalArgumentException - if the given lineNumber does not exist the source
      Since:
      0.17
    • createSection

      public final SourceSection createSection(int charIndex, int length)
      Creates a representation of a contiguous region of text in the source. Please note that calling this method does only cause the code of this source to be loaded if assertions enabled. The bounds of the source section are only verified if assertions (-ea) are enabled in the host system. An IllegalArgumentException is thrown if the given indices are out of bounds of the source bounds.
      Parameters:
      charIndex - 0-based position of the first character in the section
      length - the number of characters in the section
      Returns:
      newly created object representing the specified region
      Throws:
      UnsupportedOperationException - if this source cannot contain characters.
      IllegalArgumentException - if charIndex < 0 or length < 0; in case assertions are enabled also if the given bounds are out of the source bounds.
      Since:
      0.17
    • createSection

      public final SourceSection createSection(int startLine, int startColumn, int length)
      Creates a representation of a contiguous region of text in the source. When character content is available, computes the charIndex value by building a text map of lines in the source. Please note that calling this method does cause the code of this source to be loaded, if there is any. If no code is available, UnsupportedOperationException is thrown. Use createSection(int, int, int, int) to create a SourceSection without character content.
      Parameters:
      startLine - 1-based line number of the first character in the section
      startColumn - 1-based column number of the first character in the section
      length - the number of characters in the section
      Returns:
      newly created object representing the specified region
      Throws:
      UnsupportedOperationException - if this source does not contain characters.
      IllegalArgumentException - if arguments are outside the text of the source bounds
      Since:
      0.17
      See Also:
    • toString

      public String toString()
      Overrides:
      toString in class Object
      Since:
      19.0
    • newBuilder

      public static Source.LiteralBuilder newBuilder(String language, CharSequence characters, String name)
      Creates a new character based literal source from a character sequence. The given characters must not mutate after they were accessed for the first time.

      Use this method for sources that do originate from a literal. For file or URL sources use the appropriate builder constructor and Source.SourceBuilder.content(CharSequence).

      Example usage:

      Source source = Source.newBuilder("js", "function() {\n"
                      + "  return 'Hi';\n"
                      + "}\n", "hi.js").build();
      assert "hi.js".equals(source.getName());
      
      Parameters:
      language - the language id, must not be null
      characters - the character sequence or string, must not be null
      name - the name of the source, if null then "Unnamed" will be used as name.
      Since:
      19.0
    • newBuilder

      public static Source.LiteralBuilder newBuilder(String language, ByteSequence bytes, String name)
      Creates a new byte based literal source from a byte sequence. The given bytes must not mutate after they were accessed for the first time.

      Use this method for sources that do originate from a literal. For file or URL sources use the appropriate builder constructor and Source.SourceBuilder.content(ByteSequence).

      Example usage:

      byte[] bytes = new byte[] {/* Binary */};
      Source source = Source.newBuilder("llvm",
                      ByteSequence.create(bytes),
                      "<literal>").build();
      
      Parameters:
      language - the language id, must not be null
      bytes - the byte sequence or string, must not be null
      name - the name of the source, if null then "Unnamed" will be used as name.
      Since:
      19.0
    • newBuilder

      public static Source.SourceBuilder newBuilder(String language, TruffleFile file)
      Creates a new file based source builder from a given file. A file based source is either interpreted as binary or character source depending on the default MIME type of the language, the contents or the specified MIME type. A language may be detected from an existing file using findLanguage(TruffleFile).

      Example usage:

      assert file.getName().endsWith(".java") :
          "Imagine 'c:\\sources\\Example.java' file";
      
      String language = Source.findLanguage(file);
      Source source = Source.newBuilder(language, file).build();
      
      assert file.getName().equals(source.getName());
      assert file.getPath().equals(source.getPath());
      assert file.toUri().equals(source.getURI());
      
      Parameters:
      language - the language id, must not be null
      file - the file to use and load, must not be null
      Since:
      19.0
    • newBuilder

      public static Source.SourceBuilder newBuilder(String language, URL url)
      Creates a new URL based source builder from a given URL. A URL based source is either interpreted as binary or character source depending on the default MIME type of the language, the contents or the specified MIME type. A language may be detected from an existing file using findLanguage(URL).

      Example usage:

      URL resource = relativeClass.getResource("sample.js");
      Source source = Source.newBuilder("js", resource)
                      .build();
      assert resource.toExternalForm().equals(source.getPath());
      assert "sample.js".equals(source.getName());
      assert resource.toURI().equals(source.getURI());
      
      Parameters:
      language - the language id, must not be null
      url - the URL to use and load, must not be null
      Since:
      19.0
    • newBuilder

      public static Source.SourceBuilder newBuilder(String language, Reader source, String name)
      Creates new character based literal source from a reader.

      Use this method for sources that do originate from a literal. For file or URL sources use the appropriate builder constructor and Source.SourceBuilder.content(CharSequence).

      Example usage:

      Reader stream = new InputStreamReader(
                      relativeClass.getResourceAsStream("sample.js")
      );
      Source source = Source.newBuilder("js", stream, "sample.js")
          .build();
      assert "sample.js".equals(source.getName());
      
      Since:
      19.0
    • newBuilder

      public static Source.LiteralBuilder newBuilder(Source source)
      Creates a new source builder that inherits from the given Source. The Source properties can be modified using the builder methods.
      Parameters:
      source - the source to inherit the properties from
      Since:
      19.2.0
    • findLanguage

      public static String findLanguage(TruffleFile file) throws IOException
      Returns the first language that supports evaluating the probed mime type of a given file. This method is a shortcut for:
       String mimeType = Source.findMimeType(file);
       return mimeType != null ? Source.findLanguage(mimeType) : null;
       
      Parameters:
      file - the file to find the first language for
      Throws:
      IOException - if an error opening the file occurred.
      Since:
      19.0
      See Also:
    • findLanguage

      public static String findLanguage(URL url) throws IOException
      Returns the first language that supports evaluating the probed mime type of a given URL. This method is a shortcut for:
       String mimeType = Source.findMimeType(url);
       return mimeType != null ? Source.findLanguage(mimeType) : null;
       
      Parameters:
      url - the url to find the first language for
      Throws:
      IOException - if an error opening the url occurred.
      Since:
      19.0
      See Also:
    • findMimeType

      public static String findMimeType(TruffleFile file) throws IOException
      Returns the probed MIME type for a given file, or null if no MIME type could be resolved. Typically the MIME type is identified using the file extension and/or using its contents. Probing the MIME type of an TruffleFile may require to opening the file.
      Throws:
      IOException - if an error opening the file occurred.
      SecurityException - if the used filesystem denied file reading.
      Since:
      19.0
      See Also:
    • findMimeType

      public static String findMimeType(URL url) throws IOException
      Returns the probed MIME type for a given url, or null if no MIME type could be resolved. Typically the MIME type is identified using the file extension, connection meta-data and/or using it contents. Returns null if the language of the given file could not be detected. Probing the language of an URL may require to open a new URL connection.
      Throws:
      IOException - if an error opening the url occurred.
      SecurityException - if the used filesystem denied file reading.
      Since:
      19.0
      See Also:
    • findLanguage

      public static String findLanguage(String mimeType)
      Returns the first installed language that supports evaluating sources for a given MIME type. Returns null if no language was found that supports a given MIME type. The languages are queried in the same order as returned by Engine.getLanguages().
      Since:
      19.0