Search in sources :

Example 6 with Module

use of com.google.javascript.jscomp.modules.Module in project closure-compiler by google.

the class TypeInference method traverseDynamicImport.

private FlowScope traverseDynamicImport(Node dynamicImport, FlowScope scope) {
    JSType templateType = registry.getNativeType(JSTypeNative.UNKNOWN_TYPE);
    // If the module specifier is a string, attempt to resolve the module
    ModuleMap moduleMap = compiler.getModuleMap();
    Node importSpecifier = dynamicImport.getFirstChild();
    CompilerInput input = compiler.getInput(NodeUtil.getInputId(dynamicImport));
    if (importSpecifier.isStringLit() && moduleMap != null && input != null) {
        ModulePath targetPath = input.getPath().resolveJsModule(importSpecifier.getString(), importSpecifier.getSourceFileName(), importSpecifier.getLineno(), importSpecifier.getCharno());
        Module targetModule = targetPath != null ? moduleMap.getModule(targetPath) : null;
        if (targetModule != null) {
            // TypedScopeCreator ensures that the MODULE_BODY type is the export namespace type
            Node scriptNode = targetModule.metadata().rootNode();
            if (scriptNode.hasOneChild() && scriptNode.getFirstChild().isModuleBody()) {
                JSType exportNamespaceType = scriptNode != null ? scriptNode.getOnlyChild().getJSType() : null;
                if (exportNamespaceType != null) {
                    templateType = exportNamespaceType;
                }
            } else {
                // Module transpilation has occurred before type inference so a MODULE_BODY node
                // no longer exists. Traverse the script to locate the module namespace variable
                // and retrieve the type from it.
                Node moduleName = NodeUtil.findPreorder(scriptNode, (node) -> node.matchesQualifiedName(targetPath.toModuleName()), Predicates.alwaysTrue());
                if (moduleName != null && moduleName.getJSType() != null) {
                    templateType = moduleName.getJSType();
                }
            }
        }
    }
    dynamicImport.setJSType(registry.createTemplatizedType(registry.getNativeObjectType(JSTypeNative.PROMISE_TYPE), templateType));
    return traverseChildren(dynamicImport, scope);
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) ModulePath(com.google.javascript.jscomp.deps.ModuleLoader.ModulePath) Node(com.google.javascript.rhino.Node) Module(com.google.javascript.jscomp.modules.Module) ModuleMap(com.google.javascript.jscomp.modules.ModuleMap)

Example 7 with Module

use of com.google.javascript.jscomp.modules.Module in project closure-compiler by google.

the class TypeInference method flowThrough.

@Override
@CheckReturnValue
FlowScope flowThrough(Node n, FlowScope input) {
    // want to infer anything about this scope.
    if (input == bottomScope) {
        return input;
    }
    // This method also does some logic for ES modules right before and after entering/exiting the
    // scope rooted at the module. The reasoning for separating out this logic is that we can just
    // ignore the actual AST nodes for IMPORT/EXPORT, in most cases, because we have already
    // created an abstraction of imports and exports.
    Node root = NodeUtil.getEnclosingScopeRoot(n);
    // Inferred types of ES module imports/exports aren't knowable until after TypeInference runs.
    // First update the type of all imports in the scope, then do flow-sensitive inference, then
    // update the implicit '*exports*' object.
    Module module = ModuleImportResolver.getModuleFromScopeRoot(compiler.getModuleMap(), compiler, root);
    TypedScope syntacticBlockScope = scopeCreator.createScope(root);
    if (module != null && module.metadata().isEs6Module()) {
        moduleImportResolver.declareEsModuleImports(module, syntacticBlockScope, compiler.getInput(NodeUtil.getInputId(n)));
    }
    // This logic is not specific to ES modules.
    FlowScope output = input.withSyntacticScope(syntacticBlockScope);
    output = inferDeclarativelyUnboundVarsWithoutTypes(output);
    output = traverse(n, output);
    updateModuleScope(module, syntacticBlockScope);
    return output;
}
Also used : Node(com.google.javascript.rhino.Node) Module(com.google.javascript.jscomp.modules.Module) FlowScope(com.google.javascript.jscomp.type.FlowScope) CheckReturnValue(com.google.errorprone.annotations.CheckReturnValue)

Example 8 with Module

use of com.google.javascript.jscomp.modules.Module in project closure-compiler by google.

the class TypedScopeCreator method containingGoogModuleIdOf.

@Nullable
static String containingGoogModuleIdOf(TypedScope scope) {
    Module module = scope.getModule();
    if (module == null) {
        TypedScope parent = scope.getParent();
        return (parent != null) ? containingGoogModuleIdOf(parent) : null;
    }
    // Stop recursing once we've hit a module scope.
    ModuleMetadata metadata = module.metadata();
    checkState(metadata.isModule(), metadata);
    /**
     * This module may not have a goog.module/goog.declareModuleId. Also don't crash if it's
     * malformed with multiple module IDs.
     */
    return Iterables.getFirst(metadata.googNamespaces(), null);
}
Also used : StaticTypedScope(com.google.javascript.rhino.jstype.StaticTypedScope) ModuleMetadata(com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata) Module(com.google.javascript.jscomp.modules.Module) Nullable(javax.annotation.Nullable)

Example 9 with Module

use of com.google.javascript.jscomp.modules.Module in project closure-compiler by google.

the class TypedScopeCreator method createScopeInternal.

private TypedScope createScopeInternal(Node root, TypedScope typedParent) {
    checkState(stage.equals(Stage.BUILDING), "Cannot create scope for %s after TypedScopeCreator is frozen", root);
    // Constructing the global scope is very different than constructing
    // inner scopes, because only global scopes can contain named classes that
    // show up in the type registry.
    TypedScope newScope = null;
    AbstractScopeBuilder scopeBuilder = null;
    Module module = ModuleImportResolver.getModuleFromScopeRoot(moduleMap, compiler, root);
    if (typedParent == null) {
        checkState(root.isRoot(), root);
        Node externsRoot = root.getFirstChild();
        Node jsRoot = root.getSecondChild();
        checkState(externsRoot.isRoot(), externsRoot);
        checkState(jsRoot.isRoot(), jsRoot);
        JSType globalThis = typeRegistry.getNativeObjectType(JSTypeNative.GLOBAL_THIS);
        // Mark the main root, the externs root, and the src root
        // with the global this type.
        root.setJSType(globalThis);
        externsRoot.setJSType(globalThis);
        jsRoot.setJSType(globalThis);
        // Find all the classes in the global scope.
        newScope = createInitialScope(root);
    } else {
        // Because JSTypeRegistry#getType looks up the scope in which a root of a qualified name is
        // declared, pre-populate this TypedScope with all qualified name roots. This prevents
        // type resolution from accidentally returning a type from an outer scope that is shadowed.
        Set<String> reservedNames = new HashSet<>();
        reservedNames.addAll(reservedNamesForScope.removeAll(root));
        if (module != null && module.metadata().isGoogModule()) {
            // TypedScopeCreator treats default export assignments, like `exports = class {};`, as
            // declarations. However, the untyped scope only contains an implicit slot for `exports`.
            reservedNames.add("exports");
        } else if (root.isFunction() && NodeUtil.isBundledGoogModuleCall(root.getParent())) {
            // Pretend that 'exports' is declared in the block of goog.loadModule
            // functions, not the function scope. See the above comment for why.
            reservedNames.remove("exports");
        }
        newScope = new TypedScope(typedParent, root, reservedNames, module);
    }
    if (root.isFunction()) {
        scopeBuilder = new FunctionScopeBuilder(newScope);
    } else if (root.isClass()) {
        scopeBuilder = new ClassScopeBuilder(newScope);
    } else {
        scopeBuilder = new NormalScopeBuilder(newScope);
    }
    scopeBuilder.build();
    if (typedParent == null) {
        List<NominalTypeBuilder> delegateProxies = new ArrayList<>();
        for (FunctionType delegateProxyCtor : delegateProxyCtors) {
            delegateProxies.add(new NominalTypeBuilder(delegateProxyCtor, delegateProxyCtor.getInstanceType()));
        }
        codingConvention.defineDelegateProxyPrototypeProperties(typeRegistry, delegateProxies, delegateCallingConventions);
    }
    if (module != null && module.metadata().isEs6Module()) {
        // Declare an implicit variable representing the namespace of this module, then add a property
        // for each exported name to that variable's type.
        ObjectType namespaceType = typeRegistry.createAnonymousObjectType(null);
        newScope.declare(Export.NAMESPACE, // Use the given MODULE_BODY as the 'declaration node' for lack of a better option.
        root, namespaceType, compiler.getInput(NodeUtil.getInputId(root)), /* inferred= */
        false);
        // Store the module object type on the MODULE_BODY.
        // The Es6RewriteModules will retrieve it from there for use when it creates a global for
        // the module object.
        root.setJSType(namespaceType);
        moduleImportResolver.updateEsModuleNamespaceType(namespaceType, module, newScope);
    }
    return newScope;
}
Also used : JSType(com.google.javascript.rhino.jstype.JSType) StaticTypedScope(com.google.javascript.rhino.jstype.StaticTypedScope) Node(com.google.javascript.rhino.Node) FunctionType(com.google.javascript.rhino.jstype.FunctionType) ArrayList(java.util.ArrayList) ObjectType(com.google.javascript.rhino.jstype.ObjectType) NominalTypeBuilder(com.google.javascript.rhino.NominalTypeBuilder) Module(com.google.javascript.jscomp.modules.Module) HashSet(java.util.HashSet)

Example 10 with Module

use of com.google.javascript.jscomp.modules.Module in project closure-compiler by google.

the class PolymerBehaviorExtractor method getNameIfModuleImport.

/**
 * Handles resolving behaviors whose root is imported from another module or a provide.
 *
 * <p>Returns null if the given name is not imported or {@link #FAILED_RESOLVE_RESULT} if it is
 * imported but is not annotated @polymerBehavior.
 */
private ResolveBehaviorNameResult getNameIfModuleImport(String name, ModuleMetadata metadata) {
    if (metadata == null || (!metadata.isEs6Module() && !metadata.isGoogModule())) {
        return null;
    }
    Module module = metadata.isGoogModule() ? moduleMap.getClosureModule(metadata.googNamespaces().asList().get(0)) : moduleMap.getModule(metadata.path());
    checkNotNull(module, metadata);
    int dot = name.indexOf('.');
    String root = dot == -1 ? name : name.substring(0, dot);
    Binding b = module.boundNames().get(root);
    if (b == null || !b.isSomeImport()) {
        return null;
    }
    String rest = dot == -1 ? "" : name.substring(dot);
    if (b.isModuleNamespace()) {
        // `import * as x from '';` or `const ns = goog.require('...`
        return resolveModuleNamespaceBinding(b, rest);
    }
    ModuleMetadata importMetadata = b.originatingExport().moduleMetadata();
    // The name in the module being imported
    String originatingName;
    if (importMetadata.isEs6Module()) {
        // import {exportName} from './mod';
        originatingName = b.originatingExport().localName() + rest;
    } else if (importMetadata.isGoogModule()) {
        // `const {exportName: localName} = goog.require('some.module');`
        originatingName = GOOG_MODULE_EXPORTS + "." + b.originatingExport().exportName() + rest;
    } else {
        // `const {exportName: localName} = goog.require('some.provide');`
        checkState(importMetadata.isGoogProvide(), importMetadata);
        originatingName = b.closureNamespace() + "." + b.originatingExport().exportName() + rest;
    }
    return resolveBehaviorName(originatingName, importMetadata);
}
Also used : Binding(com.google.javascript.jscomp.modules.Binding) ModuleMetadata(com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata) Module(com.google.javascript.jscomp.modules.Module)

Aggregations

Module (com.google.javascript.jscomp.modules.Module)16 Node (com.google.javascript.rhino.Node)11 QualifiedName (com.google.javascript.rhino.QualifiedName)5 ModuleMap (com.google.javascript.jscomp.modules.ModuleMap)4 Binding (com.google.javascript.jscomp.modules.Binding)3 JSType (com.google.javascript.rhino.jstype.JSType)3 ModulePath (com.google.javascript.jscomp.deps.ModuleLoader.ModulePath)2 ModuleMetadata (com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata)2 JSDocInfo (com.google.javascript.rhino.JSDocInfo)2 ObjectType (com.google.javascript.rhino.jstype.ObjectType)2 StaticTypedScope (com.google.javascript.rhino.jstype.StaticTypedScope)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Nullable (javax.annotation.Nullable)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 CheckReturnValue (com.google.errorprone.annotations.CheckReturnValue)1 Name (com.google.javascript.jscomp.GlobalNamespace.Name)1 Ref (com.google.javascript.jscomp.GlobalNamespace.Ref)1 ModuleMetadataMap (com.google.javascript.jscomp.modules.ModuleMetadataMap)1 FlowScope (com.google.javascript.jscomp.type.FlowScope)1