Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: angular/tsickle
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.38.0
Choose a base ref
...
head repository: angular/tsickle
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.38.1
Choose a head ref
  • 10 commits
  • 218 files changed
  • 4 contributors

Commits on Jan 14, 2020

  1. Special case the @license tag in the file overview comments so that n…

    …ewly added @Suppress tags are placed above @license tags.
    
    @license tag treats all text that comes after it as part of the license, so if @Suppress is added after @license tags, it is essentially ignored by the Closure Compiler.
    EatingW authored and evmar committed Jan 14, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b095e4d View commit details

Commits on Jan 17, 2020

  1. Update tsickle to TypeScript 3.7

    These changes have already landed in Google, syncing them out for
    posterity.
    rrdelaney authored and mprobst committed Jan 17, 2020
    Copy the full SHA
    e95ba50 View commit details

Commits on Jan 21, 2020

  1. Updated Peer Dependencies since getTypeArguments is only available in…

    … typescript >3.7.x
    Shaun Tabone authored and mprobst committed Jan 21, 2020
    Copy the full SHA
    35b7fa4 View commit details

Commits on Jan 24, 2020

  1. Copy the full SHA
    2ece0cb View commit details
  2. Copy the full SHA
    153aaac View commit details

Commits on Feb 27, 2020

  1. Add a require to tslib for all generated JS files from tsickle.

    TS gets compiled to Development mode (ES5) and Closure mode (~ES6)
    sources. Tooling generates module manifests from the Closure version.
    These manifests are used both with the Closure version and the
    Development mode version. 'tslib' is sometimes required by the
    development version but not the Closure version. Inserting the import
    `goog.require('tslib')` unconditionally makes sure that the module
    manifests are identical between Closure and Development mode, avoiding
    breakages caused by missing module dependencies.
    EatingW authored and mprobst committed Feb 27, 2020
    Copy the full SHA
    fd4c593 View commit details

Commits on Feb 28, 2020

  1. Add support for TypeScript 3.8 (#1134)

    Add support for TypeScript 3.8
    
    This upgrades the version of TypeScript Tsickle uses as a
    `devDependency` and a `peerDependency`.
    
    Support for Private Fields
    --------------------------
    Tsickle mostly ignores private fields, however it no longer warns when
    not generating externs for them. Externs are not generated because the
    fields no not exist on the class when downleveled.
    
    Support for `export * as ns` Syntax
    -----------------------------------
    Tsickle compiles:
    
    ```ts
    export * as ns from './namespace';
    ```
    
    to
    
    ```ts
    var tsickle_module_1_ = goog.require('project.namespace');
    exports.ns = tsickle_module_1_;
    ```
    
    New `tslib` Functions
    ---------------------
    Private fields require two new functions in `tslib`:
    `__classPrivateFieldGet` and `__classPrivateFieldSet`. Both of these
    were added to Tsickle's version of `tslib.js` along with Closure type
    annotations.
    
    Other Changes
    -------------
    * The `import_export_typedef_conflict` test was removed because that
      code is no longer valid in TypeScript 3.8, and produces a compile
      error.
    * `tslib@1.11.0` was added as a `devDependency`. Before it was being
      pulled in as a transitive dependency, but the packages pulling it in
      depend on `1.10`. To upgrade to TypeScript 3.8 Tsickle needs the latest
      version of `tslib`.
    rrdelaney authored Feb 28, 2020
    Copy the full SHA
    f4ae5f8 View commit details

Commits on Mar 3, 2020

  1. Prepare for upgrading the Jasmine typings.

    In the latest version, the callback must accept a readonly array.
    mprobst committed Mar 3, 2020
    Copy the full SHA
    8e4edb9 View commit details

Commits on Mar 5, 2020

  1. Copy the full SHA
    141baf2 View commit details
  2. Copy the full SHA
    8fd0a31 View commit details
Showing with 541 additions and 81 deletions.
  1. +4 −3 package.json
  2. +5 −1 src/enum_transformer.ts
  3. +6 −0 src/externs.ts
  4. +9 −1 src/fileoverview_comment_transformer.ts
  5. +77 −1 src/googmodule.ts
  6. +17 −5 src/jsdoc_transformer.ts
  7. +4 −3 src/module_type_translator.ts
  8. +1 −1 src/transformer_util.ts
  9. +1 −1 src/tsickle.ts
  10. +7 −6 src/type_translator.ts
  11. +36 −1 test/googmodule_test.ts
  12. +1 −1 test/test_support.ts
  13. +1 −0 test_files/abstract/abstract.js
  14. +1 −0 test_files/anon_class/anon_class.js
  15. +1 −0 test_files/arrow_fn.es5/arrow_fn_es5.js
  16. +1 −0 test_files/arrow_fn.untyped/arrow_fn.untyped.js
  17. +1 −0 test_files/arrow_fn/arrow_fn.js
  18. +1 −1 test_files/augment/externs.js
  19. +1 −0 test_files/augment/user.js
  20. +1 −0 test_files/automatic_semicolon_insertion/asi.js
  21. +1 −0 test_files/basic.untyped/basic.untyped.js
  22. +1 −0 test_files/blacklisted_ambient_external_module/user.js
  23. +1 −0 test_files/cast_extends/cast_extends.js
  24. +1 −0 test_files/class.untyped/class.js
  25. +1 −0 test_files/class/class.js
  26. +40 −0 test_files/class/private_field.js
  27. +22 −0 test_files/class/private_field.ts
  28. +1 −0 test_files/clutz.no_externs/import_default.js
  29. +1 −0 test_files/clutz.no_externs/strip_clutz_type.js
  30. +1 −0 test_files/clutz_type_value.no_externs/user.js
  31. +1 −0 test_files/coerce/coerce.js
  32. +1 −0 test_files/comments/comments.js
  33. +1 −0 test_files/conditional_rest_tuple_type/conditional_rest_tuple_type.js
  34. +1 −0 test_files/conditional_type/conditional_type.js
  35. +1 −0 test_files/ctors/ctors.js
  36. +1 −0 test_files/debugger/user.js
  37. +1 −0 test_files/declare/declare_nondts.js
  38. +1 −0 test_files/declare/user.js
  39. +1 −0 test_files/declare_class_ns/declare_class_ns.js
  40. +1 −0 test_files/declare_class_overloads/declare_class_overloads.js
  41. +1 −0 test_files/declare_export.untyped/declare_export.js
  42. +1 −0 test_files/declare_export/declare_export.js
  43. +1 −0 test_files/declare_export_dts/user.js
  44. +1 −0 test_files/declare_import/export_default.js
  45. +1 −0 test_files/declare_import/exporter.js
  46. +1 −2 test_files/decorator/decorator.js
  47. +1 −0 test_files/decorator/default_export.js
  48. +1 −0 test_files/decorator/external.js
  49. +1 −0 test_files/decorator/external2.js
  50. +1 −0 test_files/decorator/only_types.js
  51. +2 −2 test_files/decorator_nested_scope/decorator_nested_scope.js
  52. +1 −0 test_files/default/default.js
  53. +1 −0 test_files/doc_params/doc_params.js
  54. +1 −0 test_files/docs_on_ctor_param_properties/docs_on_ctor_param_properties.js
  55. +1 −0 test_files/enum.untyped/enum.untyped.js
  56. +1 −0 test_files/enum/enum.js
  57. +1 −0 test_files/enum/enum_user.js
  58. +1 −0 test_files/enum_ref_import/enum_ref_import.js
  59. +1 −0 test_files/enum_ref_import/exporter.js
  60. +1 −0 test_files/enum_value_literal_type/enum_value_literal_type.js
  61. +1 −0 test_files/export/export.js
  62. +1 −0 test_files/export/export_helper.js
  63. +1 −0 test_files/export/export_helper_2.js
  64. +1 −0 test_files/export/export_helper_3.js
  65. +1 −0 test_files/export/export_star_imported.js
  66. +1 −0 test_files/export/type_and_value.js
  67. +1 −0 test_files/export_declare_namespace/export_declare_namespace.js
  68. +1 −0 test_files/export_declare_namespace/user.js
  69. +1 −0 test_files/export_equals.shim/export_equals.js
  70. +1 −0 test_files/export_equals.shim/user.js
  71. +1 −0 test_files/export_local_type/export_local_type.js
  72. +1 −0 test_files/export_multi/export_multi.js
  73. +13 −0 test_files/export_star_as_ns/ns.js
  74. +2 −0 test_files/export_star_as_ns/ns.ts
  75. +16 −0 test_files/export_star_as_ns/star_as_ns.js
  76. +7 −0 test_files/export_star_as_ns/star_as_ns.ts
  77. +1 −0 test_files/export_types_values.untyped/importer.js
  78. +1 −0 test_files/export_types_values.untyped/type_exporter.js
  79. +1 −0 test_files/export_types_values.untyped/value_exporter.js
  80. +1 −0 test_files/extend_and_implement/extend_and_implement.js
  81. +1 −0 test_files/fields/fields.js
  82. +1 −0 test_files/fields_no_ctor/fields_no_ctor.js
  83. +1 −0 test_files/file_comment.puretransform/before_import.js
  84. +1 −0 test_files/file_comment.puretransform/comment_before_class.js
  85. +1 −0 test_files/file_comment.puretransform/comment_before_elided_import.js
  86. +1 −0 test_files/file_comment.puretransform/comment_before_var.js
  87. +1 −0 test_files/file_comment.puretransform/comment_no_tag.js
  88. +1 −0 test_files/file_comment.puretransform/comment_with_text.js
  89. +1 −0 test_files/file_comment.puretransform/file_comment.js
  90. +1 −0 test_files/file_comment.puretransform/fileoverview_and_jsdoc.js
  91. +1 −0 test_files/file_comment.puretransform/fileoverview_comment_add_suppress.js
  92. +12 −0 test_files/file_comment.puretransform/fileoverview_comment_add_suppress_before_license.js
  93. +9 −0 test_files/file_comment.puretransform/fileoverview_comment_add_suppress_before_license.ts
  94. +1 −0 test_files/file_comment.puretransform/fileoverview_comment_merge_suppress.js
  95. +1 −0 test_files/file_comment.puretransform/jsdoc_comment.js
  96. +1 −0 test_files/file_comment.puretransform/multiple_comments.js
  97. +1 −0 test_files/file_comment.puretransform/other_fileoverview_comments.js
  98. +1 −0 test_files/file_comment.puretransform/side_effect_import.js
  99. +1 −0 test_files/file_comment/before_import.js
  100. +1 −0 test_files/file_comment/comment_before_class.js
  101. +1 −0 test_files/file_comment/comment_before_elided_import.js
  102. +1 −0 test_files/file_comment/comment_before_var.js
  103. +1 −0 test_files/file_comment/comment_no_tag.js
  104. +1 −0 test_files/file_comment/comment_with_text.js
  105. +1 −0 test_files/file_comment/export_star.js
  106. +1 −0 test_files/file_comment/file_comment.js
  107. +1 −0 test_files/file_comment/fileoverview_and_jsdoc.js
  108. +1 −0 test_files/file_comment/fileoverview_comment_add_suppress.js
  109. +17 −0 test_files/file_comment/fileoverview_comment_add_suppress_before_license.js
  110. +9 −0 test_files/file_comment/fileoverview_comment_add_suppress_before_license.ts
  111. +1 −0 test_files/file_comment/fileoverview_comment_merge_suppress.js
  112. +1 −0 test_files/file_comment/fileoverview_in_comment_text.js
  113. +1 −0 test_files/file_comment/jsdoc_comment.js
  114. +1 −0 test_files/file_comment/latecomment.js
  115. +1 −0 test_files/file_comment/latecomment_front.js
  116. +1 −0 test_files/file_comment/multiple_comments.js
  117. +1 −0 test_files/file_comment/other_fileoverview_comments.js
  118. +1 −0 test_files/file_comment/run_in_comment.js
  119. +1 −0 test_files/file_comment/side_effect_import.js
  120. +1 −0 test_files/functions.untyped/functions.js
  121. +1 −0 test_files/functions/functions.js
  122. +1 −0 test_files/functions/two_jsdoc_blocks.js
  123. +1 −0 test_files/generic_fn_type/generic_fn_type.js
  124. +1 −0 test_files/generic_local_var/generic_local_var.js
  125. +1 −0 test_files/generic_type_alias/generic_type_alias.js
  126. +1 −0 test_files/implement_reexported_interface/exporter.js
  127. +1 −0 test_files/implement_reexported_interface/interface.js
  128. +1 −0 test_files/implement_reexported_interface/user.js
  129. +1 −0 test_files/import_alias/exporter.js
  130. +1 −0 test_files/import_alias/importer.js
  131. +1 −0 test_files/import_default/exporter.js
  132. +1 −0 test_files/import_default/import_default.js
  133. +1 −0 test_files/import_empty/import_empty.js
  134. +1 −0 test_files/import_empty/imported.js
  135. +0 −10 test_files/import_export_typedef_conflict/exporter.js
  136. +0 −1 test_files/import_export_typedef_conflict/exporter.ts
  137. +0 −18 test_files/import_export_typedef_conflict/import_export_typedef_conflict.js
  138. +0 −11 test_files/import_export_typedef_conflict/import_export_typedef_conflict.ts
  139. +1 −0 test_files/import_from_goog/import_from_goog.js
  140. +1 −0 test_files/import_only_types/import_only_types.js
  141. +1 −0 test_files/import_only_types/types_and_constenum.js
  142. +1 −0 test_files/import_only_types/types_only.js
  143. +1 −0 test_files/import_prefixed/exporter.js
  144. +1 −0 test_files/import_prefixed/import_prefixed_mixed.js
  145. +1 −0 test_files/import_prefixed/import_prefixed_types.js
  146. +1 −0 test_files/index_import/has_index/index.js
  147. +1 −0 test_files/index_import/has_index/relative.js
  148. +1 −0 test_files/index_import/lib.js
  149. +1 −0 test_files/index_import/user.js
  150. +1 −0 test_files/interface/implement_import.js
  151. +1 −0 test_files/interface/interface.js
  152. +1 −0 test_files/interface/interface_extends.js
  153. +1 −0 test_files/interface/interface_type_params.js
  154. +1 −0 test_files/invalid_closure_properties/invalid_closure_properties.js
  155. +1 −0 test_files/iterator/iterator.js
  156. +1 −0 test_files/jsdoc/enum_tag.js
  157. +1 −0 test_files/jsdoc/jsdoc.js
  158. +1 −0 test_files/jsdoc_types.untyped/default.js
  159. +1 −0 test_files/jsdoc_types.untyped/jsdoc_types.js
  160. +1 −0 test_files/jsdoc_types.untyped/module1.js
  161. +1 −0 test_files/jsdoc_types.untyped/module2.js
  162. +1 −0 test_files/jsdoc_types.untyped/nevertyped.js
  163. +1 −0 test_files/jsdoc_types/default.js
  164. +1 −0 test_files/jsdoc_types/initialized_unknown.js
  165. +1 −0 test_files/jsdoc_types/jsdoc_types.js
  166. +1 −0 test_files/jsdoc_types/module1.js
  167. +1 −0 test_files/jsdoc_types/module2.js
  168. +1 −0 test_files/jsdoc_types/nevertyped.js
  169. +1 −0 test_files/jsx/jsx.js
  170. +1 −0 test_files/methods/methods.js
  171. +1 −0 test_files/module/module.js
  172. +1 −0 test_files/namespaced/ambient_namespaced.js
  173. +1 −0 test_files/namespaced/export_enum_in_namespace.js
  174. +1 −8 test_files/namespaced/export_namespace.js
  175. +1 −0 test_files/namespaced/local_namespace.js
  176. +1 −0 test_files/namespaced/reopen_ns.js
  177. +1 −0 test_files/namespaced/user.js
  178. +1 −0 test_files/nonnull_generics/nonnull_generics.js
  179. +1 −0 test_files/nullable/nullable.js
  180. +1 −0 test_files/optional/optional.js
  181. +1 −0 test_files/parameter_properties/parameter_properties.js
  182. +1 −0 test_files/partial/partial.js
  183. +1 −0 test_files/promiseconstructor/promiseconstructor.js
  184. +1 −0 test_files/promisectorlike/promisectorlike.js
  185. +1 −0 test_files/promiselike/promiselike.js
  186. +1 −0 test_files/protected/protected.js
  187. +1 −0 test_files/rest_parameters_any/rest_parameters_any.js
  188. +1 −0 test_files/rest_parameters_generic_empty/rest_parameters_generic_empty.js
  189. +1 −0 test_files/rest_parameters_tuple/rest_parameters_tuple.js
  190. +1 −0 test_files/return_this/return_this.js
  191. +1 −0 test_files/single_value_enum/single_value_enum.js
  192. +1 −0 test_files/static/static.js
  193. +1 −0 test_files/structural.untyped/structural.untyped.js
  194. +1 −0 test_files/super/super.js
  195. +1 −0 test_files/symbol/symbol.js
  196. +1 −0 test_files/this_type/this_type.js
  197. +1 −0 test_files/transitive_symbol_type_only/exporter.js
  198. +1 −0 test_files/transitive_symbol_type_only/reexporter.js
  199. +1 −0 test_files/transitive_symbol_type_only/transitive_symbol_type_only.js
  200. +1 −0 test_files/type/type.js
  201. +1 −0 test_files/type_alias_imported/elided_comment.js
  202. +1 −0 test_files/type_alias_imported/export_constant.js
  203. +1 −0 test_files/type_alias_imported/type_alias_declare.js
  204. +1 −0 test_files/type_alias_imported/type_alias_default_exporter.js
  205. +1 −0 test_files/type_alias_imported/type_alias_exporter.js
  206. +1 −0 test_files/type_alias_imported/type_alias_imported.js
  207. +1 −0 test_files/type_and_value/module.js
  208. +1 −0 test_files/type_and_value/type_and_value.js
  209. +1 −0 test_files/type_guard_fn/type_guard_fn.js
  210. +1 −0 test_files/type_propaccess.no_externs/type_propaccess.js
  211. +1 −0 test_files/typedef.untyped/typedef.js
  212. +1 −0 test_files/typedef/typedef.js
  213. +1 −0 test_files/underscore/export_underscore.js
  214. +1 −0 test_files/underscore/underscore.js
  215. +1 −0 test_files/use_closure_externs/use_closure_externs.js
  216. +1 −0 test_files/variables/variables.js
  217. +26 −0 third_party/tslib/tslib.js
  218. +9 −4 yarn.lock
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tsickle",
"version": "0.37.1",
"version": "0.38.1",
"description": "Transpile TypeScript code to JavaScript with Closure annotations.",
"main": "src/tsickle.js",
"typings": "src/tsickle.d.ts",
@@ -11,7 +11,7 @@
"src/*"
],
"peerDependencies": {
"typescript": "~3.6.4"
"typescript": "~3.8.2"
},
"devDependencies": {
"@bazel/bazel": "^0.29.0",
@@ -29,8 +29,9 @@
"prettier": "1.14.0",
"source-map": "^0.7.3",
"source-map-support": "^0.5.6",
"tslib": "1.11",
"tslint": "5.11.0",
"typescript": "3.6.4"
"typescript": "3.8.2"
},
"scripts": {
"build": "bazel build //:npm_package",
6 changes: 5 additions & 1 deletion src/enum_transformer.ts
Original file line number Diff line number Diff line change
@@ -196,7 +196,11 @@ export function enumTransformer(typeChecker: ts.TypeChecker, diagnostics: ts.Dia
for (const member of node.members) {
const memberName = member.name;
const memberType = getEnumMemberType(typeChecker, member);
if (memberType !== 'number') continue;
// Enum members cannot be named with a private identifier, although it
// is technically valid in the AST.
if (memberType !== 'number' || ts.isPrivateIdentifier(memberName)) {
continue;
}

// TypeScript enum members can have Identifier names or String names.
// We need to emit slightly different code to support these two syntaxes:
6 changes: 6 additions & 0 deletions src/externs.ts
Original file line number Diff line number Diff line change
@@ -518,6 +518,12 @@ export function generateExterns(
debugLocationStr(exportDeclaration, namespace)}\n`);
return;
}
if (ts.isNamespaceExport(exportDeclaration.exportClause)) {
// TODO(#1135): Support generating externs using this syntax.
emit(`\n// TODO(tsickle): export * as declaration in ${
debugLocationStr(exportDeclaration, namespace)}\n`);
return;
}
for (const exportSpecifier of exportDeclaration.exportClause.elements) {
// No need to do anything for properties exported under their original name.
if (!exportSpecifier.propertyName) continue;
10 changes: 9 additions & 1 deletion src/fileoverview_comment_transformer.ts
Original file line number Diff line number Diff line change
@@ -49,7 +49,15 @@ function augmentFileoverviewComments(
suppressions = new Set((suppressTag.type || '').split(',').map(s => s.trim()));
} else {
suppressTag = {tagName: 'suppress', text: 'checked by tsc'};
tags.push(suppressTag);
// Special case the @license tag because all text following this tag is
// treated by the compiler as part of the license, so we need to place the
// new @suppress tag before @license.
const licenseTagIndex = tags.findIndex(t => t.tagName === 'license');
if (licenseTagIndex !== -1) {
tags.splice(licenseTagIndex, 0, suppressTag);
} else {
tags.push(suppressTag);
}
suppressions = new Set();
}

78 changes: 77 additions & 1 deletion src/googmodule.ts
Original file line number Diff line number Diff line change
@@ -281,7 +281,7 @@ export function commonJsToGoogmoduleTransformer(
// that a bundle by definition cannot be a goog.module()). The cast through any is necessary
// to remain compatible with earlier TS versions.
// tslint:disable-next-line:no-any
if ((sf as any).kind !== ts.SyntaxKind.SourceFile) return sf;
if ((sf as any)['kind'] !== ts.SyntaxKind.SourceFile) return sf;

// JS scripts (as opposed to modules), must not be rewritten to
// goog.modules.
@@ -428,6 +428,45 @@ export function commonJsToGoogmoduleTransformer(
ts.setTextRange(ts.createStatement(createGoogCall('require', arg)), stmt), stmt);
}

/**
* Rewrites code generated by `export * as ns from 'ns'` to something like:
*
* ```
* const tsickle_module_n_ = goog.require('ns');
* exports.ns = tsickle_module_n_;
* ```
*
* Separating the `goog.require` and `exports.ns` assignment is required by Closure to
* correctly infer the type of the exported namespace.
*/
function maybeRewriteExportStarAsNs(stmt: ts.Statement): ts.Statement[]|null {
// Ensure this looks something like `exports.ns = require('ns);`.
if (!ts.isExpressionStatement(stmt)) return null;
if (!ts.isBinaryExpression(stmt.expression)) return null;
if (stmt.expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) return null;

// Ensure the left side of the expression is an access on `exports`.
if (!ts.isPropertyAccessExpression(stmt.expression.left)) return null;
if (!ts.isIdentifier(stmt.expression.left.expression)) return null;
if (stmt.expression.left.expression.escapedText !== 'exports') return null;

// Grab the call to `require`, and exit early if not calling `require`.
if (!ts.isCallExpression(stmt.expression.right)) return null;
const ident = ts.createIdentifier(nextModuleVar());
const require = maybeCreateGoogRequire(stmt, stmt.expression.right, ident);
if (!require) return null;

const exportedName = stmt.expression.left.name;
const exportStmt = ts.setOriginalNode(
ts.setTextRange(
ts.createStatement(ts.createAssignment(
ts.createPropertyAccess(ts.createIdentifier('exports'), exportedName), ident)),
stmt),
stmt);

return [require, exportStmt];
}

/**
* visitTopLevelStatement implements the main CommonJS to goog.module conversion. It visits a
* SourceFile level statement and adds a (possibly) transformed representation of it into
@@ -480,6 +519,14 @@ export function commonJsToGoogmoduleTransformer(
return;
}
// Check for:
// exports.ns = require('...');
// which is generated by the `export * as ns from` syntax.
const exportStarAsNs = maybeRewriteExportStarAsNs(exprStmt);
if (exportStarAsNs) {
stmts.push(...exportStarAsNs);
return;
}
// Check for:
// "require('foo');" (a require for its side effects)
const expr = exprStmt.expression;
if (!ts.isCallExpression(expr)) break;
@@ -573,6 +620,35 @@ export function commonJsToGoogmoduleTransformer(
ts.createAssignment(ts.createIdentifier('module'), ts.createIdentifier('module'))));
}

// Add `goog.require('tslib');` if not JS transpilation, and it hasn't already been required.
// Rationale:
// TS gets compiled to Development mode (ES5) and Closure mode (~ES6)
// sources. Tooling generates module manifests from the Closure version.
// These manifests are used both with the Closure version and the
// Development mode version. 'tslib' is sometimes required by the
// development version but not the Closure version. Inserting the import
// below unconditionally makes sure that the module manifests are
// identical between Closure and Development mode, avoiding breakages
// caused by missing module dependencies.
if (!host.isJsTranspilation) {
// Get a copy of the already resolved module names before calling
// resolveModuleName on 'tslib'. Otherwise, resolveModuleName will
// add 'tslib' to namespaceToModuleVarName and prevent checking whether
// 'tslib' has already been required.
const resolvedModuleNames = [...namespaceToModuleVarName.keys()];

const tslibModuleName =
host.pathToModuleName(sf.fileName, resolveModuleName(host, sf.fileName, 'tslib'));

// Only add the extra require if it hasn't already been required
if (resolvedModuleNames.indexOf(tslibModuleName) === -1) {
const tslibImport = ts.createExpressionStatement(
createGoogCall('require', createSingleQuoteStringLiteral(tslibModuleName)));

// Place the goog.require('tslib') statement right after the goog.module statements
headerStmts.push(tslibImport);
}
}
// Insert goog.module() etc after any leading comments in the source file. The comments have
// been converted to NotEmittedStatements by transformer_util, which this depends on.
const insertionIdx = stmts.findIndex(s => s.kind !== ts.SyntaxKind.NotEmittedStatement);
22 changes: 17 additions & 5 deletions src/jsdoc_transformer.ts
Original file line number Diff line number Diff line change
@@ -341,9 +341,18 @@ function createClosurePropertyDeclaration(
optional: boolean): ts.Statement {
const name = propertyName(prop);
if (!name) {
mtt.debugWarn(prop, `handle unnamed member:\n${escapeForComment(prop.getText())}`);
return transformerUtil.createMultiLineComment(
prop, `Skipping unnamed member:\n${escapeForComment(prop.getText())}`);
// Skip warning for private identifiers because it is expected they are skipped in the
// Closure output.
// TODO(rdel): Once Closure Compiler determines how private properties should be represented,
// adjust this output accordingly.
if (ts.isPrivateIdentifier(prop.name)) {
return transformerUtil.createMultiLineComment(
prop, `Skipping private member:\n${escapeForComment(prop.getText())}`);
} else {
mtt.debugWarn(prop, `handle unnamed member:\n${escapeForComment(prop.getText())}`);
return transformerUtil.createMultiLineComment(
prop, `Skipping unnamed member:\n${escapeForComment(prop.getText())}`);
}
}

if (name === 'prototype') {
@@ -891,10 +900,13 @@ export function jsdocTransformer(
typesToExport.push([sym.name, sym]);
}
}
const isTypeOnlyExport = false;
exportDecl = ts.updateExportDeclaration(
exportDecl, exportDecl.decorators, exportDecl.modifiers,
ts.createNamedExports(exportSpecifiers), exportDecl.moduleSpecifier);
} else {
ts.createNamedExports(exportSpecifiers), exportDecl.moduleSpecifier,
isTypeOnlyExport);
} else if (ts.isNamedExports(exportDecl.exportClause)) {
// export {a, b, c} from 'abc';
for (const exp of exportDecl.exportClause.elements) {
const exportedName = transformerUtil.getIdentifierText(exp.name);
typesToExport.push(
7 changes: 4 additions & 3 deletions src/module_type_translator.ts
Original file line number Diff line number Diff line change
@@ -368,10 +368,11 @@ export class ModuleTypeTranslator {
if ((type.flags & ts.TypeFlags.Object) !== 0 &&
(type as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference) {
const typeRef = type as ts.TypeReference;
if (!typeRef.typeArguments) {
const typeArgs = this.typeChecker.getTypeArguments(typeRef);
if (!typeArgs) {
throw new Error('rest parameter does not resolve to a reference type');
}
newTag.type = this.typeToClosure(fnDecl, typeRef.typeArguments![0]);
newTag.type = this.typeToClosure(fnDecl, typeArgs[0]);
return;
}
// If we fail to unwrap the Array<> type, emit an unknown type.
@@ -507,7 +508,7 @@ export class ModuleTypeTranslator {
// parameter. It's not clear how to resolve the two conflicting this types best, the current
// solution prefers the explicitly given `this` parameter.
// tslint:disable-next-line:no-any accessing TS internal field.
if ((retType as any).isThisType && !hasThisParam) {
if ((retType as any)['isThisType'] && !hasThisParam) {
// foo(): this
thisReturnType = retType;
addTag({tagName: 'template', text: 'THIS'});
2 changes: 1 addition & 1 deletion src/transformer_util.ts
Original file line number Diff line number Diff line change
@@ -178,7 +178,7 @@ export function isTypeNodeKind(kind: ts.SyntaxKind) {
export function createSingleQuoteStringLiteral(text: string): ts.StringLiteral {
const stringLiteral = ts.createLiteral(text);
// tslint:disable-next-line:no-any accessing TS internal API.
(stringLiteral as any).singleQuote = true;
(stringLiteral as any)['singleQuote'] = true;
return stringLiteral;
}

2 changes: 1 addition & 1 deletion src/tsickle.ts
Original file line number Diff line number Diff line change
@@ -280,7 +280,7 @@ function addClutzAliases(
// This uses an internal TS API, assuming that accessing this will be more stable compared to
// implementing our own version.
// tslint:disable-next-line: no-any
if (options.stripInternal && (ts as any).isInternalDeclaration(d, origSourceFile)) {
if (options.stripInternal && (ts as any)['isInternalDeclaration'](d, origSourceFile)) {
return false;
}

13 changes: 7 additions & 6 deletions src/type_translator.ts
Original file line number Diff line number Diff line change
@@ -540,7 +540,7 @@ export class TypeTranslator {
// In that case, take the parent symbol of the enum member, which should be the enum
// declaration.
// tslint:disable-next-line:no-any working around a TS API deficiency.
const parent: ts.Symbol|undefined = (symbol as any).parent;
const parent: ts.Symbol|undefined = (symbol as any)['parent'];
if (!parent) return '?';
symbol = parent;
}
@@ -620,8 +620,9 @@ export class TypeTranslator {
// Translate can return '?' for a number of situations, e.g. type/value conflicts.
// `?<?>` is illegal syntax in Closure Compiler, so just return `?` here.
if (typeStr === '?') return '?';
if (referenceType.typeArguments) {
const params = referenceType.typeArguments.map(t => this.translate(t));
const typeArgs = this.typeChecker.getTypeArguments(referenceType);
if (typeArgs) {
const params = typeArgs.map(t => this.translate(t));
typeStr += `<${params.join(', ')}>`;
}
return typeStr;
@@ -852,14 +853,14 @@ export class TypeTranslator {
paramTypes.push('!Array<?>');
continue;
}
const typeRef = paramType as ts.TypeReference;
if (!typeRef.typeArguments) {
const typeArgs = this.typeChecker.getTypeArguments(paramType as ts.TypeReference);
if (typeArgs.length === 0) {
// When a rest argument resolves empty, i.e. the concrete instantiation does not take any
// arguments, the type arguments are empty. Emit a function type that takes no arg in this
// position then.
continue;
}
paramType = typeRef.typeArguments[0];
paramType = typeArgs[0];
}
let typeStr = this.translate(paramType);
if (varArgs) typeStr = '...' + typeStr;
Loading