Search in sources :

Example 1 with QualifiedName

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

the class CheckMissingRequires method visitNode.

private void visitNode(NodeTraversal t, Node n, ModuleMetadata currentModule) {
    JSDocInfo info = n.getJSDocInfo();
    if (info != null) {
        visitJsDocInfo(t, currentModule, info);
    }
    if (n.isQualifiedName() && !n.getParent().isGetProp()) {
        QualifiedName qualifiedName = n.getQualifiedNameObject();
        String root = qualifiedName.getRoot();
        if (root.equals("this") || root.equals("super")) {
            return;
        }
        visitQualifiedName(t, n, currentModule, n.getQualifiedNameObject(), /* isStrongReference= */
        true);
    }
}
Also used : QualifiedName(com.google.javascript.rhino.QualifiedName) JSDocInfo(com.google.javascript.rhino.JSDocInfo)

Example 2 with QualifiedName

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

the class CheckMissingRequires method hasAcceptableRequire.

/**
 * Does `rdep` contain an acceptable require for `namespace` from `dep`?
 *
 * <p>Any require for a parent of `namespace` from `rdep` onto `dep`, which declares that parent,
 * is sufficient. This constraint still ensures correct dependency ordering.
 *
 * <p>We loosen the check in this way because we want to make it easy to migrate multi-provide
 * files into modules. That includes deleting obsolete provides and splitting provides into
 * different files.
 */
private static boolean hasAcceptableRequire(ModuleMetadata rdep, QualifiedName namespace, ModuleMetadata dep, boolean isStrongReference) {
    Set<String> acceptableRequires = rdep.stronglyRequiredGoogNamespaces().elementSet();
    if (!isStrongReference) {
        acceptableRequires = Sets.union(acceptableRequires, rdep.weaklyRequiredGoogNamespaces().elementSet());
    }
    acceptableRequires = Sets.intersection(acceptableRequires, dep.googNamespaces().elementSet());
    for (QualifiedName parent = namespace; parent != null; parent = parent.getOwner()) {
        if (acceptableRequires.contains(parent.join())) {
            return true;
        }
    }
    return false;
}
Also used : QualifiedName(com.google.javascript.rhino.QualifiedName)

Example 3 with QualifiedName

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

the class ModuleRenaming method getGlobalNameForJsDoc.

/**
 * Returns the globalized name of a reference to a binding in JS Doc.
 *
 * <p>For example:
 *
 * <pre>
 *   // bar
 *   export class Bar {}
 * </pre>
 *
 * <pre>
 *   // foo
 *   import * as bar from 'bar';
 *   export {bar};
 * </pre>
 *
 * <pre>
 *   import * as foo from 'foo';
 *   let /** !foo.bar.Bar *\/ b;
 * </pre>
 *
 * <p>Should call this method with the binding for {@code foo} and a list ("bar", "Bar"). In this
 * example any of these properties could also be modules. This method will replace as much as the
 * GETPROP as it can with module exported variables. Meaning in the above example this would
 * return something like "baz$$module$bar", whereas if this method were called for just "foo.bar"
 * it would return "module$bar", as it refers to a module object itself.
 */
static String getGlobalNameForJsDoc(ModuleMap moduleMap, Binding binding, List<String> propertyChain) {
    int prop = 0;
    while (binding.isModuleNamespace() && binding.metadata().isEs6Module() && prop < propertyChain.size()) {
        String propertyName = propertyChain.get(prop);
        Module m = moduleMap.getModule(binding.metadata().path());
        if (m.namespace().containsKey(propertyName)) {
            binding = m.namespace().get(propertyName);
        } else {
            // error, but we're working on type checking modules soon.
            break;
        }
        prop++;
    }
    QualifiedName globalName = getGlobalName(binding);
    while (prop < propertyChain.size()) {
        globalName = globalName.getprop(propertyChain.get(prop++));
    }
    return globalName.join();
}
Also used : QualifiedName(com.google.javascript.rhino.QualifiedName) Module(com.google.javascript.jscomp.modules.Module)

Example 4 with QualifiedName

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

the class CheckMissingRequires method visitQualifiedName.

private void visitQualifiedName(NodeTraversal t, Node n, ModuleMetadata currentFile, QualifiedName qualifiedName, boolean isStrongReference) {
    if (qualifiedName.isSimple() && templateParamNames.contains(qualifiedName.getRoot())) {
        // precede the reference within the same source file (e.g. an ES5 ctor in a different file).
        return;
    }
    if (qualifiedName.isSimple() && qualifiedName.getRoot().equals("xid")) {
        // TODO(b/160167649): Decide if we should report `xid` which initially was too common to fix.
        return;
    }
    Var var = t.getScope().getVar(qualifiedName.getRoot());
    if (var != null && var.getScope().isLocal()) {
        // by the aliasing and destructuring forms of `goog.require` and `goog.requireType`.
        return;
    }
    // Look for the longest prefix match against a provided namespace.
    for (QualifiedName subName = qualifiedName; subName != null; subName = subName.getOwner()) {
        String namespace = subName.join();
        if (namespace.equals("goog.module")) {
            // name, but it's (confusingly) unrelated to the `goog.module` primitive.
            return;
        }
        // TODO(tjgq): Also check for these references.
        if (currentFile.googNamespaces().contains(namespace)) {
            return;
        }
        ModuleMetadata requiredFile = moduleByNamespace.get(namespace);
        if (requiredFile == null) {
            continue;
        }
        final DiagnosticType toReport;
        if (currentFile.isModule()) {
            /**
             * In files that represent modules, report a require without an alias the same as a totally
             * missing require.
             */
            toReport = isStrongReference ? MISSING_REQUIRE : MISSING_REQUIRE_TYPE;
        } else if (!hasAcceptableRequire(currentFile, subName, requiredFile, isStrongReference)) {
            /**
             * In files that aren't modules, report a qualified name reference only if there's no
             * require to satisfy it.
             */
            toReport = isStrongReference ? MISSING_REQUIRE_IN_PROVIDES_FILE : MISSING_REQUIRE_TYPE_IN_PROVIDES_FILE;
        } else {
            return;
        }
        t.report(n, toReport, namespace);
        return;
    }
}
Also used : QualifiedName(com.google.javascript.rhino.QualifiedName) ModuleMetadata(com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata)

Example 5 with QualifiedName

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

the class Es6RewriteModules method visitScript.

private void visitScript(NodeTraversal t, Node script) {
    final Node moduleBody = script.getFirstChild();
    // TypedScopeCreator sets the module object type on the MODULE_BODY during type checking.
    final AstFactory.Type moduleObjectType = type(moduleBody);
    inlineModuleToGlobalScope(moduleBody);
    ClosureRewriteModule.checkAndSetStrictModeDirective(t, script);
    Module thisModule = moduleMap.getModule(t.getInput().getPath());
    QualifiedName qualifiedName = ModuleRenaming.getGlobalName(thisModule.metadata(), /* googNamespace= */
    null);
    checkState(qualifiedName.isSimple(), "Unexpected qualified name %s", qualifiedName);
    String moduleName = qualifiedName.getRoot();
    Node moduleVar = createExportsObject(moduleName, t, script, moduleObjectType);
    // Rename vars to not conflict in global scope.
    NodeTraversal.traverse(compiler, script, new RenameGlobalVars(thisModule));
    // Rename the exports object to something we can reference later.
    moduleVar.getFirstChild().setString(moduleName);
    moduleVar.makeNonIndexableRecursive();
    declareGlobalVariable(moduleVar.getFirstChild(), t);
    // 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. Note that we also want to do this
    // AFTER renaming all module scoped vars in the event that something that is goog.require'd is
    // a global, unqualified name (e.g. if "goog.provide('foo')" exists, we don't want to rewrite
    // "const foo = goog.require('foo')" to "const foo = foo". If we rewrite our module scoped names
    // first then we'll rewrite to "const foo$module$fudge = goog.require('foo')", then to
    // "const foo$module$fudge = foo".
    rewriteRequires(script);
    t.reportCodeChange();
}
Also used : Node(com.google.javascript.rhino.Node) QualifiedName(com.google.javascript.rhino.QualifiedName) Module(com.google.javascript.jscomp.modules.Module)

Aggregations

QualifiedName (com.google.javascript.rhino.QualifiedName)10 Node (com.google.javascript.rhino.Node)6 Module (com.google.javascript.jscomp.modules.Module)4 JSDocInfo (com.google.javascript.rhino.JSDocInfo)2 JSType (com.google.javascript.rhino.jstype.JSType)2 ObjectType (com.google.javascript.rhino.jstype.ObjectType)2 ImmutableList (com.google.common.collect.ImmutableList)1 Binding (com.google.javascript.jscomp.modules.Binding)1 ModuleMap (com.google.javascript.jscomp.modules.ModuleMap)1 ModuleMetadataMap (com.google.javascript.jscomp.modules.ModuleMetadataMap)1 ModuleMetadata (com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata)1 JSTypeExpression (com.google.javascript.rhino.JSTypeExpression)1 StaticScope (com.google.javascript.rhino.StaticScope)1 StaticSlot (com.google.javascript.rhino.StaticSlot)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1