From 8924e38fb3c7474be4a5ec2e77fe87f444bc4780 Mon Sep 17 00:00:00 2001 From: Laura Harker Date: Tue, 30 Apr 2024 12:02:11 -0700 Subject: [PATCH] Add test cases for @ngInject escaping in tsickle PiperOrigin-RevId: 629486852 --- demo/package.json | 2 +- package.json | 4 +- src/clutz.ts | 59 +- src/decorators.ts | 6 +- src/enum_transformer.ts | 9 +- src/externs.ts | 13 +- src/fileoverview_comment_transformer.ts | 82 +-- src/googmodule.ts | 137 ++-- src/jsdoc.ts | 87 ++- src/jsdoc_transformer.ts | 66 +- src/ns_transformer.ts | 57 +- src/summary.ts | 10 + src/transformer_util.ts | 29 +- src/ts_migration_exports_shim.ts | 3 + src/tsickle.ts | 36 +- src/tsickle_declaration_marker.ts | 38 -- src/type_translator.ts | 22 + test/googmodule_test.ts | 26 +- test/test_support.ts | 21 +- test/tsickle_test.ts | 169 ++++- test_files/abstract/abstract.js | 2 - test_files/async_functions/async_functions.js | 2 - test_files/augment/externs.js | 2 - test_files/augment/user.js | 2 - test_files/basic.untyped/basic.untyped.js | 2 - test_files/cast_extends/cast_extends.js | 2 - test_files/class.untyped/class.js | 2 - test_files/class/class.js | 2 - test_files/clutz.no_externs/import_default.js | 2 - .../clutz2_output_demo8.d.ts | 18 - .../clutz_output_demo1.d.ts | 16 - .../clutz_output_demo2.d.ts | 16 - .../clutz_output_demo3.d.ts | 16 - .../clutz_output_demo4.d.ts | 13 - .../clutz_output_demo5.d.ts | 17 - .../clutz_output_demo6.d.ts | 18 - .../clutz_output_demo7.d.ts | 11 - .../user_code.d.ts | 53 -- .../user_code.ts | 69 -- .../clutz_type_value.no_externs/user.js | 2 - test_files/comments/comments.js | 2 - test_files/comments/freestanding_jsdoc.js | 25 + test_files/comments/freestanding_jsdoc.ts | 15 + test_files/comments/trailing_no_semicolon.js | 20 + test_files/comments/trailing_no_semicolon.ts | 17 + .../conditional_rest_tuple_type.js | 2 - test_files/ctors/ctors.js | 2 - test_files/debugger/user.js | 2 - test_files/decl_merge/imported_inner_decl.js | 2 - test_files/decl_merge/inner_class.js | 2 - test_files/decl_merge/inner_enum.js | 2 - test_files/decl_merge/inner_interface.js | 18 +- test_files/decl_merge/inner_interface.ts | 2 +- test_files/decl_merge/inner_typedef.js | 2 - test_files/decl_merge/outer_enum.js | 29 + test_files/decl_merge/outer_enum.ts | 20 + test_files/decl_merge/rejected_ns.js | 44 +- test_files/decl_merge/rejected_ns.ts | 15 +- test_files/declare_export/declare_export.js | 8 +- test_files/declare_export_dts/user.js | 2 - .../declare_import/declare_import_in_ts.js | 2 - test_files/declare_var_and_ns/externs.js | 2 - test_files/decorator/decorator.js | 2 - test_files/decorator/default_export.js | 2 - test_files/decorator/export_const.js | 2 - test_files/decorator/only_types.js | 2 - test_files/doc_params/doc_params.js | 2 - .../docs_on_ctor_param_properties.js | 2 - test_files/enum.no_nstransform/enum.js | 40 ++ test_files/enum.no_nstransform/enum.ts | 27 + test_files/enum.puretransform/enum.js | 21 + test_files/enum.puretransform/enum.ts | 17 + test_files/enum/enum.js | 5 +- test_files/enum/enum.ts | 1 + test_files/enum/enum_user.js | 2 - test_files/enum_ref_import/enum_ref_import.js | 2 - .../enum_value_literal_type.js | 8 +- test_files/eventmap/eventmap.js | 2 - test_files/export/export.js | 2 + test_files/export/export_helper.js | 4 +- test_files/export/export_helper_2.js | 2 - test_files/export/export_helper_3.js | 2 - test_files/export/export_star_imported.js | 4 +- test_files/export_declare_namespace/user.js | 2 - .../export_destructuring.js | 28 + .../export_destructuring.ts | 11 + .../export_local_type/export_local_type.js | 2 - test_files/export_merged/main.js | 2 - test_files/export_multi/export_multi.js | 2 - test_files/export_star_as_ns/star_as_ns.js | 2 - test_files/exporting_decorator/exporting.js | 2 - .../extend_and_implement.js | 2 - test_files/fields/fields.js | 2 - test_files/fields_no_ctor/fields_no_ctor.js | 2 - test_files/file_comment/before_import.js | 2 - .../file_comment/comment_before_class.js | 2 - .../comment_before_elided_import.js | 2 - test_files/file_comment/comment_before_var.js | 2 - test_files/file_comment/comment_no_tag.js | 4 +- test_files/file_comment/comment_with_text.js | 2 - test_files/file_comment/export_star.js | 2 - ...iew_comment_add_suppress_before_license.js | 2 - .../fileoverview_comment_merge_suppress.js | 6 +- .../fileoverview_in_comment_text.js | 2 - test_files/file_comment/latecomment_front.js | 4 +- test_files/file_comment/multiple_comments.js | 10 +- test_files/file_comment/side_effect_import.js | 2 - test_files/functions/functions.js | 2 - test_files/functions/two_jsdoc_blocks.js | 2 - test_files/generic_extends/user.js | 2 - test_files/generic_in_prop_access/user.js | 2 - .../generic_local_var/generic_local_var.js | 2 - test_files/generic_nested_classes/user.js | 2 - .../ignored_ambient_external_module/user.js | 2 - .../interface.js | 2 - .../implement_reexported_interface/user.js | 2 - test_files/implements/implements.js | 2 - .../clutz_input.d.ts | 14 - .../decluser.d.ts | 14 - .../decluser.ts | 5 - .../jsprovides.js | 7 - .../conflicting_multiple.js | 2 - .../conflicting_multiple_bystar.js | 2 - .../conflicting_multiple_empty.js | 2 - .../conflicting_multiple_type.js | 2 - .../multiple_side_effect.js | 2 - test_files/import_by_path.no_externs/user.js | 2 - .../import_by_path.no_externs/user_default.js | 2 - .../using_multiple.js | 2 - .../import_equals/import_equals_type_usage.js | 2 - .../import_from_goog.js | 2 - .../import_only_types/types_and_constenum.js | 6 +- test_files/import_only_types/types_only.js | 2 - .../import_prefixed/import_prefixed_mixed.js | 4 +- .../import_prefixed/import_prefixed_types.js | 8 +- test_files/interface/implement_import.js | 2 - test_files/interface/interface.js | 2 - test_files/interface/interface_extends.js | 2 - test_files/interface/interface_merge.js | 2 - test_files/interface/interface_type_params.js | 2 - test_files/internal.declaration/internal.d.ts | 5 + .../invalid_closure_properties.js | 2 - test_files/jsdoc/enum_tag.js | 2 - test_files/jsdoc/jsdoc.js | 18 +- test_files/jsdoc/jsdoc.ts | 12 + test_files/jsdoc_types.untyped/jsdoc_types.js | 8 +- test_files/jsdoc_types.untyped/module1.js | 2 - test_files/jsdoc_types.untyped/module2.js | 2 - test_files/jsdoc_types.untyped/nevertyped.js | 2 - test_files/jsdoc_types/initialized_unknown.js | 2 - test_files/jsdoc_types/jsdoc_types.js | 2 - test_files/jsdoc_types/module1.js | 2 - test_files/jsdoc_types/module2.js | 2 - test_files/jsdoc_types/nevertyped.js | 2 - test_files/jsx.no_externs/jsx.js | 2 - test_files/methods/methods.js | 2 - .../export_enum_in_namespace.js | 2 - .../export_namespace.js | 2 +- .../merged_namespace.js | 2 - .../namespaced.no_nstransform/reopen_ns.js | 2 - test_files/nullable/nullable.js | 2 - test_files/optional_chaining/keyed_access.js | 2 - .../optional_chaining/optional_chaining.js | 2 - test_files/optional_method/optional_method.js | 2 - .../parameter_properties.js | 2 - test_files/partial/partial.js | 2 - test_files/private_field/private_field.js | 2 - .../promiseconstructor/promiseconstructor.js | 2 - test_files/protected/protected.js | 2 - test_files/readonly/readonly.js | 2 - test_files/recursive_alias/recursive_alias.js | 2 - test_files/recursive_union/recursive_union.js | 2 - .../rest_parameters_any.js | 2 - .../rest_parameters_generic_empty.js | 2 - .../rest_parameters_tuple.js | 2 - test_files/return_this/return_this.js | 2 - test_files/scope_collision/collision.js | 2 - test_files/side_effect_import/module1.js | 2 - test_files/side_effect_import/module2.js | 2 - .../side_effect_import/side_effect_import.js | 2 - .../single_value_enum/single_value_enum.js | 2 - test_files/static/static.js | 2 - .../uncapitalize_lowercase.js | 2 - .../structural.untyped/structural.untyped.js | 2 - test_files/super/super.js | 2 - test_files/this_type/this_type.js | 2 - .../transitive_symbol_type_only/exporter.js | 2 - .../transitive_symbol_type_only.js | 2 - .../bad.js | 2 - ...ult_shorthand_with_more_than_one_export.js | 2 - .../bad_default_shorthand_with_no_exports.js | 2 - .../bad_dln_only.js | 2 - .../correct_default_shorthand.js | 2 - .../correct_default_type.js | 2 - .../correct_default_value.js | 2 - .../correct_default_with_re_export.js | 2 - .../correct_named.js | 2 - .../correct_named_shorthand.js | 2 - .../pintomodule.js | 2 - .../emits_other_errors.js | 2 - test_files/tuple_types/tuple_functions.js | 2 - test_files/tuple_types/tuple_types.js | 2 - .../type_alias_imported/type_alias_declare.js | 2 - .../type_alias_default_exporter.js | 2 - test_files/type_and_value/module.js | 2 - .../type_args_repeated/type_args_repeated.js | 2 - test_files/type_intersection/intersection.js | 2 - test_files/type_narrowing/emit_extra_casts.js | 2 - .../type_propaccess.js | 2 - test_files/typeof_function_overloads/user.js | 19 + test_files/typeof_function_overloads/user.ts | 11 + test_files/underscore/underscore.js | 2 - .../use_closure_externs.js | 2 - test_files/visibility/public_override.js | 2 - yarn.lock | 603 ++++++++++++++++++ 215 files changed, 1552 insertions(+), 998 deletions(-) delete mode 100644 src/tsickle_declaration_marker.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/clutz2_output_demo8.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/clutz_output_demo1.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/clutz_output_demo2.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/clutz_output_demo3.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/clutz_output_demo4.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/clutz_output_demo5.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/clutz_output_demo6.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/clutz_output_demo7.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/user_code.d.ts delete mode 100644 test_files/clutz_imports.declaration.no_externs/user_code.ts create mode 100644 test_files/comments/freestanding_jsdoc.js create mode 100644 test_files/comments/freestanding_jsdoc.ts create mode 100644 test_files/comments/trailing_no_semicolon.js create mode 100644 test_files/comments/trailing_no_semicolon.ts create mode 100644 test_files/decl_merge/outer_enum.js create mode 100644 test_files/decl_merge/outer_enum.ts create mode 100644 test_files/enum.no_nstransform/enum.js create mode 100644 test_files/enum.no_nstransform/enum.ts create mode 100644 test_files/enum.puretransform/enum.js create mode 100644 test_files/enum.puretransform/enum.ts create mode 100644 test_files/export_destructuring/export_destructuring.js create mode 100644 test_files/export_destructuring/export_destructuring.ts delete mode 100644 test_files/import_by_path.declaration.no_externs/clutz_input.d.ts delete mode 100644 test_files/import_by_path.declaration.no_externs/decluser.d.ts delete mode 100644 test_files/import_by_path.declaration.no_externs/decluser.ts delete mode 100644 test_files/import_by_path.declaration.no_externs/jsprovides.js create mode 100644 test_files/typeof_function_overloads/user.js create mode 100644 test_files/typeof_function_overloads/user.ts create mode 100644 yarn.lock diff --git a/demo/package.json b/demo/package.json index 0bd9d3e46..ff2929688 100644 --- a/demo/package.json +++ b/demo/package.json @@ -8,7 +8,7 @@ "dependencies": { "minimist": "^1.2.3", "tsickle": "file:../", - "typescript": "5.2.2" + "typescript": "5.4.2" }, "devDependencies": { "@types/minimist": "1.2.0", diff --git a/package.json b/package.json index b2f9930b5..e5423f429 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "out/src/*" ], "peerDependencies": { - "typescript": "~5.1.5" + "typescript": "~5.4.2" }, "devDependencies": { "@types/diff-match-patch": "^1.0.32", @@ -28,7 +28,7 @@ "source-map-support": "^0.5.19", "tslib": "^2.2.0", "tslint": "^6.1.3", - "typescript": "5.2.2" + "typescript": "5.4.2" }, "scripts": { "build": "tsc", diff --git a/src/clutz.ts b/src/clutz.ts index 2e1a818e8..855abab58 100644 --- a/src/clutz.ts +++ b/src/clutz.ts @@ -21,6 +21,11 @@ import * as googmodule from './googmodule'; import * as path from './path'; import {isDeclaredInClutzDts} from './type_translator'; +interface ClutzHost { + /** See compiler_host.ts */ + rootDirsRelative(fileName: string): string; +} + /** * Constructs a ts.CustomTransformerFactory that postprocesses the .d.ts * that are generated by ordinary TypeScript compilations to add some @@ -28,8 +33,7 @@ import {isDeclaredInClutzDts} from './type_translator'; */ export function makeDeclarationTransformerFactory( typeChecker: ts.TypeChecker, - googmoduleHost: googmodule.GoogModuleProcessorHost): - ts.CustomTransformerFactory { + host: ClutzHost&googmodule.GoogModuleProcessorHost): ts.CustomTransformerFactory { return (context: ts.TransformationContext): ts.CustomTransformer => { return { transformBundle(): ts.Bundle { @@ -49,8 +53,7 @@ export function makeDeclarationTransformerFactory( // import 'path/to/the/js_file'; // so to for that import to resolve, you need to first import the clutz // d.ts that defines that declared module. - const imports = - gatherNecessaryClutzImports(googmoduleHost, typeChecker, file); + const imports = gatherNecessaryClutzImports(host, typeChecker, file); let importStmts: ts.Statement[]|undefined; if (imports.length > 0) { importStmts = imports.map(fileName => { @@ -66,22 +69,56 @@ export function makeDeclarationTransformerFactory( // Construct `declare global {}` in the Clutz namespace for symbols // Clutz might use. const globalBlock = generateClutzAliases( - file, googmoduleHost.pathToModuleName('', file.fileName), - typeChecker, options); + file, host.pathToModuleName('', file.fileName), typeChecker, + options); // Only need to transform file if we needed one of the above additions. if (!importStmts && !globalBlock) return file; - return ts.factory.updateSourceFile(file, [ - ...(importStmts ?? []), - ...file.statements, - ...(globalBlock ? [globalBlock] : []), - ]); + return ts.factory.updateSourceFile( + file, + ts.setTextRange( + ts.factory.createNodeArray([ + ...(importStmts ?? []), + ...file.statements, + ...(globalBlock ? [globalBlock] : []), + ]), + file.statements), + file.isDeclarationFile, + file.referencedFiles.map( + f => fixRelativeReference(f, file, options, host)), + // /// directives are ignored under bazel. + /*typeReferences=*/[]); } }; }; } +/** + * Fixes a relative reference from an output file with respect to multiple + * rootDirs. See https://github.com/Microsoft/TypeScript/issues/8245 for + * details. + */ +function fixRelativeReference( + reference: ts.FileReference, origin: ts.SourceFile, + options: ts.CompilerOptions, host: ClutzHost): ts.FileReference { + if (!options.outDir || !options.rootDir) { + return reference; + } + const originDir = path.dirname(origin.fileName); + // Where TypeScript expects the output to be. + const expectedOutDir = + path.join(options.outDir, path.relative(options.rootDir, originDir)); + const referencedFile = path.join(expectedOutDir, reference.fileName); + // Where the output is actually emitted. + const actualOutDir = + path.join(options.outDir, host.rootDirsRelative(originDir)); + const fixedReference = path.relative(actualOutDir, referencedFile); + + reference.fileName = fixedReference; + return reference; +} + /** Compares two strings and returns a number suitable for use in sort(). */ function stringCompare(a: string, b: string): number { if (a < b) return -1; diff --git a/src/decorators.ts b/src/decorators.ts index fb8523ad1..57e6e6903 100644 --- a/src/decorators.ts +++ b/src/decorators.ts @@ -98,7 +98,7 @@ export function transformDecoratorsOutputForClosurePropertyRenaming(diagnostics: return (context: ts.TransformationContext) => { const result: ts.Transformer = (sourceFile: ts.SourceFile) => { let nodeNeedingGoogReflect: undefined|ts.Node = undefined; - const visitor: ts.Visitor = (node) => { + const visitor = (node: ts.Node) => { const replacementNode = rewriteDecorator(node); if (replacementNode) { nodeNeedingGoogReflect = node; @@ -107,9 +107,7 @@ export function transformDecoratorsOutputForClosurePropertyRenaming(diagnostics: return ts.visitEachChild(node, visitor, context); }; let updatedSourceFile = - // TODO: go/ts50upgrade - Remove after upgrade. - // tslint:disable-next-line:no-unnecessary-type-assertion - ts.visitNode(sourceFile, visitor, ts.isSourceFile)!; + ts.visitNode(sourceFile, visitor, ts.isSourceFile); if (nodeNeedingGoogReflect !== undefined) { const statements = [...updatedSourceFile.statements]; const googModuleIndex = statements.findIndex(isGoogModuleStatement); diff --git a/src/enum_transformer.ts b/src/enum_transformer.ts index 812b4fff0..4b7869bdd 100644 --- a/src/enum_transformer.ts +++ b/src/enum_transformer.ts @@ -19,6 +19,7 @@ * type resolve ("@type {Foo}"). */ +import {TsickleHost} from 'tsickle'; import * as ts from 'typescript'; import * as jsdoc from './jsdoc'; @@ -95,7 +96,7 @@ export function getEnumType(typeChecker: ts.TypeChecker, enumDecl: ts.EnumDeclar /** * Transformer factory for the enum transformer. See fileoverview for details. */ -export function enumTransformer(typeChecker: ts.TypeChecker): +export function enumTransformer(host: TsickleHost, typeChecker: ts.TypeChecker): (context: ts.TransformationContext) => ts.Transformer { return (context: ts.TransformationContext) => { function visitor(node: T): T|ts.Node[] { @@ -180,7 +181,11 @@ export function enumTransformer(typeChecker: ts.TypeChecker): /* modifiers */ undefined, ts.factory.createVariableDeclarationList( [varDecl], - /* create a const var */ ts.NodeFlags.Const)), + /* When using unoptimized namespaces, create a var + declaration, otherwise create a const var. See b/157460535 */ + host.useDeclarationMergingTransformation ? + ts.NodeFlags.Const : + undefined)), node), node); diff --git a/src/externs.ts b/src/externs.ts index a30f6caf0..cae60d17d 100644 --- a/src/externs.ts +++ b/src/externs.ts @@ -295,24 +295,13 @@ export function generateExterns( * interface Foo { x: number; } * interface Foo { y: number; } * we only want to emit the "\@record" for Foo on the first one. - * - * The exception are variable declarations, which - in externs - do not assign a value: - * /.. \@type {...} ./ - * var someVariable; - * /.. \@type {...} ./ - * someNamespace.someVariable; - * If a later declaration wants to add additional properties on someVariable, tsickle must still - * emit an assignment into the object, as it's otherwise absent. */ function isFirstValueDeclaration(decl: ts.DeclarationStatement): boolean { if (!decl.name) return true; const sym = typeChecker.getSymbolAtLocation(decl.name)!; if (!sym.declarations || sym.declarations.length < 2) return true; const earlierDecls = sym.declarations.slice(0, sym.declarations.indexOf(decl)); - // Either there are no earlier declarations, or all of them are variables (see above). tsickle - // emits a value for all other declaration kinds (function for functions, classes, interfaces, - // {} object for namespaces). - return earlierDecls.length === 0 || earlierDecls.every(ts.isVariableDeclaration); + return earlierDecls.length === 0 || earlierDecls.every(d => ts.isVariableDeclaration(d) && d.getSourceFile() !== decl.getSourceFile()); } /** Writes the actual variable statement of a Closure variable declaration. */ diff --git a/src/fileoverview_comment_transformer.ts b/src/fileoverview_comment_transformer.ts index 59563102b..6b7dd07a2 100644 --- a/src/fileoverview_comment_transformer.ts +++ b/src/fileoverview_comment_transformer.ts @@ -10,7 +10,7 @@ import * as ts from 'typescript'; import * as jsdoc from './jsdoc'; import * as path from './path'; -import {createNotEmittedStatement, reportDiagnostic, synthesizeCommentRanges, updateSourceFileNode} from './transformer_util'; +import {reportDiagnostic, synthesizeCommentRanges, updateSourceFileNode} from './transformer_util'; /** * A set of JSDoc tags that mark a comment as a fileoverview comment. These are @@ -65,6 +65,9 @@ function augmentFileoverviewComments( // * Suppress uselessCode. We emit an "if (false)" around type // declarations, which is flagged as unused code unless we suppress it. 'uselessCode', + // suspiciousCode errors flag patterns that are suspicious if human-written + // but not inherently wrong. See also b/323580655. + 'suspiciousCode', // * Suppress some checks for user errors that TS already checks. 'missingReturn', 'unusedPrivateMembers', @@ -152,35 +155,34 @@ export function transformFileoverviewCommentFactory( // they do not get lost later on. const synthesizedComments = jsdoc.synthesizeLeadingComments(firstStatement); - const notEmitted = ts.factory.createNotEmittedStatement(sourceFile); // Modify the comments on the firstStatement in place by removing the // file-level comments. fileComments = synthesizedComments.splice(0, i + 1); - // Move the fileComments onto notEmitted. - ts.setSyntheticLeadingComments(notEmitted, fileComments); - sourceFile = - updateSourceFileNode(sourceFile, ts.factory.createNodeArray([ - notEmitted, firstStatement, ...sourceFile.statements.slice(1) - ])); break; } + } - - // Now walk every top level statement and escape/drop any @fileoverview - // comments found. Closure ignores all @fileoverview comments but the - // last, so tsickle must make sure not to emit duplicated ones. - for (let i = 0; i < sourceFile.statements.length; i++) { - const stmt = sourceFile.statements[i]; - // Accept the NotEmittedStatement inserted above. - if (i === 0 && stmt.kind === ts.SyntaxKind.NotEmittedStatement) { - continue; - } - const comments = jsdoc.synthesizeLeadingComments(stmt); - checkNoFileoverviewComments( - stmt, comments, - `file comments must be at the top of the file, ` + - `separated from the file body by an empty line.`); + // Move the fileComments onto notEmitted. + const notEmitted = ts.factory.createNotEmittedStatement(sourceFile); + ts.setSyntheticLeadingComments(notEmitted, fileComments); + sourceFile = updateSourceFileNode( + sourceFile, + ts.factory.createNodeArray([notEmitted, ...sourceFile.statements])); + + // Now walk every top level statement and escape/drop any @fileoverview + // comments found. Closure ignores all @fileoverview comments but the + // last, so tsickle must make sure not to emit duplicated ones. + for (let i = 0; i < sourceFile.statements.length; i++) { + const stmt = sourceFile.statements[i]; + // Accept the NotEmittedStatement inserted above. + if (i === 0 && stmt.kind === ts.SyntaxKind.NotEmittedStatement) { + continue; } + const comments = jsdoc.synthesizeLeadingComments(stmt); + checkNoFileoverviewComments( + stmt, comments, + `file comments must be at the top of the file, ` + + `separated from the file body by an empty line.`); } // Closure Compiler considers the *last* comment with @fileoverview (or @@ -192,14 +194,17 @@ export function transformFileoverviewCommentFactory( let fileoverviewIdx = -1; let tags: jsdoc.Tag[] = []; for (let i = fileComments.length - 1; i >= 0; i--) { - const parse = jsdoc.parseContents(fileComments[i].text); - if (parse !== null && - parse.tags.some(t => FILEOVERVIEW_COMMENT_MARKERS.has(t.tagName))) { + const parsed = jsdoc.parse(fileComments[i]); + if (parsed !== null && + parsed.tags.some( + t => FILEOVERVIEW_COMMENT_MARKERS.has(t.tagName))) { fileoverviewIdx = i; - tags = parse.tags; + tags = parsed.tags; break; } } + const mutableJsDoc = new jsdoc.MutableJSDoc( + notEmitted, fileComments, fileoverviewIdx, tags); if (fileoverviewIdx !== -1) { checkNoFileoverviewComments( @@ -208,28 +213,11 @@ export function transformFileoverviewCommentFactory( `duplicate file level comment`); } - augmentFileoverviewComments(options, sourceFile, tags, generateExtraSuppressions); - const commentText = jsdoc.toStringWithoutStartEnd(tags); - - if (fileoverviewIdx < 0) { - // No existing comment to merge with, just emit a new one. - return addNewFileoverviewComment(sourceFile, commentText); - } + augmentFileoverviewComments( + options, sourceFile, mutableJsDoc.tags, generateExtraSuppressions); + mutableJsDoc.updateComment(); - fileComments[fileoverviewIdx].text = commentText; - // sf does not need to be updated, synthesized comments are mutable. return sourceFile; }; }; } - -function addNewFileoverviewComment( - sf: ts.SourceFile, commentText: string): ts.SourceFile { - let syntheticFirstStatement = createNotEmittedStatement(sf); - syntheticFirstStatement = ts.addSyntheticTrailingComment( - syntheticFirstStatement, ts.SyntaxKind.MultiLineCommentTrivia, - commentText, true); - return updateSourceFileNode( - sf, - ts.factory.createNodeArray([syntheticFirstStatement, ...sf.statements])); -} diff --git a/src/googmodule.ts b/src/googmodule.ts index bf6e6d91b..fce705bec 100644 --- a/src/googmodule.ts +++ b/src/googmodule.ts @@ -29,11 +29,9 @@ export interface GoogModuleProcessorHost { * Takes the import URL of an ES6 import and returns the googmodule module * name for the imported module, iff the module is an original closure * JavaScript file. - * - * Warning: If this function is present, GoogModule won't produce diagnostics - * for multiple provides. */ - jsPathToModuleName?(importPath: string): string|undefined; + jsPathToModuleName? + (importPath: string): {name: string, multipleProvides: boolean}|undefined; /** * Takes the import URL of an ES6 import and returns the property name that * should be stripped from the usage. @@ -89,7 +87,8 @@ export function jsPathToNamespace( host: GoogModuleProcessorHost, context: ts.Node, diagnostics: ts.Diagnostic[], importPath: string, getModuleSymbol: () => ts.Symbol | undefined): string|undefined { - const namespace = localJsPathToNamespace(host, importPath); + const namespace = + localJsPathToNamespace(host, context, diagnostics, importPath); if (namespace) return namespace; const moduleSymbol = getModuleSymbol(); @@ -105,7 +104,8 @@ export function jsPathToNamespace( * Forwards to `jsPathToModuleName` on the host if present. */ export function localJsPathToNamespace( - host: GoogModuleProcessorHost, importPath: string): string|undefined { + host: GoogModuleProcessorHost, context: ts.Node|undefined, + diagnostics: ts.Diagnostic[], importPath: string): string|undefined { if (importPath.match(/^goog:/)) { // This is a namespace import, of the form "goog:foo.bar". // Fix it to just "foo.bar". @@ -113,7 +113,12 @@ export function localJsPathToNamespace( } if (host.jsPathToModuleName) { - return host.jsPathToModuleName(importPath); + const module = host.jsPathToModuleName(importPath); + if (!module) return undefined; + if (module.multipleProvides) { + reportMultipleProvidesError(context, diagnostics, importPath); + } + return module.name; } return undefined; @@ -394,10 +399,7 @@ function getGoogNamespaceFromClutzComments( findLocalInDeclarations(moduleSymbol, '__clutz_multiple_provides'); if (hasMultipleProvides) { // Report an error... - reportDiagnostic( - tsickleDiagnostics, context, - `referenced JavaScript module ${ - tsImport} provides multiple namespaces and cannot be imported by path.`); + reportMultipleProvidesError(context, tsickleDiagnostics, tsImport); // ... but continue producing an emit that effectively references the first // provided symbol (to continue finding any additional errors). } @@ -411,6 +413,15 @@ function getGoogNamespaceFromClutzComments( return actualNamespace; } +function reportMultipleProvidesError( + context: ts.Node|undefined, diagnostics: ts.Diagnostic[], + importPath: string) { + reportDiagnostic( + diagnostics, context, + `referenced JavaScript module ${ + importPath} provides multiple namespaces and cannot be imported by path.`); +} + /** * Converts a TS/ES module './import/path' into a goog.module compatible * namespace, handling regular imports and `goog:` namespace imports. @@ -446,27 +457,6 @@ function rewriteModuleExportsAssignment(expr: ts.ExpressionStatement) { expr); } -/** - * Checks whether expr is of the form `exports.abc = identifier` and if so, - * returns the string abc, otherwise returns null. - */ -function isExportsAssignment(expr: ts.Expression): string|null { - // Verify this looks something like `exports.abc = ...`. - if (!ts.isBinaryExpression(expr)) return null; - if (expr.operatorToken.kind !== ts.SyntaxKind.EqualsToken) return null; - - // Verify the left side of the expression is an access on `exports`. - if (!ts.isPropertyAccessExpression(expr.left)) return null; - if (!ts.isIdentifier(expr.left.expression)) return null; - if (expr.left.expression.escapedText !== 'exports') return null; - - // Check whether right side of assignment is an identifier. - if (!ts.isIdentifier(expr.right)) return null; - - // Return the property name as string. - return expr.left.name.escapedText.toString(); -} - /** * Convert a series of comma-separated expressions * x = foo, y(), z.bar(); @@ -976,13 +966,19 @@ export function commonJsToGoogmoduleTransformer( // onSubstituteNode callback. ts.setEmitFlags(arg.right.expression, ts.EmitFlags.NoSubstitution); - // Namespaces can merge with classes and functions. TypeScript emits - // separate exports assignments for those. Don't emit extra ones here. + // Namespaces can merge with classes and functions and TypeScript emits + // separate exports assignments for those already. No need to add an + // extra one. + // The same is true for enums, but only if they have been transformed + // to closure enums. const notAlreadyExported = matchingExports.filter( decl => !ts.isClassDeclaration( decl.declarationSymbol.valueDeclaration) && !ts.isFunctionDeclaration( - decl.declarationSymbol.valueDeclaration)); + decl.declarationSymbol.valueDeclaration) && + !(host.transformTypesToClosure && + ts.isEnumDeclaration( + decl.declarationSymbol.valueDeclaration))); const exportNames = notAlreadyExported.map(decl => decl.exportName); return { @@ -1147,7 +1143,6 @@ export function commonJsToGoogmoduleTransformer( return exportStmt; } - const exportsSeen = new Set(); const seenNamespaceOrEnumExports = new Set(); /** @@ -1245,53 +1240,27 @@ export function commonJsToGoogmoduleTransformer( return; } - // Avoid EXPORT_REPEATED_ERROR from JSCompiler. Occurs for: - // class Foo {} - // namespace Foo { ... } - // export {Foo}; - // TypeScript emits 2 separate exports assignments. One after the - // class and one after the namespace. - // TODO(b/277272562): TypeScript 5.1 changes how exports assignments - // are emitted, making this no longer an issue. On the other hand - // this is unsafe. We really need to keep the _last_ (not the first) - // export assignment in the general case. Remove this check after - // the 5.1 upgrade. - const exportName = isExportsAssignment(exprStmt.expression); - if (exportName) { - if (exportsSeen.has(exportName)) { - stmts.push(createNotEmittedStatementWithComments(sf, exprStmt)); - return; - } - exportsSeen.add(exportName); - } - - // TODO(b/277272562): This code works in 5.1. But breaks in 5.0, - // which emits separate exports assignments for namespaces and enums - // and this code would emit duplicate exports assignments. Run this - // unconditionally after 5.1 has been released. - if ((ts.versionMajorMinor as string) !== '5.0') { - // Check for inline exports assignments as they are emitted for - // exported namespaces and enums, e.g.: - // (function (Foo) { - // })(Foo || (exports.Foo = exports.Bar = Foo = {})); - // and moves the exports assignments to a separate statement. - const exportInIifeArguments = - maybeRewriteExportsAssignmentInIifeArguments(exprStmt); - if (exportInIifeArguments) { - stmts.push(exportInIifeArguments.statement); - for (const newExport of exportInIifeArguments.exports) { - const exportName = newExport.expression.left.name.text; - // Namespaces produce multiple exports assignments when - // they're re-opened in the same file. Only emit the first one - // here. This is fine because the namespace object itself - // cannot be re-assigned later. - if (!seenNamespaceOrEnumExports.has(exportName)) { - stmts.push(newExport); - seenNamespaceOrEnumExports.add(exportName); - } + // Check for inline exports assignments as they are emitted for + // exported namespaces and enums, e.g.: + // (function (Foo) { + // })(Foo || (exports.Foo = exports.Bar = Foo = {})); + // and moves the exports assignments to a separate statement. + const exportInIifeArguments = + maybeRewriteExportsAssignmentInIifeArguments(exprStmt); + if (exportInIifeArguments) { + stmts.push(exportInIifeArguments.statement); + for (const newExport of exportInIifeArguments.exports) { + const exportName = newExport.expression.left.name.text; + // Namespaces produce multiple exports assignments when + // they're re-opened in the same file. Only emit the first one + // here. This is fine because the namespace object itself + // cannot be re-assigned later. + if (!seenNamespaceOrEnumExports.has(exportName)) { + stmts.push(newExport); + seenNamespaceOrEnumExports.add(exportName); } - return; } + return; } // Delay `exports.X = X` assignments for decorated classes. @@ -1473,7 +1442,7 @@ export function commonJsToGoogmoduleTransformer( 'requireDynamic', createSingleQuoteStringLiteral(imp)); } - const visitForDynamicImport: ts.Visitor = (node) => { + const visitForDynamicImport = (node: ts.Node) => { const replacementNode = rewriteDynamicRequire(node); if (replacementNode) { return replacementNode; @@ -1482,9 +1451,7 @@ export function commonJsToGoogmoduleTransformer( }; if (host.transformDynamicImport === 'closure') { - // TODO: go/ts50upgrade - Remove after upgrade. - // tslint:disable-next-line:no-unnecessary-type-assertion - sf = ts.visitNode(sf, visitForDynamicImport, ts.isSourceFile)!; + sf = ts.visitNode(sf, visitForDynamicImport, ts.isSourceFile); } // Convert each top level statement to goog.module. diff --git a/src/jsdoc.ts b/src/jsdoc.ts index 063c009b6..4ab7ba586 100644 --- a/src/jsdoc.ts +++ b/src/jsdoc.ts @@ -143,6 +143,15 @@ const CLOSURE_ALLOWED_JSDOC_TAGS_OUTPUT = new Set([ 'wizmodule', ]); +/** + * JSDoc comments not attached to any nodes can generally not contains any tags, + * so all are banned. The exception is "license", which is supported as a + * standalone comment next to the fileoverview. + */ +const BANNED_JSDOC_TAGS_IN_FREESTANDING_COMMENTS = + new Set(CLOSURE_ALLOWED_JSDOC_TAGS_OUTPUT); +BANNED_JSDOC_TAGS_IN_FREESTANDING_COMMENTS.delete('license'); + /** * A list of JSDoc @tags that are never allowed in TypeScript source. These are Closure tags that * can be expressed in the TypeScript surface syntax. As tsickle's emit will mangle type names, @@ -222,7 +231,7 @@ export function normalizeLineEndings(input: string): string { * * @param commentText a comment's text content, i.e. the comment w/o /* and * /. */ -export function parseContents(commentText: string): ParsedJSDocComment|null { +function parseContents(commentText: string): ParsedJSDocComment|null { // Make sure we have proper line endings before parsing on Windows. commentText = normalizeLineEndings(commentText); // Strip all the " * " bits from the front of each line. @@ -233,7 +242,7 @@ export function parseContents(commentText: string): ParsedJSDocComment|null { for (const line of lines) { let match = line.match(/^\s*@([^\s{]+) *({?.*)/); if (match) { - let [_, tagName, text] = match; + let [, tagName, text] = match; if (tagName === 'returns') { // A synonym for 'return'. tagName = 'return'; @@ -276,7 +285,7 @@ export function parseContents(commentText: string): ParsedJSDocComment|null { let parameterName: string|undefined; if (tagName === 'param') { match = text.match(/^(\S+) ?(.*)/); - if (match) [_, parameterName, text] = match; + if (match) [, parameterName, text] = match; } const tag: Tag = {tagName}; @@ -345,7 +354,7 @@ function tagToString(tag: Tag, escapeExtraTags = new Set()): string { return out; } -/** Tags that must only occur onces in a comment (filtered below). */ +/** Tags that must only occur once in a comment (filtered below). */ const SINGLETON_TAGS = new Set(['deprecated']); /** @@ -365,7 +374,7 @@ export interface SynthesizedCommentWithOriginal extends ts.SynthesizedComment { */ export function synthesizeLeadingComments(node: ts.Node): SynthesizedCommentWithOriginal[] { const existing = ts.getSyntheticLeadingComments(node); - if (existing) return existing; + if (existing && hasLeadingCommentsSuppressed(node)) return existing; const text = ts.getOriginalNode(node).getFullText(); const synthComments = getLeadingCommentRangesSynthesized(text, node.getFullStart()); if (synthComments.length) { @@ -375,6 +384,23 @@ export function synthesizeLeadingComments(node: ts.Node): SynthesizedCommentWith return synthComments; } +function hasLeadingCommentsSuppressed(node: ts.Node): boolean { + const internalNode = node as InternalNode; + if (!internalNode.emitNode) return false; + return (internalNode.emitNode.flags & ts.EmitFlags.NoLeadingComments) === + ts.EmitFlags.NoLeadingComments; +} + +declare interface InternalNode extends ts.Node { + // http://google3/third_party/javascript/node_modules/typescript/stable/src/compiler/types.ts;l=954;rcl=589121220 + emitNode?: InternalEmitNode; +} + +declare interface InternalEmitNode { + // http://google3/third_party/javascript/node_modules/typescript/stable/src/compiler/types.ts;l=7982;rcl=589121220 + flags: ts.EmitFlags; +} + /** * parseLeadingCommentRangesSynthesized parses the leading comment ranges out of the given text and * converts them to SynthesizedComments. @@ -435,7 +461,8 @@ export function toSynthesizedComment( } /** Serializes a Comment out to a string, but does not include the start and end comment tokens. */ -export function toStringWithoutStartEnd(tags: Tag[], escapeExtraTags = new Set()): string { +function toStringWithoutStartEnd( + tags: Tag[], escapeExtraTags = new Set()): string { return serialize(tags, false, escapeExtraTags); } @@ -529,22 +556,36 @@ export function createGeneratedFromComment(file: string): string { * allows code to modify (including delete) it. */ export class MutableJSDoc { + private sanitizedOtherComments = false; + constructor( private readonly node: ts.Node, - private sourceComment: ts.SynthesizedComment|null, public tags: Tag[]) {} + private readonly allComments: ts.SynthesizedComment[], + private sourceComment: number, public tags: Tag[]) {} updateComment(escapeExtraTags?: Set) { + if (!this.sanitizedOtherComments) { + for (let i = 0; i < this.allComments.length; i++) { + if (i === this.sourceComment) continue; + const comment = this.allComments[i]; + const parsed = parse(comment); + if (!parsed) continue; + comment.text = toStringWithoutStartEnd( + parsed.tags, BANNED_JSDOC_TAGS_IN_FREESTANDING_COMMENTS); + } + + this.sanitizedOtherComments = true; + } + const text = toStringWithoutStartEnd(this.tags, escapeExtraTags); - if (this.sourceComment) { + if (this.sourceComment >= 0) { if (!text) { // Delete the (now empty) comment. - const comments = ts.getSyntheticLeadingComments(this.node)!; - const idx = comments.indexOf(this.sourceComment); - comments.splice(idx, 1); - this.sourceComment = null; + this.allComments.splice(this.sourceComment, 1); + this.sourceComment = -1; return; } - this.sourceComment.text = text; + this.allComments[this.sourceComment].text = text; return; } @@ -558,9 +599,9 @@ export class MutableJSDoc { pos: -1, end: -1, }; - const comments = ts.getSyntheticLeadingComments(this.node) || []; - comments.push(comment); - ts.setSyntheticLeadingComments(this.node, comments); + this.allComments.push(comment); + this.sourceComment = this.allComments.length - 1; + ts.setSyntheticLeadingComments(this.node, this.allComments); } } @@ -577,7 +618,7 @@ export function getJSDocTags( node: ts.Node, diagnostics?: ts.Diagnostic[], sourceFile?: ts.SourceFile): Tag[] { if (!ts.getParseTreeNode(node)) return []; - const [tags, ] = parseJSDoc(node, diagnostics, sourceFile); + const [, , tags] = parseJSDoc(node, diagnostics, sourceFile); return tags; } @@ -592,13 +633,13 @@ export function getJSDocTags( export function getMutableJSDoc( node: ts.Node, diagnostics?: ts.Diagnostic[], sourceFile?: ts.SourceFile): MutableJSDoc { - const [tags, comment] = parseJSDoc(node, diagnostics, sourceFile); - return new MutableJSDoc(node, comment, tags); + const [comments, i, tags] = parseJSDoc(node, diagnostics, sourceFile); + return new MutableJSDoc(node, comments, i, tags); } function parseJSDoc( node: ts.Node, diagnostics?: ts.Diagnostic[], - sourceFile?: ts.SourceFile): [Tag[], ts.SynthesizedComment|null] { + sourceFile?: ts.SourceFile): [ts.SynthesizedComment[], number, Tag[]] { // synthesizeLeadingComments below changes text locations for node, so extract // the location here in case it is needed later to report diagnostics. let nodeCommentRange: ts.TextRange|undefined; @@ -609,7 +650,7 @@ function parseJSDoc( } const comments = synthesizeLeadingComments(node); - if (!comments || comments.length === 0) return [[], null]; + if (!comments || comments.length === 0) return [[], -1, []]; for (let i = comments.length - 1; i >= 0; i--) { const comment = comments[i]; @@ -621,8 +662,8 @@ function parseJSDoc( diagnostics, node, parsed.warnings.join('\n'), range, ts.DiagnosticCategory.Warning); } - return [parsed.tags, comment]; + return [comments, i, parsed.tags]; } } - return [[], null]; + return [comments, -1, []]; } diff --git a/src/jsdoc_transformer.ts b/src/jsdoc_transformer.ts index 6e3e5119b..1de81773b 100644 --- a/src/jsdoc_transformer.ts +++ b/src/jsdoc_transformer.ts @@ -791,7 +791,8 @@ export function jsdocTransformer( ts.setSyntheticLeadingComments(commentHolder, leading.filter(c => c.text[0] !== '*')); stmts.push(commentHolder); } - + const isExported = varStmt.modifiers?.some( + (modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword); for (const decl of varStmt.declarationList.declarations) { const localTags: jsdoc.Tag[] = []; if (tags) { @@ -827,14 +828,14 @@ export function jsdocTransformer( const updatedBinding = renameArrayBindings(decl.name, aliases); if (updatedBinding && aliases.length > 0) { const declVisited = - // TODO: go/ts50upgrade - Remove after upgrade. - // tslint:disable-next-line:no-unnecessary-type-assertion ts.visitNode(decl, visitor, ts.isVariableDeclaration)!; const newDecl = ts.factory.updateVariableDeclaration( declVisited, updatedBinding, declVisited.exclamationToken, declVisited.type, declVisited.initializer); const newStmt = ts.factory.createVariableStatement( - varStmt.modifiers, + varStmt.modifiers?.filter( + (modifier) => + modifier.kind !== ts.SyntaxKind.ExportKeyword), ts.factory.createVariableDeclarationList([newDecl], flags)); if (localTags.length) { addCommentOn( @@ -842,14 +843,13 @@ export function jsdocTransformer( } stmts.push(newStmt); stmts.push(...createArrayBindingAliases( - varStmt.declarationList.flags, aliases)); + varStmt.declarationList.flags, aliases, isExported)); continue; } } - const newDecl = - // TODO: go/ts50upgrade - Remove after upgrade. - // tslint:disable-next-line:no-unnecessary-type-assertion - ts.visitNode(decl, visitor, ts.isVariableDeclaration)!; + const newDecl = ts.setEmitFlags( + ts.visitNode(decl, visitor, ts.isVariableDeclaration)!, + ts.EmitFlags.NoComments); const newStmt = ts.factory.createVariableStatement( varStmt.modifiers, ts.factory.createVariableDeclarationList([newDecl], flags)); @@ -1116,8 +1116,12 @@ export function jsdocTransformer( // Note: We create explicit exports of type symbols for closure in visitExportDeclaration. return false; } - if (!tsOptions.preserveConstEnums && sym.flags & ts.SymbolFlags.ConstEnum) { - return false; + if (sym.flags & ts.SymbolFlags.ConstEnum) { + if (tsOptions.preserveConstEnums) { + return !sym.valueDeclaration!.getSourceFile().isDeclarationFile; + } else { + return false; + } } return true; } @@ -1172,7 +1176,7 @@ export function jsdocTransformer( exportDecl = ts.factory.updateExportDeclaration( exportDecl, exportDecl.modifiers, isTypeOnlyExport, ts.factory.createNamedExports(exportSpecifiers), - exportDecl.moduleSpecifier, exportDecl.assertClause); + exportDecl.moduleSpecifier, exportDecl.attributes); } else if (ts.isNamedExports(exportDecl.exportClause)) { // export {a, b, c} from 'abc'; for (const exp of exportDecl.exportClause.elements) { @@ -1192,7 +1196,9 @@ export function jsdocTransformer( } const isTypeAlias = (aliasedSymbol.flags & ts.SymbolFlags.Value) === 0 && (aliasedSymbol.flags & (ts.SymbolFlags.TypeAlias | ts.SymbolFlags.Interface)) !== 0; - if (!isTypeAlias) continue; + const isConstEnum = + (aliasedSymbol.flags & ts.SymbolFlags.ConstEnum) !== 0; + if (!isTypeAlias && !isConstEnum) continue; const typeName = moduleTypeTranslator.symbolsToAliasedNames.get(aliasedSymbol) || aliasedSymbol.name; const stmt = ts.factory.createExpressionStatement( @@ -1272,16 +1278,6 @@ export function jsdocTransformer( return result; } - /** - * Visits enum declarations to check for validity of JSDoc comments without transforming the - * node at all. - */ - function visitEnumDeclaration(node: ts.EnumDeclaration) { - // Calling `getJSDoc` will validate and report any errors, but this code - // doesn't really care about the return value. - moduleTypeTranslator.getJSDoc(node, /* reportWarnings */ true); - } - /** * Counter to generate (reasonably) unique alias names for array * rebindings. @@ -1322,8 +1318,6 @@ export function jsdocTransformer( e, e.dotDotDotToken, ts.visitNode(e.propertyName, visitor, ts.isPropertyName), updatedBindingName, - // TODO: go/ts50upgrade - Remove after upgrade. - // tslint:disable-next-line:no-unnecessary-type-assertion ts.visitNode(e.initializer, visitor) as ts.Expression)); } return ts.factory.updateArrayBindingPattern(node, updatedElements); @@ -1336,8 +1330,8 @@ export function jsdocTransformer( * controls const/let/var in particular. */ function createArrayBindingAliases( - flags: ts.NodeFlags, - aliases: Array<[ts.Identifier, ts.Identifier]>): ts.Statement[] { + flags: ts.NodeFlags, aliases: Array<[ts.Identifier, ts.Identifier]>, + needsExport = false): ts.Statement[] { const aliasDecls: ts.Statement[] = []; for (const [oldName, aliasName] of aliases) { const typeStr = @@ -1354,7 +1348,10 @@ export function jsdocTransformer( /* type? */ undefined, closureCastExpr)], flags); const varStmt = ts.factory.createVariableStatement( - /*modifiers*/ undefined, varDeclList); + needsExport ? + [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)] : + undefined, + varDeclList); aliasDecls.push(varStmt); } return aliasDecls; @@ -1406,22 +1403,15 @@ export function jsdocTransformer( if (ts.isBlock(node.statement)) { updatedStatement = ts.factory.updateBlock(node.statement, [ ...aliasDecls, - // TODO: go/ts50upgrade - Remove after upgrade. - // tslint:disable-next-line:no-unnecessary-type-assertion ...ts.visitNode(node.statement, visitor, ts.isBlock)!.statements ]); } else { updatedStatement = ts.factory.createBlock([ - ...aliasDecls, - // TODO: go/ts50upgrade - Remove after upgrade. - // tslint:disable-next-line:no-unnecessary-type-assertion - ts.visitNode(node.statement, visitor) as ts.Statement + ...aliasDecls, ts.visitNode(node.statement, visitor) as ts.Statement ]); } return ts.factory.updateForOfStatement( node, node.awaitModifier, updatedInitializer, - // TODO: go/ts50upgrade - Remove after upgrade. - // tslint:disable-next-line:no-unnecessary-type-assertion ts.visitNode(node.expression, visitor) as ts.Expression, updatedStatement); } @@ -1467,6 +1457,7 @@ export function jsdocTransformer( case ts.SyntaxKind.PropertyDeclaration: case ts.SyntaxKind.ModuleDeclaration: case ts.SyntaxKind.EnumMember: + case ts.SyntaxKind.EnumDeclaration: escapeIllegalJSDoc(node); break; case ts.SyntaxKind.Parameter: @@ -1491,9 +1482,6 @@ export function jsdocTransformer( case ts.SyntaxKind.PropertyAccessExpression: return visitPropertyAccessExpression( node as ts.PropertyAccessExpression); - case ts.SyntaxKind.EnumDeclaration: - visitEnumDeclaration(node as ts.EnumDeclaration); - break; case ts.SyntaxKind.ForOfStatement: return visitForOfStatement(node as ts.ForOfStatement); case ts.SyntaxKind.DeleteExpression: diff --git a/src/ns_transformer.ts b/src/ns_transformer.ts index 67300c942..cf6681876 100644 --- a/src/ns_transformer.ts +++ b/src/ns_transformer.ts @@ -14,6 +14,7 @@ import * as ts from 'typescript'; import {AnnotatorHost} from './annotator_host'; +import {getMutableJSDoc} from './jsdoc'; import {getIdentifierText, getPreviousDeclaration, hasModifierFlag, isAmbient, markAsMergedDeclaration, reportDiagnostic} from './transformer_util'; /** @@ -72,8 +73,8 @@ export function namespaceTransformer( // transformation fails. function transformNamespace( ns: ts.ModuleDeclaration, - mergedDecl: ts.ClassDeclaration| - ts.InterfaceDeclaration): ts.Statement[] { + mergedDecl: ts.ClassDeclaration|ts.InterfaceDeclaration| + ts.EnumDeclaration): ts.Statement[] { if (!ns.body || !ts.isModuleBlock(ns.body)) { if (ts.isModuleDeclaration(ns)) { error( @@ -83,10 +84,15 @@ export function namespaceTransformer( return [ns]; } const nsName = getIdentifierText(ns.name as ts.Identifier); + const mergingWithEnum = ts.isEnumDeclaration(mergedDecl); const transformedNsStmts: ts.Statement[] = []; for (const stmt of ns.body.statements) { if (ts.isEmptyStatement(stmt)) continue; if (ts.isClassDeclaration(stmt)) { + if (mergingWithEnum) { + errorNotAllowed(stmt, 'class'); + continue; + } transformInnerDeclaration( stmt, (classDecl, notExported, hoistedIdent) => { return ts.factory.updateClassDeclaration( @@ -95,12 +101,20 @@ export function namespaceTransformer( classDecl.members); }); } else if (ts.isEnumDeclaration(stmt)) { + if (mergingWithEnum) { + errorNotAllowed(stmt, 'enum'); + continue; + } transformInnerDeclaration( stmt, (enumDecl, notExported, hoistedIdent) => { return ts.factory.updateEnumDeclaration( enumDecl, notExported, hoistedIdent, enumDecl.members); }); } else if (ts.isInterfaceDeclaration(stmt)) { + if (mergingWithEnum) { + errorNotAllowed(stmt, 'interface'); + continue; + } transformInnerDeclaration( stmt, (interfDecl, notExported, hoistedIdent) => { return ts.factory.updateInterfaceDeclaration( @@ -109,6 +123,10 @@ export function namespaceTransformer( interfDecl.members); }); } else if (ts.isTypeAliasDeclaration(stmt)) { + if (mergingWithEnum) { + errorNotAllowed(stmt, 'type alias'); + continue; + } transformTypeAliasDeclaration(stmt); } else if (ts.isVariableStatement(stmt)) { if ((ts.getCombinedNodeFlags(stmt.declarationList) & @@ -116,13 +134,28 @@ export function namespaceTransformer( error( stmt, 'non-const values are not supported. (go/ts-merged-namespaces)'); + continue; } if (!ts.isInterfaceDeclaration(mergedDecl)) { error( stmt, 'const declaration only allowed when merging with an interface (go/ts-merged-namespaces)'); + continue; } transformConstDeclaration(stmt); + } else if (ts.isFunctionDeclaration(stmt)) { + if (!ts.isEnumDeclaration(mergedDecl)) { + error( + stmt, + 'function declaration only allowed when merging with an enum (go/ts-merged-namespaces)'); + } + transformInnerDeclaration( + stmt, (funcDecl, notExported, hoistedIdent) => { + return ts.factory.updateFunctionDeclaration( + funcDecl, notExported, funcDecl.asteriskToken, + hoistedIdent, funcDecl.typeParameters, + funcDecl.parameters, funcDecl.type, funcDecl.body); + }); } else { error( stmt, @@ -145,6 +178,12 @@ export function namespaceTransformer( // Local functions follow. + function errorNotAllowed(stmt: ts.Statement, declKind: string) { + error( + stmt, + `${declKind} cannot be merged with enum declaration. (go/ts-merged-namespaces)`); + } + type DeclarationStatement = ts.Declaration&ts.DeclarationStatement; function transformConstDeclaration(varDecl: ts.VariableStatement) { @@ -243,9 +282,10 @@ export function namespaceTransformer( initializer)); ts.setTextRange(prop, original); ts.setOriginalNode(prop, original); - return ts.addSyntheticLeadingComment( - prop, ts.SyntaxKind.MultiLineCommentTrivia, '* @const ', - /* hasTrailingNewLine */ true); + const jsDoc = getMutableJSDoc(prop, diagnostics, sourceFile); + jsDoc.tags.push({tagName: 'const'}); + jsDoc.updateComment(); + return prop; } function isNamespaceRef(ident: ts.Identifier): boolean { @@ -365,12 +405,13 @@ export function namespaceTransformer( } if (!ts.isInterfaceDeclaration(mergedDecl) && - !ts.isClassDeclaration(mergedDecl)) { - // The previous declaration is not a class or interface. + !ts.isClassDeclaration(mergedDecl) && + !ts.isEnumDeclaration(mergedDecl)) { + // The previous declaration is not a class, enum, or interface. transformedStmts.push(ns); // Nothing to do here. error( ns.name, - 'merged declaration must be local class or interface. (go/ts-merged-namespaces)'); + 'merged declaration must be local class, enum, or interface. (go/ts-merged-namespaces)'); return; } diff --git a/src/summary.ts b/src/summary.ts index ffbff10fb..6edb7577f 100644 --- a/src/summary.ts +++ b/src/summary.ts @@ -48,12 +48,14 @@ export class FileSummary { private readonly strongRequireSet = new Map(); private readonly weakRequireSet = new Map(); private readonly dynamicRequireSet = new Map(); + private readonly maybeRequireSet = new Map(); private readonly modSet = new Map(); private readonly enhancedSet = new Map(); toggles: string[] = []; modName: string|undefined; autochunk = false; enhanceable = false; + legacyNamespace = false; moduleType = ModuleType.UNKNOWN; private stringify(symbol: Symbol): string { @@ -97,6 +99,14 @@ export class FileSummary { return [...this.dynamicRequireSet.values()]; } + addMaybeRequire(maybeRequire: Symbol) { + this.maybeRequireSet.set(this.stringify(maybeRequire), maybeRequire); + } + + get maybeRequires(): Symbol[] { + return [...this.maybeRequireSet.values()]; + } + addMods(mods: Symbol) { this.modSet.set(this.stringify(mods), mods); } diff --git a/src/transformer_util.ts b/src/transformer_util.ts index 6c60ef0dd..2b1076210 100644 --- a/src/transformer_util.ts +++ b/src/transformer_util.ts @@ -112,17 +112,6 @@ export function synthesizeCommentRanges( return synthesizedComments; } -/** - * Creates a non emitted statement that can be used to store synthesized comments. - */ -export function createNotEmittedStatement(sourceFile: ts.SourceFile): ts.NotEmittedStatement { - const stmt = ts.factory.createNotEmittedStatement(sourceFile); - ts.setOriginalNode(stmt, undefined); - ts.setTextRange(stmt, {pos: 0, end: 0}); - ts.setEmitFlags(stmt, ts.EmitFlags.CustomPrologue); - return stmt; -} - /** * This is a version of `ts.visitEachChild` that works that calls our version * of `updateSourceFileNode`, so that typescript doesn't lose type information @@ -152,7 +141,7 @@ export function updateSourceFileNode( } sf = ts.factory.updateSourceFile( sf, - statements, + ts.setTextRange(statements, sf.statements), sf.isDeclarationFile, sf.referencedFiles, sf.typeReferenceDirectives, @@ -227,28 +216,30 @@ export function reportDebugWarning( * @param textRange pass to overrride the text range from the node with a more specific range. */ export function reportDiagnostic( - diagnostics: ts.Diagnostic[], node: ts.Node, messageText: string, textRange?: ts.TextRange, - category = ts.DiagnosticCategory.Error) { + diagnostics: ts.Diagnostic[], node: ts.Node|undefined, messageText: string, + textRange?: ts.TextRange, category = ts.DiagnosticCategory.Error) { diagnostics.push(createDiagnostic(node, messageText, textRange, category)); } function createDiagnostic( - node: ts.Node, messageText: string, textRange: ts.TextRange|undefined, + node: ts.Node|undefined, messageText: string, + textRange: ts.TextRange|undefined, category: ts.DiagnosticCategory): ts.Diagnostic { - let start, length: number; + let start: number|undefined; + let length: number|undefined; // getStart on a synthesized node can crash (due to not finding an associated // source file). Make sure to use the original node. node = ts.getOriginalNode(node); if (textRange) { start = textRange.pos; length = textRange.end - textRange.pos; - } else { + } else if (node) { // Only use getStart if node has a valid pos, as it might be synthesized. start = node.pos >= 0 ? node.getStart() : 0; length = node.end - node.pos; } return { - file: node.getSourceFile(), + file: node?.getSourceFile(), start, length, messageText, @@ -431,4 +422,4 @@ export function getPreviousDeclaration( } } return null; -} \ No newline at end of file +} diff --git a/src/ts_migration_exports_shim.ts b/src/ts_migration_exports_shim.ts index ac715764b..0136ea45e 100644 --- a/src/ts_migration_exports_shim.ts +++ b/src/ts_migration_exports_shim.ts @@ -457,6 +457,9 @@ class Generator { fileSummary.addStrongRequire({type: Type.CLOSURE, name: 'goog'}); fileSummary.addStrongRequire( {type: Type.CLOSURE, name: this.srcIds.googModuleId}); + if (maybeDeclareLegacyNameCall) { + fileSummary.legacyNamespace = true; + } fileSummary.autochunk = isAutoChunk; fileSummary.moduleType = ModuleType.GOOG_MODULE; diff --git a/src/tsickle.ts b/src/tsickle.ts index 3b10f073a..c6f825471 100644 --- a/src/tsickle.ts +++ b/src/tsickle.ts @@ -8,6 +8,7 @@ import * as ts from 'typescript'; +import * as path from './path'; import {AnnotatorHost} from './annotator_host'; import {assertAbsolute} from './cli_support'; import * as clutz from './clutz'; @@ -23,14 +24,13 @@ import {namespaceTransformer} from './ns_transformer'; import {FileSummary, SummaryGenerationProcessorHost} from './summary'; import {isDtsFileName} from './transformer_util'; import * as tsmes from './ts_migration_exports_shim'; -import {makeTsickleDeclarationMarkerTransformerFactory} from './tsickle_declaration_marker'; // Exported for users as a default impl of pathToModuleName. export {pathToModuleName} from './cli_support'; // Retained here for API compatibility. export {getGeneratedExterns} from './externs'; -export {FileMap, ModulesManifest} from './modules_manifest'; -export {FileSummary, ModuleType, Symbol, Type} from './summary'; +export {type FileMap, ModulesManifest} from './modules_manifest'; +export {FileSummary, ModuleType, type Symbol, Type} from './summary'; export interface TsickleHost extends googmodule.GoogModuleProcessorHost, tsmes.TsMigrationExportsShimProcessorHost, @@ -154,6 +154,25 @@ export interface EmitTransformers { } +function writeWithTsickleHeader( + writeFile: ts.WriteFileCallback, rootDir: string) { + return (fileName: string, content: string, writeByteOrderMark: boolean, + onError: ((message: string) => void)|undefined, + sourceFiles: readonly ts.SourceFile[]|undefined, + data: ts.WriteFileCallbackData|undefined) => { + if (fileName.endsWith('.d.ts')) { + // Add tsickle header. + const sources = + sourceFiles?.map(sf => path.relative(rootDir, sf.fileName)); + content = `//!! generated by tsickle from ${ + sources?.join(' ') || '???'}\n${content}`; + } + + writeFile( + fileName, content, writeByteOrderMark, onError, sourceFiles, data); + }; +} + /** * @deprecated Exposed for backward compat with Angular. Use emit() instead. */ @@ -222,7 +241,7 @@ export function emit( } tsickleSourceTransformers.push( jsdocTransformer(host, tsOptions, typeChecker, tsickleDiagnostics)); - tsickleSourceTransformers.push(enumTransformer(typeChecker)); + tsickleSourceTransformers.push(enumTransformer(host, typeChecker)); } if (host.transformDecorators) { tsickleSourceTransformers.push( @@ -254,14 +273,9 @@ export function emit( clutz.makeDeclarationTransformerFactory(typeChecker, host)); } - // Adds a marker to the top of tsickle-generated .d.ts files, should always go - // last - tsTransformers.afterDeclarations!.push( - makeTsickleDeclarationMarkerTransformerFactory(tsOptions)); - const {diagnostics: tsDiagnostics, emitSkipped, emittedFiles} = program.emit( - targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, - tsTransformers); + targetSourceFile, writeWithTsickleHeader(writeFile, tsOptions.rootDir), + cancellationToken, emitOnlyDtsFiles, tsTransformers); const externs: {[fileName: string]: {output: string, moduleNamespace: string}} = {}; diff --git a/src/tsickle_declaration_marker.ts b/src/tsickle_declaration_marker.ts deleted file mode 100644 index 76af06e42..000000000 --- a/src/tsickle_declaration_marker.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -import * as ts from 'typescript'; - -import * as path from './path'; -import {createNotEmittedStatement, updateSourceFileNode} from './transformer_util'; - -/** Marks tsickle generated .d.ts's with a comment we can find later. */ -export function makeTsickleDeclarationMarkerTransformerFactory( - options: ts.CompilerOptions): ts.CustomTransformerFactory { - return (context: ts.TransformationContext): ts.CustomTransformer => { - return { - transformBundle(): ts.Bundle { - // The TS API wants declaration transfomers to be able to handle Bundle, - // but we don't support them within tsickle. - throw new Error('did not expect to transform a bundle'); - }, - transformSourceFile(sf: ts.SourceFile): ts.SourceFile { - if (!options.rootDir) return sf; - let syntheticFirstStatement = createNotEmittedStatement(sf); - syntheticFirstStatement = ts.addSyntheticTrailingComment( - syntheticFirstStatement, ts.SyntaxKind.SingleLineCommentTrivia, - `!! generated by tsickle from ${ - path.relative(options.rootDir, sf.fileName)}`, - /*hasTrailingNewLine=*/ true); - return updateSourceFileNode(sf, ts.factory.createNodeArray([ - syntheticFirstStatement, ...sf.statements - ])); - } - }; - }; -} diff --git a/src/type_translator.ts b/src/type_translator.ts index 324ec77e8..1464a7cb4 100644 --- a/src/type_translator.ts +++ b/src/type_translator.ts @@ -860,6 +860,20 @@ export class TypeTranslator { if (sigs.length === 1) { return this.signatureToClosure(sigs[0]); } + // Function has multiple declaration. Let's see if we can find a single + // declaration with an implementation. In this case all the other + // declarations are overloads and the implementation must have a + // signature that matches all of them. + const declWithBody = type.symbol.declarations?.filter( + (d): d is ts.FunctionLikeDeclaration => + isFunctionLikeDeclaration(d) && d.body != null); + if (declWithBody?.length === 1) { + const sig = + this.typeChecker.getSignatureFromDeclaration(declWithBody[0]); + if (sig) { + return this.signatureToClosure(sig); + } + } this.warn('unhandled anonymous type with multiple call signatures'); return '?'; } @@ -1173,3 +1187,11 @@ export function restParameterType( } return typeArgs[0]; } + +function isFunctionLikeDeclaration(node: ts.Node): + node is ts.FunctionLikeDeclaration { + return ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || + ts.isConstructorDeclaration(node) || ts.isGetAccessorDeclaration(node) || + ts.isSetAccessorDeclaration(node) || ts.isFunctionExpression(node) || + ts.isArrowFunction(node); +} diff --git a/test/googmodule_test.ts b/test/googmodule_test.ts index a258a7bcf..4d804cbb5 100644 --- a/test/googmodule_test.ts +++ b/test/googmodule_test.ts @@ -13,6 +13,7 @@ import * as googmodule from '../src/googmodule'; import {ModulesManifest} from '../src/modules_manifest'; import * as testSupport from './test_support'; +import {outdent} from './test_support'; interface ResolvedNamespace { name: string; @@ -42,8 +43,14 @@ function processES5( transformDynamicImport: 'closure', }; if (pathToNamespaceMap) { - host.jsPathToModuleName = (importPath: string) => - pathToNamespaceMap.get(importPath)?.name; + host.jsPathToModuleName = (importPath: string) => { + const module = pathToNamespaceMap.get(importPath); + if (!module) return undefined; + return { + name: module.name, + multipleProvides: false, + }; + }; host.jsPathToStripProperty = (importPath: string) => pathToNamespaceMap.get(importPath)?.stripProperty; } @@ -71,21 +78,6 @@ function processES5( return {output, manifest, rootDir}; } -/** - * Remove the first line (if empty) and unindents the all other lines by the - * amount of leading whitespace in the second line. - */ -function outdent(str: string) { - const lines = str.split('\n'); - if (lines.length < 2) return str; - if (lines.shift() !== '') return str; - const indent = lines[0].match(/^ */)![0].length; - for (let i = 0; i < lines.length; i++) { - lines[i] = lines[i].substring(indent); - } - return lines.join('\n'); -} - describe('convertCommonJsToGoogModule', () => { beforeEach(() => { testSupport.addDiffMatchers(); diff --git a/test/test_support.ts b/test/test_support.ts index c270ac144..3b0aa1799 100644 --- a/test/test_support.ts +++ b/test/test_support.ts @@ -312,7 +312,7 @@ export function goldenTests(): GoldenFileTest[] { testDir => !testDir.includes('ts_migration_exports_shim')); } let tests = testDirs.map(testDir => { - let tsPaths = glob.sync(path.join(testDir, '**/*.ts')); + let tsPaths = glob.sync(path.join(testDir, '**/*.ts')).sort(); tsPaths = tsPaths.concat(glob.sync(path.join(testDir, '*.tsx'))); tsPaths = tsPaths.filter(p => !p.match(/\.(tsickle|decorated|tsmes)\./)); const tsFiles = tsPaths.map(f => path.relative(testDir, f)); @@ -337,7 +337,9 @@ export function goldenTests(): GoldenFileTest[] { * verification by the e2e_clutz_dts_test. */ export function allDtsPaths(): string[] { - return glob.sync(path.join(rootDir(), 'test_files', '**/*.d.ts')); + // Sorting is no longer supported by glob.sync + // (https://github.com/isaacs/node-glob/issues/372) + return glob.sync(path.join(rootDir(), 'test_files', '**/*.d.ts')).sort(); } /** @@ -453,3 +455,18 @@ export function pathToModuleName( if (fileName === tslibPath()) return 'tslib'; return cliSupport.pathToModuleName(rootModulePath, context, fileName); } + +/** + * Remove the first line (if empty) and unindents the all other lines by the + * amount of leading whitespace in the second line. + */ +export function outdent(str: string) { + const lines = str.split('\n'); + if (lines.length < 2) return str; + if (lines.shift() !== '') return str; + const indent = lines[0].match(/^ */)![0].length; + for (let i = 0; i < lines.length; i++) { + lines[i] = lines[i].substring(indent); + } + return lines.join('\n'); +} diff --git a/test/tsickle_test.ts b/test/tsickle_test.ts index 7fbb9592a..0f5a8f9e1 100644 --- a/test/tsickle_test.ts +++ b/test/tsickle_test.ts @@ -13,14 +13,14 @@ import {assertAbsolute} from '../src/cli_support'; import * as tsickle from '../src/tsickle'; import * as testSupport from './test_support'; +import {outdent} from './test_support'; describe('emitWithTsickle', () => { function emitWithTsickle( tsSources: {[fileName: string]: string}, tsConfigOverride: Partial = {}, tsickleHostOverride: Partial = {}, - customTransformers?: tsickle.EmitTransformers): - {[fileName: string]: string} { + customTransformers?: tsickle.EmitTransformers) { const tsCompilerOptions: ts.CompilerOptions = { ...testSupport.compilerOptions, target: ts.ScriptTarget.ES5, @@ -55,13 +55,13 @@ describe('emitWithTsickle', () => { return importPath.replace(/\/|\\/g, '.'); }, fileNameToModuleId: (fileName) => fileName.replace(/^\.\//, ''), - ...tsickleHostOverride, options: tsCompilerOptions, rootDirsRelative: testSupport.relativeToTsickleRoot, - transformDynamicImport: 'closure' + transformDynamicImport: 'closure', + ...tsickleHostOverride, }; const jsSources: {[fileName: string]: string} = {}; - tsickle.emit( + const {diagnostics} = tsickle.emit( program, tsickleHost, (fileName: string, data: string) => { jsSources[path.relative(tsCompilerOptions.rootDir!, fileName)] = data; @@ -69,7 +69,7 @@ describe('emitWithTsickle', () => { /* sourceFile */ undefined, /* cancellationToken */ undefined, /* emitOnlyDtsFiles */ undefined, customTransformers); - return jsSources; + return {jsSources, diagnostics}; } @@ -91,7 +91,7 @@ describe('emitWithTsickle', () => { const tsSources = { 'a.ts': `export const x = 1;`, }; - const jsSources = emitWithTsickle( + const {jsSources} = emitWithTsickle( tsSources, undefined, { shouldSkipTsickleProcessing: () => true, }, @@ -100,20 +100,84 @@ describe('emitWithTsickle', () => { expect(jsSources['a.js']).toContain('exports.x = 2;'); }); - it('should export const enums when preserveConstEnums is true', () => { + it('escapes JSDoc on const enums in unoptimized namespaces', () => { const tsSources = { - 'a.ts': `export const enum Foo { Bar };`, - 'b.ts': `export * from './a';`, + 'a.ts': outdent(` + namespace Foo { + /** @customTag */ + export const enum Bar { A } + } + `), }; - const jsSources = emitWithTsickle( + const {jsSources} = emitWithTsickle( tsSources, { preserveConstEnums: true, module: ts.ModuleKind.ES2015, }, - {googmodule: false}); + { + useDeclarationMergingTransformation: false, + }); - expect(jsSources['b.js']).toContain(`export { Foo } from './a';`); + expect(jsSources['a.js']).toContain(outdent(` + (function (Foo) { + /** + * \\@customTag + */ + var Bar; + `)); + }); + + describe('const enum exports', () => { + it('should export value when preserveConstEnums is enabled (from .ts file)', () => { + const tsSources = { + // Simulate a.ts, b.ts and c.ts being in the same compilation unit. + 'a.ts': `export const enum Foo { Bar }`, + 'b.ts': `export * from './a';`, + 'c.ts': `export {Foo as Bar} from './a';`, + }; + + const {jsSources} = emitWithTsickle(tsSources, { + preserveConstEnums: true, + module: ts.ModuleKind.ES2015, + }); + + expect(jsSources['b.js']).toContain(`export { Foo } from './a';`); + expect(jsSources['c.js']).toContain(`export { Foo as Bar } from './a';`); + }); + + it('should export type when preserveConstEnums is enabled (from .d.ts file)', () => { + const tsSources = { + // Simulate a.d.ts coming from a different compilation unit. + 'a.d.ts': `export declare const enum Foo { Bar = 0 }`, + 'b.ts': `export * from './a';`, + 'c.ts': `export {Foo as Bar} from './a';`, + }; + + const {jsSources} = emitWithTsickle(tsSources, { + preserveConstEnums: true, + module: ts.ModuleKind.ES2015, + }); + + expect(jsSources['b.js']).toContain(`exports.Foo; // re-export typedef`); + expect(jsSources['c.js']).toContain(`exports.Bar; // re-export typedef`); + }); + + it('should export type when preserveConstEnums is disabled', () => { + const tsSources = { + 'a.ts': `export const enum Foo { Bar }`, + 'b.ts': `export * from './a';`, + 'c.ts': `export {Foo as Bar} from './a';`, + }; + + const {jsSources} = emitWithTsickle(tsSources, { + preserveConstEnums: false, + module: ts.ModuleKind.ES2015, + }); + + expect(jsSources['b.js']).toContain(`exports.Foo; // re-export typedef`); + expect(jsSources['c.js']).toContain(`exports.Bar; // re-export typedef`); + }); }); it('should not go into an infinite loop with a self-referential type', () => { @@ -121,16 +185,62 @@ describe('emitWithTsickle', () => { 'a.ts': `export function f() : typeof f { return f; }`, }; - const jsSources = emitWithTsickle(tsSources, { + const {jsSources} = emitWithTsickle(tsSources, { module: ts.ModuleKind.ES2015, }); - expect(jsSources['a.js']).toContain(` -/** - * @return {function(): ?} - */ -export function f() { return f; } -`); + expect(jsSources['a.js']).toContain(outdent(` + /** + * @return {function(): ?} + */ + export function f() { return f; } + `)); + }); + + it('reports multi-provides error with jsPathToModuleName impl', () => { + const tsSources = { + 'a.ts': `import {} from 'google3/multi/provide';`, + 'clutz.d.ts': `declare module 'google3/multi/provide' { export {}; }`, + }; + const {diagnostics} = + emitWithTsickle( + tsSources, /* tsConfigOverride= */ undefined, + /* tsickleHostOverride= */ { + jsPathToModuleName(importPath: string) { + if (importPath === 'google3/multi/provide') { + return { + name: 'multi.provide', + multipleProvides: true, + }; + } + return undefined; + } + }); + expect(testSupport.formatDiagnostics(diagnostics)) + .toContain( + 'referenced JavaScript module google3/multi/provide provides multiple namespaces and cannot be imported by path'); + }); + + it('allows side-effect import of multi-provides module', () => { + const tsSources = { + 'a.ts': `import 'google3/multi/provide';`, + 'clutz.d.ts': `declare module 'google3/multi/provide' { export {}; }`, + }; + const {jsSources} = emitWithTsickle( + tsSources, /* tsConfigOverride= */ undefined, + /* tsickleHostOverride= */ { + googmodule: true, + jsPathToModuleName(importPath: string) { + if (importPath === 'google3/multi/provide') { + return { + name: 'multi.provide', + multipleProvides: true, + }; + } + return undefined; + }, + }); + expect(jsSources['a.js']).toContain(`goog.require('multi.provide');`); }); describe('regressions', () => { @@ -140,16 +250,15 @@ export function f() { return f; } 'a.ts': `export const x = 1;`, 'b.ts': `export * from './a';\n`, }; - const jsSources = emitWithTsickle( - tsSources, { - declaration: true, - module: ts.ModuleKind.ES2015, - }, - {googmodule: false}); - - expect(jsSources['b.d.ts']) - .toEqual(`//!! generated by tsickle from b.ts -export * from './a';\n`); + const {jsSources} = emitWithTsickle(tsSources, { + declaration: true, + module: ts.ModuleKind.ES2015, + }); + + expect(jsSources['b.d.ts']).toEqual(outdent(` + //!! generated by tsickle from b.ts + export * from './a'; + `)); }); }); }); diff --git a/test_files/abstract/abstract.js b/test_files/abstract/abstract.js index 93226c052..3020474d2 100644 --- a/test_files/abstract/abstract.js +++ b/test_files/abstract/abstract.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/abstract/abstract.ts * @suppress {uselessCode} - * */ goog.module('test_files.abstract.abstract'); var module = module || { id: 'test_files/abstract/abstract.ts' }; diff --git a/test_files/async_functions/async_functions.js b/test_files/async_functions/async_functions.js index 55fe1d0f1..f6c70d481 100644 --- a/test_files/async_functions/async_functions.js +++ b/test_files/async_functions/async_functions.js @@ -2,14 +2,12 @@ goog.module('test_files.async_functions.async_functions'); var module = module || { id: 'test_files/async_functions/async_functions.ts' }; const tslib_1 = goog.require('tslib'); /** - * * @fileoverview * Exercises various forms of async functions. When TypeScript downlevels these * functions, it inserts a reference to 'this' which then tickles a Closure * check around whether 'this' has a known type. * Generated from: test_files/async_functions/async_functions.ts * @suppress {uselessCode} - * */ /** * @param {string} param diff --git a/test_files/augment/externs.js b/test_files/augment/externs.js index 18fb334ad..077c7e11f 100644 --- a/test_files/augment/externs.js +++ b/test_files/augment/externs.js @@ -8,8 +8,6 @@ var test_files$augment$angular$index_ = {}; /** @type {!test_files$augment$angular$index_.angular.IAngularStatic} */ test_files$augment$angular$index_.angular; -/** @const */ -test_files$augment$angular$index_.angular = {}; /** * @record * @struct diff --git a/test_files/augment/user.js b/test_files/augment/user.js index b9e98fb82..dcde6707a 100644 --- a/test_files/augment/user.js +++ b/test_files/augment/user.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/augment/user.ts * @suppress {checkTypes} - * */ goog.module('test_files.augment.user'); var module = module || { id: 'test_files/augment/user.ts' }; diff --git a/test_files/basic.untyped/basic.untyped.js b/test_files/basic.untyped/basic.untyped.js index 36c8d2723..2de145c88 100644 --- a/test_files/basic.untyped/basic.untyped.js +++ b/test_files/basic.untyped/basic.untyped.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This test is just a random collection of typed code, to ensure * the output is all with {?} annotations. * Generated from: test_files/basic.untyped/basic.untyped.ts * @suppress {uselessCode} - * */ goog.module('test_files.basic.untyped.basic.untyped'); var module = module || { id: 'test_files/basic.untyped/basic.untyped.ts' }; diff --git a/test_files/cast_extends/cast_extends.js b/test_files/cast_extends/cast_extends.js index bdf2b6a9f..1484302df 100644 --- a/test_files/cast_extends/cast_extends.js +++ b/test_files/cast_extends/cast_extends.js @@ -1,13 +1,11 @@ // test_files/cast_extends/cast_extends.ts(18,1): warning TS0: unhandled type flags: Intersection // test_files/cast_extends/cast_extends.ts(24,10): warning TS0: unhandled type flags: Intersection /** - * * @fileoverview Reproduces an issue where tsickle would emit a cast for the * "extends" clause, and Closure would report an error due to the extends * expression not resolving to a plain identifier. * Generated from: test_files/cast_extends/cast_extends.ts * @suppress {checkTypes,uselessCode} - * */ goog.module('test_files.cast_extends.cast_extends'); var module = module || { id: 'test_files/cast_extends/cast_extends.ts' }; diff --git a/test_files/class.untyped/class.js b/test_files/class.untyped/class.js index 5d68e3b5a..46ca33f87 100644 --- a/test_files/class.untyped/class.js +++ b/test_files/class.untyped/class.js @@ -1,10 +1,8 @@ // test_files/class.untyped/class.ts(48,1): warning TS0: type/symbol conflict for Zone, using {?} for now /** - * * @fileoverview * Generated from: test_files/class.untyped/class.ts * @suppress {uselessCode} - * */ goog.module('test_files.class.untyped.class'); var module = module || { id: 'test_files/class.untyped/class.ts' }; diff --git a/test_files/class/class.js b/test_files/class/class.js index 2dff26d72..58672f4ac 100644 --- a/test_files/class/class.js +++ b/test_files/class/class.js @@ -6,7 +6,6 @@ // test_files/class/class.ts(136,38): warning TS0: type/symbol conflict for Zone, using {?} for now // test_files/class/class.ts(136,1): warning TS0: dropped implements: {?} type /** - * * @fileoverview This test exercises the various ways classes and interfaces can * interact. There are three types of classy things: interface, class, abstract * class And there are two keywords for relating them: extends, implements You @@ -16,7 +15,6 @@ * Generated from: test_files/class/class.ts * @suppress {uselessCode} * @suppress {dangerousUnrecognizedTypeError} - * */ goog.module('test_files.class.class'); var module = module || { id: 'test_files/class/class.ts' }; diff --git a/test_files/clutz.no_externs/import_default.js b/test_files/clutz.no_externs/import_default.js index ae4bb2d6a..390d3e2b1 100644 --- a/test_files/clutz.no_externs/import_default.js +++ b/test_files/clutz.no_externs/import_default.js @@ -1,8 +1,6 @@ /** - * * @fileoverview Reproduces a problem where a renamed Clutz default export ({default as X}) would * produce type annotations including an indirection to the aliased symbol. - * * Generated from: test_files/clutz.no_externs/import_default.ts */ goog.module('test_files.clutz.no_externs.import_default'); diff --git a/test_files/clutz_imports.declaration.no_externs/clutz2_output_demo8.d.ts b/test_files/clutz_imports.declaration.no_externs/clutz2_output_demo8.d.ts deleted file mode 100644 index 3874d54c0..000000000 --- a/test_files/clutz_imports.declaration.no_externs/clutz2_output_demo8.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -//!! generated by clutz2 -/** - * @fileoverview This file contains the Clutz2 output for a simple goog.provide. - * It was manually created and is a support file for the actual test. - */ - -declare namespace ಠ_ಠ.clutz { - namespace demo8 { - export class C { - private noStructuralTyping_demo8$C: any; - } - } // namespace demo8 -} // ಠ_ಠ.clutz - -declare module 'goog:demo8' { - import demo8 = ಠ_ಠ.clutz.demo8; - export default demo8; -} diff --git a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo1.d.ts b/test_files/clutz_imports.declaration.no_externs/clutz_output_demo1.d.ts deleted file mode 100644 index 923e8b723..000000000 --- a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo1.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -//!! generated by clutz. -/** - * @fileoverview This file contains the Clutz output for a simple goog.module. - * It was manually created and is a support file for the actual test. - */ - -declare namespace ಠ_ಠ.clutz.module$exports$demo1 { - class C { - private noStructuralTyping_module$exports$demo1_C: any; - foo(): void; - } -} -declare module 'goog:demo1' { -import demo1 = ಠ_ಠ.clutz.module$exports$demo1; - export = demo1; -} diff --git a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo2.d.ts b/test_files/clutz_imports.declaration.no_externs/clutz_output_demo2.d.ts deleted file mode 100644 index 52c32f839..000000000 --- a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo2.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -//!! generated by clutz. -/** - * @fileoverview This file contains the Clutz output for a simple goog.provide. - * It was manually created and is a support file for the actual test. - */ - -declare namespace ಠ_ಠ.clutz.demo2 { - class C { - private noStructuralTyping_demo2_C: any; - bar(): void; - } -} -declare module 'goog:demo2' { -import demo2 = ಠ_ಠ.clutz.demo2; - export = demo2; -} diff --git a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo3.d.ts b/test_files/clutz_imports.declaration.no_externs/clutz_output_demo3.d.ts deleted file mode 100644 index 5c68d9376..000000000 --- a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo3.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -//!! generated by clutz. -/** - * @fileoverview This file contains the Clutz output for a simple goog.module. - * It was manually created and is a support file for the actual test. - */ - -declare namespace ಠ_ಠ.clutz { - class module$exports$demo3 { - private noStructuralTyping_module$exports$demo3: any; - bar(): void; - } -} -declare module 'goog:demo3' { -import demo3 = ಠ_ಠ.clutz.module$exports$demo3; - export default demo3; -} diff --git a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo4.d.ts b/test_files/clutz_imports.declaration.no_externs/clutz_output_demo4.d.ts deleted file mode 100644 index 4758a64fd..000000000 --- a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo4.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -//!! generated by clutz. -/** - * @fileoverview This file contains the Clutz output for a simple goog.provide. - * It was manually created and is a support file for the actual test. - */ - -declare namespace ಠ_ಠ.clutz.demo4 { - function f(): void; -} -declare module 'goog:demo4' { -import demo4 = ಠ_ಠ.clutz.demo4; - export = demo4; -} diff --git a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo5.d.ts b/test_files/clutz_imports.declaration.no_externs/clutz_output_demo5.d.ts deleted file mode 100644 index 9cb9ad9ae..000000000 --- a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo5.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -//!! generated by clutz. -/** - * @fileoverview This file contains the Clutz output for a simple goog.module. - * It was manually created and is a support file for the actual test. - */ - -declare namespace ಠ_ಠ.clutz.module$exports$demo5 { - class C { - private noStructuralTyping_module$exports$demo5_C : any; - f ( ) : void ; - } -} -declare module 'goog:demo5' { - import demo5 = ಠ_ಠ.clutz.module$exports$demo5; - export = demo5; -} - diff --git a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo6.d.ts b/test_files/clutz_imports.declaration.no_externs/clutz_output_demo6.d.ts deleted file mode 100644 index 96b67ac90..000000000 --- a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo6.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -//!! generated by clutz. -/** - * @fileoverview This file contains the Clutz output for a simple goog.module, - * with a generic class. - * It was manually created and is a support file for the actual test. - */ - -declare namespace ಠ_ಠ.clutz.module$exports$demo6 { - class C < T = any > { - private noStructuralTyping_module$exports$demo6_C : [ T ]; - foo ( ) : void ; - } -} -declare module 'goog:demo6' { - import demo6 = ಠ_ಠ.clutz.module$exports$demo6; - export = demo6; -} - diff --git a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo7.d.ts b/test_files/clutz_imports.declaration.no_externs/clutz_output_demo7.d.ts deleted file mode 100644 index 5333dad3a..000000000 --- a/test_files/clutz_imports.declaration.no_externs/clutz_output_demo7.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -//!! generated by clutz. -/** - * @fileoverview This file contains the Clutz output for an externs file. - * It was manually created and is a support file for the actual test. - */ - -declare namespace demo7 { - class C { - foo(): void; - } -} diff --git a/test_files/clutz_imports.declaration.no_externs/user_code.d.ts b/test_files/clutz_imports.declaration.no_externs/user_code.d.ts deleted file mode 100644 index 0a3d3ba90..000000000 --- a/test_files/clutz_imports.declaration.no_externs/user_code.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -// test_files/clutz_imports.declaration.no_externs/user_code.ts(39,1): warning TS0: anonymous type has no symbol -//!! generated by tsickle from test_files/clutz_imports.declaration.no_externs/user_code.ts -import "test_files/clutz_imports.declaration.no_externs/clutz_output_demo1"; -import "test_files/clutz_imports.declaration.no_externs/clutz_output_demo2"; -import "test_files/clutz_imports.declaration.no_externs/clutz2_output_demo8"; -import "test_files/clutz_imports.declaration.no_externs/clutz_output_demo4"; -import "test_files/clutz_imports.declaration.no_externs/clutz_output_demo6"; -import "test_files/clutz_imports.declaration.no_externs/clutz_output_demo5"; -import "test_files/clutz_imports.declaration.no_externs/clutz_output_demo7"; -/** - * @fileoverview This file simulates a TypeScript file that interacts with Clutz - * types. The expected output is that the generated .d.ts file has explicit - * "import" statements that refer directly to the paths that define some of - * the Clutz symbols (either goog: or look of disapproval) referenced in the - * public API of this file. - */ -import * as demo1 from 'goog:demo1'; -/** - * demo1 is exposed in the public API via an import, so we expect the output - * d.ts to have an import of the module underlying goog:demo1. - */ -export declare function f1(c: demo1.C): void; -/** - * demo2 is exposed in the public API via a direct reference to the look of - * disapproval namespace, so we expect the output d.ts to have an import of the - * module underlying goog:demo2. - * - * demo8 is the same, but the d.ts file is generated by Clutz2. - */ -export declare function f2(c: ಠ_ಠ.clutz.demo2.C, c2: ಠ_ಠ.clutz.demo8.C): void; -/** - * demo4 verifies that the Clutz type via 'typeof' still produces an import - * statement in the output. (It differs from the above in that a typeof node - * in the TS AST contains the reference to a Clutz symbol as a value, not a - * type.) - */ -export type f4 = typeof ಠ_ಠ.clutz.demo4; -export declare function f5(): ಠ_ಠ.clutz.module$exports$demo6.C<ಠ_ಠ.clutz.module$exports$demo5.C> | undefined; -/** - * demo7 contains typings generated from externs. - * - * Even though we don't reference the internal Clutz namespace here, we expect - * the output d.ts to have an import to the demo7 file. - */ -export declare function f6(c: demo7.C): void; -declare global { - namespace ಠ_ಠ.clutz { - export { f1 as module$contents$test_files$clutz_imports$declaration$no_externs$user_code_f1, f2 as module$contents$test_files$clutz_imports$declaration$no_externs$user_code_f2, f4 as module$contents$test_files$clutz_imports$declaration$no_externs$user_code_f4, f5 as module$contents$test_files$clutz_imports$declaration$no_externs$user_code_f5, f6 as module$contents$test_files$clutz_imports$declaration$no_externs$user_code_f6 }; - export namespace module$exports$test_files$clutz_imports$declaration$no_externs$user_code { - export { f1, f2, f4, f5, f6 }; - } - } -} diff --git a/test_files/clutz_imports.declaration.no_externs/user_code.ts b/test_files/clutz_imports.declaration.no_externs/user_code.ts deleted file mode 100644 index 9c2741eea..000000000 --- a/test_files/clutz_imports.declaration.no_externs/user_code.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @fileoverview This file simulates a TypeScript file that interacts with Clutz - * types. The expected output is that the generated .d.ts file has explicit - * "import" statements that refer directly to the paths that define some of - * the Clutz symbols (either goog: or look of disapproval) referenced in the - * public API of this file. - */ - -import * as demo1 from 'goog:demo1'; -import demo3 from 'goog:demo3'; - -/** - * demo1 is exposed in the public API via an import, so we expect the output - * d.ts to have an import of the module underlying goog:demo1. - */ -export function f1(c: demo1.C) {} - -/** - * demo2 is exposed in the public API via a direct reference to the look of - * disapproval namespace, so we expect the output d.ts to have an import of the - * module underlying goog:demo2. - * - * demo8 is the same, but the d.ts file is generated by Clutz2. - */ -export function f2(c: ಠ_ಠ.clutz.demo2.C, c2: ಠ_ಠ.clutz.demo8.C) {} - -/** - * demo3 is used by this module, but not exported, so we don't expect an import - * of the underlying module in the output d.ts. - */ -function f3(c: demo3) {} - -/** - * demo4 verifies that the Clutz type via 'typeof' still produces an import - * statement in the output. (It differs from the above in that a typeof node - * in the TS AST contains the reference to a Clutz symbol as a value, not a - * type.) - */ -export type f4 = typeof ಠ_ಠ.clutz.demo4; - -/** - * This next example verifies that references generated by TS are still handled. - * The internal function here references a Clutz type, which normally would - * stay internal-only and not affect the d.ts. But then we export a function - * that uses inference to refer to this type. - * - * This is a special case because the Clutz type appears in the d.ts but it - * is generated by a codepath in the TS compiler that causes the type to have no - * symbol present in the TypeChecker. - * - * This also uses a generic, to cover one additional case. - * We expect both demo5 and demo6 to show up in the public API of the d.ts. - */ -function internal(): - ಠ_ಠ.clutz.module$exports$demo6.C<ಠ_ಠ.clutz.module$exports$demo5.C>| - undefined { - return undefined; -} -export function f5() { - return internal(); -} - -/** - * demo7 contains typings generated from externs. - * - * Even though we don't reference the internal Clutz namespace here, we expect - * the output d.ts to have an import to the demo7 file. - */ -export function f6(c: demo7.C) {} diff --git a/test_files/clutz_type_value.no_externs/user.js b/test_files/clutz_type_value.no_externs/user.js index 787b8adab..4128b4022 100644 --- a/test_files/clutz_type_value.no_externs/user.js +++ b/test_files/clutz_type_value.no_externs/user.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This test verifies that a type/value-conflict symbol that * occurs in a clutz file still can be used in a heritage clause. * Generated from: test_files/clutz_type_value.no_externs/user.ts * @suppress {uselessCode} - * */ goog.module('test_files.clutz_type_value.no_externs.user'); var module = module || { id: 'test_files/clutz_type_value.no_externs/user.ts' }; diff --git a/test_files/comments/comments.js b/test_files/comments/comments.js index 943006a73..c234595a9 100644 --- a/test_files/comments/comments.js +++ b/test_files/comments/comments.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/comments/comments.ts * @suppress {uselessCode} - * */ goog.module('test_files.comments.comments'); var module = module || { id: 'test_files/comments/comments.ts' }; diff --git a/test_files/comments/freestanding_jsdoc.js b/test_files/comments/freestanding_jsdoc.js new file mode 100644 index 000000000..3b4fba061 --- /dev/null +++ b/test_files/comments/freestanding_jsdoc.js @@ -0,0 +1,25 @@ +/** + * @fileoverview Tsickle should escape unknown JSDoc tags in comments not + * attached to any particular node. + * Generated from: test_files/comments/freestanding_jsdoc.ts + */ +/** + * \@unknowntag + */ +goog.module('test_files.comments.freestanding_jsdoc'); +var module = module || { id: 'test_files/comments/freestanding_jsdoc.ts' }; +goog.require('tslib'); +/** + * \@unknowntag + */ +class Foo { +} +/** + * \@param a it's a string + */ +/** + * This is "bar". + * @param {string} a + * @return {void} + */ +function bar(a) { } diff --git a/test_files/comments/freestanding_jsdoc.ts b/test_files/comments/freestanding_jsdoc.ts new file mode 100644 index 000000000..ec06f5803 --- /dev/null +++ b/test_files/comments/freestanding_jsdoc.ts @@ -0,0 +1,15 @@ +/** + * @fileoverview Tsickle should escape unknown JSDoc tags in comments not + * attached to any particular node. + */ + +/** @unknowntag */ + +/** @unknowntag */ +class Foo {} + + +/** @param a it's a string */ + +/** This is "bar". */ +function bar(a: string) {} diff --git a/test_files/comments/trailing_no_semicolon.js b/test_files/comments/trailing_no_semicolon.js new file mode 100644 index 000000000..897b2be10 --- /dev/null +++ b/test_files/comments/trailing_no_semicolon.js @@ -0,0 +1,20 @@ +/** + * @fileoverview Tests that the JSDoc comment of `other` is only emitted once. + * Without the trailing semicolon after `noExplicitSemicolon` TypeScript seems + * to duplicate the trailing comment as soon as a custom transformer modifies + * the variable statement. + * Generated from: test_files/comments/trailing_no_semicolon.ts + */ +goog.module('test_files.comments.trailing_no_semicolon'); +var module = module || { id: 'test_files/comments/trailing_no_semicolon.ts' }; +goog.require('tslib'); +/** @type {number} */ +const noExplicitSemicolon = 0; +/** + * This is a comment with a JSDoc tag + * JSCompiler doesn't recognize + * + * \@foobar + * @type {number} + */ +exports.other = 1; diff --git a/test_files/comments/trailing_no_semicolon.ts b/test_files/comments/trailing_no_semicolon.ts new file mode 100644 index 000000000..b68b9844a --- /dev/null +++ b/test_files/comments/trailing_no_semicolon.ts @@ -0,0 +1,17 @@ +/** + * @fileoverview Tests that the JSDoc comment of `other` is only emitted once. + * Without the trailing semicolon after `noExplicitSemicolon` TypeScript seems + * to duplicate the trailing comment as soon as a custom transformer modifies + * the variable statement. + */ + + +const noExplicitSemicolon = 0 + +/** + * This is a comment with a JSDoc tag + * JSCompiler doesn't recognize + * + * @foobar + */ +export const other = 1; diff --git a/test_files/conditional_rest_tuple_type/conditional_rest_tuple_type.js b/test_files/conditional_rest_tuple_type/conditional_rest_tuple_type.js index 3d59702e8..b1d85f603 100644 --- a/test_files/conditional_rest_tuple_type/conditional_rest_tuple_type.js +++ b/test_files/conditional_rest_tuple_type/conditional_rest_tuple_type.js @@ -2,10 +2,8 @@ // test_files/conditional_rest_tuple_type/conditional_rest_tuple_type.ts(8,14): warning TS0: unable to translate rest args type // test_files/conditional_rest_tuple_type/conditional_rest_tuple_type.ts(9,31): warning TS0: failed to resolve rest parameter type, emitting ? /** - * * @fileoverview Tests an interaction between conditional types and rest (...) * types. - * * Generated from: test_files/conditional_rest_tuple_type/conditional_rest_tuple_type.ts */ goog.module('test_files.conditional_rest_tuple_type.conditional_rest_tuple_type'); diff --git a/test_files/ctors/ctors.js b/test_files/ctors/ctors.js index 0b71e35c9..f16e84213 100644 --- a/test_files/ctors/ctors.js +++ b/test_files/ctors/ctors.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/ctors/ctors.ts * @suppress {uselessCode} - * */ goog.module('test_files.ctors.ctors'); var module = module || { id: 'test_files/ctors/ctors.ts' }; diff --git a/test_files/debugger/user.js b/test_files/debugger/user.js index 45bf4e64e..004d4db2e 100644 --- a/test_files/debugger/user.js +++ b/test_files/debugger/user.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/debugger/user.ts * @suppress {checkTypes} - * */ // TODO: the type below should be emitted as `outer.debugger.Foo`. However // TypeScript does not take the re-export in the outer namespace into account, diff --git a/test_files/decl_merge/imported_inner_decl.js b/test_files/decl_merge/imported_inner_decl.js index fbbf4cd3f..7448ae67c 100644 --- a/test_files/decl_merge/imported_inner_decl.js +++ b/test_files/decl_merge/imported_inner_decl.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Ensure transformed inner classes and enums can be * imported and used, and the types are properly annotated in the * JS output. - * * Generated from: test_files/decl_merge/imported_inner_decl.ts */ goog.module('test_files.decl_merge.imported_inner_decl'); diff --git a/test_files/decl_merge/inner_class.js b/test_files/decl_merge/inner_class.js index 2ef74eb06..6e5b4ef81 100644 --- a/test_files/decl_merge/inner_class.js +++ b/test_files/decl_merge/inner_class.js @@ -1,14 +1,12 @@ // test_files/decl_merge/inner_class.ts(49,7): warning TS0: anonymous type has no symbol // test_files/decl_merge/inner_class.ts(51,13): warning TS0: anonymous type has no symbol /** - * * @fileoverview Ensure inner classes defined with declaration merging * are properly transformed and hoisted out of the namespace, and * no iife is created for the namespace. * * Generated from: test_files/decl_merge/inner_class.ts * @suppress {uselessCode,checkTypes} - * */ goog.module('test_files.decl_merge.inner_class'); var module = module || { id: 'test_files/decl_merge/inner_class.ts' }; diff --git a/test_files/decl_merge/inner_enum.js b/test_files/decl_merge/inner_enum.js index 812e0e5f9..6015d193b 100644 --- a/test_files/decl_merge/inner_enum.js +++ b/test_files/decl_merge/inner_enum.js @@ -1,12 +1,10 @@ /** - * * @fileoverview Ensure enums nested in a class, defined with declaration * merging are properly transformed and hoisted out of the namespace, and no * iife is created for the namespace. * * Generated from: test_files/decl_merge/inner_enum.ts * @suppress {uselessCode} - * */ goog.module('test_files.decl_merge.inner_enum'); var module = module || { id: 'test_files/decl_merge/inner_enum.ts' }; diff --git a/test_files/decl_merge/inner_interface.js b/test_files/decl_merge/inner_interface.js index 27d6cb6ba..9db707d05 100644 --- a/test_files/decl_merge/inner_interface.js +++ b/test_files/decl_merge/inner_interface.js @@ -1,12 +1,10 @@ /** - * * @fileoverview Ensure interfaces nested in an outer class or interface, * defined with declaration merging are properly transformed and hoisted out of * the namespace, and no iife is created for the namespace. * * Generated from: test_files/decl_merge/inner_interface.ts * @suppress {uselessCode} - * */ goog.module('test_files.decl_merge.inner_interface'); var module = module || { id: 'test_files/decl_merge/inner_interface.ts' }; @@ -54,7 +52,10 @@ if (false) { */ OC$I.prototype.bar = function (e) { }; } -/** @const */ +/** + * Bla interface + * @const + */ OC.I = OC$I; /** * @record @@ -81,14 +82,19 @@ const OI$E = { }; OI$E[OI$E.a] = 'a'; OI$E[OI$E.b] = 'b'; -/** @const */ +/** + * Bla enum + * @const + */ OI.E = OI$E; /** @const */ OI.C1 = 0; /** @const */ OI.C2 = 'string const'; -/** Bla const */ -/** @const */ +/** + * Bla const + * @const + */ OI.C3 = OI.E.a; /** * @param {!OC.J} j diff --git a/test_files/decl_merge/inner_interface.ts b/test_files/decl_merge/inner_interface.ts index 6a3943e5a..5e6d86478 100644 --- a/test_files/decl_merge/inner_interface.ts +++ b/test_files/decl_merge/inner_interface.ts @@ -39,4 +39,4 @@ function f(j: OC.J) { function g(): OI.E { return OI.E.a; -} \ No newline at end of file +} diff --git a/test_files/decl_merge/inner_typedef.js b/test_files/decl_merge/inner_typedef.js index 763f42800..54d300d34 100644 --- a/test_files/decl_merge/inner_typedef.js +++ b/test_files/decl_merge/inner_typedef.js @@ -1,11 +1,9 @@ /** - * * @fileoverview Ensure that a type alias declared in a declaration * merging namespace is generated as a property of the merged outer class. * * Generated from: test_files/decl_merge/inner_typedef.ts * @suppress {uselessCode,checkTypes} - * */ goog.module('test_files.decl_merge.inner_typedef'); var module = module || { id: 'test_files/decl_merge/inner_typedef.ts' }; diff --git a/test_files/decl_merge/outer_enum.js b/test_files/decl_merge/outer_enum.js new file mode 100644 index 000000000..8b7382f4c --- /dev/null +++ b/test_files/decl_merge/outer_enum.js @@ -0,0 +1,29 @@ +/** + * @fileoverview Ensure that a function declared in a declaration + * merging namespace is generated as a property of the merged outer enum. + * + * Generated from: test_files/decl_merge/outer_enum.ts + * @suppress {uselessCode,checkTypes} + */ +goog.module('test_files.decl_merge.outer_enum'); +var module = module || { id: 'test_files/decl_merge/outer_enum.ts' }; +goog.require('tslib'); +/** @enum {number} */ +const E = { + a: 42, + b: 43, +}; +exports.E = E; +E[E.a] = 'a'; +E[E.b] = 'b'; +/** + * @param {string} s + * @return {!E} + */ +function E$fromString(s) { + return s === 'a' ? E.a : E.b; +} +/** @const */ +E.fromString = E$fromString; +/** @type {!E} */ +const e = E.fromString('a'); diff --git a/test_files/decl_merge/outer_enum.ts b/test_files/decl_merge/outer_enum.ts new file mode 100644 index 000000000..b89996cc3 --- /dev/null +++ b/test_files/decl_merge/outer_enum.ts @@ -0,0 +1,20 @@ +/** + * @fileoverview Ensure that a function declared in a declaration + * merging namespace is generated as a property of the merged outer enum. + * + * @suppress {uselessCode,checkTypes} + */ + +export enum E { + a = 42, + b +} + +// tslint:disable-next-line:no-namespace +export namespace E { + export function fromString(s: string) { + return s === 'a' ? E.a : E.b; + }; +} + +const e = E.fromString('a'); diff --git a/test_files/decl_merge/rejected_ns.js b/test_files/decl_merge/rejected_ns.js index 54aa1d565..566444941 100644 --- a/test_files/decl_merge/rejected_ns.js +++ b/test_files/decl_merge/rejected_ns.js @@ -1,20 +1,19 @@ -// test_files/decl_merge/rejected_ns.ts(34,1): warning TS0: type/symbol conflict for Inbetween, using {?} for now +// test_files/decl_merge/rejected_ns.ts(32,1): warning TS0: type/symbol conflict for Inbetween, using {?} for now // test_files/decl_merge/rejected_ns.ts(9,11): error TS0: transformation of plain namespace not supported. (go/ts-merged-namespaces) -// test_files/decl_merge/rejected_ns.ts(13,11): error TS0: merged declaration must be local class or interface. (go/ts-merged-namespaces) -// test_files/decl_merge/rejected_ns.ts(21,11): error TS0: merged declaration must be local class or interface. (go/ts-merged-namespaces) -// test_files/decl_merge/rejected_ns.ts(26,3): error TS0: const declaration only allowed when merging with an interface (go/ts-merged-namespaces) -// test_files/decl_merge/rejected_ns.ts(38,3): error TS0: non-const values are not supported. (go/ts-merged-namespaces) -// test_files/decl_merge/rejected_ns.ts(40,9): error TS0: 'K' must be exported. (go/ts-merged-namespaces) -// test_files/decl_merge/rejected_ns.ts(42,16): error TS0: Destructuring declarations are not supported. (go/ts-merged-namespaces) -// test_files/decl_merge/rejected_ns.ts(47,11): error TS0: nested namespaces are not supported. (go/ts-merged-namespaces) +// test_files/decl_merge/rejected_ns.ts(13,11): error TS0: merged declaration must be local class, enum, or interface. (go/ts-merged-namespaces) +// test_files/decl_merge/rejected_ns.ts(19,3): error TS0: const declaration only allowed when merging with an interface (go/ts-merged-namespaces) +// test_files/decl_merge/rejected_ns.ts(24,3): error TS0: function declaration only allowed when merging with an enum (go/ts-merged-namespaces) +// test_files/decl_merge/rejected_ns.ts(36,3): error TS0: non-const values are not supported. (go/ts-merged-namespaces) +// test_files/decl_merge/rejected_ns.ts(38,9): error TS0: 'K' must be exported. (go/ts-merged-namespaces) +// test_files/decl_merge/rejected_ns.ts(40,16): error TS0: Destructuring declarations are not supported. (go/ts-merged-namespaces) +// test_files/decl_merge/rejected_ns.ts(44,3): error TS0: function declaration only allowed when merging with an enum (go/ts-merged-namespaces) +// test_files/decl_merge/rejected_ns.ts(48,11): error TS0: nested namespaces are not supported. (go/ts-merged-namespaces) /** - * * @fileoverview Test namespace transformations that are not supported * and result in compiler errors. * * Generated from: test_files/decl_merge/rejected_ns.ts * @suppress {uselessCode,checkTypes} - * */ goog.module('test_files.decl_merge.rejected_ns'); var module = module || { id: 'test_files/decl_merge/rejected_ns.ts' }; @@ -24,21 +23,21 @@ goog.require('tslib'); * @return {void} */ function funcToBeMerged() { } -/** @enum {number} */ -const Colors = { - red: 0, - green: 1, - blue: 2, -}; -Colors[Colors.red] = 'red'; -Colors[Colors.green] = 'green'; -Colors[Colors.blue] = 'blue'; // Adding const values is only allowed on interfaces. class Cabbage { } (function (Cabbage) { Cabbage.C = 0; })(Cabbage || (Cabbage = {})); +// Adding functions is only allowed on enums. +(function (Cabbage) { + /** + * @return {void} + */ + function foo() { } + Cabbage.foo = foo; + ; +})(Cabbage || (Cabbage = {})); /** @type {{a: number, b: string}} */ const o = { a: 0, @@ -60,6 +59,13 @@ var Inbetween; // Destructuring declarations are not allowed. Inbetween.a = o.a, Inbetween.b = o.b; })(Inbetween || (Inbetween = {})); +(function (Inbetween) { + /** + * @return {void} + */ + function foo() { } + Inbetween.foo = foo; +})(Inbetween || (Inbetween = {})); // Nested namespaces are not supported. class A { } diff --git a/test_files/decl_merge/rejected_ns.ts b/test_files/decl_merge/rejected_ns.ts index 2e414d803..fdb0df004 100644 --- a/test_files/decl_merge/rejected_ns.ts +++ b/test_files/decl_merge/rejected_ns.ts @@ -12,13 +12,6 @@ namespace notMerging {} function funcToBeMerged() {} namespace funcToBeMerged {} -// Declaration merging with enums is not supported. -enum Colors { - red, - green, - blue -} -namespace Colors {} // Adding const values is only allowed on interfaces. class Cabbage {} @@ -26,6 +19,11 @@ namespace Cabbage { export const C = 0; } +// Adding functions is only allowed on enums. +namespace Cabbage { + export function foo() {}; +} + const o = { a: 0, b: '' @@ -42,6 +40,9 @@ namespace Inbetween { export const {a, b} = o; } +namespace Inbetween { + export function foo() {} +} // Nested namespaces are not supported. class A {} namespace A.B {} diff --git a/test_files/declare_export/declare_export.js b/test_files/declare_export/declare_export.js index fb7dc47dd..d73c4759c 100644 --- a/test_files/declare_export/declare_export.js +++ b/test_files/declare_export/declare_export.js @@ -1,7 +1,3 @@ -/** - * @fileoverview added by tsickle - * Generated from: test_files/declare_export/declare_export.ts - */ // All of the types/values declared in this file should // 1) generate externs // 2) generate an export @@ -12,6 +8,10 @@ // should be namespaced into a private namespace. // E.g. "export declare interface Error" should not conflict with the // Closure builtin Error type. +/** + * @fileoverview added by tsickle + * Generated from: test_files/declare_export/declare_export.ts + */ goog.module('test_files.declare_export.declare_export'); var module = module || { id: 'test_files/declare_export/declare_export.ts' }; goog.require('tslib'); diff --git a/test_files/declare_export_dts/user.js b/test_files/declare_export_dts/user.js index 8b7f2fa28..c46edcc05 100644 --- a/test_files/declare_export_dts/user.js +++ b/test_files/declare_export_dts/user.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/declare_export_dts/user.ts * @suppress {checkTypes} - * */ goog.module('test_files.declare_export_dts.user'); var module = module || { id: 'test_files/declare_export_dts/user.ts' }; diff --git a/test_files/declare_import/declare_import_in_ts.js b/test_files/declare_import/declare_import_in_ts.js index 1ab369a39..8334701d8 100644 --- a/test_files/declare_import/declare_import_in_ts.js +++ b/test_files/declare_import/declare_import_in_ts.js @@ -4,13 +4,11 @@ // test_files/declare_import/declare_import_in_ts.ts(22,1): warning TS0: dropped extends: {?} type // test_files/declare_import/declare_import_in_ts.ts(25,1): warning TS0: dropped extends: {?} type /** - * * @fileoverview Tests that imports in .ts resolve to the correct result names. See externs.ts * addImportAliases. * * The code below tests mixing symbols from .d.ts and .ts files, to make sure type references are * uniformly generated. - * * Generated from: test_files/declare_import/declare_import_in_ts.ts */ goog.module('test_files.declare_import.declare_import_in_ts'); diff --git a/test_files/declare_var_and_ns/externs.js b/test_files/declare_var_and_ns/externs.js index eb909e167..9b522a4c1 100644 --- a/test_files/declare_var_and_ns/externs.js +++ b/test_files/declare_var_and_ns/externs.js @@ -6,8 +6,6 @@ // Generated from: test_files/declare_var_and_ns/declare_var_and_ns.d.ts /** @type {!globalVariable.SomeInterface} */ var globalVariable; -/** @const */ -var globalVariable = {}; /** * @record * @struct diff --git a/test_files/decorator/decorator.js b/test_files/decorator/decorator.js index d378afbf4..d3e726cdd 100644 --- a/test_files/decorator/decorator.js +++ b/test_files/decorator/decorator.js @@ -4,14 +4,12 @@ var module = module || { id: 'test_files/decorator/decorator.ts' }; const tslib_1 = goog.require('tslib'); const __tsickle_googReflect = goog.require("goog.reflect"); /** - * * @fileoverview OtherClass is reachable via the imports for './external' and * './external2'. Test that were using it from the right import, and not just * the first that allows access to the value. That is important when imports are * elided. * Generated from: test_files/decorator/decorator.ts * @suppress {uselessCode} - * */ const tsickle_default_export_1 = goog.requireType("test_files.decorator.default_export"); const tsickle_external_2 = goog.requireType("test_files.decorator.external"); diff --git a/test_files/decorator/default_export.js b/test_files/decorator/default_export.js index d2580a9bc..cf42cd7e1 100644 --- a/test_files/decorator/default_export.js +++ b/test_files/decorator/default_export.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Tests using a default imported class for in a decorated ctor. * Generated from: test_files/decorator/default_export.ts * @suppress {uselessCode} - * */ goog.module('test_files.decorator.default_export'); var module = module || { id: 'test_files/decorator/default_export.ts' }; diff --git a/test_files/decorator/export_const.js b/test_files/decorator/export_const.js index 7244ec0c9..533749b16 100644 --- a/test_files/decorator/export_const.js +++ b/test_files/decorator/export_const.js @@ -3,10 +3,8 @@ goog.module('test_files.decorator.export_const'); var module = module || { id: 'test_files/decorator/export_const.ts' }; const tslib_1 = goog.require('tslib'); /** - * * @fileoverview Decorated class, whose type and value are exported separately. * The value used afterwards. - * * Generated from: test_files/decorator/export_const.ts */ /** diff --git a/test_files/decorator/only_types.js b/test_files/decorator/only_types.js index 0d51e5b62..dec44532f 100644 --- a/test_files/decorator/only_types.js +++ b/test_files/decorator/only_types.js @@ -1,10 +1,8 @@ /** - * * @fileoverview only_types only exports types, so TypeScript will elide the * import entirely. * Generated from: test_files/decorator/only_types.ts * @suppress {uselessCode} - * */ goog.module('test_files.decorator.only_types'); var module = module || { id: 'test_files/decorator/only_types.ts' }; diff --git a/test_files/doc_params/doc_params.js b/test_files/doc_params/doc_params.js index 9550608d8..0b4ba83b3 100644 --- a/test_files/doc_params/doc_params.js +++ b/test_files/doc_params/doc_params.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/doc_params/doc_params.ts * @suppress {uselessCode} - * */ goog.module('test_files.doc_params.doc_params'); var module = module || { id: 'test_files/doc_params/doc_params.ts' }; diff --git a/test_files/docs_on_ctor_param_properties/docs_on_ctor_param_properties.js b/test_files/docs_on_ctor_param_properties/docs_on_ctor_param_properties.js index f0a2b8095..22a62f359 100644 --- a/test_files/docs_on_ctor_param_properties/docs_on_ctor_param_properties.js +++ b/test_files/docs_on_ctor_param_properties/docs_on_ctor_param_properties.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/docs_on_ctor_param_properties/docs_on_ctor_param_properties.ts * @suppress {uselessCode} - * */ goog.module('test_files.docs_on_ctor_param_properties.docs_on_ctor_param_properties'); var module = module || { id: 'test_files/docs_on_ctor_param_properties/docs_on_ctor_param_properties.ts' }; diff --git a/test_files/enum.no_nstransform/enum.js b/test_files/enum.no_nstransform/enum.js new file mode 100644 index 000000000..c30ae982f --- /dev/null +++ b/test_files/enum.no_nstransform/enum.js @@ -0,0 +1,40 @@ +/** + * @fileoverview Check that enums are translated to a var declaration + * when namespace transformation is turned off, i.e. the build target + * has the attribute --allow_unoptimized_namespaces. + * Generated from: test_files/enum.no_nstransform/enum.ts + * @suppress {checkTypes,uselessCode} + */ +goog.module('test_files.enum.no_nstransform.enum'); +var module = module || { id: 'test_files/enum.no_nstransform/enum.ts' }; +goog.require('tslib'); +/** + * This enum should be translated to `var E = {...}` instead of the usual + * `const E = {...}` + * @enum {number} + */ +var E = { + e0: 0, + e1: 1, + e2: 2, +}; +exports.E = E; +E[E.e0] = 'e0'; +E[E.e1] = 'e1'; +E[E.e2] = 'e2'; +// We need to emit the enum as a var declaration so that declaration +// merging with a namespace works. The unoptimized namespace is emitted +// by tsc as a var declaration and an IIFE. +var E; +(function (E) { + /** + * @param {string} s + * @return {?} + */ + function fromString(s) { + return E.e0; + } + E.fromString = fromString; +})(E || (E = {})); +/** @type {!E} */ +const foo = E.e2; diff --git a/test_files/enum.no_nstransform/enum.ts b/test_files/enum.no_nstransform/enum.ts new file mode 100644 index 000000000..4f829e1d3 --- /dev/null +++ b/test_files/enum.no_nstransform/enum.ts @@ -0,0 +1,27 @@ +/** + * @fileoverview Check that enums are translated to a var declaration + * when namespace transformation is turned off, i.e. the build target + * has the attribute --allow_unoptimized_namespaces. + * @suppress {checkTypes,uselessCode} + */ + +/** + * This enum should be translated to `var E = {...}` instead of the usual + * `const E = {...}` + */ +export enum E { + e0 = 0, + e1, + e2 +} + +// We need to emit the enum as a var declaration so that declaration +// merging with a namespace works. The unoptimized namespace is emitted +// by tsc as a var declaration and an IIFE. +export namespace E { + export function fromString(s: string) { + return E.e0; + } +} + +const foo = E.e2; diff --git a/test_files/enum.puretransform/enum.js b/test_files/enum.puretransform/enum.js new file mode 100644 index 000000000..b0a8c2eb8 --- /dev/null +++ b/test_files/enum.puretransform/enum.js @@ -0,0 +1,21 @@ +/** + * @fileoverview Test devmode (i.e. no JSDoc or special enum transformer) emit + * for enum merged with namespace. + * @suppress {missingProperties} + */ +goog.module('test_files.enum.puretransform.enum'); +var module = module || { id: 'test_files/enum.puretransform/enum.ts' }; +goog.require('tslib'); +var E; +(function (E) { + E[E["e0"] = 0] = "e0"; + E[E["e1"] = 1] = "e1"; + E[E["e2"] = 2] = "e2"; +})(E || (E = {})); +exports.E = E; +(function (E) { + function fromString(s) { + return E.e0; + } + E.fromString = fromString; +})(E || (E = {})); diff --git a/test_files/enum.puretransform/enum.ts b/test_files/enum.puretransform/enum.ts new file mode 100644 index 000000000..ecca84131 --- /dev/null +++ b/test_files/enum.puretransform/enum.ts @@ -0,0 +1,17 @@ +/** + * @fileoverview Test devmode (i.e. no JSDoc or special enum transformer) emit + * for enum merged with namespace. + * @suppress {missingProperties} + */ + +export enum E { + e0 = 0, + e1, + e2 +} + +export namespace E { + export function fromString(s: string) { + return E.e0; + } +} diff --git a/test_files/enum/enum.js b/test_files/enum/enum.js index 8041302d5..c42c2a62a 100644 --- a/test_files/enum/enum.js +++ b/test_files/enum/enum.js @@ -1,11 +1,9 @@ // test_files/enum/enum.ts(7,7): warning TS0: should not emit a 'never' type /** - * * @fileoverview Line with a missing semicolon should not break the following * enum. * Generated from: test_files/enum/enum.ts * @suppress {checkTypes,uselessCode} - * */ goog.module('test_files.enum.enum'); var module = module || { id: 'test_files/enum/enum.ts' }; @@ -57,7 +55,8 @@ let variableUsingExportedEnum; const ComponentIndex = { Scheme: 1, UserInfo: 2, - Domain: 0, + // TODO: b/313666408 - Fix tsc to not duplicate comments like the following + Domain: 0, // Be sure to exercise the code with a 0 enum value. // Be sure to exercise the code with a 0 enum value. UserInfo2: 2, }; diff --git a/test_files/enum/enum.ts b/test_files/enum/enum.ts index 8f913933b..b070ff424 100644 --- a/test_files/enum/enum.ts +++ b/test_files/enum/enum.ts @@ -36,6 +36,7 @@ let variableUsingExportedEnum: EnumTest2; enum ComponentIndex { Scheme = 1, UserInfo, + // TODO: b/313666408 - Fix tsc to not duplicate comments like the following Domain = 0, // Be sure to exercise the code with a 0 enum value. UserInfo2 = UserInfo, } diff --git a/test_files/enum/enum_user.js b/test_files/enum/enum_user.js index d2643c681..f96d6f479 100644 --- a/test_files/enum/enum_user.js +++ b/test_files/enum/enum_user.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/enum/enum_user.ts * @suppress {checkTypes,uselessCode} - * */ goog.module('test_files.enum.enum_user'); var module = module || { id: 'test_files/enum/enum_user.ts' }; diff --git a/test_files/enum_ref_import/enum_ref_import.js b/test_files/enum_ref_import/enum_ref_import.js index 9c49024bb..2c33c6ac1 100644 --- a/test_files/enum_ref_import/enum_ref_import.js +++ b/test_files/enum_ref_import/enum_ref_import.js @@ -1,5 +1,4 @@ /** - * * @fileoverview TypeScript statically resolves enum member values to constants, * if possible, and directly emits those constants. Because of this, TS should * elide any imports for modules referenced in the expressions of such constant @@ -12,7 +11,6 @@ * (`var ValuesInInitializer = {ENUM_MEMBER: "x"}`), TypeScript no longer elides * the import (for `Enum` here). Thus we emit code that has an unncessary * import. - * * Generated from: test_files/enum_ref_import/enum_ref_import.ts */ goog.module('test_files.enum_ref_import.enum_ref_import'); diff --git a/test_files/enum_value_literal_type/enum_value_literal_type.js b/test_files/enum_value_literal_type/enum_value_literal_type.js index 5b9520ef5..4ea9c7a03 100644 --- a/test_files/enum_value_literal_type/enum_value_literal_type.js +++ b/test_files/enum_value_literal_type/enum_value_literal_type.js @@ -1,11 +1,11 @@ -/** - * @fileoverview added by tsickle - * Generated from: test_files/enum_value_literal_type/enum_value_literal_type.ts - */ // Note: if you only have one value in the enum, then the type of "x" below // is just ExportedEnum, regardless of the annotation. This might be a bug // in TypeScript but this test is just trying to verify the behavior of // exporting an enum's value, not that. +/** + * @fileoverview added by tsickle + * Generated from: test_files/enum_value_literal_type/enum_value_literal_type.ts + */ goog.module('test_files.enum_value_literal_type.enum_value_literal_type'); var module = module || { id: 'test_files/enum_value_literal_type/enum_value_literal_type.ts' }; goog.require('tslib'); diff --git a/test_files/eventmap/eventmap.js b/test_files/eventmap/eventmap.js index 3e94f5787..993d6b368 100644 --- a/test_files/eventmap/eventmap.js +++ b/test_files/eventmap/eventmap.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/eventmap/eventmap.ts * @suppress {checkTypes} - * */ goog.module('test_files.eventmap.eventmap'); var module = module || { id: 'test_files/eventmap/eventmap.ts' }; diff --git a/test_files/export/export.js b/test_files/export/export.js index 614faff4b..85df4d44b 100644 --- a/test_files/export/export.js +++ b/test_files/export/export.js @@ -21,6 +21,8 @@ exports.RenamedTypeDef; // re-export typedef exports.TypeDef; // re-export typedef /** @typedef {!tsickle_export_helper_1.Interface} */ exports.Interface; // re-export typedef +/** @typedef {!tsickle_export_helper_1.ConstEnum} */ +exports.ConstEnum; // re-export typedef /** @typedef {!tsickle_export_helper_1.DeclaredType} */ exports.DeclaredType; // re-export typedef /** @typedef {!tsickle_export_helper_1.DeclaredInterface} */ diff --git a/test_files/export/export_helper.js b/test_files/export/export_helper.js index 5cad2eee1..952036917 100644 --- a/test_files/export/export_helper.js +++ b/test_files/export/export_helper.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This file isn't itself a test case, but it is imported by the * export.in.ts test case. * Generated from: test_files/export/export_helper.ts * @suppress {uselessCode} - * */ goog.module('test_files.export.export_helper'); var module = module || { id: 'test_files/export/export_helper.ts' }; @@ -16,6 +14,8 @@ exports.export4 = export_helper_2_1.export4; exports.TypeDef; // re-export typedef /** @typedef {!tsickle_export_helper_2_1.Interface} */ exports.Interface; // re-export typedef +/** @typedef {!tsickle_export_helper_2_1.ConstEnum} */ +exports.ConstEnum; // re-export typedef /** @typedef {!tsickle_export_helper_2_1.DeclaredType} */ exports.DeclaredType; // re-export typedef /** @typedef {!tsickle_export_helper_2_1.DeclaredInterface} */ diff --git a/test_files/export/export_helper_2.js b/test_files/export/export_helper_2.js index 3359e9128..e90e5fafd 100644 --- a/test_files/export/export_helper_2.js +++ b/test_files/export/export_helper_2.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This file isn't itself a test case, but it is imported by the * export.in.ts test case. * Generated from: test_files/export/export_helper_2.ts * @suppress {uselessCode} - * */ goog.module('test_files.export.export_helper_2'); var module = module || { id: 'test_files/export/export_helper_2.ts' }; diff --git a/test_files/export/export_helper_3.js b/test_files/export/export_helper_3.js index d63681078..8bd165acb 100644 --- a/test_files/export/export_helper_3.js +++ b/test_files/export/export_helper_3.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This file isn't itself a test case, but it is imported by the * export.in.ts test case. * Generated from: test_files/export/export_helper_3.ts * @suppress {uselessCode} - * */ goog.module('test_files.export.export_helper_3'); var module = module || { id: 'test_files/export/export_helper_3.ts' }; diff --git a/test_files/export/export_star_imported.js b/test_files/export/export_star_imported.js index 574f72e86..5e1db0dc0 100644 --- a/test_files/export/export_star_imported.js +++ b/test_files/export/export_star_imported.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/export/export_star_imported.ts * @suppress {checkTypes} - * */ goog.module('test_files.export.export_star_imported'); var module = module || { id: 'test_files/export/export_star_imported.ts' }; @@ -22,6 +20,8 @@ exports.RenamedTypeDef; // re-export typedef exports.TypeDef; // re-export typedef /** @typedef {!tsickle_export_helper_1.Interface} */ exports.Interface; // re-export typedef +/** @typedef {!tsickle_export_helper_1.ConstEnum} */ +exports.ConstEnum; // re-export typedef /** @typedef {!tsickle_export_helper_1.DeclaredType} */ exports.DeclaredType; // re-export typedef /** @typedef {!tsickle_export_helper_1.DeclaredInterface} */ diff --git a/test_files/export_declare_namespace/user.js b/test_files/export_declare_namespace/user.js index da3f9b82b..3daabba18 100644 --- a/test_files/export_declare_namespace/user.js +++ b/test_files/export_declare_namespace/user.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/export_declare_namespace/user.ts * @suppress {checkTypes} - * */ goog.module('test_files.export_declare_namespace.user'); var module = module || { id: 'test_files/export_declare_namespace/user.ts' }; diff --git a/test_files/export_destructuring/export_destructuring.js b/test_files/export_destructuring/export_destructuring.js new file mode 100644 index 000000000..5958c9f94 --- /dev/null +++ b/test_files/export_destructuring/export_destructuring.js @@ -0,0 +1,28 @@ +goog.module('test_files.export_destructuring.export_destructuring'); +var module = module || { id: 'test_files/export_destructuring/export_destructuring.ts' }; +goog.require('tslib'); +var _a; +/** + * @fileoverview added by tsickle + * Generated from: test_files/export_destructuring/export_destructuring.ts + */ +/** + * @param {number} n + * @return {!Array} + */ +function signal(n) { + return [n, n + 1]; +} +/** + * @param {number} n + * @return {{c: number, d: number}} + */ +function objectLiteral(n) { + return { c: n, d: n + 1 }; +} +const [a__tsickle_destructured_1, b__tsickle_destructured_2] = signal(0); +exports.a = /** @type {number} */ (a__tsickle_destructured_1); +exports.b = /** @type {number} */ (b__tsickle_destructured_2); +_a = objectLiteral(0); +exports.c = _a.c; +exports.d = _a.d; diff --git a/test_files/export_destructuring/export_destructuring.ts b/test_files/export_destructuring/export_destructuring.ts new file mode 100644 index 000000000..87fcaff10 --- /dev/null +++ b/test_files/export_destructuring/export_destructuring.ts @@ -0,0 +1,11 @@ + +function signal(n: number) { + return [n, n + 1]; +} +function objectLiteral(n: number) { + return {c: n, d: n + 1}; +} + +export const [a, b] = signal(0); + +export const {c, d} = objectLiteral(0); diff --git a/test_files/export_local_type/export_local_type.js b/test_files/export_local_type/export_local_type.js index 704f40282..6f7c38b58 100644 --- a/test_files/export_local_type/export_local_type.js +++ b/test_files/export_local_type/export_local_type.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Regression test to ensure local type symbols can be exported. * Generated from: test_files/export_local_type/export_local_type.ts * @suppress {uselessCode} - * */ goog.module('test_files.export_local_type.export_local_type'); var module = module || { id: 'test_files/export_local_type/export_local_type.ts' }; diff --git a/test_files/export_merged/main.js b/test_files/export_merged/main.js index f288445ac..9d4512e1c 100644 --- a/test_files/export_merged/main.js +++ b/test_files/export_merged/main.js @@ -1,11 +1,9 @@ /** - * * @fileoverview Test to ensure that only one assignment to * `exports.A` is emitted when A is a namespace with merged declarations. * Tsickle eliminates the second assignment. * Generated from: test_files/export_merged/main.ts * @suppress {checkTypes} - * */ goog.module('test_files.export_merged.main'); var module = module || { id: 'test_files/export_merged/main.ts' }; diff --git a/test_files/export_multi/export_multi.js b/test_files/export_multi/export_multi.js index 8d99eb867..5d15c4896 100644 --- a/test_files/export_multi/export_multi.js +++ b/test_files/export_multi/export_multi.js @@ -3,10 +3,8 @@ var module = module || { id: 'test_files/export_multi/export_multi.ts' }; goog.require('tslib'); var _a, _b; /** - * * @fileoverview Some export forms that create multi-expression 'export' * statements, which are illegal under Closure and must be rewritten. - * * Generated from: test_files/export_multi/export_multi.ts */ /** @enum {string} */ diff --git a/test_files/export_star_as_ns/star_as_ns.js b/test_files/export_star_as_ns/star_as_ns.js index b76ac41a1..37e558ac2 100644 --- a/test_files/export_star_as_ns/star_as_ns.js +++ b/test_files/export_star_as_ns/star_as_ns.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Tests exporting a namespace with a given name from Closure. This doesn't expand * each export like the `export * from '...'` syntax, so it's output just an assignment of the * imported module to a property on `exports`. - * * Generated from: test_files/export_star_as_ns/star_as_ns.ts */ goog.module('test_files.export_star_as_ns.star_as_ns'); diff --git a/test_files/exporting_decorator/exporting.js b/test_files/exporting_decorator/exporting.js index 508e77404..a9c9a8f30 100644 --- a/test_files/exporting_decorator/exporting.js +++ b/test_files/exporting_decorator/exporting.js @@ -3,11 +3,9 @@ var module = module || { id: 'test_files/exporting_decorator/exporting.ts' }; const tslib_1 = goog.require('tslib'); const __tsickle_googReflect = goog.require("goog.reflect"); /** - * * @fileoverview * Generated from: test_files/exporting_decorator/exporting.ts * @suppress {uselessCode} - * */ /** * \@ExportDecoratedItems diff --git a/test_files/extend_and_implement/extend_and_implement.js b/test_files/extend_and_implement/extend_and_implement.js index da6b18cee..1f5e862a2 100644 --- a/test_files/extend_and_implement/extend_and_implement.js +++ b/test_files/extend_and_implement/extend_and_implement.js @@ -1,12 +1,10 @@ // test_files/extend_and_implement/extend_and_implement.ts(16,1): warning TS0: dropped implements: cannot implements a class /** - * * @fileoverview Reproduces a problem where tsickle would emit "\\@extends * {ClassInImplements}", conflicting the ES6 extends syntax, leading to * incorrect optimization results. * Generated from: test_files/extend_and_implement/extend_and_implement.ts * @suppress {uselessCode} - * */ goog.module('test_files.extend_and_implement.extend_and_implement'); var module = module || { id: 'test_files/extend_and_implement/extend_and_implement.ts' }; diff --git a/test_files/fields/fields.js b/test_files/fields/fields.js index ce105e3ef..ff99fe59a 100644 --- a/test_files/fields/fields.js +++ b/test_files/fields/fields.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/fields/fields.ts * @suppress {uselessCode} - * */ goog.module('test_files.fields.fields'); var module = module || { id: 'test_files/fields/fields.ts' }; diff --git a/test_files/fields_no_ctor/fields_no_ctor.js b/test_files/fields_no_ctor/fields_no_ctor.js index b82bd65b9..4b5b53fd9 100644 --- a/test_files/fields_no_ctor/fields_no_ctor.js +++ b/test_files/fields_no_ctor/fields_no_ctor.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/fields_no_ctor/fields_no_ctor.ts * @suppress {uselessCode} - * */ goog.module('test_files.fields_no_ctor.fields_no_ctor'); var module = module || { id: 'test_files/fields_no_ctor/fields_no_ctor.ts' }; diff --git a/test_files/file_comment/before_import.js b/test_files/file_comment/before_import.js index d34e74f12..8a7bb01ca 100644 --- a/test_files/file_comment/before_import.js +++ b/test_files/file_comment/before_import.js @@ -1,9 +1,7 @@ /** - * * @fileoverview fileoverview comment before import. transformer_util.ts has * special logic to handle comments before import/require() calls. This file * tests the regular import case. - * * Generated from: test_files/file_comment/before_import.ts */ goog.module('test_files.file_comment.before_import'); diff --git a/test_files/file_comment/comment_before_class.js b/test_files/file_comment/comment_before_class.js index 97cdbc3fc..81cc56706 100644 --- a/test_files/file_comment/comment_before_class.js +++ b/test_files/file_comment/comment_before_class.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Class handling code does not special cases comments preceding * it before its JSDoc block. This comment would not get emitted if detached * source file comments were not emitted separately. - * * Generated from: test_files/file_comment/comment_before_class.ts */ goog.module('test_files.file_comment.comment_before_class'); diff --git a/test_files/file_comment/comment_before_elided_import.js b/test_files/file_comment/comment_before_elided_import.js index e3518f9a9..fe127f4d8 100644 --- a/test_files/file_comment/comment_before_elided_import.js +++ b/test_files/file_comment/comment_before_elided_import.js @@ -1,8 +1,6 @@ /** - * * @fileoverview This is a comment before an import, where the import will be elided but the comment * must be kept. - * * Generated from: test_files/file_comment/comment_before_elided_import.ts */ goog.module('test_files.file_comment.comment_before_elided_import'); diff --git a/test_files/file_comment/comment_before_var.js b/test_files/file_comment/comment_before_var.js index 9c8295ad5..331913513 100644 --- a/test_files/file_comment/comment_before_var.js +++ b/test_files/file_comment/comment_before_var.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This comment must not be emitted twice. * Generated from: test_files/file_comment/comment_before_var.ts * @mods {google3.java.com.google.javascript.typescript.examples.boqui.boqui} * @modName {foobar} - * */ goog.module('test_files.file_comment.comment_before_var'); var module = module || { id: 'test_files/file_comment/comment_before_var.ts' }; diff --git a/test_files/file_comment/comment_no_tag.js b/test_files/file_comment/comment_no_tag.js index 67ed9dfdc..b18d7621d 100644 --- a/test_files/file_comment/comment_no_tag.js +++ b/test_files/file_comment/comment_no_tag.js @@ -1,8 +1,10 @@ +/** + * A comment without any tags. + */ /** * @fileoverview added by tsickle * Generated from: test_files/file_comment/comment_no_tag.ts */ -/** A comment without any tags. */ // here comes code. goog.module('test_files.file_comment.comment_no_tag'); var module = module || { id: 'test_files/file_comment/comment_no_tag.ts' }; diff --git a/test_files/file_comment/comment_with_text.js b/test_files/file_comment/comment_with_text.js index 8d30d2133..7271aeb4c 100644 --- a/test_files/file_comment/comment_with_text.js +++ b/test_files/file_comment/comment_with_text.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/file_comment/comment_with_text.ts * @suppress {undefinedVars} because we don't like them errors - * */ goog.module('test_files.file_comment.comment_with_text'); var module = module || { id: 'test_files/file_comment/comment_with_text.ts' }; diff --git a/test_files/file_comment/export_star.js b/test_files/file_comment/export_star.js index b40bb7c13..93a879b4f 100644 --- a/test_files/file_comment/export_star.js +++ b/test_files/file_comment/export_star.js @@ -1,9 +1,7 @@ /** - * * @fileoverview fileoverview comment before export. transformer_util.ts has * special logic to handle comments before import/require() calls. This file * tests the export * case. - * * Generated from: test_files/file_comment/export_star.ts */ goog.module('test_files.file_comment.export_star'); diff --git a/test_files/file_comment/fileoverview_comment_add_suppress_before_license.js b/test_files/file_comment/fileoverview_comment_add_suppress_before_license.js index 55497bb9d..7fe31d22e 100644 --- a/test_files/file_comment/fileoverview_comment_add_suppress_before_license.js +++ b/test_files/file_comment/fileoverview_comment_add_suppress_before_license.js @@ -1,11 +1,9 @@ /** - * * @fileoverview a comment with a license tag. * * Generated from: test_files/file_comment/fileoverview_comment_add_suppress_before_license.ts * @license * Some license - * */ // here comes code. goog.module('test_files.file_comment.fileoverview_comment_add_suppress_before_license'); diff --git a/test_files/file_comment/fileoverview_comment_merge_suppress.js b/test_files/file_comment/fileoverview_comment_merge_suppress.js index 6d7e30ea7..94e1afbb8 100644 --- a/test_files/file_comment/fileoverview_comment_merge_suppress.js +++ b/test_files/file_comment/fileoverview_comment_merge_suppress.js @@ -1,11 +1,11 @@ /** - * * @fileoverview Tests merging JSDoc tags in fileoverview comments. * Generated from: test_files/file_comment/fileoverview_comment_merge_suppress.ts * @suppress {extraRequire} - * */ -/** second comment here */ +/** + * second comment here + */ goog.module('test_files.file_comment.fileoverview_comment_merge_suppress'); var module = module || { id: 'test_files/file_comment/fileoverview_comment_merge_suppress.ts' }; goog.require('tslib'); diff --git a/test_files/file_comment/fileoverview_in_comment_text.js b/test_files/file_comment/fileoverview_in_comment_text.js index e955e9c23..058eb0166 100644 --- a/test_files/file_comment/fileoverview_in_comment_text.js +++ b/test_files/file_comment/fileoverview_in_comment_text.js @@ -1,8 +1,6 @@ /** - * * @fileoverview Tests that mere mentions of file overview tags in comment bodies don't get * reported as errors. - * * Generated from: test_files/file_comment/fileoverview_in_comment_text.ts */ goog.module('test_files.file_comment.fileoverview_in_comment_text'); diff --git a/test_files/file_comment/latecomment_front.js b/test_files/file_comment/latecomment_front.js index 49f9731a4..c4c471d81 100644 --- a/test_files/file_comment/latecomment_front.js +++ b/test_files/file_comment/latecomment_front.js @@ -1,4 +1,6 @@ -/** @license Here is a license comment. */ +/** + * @license Here is a license comment. + */ /** * @fileoverview with a late fileoverview comment before the first statement. * Generated from: test_files/file_comment/latecomment_front.ts diff --git a/test_files/file_comment/multiple_comments.js b/test_files/file_comment/multiple_comments.js index bae1c03af..755a16261 100644 --- a/test_files/file_comment/multiple_comments.js +++ b/test_files/file_comment/multiple_comments.js @@ -7,17 +7,17 @@ * found in the LICENSE file at https://angular.io/license */ /** - * @fileoverview This comment is ignored by Closure compiler. - * @suppress {undefinedVars} + * \@fileoverview This comment is ignored by Closure compiler. + * \@suppress {undefinedVars} */ /** - * * @fileoverview The last fileoverview actually takes effect. * Generated from: test_files/file_comment/multiple_comments.ts * @suppress {const} - * */ -/** Here's another trailing comment */ +/** + * Here's another trailing comment + */ goog.module('test_files.file_comment.multiple_comments'); var module = module || { id: 'test_files/file_comment/multiple_comments.ts' }; goog.require('tslib'); diff --git a/test_files/file_comment/side_effect_import.js b/test_files/file_comment/side_effect_import.js index 19328b47d..f95734da0 100644 --- a/test_files/file_comment/side_effect_import.js +++ b/test_files/file_comment/side_effect_import.js @@ -1,9 +1,7 @@ /** - * * @fileoverview This is a fileoverview comment preceding a side-effect import. * transformer_util.ts has special logic to handle comments before * import/require() calls. This file tests the side-effect import case. - * * Generated from: test_files/file_comment/side_effect_import.ts */ goog.module('test_files.file_comment.side_effect_import'); diff --git a/test_files/functions/functions.js b/test_files/functions/functions.js index 7b6d5a283..a76945fa5 100644 --- a/test_files/functions/functions.js +++ b/test_files/functions/functions.js @@ -1,10 +1,8 @@ // test_files/functions/functions.ts(38,20): warning TS0: failed to resolve rest parameter type, emitting ? /** - * * @fileoverview * Generated from: test_files/functions/functions.ts * @suppress {checkTypes} - * */ goog.module('test_files.functions.functions'); var module = module || { id: 'test_files/functions/functions.ts' }; diff --git a/test_files/functions/two_jsdoc_blocks.js b/test_files/functions/two_jsdoc_blocks.js index 419f4117b..04b9c56a6 100644 --- a/test_files/functions/two_jsdoc_blocks.js +++ b/test_files/functions/two_jsdoc_blocks.js @@ -1,7 +1,5 @@ /** - * * @fileoverview This text here matches the text below in length. - * * Generated from: test_files/functions/two_jsdoc_blocks.ts */ goog.module('test_files.functions.two_jsdoc_blocks'); diff --git a/test_files/generic_extends/user.js b/test_files/generic_extends/user.js index 681c975ed..62c2cfe34 100644 --- a/test_files/generic_extends/user.js +++ b/test_files/generic_extends/user.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Tests template parameters in extends clauses. * Generated from: test_files/generic_extends/user.ts * @suppress {uselessCode} - * */ goog.module('test_files.generic_extends.user'); var module = module || { id: 'test_files/generic_extends/user.ts' }; diff --git a/test_files/generic_in_prop_access/user.js b/test_files/generic_in_prop_access/user.js index aca6c60b2..c2afe32d9 100644 --- a/test_files/generic_in_prop_access/user.js +++ b/test_files/generic_in_prop_access/user.js @@ -2,13 +2,11 @@ // test_files/generic_in_prop_access/user.ts(17,9): warning TS0: unhandled type flags: IncludesWildcard // test_files/generic_in_prop_access/user.ts(17,18): warning TS0: unhandled type flags: IncludesWildcard /** - * * @fileoverview Tests template parameters for identifier in property access * expression, where TypeScript narrows its type only on usage, i.e. in the * return statement below. * Generated from: test_files/generic_in_prop_access/user.ts * @suppress {uselessCode} - * */ goog.module('test_files.generic_in_prop_access.user'); var module = module || { id: 'test_files/generic_in_prop_access/user.ts' }; diff --git a/test_files/generic_local_var/generic_local_var.js b/test_files/generic_local_var/generic_local_var.js index 41f488810..c974e8078 100644 --- a/test_files/generic_local_var/generic_local_var.js +++ b/test_files/generic_local_var/generic_local_var.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/generic_local_var/generic_local_var.ts * @suppress {uselessCode} - * */ goog.module('test_files.generic_local_var.generic_local_var'); var module = module || { id: 'test_files/generic_local_var/generic_local_var.ts' }; diff --git a/test_files/generic_nested_classes/user.js b/test_files/generic_nested_classes/user.js index 984e4ebbe..8740e5f8c 100644 --- a/test_files/generic_nested_classes/user.js +++ b/test_files/generic_nested_classes/user.js @@ -1,8 +1,6 @@ /** - * * @fileoverview Tests template parameters for generic classes nested inside * another generic class. - * * Generated from: test_files/generic_nested_classes/user.ts */ goog.module('test_files.generic_nested_classes.user'); diff --git a/test_files/ignored_ambient_external_module/user.js b/test_files/ignored_ambient_external_module/user.js index 0e777e082..5b0332550 100644 --- a/test_files/ignored_ambient_external_module/user.js +++ b/test_files/ignored_ambient_external_module/user.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Regression test for type-ignored ambient modules. * Generated from: test_files/ignored_ambient_external_module/user.ts * @suppress {uselessCode} - * */ goog.module('test_files.ignored_ambient_external_module.user'); var module = module || { id: 'test_files/ignored_ambient_external_module/user.ts' }; diff --git a/test_files/implement_reexported_interface/interface.js b/test_files/implement_reexported_interface/interface.js index 0b83ac28b..0c7ef013c 100644 --- a/test_files/implement_reexported_interface/interface.js +++ b/test_files/implement_reexported_interface/interface.js @@ -1,9 +1,7 @@ /** - * * @fileoverview See user.ts for the actual test. * Generated from: test_files/implement_reexported_interface/interface.ts * @suppress {uselessCode} - * */ goog.module('test_files.implement_reexported_interface.interface'); var module = module || { id: 'test_files/implement_reexported_interface/interface.ts' }; diff --git a/test_files/implement_reexported_interface/user.js b/test_files/implement_reexported_interface/user.js index 2951f119f..37126cbd9 100644 --- a/test_files/implement_reexported_interface/user.js +++ b/test_files/implement_reexported_interface/user.js @@ -1,5 +1,4 @@ /** - * * @fileoverview Tests that a re-exported interface can be implemented. * * This reproduces a bug where tsickle would define re-exports as just @@ -9,7 +8,6 @@ * * Generated from: test_files/implement_reexported_interface/user.ts * @suppress {uselessCode} - * */ goog.module('test_files.implement_reexported_interface.user'); var module = module || { id: 'test_files/implement_reexported_interface/user.ts' }; diff --git a/test_files/implements/implements.js b/test_files/implements/implements.js index 156c40adf..e2e6e712a 100644 --- a/test_files/implements/implements.js +++ b/test_files/implements/implements.js @@ -1,12 +1,10 @@ // test_files/implements/implements.ts(13,1): warning TS0: dropped implements: dropped implements of a type literal: MyRecord // test_files/implements/implements.ts(19,1): warning TS0: dropped implements: dropped implements of a type literal: RecordAlias /** - * * @fileoverview Tests various types of 'implements' clauses, e.g. 'implements' * of a generic type alias of an underlying interface. * Generated from: test_files/implements/implements.ts * @suppress {uselessCode} - * */ goog.module('test_files.implements.implements'); var module = module || { id: 'test_files/implements/implements.ts' }; diff --git a/test_files/import_by_path.declaration.no_externs/clutz_input.d.ts b/test_files/import_by_path.declaration.no_externs/clutz_input.d.ts deleted file mode 100644 index 7dde5e336..000000000 --- a/test_files/import_by_path.declaration.no_externs/clutz_input.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Mocks for Clutz-generated .d.ts. - -declare namespace ಠ_ಠ.clutz.another.module { - export class SomeClass {} -} -declare module 'goog:another.module' { -import SomeClass = ಠ_ಠ.clutz.another.module.SomeClass; - export {SomeClass}; -} -declare module 'google3/another/file' { -import SomeClass = ಠ_ಠ.clutz.another.module.SomeClass; - export {SomeClass}; - const __clutz_actual_namespace: 'another.module'; -} diff --git a/test_files/import_by_path.declaration.no_externs/decluser.d.ts b/test_files/import_by_path.declaration.no_externs/decluser.d.ts deleted file mode 100644 index c845f22b6..000000000 --- a/test_files/import_by_path.declaration.no_externs/decluser.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -//!! generated by tsickle from test_files/import_by_path.declaration.no_externs/decluser.ts -import "test_files/import_by_path.declaration.no_externs/clutz_input"; -import { SomeClass } from 'google3/another/file'; -export declare class UsingPathImports { - someField?: SomeClass; -} -declare global { - namespace ಠ_ಠ.clutz { - export { UsingPathImports as module$contents$test_files$import_by_path$declaration$no_externs$decluser_UsingPathImports }; - export namespace module$exports$test_files$import_by_path$declaration$no_externs$decluser { - export { UsingPathImports }; - } - } -} diff --git a/test_files/import_by_path.declaration.no_externs/decluser.ts b/test_files/import_by_path.declaration.no_externs/decluser.ts deleted file mode 100644 index 7b01a7f96..000000000 --- a/test_files/import_by_path.declaration.no_externs/decluser.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {SomeClass} from 'google3/another/file'; - -export class UsingPathImports { - someField?: SomeClass; -} diff --git a/test_files/import_by_path.declaration.no_externs/jsprovides.js b/test_files/import_by_path.declaration.no_externs/jsprovides.js deleted file mode 100644 index 26ec015a9..000000000 --- a/test_files/import_by_path.declaration.no_externs/jsprovides.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @fileoverview Description of this file. - */ - -goog.module('another.module'); - -exports.SomeClass = class {}; diff --git a/test_files/import_by_path.no_externs/conflicting_multiple.js b/test_files/import_by_path.no_externs/conflicting_multiple.js index aa3b6a369..8a7c23055 100644 --- a/test_files/import_by_path.no_externs/conflicting_multiple.js +++ b/test_files/import_by_path.no_externs/conflicting_multiple.js @@ -1,11 +1,9 @@ // test_files/import_by_path.no_externs/conflicting_multiple.ts(7,21): error TS0: referenced JavaScript module google3/path/to/multiple_provides/conflicting provides multiple namespaces and cannot be imported by path. /** - * * @fileoverview Negative test: this TS file attempts to import a JS module that * provides multiple conflicting namespaces by path, which is an error. * Generated from: test_files/import_by_path.no_externs/conflicting_multiple.ts * @suppress {checkTypes} - * */ goog.module('test_files.import_by_path.no_externs.conflicting_multiple'); var module = module || { id: 'test_files/import_by_path.no_externs/conflicting_multiple.ts' }; diff --git a/test_files/import_by_path.no_externs/conflicting_multiple_bystar.js b/test_files/import_by_path.no_externs/conflicting_multiple_bystar.js index e87f89b4a..2593b973f 100644 --- a/test_files/import_by_path.no_externs/conflicting_multiple_bystar.js +++ b/test_files/import_by_path.no_externs/conflicting_multiple_bystar.js @@ -1,11 +1,9 @@ // test_files/import_by_path.no_externs/conflicting_multiple_bystar.ts(7,25): error TS0: referenced JavaScript module google3/path/to/multiple_provides/conflicting provides multiple namespaces and cannot be imported by path. /** - * * @fileoverview Negative test: import by star reports errors for conflicting * symbols. * Generated from: test_files/import_by_path.no_externs/conflicting_multiple_bystar.ts * @suppress {checkTypes} - * */ goog.module('test_files.import_by_path.no_externs.conflicting_multiple_bystar'); var module = module || { id: 'test_files/import_by_path.no_externs/conflicting_multiple_bystar.ts' }; diff --git a/test_files/import_by_path.no_externs/conflicting_multiple_empty.js b/test_files/import_by_path.no_externs/conflicting_multiple_empty.js index 1f6a533de..f44348150 100644 --- a/test_files/import_by_path.no_externs/conflicting_multiple_empty.js +++ b/test_files/import_by_path.no_externs/conflicting_multiple_empty.js @@ -1,10 +1,8 @@ // test_files/import_by_path.no_externs/conflicting_multiple_empty.ts(6,41): error TS0: referenced JavaScript module google3/path/to/multiple_provides/conflicting provides multiple namespaces and cannot be imported by path. /** - * * @fileoverview Negative test for importing no symbols from a module, by path. * Generated from: test_files/import_by_path.no_externs/conflicting_multiple_empty.ts * @suppress {checkTypes} - * */ goog.module('test_files.import_by_path.no_externs.conflicting_multiple_empty'); var module = module || { id: 'test_files/import_by_path.no_externs/conflicting_multiple_empty.ts' }; diff --git a/test_files/import_by_path.no_externs/conflicting_multiple_type.js b/test_files/import_by_path.no_externs/conflicting_multiple_type.js index c9c947883..ca9642b14 100644 --- a/test_files/import_by_path.no_externs/conflicting_multiple_type.js +++ b/test_files/import_by_path.no_externs/conflicting_multiple_type.js @@ -1,11 +1,9 @@ // test_files/import_by_path.no_externs/conflicting_multiple_type.ts(7,25): error TS0: referenced JavaScript module google3/path/to/multiple_provides/conflicting provides multiple namespaces and cannot be imported by path. /** - * * @fileoverview Negative test: import type reports errors for conflicting * symbols. * Generated from: test_files/import_by_path.no_externs/conflicting_multiple_type.ts * @suppress {checkTypes} - * */ goog.module('test_files.import_by_path.no_externs.conflicting_multiple_type'); var module = module || { id: 'test_files/import_by_path.no_externs/conflicting_multiple_type.ts' }; diff --git a/test_files/import_by_path.no_externs/multiple_side_effect.js b/test_files/import_by_path.no_externs/multiple_side_effect.js index 346710866..99f55ade5 100644 --- a/test_files/import_by_path.no_externs/multiple_side_effect.js +++ b/test_files/import_by_path.no_externs/multiple_side_effect.js @@ -1,12 +1,10 @@ /** - * * @fileoverview Imports a module with conflicting provides, but with a * side-effect import. tsickle only reports an error when code imports a symbol * from a module with conflicting symbol exports, but not for a side effect * import. * Generated from: test_files/import_by_path.no_externs/multiple_side_effect.ts * @suppress {checkTypes} - * */ goog.module('test_files.import_by_path.no_externs.multiple_side_effect'); var module = module || { id: 'test_files/import_by_path.no_externs/multiple_side_effect.ts' }; diff --git a/test_files/import_by_path.no_externs/user.js b/test_files/import_by_path.no_externs/user.js index 79123c82b..7d67dd835 100644 --- a/test_files/import_by_path.no_externs/user.js +++ b/test_files/import_by_path.no_externs/user.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Tests that tsickle emits goog namespace references when * importing modules by path. * Generated from: test_files/import_by_path.no_externs/user.ts * @suppress {checkTypes} - * */ goog.module('test_files.import_by_path.no_externs.user'); var module = module || { id: 'test_files/import_by_path.no_externs/user.ts' }; diff --git a/test_files/import_by_path.no_externs/user_default.js b/test_files/import_by_path.no_externs/user_default.js index ab205f98f..f9f65929d 100644 --- a/test_files/import_by_path.no_externs/user_default.js +++ b/test_files/import_by_path.no_externs/user_default.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Tests that tsickle emits goog namespace references when * importing modules by path, and handles named to default export conversion. * Generated from: test_files/import_by_path.no_externs/user_default.ts * @suppress {checkTypes} - * */ goog.module('test_files.import_by_path.no_externs.user_default'); var module = module || { id: 'test_files/import_by_path.no_externs/user_default.ts' }; diff --git a/test_files/import_by_path.no_externs/using_multiple.js b/test_files/import_by_path.no_externs/using_multiple.js index b62126875..264ebebc7 100644 --- a/test_files/import_by_path.no_externs/using_multiple.js +++ b/test_files/import_by_path.no_externs/using_multiple.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Using a namespace that provides multiple, nested symbols. * Generated from: test_files/import_by_path.no_externs/using_multiple.ts * @suppress {checkTypes} - * */ goog.module('test_files.import_by_path.no_externs.using_multiple'); var module = module || { id: 'test_files/import_by_path.no_externs/using_multiple.ts' }; diff --git a/test_files/import_equals/import_equals_type_usage.js b/test_files/import_equals/import_equals_type_usage.js index 1cf2bb37b..1c7c58912 100644 --- a/test_files/import_equals/import_equals_type_usage.js +++ b/test_files/import_equals/import_equals_type_usage.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Tests type only usage of symbols imported using import equals * syntax. TypeScript elides those imports, so type references have to use * tsickle's requireType symbols. - * * Generated from: test_files/import_equals/import_equals_type_usage.ts */ goog.module('test_files.import_equals.import_equals_type_usage'); diff --git a/test_files/import_from_goog.no_externs/import_from_goog.js b/test_files/import_from_goog.no_externs/import_from_goog.js index b9f6ad3e9..94b4640c5 100644 --- a/test_files/import_from_goog.no_externs/import_from_goog.js +++ b/test_files/import_from_goog.no_externs/import_from_goog.js @@ -1,7 +1,5 @@ /** - * * @fileoverview - * * Generated from: test_files/import_from_goog.no_externs/import_from_goog.ts */ goog.module('test_files.import_from_goog.no_externs.import_from_goog'); diff --git a/test_files/import_only_types/types_and_constenum.js b/test_files/import_only_types/types_and_constenum.js index bbf8cc5e3..2b9533a1a 100644 --- a/test_files/import_only_types/types_and_constenum.js +++ b/test_files/import_only_types/types_and_constenum.js @@ -1,10 +1,10 @@ +// const enum values are inlined, so even though const enums are values, +// TypeScript might not generate any imports for them, which means modules +// containing only types and const enums must be "force loaded". /** * @fileoverview added by tsickle * Generated from: test_files/import_only_types/types_and_constenum.ts */ -// const enum values are inlined, so even though const enums are values, -// TypeScript might not generate any imports for them, which means modules -// containing only types and const enums must be "force loaded". goog.module('test_files.import_only_types.types_and_constenum'); var module = module || { id: 'test_files/import_only_types/types_and_constenum.ts' }; goog.require('tslib'); diff --git a/test_files/import_only_types/types_only.js b/test_files/import_only_types/types_only.js index 4ac33c807..10620fa63 100644 --- a/test_files/import_only_types/types_only.js +++ b/test_files/import_only_types/types_only.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Exports only types, but must still be goog.require'd for * Closure Compiler. * Generated from: test_files/import_only_types/types_only.ts * @suppress {uselessCode} - * */ goog.module('test_files.import_only_types.types_only'); var module = module || { id: 'test_files/import_only_types/types_only.ts' }; diff --git a/test_files/import_prefixed/import_prefixed_mixed.js b/test_files/import_prefixed/import_prefixed_mixed.js index b3f17b062..4682dfa41 100644 --- a/test_files/import_prefixed/import_prefixed_mixed.js +++ b/test_files/import_prefixed/import_prefixed_mixed.js @@ -1,3 +1,5 @@ +// This file imports exporter with a prefix import (* as ...), and then uses the +// import in a type and in a value position. /** * @fileoverview added by tsickle * Generated from: test_files/import_prefixed/import_prefixed_mixed.ts @@ -6,8 +8,6 @@ goog.module('test_files.import_prefixed.import_prefixed_mixed'); var module = module || { id: 'test_files/import_prefixed/import_prefixed_mixed.ts' }; goog.require('tslib'); const tsickle_exporter_1 = goog.requireType("test_files.import_prefixed.exporter"); -// This file imports exporter with a prefix import (* as ...), and then uses the -// import in a type and in a value position. const exporter = goog.require('test_files.import_prefixed.exporter'); /** @type {(string|number)} */ let someVar; diff --git a/test_files/import_prefixed/import_prefixed_types.js b/test_files/import_prefixed/import_prefixed_types.js index a70c737d6..81cd2afda 100644 --- a/test_files/import_prefixed/import_prefixed_types.js +++ b/test_files/import_prefixed/import_prefixed_types.js @@ -1,3 +1,7 @@ +// This file imports exporter with a prefix import (* as ...), and then only +// uses the import in a type position. +// tsickle emits a goog.forwardDeclare for the type and uses it to refer to the +// type TypeExport. /** * @fileoverview added by tsickle * Generated from: test_files/import_prefixed/import_prefixed_types.ts @@ -6,10 +10,6 @@ goog.module('test_files.import_prefixed.import_prefixed_types'); var module = module || { id: 'test_files/import_prefixed/import_prefixed_types.ts' }; goog.require('tslib'); const tsickle_exporter_1 = goog.requireType("test_files.import_prefixed.exporter"); -// This file imports exporter with a prefix import (* as ...), and then only -// uses the import in a type position. -// tsickle emits a goog.forwardDeclare for the type and uses it to refer to the -// type TypeExport. /** @type {(string|number)} */ const someVar = 1; console.log(someVar); diff --git a/test_files/interface/implement_import.js b/test_files/interface/implement_import.js index 7633da261..46e2816c2 100644 --- a/test_files/interface/implement_import.js +++ b/test_files/interface/implement_import.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/interface/implement_import.ts * @suppress {uselessCode} - * */ goog.module('test_files.interface.implement_import'); var module = module || { id: 'test_files/interface/implement_import.ts' }; diff --git a/test_files/interface/interface.js b/test_files/interface/interface.js index c5a06ade8..8803c1d2b 100644 --- a/test_files/interface/interface.js +++ b/test_files/interface/interface.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/interface/interface.ts * @suppress {uselessCode} - * */ goog.module('test_files.interface.interface'); var module = module || { id: 'test_files/interface/interface.ts' }; diff --git a/test_files/interface/interface_extends.js b/test_files/interface/interface_extends.js index 5f075481b..81dfbaefe 100644 --- a/test_files/interface/interface_extends.js +++ b/test_files/interface/interface_extends.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/interface/interface_extends.ts * @suppress {uselessCode} - * */ goog.module('test_files.interface.interface_extends'); var module = module || { id: 'test_files/interface/interface_extends.ts' }; diff --git a/test_files/interface/interface_merge.js b/test_files/interface/interface_merge.js index 22ebf38e0..059c717d7 100644 --- a/test_files/interface/interface_merge.js +++ b/test_files/interface/interface_merge.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Test to ensure that there is only one record declaration * for a merged interface. * Generated from: test_files/interface/interface_merge.ts * @suppress {uselessCode} - * */ goog.module('test_files.interface.interface_merge'); var module = module || { id: 'test_files/interface/interface_merge.ts' }; diff --git a/test_files/interface/interface_type_params.js b/test_files/interface/interface_type_params.js index 28a6f033f..18d5587af 100644 --- a/test_files/interface/interface_type_params.js +++ b/test_files/interface/interface_type_params.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/interface/interface_type_params.ts * @suppress {uselessCode} - * */ goog.module('test_files.interface.interface_type_params'); var module = module || { id: 'test_files/interface/interface_type_params.ts' }; diff --git a/test_files/internal.declaration/internal.d.ts b/test_files/internal.declaration/internal.d.ts index eae8448e9..1bd9c76a6 100644 --- a/test_files/internal.declaration/internal.d.ts +++ b/test_files/internal.declaration/internal.d.ts @@ -1,3 +1,8 @@ // test_files/internal.declaration/internal.ts(27,18): error TS0: transformation of plain namespace not supported. (go/ts-merged-namespaces) //!! generated by tsickle from test_files/internal.declaration/internal.ts +/** + * @fileoverview Test to reproduce that \@internal declarations are not + * re-exported for Clutz. There should not be any `.d.ts` aliases generated for + * the declarations below. + */ export {}; diff --git a/test_files/invalid_closure_properties/invalid_closure_properties.js b/test_files/invalid_closure_properties/invalid_closure_properties.js index 48c31a288..3924e828a 100644 --- a/test_files/invalid_closure_properties/invalid_closure_properties.js +++ b/test_files/invalid_closure_properties/invalid_closure_properties.js @@ -1,9 +1,7 @@ // test_files/invalid_closure_properties/invalid_closure_properties.ts(18,12): warning TS0: omitting inexpressible property name: with spaces /** - * * @fileoverview Check the type generated when using a builtin symbol as * a computed property. - * * Generated from: test_files/invalid_closure_properties/invalid_closure_properties.ts */ // This test is verifying the type of this expression, which ultimately diff --git a/test_files/jsdoc/enum_tag.js b/test_files/jsdoc/enum_tag.js index 2d8efab60..583eeba39 100644 --- a/test_files/jsdoc/enum_tag.js +++ b/test_files/jsdoc/enum_tag.js @@ -3,12 +3,10 @@ // test_files/jsdoc/enum_tag.ts(21,1): warning TS0: @enum annotations are redundant with TypeScript equivalents // test_files/jsdoc/enum_tag.ts(30,3): warning TS0: @enum annotations are redundant with TypeScript equivalents /** - * * @fileoverview Checks that JSDoc `\@enum` tags on an `enum` are flagged as * warnings. * Generated from: test_files/jsdoc/enum_tag.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc.enum_tag'); var module = module || { id: 'test_files/jsdoc/enum_tag.ts' }; diff --git a/test_files/jsdoc/jsdoc.js b/test_files/jsdoc/jsdoc.js index e27f2c9c4..065088050 100644 --- a/test_files/jsdoc/jsdoc.js +++ b/test_files/jsdoc/jsdoc.js @@ -13,11 +13,9 @@ // test_files/jsdoc/jsdoc.ts(96,3): warning TS0: @constructor annotations are redundant with TypeScript equivalents // test_files/jsdoc/jsdoc.ts(144,1): warning TS0: the type annotation on @define is redundant with its TypeScript type, remove the {...} part /** - * * @fileoverview * Generated from: test_files/jsdoc/jsdoc.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc.jsdoc'); var module = module || { id: 'test_files/jsdoc/jsdoc.ts' }; @@ -210,3 +208,19 @@ const DEFINE_WITH_DECLARED_TYPE = 'y'; * @type {number} */ const logTypeInCompiler = 0; +class NgInjectClass { + /** + * @ngInject + * @public + */ + constructor() { } +} +class NgInjectClassWithStruct { + // The @struct tag does not mean anything to TypeScript but is ok to use. + // TODO(b/335205805): don't escape @ngInject here. + /** + * @struct \@ngInject + * @public + */ + constructor() { } +} diff --git a/test_files/jsdoc/jsdoc.ts b/test_files/jsdoc/jsdoc.ts index 819138761..47ba6b29c 100644 --- a/test_files/jsdoc/jsdoc.ts +++ b/test_files/jsdoc/jsdoc.ts @@ -158,3 +158,15 @@ const DEFINE_WITH_DECLARED_TYPE: string = 'y'; /** @logTypeInCompiler */ const logTypeInCompiler = 0; + +class NgInjectClass { + /** @ngInject */ + constructor() {} +} + +class NgInjectClassWithStruct { + // The @struct tag does not mean anything to TypeScript but is ok to use. + // TODO(b/335205805): don't escape @ngInject here. + /** @struct @ngInject */ + constructor() {} +} diff --git a/test_files/jsdoc_types.untyped/jsdoc_types.js b/test_files/jsdoc_types.untyped/jsdoc_types.js index 32495b6b0..bc4842968 100644 --- a/test_files/jsdoc_types.untyped/jsdoc_types.js +++ b/test_files/jsdoc_types.untyped/jsdoc_types.js @@ -1,11 +1,11 @@ -/** - * @fileoverview added by tsickle - * Generated from: test_files/jsdoc_types.untyped/jsdoc_types.ts - */ /** * This test tests importing a type across module boundaries, * ensuring that the type gets the proper name in JSDoc comments. */ +/** + * @fileoverview added by tsickle + * Generated from: test_files/jsdoc_types.untyped/jsdoc_types.ts + */ goog.module('test_files.jsdoc_types.untyped.jsdoc_types'); var module = module || { id: 'test_files/jsdoc_types.untyped/jsdoc_types.ts' }; goog.require('tslib'); diff --git a/test_files/jsdoc_types.untyped/module1.js b/test_files/jsdoc_types.untyped/module1.js index 13ccf0e63..65201999d 100644 --- a/test_files/jsdoc_types.untyped/module1.js +++ b/test_files/jsdoc_types.untyped/module1.js @@ -1,11 +1,9 @@ // test_files/jsdoc_types.untyped/module1.ts(9,3): warning TS0: handle unnamed member: // 'quoted-bad-name': string; /** - * * @fileoverview * Generated from: test_files/jsdoc_types.untyped/module1.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc_types.untyped.module1'); var module = module || { id: 'test_files/jsdoc_types.untyped/module1.ts' }; diff --git a/test_files/jsdoc_types.untyped/module2.js b/test_files/jsdoc_types.untyped/module2.js index 11d7ed2ab..b5c7d41a7 100644 --- a/test_files/jsdoc_types.untyped/module2.js +++ b/test_files/jsdoc_types.untyped/module2.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/jsdoc_types.untyped/module2.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc_types.untyped.module2'); var module = module || { id: 'test_files/jsdoc_types.untyped/module2.ts' }; diff --git a/test_files/jsdoc_types.untyped/nevertyped.js b/test_files/jsdoc_types.untyped/nevertyped.js index 53df7c44c..b46af99da 100644 --- a/test_files/jsdoc_types.untyped/nevertyped.js +++ b/test_files/jsdoc_types.untyped/nevertyped.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This filename is specially marked in the tsickle test suite * runner so that its types are always {?}. * Generated from: test_files/jsdoc_types.untyped/nevertyped.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc_types.untyped.nevertyped'); var module = module || { id: 'test_files/jsdoc_types.untyped/nevertyped.ts' }; diff --git a/test_files/jsdoc_types/initialized_unknown.js b/test_files/jsdoc_types/initialized_unknown.js index 841a8051c..dbf1770e7 100644 --- a/test_files/jsdoc_types/initialized_unknown.js +++ b/test_files/jsdoc_types/initialized_unknown.js @@ -1,8 +1,6 @@ /** - * * @fileoverview Tests that initialized variables that end up untyped (`?`) do not get an explicit * type annotation, so that Closure's type inference can kick in and possibly do a better job. - * * Generated from: test_files/jsdoc_types/initialized_unknown.ts */ // This should not have a type annotation. diff --git a/test_files/jsdoc_types/jsdoc_types.js b/test_files/jsdoc_types/jsdoc_types.js index c87f87294..3b5dbf80d 100644 --- a/test_files/jsdoc_types/jsdoc_types.js +++ b/test_files/jsdoc_types/jsdoc_types.js @@ -1,12 +1,10 @@ // test_files/jsdoc_types/jsdoc_types.ts(40,1): warning TS0: dropped implements: {?} type // test_files/jsdoc_types/jsdoc_types.ts(43,1): warning TS0: dropped implements: {?} type /** - * * @fileoverview This test tests importing a type across module boundaries, * ensuring that the type gets the proper name in JSDoc comments. * Generated from: test_files/jsdoc_types/jsdoc_types.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc_types.jsdoc_types'); var module = module || { id: 'test_files/jsdoc_types/jsdoc_types.ts' }; diff --git a/test_files/jsdoc_types/module1.js b/test_files/jsdoc_types/module1.js index b33112fba..75f54a394 100644 --- a/test_files/jsdoc_types/module1.js +++ b/test_files/jsdoc_types/module1.js @@ -1,11 +1,9 @@ // test_files/jsdoc_types/module1.ts(9,3): warning TS0: handle unnamed member: // 'quoted-bad-name': string; /** - * * @fileoverview * Generated from: test_files/jsdoc_types/module1.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc_types.module1'); var module = module || { id: 'test_files/jsdoc_types/module1.ts' }; diff --git a/test_files/jsdoc_types/module2.js b/test_files/jsdoc_types/module2.js index 00be7aceb..9253b8a46 100644 --- a/test_files/jsdoc_types/module2.js +++ b/test_files/jsdoc_types/module2.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/jsdoc_types/module2.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc_types.module2'); var module = module || { id: 'test_files/jsdoc_types/module2.ts' }; diff --git a/test_files/jsdoc_types/nevertyped.js b/test_files/jsdoc_types/nevertyped.js index 48e25af43..35f5240cd 100644 --- a/test_files/jsdoc_types/nevertyped.js +++ b/test_files/jsdoc_types/nevertyped.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This filename is specially marked in the tsickle test suite * runner so that its types are always {?}. * Generated from: test_files/jsdoc_types/nevertyped.ts * @suppress {uselessCode} - * */ goog.module('test_files.jsdoc_types.nevertyped'); var module = module || { id: 'test_files/jsdoc_types/nevertyped.ts' }; diff --git a/test_files/jsx.no_externs/jsx.js b/test_files/jsx.no_externs/jsx.js index 4f66efa06..28ff759f1 100644 --- a/test_files/jsx.no_externs/jsx.js +++ b/test_files/jsx.no_externs/jsx.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Fake a subcomponent, just to exercise components within * components. * Generated from: test_files/jsx.no_externs/jsx.tsx * @suppress {checkTypes} - * */ goog.module('test_files.jsx.no_externs.jsx.tsx'); var module = module || { id: 'test_files/jsx.no_externs/jsx.tsx' }; diff --git a/test_files/methods/methods.js b/test_files/methods/methods.js index 014e90fb5..267257f32 100644 --- a/test_files/methods/methods.js +++ b/test_files/methods/methods.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/methods/methods.ts * @suppress {uselessCode} - * */ goog.module('test_files.methods.methods'); var module = module || { id: 'test_files/methods/methods.ts' }; diff --git a/test_files/namespaced.no_nstransform/export_enum_in_namespace.js b/test_files/namespaced.no_nstransform/export_enum_in_namespace.js index 46a4f40bd..205ade23e 100644 --- a/test_files/namespaced.no_nstransform/export_enum_in_namespace.js +++ b/test_files/namespaced.no_nstransform/export_enum_in_namespace.js @@ -1,8 +1,6 @@ /** - * * @fileoverview tsickle's Closure compatible exported enum emit does not work in namespaces. Bar * below must be exported onto foo, which tsickle does by disabling its emit for namespace'd enums. - * * Generated from: test_files/namespaced.no_nstransform/export_enum_in_namespace.ts */ // tslint:disable:no-namespace diff --git a/test_files/namespaced.no_nstransform/export_namespace.js b/test_files/namespaced.no_nstransform/export_namespace.js index aaf41e832..79bc246ee 100644 --- a/test_files/namespaced.no_nstransform/export_namespace.js +++ b/test_files/namespaced.no_nstransform/export_namespace.js @@ -1,8 +1,8 @@ +// tslint:disable:no-namespace /** * @fileoverview added by tsickle * Generated from: test_files/namespaced.no_nstransform/export_namespace.ts */ -// tslint:disable:no-namespace goog.module('test_files.namespaced.no_nstransform.export_namespace'); var module = module || { id: 'test_files/namespaced.no_nstransform/export_namespace.ts' }; goog.require('tslib'); diff --git a/test_files/namespaced.no_nstransform/merged_namespace.js b/test_files/namespaced.no_nstransform/merged_namespace.js index d16313489..1c5ee04fc 100644 --- a/test_files/namespaced.no_nstransform/merged_namespace.js +++ b/test_files/namespaced.no_nstransform/merged_namespace.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Test transpilation of namespaces merging with classes or * functions. * Generated from: test_files/namespaced.no_nstransform/merged_namespace.ts * @suppress {checkTypes,constantProperty} - * */ goog.module('test_files.namespaced.no_nstransform.merged_namespace'); var module = module || { id: 'test_files/namespaced.no_nstransform/merged_namespace.ts' }; diff --git a/test_files/namespaced.no_nstransform/reopen_ns.js b/test_files/namespaced.no_nstransform/reopen_ns.js index 6e3fb0f1c..7c6581c91 100644 --- a/test_files/namespaced.no_nstransform/reopen_ns.js +++ b/test_files/namespaced.no_nstransform/reopen_ns.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/namespaced.no_nstransform/reopen_ns.ts * @suppress {checkTypes,constantProperty} - * */ goog.module('test_files.namespaced.no_nstransform.reopen_ns'); var module = module || { id: 'test_files/namespaced.no_nstransform/reopen_ns.ts' }; diff --git a/test_files/nullable/nullable.js b/test_files/nullable/nullable.js index 0c1227bf3..b1db91e20 100644 --- a/test_files/nullable/nullable.js +++ b/test_files/nullable/nullable.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/nullable/nullable.ts * @suppress {checkTypes,uselessCode} - * */ goog.module('test_files.nullable.nullable'); var module = module || { id: 'test_files/nullable/nullable.ts' }; diff --git a/test_files/optional_chaining/keyed_access.js b/test_files/optional_chaining/keyed_access.js index 444c1de93..917c0f69d 100644 --- a/test_files/optional_chaining/keyed_access.js +++ b/test_files/optional_chaining/keyed_access.js @@ -3,7 +3,6 @@ var module = module || { id: 'test_files/optional_chaining/keyed_access.ts' }; goog.require('tslib'); var _a; /** - * * @fileoverview Tests that tsickle correctly handles casting to the correct * type after an optional property access. There was a bug where tsickle's * non-nullable assertion transformation would remove type information from a @@ -12,7 +11,6 @@ var _a; * that crash. * Generated from: test_files/optional_chaining/keyed_access.ts * @suppress {checkTypes,uselessCode} - * */ /** * @record diff --git a/test_files/optional_chaining/optional_chaining.js b/test_files/optional_chaining/optional_chaining.js index adfb2d0c4..68b0bad04 100644 --- a/test_files/optional_chaining/optional_chaining.js +++ b/test_files/optional_chaining/optional_chaining.js @@ -3,7 +3,6 @@ var module = module || { id: 'test_files/optional_chaining/optional_chaining.ts' goog.require('tslib'); var _a, _b, _c; /** - * * @fileoverview Tests that tsickle handles non-nullable assertions in optional * chains correctly. The correct behavior is not emitting any special casts * because Closure Compiler will not check possibly-undefined property access. @@ -12,7 +11,6 @@ var _a, _b, _c; * For more information see jsdoc_transformer.ts. * Generated from: test_files/optional_chaining/optional_chaining.ts * @suppress {checkTypes} - * */ /** @type {(undefined|{a: (undefined|{b: number})})} */ let basic; diff --git a/test_files/optional_method/optional_method.js b/test_files/optional_method/optional_method.js index f23c04180..e840e1607 100644 --- a/test_files/optional_method/optional_method.js +++ b/test_files/optional_method/optional_method.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/optional_method/optional_method.ts * @suppress {uselessCode} - * */ goog.module('test_files.optional_method.optional_method'); var module = module || { id: 'test_files/optional_method/optional_method.ts' }; diff --git a/test_files/parameter_properties/parameter_properties.js b/test_files/parameter_properties/parameter_properties.js index 414cb35d8..e8efc0922 100644 --- a/test_files/parameter_properties/parameter_properties.js +++ b/test_files/parameter_properties/parameter_properties.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/parameter_properties/parameter_properties.ts * @suppress {uselessCode} - * */ goog.module('test_files.parameter_properties.parameter_properties'); var module = module || { id: 'test_files/parameter_properties/parameter_properties.ts' }; diff --git a/test_files/partial/partial.js b/test_files/partial/partial.js index fffb1fea6..8ee0b17b7 100644 --- a/test_files/partial/partial.js +++ b/test_files/partial/partial.js @@ -1,10 +1,8 @@ // test_files/partial/partial.ts(12,1): warning TS0: dropped implements: dropped implements of a type literal: Partial /** - * * @fileoverview * Generated from: test_files/partial/partial.ts * @suppress {uselessCode} - * */ goog.module('test_files.partial.partial'); var module = module || { id: 'test_files/partial/partial.ts' }; diff --git a/test_files/private_field/private_field.js b/test_files/private_field/private_field.js index e58718c1d..fbb9e6b6f 100644 --- a/test_files/private_field/private_field.js +++ b/test_files/private_field/private_field.js @@ -3,13 +3,11 @@ var module = module || { id: 'test_files/private_field/private_field.ts' }; var _ContainsPrivateField_someField; const tslib_1 = goog.require('tslib'); /** - * * @fileoverview Tests the generation of private field accessors from Tsickle. * They do not generate any externs, as they do not exist on the class * themselves when downleveled by TypeScript. * Generated from: test_files/private_field/private_field.ts * @suppress {checkTypes,uselessCode} - * */ class ContainsPrivateField { /** diff --git a/test_files/promiseconstructor/promiseconstructor.js b/test_files/promiseconstructor/promiseconstructor.js index 5d98c9949..573ecffad 100644 --- a/test_files/promiseconstructor/promiseconstructor.js +++ b/test_files/promiseconstructor/promiseconstructor.js @@ -1,12 +1,10 @@ /** - * * @fileoverview typeof Promise actually resolves to "PromiseConstructor" in * TypeScript, which is a type that doesn't exist in Closure's type world. This * code passes the e2e test because closure_externs.js declares * PromiseConstructor. * Generated from: test_files/promiseconstructor/promiseconstructor.ts * @suppress {checkTypes} - * */ goog.module('test_files.promiseconstructor.promiseconstructor'); var module = module || { id: 'test_files/promiseconstructor/promiseconstructor.ts' }; diff --git a/test_files/protected/protected.js b/test_files/protected/protected.js index a35368df4..7804e4b8c 100644 --- a/test_files/protected/protected.js +++ b/test_files/protected/protected.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This test checks that we emit \\@private/\\@protected where * necessary. * Generated from: test_files/protected/protected.ts * @suppress {uselessCode} - * */ goog.module('test_files.protected.protected'); var module = module || { id: 'test_files/protected/protected.ts' }; diff --git a/test_files/readonly/readonly.js b/test_files/readonly/readonly.js index 880045022..2761f0c92 100644 --- a/test_files/readonly/readonly.js +++ b/test_files/readonly/readonly.js @@ -1,9 +1,7 @@ /** - * * @fileoverview Tests `readonly` properties are annotated with `\@const`. * Generated from: test_files/readonly/readonly.ts * @suppress {uselessCode} - * */ goog.module('test_files.readonly.readonly'); var module = module || { id: 'test_files/readonly/readonly.ts' }; diff --git a/test_files/recursive_alias/recursive_alias.js b/test_files/recursive_alias/recursive_alias.js index c21da5784..7a3d559b6 100644 --- a/test_files/recursive_alias/recursive_alias.js +++ b/test_files/recursive_alias/recursive_alias.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This test checks that tsickle breaks out of recursive type * definitions where the type being declared is used as a type parameter. * Generated from: test_files/recursive_alias/recursive_alias.ts * @suppress {uselessCode} - * */ goog.module('test_files.recursive_alias.recursive_alias'); var module = module || { id: 'test_files/recursive_alias/recursive_alias.ts' }; diff --git a/test_files/recursive_union/recursive_union.js b/test_files/recursive_union/recursive_union.js index c54e1699c..76e366612 100644 --- a/test_files/recursive_union/recursive_union.js +++ b/test_files/recursive_union/recursive_union.js @@ -1,8 +1,6 @@ /** - * * @fileoverview Reproduces a reported crash in tsickle with recursive union * types. - * * Generated from: test_files/recursive_union/recursive_union.ts */ goog.module('test_files.recursive_union.recursive_union'); diff --git a/test_files/rest_parameters_any/rest_parameters_any.js b/test_files/rest_parameters_any/rest_parameters_any.js index 53fc88f07..36b539615 100644 --- a/test_files/rest_parameters_any/rest_parameters_any.js +++ b/test_files/rest_parameters_any/rest_parameters_any.js @@ -1,10 +1,8 @@ // test_files/rest_parameters_any/rest_parameters_any.ts(26,7): warning TS0: unable to translate rest args type /** - * * @fileoverview This test covers the rest parameter of function and method * signatures. This includes signatures only consisting of a rest parameter and * signatures mixing both explicit declarations and a rest parameter. - * * Generated from: test_files/rest_parameters_any/rest_parameters_any.ts */ goog.module('test_files.rest_parameters_any.rest_parameters_any'); diff --git a/test_files/rest_parameters_generic_empty/rest_parameters_generic_empty.js b/test_files/rest_parameters_generic_empty/rest_parameters_generic_empty.js index ab73a5c47..7696cd3db 100644 --- a/test_files/rest_parameters_generic_empty/rest_parameters_generic_empty.js +++ b/test_files/rest_parameters_generic_empty/rest_parameters_generic_empty.js @@ -1,9 +1,7 @@ // test_files/rest_parameters_generic_empty/rest_parameters_generic_empty.ts(13,7): warning TS0: unable to translate rest args type /** - * * @fileoverview Tests what happens when a rest args (...x) param is * instantiated in a context where it creates a zero-argument function. - * * Generated from: test_files/rest_parameters_generic_empty/rest_parameters_generic_empty.ts */ goog.module('test_files.rest_parameters_generic_empty.rest_parameters_generic_empty'); diff --git a/test_files/rest_parameters_tuple/rest_parameters_tuple.js b/test_files/rest_parameters_tuple/rest_parameters_tuple.js index a54e3ecdd..054437fc1 100644 --- a/test_files/rest_parameters_tuple/rest_parameters_tuple.js +++ b/test_files/rest_parameters_tuple/rest_parameters_tuple.js @@ -1,9 +1,7 @@ // test_files/rest_parameters_tuple/rest_parameters_tuple.ts(6,20): warning TS0: failed to resolve rest parameter type, emitting ? /** - * * @fileoverview Tests that complex union/tuple types for rest parameters get emitted as a fallback * '?' unknown type. - * * Generated from: test_files/rest_parameters_tuple/rest_parameters_tuple.ts */ goog.module('test_files.rest_parameters_tuple.rest_parameters_tuple'); diff --git a/test_files/return_this/return_this.js b/test_files/return_this/return_this.js index 7584d583f..0b8ba95bb 100644 --- a/test_files/return_this/return_this.js +++ b/test_files/return_this/return_this.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/return_this/return_this.ts * @suppress {uselessCode} - * */ goog.module('test_files.return_this.return_this'); var module = module || { id: 'test_files/return_this/return_this.ts' }; diff --git a/test_files/scope_collision/collision.js b/test_files/scope_collision/collision.js index a1c521661..165a45666 100644 --- a/test_files/scope_collision/collision.js +++ b/test_files/scope_collision/collision.js @@ -1,10 +1,8 @@ /** - * * @fileoverview * TODO(b/195232797): remove the checkTypes suppression * Generated from: test_files/scope_collision/collision.ts * @suppress {checkTypes,uselessCode} - * */ goog.module('test_files.scope_collision.collision'); var module = module || { id: 'test_files/scope_collision/collision.ts' }; diff --git a/test_files/side_effect_import/module1.js b/test_files/side_effect_import/module1.js index 517cb3a27..8beca783c 100644 --- a/test_files/side_effect_import/module1.js +++ b/test_files/side_effect_import/module1.js @@ -1,7 +1,5 @@ /** - * * @fileoverview A module for importing from the main test. - * * Generated from: test_files/side_effect_import/module1.ts */ goog.module('test_files.side_effect_import.module1'); diff --git a/test_files/side_effect_import/module2.js b/test_files/side_effect_import/module2.js index a951e38cd..e41f5cc0d 100644 --- a/test_files/side_effect_import/module2.js +++ b/test_files/side_effect_import/module2.js @@ -1,7 +1,5 @@ /** - * * @fileoverview A module for importing from the main test. - * * Generated from: test_files/side_effect_import/module2.ts */ goog.module('test_files.side_effect_import.module2'); diff --git a/test_files/side_effect_import/side_effect_import.js b/test_files/side_effect_import/side_effect_import.js index e8b0a1b48..cff92894d 100644 --- a/test_files/side_effect_import/side_effect_import.js +++ b/test_files/side_effect_import/side_effect_import.js @@ -1,8 +1,6 @@ /** - * * @fileoverview Use some side-effect imports and verify that tsickle generates * proper module code from them. - * * Generated from: test_files/side_effect_import/side_effect_import.ts */ // tslint:disable diff --git a/test_files/single_value_enum/single_value_enum.js b/test_files/single_value_enum/single_value_enum.js index 38755e3b0..1ec501ab8 100644 --- a/test_files/single_value_enum/single_value_enum.js +++ b/test_files/single_value_enum/single_value_enum.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Regression test for single valued enums. TypeScript's getBaseTypeOfLiteralType * returns the EnumLiteral type for SingleValuedEnum.C below, instead of SingleValuedEnum directly. * Previously, tsickle would then emit the type as `SingleValuedEnum.C`, which is illegal in * Closure. - * * Generated from: test_files/single_value_enum/single_value_enum.ts */ goog.module('test_files.single_value_enum.single_value_enum'); diff --git a/test_files/static/static.js b/test_files/static/static.js index 2f1e69ab7..ede55d851 100644 --- a/test_files/static/static.js +++ b/test_files/static/static.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/static/static.ts * @suppress {uselessCode} - * */ goog.module('test_files.static.static'); var module = module || { id: 'test_files/static/static.ts' }; diff --git a/test_files/string_manipulations/uncapitalize_lowercase.js b/test_files/string_manipulations/uncapitalize_lowercase.js index 35fbb414a..0ecf75208 100644 --- a/test_files/string_manipulations/uncapitalize_lowercase.js +++ b/test_files/string_manipulations/uncapitalize_lowercase.js @@ -1,8 +1,6 @@ /** - * * @fileoverview A short test that ensures that string manipulation types (such * as `Uncapitalize`) are converted to a generic `string` type. - * * Generated from: test_files/string_manipulations/uncapitalize_lowercase.ts */ goog.module('test_files.string_manipulations.uncapitalize_lowercase'); diff --git a/test_files/structural.untyped/structural.untyped.js b/test_files/structural.untyped/structural.untyped.js index 05e20d61f..6820b456c 100644 --- a/test_files/structural.untyped/structural.untyped.js +++ b/test_files/structural.untyped/structural.untyped.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Ensure that a class is structurally equivalent to an object * literal with the same fields. * Generated from: test_files/structural.untyped/structural.untyped.ts * @suppress {uselessCode} - * */ goog.module('test_files.structural.untyped.structural.untyped'); var module = module || { id: 'test_files/structural.untyped/structural.untyped.ts' }; diff --git a/test_files/super/super.js b/test_files/super/super.js index 5e3ba3b10..c42fc4bf7 100644 --- a/test_files/super/super.js +++ b/test_files/super/super.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/super/super.ts * @suppress {uselessCode} - * */ goog.module('test_files.super.super'); var module = module || { id: 'test_files/super/super.ts' }; diff --git a/test_files/this_type/this_type.js b/test_files/this_type/this_type.js index 79e8db3d0..ed2663119 100644 --- a/test_files/this_type/this_type.js +++ b/test_files/this_type/this_type.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/this_type/this_type.ts * @suppress {checkTypes,uselessCode} - * */ goog.module('test_files.this_type.this_type'); var module = module || { id: 'test_files/this_type/this_type.ts' }; diff --git a/test_files/transitive_symbol_type_only/exporter.js b/test_files/transitive_symbol_type_only/exporter.js index 93811bc1b..e443533b1 100644 --- a/test_files/transitive_symbol_type_only/exporter.js +++ b/test_files/transitive_symbol_type_only/exporter.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/transitive_symbol_type_only/exporter.ts * @suppress {uselessCode} - * */ goog.module('test_files.transitive_symbol_type_only.exporter'); var module = module || { id: 'test_files/transitive_symbol_type_only/exporter.ts' }; diff --git a/test_files/transitive_symbol_type_only/transitive_symbol_type_only.js b/test_files/transitive_symbol_type_only/transitive_symbol_type_only.js index 02b070483..64e46af3b 100644 --- a/test_files/transitive_symbol_type_only/transitive_symbol_type_only.js +++ b/test_files/transitive_symbol_type_only/transitive_symbol_type_only.js @@ -1,9 +1,7 @@ /** - * * @fileoverview This file uses a type alias that references a type defined in another file. The * test makes sure there is no hard goog.require for the transitive file, as that breaks strict * dependency checking in some systems. - * * Generated from: test_files/transitive_symbol_type_only/transitive_symbol_type_only.ts */ goog.module('test_files.transitive_symbol_type_only.transitive_symbol_type_only'); diff --git a/test_files/ts_migration_exports_shim.no_externs/bad.js b/test_files/ts_migration_exports_shim.no_externs/bad.js index 7d33226ea..0df005185 100644 --- a/test_files/ts_migration_exports_shim.no_externs/bad.js +++ b/test_files/ts_migration_exports_shim.no_externs/bad.js @@ -9,13 +9,11 @@ // test_files/ts_migration_exports_shim.no_externs/bad.ts(51,23): error TS0: export types must be plain identifiers // test_files/ts_migration_exports_shim.no_externs/bad.ts(52,28): error TS0: must be a type reference /** - * * @fileoverview negative tests for the tsMigrationExportsShim transformation. * * Suppress expected errors for :test_files_compilation_test * Generated from: test_files/ts_migration_exports_shim.no_externs/bad.ts * @suppress {checkTypes,uselessCode,visibility} - * */ // Allowed to be exported by tsmes. goog.module('test_files.ts_migration_exports_shim.no_externs.bad'); diff --git a/test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_more_than_one_export.js b/test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_more_than_one_export.js index c3fd6c3b4..9278ef4ac 100644 --- a/test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_more_than_one_export.js +++ b/test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_more_than_one_export.js @@ -1,13 +1,11 @@ // test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_more_than_one_export.ts(14,1): error TS0: can only call goog.tsMigrationDefaultExportsShim when there is exactly one export. /** - * * @fileoverview negative tests for the tsMigrationDefaultExportsShim * transformation. * * Suppress expected errors for :test_files_compilation_test * Generated from: test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_more_than_one_export.ts * @suppress {checkTypes,visibility} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.bad_default_shorthand_with_more_than_one_export'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_more_than_one_export.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_no_exports.js b/test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_no_exports.js index 04c90a758..1e8357877 100644 --- a/test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_no_exports.js +++ b/test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_no_exports.js @@ -1,13 +1,11 @@ // test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_no_exports.ts(11,1): error TS0: can only call goog.tsMigrationDefaultExportsShim when there is exactly one export. /** - * * @fileoverview negative tests for the tsMigrationDefaultExportsShim * transformation. * * Suppress expected errors for :test_files_compilation_test * Generated from: test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_no_exports.ts * @suppress {checkTypes,visibility} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.bad_default_shorthand_with_no_exports'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/bad_default_shorthand_with_no_exports.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/bad_dln_only.js b/test_files/ts_migration_exports_shim.no_externs/bad_dln_only.js index 8267b8ff9..e4c7433da 100644 --- a/test_files/ts_migration_exports_shim.no_externs/bad_dln_only.js +++ b/test_files/ts_migration_exports_shim.no_externs/bad_dln_only.js @@ -1,13 +1,11 @@ // test_files/ts_migration_exports_shim.no_externs/bad_dln_only.ts(12,1): error TS0: goog.tsMigrationExportsShimDeclareLegacyNamespace requires a goog.tsMigration*ExportsShim call as well /** - * * @fileoverview negative test for the tsMigrationExportsShim transformation for * tsMigrationExportsShimDeclareLegacyNamespace. * * Suppress expected errors for :test_files_compilation_test * Generated from: test_files/ts_migration_exports_shim.no_externs/bad_dln_only.ts * @suppress {checkTypes,visibility} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.bad_dln_only'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/bad_dln_only.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/correct_default_shorthand.js b/test_files/ts_migration_exports_shim.no_externs/correct_default_shorthand.js index dddf471b7..936378b22 100644 --- a/test_files/ts_migration_exports_shim.no_externs/correct_default_shorthand.js +++ b/test_files/ts_migration_exports_shim.no_externs/correct_default_shorthand.js @@ -1,9 +1,7 @@ /** - * * @fileoverview An example export to be re-exported. * Generated from: test_files/ts_migration_exports_shim.no_externs/correct_default_shorthand.ts * @suppress {uselessCode} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.correct_default_shorthand'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/correct_default_shorthand.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/correct_default_type.js b/test_files/ts_migration_exports_shim.no_externs/correct_default_type.js index 87b1b3e43..4d45eea5e 100644 --- a/test_files/ts_migration_exports_shim.no_externs/correct_default_type.js +++ b/test_files/ts_migration_exports_shim.no_externs/correct_default_type.js @@ -1,9 +1,7 @@ /** - * * @fileoverview An example export to be re-exported. * Generated from: test_files/ts_migration_exports_shim.no_externs/correct_default_type.ts * @suppress {uselessCode} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.correct_default_type'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/correct_default_type.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/correct_default_value.js b/test_files/ts_migration_exports_shim.no_externs/correct_default_value.js index 57963c261..061d3f24d 100644 --- a/test_files/ts_migration_exports_shim.no_externs/correct_default_value.js +++ b/test_files/ts_migration_exports_shim.no_externs/correct_default_value.js @@ -1,9 +1,7 @@ /** - * * @fileoverview An example export to be re-exported. * Generated from: test_files/ts_migration_exports_shim.no_externs/correct_default_value.ts * @suppress {uselessCode} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.correct_default_value'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/correct_default_value.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/correct_default_with_re_export.js b/test_files/ts_migration_exports_shim.no_externs/correct_default_with_re_export.js index 30ec51f46..79bd8ab5c 100644 --- a/test_files/ts_migration_exports_shim.no_externs/correct_default_with_re_export.js +++ b/test_files/ts_migration_exports_shim.no_externs/correct_default_with_re_export.js @@ -1,9 +1,7 @@ /** - * * @fileoverview An example export with a re-export to be re-exported via TSMES. * Generated from: test_files/ts_migration_exports_shim.no_externs/correct_default_with_re_export.ts * @suppress {uselessCode} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.correct_default_with_re_export'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/correct_default_with_re_export.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/correct_named.js b/test_files/ts_migration_exports_shim.no_externs/correct_named.js index 9631d1c08..ff7a0197d 100644 --- a/test_files/ts_migration_exports_shim.no_externs/correct_named.js +++ b/test_files/ts_migration_exports_shim.no_externs/correct_named.js @@ -1,9 +1,7 @@ /** - * * @fileoverview An example export to be re-exported. * Generated from: test_files/ts_migration_exports_shim.no_externs/correct_named.ts * @suppress {uselessCode} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.correct_named'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/correct_named.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/correct_named_shorthand.js b/test_files/ts_migration_exports_shim.no_externs/correct_named_shorthand.js index 34b0ed71b..983d5ad11 100644 --- a/test_files/ts_migration_exports_shim.no_externs/correct_named_shorthand.js +++ b/test_files/ts_migration_exports_shim.no_externs/correct_named_shorthand.js @@ -1,9 +1,7 @@ /** - * * @fileoverview An example export to be re-exported. * Generated from: test_files/ts_migration_exports_shim.no_externs/correct_named_shorthand.ts * @suppress {uselessCode} - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.correct_named_shorthand'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/correct_named_shorthand.ts' }; diff --git a/test_files/ts_migration_exports_shim.no_externs/pintomodule.js b/test_files/ts_migration_exports_shim.no_externs/pintomodule.js index 3f751b053..b31922f3b 100644 --- a/test_files/ts_migration_exports_shim.no_externs/pintomodule.js +++ b/test_files/ts_migration_exports_shim.no_externs/pintomodule.js @@ -1,10 +1,8 @@ /** - * * @fileoverview This file is marked as a pintomodule, which must be propagated * into the .tsmes.closure.js file. * Generated from: test_files/ts_migration_exports_shim.no_externs/pintomodule.ts * @pintomodule - * */ goog.module('test_files.ts_migration_exports_shim.no_externs.pintomodule'); var module = module || { id: 'test_files/ts_migration_exports_shim.no_externs/pintomodule.ts' }; diff --git a/test_files/ts_migration_exports_shim.tsmes_disabled.no_externs/emits_other_errors.js b/test_files/ts_migration_exports_shim.tsmes_disabled.no_externs/emits_other_errors.js index ac139161d..98d5a6f6d 100644 --- a/test_files/ts_migration_exports_shim.tsmes_disabled.no_externs/emits_other_errors.js +++ b/test_files/ts_migration_exports_shim.tsmes_disabled.no_externs/emits_other_errors.js @@ -2,13 +2,11 @@ // test_files/ts_migration_exports_shim.tsmes_disabled.no_externs/emits_other_errors.ts(62,3): error TS0: goog.tsMigrationExportsShim is only allowed in top level statements // test_files/ts_migration_exports_shim.tsmes_disabled.no_externs/emits_other_errors.ts(35,1): error TS0: calls to goog.tsMigration*ExportsShim are not enabled. Please set generate_ts_migration_exports_shim = True in the BUILD file to enable this feature. /** - * * @fileoverview negative tests for the tsMigrationExportsShim transformation. * * Suppress expected errors for :test_files_compilation_test * Generated from: test_files/ts_migration_exports_shim.tsmes_disabled.no_externs/emits_other_errors.ts * @suppress {checkTypes,uselessCode,visibility} - * */ // Allowed to be exported by tsmes. goog.module('test_files.ts_migration_exports_shim.tsmes_disabled.no_externs.emits_other_errors'); diff --git a/test_files/tuple_types/tuple_functions.js b/test_files/tuple_types/tuple_functions.js index 172f5edec..7045bfecb 100644 --- a/test_files/tuple_types/tuple_functions.js +++ b/test_files/tuple_types/tuple_functions.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Tests that destructured parameters get aliased into more * specific local variables. * Generated from: test_files/tuple_types/tuple_functions.ts * @suppress {uselessCode} - * */ goog.module('test_files.tuple_types.tuple_functions'); var module = module || { id: 'test_files/tuple_types/tuple_functions.ts' }; diff --git a/test_files/tuple_types/tuple_types.js b/test_files/tuple_types/tuple_types.js index 354bf8d0d..b88153be8 100644 --- a/test_files/tuple_types/tuple_types.js +++ b/test_files/tuple_types/tuple_types.js @@ -1,8 +1,6 @@ /** - * * @fileoverview Tests that tuple types get emitted with local aliases to * attach Closure types to. - * * Generated from: test_files/tuple_types/tuple_types.ts */ goog.module('test_files.tuple_types.tuple_types'); diff --git a/test_files/type_alias_imported/type_alias_declare.js b/test_files/type_alias_imported/type_alias_declare.js index f9423970a..6f038d44a 100644 --- a/test_files/type_alias_imported/type_alias_declare.js +++ b/test_files/type_alias_imported/type_alias_declare.js @@ -1,11 +1,9 @@ /** - * * @fileoverview Declares the symbols used in union types in * type_alias_exporter. These symbols must ultimately be imported by * type_alias_imported. * Generated from: test_files/type_alias_imported/type_alias_declare.ts * @suppress {uselessCode} - * */ goog.module('test_files.type_alias_imported.type_alias_declare'); var module = module || { id: 'test_files/type_alias_imported/type_alias_declare.ts' }; diff --git a/test_files/type_alias_imported/type_alias_default_exporter.js b/test_files/type_alias_imported/type_alias_default_exporter.js index db6ed3a6f..39a8807a6 100644 --- a/test_files/type_alias_imported/type_alias_default_exporter.js +++ b/test_files/type_alias_imported/type_alias_default_exporter.js @@ -1,8 +1,6 @@ /** - * * @fileoverview Declares a type alias as default export. This allows testing that the appropriate * type reference is created (no .default property). - * * Generated from: test_files/type_alias_imported/type_alias_default_exporter.ts */ goog.module('test_files.type_alias_imported.type_alias_default_exporter'); diff --git a/test_files/type_and_value/module.js b/test_files/type_and_value/module.js index 186863eb2..355c66c43 100644 --- a/test_files/type_and_value/module.js +++ b/test_files/type_and_value/module.js @@ -1,12 +1,10 @@ // test_files/type_and_value/module.ts(7,1): warning TS0: type/symbol conflict for TypeAndValue, using {?} for now // test_files/type_and_value/module.ts(12,1): warning TS0: type/symbol conflict for TemplatizedTypeAndValue, using {?} for now /** - * * @fileoverview TypeAndValue is both a type and a value, which is allowed in * TypeScript but disallowed in Closure. * Generated from: test_files/type_and_value/module.ts * @suppress {uselessCode} - * */ // WARNING: interface has both a type and a value, skipping emit goog.module('test_files.type_and_value.module'); diff --git a/test_files/type_args_repeated/type_args_repeated.js b/test_files/type_args_repeated/type_args_repeated.js index 991be033f..cbbe7d756 100644 --- a/test_files/type_args_repeated/type_args_repeated.js +++ b/test_files/type_args_repeated/type_args_repeated.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Test file to test that tsickle emits consistent closure types * when type args are repeated. * Generated from: test_files/type_args_repeated/type_args_repeated.ts * @suppress {checkTypes} - * */ goog.module('test_files.type_args_repeated.type_args_repeated'); var module = module || { id: 'test_files/type_args_repeated/type_args_repeated.ts' }; diff --git a/test_files/type_intersection/intersection.js b/test_files/type_intersection/intersection.js index 48ac0f6bf..944afa318 100644 --- a/test_files/type_intersection/intersection.js +++ b/test_files/type_intersection/intersection.js @@ -2,13 +2,11 @@ // test_files/type_intersection/intersection.ts(19,1): warning TS0: unhandled type flags: Intersection // test_files/type_intersection/intersection.ts(19,1): warning TS0: unhandled type flags: Intersection /** - * * @fileoverview Test that type alias declarations containing an intersection * of type literals does not lose property names in the externs. Regression * test for b/261049209. * Generated from: test_files/type_intersection/intersection.ts * @suppress {uselessCode} - * */ goog.module('test_files.type_intersection.intersection'); var module = module || { id: 'test_files/type_intersection/intersection.ts' }; diff --git a/test_files/type_narrowing/emit_extra_casts.js b/test_files/type_narrowing/emit_extra_casts.js index 0db1102a1..276251170 100644 --- a/test_files/type_narrowing/emit_extra_casts.js +++ b/test_files/type_narrowing/emit_extra_casts.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Test that type casts are emitted when a type is used which was * narrowed since declaration. * Generated from: test_files/type_narrowing/emit_extra_casts.ts * @suppress {uselessCode} - * */ goog.module('test_files.type_narrowing.emit_extra_casts'); var module = module || { id: 'test_files/type_narrowing/emit_extra_casts.ts' }; diff --git a/test_files/type_propaccess.no_externs/type_propaccess.js b/test_files/type_propaccess.no_externs/type_propaccess.js index 212c22262..fd6946089 100644 --- a/test_files/type_propaccess.no_externs/type_propaccess.js +++ b/test_files/type_propaccess.no_externs/type_propaccess.js @@ -1,9 +1,7 @@ /** - * * @fileoverview * Generated from: test_files/type_propaccess.no_externs/type_propaccess.ts * @suppress {checkTypes} - * */ goog.module('test_files.type_propaccess.no_externs.type_propaccess'); var module = module || { id: 'test_files/type_propaccess.no_externs/type_propaccess.ts' }; diff --git a/test_files/typeof_function_overloads/user.js b/test_files/typeof_function_overloads/user.js new file mode 100644 index 000000000..f4b57e581 --- /dev/null +++ b/test_files/typeof_function_overloads/user.js @@ -0,0 +1,19 @@ +/** + * @fileoverview Test overloaded function type emit. + * Generated from: test_files/typeof_function_overloads/user.ts + */ +goog.module('test_files.typeof_function_overloads.user'); +var module = module || { id: 'test_files/typeof_function_overloads/user.ts' }; +goog.require('tslib'); +/** + * @param {?=} initialValue + * @return {null} + */ +function ɵinput(initialValue) { + return null; +} +exports.ɵinput = ɵinput; +/** @typedef {function(?=): null} */ +exports.InputFn; +/** @type {function(?=): null} */ +exports.input = ɵinput; diff --git a/test_files/typeof_function_overloads/user.ts b/test_files/typeof_function_overloads/user.ts new file mode 100644 index 000000000..f4233189f --- /dev/null +++ b/test_files/typeof_function_overloads/user.ts @@ -0,0 +1,11 @@ +/** + * @fileoverview Test overloaded function type emit. + */ + +export function ɵinput(): null; +export function ɵinput(initialValue: any): null; +export function ɵinput(initialValue?: any): null { + return null; +} +export type InputFn = typeof ɵinput; +export const input = ɵinput; diff --git a/test_files/underscore/underscore.js b/test_files/underscore/underscore.js index adba00106..534e6fb38 100644 --- a/test_files/underscore/underscore.js +++ b/test_files/underscore/underscore.js @@ -1,10 +1,8 @@ /** - * * @fileoverview Verify that double-underscored names in various places don't * get corrupted. See getIdentifierText() in tsickle.ts. * Generated from: test_files/underscore/underscore.ts * @suppress {uselessCode} - * */ goog.module('test_files.underscore.underscore'); var module = module || { id: 'test_files/underscore/underscore.ts' }; diff --git a/test_files/use_closure_externs/use_closure_externs.js b/test_files/use_closure_externs/use_closure_externs.js index 5765cba9e..863d189d5 100644 --- a/test_files/use_closure_externs/use_closure_externs.js +++ b/test_files/use_closure_externs/use_closure_externs.js @@ -1,10 +1,8 @@ /** - * * @fileoverview A source file that uses types that are used in .d.ts files, but * that are not available or use different names in Closure's externs. * Generated from: test_files/use_closure_externs/use_closure_externs.ts * @suppress {checkTypes} - * */ goog.module('test_files.use_closure_externs.use_closure_externs'); var module = module || { id: 'test_files/use_closure_externs/use_closure_externs.ts' }; diff --git a/test_files/visibility/public_override.js b/test_files/visibility/public_override.js index 31f3039e3..af2c752af 100644 --- a/test_files/visibility/public_override.js +++ b/test_files/visibility/public_override.js @@ -1,12 +1,10 @@ /** - * * @fileoverview Reproduces a problem where TS implicitly defaults to public * visibility, whereas Closure Compiler implicitly inherits the parent's class * visibility, leading to a mismatch and warning generated in Closure Compiler * for code that compiles fine in TS. * Generated from: test_files/visibility/public_override.ts * @suppress {uselessCode} - * */ goog.module('test_files.visibility.public_override'); var module = module || { id: 'test_files/visibility/public_override.ts' }; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 000000000..6489d7c35 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,603 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658" + integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g== + dependencies: + "@babel/highlight" "^7.12.13" + +"@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== + +"@babel/highlight@^7.12.13": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@types/diff-match-patch@^1.0.32": + version "1.0.32" + resolved "https://registry.yarnpkg.com/@types/diff-match-patch/-/diff-match-patch-1.0.32.tgz#d9c3b8c914aa8229485351db4865328337a3d09f" + integrity sha512-bPYT5ECFiblzsVzyURaNhljBH2Gh1t9LowgUwciMrNAhFewLkHT2H0Mto07Y4/3KCOGZHRQll3CTtQZ0X11D/A== + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/glob@5.0.35": + version "5.0.35" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a" + integrity sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/jasmine@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.7.7.tgz#56718af036be3c9f86eca560a22e39440b2b0784" + integrity sha512-yZzGe1d1T0y+imXDZ79F030nn8qbmiwpWKCZKvKN0KbTzwXAVYShUxkIxu1ba+vhIdabTGVGCfbtZC0oOam8TQ== + +"@types/minimatch@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" + integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== + +"@types/minimist@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" + integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== + +"@types/node@*": + version "15.12.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.1.tgz#9b60797dee1895383a725f828a869c86c6caa5c2" + integrity sha512-zyxJM8I1c9q5sRMtVF+zdd13Jt6RU4r4qfhTd7lQubyThvLfx6yYekWSQjGCGV2Tkecgxnlpl/DNlb6Hg+dmEw== + +"@types/node@^10.5.6": + version "10.17.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" + integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== + +"@types/source-map-support@^0.5.3": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@types/source-map-support/-/source-map-support-0.5.3.tgz#acb6b3e499c20692552d16934c16162c84594e16" + integrity sha512-fvjMjVH8Rmokw2dWh1dkj90iX5R8FPjeZzjNH+6eFXReh0QnHFf1YBl3B0CF0RohIAA3SDRJsGeeUWKl6d7HqA== + dependencies: + source-map "^0.6.0" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +chalk@2.x, chalk@^2.0.0, chalk@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +coffeescript@~1.12.7: + version "1.12.7" + resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.12.7.tgz#e57ee4c4867cf7f606bfc4a0f2d550c0981ddd27" + integrity sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +commander@^2.12.1: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +diff-match-patch@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37" + integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gaze@~1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" + integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== + dependencies: + globule "^1.0.0" + +glob@7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.1, glob@^7.1.6, glob@~7.1.1: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globule@^1.0.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.2.tgz#d8bdd9e9e4eef8f96e245999a5dee7eb5d8529c4" + integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA== + dependencies: + glob "~7.1.1" + lodash "~4.17.10" + minimatch "~3.0.2" + +google-closure-compiler-java@^20190929.0.0: + version "20190929.0.0" + resolved "https://registry.yarnpkg.com/google-closure-compiler-java/-/google-closure-compiler-java-20190929.0.0.tgz#faa2c5750982a79c8a4c27999164842502d6b80a" + integrity sha512-fDThDeix5BDIQrP1ESznDq6VDLxY539JF2Hhm+/+XfgXz/kfxWB6RIcsHF+pI4QdNYEEaUGsE3gvF0bYpesUUQ== + +google-closure-compiler-js@^20190929.0.0: + version "20190929.0.0" + resolved "https://registry.yarnpkg.com/google-closure-compiler-js/-/google-closure-compiler-js-20190929.0.0.tgz#6b62c7122fcce86a978a5496fb593949452edefe" + integrity sha512-IB9GJCJPGcSNZWtferd15lA9InUaab9oWPZhJssZN3z/nsHPzV9SqKJLj2oajmcaf2uINhlOIsCVWZwC+AbwVA== + +google-closure-compiler-linux@^20190929.0.0: + version "20190929.0.0" + resolved "https://registry.yarnpkg.com/google-closure-compiler-linux/-/google-closure-compiler-linux-20190929.0.0.tgz#394b29e8c294498be34f5e86eb3f38fa5d2abe6a" + integrity sha512-gu/H1z7MqC43rXnGGoUyGdb12kTFpkDNw0huKj1ScXNvHgq5fQteicQKd7EpiKOIlMBJbJOKoVFNpU1nrAfNvQ== + +google-closure-compiler-osx@^20190929.0.0: + version "20190929.0.0" + resolved "https://registry.yarnpkg.com/google-closure-compiler-osx/-/google-closure-compiler-osx-20190929.0.0.tgz#06e501a0c7ae78b6bc16c260ba137c82bb9d933f" + integrity sha512-SZbp2BOhwjrJdrShZ4HrtBHOEJyKvOtka47uXyo83AdZMX22EV04z+mQCMFHtBautgG/mCsL8eX75nlMPXzkjg== + +google-closure-compiler-windows@^20190929.0.0: + version "20190929.0.0" + resolved "https://registry.yarnpkg.com/google-closure-compiler-windows/-/google-closure-compiler-windows-20190929.0.0.tgz#d6ab1ff5c74d87302884cc7691349d2f14e73b51" + integrity sha512-b1azZx19cQnYqwof+4KxWcjjOJ88QeDDIvmjCmuAZjXG5UC0os/1cutg0AeK3gZnXAsaQwAh3szy+QGKT6IgWw== + +google-closure-compiler@^20190929.0.0: + version "20190929.0.0" + resolved "https://registry.yarnpkg.com/google-closure-compiler/-/google-closure-compiler-20190929.0.0.tgz#9ddd9150e852fe6486e7840ba8277e67ee50ec72" + integrity sha512-psPXU3rfTbx4WsTOxtxCnNQqZdphdH1fS7KbqISJ3Bk1G6WMFapnCUHdnXsFz96i/XrVaTxjwUfrNdoz/F+PsA== + dependencies: + chalk "2.x" + google-closure-compiler-java "^20190929.0.0" + google-closure-compiler-js "^20190929.0.0" + minimist "1.x" + vinyl "2.x" + vinyl-sourcemaps-apply "^0.2.0" + optionalDependencies: + google-closure-compiler-linux "^20190929.0.0" + google-closure-compiler-osx "^20190929.0.0" + google-closure-compiler-windows "^20190929.0.0" + +growl@^1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-core-module@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== + dependencies: + has "^1.0.3" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +jasmine-core@~3.7.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.7.1.tgz#0401327f6249eac993d47bbfa18d4e8efacfb561" + integrity sha512-DH3oYDS/AUvvr22+xUBW62m1Xoy7tUlY1tsxKEJvl5JeJ7q8zd1K5bUwiOxdH+erj6l2vAMM3hV25Xs9/WrmuQ== + +jasmine-growl-reporter@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/jasmine-growl-reporter/-/jasmine-growl-reporter-2.0.0.tgz#4943a2481193d66a8a68ee2f38b6c360fb037859" + integrity sha512-RYwVfPaGgxQQSHDOt6jQ99/KAkFQ/Fiwg/AzBS+uO9A4UhGhxb7hwXaUUSU/Zs0MxBoFNqmIRC+7P4/+5O3lXg== + dependencies: + growl "^1.10.5" + +jasmine-node@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jasmine-node/-/jasmine-node-3.0.0.tgz#f12b6fdd24633402ec23e8ea6fef6ffbcb464f90" + integrity sha512-vUa5Q7bQYwHHqi6FlJYndiKqZp+d+c3MKe0QUMwwrC4JRmoRV3zkg0buxB/uQ6qLh0NO34TNstpAnvaZ6xGlAA== + dependencies: + coffeescript "~1.12.7" + gaze "~1.1.2" + jasmine-growl-reporter "~2.0.0" + jasmine-reporters "~1.0.0" + mkdirp "~0.3.5" + requirejs "~2.3.6" + underscore "~1.9.1" + walkdir "~0.0.12" + +jasmine-reporters@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jasmine-reporters/-/jasmine-reporters-1.0.2.tgz#ab613ed5977dc7487e85b3c12f6a8ea8db2ade31" + integrity sha1-q2E+1Zd9x0h+hbPBL2qOqNsq3jE= + dependencies: + mkdirp "~0.3.5" + +jasmine@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/jasmine/-/jasmine-3.7.0.tgz#d36638c0c815e6ad5666676e386d79e2ccb70835" + integrity sha512-wlzGQ+cIFzMEsI+wDqmOwvnjTvolLFwlcpYLCqSPPH0prOQaW3P+IzMhHYn934l1imNvw07oCyX+vGUv3wmtSQ== + dependencies: + glob "^7.1.6" + jasmine-core "~3.7.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +lodash@~4.17.10: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@1.x, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mkdirp@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.5.tgz#de3e5f8961c88c787ee1368df849ac4413eca8d7" + integrity sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc= + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-parse@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +readable-stream@^2.3.5: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +replace-ext@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== + +requirejs@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9" + integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg== + +resolve@^1.3.2: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +semver@^5.3.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +source-map-support@^0.5.19: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.3: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +tslib@^1.13.0, tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== + +tslint@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" + integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.3" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.13.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +typescript@~4.3: + version "4.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" + integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== + +underscore@~1.9.1: + version "1.9.2" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.2.tgz#0c8d6f536d6f378a5af264a72f7bec50feb7cf2f" + integrity sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ== + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +vinyl-sourcemaps-apply@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + integrity sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU= + dependencies: + source-map "^0.5.1" + +vinyl@2.x: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" + integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +walkdir@~0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.12.tgz#2f24f1ade64aab1e458591d4442c8868356e9281" + integrity sha512-HFhaD4mMWPzFSqhpyDG48KDdrjfn409YQuVW7ckZYhW4sE87mYtWifdB/+73RA7+p4s4K18n5Jfx1kHthE1gBw== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=