Search in sources :

Example 31 with JSDocInfoBuilder

use of com.google.javascript.rhino.JSDocInfoBuilder 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.
}
Also used : Node(com.google.javascript.rhino.Node) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) JSDocInfo(com.google.javascript.rhino.JSDocInfo) JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder)

Example 32 with JSDocInfoBuilder

use of com.google.javascript.rhino.JSDocInfoBuilder 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);
}
Also used : Node(com.google.javascript.rhino.Node) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder)

Example 33 with JSDocInfoBuilder

use of com.google.javascript.rhino.JSDocInfoBuilder in project closure-compiler by google.

the class JsDocInfoParserTest method testParseLicense.

public void testParseLicense() {
    this.fileLevelJsDocBuilder = new JSDocInfoBuilder(false);
    String comment = "@license Foo\nBar\n\nBaz*/";
    parse(comment);
    JSDocInfo info = this.fileLevelJsDocBuilder.build(true);
    assertThat(info.getLicense()).isEqualTo(" Foo\nBar\n\nBaz");
}
Also used : JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder) JSDocInfo(com.google.javascript.rhino.JSDocInfo)

Example 34 with JSDocInfoBuilder

use of com.google.javascript.rhino.JSDocInfoBuilder in project closure-compiler by google.

the class ClosureRewriteClass method mergeJsDocFor.

private JSDocInfo mergeJsDocFor(ClassDefinition cls, Node associatedNode) {
    // avoid null checks
    JSDocInfo classInfo = (cls.classInfo != null) ? cls.classInfo : new JSDocInfoBuilder(true).build(true);
    JSDocInfo ctorInfo = (cls.constructor.info != null) ? cls.constructor.info : new JSDocInfoBuilder(true).build(true);
    Node superNode = cls.superClass;
    // Start with a clone of the constructor info if there is one.
    JSDocInfoBuilder mergedInfo = cls.constructor.info != null ? JSDocInfoBuilder.copyFrom(ctorInfo) : new JSDocInfoBuilder(true);
    // merge block description
    String blockDescription = Joiner.on("\n").skipNulls().join(classInfo.getBlockDescription(), ctorInfo.getBlockDescription());
    if (!blockDescription.isEmpty()) {
        mergedInfo.recordBlockDescription(blockDescription);
    }
    // merge suppressions
    Set<String> suppressions = new HashSet<>();
    suppressions.addAll(classInfo.getSuppressions());
    suppressions.addAll(ctorInfo.getSuppressions());
    if (!suppressions.isEmpty()) {
        mergedInfo.recordSuppressions(suppressions);
    }
    // Use class deprecation if set.
    if (classInfo.isDeprecated()) {
        mergedInfo.recordDeprecated();
    }
    String deprecationReason = null;
    if (classInfo.getDeprecationReason() != null) {
        deprecationReason = classInfo.getDeprecationReason();
        mergedInfo.recordDeprecationReason(deprecationReason);
    }
    // Use class visibility if specifically set
    Visibility visibility = classInfo.getVisibility();
    if (visibility != null && visibility != JSDocInfo.Visibility.INHERITED) {
        mergedInfo.recordVisibility(classInfo.getVisibility());
    }
    if (classInfo.isAbstract()) {
        mergedInfo.recordAbstract();
    }
    if (classInfo.isConstant()) {
        mergedInfo.recordConstancy();
    }
    if (classInfo.isExport()) {
        mergedInfo.recordExport();
    }
    // If @ngInject is on the ctor, it's already been copied above.
    if (classInfo.isNgInject()) {
        compiler.report(JSError.make(associatedNode, GOOG_CLASS_NG_INJECT_ON_CLASS));
        mergedInfo.recordNgInject(true);
    }
    if (classInfo.makesUnrestricted() || ctorInfo.makesUnrestricted()) {
        mergedInfo.recordUnrestricted();
    } else if (classInfo.makesDicts() || ctorInfo.makesDicts()) {
        mergedInfo.recordDict();
    } else {
        // @struct by default
        mergedInfo.recordStruct();
    }
    // @constructor is implied, @interface must be explicit
    boolean isInterface = classInfo.isInterface() || ctorInfo.isInterface();
    if (isInterface) {
        if (classInfo.usesImplicitMatch() || ctorInfo.usesImplicitMatch()) {
            mergedInfo.recordImplicitMatch();
        } else {
            mergedInfo.recordInterface();
        }
        List<JSTypeExpression> extendedInterfaces = null;
        if (classInfo.getExtendedInterfacesCount() > 0) {
            extendedInterfaces = classInfo.getExtendedInterfaces();
        } else if (ctorInfo.getExtendedInterfacesCount() == 0 && superNode != null) {
            extendedInterfaces = ImmutableList.of(new JSTypeExpression(new Node(Token.BANG, IR.string(superNode.getQualifiedName())), VIRTUAL_FILE));
        }
        if (extendedInterfaces != null) {
            for (JSTypeExpression extend : extendedInterfaces) {
                mergedInfo.recordExtendedInterface(extend);
            }
        }
    } else {
        // @constructor by default
        mergedInfo.recordConstructor();
        if (classInfo.getBaseType() != null) {
            mergedInfo.recordBaseType(classInfo.getBaseType());
        } else if (superNode != null) {
            // a "super" implies @extends, build a default.
            JSTypeExpression baseType = new JSTypeExpression(new Node(Token.BANG, IR.string(superNode.getQualifiedName())), VIRTUAL_FILE);
            mergedInfo.recordBaseType(baseType);
        }
        // @implements from the class if they exist
        List<JSTypeExpression> interfaces = classInfo.getImplementedInterfaces();
        for (JSTypeExpression implemented : interfaces) {
            mergedInfo.recordImplementedInterface(implemented);
        }
    }
    // merge @template types if they exist
    List<String> templateNames = new ArrayList<>();
    templateNames.addAll(classInfo.getTemplateTypeNames());
    templateNames.addAll(ctorInfo.getTemplateTypeNames());
    for (String typeName : templateNames) {
        mergedInfo.recordTemplateTypeName(typeName);
    }
    return mergedInfo.build();
}
Also used : Node(com.google.javascript.rhino.Node) ArrayList(java.util.ArrayList) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) Visibility(com.google.javascript.rhino.JSDocInfo.Visibility) JSDocInfo(com.google.javascript.rhino.JSDocInfo) JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder) HashSet(java.util.HashSet)

Example 35 with JSDocInfoBuilder

use of com.google.javascript.rhino.JSDocInfoBuilder in project closure-compiler by google.

the class DeclaredGlobalExternsOnWindow method addExtern.

private static void addExtern(Node node) {
    String name = node.getString();
    JSDocInfo oldJSDocInfo = NodeUtil.getBestJSDocInfo(node);
    // TODO(tbreisacher): Consider adding externs to 'this' instead of 'window',
    // for environments where the global object is not called 'window.'
    Node window = IR.name("window");
    Node string = IR.string(name);
    Node getprop = IR.getprop(window, string);
    Node newNode = getprop;
    if (oldJSDocInfo != null) {
        JSDocInfoBuilder builder;
        if (oldJSDocInfo.isConstructorOrInterface() || oldJSDocInfo.hasEnumParameterType()) {
            Node nameNode = IR.name(name);
            newNode = IR.assign(getprop, nameNode);
            builder = new JSDocInfoBuilder(false);
            if (oldJSDocInfo.isConstructor()) {
                builder.recordConstructor();
            }
            if (oldJSDocInfo.isInterface()) {
                builder.recordInterface();
            }
            if (oldJSDocInfo.usesImplicitMatch()) {
                builder.recordImplicitMatch();
            }
            if (oldJSDocInfo.hasEnumParameterType()) {
                builder.recordEnumParameterType(oldJSDocInfo.getEnumParameterType());
            }
        } else {
            if (NodeUtil.isNamespaceDecl(node)) {
                newNode = IR.assign(getprop, IR.name(name));
            } else {
                Node rhs = NodeUtil.getRValueOfLValue(node);
                // Type-aliasing definition
                if (oldJSDocInfo.hasConstAnnotation() && rhs != null && rhs.isQualifiedName()) {
                    newNode = IR.assign(getprop, rhs.cloneTree());
                }
            }
            builder = JSDocInfoBuilder.copyFrom(oldJSDocInfo);
        }
        // TODO(blickly): Remove these suppressions when all externs declarations on window are gone.
        builder.recordSuppressions(ImmutableSet.of("const", "duplicate"));
        JSDocInfo jsDocInfo = builder.build();
        newNode.setJSDocInfo(jsDocInfo);
    }
    newNode.useSourceInfoFromForTree(node);
    newNode.setOriginalName(name);
    node.getGrandparent().addChildToBack(IR.exprResult(newNode));
}
Also used : Node(com.google.javascript.rhino.Node) JSDocInfo(com.google.javascript.rhino.JSDocInfo) JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder)

Aggregations

JSDocInfoBuilder (com.google.javascript.rhino.JSDocInfoBuilder)40 Node (com.google.javascript.rhino.Node)27 JSTypeExpression (com.google.javascript.rhino.JSTypeExpression)18 TypeDeclarationNode (com.google.javascript.rhino.Node.TypeDeclarationNode)10 JSDocInfo (com.google.javascript.rhino.JSDocInfo)8 MemberDefinition (com.google.javascript.jscomp.PolymerPass.MemberDefinition)4 Visibility (com.google.javascript.rhino.JSDocInfo.Visibility)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 ClassDeclarationMetadata (com.google.javascript.jscomp.Es6RewriteClass.ClassDeclarationMetadata)1 FeatureSet (com.google.javascript.jscomp.parsing.parser.FeatureSet)1 TypeI (com.google.javascript.rhino.TypeI)1 TypeIRegistry (com.google.javascript.rhino.TypeIRegistry)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1