Skip to content

Commit

Permalink
Allow preserving both @OverRide and type annotation during ES6 class …
Browse files Browse the repository at this point in the history
…rewriting.

For example, a getter that is annotated as
  /** @OverRide @return {number} */
will be rewritten to a property that contains:
  /** @OverRide @type {number} */

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=175721759
  • Loading branch information
blickly authored and Tyler Breisacher committed Nov 14, 2017
1 parent dae4f97 commit 436a340
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 26 deletions.
14 changes: 9 additions & 5 deletions src/com/google/javascript/jscomp/Es6RewriteClass.java
Expand Up @@ -322,6 +322,7 @@ private void updateClassJsDoc(@Nullable JSDocInfo ctorInfo, JSDocInfoBuilder new
/** /**
* @param node A getter or setter node. * @param node A getter or setter node.
*/ */
@Nullable
private JSTypeExpression getTypeFromGetterOrSetter(Node node) { private JSTypeExpression getTypeFromGetterOrSetter(Node node) {
JSDocInfo info = node.getJSDocInfo(); JSDocInfo info = node.getJSDocInfo();
if (info != null) { if (info != null) {
Expand All @@ -340,7 +341,7 @@ private JSTypeExpression getTypeFromGetterOrSetter(Node node) {
} }
} }


return new JSTypeExpression(new Node(Token.QMARK), node.getSourceFileName()); return null;
} }


/** /**
Expand Down Expand Up @@ -397,7 +398,7 @@ private void visitNonMethodMember(Node member, ClassDeclarationMetadata metadata
return; return;
} }


JSTypeExpression typeExpr = getTypeFromGetterOrSetter(member).copy(); JSTypeExpression typeExpr = getTypeFromGetterOrSetter(member);
addToDefinePropertiesObject(metadata, member); addToDefinePropertiesObject(metadata, member);


Map<String, JSDocInfo> membersToDeclare; Map<String, JSDocInfo> membersToDeclare;
Expand All @@ -415,7 +416,7 @@ private void visitNonMethodMember(Node member, ClassDeclarationMetadata metadata
} }
JSDocInfo existingJSDoc = membersToDeclare.get(memberName); JSDocInfo existingJSDoc = membersToDeclare.get(memberName);
JSTypeExpression existingType = existingJSDoc == null ? null : existingJSDoc.getType(); JSTypeExpression existingType = existingJSDoc == null ? null : existingJSDoc.getType();
if (existingType != null && !existingType.equals(typeExpr)) { if (existingType != null && typeExpr != null && !existingType.equals(typeExpr)) {
compiler.report(JSError.make(member, CONFLICTING_GETTER_SETTER_TYPE, memberName)); compiler.report(JSError.make(member, CONFLICTING_GETTER_SETTER_TYPE, memberName));
} else { } else {
JSDocInfoBuilder jsDoc = new JSDocInfoBuilder(false); JSDocInfoBuilder jsDoc = new JSDocInfoBuilder(false);
Expand All @@ -425,8 +426,11 @@ private void visitNonMethodMember(Node member, ClassDeclarationMetadata metadata
} }
if (member.getJSDocInfo() != null && member.getJSDocInfo().isOverride()) { if (member.getJSDocInfo() != null && member.getJSDocInfo().isOverride()) {
jsDoc.recordOverride(); jsDoc.recordOverride();
} else { } else if (typeExpr == null) {
jsDoc.recordType(typeExpr); typeExpr = new JSTypeExpression(new Node(Token.QMARK), member.getSourceFileName());
}
if (typeExpr != null) {
jsDoc.recordType(typeExpr.copy());
} }
if (member.isStaticMember() && !member.isComputedProp()) { if (member.isStaticMember() && !member.isComputedProp()) {
jsDoc.recordNoCollapse(); jsDoc.recordNoCollapse();
Expand Down
40 changes: 19 additions & 21 deletions test/com/google/javascript/jscomp/Es6RewriteClassTest.java
Expand Up @@ -1102,49 +1102,47 @@ public void testSuperMethodInGetter() {
"});")); "});"));
} }


public void testOverrideOfGetter() { public void testOverrideOfGetterFromInterface() {
setLanguageOut(LanguageMode.ECMASCRIPT5); setLanguageOut(LanguageMode.ECMASCRIPT5);


test( test(
lines( lines(
"/** @abstract */", "/** @interface */",
"class Base {", "class Int {",
" /** @return {number} */", " /** @return {number} */",
" get x() {}", " get x() {}",
"}", "}",
"", "",
"class Subclass extends Base {", "/** @implements {Int} */",
" /** @override */", "class C {",
" get x() {", " /** @override @return {number} */",
" return 5;", " get x() {}",
" }",
"}"), "}"),
lines( lines(
"/** @abstract @constructor @struct */", "/** @interface @struct */",
"let Base = function() {};", "let Int = function() {};",
"/** @type {number} */", "/** @type {number} */",
"Base.prototype.x;", "Int.prototype.x;",
"$jscomp.global.Object.defineProperties(Base.prototype, {", "$jscomp.global.Object.defineProperties(Int.prototype, {",
" x: {", " x: {",
" configurable:true,", " configurable:true,",
" enumerable:true,", " enumerable:true,",
" /** @this {Base} @return {number} */", " /** @this {Int} @return {number} */",
" get: function() {},", " get: function() {},",
" }", " }",
"});", "});",
"", "",
"/** @constructor @struct @extends {Base} @param {...?} var_args */", "/** @constructor @struct @implements {Int} */",
"let Subclass = function(var_args) { Base.apply(this, arguments); };", "let C = function() {};",
"", "",
"/** @override */", "/** @override @type {number} */",
"Subclass.prototype.x;", "C.prototype.x;",
"$jscomp.inherits(Subclass, Base);", "$jscomp.global.Object.defineProperties(C.prototype, {",
"$jscomp.global.Object.defineProperties(Subclass.prototype, {",
" x: {", " x: {",
" configurable:true,", " configurable:true,",
" enumerable:true,", " enumerable:true,",
" /** @this {Subclass} @override */", " /** @this {C} @override @return {number} */",
" get: function() { return 5; },", " get: function() {},",
" }", " }",
"});")); "});"));
} }
Expand Down

0 comments on commit 436a340

Please sign in to comment.