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);
}
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;
}
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);
}
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;
}
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);
}
Aggregations