public interface LanguageProvider
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.Modifier and Type | Method and Description |
---|---|
default Map<String,String> |
additionalOptions()
Allows language providers to provide language options during the creation of the test
context.
|
Collection<? extends Snippet> |
createExpressions(Context context)
Creates a collection of functions representing language expressions to test.
|
Value |
createIdentityFunction(Context context)
Creates an identity function.
|
default Snippet |
createIdentityFunctionSnippet(Context context)
Creates a
Snippet for an identity function. |
default Collection<? extends InlineSnippet> |
createInlineScripts(Context context)
Creates a collection of inline code snippets.
|
Collection<? extends Source> |
createInvalidSyntaxScripts(Context context)
Creates a collection of scripts containing a syntax error.
|
Collection<? extends Snippet> |
createScripts(Context context)
Creates a collection of simple scripts used for instrumentation testing.
|
Collection<? extends Snippet> |
createStatements(Context context)
Creates a collection of functions representing language statements to test.
|
Collection<? extends Snippet> |
createValueConstructors(Context context)
Creates a collection of functions creating language data types.
|
String |
getId()
Returns an identification of a provider.
|
String getId()
default Map<String,String> additionalOptions()
LanguageProviders
are only allowed to set options of the
language they represent (Options starting with LanguageProvider.getId()
). Attempts to set options
other than their own language will throw IllegalArgumentException
on test context
creation.(key, value)
pairs of language option to add to the context.Value createIdentityFunction(Context context)
The JavaScript sample implementation:
@Override
publicValue
createIdentityFunction(Context
context) { return context.eval("js", "(function (a){ return a; })"); }
The R sample implementation:
@Override
publicValue
createIdentityFunction(Context
context) { return context.eval("R", "function (a){ a }"); }
context
- the context for a guest language code literal evaluationValue
representing the identity functiondefault Snippet createIdentityFunctionSnippet(Context context)
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 LanguageProvider.createIdentityFunction(org.graalvm.polyglot.Context)
.
The implementor can delegate to the default identity function verifier obtained by
ResultVerifier.getIdentityFunctionDefaultResultVerifier()
.
context
- the context for a guest language code literal evaluationSnippet
representing the identity functionCollection<? extends Snippet> createValueConstructors(Context context)
TypeDescriptor
to it. The TypeDescriptor
can be one of the predefined TypeDescriptor
s, an
array with component type, an executable with required parameter types or an intersection
type.
The JavaScript sample implementation creating a boolean type:
@Override
publicCollection
<? extendsSnippet
> createValueConstructors(Context
context) { finalCollection
<Snippet
> valueConstructors = newArrayList
<>();Snippet
.Builder builder =Snippet
.newBuilder( "boolean", context.eval("js", "(function (){ return false;})"),TypeDescriptor
.BOOLEAN); valueConstructors.add(builder.build()); return valueConstructors; }
The R sample implementation creating a boolean type:
@Override
publicCollection
<? extendsSnippet
> createValueConstructors(Context
context) { finalCollection
<Snippet
> valueConstructors = newArrayList
<>();Snippet
.Builder builder =Snippet
.newBuilder( "boolean", context.eval("R", "function (){ FALSE }"),TypeDescriptor
.BOOLEAN); valueConstructors.add(builder.build()); return valueConstructors; }
context
- the context for a guest language code literal evaluationCollection<? extends Snippet> createExpressions(Context context)
TypeDescriptor
s to its parameters and return type. The parameter types and return
type can be one of the predefined TypeDescriptor
s, an array with component type, an
executable with required parameter types or an union type.
The JavaScript sample implementation creating a plus operator:
@Override
publicCollection
<? extendsSnippet
> createExpressions(Context
context) { finalCollection
<Snippet
> expressions = newArrayList
<>(); finalTypeDescriptor
numeric =TypeDescriptor
.union(TypeDescriptor
.NUMBER,TypeDescriptor
.BOOLEAN); finalTypeDescriptor
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
publicCollection
<? extendsSnippet
> createExpressions(Context
context) { finalCollection
<Snippet
> expressions = newArrayList
<>(); finalTypeDescriptor
numOrBool =TypeDescriptor
.union(TypeDescriptor
.NUMBER,TypeDescriptor
.BOOLEAN); finalTypeDescriptor
arrNumOrBool =TypeDescriptor
.array( numOrBool); finalTypeDescriptor
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; }
context
- the context for a guest language code literal evaluationCollection<? extends Snippet> createStatements(Context context)
TypeDescriptor
s to its parameters and return type. The parameter types and return
type can be one of the predefined TypeDescriptor
s, an array with component type, an
executable with required parameter types or an union type.
The JavaScript sample implementation creating the if
statement:
@Override
publicCollection
<? extendsSnippet
> createStatements(Context
context) { finalCollection
<Snippet
> statements = newArrayList
<>();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
publicCollection
<? extendsSnippet
> createStatements(Context
context) { finalCollection
<Snippet
> statements = newArrayList
<>(); finalTypeDescriptor
numberOrBoolean =TypeDescriptor
.union(TypeDescriptor
.NUMBER,TypeDescriptor
.BOOLEAN); finalTypeDescriptor
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; }
context
- the context for a guest language code literal evaluationCollection<? extends Snippet> createScripts(Context context)
ResultVerifier
.
The JavaScript sample implementation:
@Override
publicCollection
<? extendsSnippet
> createScripts(Context
context) { try { finalCollection
<Snippet
> scripts = newArrayList
<>();Reader
reader = newInputStreamReader
( 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 newRuntimeException
(ioe); } }
context
- the context for a guest language code literal evaluationCollection<? extends Source> createInvalidSyntaxScripts(Context context)
The JavaScript sample implementation:
@Override
publicCollection
<? extendsSource
> createInvalidSyntaxScripts(Context
ctx) { try { finalCollection
<Source
> scripts = newArrayList
<>();Reader
reader = newInputStreamReader
( getClass().getResourceAsStream("invalidSyntax.js"), "UTF-8"); scripts.add(Source
.newBuilder( "js", reader, "invalidSyntax.js").build()); return scripts; } catch (IOException
ioe) { throw newRuntimeException
(ioe); } }
context
- the context for a guest language code literal evaluationdefault Collection<? extends InlineSnippet> createInlineScripts(Context context)
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
publicCollection
<? extendsInlineSnippet
> createInlineScripts(Context
context) { finalCollection
<InlineSnippet
> inlineScripts = newArrayList
<>();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; }
context
- the context for a guest language code literal evaluation