Interface LanguageProvider


public interface LanguageProvider
The LanguageProvider provides factory methods for language data types, expressions, statements and scripts used for testing language inter-operability. The LanguageProvider implementations are loaded by the ServiceLoader and should be registered in the 'META-INF/services/org.graalvm.polyglot.tck.LanguageProvider'. See Test Compatibility Kit for details how to add a new language provider and execute tests.
Since:
0.30
  • Method Details

    • getId

      String getId()
      Returns an identification of a provider. The common pattern is to use the identification of the tested language.
      Returns:
      the language identification
      Since:
      0.30
    • additionalOptions

      default Map<String,String> additionalOptions()
      Allows language providers to provide language options during the creation of the test context. LanguageProviders are only allowed to set options of the language they represent (Options starting with getId()). Attempts to set options other than their own language will throw IllegalArgumentException on test context creation.
      Returns:
      The (key, value) pairs of language option to add to the context.
      Since:
      22.3
    • createIdentityFunction

      org.graalvm.polyglot.Value createIdentityFunction(org.graalvm.polyglot.Context context)
      Creates an identity function. The identity function just returns its argument.

      The JavaScript sample implementation:

       @Override
       public Value createIdentityFunction(Context context) {
           return context.eval("js", "(function (a){ return a; })");
       }
       

      The R sample implementation:

       @Override
       public Value createIdentityFunction(Context context) {
           return context.eval("R", "function (a){ a }");
       }
       
      Parameters:
      context - the context for a guest language code literal evaluation
      Returns:
      the Value representing the identity function
      Since:
      0.30
    • createIdentityFunctionSnippet

      default Snippet createIdentityFunctionSnippet(org.graalvm.polyglot.Context context)
      Creates a Snippet for an identity function. The identity function just returns its argument. This method allows an implementor to override the default identity function verification. In most cases it's not needed to implement this method and it's enough to implement createIdentityFunction(org.graalvm.polyglot.Context).

      The implementor can delegate to the default identity function verifier obtained by ResultVerifier.getIdentityFunctionDefaultResultVerifier().

      Parameters:
      context - the context for a guest language code literal evaluation
      Returns:
      the Snippet representing the identity function
      Since:
      19.1.0
    • createValueConstructors

      Collection<? extends Snippet> createValueConstructors(org.graalvm.polyglot.Context context)
      Creates a collection of functions creating language data types. For each language data type create a function returning a value of given type and assign a correct TypeDescriptor to it. The TypeDescriptor can be one of the predefined TypeDescriptors, an array with component type, an executable with required parameter types or an intersection type.

      The JavaScript sample implementation creating a boolean type:

      Parameters:
      context - the context for a guest language code literal evaluation
      Returns:
      factories creating the language data types
      Since:
      0.30
    • createExpressions

      Collection<? extends Snippet> createExpressions(org.graalvm.polyglot.Context context)
      Creates a collection of functions representing language expressions to test. For each language operator create a function performing given operator and assign a correct TypeDescriptors to its parameters and return type. The parameter types and return type can be one of the predefined TypeDescriptors, an array with component type, an executable with required parameter types or an union type.

      The JavaScript sample implementation creating a plus operator:

       @Override
       public Collection<? extends Snippet> createExpressions(Context context) {
           final Collection<Snippet> expressions = new ArrayList<>();
           final TypeDescriptor numeric = TypeDescriptor.union(
                           TypeDescriptor.NUMBER,
                           TypeDescriptor.BOOLEAN);
           final TypeDescriptor nonNumeric = TypeDescriptor.union(
                           TypeDescriptor.STRING,
                           TypeDescriptor.OBJECT,
                           TypeDescriptor.ARRAY,
                           TypeDescriptor.EXECUTABLE_ANY);
           Snippet.Builder builder = Snippet.newBuilder(
                           "+",
                           context.eval("js",
                                           "(function (a, b){ return a + b;})"),
                           TypeDescriptor.NUMBER).parameterTypes(numeric, numeric);
           expressions.add(builder.build());
           builder = Snippet.newBuilder(
                           "+",
                           context.eval("js",
                                           "(function (a, b){ return a + b;})"),
                           TypeDescriptor.STRING).parameterTypes(nonNumeric, TypeDescriptor.ANY);
           expressions.add(builder.build());
           builder = Snippet.newBuilder(
                           "+",
                           context.eval("js",
                                           "(function (a, b){ return a + b;})"),
                           TypeDescriptor.STRING).parameterTypes(TypeDescriptor.ANY, nonNumeric);
           expressions.add(builder.build());
           return expressions;
       }
       
      The R sample implementation creating a plus operator:
       @Override
       public Collection<? extends Snippet> createExpressions(Context context) {
           final Collection<Snippet> expressions = new ArrayList<>();
           final TypeDescriptor numOrBool = TypeDescriptor.union(
                           TypeDescriptor.NUMBER,
                           TypeDescriptor.BOOLEAN);
           final TypeDescriptor arrNumOrBool = TypeDescriptor.array(
                           numOrBool);
           final TypeDescriptor numeric = TypeDescriptor.union(
                           numOrBool,
                           arrNumOrBool);
           Snippet.Builder builder = Snippet.newBuilder(
                           "+",
                           context.eval("R",
                                           "function (a, b){ a + b}"),
                           numeric).parameterTypes(numeric, numeric);
           expressions.add(builder.build());
           return expressions;
       }
       
      Parameters:
      context - the context for a guest language code literal evaluation
      Returns:
      factories creating the language expressions
      Since:
      0.30
    • createStatements

      Collection<? extends Snippet> createStatements(org.graalvm.polyglot.Context context)
      Creates a collection of functions representing language statements to test. For each control flow statement create a function performing given statement and assign a correct TypeDescriptors to its parameters and return type. The parameter types and return type can be one of the predefined TypeDescriptors, an array with component type, an executable with required parameter types or an union type.

      The JavaScript sample implementation creating the if statement:

       @Override
       public Collection<? extends Snippet> createStatements(Context context) {
           final Collection<Snippet> statements = new ArrayList<>();
           Snippet.Builder builder = Snippet.newBuilder(
                           "if",
                           context.eval("js",
                                           "(function (p){\n" +
                                                           "  if (p) return true ; else  return false;\n" +
                                                           "})"),
                           TypeDescriptor.BOOLEAN).parameterTypes(
                                           TypeDescriptor.union(
                                                           TypeDescriptor.STRING,
                                                           TypeDescriptor.OBJECT,
                                                           TypeDescriptor.NUMBER,
                                                           TypeDescriptor.BOOLEAN));
           statements.add(builder.build());
           return statements;
       }
       

      The R sample implementation creating the if statement:

       @Override
       public Collection<? extends Snippet> createStatements(Context context) {
           final Collection<Snippet> statements = new ArrayList<>();
           final TypeDescriptor numberOrBoolean = TypeDescriptor.union(
                           TypeDescriptor.NUMBER,
                           TypeDescriptor.BOOLEAN);
           final TypeDescriptor arrayNumberOrBoolean = TypeDescriptor.array(
                           numberOrBoolean);
           Snippet.Builder builder = Snippet.newBuilder(
                           "if",
                           context.eval("R",
                                           "function(p){\n" +
                                                           "  if (p) { return (TRUE) } else { return (FALSE) }\n" +
                                                           "}"),
                           TypeDescriptor.BOOLEAN).parameterTypes(
                                           TypeDescriptor.union(
                                                           numberOrBoolean,
                                                           arrayNumberOrBoolean));
           statements.add(builder.build());
           return statements;
       }
       
      Parameters:
      context - the context for a guest language code literal evaluation
      Returns:
      factories creating the language statements
      Since:
      0.30
    • createScripts

      Collection<? extends Snippet> createScripts(org.graalvm.polyglot.Context context)
      Creates a collection of simple scripts used for instrumentation testing. Each script is represented as a function performing the script. The function must have no formal parameters but may return a result which can be asserted by ResultVerifier.

      The JavaScript sample implementation:

       @Override
       public Collection<? extends Snippet> createScripts(Context context) {
           try {
               final Collection<Snippet> scripts = new ArrayList<>();
               Reader reader = new InputStreamReader(
                               getClass().getResourceAsStream("sample.js"),
                               "UTF-8");
               Source source = Source.newBuilder(
                               "js",
                               reader,
                               "sample.js").build();
               Snippet.Builder builder = Snippet.newBuilder(
                               source.getName(),
                               context.eval(source),
                               TypeDescriptor.NULL);
               scripts.add(builder.build());
               return scripts;
           } catch (IOException ioe) {
               throw new RuntimeException(ioe);
           }
       }
       
      Parameters:
      context - the context for a guest language code literal evaluation
      Returns:
      the language scripts
      Since:
      0.30
    • createInvalidSyntaxScripts

      Collection<? extends org.graalvm.polyglot.Source> createInvalidSyntaxScripts(org.graalvm.polyglot.Context context)
      Creates a collection of scripts containing a syntax error.

      The JavaScript sample implementation:

       @Override
       public Collection<? extends Source> createInvalidSyntaxScripts(Context ctx) {
           try {
               final Collection scripts = new ArrayList<>();
               Reader reader = new InputStreamReader(
                               getClass().getResourceAsStream("invalidSyntax.js"),
                               "UTF-8");
               scripts.add(Source.newBuilder(
                               "js",
                               reader,
                               "invalidSyntax.js").build());
               return scripts;
           } catch (IOException ioe) {
               throw new RuntimeException(ioe);
           }
       }
       
      Parameters:
      context - the context for a guest language code literal evaluation
      Returns:
      the scripts
      Since:
      0.30
    • createInlineScripts

      default Collection<? extends InlineSnippet> createInlineScripts(org.graalvm.polyglot.Context context)
      Creates a collection of inline code snippets.

      This method is optional, it should be implemented if TruffleLanguage.parse(InlineParsingRequest) is implemented. It returns an empty list by default.

      The JavaScript sample implementation creating inline code snippets:

       @Override
       public Collection<? extends InlineSnippet> createInlineScripts(Context context) {
           final Collection<InlineSnippet> inlineScripts = new ArrayList<>();
           Snippet.Builder scriptBuilder = Snippet.newBuilder(
                           "factorial",
                           context.eval("js",
                                           "(function (){\n" +
                                                           "  let factorial = function(n) {\n" +
                                                           "    let f = 1;\n" +
                                                           "    for (let i = 2; i <= n; i++) {\n" +
                                                           "      f *= i;\n" +
                                                           "    }\n" +
                                                           "  };\n" +
                                                           "  return factorial(10);\n" +
                                                           "})"),
                           TypeDescriptor.NUMBER);
           InlineSnippet.Builder builder = InlineSnippet.newBuilder(
                           scriptBuilder.build(),
                           "n * n").locationPredicate((SourceSection section) -> {
                               int line = section.getStartLine();
                               return 3 <= line && line <= 6;
                           });
           inlineScripts.add(builder.build());
           builder = InlineSnippet.newBuilder(
                           scriptBuilder.build(),
                           "Math.sin(Math.PI)");
           inlineScripts.add(builder.build());
           return inlineScripts;
       }
       
      Parameters:
      context - the context for a guest language code literal evaluation
      Returns:
      A collection of inline code snippets.
      Since:
      0.32