From 80620f04b7094fb71a825b831174eeba99a88359 Mon Sep 17 00:00:00 2001 From: tbreisacher Date: Thu, 11 May 2017 00:38:21 -0700 Subject: [PATCH] Check that @export annotations on getters/setters are preserved in transpilation. Part of https://github.com/google/closure-compiler/issues/2474 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=155720252 --- .../javascript/jscomp/Es6RewriteClass.java | 14 +++-- .../jscomp/Es6RewriteClassTest.java | 62 +++++++++++++++++++ 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/com/google/javascript/jscomp/Es6RewriteClass.java b/src/com/google/javascript/jscomp/Es6RewriteClass.java index cef97e9b511..f5223fa6e5c 100644 --- a/src/com/google/javascript/jscomp/Es6RewriteClass.java +++ b/src/com/google/javascript/jscomp/Es6RewriteClass.java @@ -23,6 +23,7 @@ import com.google.javascript.jscomp.CompilerOptions.LanguageMode; import com.google.javascript.rhino.IR; import com.google.javascript.rhino.JSDocInfo; +import com.google.javascript.rhino.JSDocInfo.Visibility; import com.google.javascript.rhino.JSDocInfoBuilder; import com.google.javascript.rhino.JSTypeExpression; import com.google.javascript.rhino.Node; @@ -143,7 +144,7 @@ private void visitClass(final NodeTraversal t, final Node classNode, final Node && (member.getBooleanProp(Node.COMPUTED_PROP_GETTER) || member.getBooleanProp(Node.COMPUTED_PROP_SETTER))) || (member.isGetterDef() || member.isSetterDef())) { - visitComputedPropInClass(member, metadata); + visitNonMethodMember(member, metadata); } else if (member.isMemberFunctionDef() && member.getString().equals("constructor")) { ctorJSDocInfo = member.getJSDocInfo(); constructor = member.getFirstChild().detach(); @@ -160,7 +161,7 @@ private void visitClass(final NodeTraversal t, final Node classNode, final Node "Unexpected class member:", member); Preconditions.checkState(!member.getBooleanProp(Node.COMPUTED_PROP_VARIABLE), "Member variables should have been transpiled earlier:", member); - visitClassMember(member, metadata); + visitMethod(member, metadata); } } @@ -366,7 +367,10 @@ private void addToDefinePropertiesObject(ClassDeclarationMetadata metadata, Node prop.useSourceInfoIfMissingFromForTree(member); } - private void visitComputedPropInClass(Node member, ClassDeclarationMetadata metadata) { + /** + * Visits class members other than simple methods: Getters, setters, and computed properties. + */ + private void visitNonMethodMember(Node member, ClassDeclarationMetadata metadata) { if (member.isComputedProp() && member.isStaticMember()) { cannotConvertYet(member, "Static computed property"); return; @@ -400,6 +404,7 @@ private void visitComputedPropInClass(Node member, ClassDeclarationMetadata meta jsDoc.recordType(typeExpr); if (member.getJSDocInfo() != null && member.getJSDocInfo().isExport()) { jsDoc.recordExport(); + jsDoc.recordVisibility(Visibility.PUBLIC); } if (member.isStaticMember() && !member.isComputedProp()) { jsDoc.recordNoCollapse(); @@ -412,8 +417,7 @@ private void visitComputedPropInClass(Node member, ClassDeclarationMetadata meta * Handles transpilation of a standard class member function. Getters, setters, and the * constructor are not handled here. */ - private void visitClassMember( - Node member, ClassDeclarationMetadata metadata) { + private void visitMethod(Node member, ClassDeclarationMetadata metadata) { Node qualifiedMemberAccess = getQualifiedMemberAccess( member, NodeUtil.newQName(compiler, metadata.fullClassName), diff --git a/test/com/google/javascript/jscomp/Es6RewriteClassTest.java b/test/com/google/javascript/jscomp/Es6RewriteClassTest.java index 0fca5e38200..f65ed0fc96a 100644 --- a/test/com/google/javascript/jscomp/Es6RewriteClassTest.java +++ b/test/com/google/javascript/jscomp/Es6RewriteClassTest.java @@ -1577,6 +1577,68 @@ public void testEs5GettersAndSettersClassesWithTypes() { CONFLICTING_GETTER_SETTER_TYPE); } + public void testEs5GetterWithExport() { + setLanguageOut(LanguageMode.ECMASCRIPT5); + test( + "class C { /** @export @return {string} */ get foo() {} }", + LINE_JOINER.join( + "/**", + " * @constructor @struct", + " */", + "let C = function() {}", + "", + "/**", + " * @export", + " * @type {string}", + " */", + "C.prototype.foo;", + "", + "$jscomp.global.Object.defineProperties(C.prototype, {", + " foo: {", + " configurable: true,", + " enumerable: true,", + "", + " /**", + " * @return {string}", + " * @this {C}", + " * @export", + " */", + " get: function() {},", + " }", + "});")); + } + + public void testEs5SetterWithExport() { + setLanguageOut(LanguageMode.ECMASCRIPT5); + test( + "class C { /** @export @param {string} x */ set foo(x) {} }", + LINE_JOINER.join( + "/**", + " * @constructor @struct", + " */", + "let C = function() {}", + "", + "/**", + " * @export", + " * @type {string}", + " */", + "C.prototype.foo;", + "", + "$jscomp.global.Object.defineProperties(C.prototype, {", + " foo: {", + " configurable: true,", + " enumerable: true,", + "", + " /**", + " * @param {string} x", + " * @this {C}", + " * @export", + " */", + " set: function(x) {},", + " }", + "});")); + } + /** * @bug 20536614 */