Search in sources :

Example 36 with JSDocInfoBuilder

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

the class Es6RewriteClass method visitNonMethodMember.

/**
 * Visits class members other than simple methods: Getters, setters, and computed properties.
 */
private void visitNonMethodMember(Node member, ClassDeclarationMetadata metadata) {
    if (member.isComputedProp() && member.isStaticMember()) {
        cannotConvertYet(member, "Static computed property");
        return;
    }
    if (member.isComputedProp() && !member.getFirstChild().isQualifiedName()) {
        cannotConvert(member.getFirstChild(), "Computed property with non-qualified-name key");
        return;
    }
    JSTypeExpression typeExpr = getTypeFromGetterOrSetter(member);
    addToDefinePropertiesObject(metadata, member);
    Map<String, JSDocInfo> membersToDeclare;
    String memberName;
    if (member.isComputedProp()) {
        checkState(!member.isStaticMember());
        membersToDeclare = metadata.prototypeComputedPropsToDeclare;
        memberName = member.getFirstChild().getQualifiedName();
    } else {
        membersToDeclare = member.isStaticMember() ? metadata.classMembersToDeclare : metadata.prototypeMembersToDeclare;
        memberName = member.getString();
    }
    JSDocInfo existingJSDoc = membersToDeclare.get(memberName);
    JSTypeExpression existingType = existingJSDoc == null ? null : existingJSDoc.getType();
    if (existingType != null && typeExpr != null && !existingType.equals(typeExpr)) {
        compiler.report(JSError.make(member, CONFLICTING_GETTER_SETTER_TYPE, memberName));
    } else {
        JSDocInfoBuilder jsDoc = new JSDocInfoBuilder(false);
        if (member.getJSDocInfo() != null && member.getJSDocInfo().isExport()) {
            jsDoc.recordExport();
            jsDoc.recordVisibility(Visibility.PUBLIC);
        }
        if (member.getJSDocInfo() != null && member.getJSDocInfo().isOverride()) {
            jsDoc.recordOverride();
        } else if (typeExpr == null) {
            typeExpr = new JSTypeExpression(new Node(Token.QMARK), member.getSourceFileName());
        }
        if (typeExpr != null) {
            jsDoc.recordType(typeExpr.copy());
        }
        if (member.isStaticMember() && !member.isComputedProp()) {
            jsDoc.recordNoCollapse();
        }
        membersToDeclare.put(memberName, jsDoc.build());
    }
}
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 37 with JSDocInfoBuilder

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

the class PolymerClassRewriter method rewritePolymerCall.

/**
 * 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 rewritePolymerCall(Node exprRoot, final PolymerClassDefinition cls, boolean isInGlobalScope) {
    Node objLit = checkNotNull(cls.descriptor);
    // 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(), cls.defType);
    PolymerPassStaticUtils.switchDollarSignPropsToBrackets(objLit, compiler);
    PolymerPassStaticUtils.quoteListenerAndHostAttributeKeys(objLit, compiler);
    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());
        NodeUtil.markNewScopesChanged(assign, compiler);
        assign.setJSDocInfo(constructorDoc.build());
        Node exprResult = IR.exprResult(assign);
        exprResult.useSourceInfoIfMissingFromForTree(cls.target);
        block.addChildToBack(exprResult);
    } else {
        // var foo = Polymer({...}); OR Polymer({...});
        Node var = IR.var(cls.target.cloneTree(), cls.constructor.value.cloneTree());
        NodeUtil.markNewScopesChanged(var, compiler);
        var.useSourceInfoIfMissingFromForTree(exprRoot);
        var.setJSDocInfo(constructorDoc.build());
        block.addChildToBack(var);
    }
    appendPropertiesToBlock(cls, block, cls.target.getQualifiedName() + ".prototype.");
    appendBehaviorMembersToBlock(cls, block);
    ImmutableList<MemberDefinition> readOnlyProps = parseReadOnlyProperties(cls, block);
    ImmutableList<MemberDefinition> attributeReflectedProps = parseAttributeReflectedProperties(cls);
    addInterfaceExterns(cls, readOnlyProps, attributeReflectedProps);
    removePropertyDocs(objLit, PolymerClassDefinition.DefinitionType.ObjectLiteral);
    Node statements = block.removeChildren();
    Node parent = exprRoot.getParent();
    // global.
    if (this.polymerVersion == 1 && !isInGlobalScope && !cls.target.isGetProp()) {
        Node scriptNode = NodeUtil.getEnclosingScript(parent);
        scriptNode.addChildrenToFront(statements);
        compiler.reportChangeToChangeScope(scriptNode);
    } else {
        Node beforeRoot = exprRoot.getPrevious();
        if (beforeRoot == null) {
            parent.addChildrenToFront(statements);
        } else {
            parent.addChildrenAfter(statements, beforeRoot);
        }
        compiler.reportChangeToEnclosingScope(parent);
    }
    compiler.reportChangeToEnclosingScope(statements);
    // we might need to update the FeatureSet.
    if (cls.features != null) {
        Node scriptNode = NodeUtil.getEnclosingScript(parent);
        FeatureSet oldFeatures = (FeatureSet) scriptNode.getProp(Node.FEATURE_SET);
        FeatureSet newFeatures = oldFeatures.union(cls.features);
        if (!newFeatures.equals(oldFeatures)) {
            scriptNode.putProp(Node.FEATURE_SET, newFeatures);
            compiler.reportChangeToChangeScope(scriptNode);
        }
    }
    if (NodeUtil.isNameDeclaration(exprRoot)) {
        Node assignExpr = varToAssign(exprRoot);
        parent.replaceChild(exprRoot, assignExpr);
        compiler.reportChangeToEnclosingScope(assignExpr);
    }
    // with the class members.
    if (polymerVersion > 1 && propertyRenamingEnabled && cls.descriptor != null) {
        Node props = NodeUtil.getFirstPropMatchingKey(cls.descriptor, "properties");
        if (props != null && props.isObjectLit()) {
            addObjectReflectionCall(cls, props);
        }
    }
}
Also used : Node(com.google.javascript.rhino.Node) FeatureSet(com.google.javascript.jscomp.parsing.parser.FeatureSet) JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder) MemberDefinition(com.google.javascript.jscomp.PolymerPass.MemberDefinition)

Example 38 with JSDocInfoBuilder

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

the class PolymerClassRewriter method rewritePolymerClassDeclaration.

/**
 * Rewrites a class which extends Polymer.Element to a set of declarations and assignments which
 * can be understood by the compiler.
 *
 * @param clazz The class node
 * @param cls The extracted {@link PolymerClassDefinition} for the Polymer element created by this
 *     call.
 */
void rewritePolymerClassDeclaration(Node clazz, final PolymerClassDefinition cls, boolean isInGlobalScope) {
    if (cls.descriptor != null) {
        addTypesToFunctions(cls.descriptor, cls.target.getQualifiedName(), cls.defType);
    }
    PolymerPassStaticUtils.switchDollarSignPropsToBrackets(NodeUtil.getClassMembers(clazz), compiler);
    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();
    appendPropertiesToBlock(cls, block, cls.target.getQualifiedName() + ".prototype.");
    ImmutableList<MemberDefinition> readOnlyProps = parseReadOnlyProperties(cls, block);
    ImmutableList<MemberDefinition> attributeReflectedProps = parseAttributeReflectedProperties(cls);
    addInterfaceExterns(cls, readOnlyProps, attributeReflectedProps);
    // If an external interface is required, mark the class as implementing it
    if (!readOnlyProps.isEmpty() || !attributeReflectedProps.isEmpty()) {
        JSDocInfoBuilder classInfo = JSDocInfoBuilder.maybeCopyFrom(clazz.getJSDocInfo());
        String interfaceName = getInterfaceName(cls);
        JSTypeExpression interfaceType = new JSTypeExpression(new Node(Token.BANG, IR.string(interfaceName)), VIRTUAL_FILE);
        classInfo.recordImplementedInterface(interfaceType);
        clazz.setJSDocInfo(classInfo.build());
    }
    if (block.hasChildren()) {
        removePropertyDocs(cls.descriptor, cls.defType);
        Node stmt = NodeUtil.getEnclosingStatement(clazz);
        stmt.getParent().addChildrenAfter(block.removeChildren(), stmt);
        compiler.reportChangeToEnclosingScope(stmt);
    }
    addReturnTypeIfMissing(cls, "is", new JSTypeExpression(IR.string("string"), VIRTUAL_FILE));
    Node type = new Node(Token.BANG);
    Node array = IR.string("Array");
    type.addChildToBack(array);
    Node arrayTemplateType = new Node(Token.BLOCK, IR.string("string"));
    array.addChildToBack(arrayTemplateType);
    addReturnTypeIfMissing(cls, "observers", new JSTypeExpression(type, VIRTUAL_FILE));
    addReturnTypeIfMissing(cls, "properties", new JSTypeExpression(IR.string(POLYMER_ELEMENT_PROP_CONFIG), VIRTUAL_FILE));
    // with the class members.
    if (propertyRenamingEnabled && cls.descriptor != null) {
        addObjectReflectionCall(cls, cls.descriptor);
    }
}
Also used : Node(com.google.javascript.rhino.Node) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder) MemberDefinition(com.google.javascript.jscomp.PolymerPass.MemberDefinition)

Example 39 with JSDocInfoBuilder

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

the class PolymerClassRewriter method addInterfaceExterns.

/**
 * 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, List<MemberDefinition> attributeReflectedProps) {
    Node block = IR.block();
    String interfaceName = getInterfaceName(cls);
    Node fnNode = NodeUtil.emptyFunction();
    compiler.reportChangeToChangeScope(fnNode);
    Node varNode = IR.var(NodeUtil.newQName(compiler, interfaceName), fnNode);
    JSDocInfoBuilder info = new JSDocInfoBuilder(true);
    info.recordInterface();
    varNode.setJSDocInfo(info.build());
    block.addChildToBack(varNode);
    if (polymerVersion == 1) {
        // For Polymer 1, all declared properties are non-renameable
        appendPropertiesToBlock(cls, block, interfaceName + ".prototype.");
    } else {
        List<MemberDefinition> interfaceProperties = new ArrayList<>();
        interfaceProperties.addAll(readOnlyProps);
        if (attributeReflectedProps != null) {
            interfaceProperties.addAll(attributeReflectedProps);
        }
        // For Polymer 2, only read-only properties and reflectToAttribute properties are
        // non-renameable. Other properties follow the ALL_UNQUOTED renaming rules.
        PolymerClassDefinition tmpDef = new PolymerClassDefinition(cls.defType, cls.definition, cls.target, cls.descriptor, null, null, null, interfaceProperties, null, null);
        // disallow renaming of readonly properties
        appendPropertiesToBlock(tmpDef, 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 scopeRoot = polymerElementExterns;
    if (!scopeRoot.isScript()) {
        scopeRoot = scopeRoot.getParent();
    }
    Node stmts = block.removeChildren();
    scopeRoot.addChildrenToBack(stmts);
    compiler.reportChangeToEnclosingScope(stmts);
}
Also used : Node(com.google.javascript.rhino.Node) ArrayList(java.util.ArrayList) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) JSDocInfoBuilder(com.google.javascript.rhino.JSDocInfoBuilder) MemberDefinition(com.google.javascript.jscomp.PolymerPass.MemberDefinition)

Example 40 with JSDocInfoBuilder

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

the class ProcessClosurePrimitives method createUnknownTypeJsDocInfo.

private JSDocInfo createUnknownTypeJsDocInfo() {
    JSDocInfoBuilder castToUnknownBuilder = new JSDocInfoBuilder(true);
    castToUnknownBuilder.recordType(new JSTypeExpression(JsDocInfoParser.parseTypeString("?"), "<ProcessClosurePrimitives.java>"));
    return castToUnknownBuilder.build();
}
Also used : JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) 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