Skip to content

Commit

Permalink
fix: parent relationship in TaggedTemplateLiteral (#1238) (#1239)
Browse files Browse the repository at this point in the history
fix: parent relationship in TaggedTemplateLiteral.

Fixes #1238

Co-authored-by: Ihor Kuzmanenko <[email protected]>
  • Loading branch information
kuzjka and kuzjka authored Jul 16, 2022
1 parent 7a94441 commit 2daadfc
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/org/mozilla/javascript/ast/TaggedTemplateLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public AstNode getTarget() {

public void setTarget(AstNode target) {
this.target = target;
target.setParent(this);
}

public AstNode getTemplateLiteral() {
Expand All @@ -44,6 +45,7 @@ public AstNode getTemplateLiteral() {

public void setTemplateLiteral(AstNode templateLiteral) {
this.templateLiteral = templateLiteral;
templateLiteral.setParent(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package org.mozilla.javascript.tests.es6;

import static org.junit.Assert.*;

import org.junit.Test;
import org.mozilla.javascript.Parser;
import org.mozilla.javascript.ast.*;

/** Tests for ES6+ tagged templates support. */
public class TaggedTemplateLiteralTest {

/**
* Target and {@link org.mozilla.javascript.ast.TemplateLiteral} nodes inside the tagged
* template should have {@link org.mozilla.javascript.ast.TaggedTemplateLiteral} node as their
* parent.
*
* <p>See <a href="https://github.com/mozilla/rhino/issues/1238">#1238</a> for details.
*/
@Test
public void testTaggedTemplateChildrenHaveParent() {
String script = "tag`template`;";

AstRoot root = new Parser().parse(script, "test", 0);
TaggedTemplateFinder finder = new TaggedTemplateFinder();
root.visit(finder);
TaggedTemplateLiteral taggedTemplate = finder.getNode();

assertNotNull(taggedTemplate);
assertEquals(taggedTemplate, taggedTemplate.getTarget().getParent());
assertEquals(taggedTemplate, taggedTemplate.getTemplateLiteral().getParent());
}

/**
* Target and {@link org.mozilla.javascript.ast.TemplateLiteral} nodes inside the tagged
* template should resolve the AST root.
*
* <p>See <a href="https://github.com/mozilla/rhino/issues/1238">#1238</a> for details.
*/
@Test
public void testTaggedTemplateChildrenHaveAstRoot() {
String script = "tag`template`";

AstRoot root = new Parser().parse(script, "test", 0);
TaggedTemplateFinder finder = new TaggedTemplateFinder();
root.visit(finder);
TaggedTemplateLiteral taggedTemplate = finder.getNode();

assertNotNull(taggedTemplate);
assertEquals(root, taggedTemplate.getAstRoot());
assertEquals(root, taggedTemplate.getTarget().getAstRoot());
assertEquals(root, taggedTemplate.getTemplateLiteral().getAstRoot());
}

/**
* AST nodes, which are descendants of a tagged template node should resolve the AST root.
*
* <p>See <a href="https://github.com/mozilla/rhino/issues/1238">#1238</a> for details.
*/
@Test
public void testInnerNodeHasAstRoot() {
String script = "someObj.property()`template`";

AstRoot root = new Parser().parse(script, "test", 0);
NameFinder finder = new NameFinder("property");
root.visit(finder);
Name nameNode = finder.getNode();

assertNotNull(nameNode);
assertEquals(root, nameNode.getAstRoot());
}

/** Finds first {@link TaggedTemplateLiteral} node in the AST. */
private static class TaggedTemplateFinder implements NodeVisitor {
private TaggedTemplateLiteral node;

public TaggedTemplateLiteral getNode() {
return node;
}

@Override
public boolean visit(AstNode node) {
if (node instanceof TaggedTemplateLiteral) {
this.node = (TaggedTemplateLiteral) node;
return false;
}
return true;
}
}

/** Finds first {@link Name} node for given identifier. */
private static class NameFinder implements NodeVisitor {
private Name node;
private String name;

public NameFinder(String name) {
this.name = name;
}

public Name getNode() {
return node;
}

@Override
public boolean visit(AstNode node) {
if (node instanceof Name) {
Name nameNode = (Name) node;
if (nameNode.getIdentifier().equals(name)) {
this.node = nameNode;
return false;
}
}
return true;
}
}
}

0 comments on commit 2daadfc

Please sign in to comment.