com.google.javascript.rhino.JSDocInfoBuilder

Here are the examples of the java api class com.google.javascript.rhino.JSDocInfoBuilder taken from open source projects.

1. PolymerClassRewriter#getConstructorDoc()

Project: closure-compiler
File: PolymerClassRewriter.java
/**
   * @return The proper constructor doc for the Polymer call.
   */
private JSDocInfoBuilder getConstructorDoc(final PolymerClassDefinition cls) {
    JSDocInfoBuilder constructorDoc = JSDocInfoBuilder.maybeCopyFrom(cls.constructor.info);
    constructorDoc.recordConstructor();
    JSTypeExpression baseType = new JSTypeExpression(new Node(Token.BANG, IR.string(PolymerPassStaticUtils.getPolymerElementType(cls))), PolymerPass.VIRTUAL_FILE);
    constructorDoc.recordBaseType(baseType);
    String interfaceName = getInterfaceName(cls);
    JSTypeExpression interfaceType = new JSTypeExpression(new Node(Token.BANG, IR.string(interfaceName)), PolymerPass.VIRTUAL_FILE);
    constructorDoc.recordImplementedInterface(interfaceType);
    return constructorDoc;
}

2. PolymerClassRewriter#makeReadOnlySetter()

Project: closure-compiler
File: PolymerClassRewriter.java
/**
   * Adds the generated setter for a readonly property.
   * @see https://www.polymer-project.org/0.8/docs/devguide/properties.html#read-only
   */
private Node makeReadOnlySetter(String propName, String qualifiedPath) {
    String setterName = "_set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
    Node fnNode = IR.function(IR.name(""), IR.paramList(IR.name(propName)), IR.block());
    Node exprResNode = IR.exprResult(IR.assign(NodeUtil.newQName(compiler, qualifiedPath + setterName), fnNode));
    JSDocInfoBuilder info = new JSDocInfoBuilder(true);
    // This is overriding a generated function which was added to the interface in
    // {@code addInterfaceExterns}.
    info.recordOverride();
    exprResNode.getFirstChild().setJSDocInfo(info.build());
    return exprResNode;
}

3. Es6TypedToEs6Converter#visitTypeAlias()

Project: closure-compiler
File: Es6TypedToEs6Converter.java
private void visitTypeAlias(NodeTraversal t, Node n, Node parent) {
    String alias = n.getString();
    if (t.getScope().isDeclared(alias, true)) {
        compiler.report(JSError.make(n, TYPE_ALIAS_ALREADY_DECLARED, alias));
    }
    JSDocInfoBuilder builder = JSDocInfoBuilder.maybeCopyFrom(n.getJSDocInfo());
    builder.recordTypedef(new JSTypeExpression(convertWithLocation(n.getFirstChild()), n.getSourceFileName()));
    Node newName = maybeGetQualifiedNameNode(IR.name(n.getString())).useSourceInfoIfMissingFromForTree(n);
    Node newDec1 = NodeUtil.newQNameDeclaration(compiler, newName.getQualifiedName(), null, builder.build()).useSourceInfoFromForTree(n);
    parent.replaceChild(n, newDec1);
    compiler.reportCodeChange();
}

4. CheckSideEffects#addExtern()

Project: closure-compiler
File: CheckSideEffects.java
private void addExtern() {
    Node name = IR.name(PROTECTOR_FN);
    name.putBooleanProp(Node.IS_CONSTANT_NAME, true);
    Node var = IR.var(name);
    // Add "@noalias" so we can strip the method when AliasExternals is enabled.
    JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
    builder.recordNoAlias();
    var.setJSDocInfo(builder.build());
    CompilerInput input = compiler.getSynthesizedExternsInput();
    name.setStaticSourceFile(input.getSourceFile());
    var.setStaticSourceFile(input.getSourceFile());
    input.getAstRoot(compiler).addChildrenToBack(var);
    compiler.reportCodeChange();
}

5. ClosureRewriteModule#markConstAndCopyJsDoc()

Project: closure-compiler
File: ClosureRewriteModule.java
/**
   * Will skip const if the target is a class definition as that has a different meaning.
   */
private void markConstAndCopyJsDoc(Node from, Node target, Node value) {
    JSDocInfo info = from.getJSDocInfo();
    JSDocInfoBuilder builder = JSDocInfoBuilder.maybeCopyFrom(info);
    // Don't add @const on class declarations because in that context it means "not subclassable".
    if (!isCallTo(value, "goog.defineClass") && !(info != null && info.isConstructorOrInterface())) {
        builder.recordConstancy();
        compiler.reportCodeChange();
    }
    target.setJSDocInfo(builder.build());
}

6. JSTypeTest#testGetAndSetJSDocInfoWithObjectTypes()

Project: closure-compiler
File: JSTypeTest.java
public void testGetAndSetJSDocInfoWithObjectTypes() throws Exception {
    ObjectType sup = registry.createObjectType(null, registry.createAnonymousObjectType(null));
    ObjectType sub = registry.createObjectType(null, sup);
    JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
    builder.recordDeprecated();
    JSDocInfo deprecated = builder.build();
    builder = new JSDocInfoBuilder(false);
    builder.recordVisibility(Visibility.PRIVATE);
    JSDocInfo privateInfo = builder.build();
    sup.defineProperty("X", NUMBER_TYPE, true, null);
    sup.setPropertyJSDocInfo("X", privateInfo);
    sub.defineProperty("X", NUMBER_TYPE, true, null);
    sub.setPropertyJSDocInfo("X", deprecated);
    assertFalse(sup.getOwnPropertyJSDocInfo("X").isDeprecated());
    assertEquals(Visibility.PRIVATE, sup.getOwnPropertyJSDocInfo("X").getVisibility());
    assertTypeEquals(NUMBER_TYPE, sup.getPropertyType("X"));
    assertTrue(sub.getOwnPropertyJSDocInfo("X").isDeprecated());
    assertEquals(Visibility.INHERITED, sub.getOwnPropertyJSDocInfo("X").getVisibility());
    assertTypeEquals(NUMBER_TYPE, sub.getPropertyType("X"));
}

7. PolymerClassRewriter#rewritePolymerClass()

Project: closure-compiler
File: PolymerClassRewriter.java
/**
   * Rewrites a given call to Polymer({}) to a set of declarations and assignments which can be
   * understood by the compiler.
   *
   * @param exprRoot The root expression of the call to Polymer({}).
   * @param cls The extracted {@link PolymerClassDefinition} for the Polymer element created by this
   *     call.
   */
void rewritePolymerClass(Node exprRoot, final PolymerClassDefinition cls, boolean isInGlobalScope) {
    Node call = exprRoot.getFirstChild();
    if (call.isAssign()) {
        call = call.getSecondChild();
    } else if (call.isName()) {
        call = call.getFirstChild();
    }
    Node objLit = cls.descriptor;
    if (hasShorthandAssignment(objLit)) {
        compiler.report(JSError.make(objLit, PolymerPassErrors.POLYMER_SHORTHAND_NOT_SUPPORTED));
        return;
    }
    // Add {@code @lends} to the object literal.
    JSDocInfoBuilder objLitDoc = new JSDocInfoBuilder(true);
    objLitDoc.recordLends(cls.target.getQualifiedName() + ".prototype");
    objLit.setJSDocInfo(objLitDoc.build());
    addTypesToFunctions(objLit, cls.target.getQualifiedName());
    PolymerPassStaticUtils.switchDollarSignPropsToBrackets(objLit, compiler);
    PolymerPassStaticUtils.quoteListenerAndHostAttributeKeys(objLit);
    for (MemberDefinition prop : cls.props) {
        if (prop.value.isObjectLit()) {
            PolymerPassStaticUtils.switchDollarSignPropsToBrackets(prop.value, compiler);
        }
    }
    // For simplicity add everything into a block, before adding it to the AST.
    Node block = IR.block();
    JSDocInfoBuilder constructorDoc = this.getConstructorDoc(cls);
    // Remove the original constructor JS docs from the objlit.
    Node ctorKey = cls.constructor.value.getParent();
    if (ctorKey != null) {
        ctorKey.removeProp(Node.JSDOC_INFO_PROP);
    }
    if (cls.target.isGetProp()) {
        // foo.bar = Polymer({...});
        Node assign = IR.assign(cls.target.cloneTree(), cls.constructor.value.cloneTree());
        assign.setJSDocInfo(constructorDoc.build());
        Node exprResult = IR.exprResult(assign);
        block.addChildToBack(exprResult);
    } else {
        // var foo = Polymer({...}); OR Polymer({...});
        Node var = IR.var(cls.target.cloneTree(), cls.constructor.value.cloneTree());
        var.setJSDocInfo(constructorDoc.build());
        block.addChildToBack(var);
    }
    appendPropertiesToBlock(cls, block, cls.target.getQualifiedName() + ".prototype.");
    appendBehaviorMembersToBlock(cls, block);
    ImmutableList<MemberDefinition> readOnlyProps = parseReadOnlyProperties(cls, block);
    addInterfaceExterns(cls, readOnlyProps);
    removePropertyDocs(objLit);
    block.useSourceInfoIfMissingFromForTree(exprRoot);
    Node statements = block.removeChildren();
    Node parent = exprRoot.getParent();
    // moving to the new type inference system which should be able to infer these types better.
    if (!isInGlobalScope && !cls.target.isGetProp()) {
        Node scriptNode = NodeUtil.getEnclosingScript(exprRoot);
        scriptNode.addChildrenToFront(statements);
    } else {
        Node beforeRoot = parent.getChildBefore(exprRoot);
        if (beforeRoot == null) {
            parent.addChildrenToFront(statements);
        } else {
            parent.addChildrenAfter(statements, beforeRoot);
        }
    }
    if (NodeUtil.isNameDeclaration(exprRoot)) {
        Node assignExpr = varToAssign(exprRoot);
        parent.replaceChild(exprRoot, assignExpr);
    }
    compiler.reportCodeChange();
}

8. NodeUtil#createConstantJsDoc()

Project: closure-compiler
File: NodeUtil.java
static JSDocInfo createConstantJsDoc() {
    JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
    builder.recordConstancy();
    return builder.build();
}

9. ConvertToTypedInterface#getTypeJSDoc()

Project: closure-compiler
File: ConvertToTypedInterface.java
private static JSDocInfo getTypeJSDoc(JSDocInfo oldJSDoc, String contents) {
    JSDocInfoBuilder builder = JSDocInfoBuilder.copyFrom(oldJSDoc);
    builder.recordType(new JSTypeExpression(Node.newString(contents), ""));
    return builder.build();
}

10. ConvertToTypedInterface#getAllTypeJSDoc()

Project: closure-compiler
File: ConvertToTypedInterface.java
private static JSDocInfo getAllTypeJSDoc() {
    JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
    builder.recordType(new JSTypeExpression(new Node(Token.STAR), ""));
    return builder.build();
}

11. JSTypeTest#testGetAndSetJSDocInfoWithNoType()

Project: closure-compiler
File: JSTypeTest.java
public void testGetAndSetJSDocInfoWithNoType() throws Exception {
    JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
    builder.recordDeprecated();
    JSDocInfo deprecated = builder.build();
    NO_TYPE.setPropertyJSDocInfo("X", deprecated);
    assertNull(NO_TYPE.getOwnPropertyJSDocInfo("X"));
}

12. JSTypeTest#testGetAndSetJSDocInfoWithNamedType()

Project: closure-compiler
File: JSTypeTest.java
public void testGetAndSetJSDocInfoWithNamedType() throws Exception {
    JSDocInfoBuilder builder = new JSDocInfoBuilder(false);
    builder.recordDeprecated();
    JSDocInfo info = builder.build();
    assertNull(namedGoogBar.getOwnPropertyJSDocInfo("X"));
    namedGoogBar.setPropertyJSDocInfo("X", info);
    assertTrue(namedGoogBar.getOwnPropertyJSDocInfo("X").isDeprecated());
    assertPropertyTypeInferred(namedGoogBar, "X");
    assertTypeEquals(UNKNOWN_TYPE, namedGoogBar.getPropertyType("X"));
}

13. ProcessEs6Modules#visitScript()

Project: closure-compiler
File: ProcessEs6Modules.java
private void visitScript(NodeTraversal t, Node script) {
    if (!isEs6Module) {
        return;
    }
    ClosureRewriteModule.checkAndSetStrictModeDirective(t, script);
    Preconditions.checkArgument(scriptNodeCount == 1, "ProcessEs6Modules supports only one invocation per " + "CompilerInput / script node");
    // rewriteRequires is here (rather than being part of the main visit()
    // method, because we only want to rewrite the requires if this is an
    // ES6 module.
    rewriteRequires(script);
    URI normalizedAddress = loader.normalizeInputAddress(t.getInput());
    String moduleName = ES6ModuleLoader.toModuleName(normalizedAddress);
    for (Map.Entry<String, NameNodePair> entry : exportMap.entrySet()) {
        String exportedName = entry.getKey();
        String withSuffix = entry.getValue().name;
        Node nodeForSourceInfo = entry.getValue().nodeForSourceInfo;
        Node getProp = IR.getprop(IR.name(moduleName), IR.string(exportedName));
        if (typedefs.contains(exportedName)) {
            // /** @typedef {foo} */
            // moduleName.foo;
            JSDocInfoBuilder builder = new JSDocInfoBuilder(true);
            JSTypeExpression typeExpr = new JSTypeExpression(IR.string(exportedName), script.getSourceFileName());
            builder.recordTypedef(typeExpr);
            JSDocInfo info = builder.build();
            getProp.setJSDocInfo(info);
            Node exprResult = IR.exprResult(getProp).useSourceInfoIfMissingFromForTree(nodeForSourceInfo);
            script.addChildToBack(exprResult);
        } else {
            //   moduleName.foo = foo;
            // with a @const annotation if needed.
            Node assign = IR.assign(getProp, NodeUtil.newQName(compiler, withSuffix));
            Node exprResult = IR.exprResult(assign).useSourceInfoIfMissingFromForTree(nodeForSourceInfo);
            if (classes.contains(exportedName)) {
                JSDocInfoBuilder builder = new JSDocInfoBuilder(true);
                builder.recordConstancy();
                JSDocInfo info = builder.build();
                assign.setJSDocInfo(info);
            }
            script.addChildToBack(exprResult);
        }
    }
    // Rename vars to not conflict in global scope.
    NodeTraversal.traverseEs6(compiler, script, new RenameGlobalVars(moduleName));
    if (!exportMap.isEmpty() || forceRewrite) {
        // Add goog.provide call.
        Node googProvide = IR.exprResult(IR.call(NodeUtil.newQName(compiler, "goog.provide"), IR.string(moduleName)));
        script.addChildToFront(googProvide.copyInformationFromForTree(script));
        if (reportDependencies) {
            t.getInput().addProvide(moduleName);
        }
    }
    JSDocInfoBuilder jsDocInfo = script.getJSDocInfo() == null ? new JSDocInfoBuilder(false) : JSDocInfoBuilder.copyFrom(script.getJSDocInfo());
    if (!jsDocInfo.isPopulatedWithFileOverview()) {
        jsDocInfo.recordFileOverview("");
    }
    // Don't check provides and requires, since most of them are auto-generated.
    jsDocInfo.recordSuppressions(ImmutableSet.of("missingProvide", "missingRequire"));
    script.setJSDocInfo(jsDocInfo.build());
    exportMap.clear();
    compiler.reportCodeChange();
}

14. PolymerPass#appendPolymerElementExterns()

Project: closure-compiler
File: PolymerPass.java
/**
   * Duplicates the PolymerElement externs with a different element base class if needed.
   * For example, if the base class is HTMLInputElement, then a class PolymerInputElement will be
   * added. If the element does not extend a native HTML element, this method is a no-op.
   */
private void appendPolymerElementExterns(final PolymerClassDefinition def) {
    if (!nativeExternsAdded.add(def.nativeBaseElement)) {
        return;
    }
    Node block = IR.block();
    Node baseExterns = polymerElementExterns.cloneTree();
    String polymerElementType = PolymerPassStaticUtils.getPolymerElementType(def);
    baseExterns.getFirstChild().setString(polymerElementType);
    String elementType = tagNameMap.get(def.nativeBaseElement);
    JSTypeExpression elementBaseType = new JSTypeExpression(new Node(Token.BANG, IR.string(elementType)), VIRTUAL_FILE);
    JSDocInfoBuilder baseDocs = JSDocInfoBuilder.copyFrom(baseExterns.getJSDocInfo());
    baseDocs.changeBaseType(elementBaseType);
    baseExterns.setJSDocInfo(baseDocs.build());
    block.addChildToBack(baseExterns);
    for (Node baseProp : polymerElementProps) {
        Node newProp = baseProp.cloneTree();
        Node newPropRootName = NodeUtil.getRootOfQualifiedName(newProp.getFirstFirstChild());
        newPropRootName.setString(polymerElementType);
        block.addChildToBack(newProp);
    }
    block.useSourceInfoIfMissingFromForTree(polymerElementExterns);
    Node parent = polymerElementExterns.getParent();
    Node stmts = block.removeChildren();
    parent.addChildrenAfter(stmts, polymerElementExterns);
    compiler.reportCodeChange();
}

15. PolymerClassRewriter#addInterfaceExterns()

Project: closure-compiler
File: PolymerClassRewriter.java
/**
   * Adds an interface for the given ClassDefinition to externs. This allows generated setter
   * functions for read-only properties to avoid renaming altogether.
   * @see https://www.polymer-project.org/0.8/docs/devguide/properties.html#read-only
   */
private void addInterfaceExterns(final PolymerClassDefinition cls, List<MemberDefinition> readOnlyProps) {
    Node block = IR.block();
    String interfaceName = getInterfaceName(cls);
    Node fnNode = IR.function(IR.name(""), IR.paramList(), IR.block());
    Node varNode = IR.var(NodeUtil.newQName(compiler, interfaceName), fnNode);
    JSDocInfoBuilder info = new JSDocInfoBuilder(true);
    info.recordInterface();
    varNode.setJSDocInfo(info.build());
    block.addChildToBack(varNode);
    appendPropertiesToBlock(cls, block, interfaceName + ".prototype.");
    for (MemberDefinition prop : readOnlyProps) {
        // Add all _set* functions to avoid renaming.
        String propName = prop.name.getString();
        String setterName = "_set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);
        Node setterExprNode = IR.exprResult(NodeUtil.newQName(compiler, interfaceName + ".prototype." + setterName));
        JSDocInfoBuilder setterInfo = new JSDocInfoBuilder(true);
        JSTypeExpression propType = PolymerPassStaticUtils.getTypeFromProperty(prop, compiler);
        setterInfo.recordParameter(propName, propType);
        setterExprNode.getFirstChild().setJSDocInfo(setterInfo.build());
        block.addChildToBack(setterExprNode);
    }
    block.useSourceInfoIfMissingFromForTree(polymerElementExterns);
    Node parent = polymerElementExterns.getParent();
    Node stmts = block.removeChildren();
    parent.addChildrenToBack(stmts);
    compiler.reportCodeChange();
}

16. Es6TypedToEs6Converter#visitEnum()

Project: closure-compiler
File: Es6TypedToEs6Converter.java
private void visitEnum(Node n, Node parent) {
    Node name = n.getFirstChild();
    Node members = n.getLastChild();
    double nextValue = 0;
    Node[] stringKeys = new Node[members.getChildCount()];
    for (int i = 0; i < members.getChildCount(); i++) {
        Node child = members.getChildAtIndex(i);
        if (child.hasChildren()) {
            nextValue = child.getFirstChild().getDouble() + 1;
        } else {
            child.addChildToFront(IR.number(nextValue++));
        }
        stringKeys[i] = child;
    }
    for (Node child : stringKeys) {
        child.detachFromParent();
    }
    String oldName = name.getString();
    String qName = maybePrependCurrNamespace(oldName);
    JSDocInfoBuilder builder = JSDocInfoBuilder.maybeCopyFrom(n.getJSDocInfo());
    builder.recordEnumParameterType(new JSTypeExpression(IR.string("number"), n.getSourceFileName()));
    Node newDec = NodeUtil.newQNameDeclaration(compiler, qName, IR.objectlit(stringKeys), builder.build()).useSourceInfoFromForTree(n);
    n.setJSDocInfo(null);
    parent.replaceChild(n, newDec);
    compiler.reportCodeChange();
}

17. Es6TypedToEs6Converter#visitInterface()

Project: closure-compiler
File: Es6TypedToEs6Converter.java
private void visitInterface(Node n, Node parent) {
    maybeAddGenerics(n, n);
    Node name = n.getFirstChild();
    Node superTypes = name.getNext();
    JSDocInfoBuilder doc = JSDocInfoBuilder.maybeCopyFrom(n.getJSDocInfo());
    doc.recordInterface();
    if (!superTypes.isEmpty()) {
        for (Node child : superTypes.children()) {
            Node type = convertWithLocation(child);
            doc.recordExtendedInterface(new JSTypeExpression(type, n.getSourceFileName()));
        }
    }
    Node insertionPoint = n;
    Node members = n.getLastChild();
    for (Node member : members.children()) {
        if (member.isCallSignature()) {
            compiler.report(JSError.make(n, CALL_SIGNATURE_NOT_SUPPORTED));
        }
        if (member.isIndexSignature()) {
            doc.recordExtendedInterface(createIObject(member));
        }
        // Synthesize a block for method signatures, or convert it to a member variable if optional.
        if (member.isMemberFunctionDef()) {
            Node function = member.getFirstChild();
            if (function.isOptionalEs6Typed()) {
                member = convertMemberFunctionToMemberVariable(member);
            } else {
                function.getLastChild().setType(Token.BLOCK);
            }
        }
        if (member.isMemberVariableDef()) {
            Node newNode = createPropertyDefinition(member, name.getString());
            insertionPoint.getParent().addChildAfter(newNode, insertionPoint);
            insertionPoint = newNode;
        }
    }
    n.setJSDocInfo(doc.build());
    // Convert interface to class
    n.setType(Token.CLASS);
    Node empty = new Node(Token.EMPTY).useSourceInfoIfMissingFrom(n);
    n.replaceChild(superTypes, empty);
    members.setType(Token.CLASS_MEMBERS);
    maybeCreateQualifiedDeclaration(n, parent);
    compiler.reportCodeChange();
}

18. Es6ToEs3Converter#addToDefinePropertiesObject()

Project: closure-compiler
File: Es6ToEs3Converter.java
/**
   * @param member A getter or setter, or a computed property that is a getter/setter.
   */
private void addToDefinePropertiesObject(ClassDeclarationMetadata metadata, Node member) {
    Node obj = member.isStaticMember() ? metadata.definePropertiesObjForClass : metadata.definePropertiesObjForPrototype;
    Node prop = member.isComputedProp() ? NodeUtil.getFirstComputedPropMatchingKey(obj, member.getFirstChild()) : NodeUtil.getFirstPropMatchingKey(obj, member.getString());
    if (prop == null) {
        prop = IR.objectlit(IR.stringKey("configurable", IR.trueNode()), IR.stringKey("enumerable", IR.trueNode()));
        if (member.isComputedProp()) {
            obj.addChildToBack(IR.computedProp(member.getFirstChild().cloneTree(), prop));
        } else {
            obj.addChildToBack(IR.stringKey(member.getString(), prop));
        }
    }
    Node function = member.getLastChild();
    JSDocInfoBuilder info = JSDocInfoBuilder.maybeCopyFrom(NodeUtil.getBestJSDocInfo(function));
    info.recordThisType(new JSTypeExpression(new Node(Token.BANG, IR.string(metadata.fullClassName)), member.getSourceFileName()));
    Node stringKey = IR.stringKey((member.isGetterDef() || member.getBooleanProp(Node.COMPUTED_PROP_GETTER)) ? "get" : "set", function.detachFromParent());
    stringKey.setJSDocInfo(info.build());
    prop.addChildToBack(stringKey);
    prop.useSourceInfoIfMissingFromForTree(member);
}

19. Es6ToEs3Converter#visitClass()

Project: closure-compiler
File: Es6ToEs3Converter.java
/**
   * Classes are processed in 3 phases:
   * <ol>
   *   <li>The class name is extracted.
   *   <li>Class members are processed and rewritten.
   *   <li>The constructor is built.
   * </ol>
   */
private void visitClass(final Node classNode, final Node parent) {
    checkClassReassignment(classNode);
    // Collect Metadata
    ClassDeclarationMetadata metadata = ClassDeclarationMetadata.create(classNode, parent);
    if (metadata == null || metadata.fullClassName == null) {
        throw new IllegalStateException("Can only convert classes that are declarations or the right hand" + " side of a simple assignment: " + classNode);
    }
    if (metadata.hasSuperClass() && !metadata.superClassNameNode.isQualifiedName()) {
        compiler.report(JSError.make(metadata.superClassNameNode, DYNAMIC_EXTENDS_TYPE));
        return;
    }
    Preconditions.checkState(NodeUtil.isStatement(metadata.insertionPoint), "insertion point must be a statement: %s", metadata.insertionPoint);
    Node constructor = null;
    JSDocInfo ctorJSDocInfo = null;
    // Process all members of the class
    Node classMembers = classNode.getLastChild();
    for (Node member : classMembers.children()) {
        if ((member.isComputedProp() && (member.getBooleanProp(Node.COMPUTED_PROP_GETTER) || member.getBooleanProp(Node.COMPUTED_PROP_SETTER))) || (member.isGetterDef() || member.isSetterDef())) {
            visitComputedPropInClass(member, metadata);
        } else if (member.isMemberFunctionDef() && member.getString().equals("constructor")) {
            ctorJSDocInfo = member.getJSDocInfo();
            constructor = member.getFirstChild().detachFromParent();
            if (!metadata.anonymous) {
                // Turns class Foo { constructor: function() {} } into function Foo() {},
                // i.e. attaches the name to the ctor function.
                constructor.replaceChild(constructor.getFirstChild(), metadata.classNameNode.cloneNode());
            }
        } else if (member.isEmpty()) {
        // Do nothing.
        } else {
            Preconditions.checkState(member.isMemberFunctionDef() || member.isComputedProp(), "Unexpected class member:", member);
            Preconditions.checkState(!member.getBooleanProp(Node.COMPUTED_PROP_VARIABLE), "Member variables should have been transpiled earlier:", member);
            visitClassMember(member, metadata);
        }
    }
    if (metadata.definePropertiesObjForPrototype.hasChildren()) {
        Node definePropsCall = IR.exprResult(IR.call(NodeUtil.newQName(compiler, "Object.defineProperties"), NodeUtil.newQName(compiler, metadata.fullClassName + ".prototype"), metadata.definePropertiesObjForPrototype));
        definePropsCall.useSourceInfoIfMissingFromForTree(classNode);
        metadata.insertNodeAndAdvance(definePropsCall);
        visitObject(metadata.definePropertiesObjForPrototype);
    }
    if (metadata.definePropertiesObjForClass.hasChildren()) {
        Node definePropsCall = IR.exprResult(IR.call(NodeUtil.newQName(compiler, "Object.defineProperties"), NodeUtil.newQName(compiler, metadata.fullClassName), metadata.definePropertiesObjForClass));
        definePropsCall.useSourceInfoIfMissingFromForTree(classNode);
        metadata.insertNodeAndAdvance(definePropsCall);
        visitObject(metadata.definePropertiesObjForClass);
    }
    Preconditions.checkNotNull(constructor);
    JSDocInfo classJSDoc = NodeUtil.getBestJSDocInfo(classNode);
    JSDocInfoBuilder newInfo = JSDocInfoBuilder.maybeCopyFrom(classJSDoc);
    newInfo.recordConstructor();
    Node enclosingStatement = NodeUtil.getEnclosingStatement(classNode);
    if (metadata.hasSuperClass()) {
        String superClassString = metadata.superClassNameNode.getQualifiedName();
        if (newInfo.isInterfaceRecorded()) {
            newInfo.recordExtendedInterface(new JSTypeExpression(new Node(Token.BANG, IR.string(superClassString)), metadata.superClassNameNode.getSourceFileName()));
        } else {
            if (!classNode.isFromExterns()) {
                Node inherits = IR.call(NodeUtil.newQName(compiler, INHERITS), NodeUtil.newQName(compiler, metadata.fullClassName), NodeUtil.newQName(compiler, superClassString));
                Node inheritsCall = IR.exprResult(inherits);
                compiler.ensureLibraryInjected("es6/util/inherits", false);
                inheritsCall.useSourceInfoIfMissingFromForTree(classNode);
                enclosingStatement.getParent().addChildAfter(inheritsCall, enclosingStatement);
            }
            newInfo.recordBaseType(new JSTypeExpression(new Node(Token.BANG, IR.string(superClassString)), metadata.superClassNameNode.getSourceFileName()));
        }
    }
    addTypeDeclarations(metadata, enclosingStatement);
    updateClassJsDoc(ctorJSDocInfo, newInfo);
    if (NodeUtil.isStatement(classNode)) {
        constructor.getFirstChild().setString("");
        Node ctorVar = IR.let(metadata.classNameNode.cloneNode(), constructor);
        ctorVar.useSourceInfoIfMissingFromForTree(classNode);
        parent.replaceChild(classNode, ctorVar);
    } else {
        parent.replaceChild(classNode, constructor);
    }
    if (NodeUtil.isStatement(constructor)) {
        constructor.setJSDocInfo(newInfo.build());
    } else if (parent.isName()) {
        // The constructor function is the RHS of a var statement.
        // Add the JSDoc to the VAR node.
        Node var = parent.getParent();
        var.setJSDocInfo(newInfo.build());
    } else if (constructor.getParent().isName()) {
        // Is a newly created VAR node.
        Node var = constructor.getGrandparent();
        var.setJSDocInfo(newInfo.build());
    } else if (parent.isAssign()) {
        // The constructor function is the RHS of an assignment.
        // Add the JSDoc to the ASSIGN node.
        parent.setJSDocInfo(newInfo.build());
    } else {
        throw new IllegalStateException("Unexpected parent node " + parent);
    }
    compiler.reportCodeChange();
}

20. Es6TemplateLiterals#visitTaggedTemplateLiteral()

Project: closure-compiler
File: Es6TemplateLiterals.java
/**
   * Converts tag`a\tb${bar}` to:
   *   // A global (module) scoped variable
   *   var $jscomp$templatelit$0 = ["a\tb"];   // cooked string array
   *   $jscomp$templatelit$0.raw = ["a\\tb"];  // raw string array
   *   ...
   *   // A call to the tagging function
   *   tag($jscomp$templatelit$0, bar);
   *
   *   See template_literal_test.js for more examples.
   *
   * @param n A TAGGED_TEMPLATELIT node
   */
static void visitTaggedTemplateLiteral(NodeTraversal t, Node n) {
    Node templateLit = n.getLastChild();
    // Prepare the raw and cooked string arrays.
    Node raw = createRawStringArray(templateLit);
    Node cooked = createCookedStringArray(templateLit);
    // Specify the type of the first argument to be ITemplateArray.
    JSTypeExpression nonNullSiteObject = new JSTypeExpression(JsDocInfoParser.parseTypeString("!ITemplateArray"), "<Es6TemplateLiterals.java>");
    JSDocInfoBuilder info = new JSDocInfoBuilder(false);
    info.recordType(nonNullSiteObject);
    Node siteObject = IR.cast(cooked, info.build());
    // Create a variable representing the template literal.
    Node callsiteId = IR.name(TEMPLATELIT_VAR + t.getCompiler().getUniqueNameIdSupplier().get());
    Node var = IR.var(callsiteId, siteObject).useSourceInfoIfMissingFromForTree(n);
    Node script = NodeUtil.getEnclosingScript(n);
    script.addChildrenToFront(var);
    // Define the "raw" property on the introduced variable.
    Node defineRaw = IR.exprResult(IR.assign(IR.getprop(callsiteId.cloneNode(), IR.string("raw")), raw)).useSourceInfoIfMissingFromForTree(n);
    script.addChildAfter(defineRaw, var);
    // Generate the call expression.
    Node call = IR.call(n.removeFirstChild(), callsiteId.cloneNode());
    for (Node child = templateLit.getFirstChild(); child != null; child = child.getNext()) {
        if (!child.isString()) {
            call.addChildToBack(child.removeFirstChild());
        }
    }
    call.useSourceInfoIfMissingFromForTree(templateLit);
    call.putBooleanProp(Node.FREE_CALL, !call.getFirstChild().isGetProp());
    n.getParent().replaceChild(n, call);
    t.getCompiler().reportCodeChange();
}

21. Es6RewriteGenerators#visitGenerator()

Project: closure-compiler
File: Es6RewriteGenerators.java
private void visitGenerator(Node n, Node parent) {
    compiler.ensureLibraryInjected("es6/symbol", false);
    hasTranslatedTry = false;
    Node genBlock = compiler.parseSyntheticCode(Joiner.on('\n').join("function generatorBody() {", "  var " + GENERATOR_STATE + " = " + generatorCaseCount + ";", "  function $jscomp$generator$impl(" + GENERATOR_NEXT_ARG + ", ", "      " + GENERATOR_THROW_ARG + ") {", "    while (1) switch (" + GENERATOR_STATE + ") {", "      case " + generatorCaseCount + ":", "      default:", "        return {value: undefined, done: true};", "    }", "  }", // TODO(tbreisacher): Remove this cast if we start returning an actual Generator object.
    "  var iterator = /** @type {!Generator<?>} */ ({", "    next: function(arg) { return $jscomp$generator$impl(arg, undefined); },", "    throw: function(arg) { return $jscomp$generator$impl(undefined, arg); },", // http://www.ecma-international.org/ecma-262/6.0/#sec-generator.prototype.return
    "    return: function(arg) { throw Error('Not yet implemented'); },", "  });", "  $jscomp.initSymbolIterator();", "  /** @this {!Generator<?>} */", "  iterator[Symbol.iterator] = function() { return this; };", "  return iterator;", "}")).getFirstChild().getLastChild().detachFromParent();
    generatorCaseCount++;
    originalGeneratorBody = n.getLastChild();
    n.replaceChild(originalGeneratorBody, genBlock);
    n.setIsGeneratorFunction(false);
    // TODO(mattloring): remove this suppression once we can optimize the switch statement to
    // remove unused cases.
    JSDocInfoBuilder builder = JSDocInfoBuilder.maybeCopyFrom(n.getJSDocInfo());
    // TODO(mattloring): copy existing suppressions.
    builder.recordSuppressions(ImmutableSet.of("uselessCode"));
    JSDocInfo info = builder.build();
    n.setJSDocInfo(info);
    // Set state to the default after the body of the function has completed.
    originalGeneratorBody.addChildToBack(IR.exprResult(IR.assign(IR.name(GENERATOR_STATE), IR.number(-1))));
    enclosingBlock = getUnique(genBlock, Token.CASE).getLastChild();
    hoistRoot = genBlock.getFirstChild();
    if (NodeUtil.isNameReferenced(originalGeneratorBody, GENERATOR_ARGUMENTS)) {
        hoistRoot.getParent().addChildAfter(IR.var(IR.name(GENERATOR_ARGUMENTS), IR.name("arguments")), hoistRoot);
    }
    if (NodeUtil.isNameReferenced(originalGeneratorBody, GENERATOR_THIS)) {
        hoistRoot.getParent().addChildAfter(IR.var(IR.name(GENERATOR_THIS), IR.thisNode()), hoistRoot);
    }
    while (originalGeneratorBody.hasChildren()) {
        currentStatement = originalGeneratorBody.removeFirstChild();
        boolean advanceCase = translateStatementInOriginalBody();
        if (advanceCase) {
            int caseNumber;
            if (currentStatement.isGeneratorMarker()) {
                caseNumber = (int) currentStatement.getFirstChild().getDouble();
            } else {
                caseNumber = generatorCaseCount;
                generatorCaseCount++;
            }
            Node oldCase = enclosingBlock.getParent();
            Node newCase = IR.caseNode(IR.number(caseNumber), IR.block());
            enclosingBlock = newCase.getLastChild();
            if (oldCase.isTry()) {
                oldCase = oldCase.getGrandparent();
                if (!currentExceptionContext.isEmpty()) {
                    Node newTry = IR.tryCatch(IR.block(), currentExceptionContext.get(0).catchBlock.cloneTree());
                    newCase.getLastChild().addChildToBack(newTry);
                    enclosingBlock = newCase.getLastChild().getLastChild().getFirstChild();
                }
            }
            oldCase.getParent().addChildAfter(newCase, oldCase);
        }
    }
    parent.useSourceInfoIfMissingFromForTree(parent);
    compiler.reportCodeChange();
}

22. ClosureRewriteModule#markConst()

Project: closure-compiler
File: ClosureRewriteModule.java
private void markConst(Node n) {
    JSDocInfoBuilder builder = JSDocInfoBuilder.maybeCopyFrom(n.getJSDocInfo());
    builder.recordConstancy();
    n.setJSDocInfo(builder.build());
}

23. ClosureRewriteClass#mergeJsDocFor()

Project: closure-compiler
File: ClosureRewriteClass.java
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.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();
}

24. JSDocInfoPrinterTest#setUp()

Project: closure-compiler
File: JSDocInfoPrinterTest.java
@Override
protected void setUp() {
    builder = new JSDocInfoBuilder(true);
}

25. Es6TypedToEs6Converter#maybeVisitColonType()

Project: closure-compiler
File: Es6TypedToEs6Converter.java
private void maybeVisitColonType(Node n, Node jsDocNode) {
    Node type = n.getDeclaredTypeExpression();
    boolean hasColonType = type != null;
    if (n.isRest() && hasColonType) {
        type = new Node(Token.ELLIPSIS, convertWithLocation(type.removeFirstChild()));
    } else if (n.isMemberVariableDef()) {
        if (type != null) {
            type = maybeProcessOptionalProperty(n, type);
        }
    } else {
        type = maybeProcessOptionalParameter(n, type);
    }
    if (type == null) {
        return;
    }
    JSDocInfoBuilder builder = JSDocInfoBuilder.maybeCopyFrom(jsDocNode.getJSDocInfo());
    JSTypeExpression typeExpression = new JSTypeExpression(type, n.getSourceFileName());
    switch(n.getType()) {
        case FUNCTION:
            builder.recordReturnType(typeExpression);
            break;
        case MEMBER_VARIABLE_DEF:
            builder.recordType(typeExpression);
            break;
        default:
            builder.recordType(typeExpression);
            builder.recordInlineType();
    }
    jsDocNode.setJSDocInfo(builder.build());
    if (hasColonType) {
        n.setDeclaredTypeExpression(null);
        compiler.reportCodeChange();
    }
}

26. Es6TypedToEs6Converter#visitClass()

Project: closure-compiler
File: Es6TypedToEs6Converter.java
private void visitClass(Node n, Node parent) {
    maybeAddGenerics(n, n);
    JSDocInfoBuilder doc = JSDocInfoBuilder.maybeCopyFrom(n.getJSDocInfo());
    Node interfaces = (Node) n.getProp(Node.IMPLEMENTS);
    if (interfaces != null) {
        for (Node child : interfaces.children()) {
            Node type = convertWithLocation(child);
            doc.recordImplementedInterface(new JSTypeExpression(type, n.getSourceFileName()));
        }
        n.removeProp(Node.IMPLEMENTS);
    }
    Node superType = n.getSecondChild();
    Node newSuperType = maybeGetQualifiedNameNode(superType);
    if (newSuperType != superType) {
        n.replaceChild(superType, newSuperType);
    }
    Node classMembers = n.getLastChild();
    ClassDeclarationMetadata metadata = ClassDeclarationMetadata.create(n, parent);
    for (Node member : classMembers.children()) {
        if (member.isCallSignature()) {
            compiler.report(JSError.make(n, CALL_SIGNATURE_NOT_SUPPORTED));
            continue;
        }
        if (member.isIndexSignature()) {
            doc.recordImplementedInterface(createIObject(member));
            continue;
        }
        // Functions are handled by the regular Es6ToEs3Converter
        if (!member.isMemberVariableDef() && !member.getBooleanProp(Node.COMPUTED_PROP_VARIABLE)) {
            maybeAddVisibility(member);
            continue;
        }
        if (metadata == null) {
            compiler.report(JSError.make(n, CANNOT_CONVERT_MEMBER_VARIABLES));
            return;
        }
        metadata.insertNodeAndAdvance(createPropertyDefinition(member, metadata.fullClassName));
        compiler.reportCodeChange();
    }
    n.setJSDocInfo(doc.build());
    maybeCreateQualifiedDeclaration(n, parent);
}

27. Es6RewriteBlockScopedDeclaration#extractInlineJSDoc()

Project: closure-compiler
File: Es6RewriteBlockScopedDeclaration.java
private static void extractInlineJSDoc(Node srcDeclaration, Node srcName, Node destDeclaration) {
    JSDocInfo existingInfo = srcDeclaration.getJSDocInfo();
    if (existingInfo == null) {
        // Extract inline JSDoc from "src" and add it to the "dest" node.
        existingInfo = srcName.getJSDocInfo();
        srcName.setJSDocInfo(null);
    }
    JSDocInfoBuilder builder = JSDocInfoBuilder.maybeCopyFrom(existingInfo);
    destDeclaration.setJSDocInfo(builder.build());
}