diff --git a/demo/package.json b/demo/package.json
index 0bd9d3e46..3c13d5def 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.3.2"
},
"devDependencies": {
"@types/minimist": "1.2.0",
diff --git a/package.json b/package.json
index b2f9930b5..3bbb1a402 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
"out/src/*"
],
"peerDependencies": {
- "typescript": "~5.1.5"
+ "typescript": "~5.3.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.3.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/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_transformer.ts b/src/jsdoc_transformer.ts
index 6e3e5119b..5505ddc67 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));
@@ -1172,7 +1172,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) {
@@ -1322,8 +1322,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 +1334,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 +1352,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 +1407,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);
}
diff --git a/src/ns_transformer.ts b/src/ns_transformer.ts
index 67300c942..129c15a3d 100644
--- a/src/ns_transformer.ts
+++ b/src/ns_transformer.ts
@@ -72,8 +72,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 +83,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 +100,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 +122,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 +133,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 +177,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) {
@@ -365,12 +403,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..9f2623345 100644
--- a/src/summary.ts
+++ b/src/summary.ts
@@ -54,6 +54,7 @@ export class FileSummary {
modName: string|undefined;
autochunk = false;
enhanceable = false;
+ legacyNamespace = false;
moduleType = ModuleType.UNKNOWN;
private stringify(symbol: Symbol): string {
diff --git a/src/transformer_util.ts b/src/transformer_util.ts
index 6c60ef0dd..8489f8fe8 100644
--- a/src/transformer_util.ts
+++ b/src/transformer_util.ts
@@ -152,7 +152,7 @@ export function updateSourceFileNode(
}
sf = ts.factory.updateSourceFile(
sf,
- statements,
+ ts.setTextRange(statements, sf.statements),
sf.isDeclarationFile,
sf.referencedFiles,
sf.typeReferenceDirectives,
@@ -227,28 +227,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 +433,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..ac0db0b80 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,7 +24,6 @@ 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';
@@ -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..6f0f2b826 100644
--- a/test/test_support.ts
+++ b/test/test_support.ts
@@ -453,3 +453,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..11d59e3e7 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,
},
@@ -106,12 +106,10 @@ describe('emitWithTsickle', () => {
'b.ts': `export * from './a';`,
};
- const jsSources = emitWithTsickle(
- tsSources, {
- preserveConstEnums: true,
- module: ts.ModuleKind.ES2015,
- },
- {googmodule: false});
+ const {jsSources} = emitWithTsickle(tsSources, {
+ preserveConstEnums: true,
+ module: ts.ModuleKind.ES2015,
+ });
expect(jsSources['b.js']).toContain(`export { Foo } from './a';`);
});
@@ -121,16 +119,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 +184,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/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/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/comments/trailing_no_semicolon.js b/test_files/comments/trailing_no_semicolon.js
new file mode 100644
index 000000000..f16924b09
--- /dev/null
+++ b/test_files/comments/trailing_no_semicolon.js
@@ -0,0 +1,22 @@
+/**
+ *
+ * @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/decl_merge/outer_enum.js b/test_files/decl_merge/outer_enum.js
new file mode 100644
index 000000000..9f3827e1a
--- /dev/null
+++ b/test_files/decl_merge/outer_enum.js
@@ -0,0 +1,31 @@
+/**
+ *
+ * @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..2fbd3bfa2 100644
--- a/test_files/decl_merge/rejected_ns.js
+++ b/test_files/decl_merge/rejected_ns.js
@@ -1,12 +1,13 @@
-// 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
@@ -24,21 +25,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 +61,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_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/enum.no_nstransform/enum.js b/test_files/enum.no_nstransform/enum.js
new file mode 100644
index 000000000..7c4ae2376
--- /dev/null
+++ b/test_files/enum.no_nstransform/enum.js
@@ -0,0 +1,42 @@
+/**
+ *
+ * @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..e67603054 100644
--- a/test_files/enum/enum.js
+++ b/test_files/enum/enum.js
@@ -57,7 +57,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/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/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/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/typeof_function_overloads/user.js b/test_files/typeof_function_overloads/user.js
new file mode 100644
index 000000000..235469fe2
--- /dev/null
+++ b/test_files/typeof_function_overloads/user.js
@@ -0,0 +1,21 @@
+/**
+ *
+ * @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/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=