Search in sources :

Example 81 with JSTypeExpression

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

the class Es6RewriteModules method addGetterExport.

private void addGetterExport(Node script, Node forSourceInfo, Node objLit, String exportedName, Node value) {
    Node getter = astFactory.createGetterDef(exportedName, value);
    getter.putBooleanProp(Node.MODULE_EXPORT, true);
    objLit.addChildToBack(getter);
    if (!astFactory.isAddingTypes()) {
        // TODO(b/143904518): Remove this code when this pass is permanently moved after type checking
        // Type checker doesn't infer getters so mark the return as unknown.
        // { /** @return {?} */ get foo() { return foo; } }
        JSDocInfo.Builder builder = JSDocInfo.builder().parseDocumentation();
        builder.recordReturnType(new JSTypeExpression(new Node(Token.QMARK).srcref(forSourceInfo), script.getSourceFileName()));
        getter.setJSDocInfo(builder.build());
    } else {
        // For a property typed as number, synthesize a type `function(): number`.
        getter.setJSType(compiler.getTypeRegistry().createFunctionType(value.getJSType()));
    }
    getter.srcrefTreeIfMissing(forSourceInfo);
    compiler.reportChangeToEnclosingScope(getter.getFirstChild().getLastChild());
    compiler.reportChangeToEnclosingScope(getter);
}
Also used : Node(com.google.javascript.rhino.Node) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) JSDocInfo(com.google.javascript.rhino.JSDocInfo)

Example 82 with JSTypeExpression

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

the class Es6RewriteModules method createExportsObject.

private Node createExportsObject(String moduleName, NodeTraversal t, Node script, AstFactory.Type moduleObjectType) {
    Node moduleObject = astFactory.createObjectLit(moduleObjectType);
    // Going to get renamed by RenameGlobalVars, so the name we choose here doesn't matter as long
    // as it doesn't collide with an existing variable. (We can't use `moduleName` since then
    // RenameGlobalVars will rename all references to `moduleName` incorrectly). We'll fix the name
    // in visitScript after the global renaming to ensure it has a name that is deterministic from
    // the path.
    // 
    // So after this method we'll have:
    // var $jscomp$tmp$exports$module$name = {};
    // module$name.exportName = localName;
    // 
    // After RenameGlobalVars:
    // var $jscomp$tmp$exports$module$nameglobalized = {};
    // module$name.exportName = localName$globalized;
    // 
    // After visitScript:
    // var module$name = {};
    // module$name.exportName = localName$globalized;
    Node moduleVar = astFactory.createSingleVarNameDeclaration("$jscomp$tmp$exports$module$name", moduleObject);
    moduleVar.getFirstChild().putBooleanProp(Node.MODULE_EXPORT, true);
    // TODO(b/144593112): Stop adding JSDoc when this pass moves to always be after typechecking.
    JSDocInfo.Builder infoBuilder = JSDocInfo.builder();
    infoBuilder.recordConstancy();
    moduleVar.setJSDocInfo(infoBuilder.build());
    moduleVar.getFirstChild().setDeclaredConstantVar(true);
    script.addChildToBack(moduleVar.srcrefTreeIfMissing(script));
    Module thisModule = moduleMap.getModule(t.getInput().getPath());
    for (Map.Entry<String, Binding> entry : thisModule.namespace().entrySet()) {
        String exportedName = entry.getKey();
        Binding binding = entry.getValue();
        Node nodeForSourceInfo = binding.sourceNode();
        boolean mutated = binding.isMutated();
        QualifiedName boundVariableQualifiedName = ModuleRenaming.getGlobalName(binding);
        checkState(boundVariableQualifiedName.isSimple(), "unexpected qualified name: %s", boundVariableQualifiedName);
        String boundVariableName = boundVariableQualifiedName.getRoot();
        Node getProp = astFactory.createGetPropWithoutColor(astFactory.createName(moduleName, moduleObjectType), exportedName);
        getProp.putBooleanProp(Node.MODULE_EXPORT, true);
        if (typedefs.contains(exportedName)) {
            // /** @typedef {foo} */
            // moduleName.foo;
            JSDocInfo.Builder builder = JSDocInfo.builder().parseDocumentation();
            JSTypeExpression typeExpr = new JSTypeExpression(astFactory.createString(exportedName).srcref(nodeForSourceInfo), script.getSourceFileName());
            builder.recordTypedef(typeExpr);
            JSDocInfo info = builder.build();
            getProp.setJSDocInfo(info);
            Node exprResult = astFactory.exprResult(getProp).srcrefTreeIfMissing(nodeForSourceInfo);
            script.addChildToBack(exprResult);
        } else if (mutated) {
            final Node globalExportName = astFactory.createName(boundVariableName, type(getProp));
            addGetterExport(script, nodeForSourceInfo, moduleObject, exportedName, globalExportName);
            NodeUtil.addFeatureToScript(t.getCurrentScript(), Feature.GETTER, compiler);
        } else {
            // Avoid the extra complexity of using getters when the property isn't mutated.
            // exports.foo = foo;
            Node assign = astFactory.createAssign(getProp, astFactory.createName(boundVariableName, type(getProp)));
            // TODO(b/144593112): Stop adding JSDoc when this pass moves to always be after typechecking
            JSDocInfo.Builder builder = JSDocInfo.builder().parseDocumentation();
            builder.recordConstancy();
            JSDocInfo info = builder.build();
            assign.setJSDocInfo(info);
            script.addChildToBack(astFactory.exprResult(assign).srcrefTreeIfMissing(nodeForSourceInfo));
        }
    }
    return moduleVar;
}
Also used : Binding(com.google.javascript.jscomp.modules.Binding) Node(com.google.javascript.rhino.Node) QualifiedName(com.google.javascript.rhino.QualifiedName) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) JSDocInfo(com.google.javascript.rhino.JSDocInfo) Module(com.google.javascript.jscomp.modules.Module) ModuleMetadataMap(com.google.javascript.jscomp.modules.ModuleMetadataMap) HashMap(java.util.HashMap) Map(java.util.Map) ModuleMap(com.google.javascript.jscomp.modules.ModuleMap)

Example 83 with JSTypeExpression

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

the class JSDocInfoPrinter method print.

public String print(JSDocInfo info) {
    boolean multiline = false;
    List<String> parts = new ArrayList<>();
    parts.add("/**");
    if (info.isExterns()) {
        parts.add("@externs");
    }
    if (info.isTypeSummary()) {
        parts.add("@typeSummary");
    }
    if (info.isExport()) {
        parts.add("@export");
    } else if (info.getVisibility() != null && info.getVisibility() != Visibility.INHERITED) {
        parts.add("@" + Ascii.toLowerCase(info.getVisibility().toString()));
    }
    if (info.getAuthors() != null) {
        multiline = true;
        for (String name : info.getAuthors()) {
            parts.add("@author " + name);
        }
    }
    if (info.isAbstract()) {
        parts.add("@abstract");
    }
    if (info.hasLendsName()) {
        parts.add(buildAnnotationWithType("lends", info.getLendsName().getRoot()));
    }
    if (info.hasConstAnnotation() && !info.isDefine()) {
        parts.add("@const");
    }
    if (info.isFinal()) {
        parts.add("@final");
    }
    String description = info.getDescription();
    if (description != null) {
        multiline = true;
        parts.add("@desc " + description);
    }
    if (info.getReferences() != null) {
        multiline = true;
        for (String desc : info.getReferences()) {
            parts.add("@see " + desc);
        }
    }
    if (info.isWizaction()) {
        parts.add("@wizaction");
    }
    if (info.isPolymerBehavior()) {
        parts.add("@polymerBehavior");
    }
    if (info.isPolymer()) {
        parts.add("@polymer");
    }
    if (info.isCustomElement()) {
        parts.add("@customElement");
    }
    if (info.isMixinClass()) {
        parts.add("@mixinClass");
    }
    if (info.isMixinFunction()) {
        parts.add("@mixinFunction");
    }
    if (info.isNoSideEffects()) {
        parts.add("@nosideeffects");
    }
    if (info.isNoCompile()) {
        parts.add("@nocompile");
    }
    if (info.isNoInline()) {
        parts.add("@noinline");
    }
    if (info.isIdGenerator()) {
        parts.add("@idGenerator {unique}");
    }
    if (info.isConsistentIdGenerator()) {
        parts.add("@idGenerator {consistent}");
    }
    if (info.isStableIdGenerator()) {
        parts.add("@idGenerator {stable}");
    }
    if (info.isXidGenerator()) {
        parts.add("@idGenerator {xid}");
    }
    if (info.isMappedIdGenerator()) {
        parts.add("@idGenerator {mapped}");
    }
    if (info.makesDicts()) {
        parts.add("@dict");
    }
    if (info.makesStructs()) {
        parts.add("@struct");
    }
    if (info.makesUnrestricted()) {
        parts.add("@unrestricted ");
    }
    if (info.isConstructor()) {
        parts.add("@constructor");
    }
    if (info.isInterface() && !info.usesImplicitMatch()) {
        parts.add("@interface");
    }
    if (info.isInterface() && info.usesImplicitMatch()) {
        parts.add("@record");
    }
    if (info.hasBaseType()) {
        multiline = true;
        Node typeNode = stripBang(info.getBaseType().getRoot());
        parts.add(buildAnnotationWithType("extends", typeNode));
    }
    for (JSTypeExpression type : info.getExtendedInterfaces()) {
        multiline = true;
        Node typeNode = stripBang(type.getRoot());
        parts.add(buildAnnotationWithType("extends", typeNode));
    }
    for (JSTypeExpression type : info.getImplementedInterfaces()) {
        multiline = true;
        Node typeNode = stripBang(type.getRoot());
        parts.add(buildAnnotationWithType("implements", typeNode));
    }
    if (info.hasThisType()) {
        multiline = true;
        Node typeNode = stripBang(info.getThisType().getRoot());
        parts.add(buildAnnotationWithType("this", typeNode));
    }
    if (info.getParameterCount() > 0) {
        multiline = true;
        for (String name : info.getParameterNames()) {
            parts.add("@param " + buildParamType(info, name));
        }
    }
    if (info.hasReturnType()) {
        multiline = true;
        parts.add(buildAnnotationWithType("return", info.getReturnType(), info.getReturnDescription()));
    }
    if (!info.getThrowsAnnotations().isEmpty() && !info.getThrowsAnnotations().get(0).isEmpty()) {
        multiline = true;
        parts.add("@throws " + info.getThrowsAnnotations().get(0));
    }
    ImmutableMap<String, JSTypeExpression> templates = info.getTemplateTypes();
    if (!templates.isEmpty()) {
        multiline = true;
        templates.forEach((name, boundExpr) -> {
            Node boundRoot = boundExpr.getRoot();
            if (boundRoot.getToken() == Token.QMARK && !boundRoot.hasChildren()) {
                // If the bound of the expression is `?` (as it is after parsing an unbounded
                // template) don't specify a bound.
                // TODO(b/140187077): This case becomes redundant when fixed. It also only covers
                // explicit `?` bounds, typedefs will remain explicit.
                parts.add("@template " + name);
            } else {
                parts.add(buildAnnotationWithType("template", boundExpr, name));
            }
        });
    }
    ImmutableMap<String, Node> typeTransformations = info.getTypeTransformations();
    if (!typeTransformations.isEmpty()) {
        multiline = true;
        for (Map.Entry<String, Node> e : typeTransformations.entrySet()) {
            String name = e.getKey();
            String tranformationDefinition = new CodePrinter.Builder(e.getValue()).build();
            parts.add("@template " + name + " := " + tranformationDefinition + " =:");
        }
    }
    if (info.isOverride()) {
        parts.add("@override");
    }
    if (info.hasType() && !info.isDefine()) {
        if (info.isInlineType()) {
            parts.add(typeNode(info.getType().getRoot()));
        } else {
            parts.add(buildAnnotationWithType("type", info.getType()));
        }
    }
    if (info.isDefine()) {
        parts.add(buildAnnotationWithType("define", info.getType()));
    }
    if (info.hasTypedefType()) {
        parts.add(buildAnnotationWithType("typedef", info.getTypedefType()));
    }
    if (info.hasEnumParameterType()) {
        parts.add(buildAnnotationWithType("enum", info.getEnumParameterType()));
    }
    if (info.isImplicitCast()) {
        parts.add("@implicitCast");
    }
    if (info.isNoCollapse()) {
        parts.add("@nocollapse");
    }
    ImmutableMap<ImmutableSet<String>, String> suppressions = info.getSuppressionsAndTheirDescription();
    if (!suppressions.isEmpty()) {
        // With ImmutableMap, the iteration order will be same as insertion order (i.e. parse order).
        for (Map.Entry<ImmutableSet<String>, String> suppression : suppressions.entrySet()) {
            String[] warnings = suppression.getKey().toArray(new String[0]);
            // Even the warnings inside a suppress annotation are printed in natural order for
            // consistency
            Arrays.sort(warnings, naturalOrder());
            String text = suppression.getValue();
            StringBuilder sb = new StringBuilder();
            sb.append("@suppress {").append(Joiner.on(',').join(warnings)).append("}");
            if (!text.isEmpty()) {
                sb.append(" ").append(text);
            }
            parts.add(sb.toString());
        }
        multiline = true;
    }
    if (info.isDeprecated()) {
        parts.add("@deprecated " + info.getDeprecationReason());
        multiline = true;
    }
    if (info.isPolymer()) {
        multiline = true;
        parts.add("@polymer");
    }
    if (info.isPolymerBehavior()) {
        multiline = true;
        parts.add("@polymerBehavior");
    }
    if (info.isMixinFunction()) {
        multiline = true;
        parts.add("@mixinFunction");
    }
    if (info.isMixinClass()) {
        multiline = true;
        parts.add("@mixinClass");
    }
    if (info.isCustomElement()) {
        multiline = true;
        parts.add("@customElement");
    }
    if (info.getClosurePrimitiveId() != null) {
        parts.add("@closurePrimitive {" + info.getClosurePrimitiveId() + "}");
    }
    if (info.isNgInject()) {
        parts.add("@ngInject");
    }
    for (String tsType : info.getTsTypes()) {
        parts.add("@tsType " + tsType);
    }
    if (printDesc && info.getBlockDescription() != null) {
        String cleaned = info.getBlockDescription().replaceAll("\n\\s*\\*\\s*", "\n");
        if (!cleaned.isEmpty()) {
            multiline = true;
            cleaned = cleaned.trim();
            if (parts.size() > 1) {
                // If there is more than one part - the opening "/**" - then add blank line between the
                // description and everything else.
                cleaned += '\n';
            }
            parts.add(1, cleaned);
        }
    }
    StringBuilder sb = new StringBuilder();
    if (multiline) {
        Joiner.on("\n").appendTo(sb, parts);
    } else {
        Joiner.on(" ").appendTo(sb, parts);
        sb.append(" */");
    }
    // Ensure all lines start with " *", and then ensure all non blank lines have a space after
    // the *.
    String s = sb.toString().replace("\n", "\n *").replaceAll("\n \\*([^ \n])", "\n * $1");
    if (multiline) {
        s += "\n */\n";
    } else {
        s += " ";
    }
    return s;
}
Also used : Node(com.google.javascript.rhino.Node) ArrayList(java.util.ArrayList) ImmutableSet(com.google.common.collect.ImmutableSet) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) ImmutableMap(com.google.common.collect.ImmutableMap) Map(java.util.Map)

Example 84 with JSTypeExpression

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

the class ProcessClosurePrimitives method checkPossibleGoogProvideInit.

private void checkPossibleGoogProvideInit(String namespace, @Nullable JSDocInfo info, Node definition) {
    if (info == null || definition.isFromExterns()) {
        return;
    }
    ModuleMetadata metadata = this.closureModules.get(namespace);
    if (metadata == null || !metadata.isGoogProvide()) {
        return;
    }
    // Validate that the namespace is not declared as a generic object type.
    JSTypeExpression expr = info.getType();
    if (expr == null) {
        return;
    }
    Node n = expr.getRoot();
    if (n.getToken() == Token.BANG) {
        n = n.getFirstChild();
    }
    if (n.isStringLit() && // templated object types are ok.
    !n.hasChildren() && n.getString().equals("Object")) {
        compiler.report(JSError.make(definition, WEAK_NAMESPACE_TYPE));
    }
}
Also used : Node(com.google.javascript.rhino.Node) ModuleMetadata(com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression)

Example 85 with JSTypeExpression

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

the class ChromePass method setJsDocWithType.

private static void setJsDocWithType(Node target, Node type) {
    JSDocInfo.Builder builder = JSDocInfo.builder();
    builder.recordType(new JSTypeExpression(type.srcrefTree(VIRTUAL_NODE), VIRTUAL_FILE));
    target.setJSDocInfo(builder.build());
}
Also used : JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) JSDocInfo(com.google.javascript.rhino.JSDocInfo)

Aggregations

JSTypeExpression (com.google.javascript.rhino.JSTypeExpression)101 Node (com.google.javascript.rhino.Node)67 JSDocInfo (com.google.javascript.rhino.JSDocInfo)58 Test (org.junit.Test)26 JSDocInfoBuilder (com.google.javascript.rhino.JSDocInfoBuilder)18 MemberDefinition (com.google.javascript.jscomp.PolymerPass.MemberDefinition)9 JSType (com.google.javascript.rhino.jstype.JSType)9 ArrayList (java.util.ArrayList)8 TypeDeclarationNode (com.google.javascript.rhino.Node.TypeDeclarationNode)7 Map (java.util.Map)6 NodeSubject.assertNode (com.google.javascript.jscomp.testing.NodeSubject.assertNode)4 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)4 ImmutableList (com.google.common.collect.ImmutableList)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 Visibility (com.google.javascript.rhino.JSDocInfo.Visibility)3 LinkedHashMap (java.util.LinkedHashMap)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 Name (com.google.javascript.jscomp.GlobalNamespace.Name)2 Ref (com.google.javascript.jscomp.GlobalNamespace.Ref)2