use of com.google.javascript.rhino.JSTypeExpression in project closure-compiler by google.
the class EarlyEs6ToEs3Converter method visitRestParam.
/**
* Processes a rest parameter
*/
private void visitRestParam(NodeTraversal t, Node restParam, Node paramList) {
Node functionBody = paramList.getNext();
int restIndex = paramList.getIndexOfChild(restParam);
String paramName = restParam.getFirstChild().getString();
Node nameNode = IR.name(paramName);
nameNode.setVarArgs(true);
nameNode.setJSDocInfo(restParam.getJSDocInfo());
paramList.replaceChild(restParam, nameNode);
// Make sure rest parameters are typechecked
JSTypeExpression type = null;
JSDocInfo info = restParam.getJSDocInfo();
JSDocInfo functionInfo = NodeUtil.getBestJSDocInfo(paramList.getParent());
if (info != null) {
type = info.getType();
} else {
if (functionInfo != null) {
type = functionInfo.getParameterType(paramName);
}
}
if (type != null && type.getRoot().getToken() != Token.ELLIPSIS) {
compiler.report(JSError.make(restParam, BAD_REST_PARAMETER_ANNOTATION));
}
if (!functionBody.hasChildren()) {
// If function has no body, we are done!
t.reportCodeChange();
return;
}
Node newBlock = IR.block().useSourceInfoFrom(functionBody);
Node name = IR.name(paramName);
Node let = IR.let(name, IR.name(REST_PARAMS)).useSourceInfoIfMissingFromForTree(functionBody);
newBlock.addChildToFront(let);
for (Node child : functionBody.children()) {
newBlock.addChildToBack(child.detach());
}
if (type != null) {
Node arrayType = IR.string("Array");
Node typeNode = type.getRoot();
Node memberType = typeNode.getToken() == Token.ELLIPSIS ? typeNode.getFirstChild().cloneTree() : typeNode.cloneTree();
if (functionInfo != null) {
memberType = replaceTypeVariablesWithUnknown(functionInfo, memberType);
}
arrayType.addChildToFront(new Node(Token.BLOCK, memberType).useSourceInfoIfMissingFrom(typeNode));
JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
builder.recordType(new JSTypeExpression(new Node(Token.BANG, arrayType), restParam.getSourceFileName()));
name.setJSDocInfo(builder.build());
}
// TODO(b/74074478): Use a general utility method instead of an inlined loop.
Node newArr = IR.var(IR.name(REST_PARAMS), IR.arraylit());
functionBody.addChildToFront(newArr.useSourceInfoIfMissingFromForTree(restParam));
Node init = IR.var(IR.name(REST_INDEX), IR.number(restIndex));
Node cond = IR.lt(IR.name(REST_INDEX), IR.getprop(IR.name("arguments"), IR.string("length")));
Node incr = IR.inc(IR.name(REST_INDEX), false);
Node body = IR.block(IR.exprResult(IR.assign(IR.getelem(IR.name(REST_PARAMS), IR.sub(IR.name(REST_INDEX), IR.number(restIndex))), IR.getelem(IR.name("arguments"), IR.name(REST_INDEX)))));
functionBody.addChildAfter(IR.forNode(init, cond, incr, body).useSourceInfoIfMissingFromForTree(restParam), newArr);
functionBody.addChildToBack(newBlock);
compiler.reportChangeToEnclosingScope(newBlock);
// For now, we are running transpilation before type-checking, so we'll
// need to make sure changes don't invalidate the JSDoc annotations.
// Therefore we keep the parameter list the same length and only initialize
// the values if they are set to undefined.
}
use of com.google.javascript.rhino.JSTypeExpression in project closure-compiler by google.
the class Es6ConvertSuper method addSyntheticConstructor.
private void addSyntheticConstructor(Node classNode) {
Node superClass = classNode.getSecondChild();
Node classMembers = classNode.getLastChild();
Node memberDef;
if (superClass.isEmpty()) {
Node function = NodeUtil.emptyFunction();
compiler.reportChangeToChangeScope(function);
memberDef = IR.memberFunctionDef("constructor", function);
} else {
if (!superClass.isQualifiedName()) {
// This will be reported as an error in Es6ToEs3Converter.
return;
}
Node body = IR.block();
// transpile, so don't generate it.
if (!classNode.isFromExterns() && !isInterface(classNode)) {
Node exprResult = IR.exprResult(IR.call(IR.getprop(IR.superNode(), IR.string("apply")), IR.thisNode(), IR.name("arguments")));
body.addChildToFront(exprResult);
}
Node constructor = IR.function(IR.name(""), IR.paramList(IR.name("var_args")), body);
compiler.reportChangeToChangeScope(constructor);
memberDef = IR.memberFunctionDef("constructor", constructor);
JSDocInfoBuilder info = new JSDocInfoBuilder(false);
info.recordParameter("var_args", new JSTypeExpression(new Node(Token.ELLIPSIS, new Node(Token.QMARK)), "<Es6ConvertSuper>"));
memberDef.setJSDocInfo(info.build());
}
memberDef.useSourceInfoIfMissingFromForTree(classNode);
memberDef.makeNonIndexableRecursive();
classMembers.addChildToFront(memberDef);
compiler.reportChangeToEnclosingScope(memberDef);
}
use of com.google.javascript.rhino.JSTypeExpression in project closure-compiler by google.
the class CheckJSDocStyle method checkInlineParams.
/**
* Checks that the inline type annotations are correct.
*/
private void checkInlineParams(NodeTraversal t, Node function) {
Node paramList = NodeUtil.getFunctionParameters(function);
for (Node param : paramList.children()) {
JSDocInfo jsDoc = param.getJSDocInfo();
if (jsDoc == null) {
t.report(param, MISSING_PARAMETER_JSDOC);
return;
} else {
JSTypeExpression paramType = jsDoc.getType();
checkNotNull(paramType, "Inline JSDoc info should always have a type");
checkParam(t, param, null, paramType);
}
}
}
use of com.google.javascript.rhino.JSTypeExpression in project closure-compiler by google.
the class NodeUtilTest method testGetDeclaredTypeExpression2.
public void testGetDeclaredTypeExpression2() {
Node ast = parse("/** @param {string} x */ function f(x) {}");
Node x = getNameNode(ast, "x");
JSTypeExpression typeExpr = NodeUtil.getDeclaredTypeExpression(x);
assertThat(typeExpr.getRoot().getString()).isEqualTo("string");
}
use of com.google.javascript.rhino.JSTypeExpression in project closure-compiler by google.
the class NodeUtilTest method testGetDeclaredTypeExpression3.
public void testGetDeclaredTypeExpression3() {
Node ast = parse("/** @param {...number} x */ function f(...x) {}");
Node x = getNameNode(ast, "x");
JSTypeExpression typeExpr = NodeUtil.getDeclaredTypeExpression(x);
assertNode(typeExpr.getRoot()).hasType(Token.ELLIPSIS);
assertThat(typeExpr.getRoot().getFirstChild().getString()).isEqualTo("number");
}
Aggregations