Skip to content

Commit

Permalink
Report an error if goog.inherits is used with an ES6 class as the sub…
Browse files Browse the repository at this point in the history
…class. We already check against it being a super class.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=249103316
  • Loading branch information
johnplaisted authored and lauraharker committed May 21, 2019
1 parent f1b5f76 commit 831b1aa
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
33 changes: 22 additions & 11 deletions src/com/google/javascript/jscomp/TypeCheck.java
Expand Up @@ -192,6 +192,12 @@ public final class TypeCheck implements NodeTraversal.Callback, CompilerPass {
DiagnosticType.warning(
"JSC_ES5_CLASS_EXTENDING_ES6_CLASS", "ES5 class {0} cannot extend ES6 class {1}");

static final DiagnosticType ES6_CLASS_EXTENDING_CLASS_WITH_GOOG_INHERITS =
DiagnosticType.warning(
"JSC_ES6_CLASS_EXTENDING_CLASS_WITH_GOOG_INHERITS",
"Do not use goog.inherits with ES6 classes. Use the ES6 `extends` keyword to inherit"
+ " instead.");

static final DiagnosticType INTERFACE_EXTENDS_LOOP =
DiagnosticType.warning("JSC_INTERFACE_EXTENDS_LOOP", "extends loop involving {0}, loop: {1}");

Expand Down Expand Up @@ -2514,18 +2520,23 @@ private void checkCallConventions(NodeTraversal t, Node n) {
compiler.getCodingConvention().getClassesDefinedByCall(n);
TypedScope scope = t.getTypedScope();
if (relationship != null) {
ObjectType superClass =
TypeValidator.getInstanceOfCtor(
scope.lookupQualifiedName(QualifiedName.of(relationship.superclassName)));
ObjectType subClass =
TypeValidator.getInstanceOfCtor(
scope.lookupQualifiedName(QualifiedName.of(relationship.subclassName)));
JSType superClass = scope.lookupQualifiedName(QualifiedName.of(relationship.superclassName));
ObjectType superClassInstanceType = TypeValidator.getInstanceOfCtor(superClass);
JSType subClass = scope.lookupQualifiedName(QualifiedName.of(relationship.subclassName));
ObjectType subClassInstance = TypeValidator.getInstanceOfCtor(subClass);
if (relationship.type == SubclassType.INHERITS
&& superClass != null
&& !superClass.isEmptyType()
&& subClass != null
&& !subClass.isEmptyType()) {
validator.expectSuperType(n, superClass, subClass);
&& superClassInstanceType != null
&& !superClassInstanceType.isEmptyType()
&& subClassInstance != null
&& !subClassInstance.isEmptyType()) {
if (n.getFirstChild().isQualifiedName()
&& n.getFirstChild().matchesQualifiedName("goog.inherits")
&& subClass.toMaybeFunctionType() != null
&& subClass.toMaybeFunctionType().getSource() != null
&& subClass.toMaybeFunctionType().getSource().isEs6Class()) {
compiler.report(JSError.make(n, ES6_CLASS_EXTENDING_CLASS_WITH_GOOG_INHERITS));
}
validator.expectSuperType(n, superClassInstanceType, subClassInstance);
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions test/com/google/javascript/jscomp/TypeCheckTest.java
Expand Up @@ -23734,6 +23734,19 @@ public void testDeclarationAnnotatedEnum_warnsIfAssignedNonEnumRhs() {
"required: enum{X}"));
}

@Test
public void testEs6ExtendCannotUseGoogInherits() {
testClosureTypes(
CLOSURE_DEFS
+ lines(
"class Super {}", //
"/** @extends {Super} */",
"class Sub {}",
"goog.inherits(Sub, Super);"),
"Do not use goog.inherits with ES6 classes. Use the ES6 `extends` keyword to inherit"
+ " instead.");
}

private void testClosureTypes(String js, String description) {
testClosureTypesMultipleWarnings(js,
description == null ? null : ImmutableList.of(description));
Expand Down

0 comments on commit 831b1aa

Please sign in to comment.