use of com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata 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);
}
use of com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata 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;
}
}
use of com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata in project closure-compiler by google.
the class ModuleImportResolver method getScopedNameFromEsBinding.
/**
* Given a Binding from an ES module, return the name and scope of the bound name.
*/
private static ScopedName getScopedNameFromEsBinding(Binding binding) {
// NB: If the original export was an `export default` then the local name is *default*.
// We've already declared a dummy variable named `*default*` in the scope.
String name = binding.isModuleNamespace() ? Export.NAMESPACE : binding.boundName();
ModuleMetadata originalMetadata = binding.isModuleNamespace() ? binding.metadata() : binding.originatingExport().moduleMetadata();
if (!originalMetadata.isEs6Module()) {
// Importing SCRIPTs should not allow you to look up names in scope.
return ScopedName.of(name, null);
}
Node scriptNode = originalMetadata.rootNode();
// Imports of nonexistent modules have a null 'root node'. Imports of names from scripts are
// meaningless.
checkState(scriptNode == null || scriptNode.isScript(), scriptNode);
return ScopedName.of(name, scriptNode != null ? scriptNode.getOnlyChild() : null);
}
use of com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata 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));
}
}
use of com.google.javascript.jscomp.modules.ModuleMetadataMap.ModuleMetadata in project closure-compiler by google.
the class ProcessClosurePrimitives method visit.
@Override
public void visit(NodeTraversal t, Node n, Node parent) {
switch(n.getToken()) {
case CALL:
{
this.checkGoogFunctions(t, n);
this.maybeProcessClassBaseCall(n);
this.checkPropertyRenameCall(n);
}
break;
case FUNCTION:
case CLASS:
if (!t.inGlobalHoistScope() || n.isFromExterns()) {
return;
}
if (!NodeUtil.isFunctionDeclaration(n) && !NodeUtil.isClassDeclaration(n)) {
return;
}
String name = n.getFirstChild().getString();
ModuleMetadata pn = this.closureModules.get(name);
if (pn != null && pn.isGoogProvide()) {
compiler.report(JSError.make(n, n.isClass() ? CLASS_NAMESPACE_ERROR : FUNCTION_NAMESPACE_ERROR, name, pn.toString()));
}
break;
case EXPR_RESULT:
if (!n.getFirstChild().isAssign() || !n.getFirstFirstChild().isQualifiedName()) {
break;
}
String lhs = n.getFirstFirstChild().getQualifiedName();
checkPossibleGoogProvideInit(lhs, n.getFirstChild().getJSDocInfo(), n);
break;
case VAR:
case CONST:
case LET:
if (!n.getFirstChild().isName()) {
break;
}
checkPossibleGoogProvideInit(n.getFirstChild().getString(), n.getJSDocInfo(), n);
break;
default:
break;
}
}
Aggregations