use of com.google.javascript.jscomp.GlobalNamespace.Name in project closure-compiler by google.
the class PolymerBehaviorExtractor method resolveBehaviorNameInternal.
/**
* Implements behavior resolution. Call {@link #resolveBehaviorName(String, ModuleMetadata)}}
* instead.
*/
private ResolveBehaviorNameResult resolveBehaviorNameInternal(String name, ModuleMetadata moduleMetadata) {
// Check if this name is a module import/require.
ResolveBehaviorNameResult result = getNameIfModuleImport(name, moduleMetadata);
if (result != null) {
return result;
}
// Check if this name is possibly from a legacy goog.module
ResolveBehaviorNameResult legacyResolve = resolveReferenceToLegacyGoogModule(name);
if (legacyResolve != null) {
return legacyResolve;
}
// If not, look it up within the current module.
Name moduleLevelName = moduleMetadata != null ? globalNames.getNameFromModule(moduleMetadata, name) : null;
Name globalName = moduleLevelName == null ? globalNames.getSlot(name) : moduleLevelName;
if (globalName == null) {
return FAILED_RESOLVE_RESULT;
}
// Whether the declaration of this node is in the top-level global scope, as opposed to a module
// or an IIFE.
boolean isGlobalDeclaration = moduleLevelName == null;
// Use any set as a backup declaration, even if it's local.
Ref declarationRef = globalName.getDeclaration();
if (declarationRef == null) {
for (Ref ref : globalName.getRefs()) {
if (ref.isSet()) {
isGlobalDeclaration = false;
declarationRef = ref;
break;
}
}
}
if (declarationRef == null) {
return FAILED_RESOLVE_RESULT;
}
Node declarationNode = declarationRef.getNode();
if (declarationNode == null) {
return FAILED_RESOLVE_RESULT;
}
Node rValue = NodeUtil.getRValueOfLValue(declarationNode);
if (rValue == null) {
return FAILED_RESOLVE_RESULT;
}
if (rValue.isQualifiedName()) {
// Another identifier; recurse.
Scope declarationScope = declarationRef.scope.getClosestHoistScope();
Module m = ModuleImportResolver.getModuleFromScopeRoot(compiler.getModuleMap(), compiler, declarationScope.getRootNode());
return resolveBehaviorName(getQualifiedNameThroughCast(rValue), m != null ? m.metadata() : null);
}
JSDocInfo behaviorInfo = NodeUtil.getBestJSDocInfo(declarationNode);
if (behaviorInfo == null || !behaviorInfo.isPolymerBehavior()) {
compiler.report(JSError.make(declarationNode, PolymerPassErrors.POLYMER_UNANNOTATED_BEHAVIOR));
}
return new ResolveBehaviorNameResult(rValue, isGlobalDeclaration, moduleMetadata);
}
use of com.google.javascript.jscomp.GlobalNamespace.Name in project closure-compiler by google.
the class GlobalNamespaceTest method testlogicalAssignmentGets1.
@Test
public void testlogicalAssignmentGets1() {
GlobalNamespace namespace = parse(lines(//
"const ns = {};", "ns.n1 = 1;", "ns.n2 = 2;", "ns.n1 ??= ns.n2;", "ns.n1 &&= ns.n2;"));
Name bar = namespace.getSlot("ns");
assertThat(bar.getGlobalSets()).isEqualTo(1);
assertThat(bar.getAliasingGets()).isEqualTo(0);
assertThat(bar.getTotalGets()).isEqualTo(0);
Name n1 = namespace.getSlot("ns.n1");
assertThat(n1.getGlobalSets()).isEqualTo(3);
assertThat(n1.getAliasingGets()).isEqualTo(0);
assertThat(n1.getTotalGets()).isEqualTo(0);
Name n2 = namespace.getSlot("ns.n2");
assertThat(n2.getGlobalSets()).isEqualTo(1);
assertThat(n2.getAliasingGets()).isEqualTo(2);
assertThat(n2.getTotalGets()).isEqualTo(2);
}
use of com.google.javascript.jscomp.GlobalNamespace.Name in project closure-compiler by google.
the class GlobalNamespaceTest method updateRefNodeRemovesTwinRelationship.
@Test
public void updateRefNodeRemovesTwinRelationship() {
GlobalNamespace namespace = parse(lines(//
"let A;", // A will have twin refs here
"const B = A = 3;"));
Name nameA = namespace.getOwnSlot("A");
// first ref is declaration of A
// second is the SET twin
Ref setTwinRef = Iterables.get(nameA.getRefs(), 1);
// third is the GET twin
Ref getTwinRef = Iterables.get(nameA.getRefs(), 2);
Node oldNode = getTwinRef.getNode();
// move the getTwinRef
Node newNode = IR.name("A");
nameA.updateRefNode(getTwinRef, newNode);
// see confirmTwinsAreCreated() for verification of the original twin relationship
// confirm that getTwinRef has been updated
assertThat(getTwinRef.getNode()).isEqualTo(newNode);
assertThat(nameA.getRefsForNode(newNode)).containsExactly(getTwinRef);
// confirm that the getTwinRef and setTwinRef are no longer twins
assertThat(getTwinRef.getTwin()).isNull();
assertThat(setTwinRef.getTwin()).isNull();
// confirm that setTwinRef remains otherwise unchanged
assertThat(setTwinRef.getNode()).isEqualTo(oldNode);
assertThat(nameA.getRefsForNode(oldNode)).containsExactly(setTwinRef);
}
use of com.google.javascript.jscomp.GlobalNamespace.Name in project closure-compiler by google.
the class GlobalNamespaceTest method withoutAssignmentFirstQnameDeclarationStatementJSDocWins.
@Test
public void withoutAssignmentFirstQnameDeclarationStatementJSDocWins() {
GlobalNamespace namespace = parse(lines(//
"const X = {};", "/** @type {string} */", "X.number;", "/** @type {Object} */", "X.number;", ""));
Name nameX = namespace.getOwnSlot("X.number");
Ref declarationRef = nameX.getDeclaration();
assertThat(declarationRef).isNull();
// Make sure JSDoc on the first assignment is the JSDoc for the name
JSDocInfo jsDocInfo = nameX.getJSDocInfo();
assertThat(jsDocInfo).isNotNull();
JSTypeExpression jsTypeExpression = jsDocInfo.getType();
assertThat(jsTypeExpression).isNotNull();
JSType jsType = jsTypeExpression.evaluate(/* scope= */
null, lastCompiler.getTypeRegistry());
assertType(jsType).isString();
}
use of com.google.javascript.jscomp.GlobalNamespace.Name in project closure-compiler by google.
the class GlobalNamespaceTest method firstGlobalAssignmentIsConsideredDeclaration.
@Test
public void firstGlobalAssignmentIsConsideredDeclaration() {
GlobalNamespace namespace = parse("");
Name n = namespace.createNameForTesting("a");
Ref set1 = n.addSingleRefForTesting(Ref.Type.SET_FROM_GLOBAL);
Ref set2 = n.addSingleRefForTesting(Ref.Type.SET_FROM_GLOBAL);
assertThat(n.getRefs()).containsExactly(set1, set2).inOrder();
assertThat(n.getDeclaration()).isEqualTo(set1);
assertThat(n.getGlobalSets()).isEqualTo(2);
n.removeRef(set1);
// declaration moves to next global assignment when first is removed
assertThat(n.getDeclaration()).isEqualTo(set2);
assertThat(n.getGlobalSets()).isEqualTo(1);
assertThat(n.getRefs()).containsExactly(set2);
}
Aggregations