/*
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or
* data (collectively the "Software"), free of charge and under any and all
* copyright rights in the Software, and any and all patent rights owned or
* freely licensable by each licensor hereunder covering either (i) the
* unmodified Software as contributed to or provided by such licensor, or (ii)
* the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or at a
* minimum a reference to the UPL must be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.graalvm.polyglot.tck;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;
import org.graalvm.polyglot.SourceSection;
import org.graalvm.polyglot.Value;
final class LanguageProviderSnippets {
static final class JsSnippets implements LanguageProvider {
@Override
public String getId() {
return "js";
}
// @formatter:off
// BEGIN: LanguageProviderSnippets#JsSnippets#createIdentityFunction
@Override
public Value createIdentityFunction(Context context) {
return context.eval("js", "(function (a){ return a; })");
}
// END: LanguageProviderSnippets#JsSnippets#createIdentityFunction
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#JsSnippets#createValueConstructors
@Override
public Collection<? extends Snippet> createValueConstructors(Context context) {
final Collection<Snippet> valueConstructors = new ArrayList<>();
Snippet.Builder builder = Snippet.newBuilder(
"boolean",
context.eval("js", "(function (){ return false;})"),
TypeDescriptor.BOOLEAN);
valueConstructors.add(builder.build());
return valueConstructors;
}
// END: LanguageProviderSnippets#JsSnippets#createValueConstructors
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#JsSnippets#createExpressions
@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;
}
// END: LanguageProviderSnippets#JsSnippets#createExpressions
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#JsSnippets#createStatements
@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;
}
// END: LanguageProviderSnippets#JsSnippets#createStatements
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#JsSnippets#createScripts
@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);
}
}
// END: LanguageProviderSnippets#JsSnippets#createScripts
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#JsSnippets#createInlineScripts
@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;
}
// END: LanguageProviderSnippets#JsSnippets#createInlineScripts
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#JsSnippets#createInvalidSyntaxScripts
@Override
public Collection<? extends Source> createInvalidSyntaxScripts(Context ctx) {
try {
final Collection<Source> 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);
}
}
// END: LanguageProviderSnippets#JsSnippets#createInvalidSyntaxScripts
// @formatter:on
}
static final class RSnippets implements LanguageProvider {
@Override
public String getId() {
return "R";
}
// @formatter:off
// BEGIN: LanguageProviderSnippets#RSnippets#createIdentityFunction
@Override
public Value createIdentityFunction(Context context) {
return context.eval("R", "function (a){ a }");
}
// END: LanguageProviderSnippets#RSnippets#createIdentityFunction
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#RSnippets#createValueConstructors
@Override
public Collection<? extends Snippet> createValueConstructors(Context context) {
final Collection<Snippet> valueConstructors = new ArrayList<>();
Snippet.Builder builder = Snippet.newBuilder(
"boolean",
context.eval("R", "function (){ FALSE }"),
TypeDescriptor.BOOLEAN);
valueConstructors.add(builder.build());
return valueConstructors;
}
// END: LanguageProviderSnippets#RSnippets#createValueConstructors
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#RSnippets#createExpressions
@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;
}
// END: LanguageProviderSnippets#RSnippets#createExpressions
// @formatter:on
// @formatter:off
// BEGIN: LanguageProviderSnippets#RSnippets#createStatements
@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;
}
// END: LanguageProviderSnippets#RSnippets#createStatements
// @formatter:on
@Override
public Collection<? extends Snippet> createScripts(Context context) {
throw new UnsupportedOperationException("Not supported.");
}
@Override
public Collection<? extends Source> createInvalidSyntaxScripts(Context context) {
throw new UnsupportedOperationException("Not supported.");
}
}
abstract static class TypeDescriptorSnippets implements LanguageProvider {
// @formatter:off
// BEGIN: LanguageProviderSnippets#TypeDescriptorSnippets#createValueConstructors
@Override
public Collection<? extends Snippet> createValueConstructors(Context context) {
return Collections.singleton(Snippet.newBuilder(
"function",
context.eval("js", "(function(){ return function(){}})"),
TypeDescriptor.EXECUTABLE).build());
}
// END: LanguageProviderSnippets#TypeDescriptorSnippets#createValueConstructors
// @formatter:on
}
}