package com.oracle.truffle.js.test.instrumentation;
import org.junit.Ignore;
import org.junit.Test;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.DeclareTag;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.LiteralTag;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.WriteVariableTag;
public class VarDeclarationsTest extends FineGrainedAccessTest {
@Test
public void var() {
evalWithTag("(function() { var b = 42; })();", DeclareTag.class);
enter(DeclareTag.class, (e, decl) -> {
assertAttribute(e, DECL_NAME, "b");
assertAttribute(e, DECL_TYPE, "var");
}).exit();
}
@Test
public void argAndVar() {
evalWithTag("(function(a) { var b = 42; })();", DeclareTag.class);
enter(DeclareTag.class, (e, decl) -> {
assertAttribute(e, DECL_NAME, "a");
assertAttribute(e, DECL_TYPE, "var");
}).exit();
enter(DeclareTag.class, (e, decl) -> {
assertAttribute(e, DECL_NAME, "b");
assertAttribute(e, DECL_TYPE, "var");
}).exit();
}
@Test
public void let() {
evalWithTag("(function() { let b = 42; })();", DeclareTag.class);
enter(DeclareTag.class, (e, decl) -> {
assertAttribute(e, DECL_NAME, "b");
assertAttribute(e, DECL_TYPE, "let");
}).exit();
}
@Test
public void constDeclareVar() {
evalWithTags("(function() { const b = 42; })();", new Class<?>[]{DeclareTag.class, WriteVariableTag.class});
enter(DeclareTag.class, (e, decl) -> {
assertAttribute(e, DECL_NAME, "b");
assertAttribute(e, DECL_TYPE, "const");
}).exit();
enter(WriteVariableTag.class, (e1, w1) -> {
assertAttribute(e1, NAME, "b");
w1.input(42);
}).exit();
}
@Test
public void letConstBlock() {
evalWithTag("(function() { const c = 1; for(var i = 0; i<c; i++) { let b = i; } })();", DeclareTag.class);
enter(DeclareTag.class, (e, decl) -> {
assertAttribute(e, DECL_NAME, "c");
assertAttribute(e, DECL_TYPE, "const");
}).exit();
enter(DeclareTag.class, (e, decl) -> {
assertAttribute(e, DECL_NAME, "i");
assertAttribute(e, DECL_TYPE, "var");
}).exit();
enter(DeclareTag.class, (e, decl) -> {
assertAttribute(e, DECL_NAME, "b");
assertAttribute(e, DECL_TYPE, "let");
}).exit();
}
@Ignore("GR-21919")
@Test
public void classDeclareVar() {
evalWithTags("class Foo{}", new Class<?>[]{DeclareTag.class, WriteVariableTag.class});
enter(DeclareTag.class, (e2) -> {
assertAttribute(e2, DECL_NAME, "Foo");
assertAttribute(e2, DECL_TYPE, "const");
}).exit();
enter(WriteVariableTag.class, (e1, w1) -> {
assertAttribute(e1, NAME, "Foo");
w1.input(assertJSFunctionInput);
}).exit();
}
@Test
public void classDeclare() {
evalWithTags("class Foo{}", new Class<?>[]{DeclareTag.class});
enter(DeclareTag.class, (e2) -> {
assertAttribute(e2, DECL_NAME, "Foo");
assertAttribute(e2, DECL_TYPE, "const");
}).exit();
}
@Test
public void functionDeclare() {
evalWithTag("(function() { function foo() {} })();", DeclareTag.class);
enter(DeclareTag.class, (e, expr) -> {
assertAttribute(e, DECL_NAME, "foo");
assertAttribute(e, DECL_TYPE, "var");
}).exit();
}
@Test
public void functionDeclareLiteral() {
evalWithTag("function foo() {};", LiteralTag.class);
enter(LiteralTag.class, (e, expr) -> {
assertAttribute(e, LITERAL_TYPE, LiteralTag.Type.FunctionLiteral.name());
}).exit();
}
@Test
public void generatorDeclare() {
evalWithTag("function* foo() {};", DeclareTag.class);
enter(DeclareTag.class, (e, expr) -> {
assertAttribute(e, DECL_NAME, "foo");
assertAttribute(e, DECL_TYPE, "var");
}).exit();
}
@Test
public void generatorDeclareLiteral() {
evalWithTag("function* foo() {};", LiteralTag.class);
enter(LiteralTag.class, (e, expr) -> {
assertAttribute(e, LITERAL_TYPE, LiteralTag.Type.FunctionLiteral.name());
}).exit();
}
}