Skip to content

Commit

Permalink
Include the unresolved type's name in the BanUnresolvedType checks
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=185585097
  • Loading branch information
blickly authored and brad4d committed Feb 14, 2018
1 parent 26f0edd commit 257d1a1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 16 deletions.
31 changes: 20 additions & 11 deletions src/com/google/javascript/jscomp/ConformanceRules.java
Expand Up @@ -1389,26 +1389,33 @@ protected ConformanceResult checkConformance(NodeTraversal t, Node n) {
if (n.isGetProp()) {
Node target = n.getFirstChild();
TypeI type = target.getTypeI();
if (type != null && !conforms(type) && !isTypeImmediatelyTightened(n)) {
return ConformanceResult.VIOLATION;
TypeI nonConformingPart = getNonConformingPart(type);
if (nonConformingPart != null && !isTypeImmediatelyTightened(n)) {
return new ConformanceResult(
ConformanceLevel.VIOLATION,
"Reference to type '" + nonConformingPart + "' never resolved.");
}
}
return ConformanceResult.CONFORMANCE;
}

private static boolean conforms(TypeI type) {
private static @Nullable TypeI getNonConformingPart(TypeI type) {
if (type == null) {
return null;
}
if (type.isUnionType()) {
// unwrap union types which might contain unresolved type name
// references for example {Foo|undefined}
for (TypeI part : type.getUnionMembers()) {
if (!conforms(part)) {
return false;
TypeI nonConformingPart = getNonConformingPart(part);
if (nonConformingPart != null) {
return nonConformingPart;
}
}
return true;
} else {
return !type.isUnresolved();
} else if (type.isUnresolved()) {
return type;
}
return null;
}
}

Expand All @@ -1421,9 +1428,11 @@ public StrictBanUnresolvedType(AbstractCompiler compiler, Requirement requiremen

@Override
protected ConformanceResult checkConformance(NodeTraversal t, Node n) {
TypeI type = n.getTypeI();
if (type != null && !BanUnresolvedType.conforms(type) && !isTypeImmediatelyTightened(n)) {
return ConformanceResult.VIOLATION;
TypeI nonConformingPart = BanUnresolvedType.getNonConformingPart(n.getTypeI());
if (nonConformingPart != null && !isTypeImmediatelyTightened(n)) {
return new ConformanceResult(
ConformanceLevel.VIOLATION,
"Reference to type '" + nonConformingPart + "' never resolved.");
}
return ConformanceResult.CONFORMANCE;
}
Expand Down
7 changes: 2 additions & 5 deletions test/com/google/javascript/jscomp/CheckConformanceTest.java
Expand Up @@ -1517,7 +1517,7 @@ public void testCustomBanUnresolvedType() {
testWarning(
"goog.forwardDeclare('Foo'); /** @param {Foo} a */ function f(a) {a.foo()};",
CheckConformance.CONFORMANCE_VIOLATION,
"Violation: BanUnresolvedType Message");
"Violation: BanUnresolvedType Message\nReference to type 'Foo' never resolved.");

this.mode = TypeInferenceMode.BOTH;
testNoWarning(lines(
Expand All @@ -1539,14 +1539,11 @@ public void testCustomStrictBanUnresolvedType() {

// NTI doesn't model unresolved types separately from unknown, so this check always results
// in conformance.
// TODO(b/67899666): Implement similar functionality in NTI for preventing uses of forward
// declared types by implementing support for resolving forward declarations to a new
// "unusable type" instead of to unknown.
this.mode = TypeInferenceMode.OTI_ONLY;
testWarning(
"goog.forwardDeclare('Foo'); /** @param {Foo} a */ var f = function(a) {}",
CheckConformance.CONFORMANCE_VIOLATION,
"Violation: StrictBanUnresolvedType Message");
"Violation: StrictBanUnresolvedType Message\nReference to type 'Foo' never resolved.");

testWarning(
new String[] {
Expand Down

0 comments on commit 257d1a1

Please sign in to comment.